Adding Test::WWW::Selenium::Catalyst
[catagits/Test-WWW-Selenium-Catalyst.git] / lib / Test / WWW / Selenium / Catalyst.pm
CommitLineData
4f6d213e 1package Test::WWW::Selenium::Catalyst;
2
3use warnings;
4use strict;
5use Carp;
6use Alien::SeleniumRC;
7use Test::WWW::Selenium;
8use Test::More;
9use Catalyst::Utils;
10
11BEGIN { $ENV{CATALYST_ENGINE} ||= 'HTTP'; }
12
13local $SIG{CHLD} = 'IGNORE';
14
15my $DEBUG = $ENV{CATALYST_DEBUG};
16my $app; # app name (MyApp)
17my $sel_pid; # pid of selenium server
18my $app_pid; # pid of myapp server
19
20=head1 NAME
21
22Test::WWW::Selenium::Catalyst - Test your Catalyst app with Selenium
23
24=cut
25
26our $VERSION = '0.00_01';
27
28=head1 SYNOPSIS
29
30 use Test::WWW::Selenium::Catalyst 'MyApp';
31 use Test::More tests => 2;
32
33 my $sel = Test::WWW::Selenium::Catalyst->start;
34 $sel->open_ok('/');
35 $sel->is_text_present_ok('Welcome to MyApp');
36
37=head1 FUNCTIONS
38
39=head2 start
40
41Starts the Selenium and Catalyst servers, and returns a
42pre-initialized, ready-to-use Test::WWW::Selenium object.
43
44[NOTE] The selenium server is actually started when you C<use> this
45module, and it's killed when your test exits.
46
47=head2 sel_pid
48
49Returns the process ID of the Selenium Server.
50
51=head2 app_pid
52
53Returns the process ID of the Catalyst server.
54
55=cut
56
57
58sub _start_server {
59 # fork off a selenium server
60 my $pid;
61 if(0 == ($pid = fork())){
62 local $SIG{TERM} = sub {
63 diag("Selenium server $$ going down (TERM)");
64 exit 0;
65 };
66
67 chdir '/';
68
69 if(!$DEBUG){
70 close *STDERR;
71 close *STDOUT;
72 close *STDIN;
73 }
74
75 diag("Selenium running in $$") if $DEBUG;
76 Alien::SeleniumRC->start()
77 or croak "Can't start Selenium server";
78 diag("Selenium server $$ going down") if $DEBUG;
79 exit 1;
80 }
81 $sel_pid = $pid;
82}
83
84sub sel_pid {
85 return $sel_pid;
86}
87
88sub app_pid {
89 return $app_pid;
90}
91
92sub import {
93 my ($class, $appname) = @_;
94 croak q{Specify your app's name} if !$appname;
95 $app = $appname;
96
97 my $d = $ENV{Catalyst::Utils::class2env($appname). "_DEBUG"}; # MYAPP_DEBUG
98 if(defined $d && $d){
99 $DEBUG = 1;
100 }
101 elsif(defined $d && $d == 0){
102 $DEBUG = 0;
103 }
104 # if it's something else, leave the CATALYST_DEBUG setting in tact
105
106 _start_server() or croak "Couldn't start selenium server";
107 return 1;
108}
109
110sub start {
111 my $class = shift;
112 my $args = shift || {};
113
114 # start a Catalyst MyApp server
115 eval("use $app");
116 croak "Couldn't load $app: $@" if $@;
117
118 my $pid;
119 if(0 == ($pid = fork())){
120 local $SIG{TERM} = sub {
121 diag("Catalyst server $$ going down (TERM)") if $DEBUG;
122 exit 0;
123 };
124 diag("Catalyst server running in $$") if $DEBUG;
125 $app->run('3000', 'localhost');
126 exit 1;
127 }
128 $app_pid = $pid;
129
130 my $tries = 5;
131 my $error;
132 my $sel;
133 while(!$sel && $tries--){
134 sleep 1;
135 diag("Waiting for selenium server to start")
136 if $DEBUG;
137
138 eval {
139 $sel = Test::WWW::Selenium->
140 new(host => 'localhost',
141 port => 4444,
142 browser => $args->{browser} || '*firefox',
143 browser_url => 'http://localhost:3000/'
144 );
145 };
146 $error = $@;
147 }
148
149 eval { $sel->start }
150 or croak "Can't start selenium: $@ (previous error: $error)";
151
152 return $sel;
153}
154
155END {
156 if($sel_pid){
157 diag("Killing Selenium Server $sel_pid") if $DEBUG;
158 kill 15, $sel_pid or diag "Killing Selenium: $!";
159 undef $sel_pid;
160 }
161 if($app_pid){
162 diag("Killing catalyst server $app_pid") if $DEBUG;
163 kill 15, $app_pid or diag "Killing MyApp: $!";
164 undef $app_pid;
165 }
166 diag("Waiting for children to die") if $DEBUG;
167 waitpid $sel_pid, 0 if $sel_pid;
168 waitpid $app_pid, 0 if $app_pid;
169}
170
171
172=head1 ENVIRONMENT
173
174Debugging messages are shown if C<CATALYST_DEBUG> or C<MYAPP_DEBUG>
175are set. C<MYAPP> is the name of your application, uppercased. (This
176is the same syntax as Catalyst itself.)
177
178=head1 DIAGNOSTICS
179
180=head2 Specify your app's name
181
182You need to pass your Catalyst app's name as the argument to the use
183statement:
184
185 use Test::WWW::Selenium::Catalyst 'MyApp'
186
187C<MyApp> is the name of your Catalyst app.
188
189=head1 AUTHOR
190
191Jonathan Rockway, C<< <jrockway at cpan.org> >>
192
193=head1 BUGS
194
195Please report any bugs or feature requests to
196C<bug-test-www-selenium-catalyst at rt.cpan.org>, or through the web interface at
197L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-WWW-Selenium-Catalyst>.
198I will be notified, and then you'll automatically be notified of progress on
199your bug as I make changes.
200
201=head1 SUPPORT
202
203You can find documentation for this module with the perldoc command.
204
205 perldoc Test::WWW::Selenium::Catalyst
206
207You can also look for information at:
208
209=over 4
210
211=item * AnnoCPAN: Annotated CPAN documentation
212
213L<http://annocpan.org/dist/Test-WWW-Selenium-Catalyst>
214
215=item * CPAN Ratings
216
217L<http://cpanratings.perl.org/d/Test-WWW-Selenium-Catalyst>
218
219=item * RT: CPAN's request tracker
220
221L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-WWW-Selenium-Catalyst>
222
223=item * Search CPAN
224
225L<http://search.cpan.org/dist/Test-WWW-Selenium-Catalyst>
226
227=back
228
229=head1 ACKNOWLEDGEMENTS
230
231=head1 COPYRIGHT & LICENSE
232
233Copyright 2006 Jonathan Rockway, all rights reserved.
234
235This program is free software; you can redistribute it and/or modify it
236under the same terms as Perl itself.
237
238=cut
239
2401; # End of Test::WWW::Selenium::Catalyst