update version to 0.02
[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
38cd3a5c 19my $www_selenium;
4f6d213e 20
21=head1 NAME
22
1cdeb21f 23Test::WWW::Selenium::Catalyst - Test your Catalyst application with Selenium
4f6d213e 24
25=cut
26
f781a955 27our $VERSION = '0.02';
4f6d213e 28
de35f86c 29=head1 DEVELOPERISH RELEASE
1cdeb21f 30
de35f86c 31This is still a test release. It's working for me in production, but
1cdeb21f 32it depends on a Java application (SeleniumRC), which can be
33unreliable. On my Debian system, I had to put C<firefox-bin> in my
34path, and add C</usr/lib/firefox> to C<LD_LIBRARY_PATH>. Every distro
35and OS is different, so I'd like some feedback on how this works on
36your system. I would like to find a clean solution that lets this
37module "Just Work" for everyone, but I have a feeling that it's going
38to look more like C<if(gentoo){ ... } elsif (debian) { ... }> and so
39on. I can live with that, but I need your help to get to that stage!
40
41Please report any problems to RT, the Catalyst mailing list, or the
42#catalyst IRC channel on L<irc.perl.org>. Thanks!
43
4f6d213e 44=head1 SYNOPSIS
45
46 use Test::WWW::Selenium::Catalyst 'MyApp';
47 use Test::More tests => 2;
48
49 my $sel = Test::WWW::Selenium::Catalyst->start;
50 $sel->open_ok('/');
51 $sel->is_text_present_ok('Welcome to MyApp');
52
1cdeb21f 53This module starts the SeleniumRC server and your Catalyst app so that
54you can test it with SeleniumRC. Once you've called
6fd21f2e 55C<< Test::WWW::Selenium::Catalyst->start >>, everything is just like
1cdeb21f 56L<Test::WWW::Selenium|Test::WWW:Selenium>.
57
cba20015 58=head1 METHODS
4f6d213e 59
60=head2 start
61
62Starts the Selenium and Catalyst servers, and returns a
63pre-initialized, ready-to-use Test::WWW::Selenium object.
64
65[NOTE] The selenium server is actually started when you C<use> this
66module, and it's killed when your test exits.
67
68=head2 sel_pid
69
70Returns the process ID of the Selenium Server.
71
72=head2 app_pid
73
74Returns the process ID of the Catalyst server.
75
76=cut
77
78
79sub _start_server {
80 # fork off a selenium server
81 my $pid;
82 if(0 == ($pid = fork())){
83 local $SIG{TERM} = sub {
6fd21f2e 84 diag("Selenium server $$ going down (TERM)") if $DEBUG;
4f6d213e 85 exit 0;
86 };
87
88 chdir '/';
89
90 if(!$DEBUG){
91 close *STDERR;
92 close *STDOUT;
e39d6317 93 #close *STDIN;
4f6d213e 94 }
95
96 diag("Selenium running in $$") if $DEBUG;
d5bcfeb7 97 Alien::SeleniumRC::start()
4f6d213e 98 or croak "Can't start Selenium server";
99 diag("Selenium server $$ going down") if $DEBUG;
100 exit 1;
101 }
102 $sel_pid = $pid;
103}
104
105sub sel_pid {
106 return $sel_pid;
107}
108
109sub app_pid {
110 return $app_pid;
111}
112
113sub import {
114 my ($class, $appname) = @_;
115 croak q{Specify your app's name} if !$appname;
116 $app = $appname;
117
118 my $d = $ENV{Catalyst::Utils::class2env($appname). "_DEBUG"}; # MYAPP_DEBUG
119 if(defined $d && $d){
120 $DEBUG = 1;
121 }
122 elsif(defined $d && $d == 0){
123 $DEBUG = 0;
124 }
125 # if it's something else, leave the CATALYST_DEBUG setting in tact
126
127 _start_server() or croak "Couldn't start selenium server";
128 return 1;
129}
130
131sub start {
132 my $class = shift;
133 my $args = shift || {};
134
135 # start a Catalyst MyApp server
136 eval("use $app");
137 croak "Couldn't load $app: $@" if $@;
138
139 my $pid;
140 if(0 == ($pid = fork())){
141 local $SIG{TERM} = sub {
142 diag("Catalyst server $$ going down (TERM)") if $DEBUG;
143 exit 0;
144 };
145 diag("Catalyst server running in $$") if $DEBUG;
146 $app->run('3000', 'localhost');
147 exit 1;
148 }
149 $app_pid = $pid;
150
151 my $tries = 5;
152 my $error;
153 my $sel;
154 while(!$sel && $tries--){
155 sleep 1;
156 diag("Waiting for selenium server to start")
157 if $DEBUG;
158
159 eval {
160 $sel = Test::WWW::Selenium->
161 new(host => 'localhost',
162 port => 4444,
163 browser => $args->{browser} || '*firefox',
38cd3a5c 164 browser_url => 'http://localhost:3000/',
165 auto_stop => 0,
4f6d213e 166 );
167 };
168 $error = $@;
169 }
38cd3a5c 170 croak "Can't start selenium: $error" if $error;
4f6d213e 171
38cd3a5c 172 return $www_selenium = $sel;
4f6d213e 173}
174
175END {
38cd3a5c 176 if($www_selenium){
177 diag("Shutting down Selenium Server $sel_pid") if $DEBUG;
178 $www_selenium->do_command('shutDown');
179 undef $www_selenium;
180 }
4f6d213e 181 if($sel_pid){
182 diag("Killing Selenium Server $sel_pid") if $DEBUG;
183 kill 15, $sel_pid or diag "Killing Selenium: $!";
184 undef $sel_pid;
185 }
186 if($app_pid){
187 diag("Killing catalyst server $app_pid") if $DEBUG;
188 kill 15, $app_pid or diag "Killing MyApp: $!";
189 undef $app_pid;
190 }
191 diag("Waiting for children to die") if $DEBUG;
192 waitpid $sel_pid, 0 if $sel_pid;
193 waitpid $app_pid, 0 if $app_pid;
194}
195
196
197=head1 ENVIRONMENT
198
199Debugging messages are shown if C<CATALYST_DEBUG> or C<MYAPP_DEBUG>
200are set. C<MYAPP> is the name of your application, uppercased. (This
201is the same syntax as Catalyst itself.)
202
203=head1 DIAGNOSTICS
204
205=head2 Specify your app's name
206
207You need to pass your Catalyst app's name as the argument to the use
208statement:
209
210 use Test::WWW::Selenium::Catalyst 'MyApp'
211
212C<MyApp> is the name of your Catalyst app.
213
1cdeb21f 214=head1 SEE ALSO
215
216=over 4
217
218=item *
219
220Selenium website: L<http://www.openqa.org/>
221
222=item *
223
224Description of what you can do with the C<$sel> object: L<Test::WWW::Selenium>
225
226=item *
227
228If you don't need a real web browser: L<Test::WWW::Mechanize::Catalyst>
229
230=back
231
4f6d213e 232=head1 AUTHOR
233
234Jonathan Rockway, C<< <jrockway at cpan.org> >>
235
236=head1 BUGS
237
238Please report any bugs or feature requests to
239C<bug-test-www-selenium-catalyst at rt.cpan.org>, or through the web interface at
240L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-WWW-Selenium-Catalyst>.
241I will be notified, and then you'll automatically be notified of progress on
242your bug as I make changes.
243
cba20015 244=head1 PATCHES
4f6d213e 245
cba20015 246Send me unified diffs against the git HEAD at:
4f6d213e 247
cba20015 248 git://git.jrock.us/Test-WWW-Selenium-Catalyst
4f6d213e 249
cba20015 250You can view the repository online at
4f6d213e 251
cba20015 252 http://git.jrock.us/?p=Test-WWW-Selenium-Catalyst.git;a=summary
4f6d213e 253
cba20015 254Thanks in advance for your contributions!
4f6d213e 255
256=head1 ACKNOWLEDGEMENTS
257
1cdeb21f 258Thanks for mst for getting on my case to actually write this thing :)
259
4f6d213e 260=head1 COPYRIGHT & LICENSE
261
262Copyright 2006 Jonathan Rockway, all rights reserved.
263
264This program is free software; you can redistribute it and/or modify it
265under the same terms as Perl itself.
266
267=cut
268
2691; # End of Test::WWW::Selenium::Catalyst