51d099f48095735379821b00c64e7b28b2e34cd7
[scpubgit/Test-Harness-Selenium.git] / lib / Test / Harness / Selenium.pm
1 package Test::Harness::Selenium;
2 use strictures 1;
3
4 use File::Find::Rule;
5 use Socialtext::WikiFixture::Selenese;
6 use HTML::TableExtract;
7 use IO::All;
8 use Alien::SeleniumRC;
9 use LWP::Simple;
10
11 use Test::More;
12 BEGIN {
13   package Test::Builder;
14
15   use Class::Method::Modifiers;
16   use ExtUtils::MakeMaker qw(prompt);
17
18   if (!$ENV{AUTOMATED_TESTING}) {
19     around ok => sub {
20       my ($orig, $self) = (shift, shift);
21       my $res = $self->$orig(@_);
22       unless ($res) {
23         if ('y' eq prompt "Well that didn't work, did it. Bail out?", 'y') {
24           exit 255;
25         }
26       }
27       return $res;
28     };
29   }
30 }
31
32 sub new {
33   my ($class, $self) = @_;
34   if($self->{xvnc}) {
35     $ENV{DISPLAY} = $self->{xvnc};
36     my $xvnc_pid = fork();
37     if(!defined $xvnc_pid) {
38       die "couldn't fork xvnc: $!";
39     }
40     elsif($xvnc_pid) {
41       $self->{xvnc_pid} = $xvnc_pid;
42     }
43     else {
44       exec("Xvnc", $self->{xvnc});
45     }
46   }
47   bless $self, $class;
48 }
49
50 sub start_server {
51   my($self) = @_;
52   $self->{server_pid} = fork();
53   if(!defined $self->{server_pid}) {
54     die "can't fork: $!";
55   }
56   if($self->{server_pid} > 0) {
57     my $tries = 0;
58     while($tries < 5) {
59       eval {
60         $self->{src} = Socialtext::WikiFixture::Selenese->new(
61           host => $self->{host},
62           port => $self->{port},
63           browser => $self->{browser},
64           browser_url => $self->{browser_url},
65         );
66       };
67       $tries++;
68       if(!defined $self->{src}) {
69         sleep 10;
70       }
71       else {
72         last;
73       }
74     }
75     die "timed out waiting for selenium server to start" if $tries == 5;
76   }
77   elsif($self->{server_pid} == 0) {
78     # muttermutter, can't specify a host for selenium
79     exec("$^X -MAlien::SeleniumRC -e 'Alien::SeleniumRC::start(q{-port $self->{port}})'");
80   }
81 }
82
83 sub stop_server {
84   my($self) = @_;
85   # okay, we're done, kill the server.
86   get("http://localhost:$self->{port}/selenium-server/driver/?cmd=shutDownSeleniumServer");
87   delete $self->{src};
88   wait;
89 }
90
91 sub test_directory {
92   my ($self, $dir) = @_;
93   my @tests = File::Find::Rule->file()->name('*.html')->in($dir);
94   for my $test (@tests) {
95     $self->start_server;
96     $self->run_tests_for($test);
97     $self->stop_server;
98   }
99 }
100
101 sub run_tests_for {
102   my ($self, $html_file) = @_;
103   my $rows = $self->get_rows_for($html_file);
104   $self->{src}->run_test_table($rows);
105 }
106
107 my $te = HTML::TableExtract->new;
108 sub get_rows_for {
109   my ($self, $html_file) = @_;
110   my $html = io($html_file)->all;
111   $te->parse($html);
112   my $table = ($te->tables)[0];
113   my @rows = map {
114     [ map { (!defined $_ or $_ eq "\240") ? () : $_ } @$_ ]
115   } grep { defined $_->[1] } $table->rows;
116   return \@rows;
117 }
118
119 sub DESTROY {
120   my($self) = @_;
121   if(exists $self->{xvnc_pid}) {
122     kill("KILL", $self->{xvnc_pid});
123   }
124 }
125
126 1;