X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FTest-WWW-Selenium-Catalyst.git;a=blobdiff_plain;f=lib%2FTest%2FWWW%2FSelenium%2FCatalyst.pm;h=014694f2fa76fcabc3a2ad4576b043bc5f4628c1;hp=258159cab4d5f1d8fcf2d4d2573875866254e9d5;hb=0744bdf67407573b567261e48b0068210f2689c6;hpb=f781a95505c871f75cc58f61a9bf8122cb57cdbe diff --git a/lib/Test/WWW/Selenium/Catalyst.pm b/lib/Test/WWW/Selenium/Catalyst.pm index 258159c..014694f 100644 --- a/lib/Test/WWW/Selenium/Catalyst.pm +++ b/lib/Test/WWW/Selenium/Catalyst.pm @@ -12,11 +12,11 @@ BEGIN { $ENV{CATALYST_ENGINE} ||= 'HTTP'; } local $SIG{CHLD} = 'IGNORE'; -my $DEBUG = $ENV{CATALYST_DEBUG}; -my $app; # app name (MyApp) -my $sel_pid; # pid of selenium server -my $app_pid; # pid of myapp server -my $www_selenium; +our $DEBUG = $ENV{CATALYST_DEBUG}; +our $app; # app name (MyApp) +our $sel_pid; # pid of selenium server +our $app_pid; # pid of myapp server +our $www_selenium; =head1 NAME @@ -24,7 +24,7 @@ Test::WWW::Selenium::Catalyst - Test your Catalyst application with Selenium =cut -our $VERSION = '0.02'; +our $VERSION = '0.05'; =head1 DEVELOPERISH RELEASE @@ -43,7 +43,7 @@ Please report any problems to RT, the Catalyst mailing list, or the =head1 SYNOPSIS - use Test::WWW::Selenium::Catalyst 'MyApp'; + use Test::WWW::Selenium::Catalyst 'MyApp', 'command line to selenium'; use Test::More tests => 2; my $sel = Test::WWW::Selenium::Catalyst->start; @@ -57,13 +57,59 @@ L. =head1 METHODS -=head2 start +=head2 start(\%args) -Starts the Selenium and Catalyst servers, and returns a -pre-initialized, ready-to-use Test::WWW::Selenium object. +Starts the Selenium and Catalyst servers, and returns a pre-initialized, +ready-to-use Test::WWW::Selenium object. -[NOTE] The selenium server is actually started when you C this -module, and it's killed when your test exits. +Arguments: + +=over + +=item app_uri + +URI at which the application can be reached. If this is specified then no +application server will be started. + +=item port + +B: 3000 + +Port on which to run the catalyst application server. The C +environment variable is also respected. + + +=item selenium_class + +B: Test::WWW::Selenium + +Classname of Selenium object to create. Use this if you want to subclass +selenium to add custom logic. + +=item selenium_host + +=item selenium_port + +Location of externally running selenium server if you do not wish this module +to control one. See also for details. + +=back + +All other options passed verbatim to the selenium constructor. + +B: By default a selenium server is started when you C this module, +and it's killed when your test exits. If wish to manage a selenium server +yourself, (for instance you wish to start up a server once and run a number of +tests against it) pass C<-no_selenium_server> to import: + + use Test::WWW::Selenium 'MyApp' + -no_selenium_server => 1 + +Along a similar vein you can also pass command line arguments to the selenium +server via C<-selenium_args>: + + use Test::WWW::Selenium 'MyApp' + -selenium_args => "-singleWindow -port 4445" =head2 sel_pid @@ -77,31 +123,39 @@ Returns the process ID of the Catalyst server. sub _start_server { + my ($class, $args) = @_; # fork off a selenium server my $pid; if(0 == ($pid = fork())){ - local $SIG{TERM} = sub { - diag("Selenium server $$ going down (TERM)") if $DEBUG; - exit 0; - }; - - chdir '/'; - - if(!$DEBUG){ - close *STDERR; - close *STDOUT; - #close *STDIN; - } - - diag("Selenium running in $$") if $DEBUG; - Alien::SeleniumRC::start() - or croak "Can't start Selenium server"; - diag("Selenium server $$ going down") if $DEBUG; - exit 1; + local $SIG{TERM} = sub { + diag("Selenium server $$ going down (TERM)") if $DEBUG; + exit 0; + }; + + chdir '/'; + + if(!$DEBUG){ + close *STDERR; + close *STDOUT; + #close *STDIN; + } + + diag("Selenium running in $$") if $DEBUG; + $class->_start_selenium($args); + diag("Selenium server $$ going down") if $DEBUG; + exit 1; } $sel_pid = $pid; } +# Moved out to be subclassable seperately to the fork logic +sub _start_selenium { + my ($class, $arg) = @_; + $arg = '' unless defined $arg; + Alien::SeleniumRC::start($arg) + or croak "Can't start Selenium server"; +} + sub sel_pid { return $sel_pid; } @@ -111,61 +165,77 @@ sub app_pid { } sub import { - my ($class, $appname) = @_; + my ($class, $appname, %args) = @_; + croak q{Specify your app's name} if !$appname; $app = $appname; my $d = $ENV{Catalyst::Utils::class2env($appname). "_DEBUG"}; # MYAPP_DEBUG - if(defined $d && $d){ - $DEBUG = 1; + if(defined $d){ + $DEBUG = $d; } - elsif(defined $d && $d == 0){ - $DEBUG = 0; + + unless ($args{-no_selenium_server}) { + $class->_start_server($args{-selenium_args}) or croak "Couldn't start selenium server"; } - # if it's something else, leave the CATALYST_DEBUG setting in tact - - _start_server() or croak "Couldn't start selenium server"; return 1; } sub start { my $class = shift; my $args = shift || {}; - - # start a Catalyst MyApp server - eval("use $app"); - croak "Couldn't load $app: $@" if $@; - - my $pid; - if(0 == ($pid = fork())){ - local $SIG{TERM} = sub { - diag("Catalyst server $$ going down (TERM)") if $DEBUG; - exit 0; - }; - diag("Catalyst server running in $$") if $DEBUG; - $app->run('3000', 'localhost'); - exit 1; + + my $port = delete $args->{port}; + $port ||= $ENV{Catalyst::Utils::class2env($app). "_PORT"} # MYAPP_PORT + || 3000; + + my $uri; + + # Check for CATALYST_SERVER env var like TWMC does. + if ( $ENV{CATALYST_SERVER} ) { + $uri = $ENV{CATALYST_SERVER}; + } elsif ( $args->{app_uri} ) { + $uri = delete $args->{app_uri} + } else { + # start a Catalyst MyApp server + eval("use $app"); + croak "Couldn't load $app: $@" if $@; + + my $pid; + if(0 == ($pid = fork())){ + local $SIG{TERM} = sub { + diag("Catalyst server $$ going down (TERM)") if $DEBUG; + exit 0; + }; + diag("Catalyst server running in $$") if $DEBUG; + $app->run($port, 'localhost'); + exit 1; + } + $uri = 'http://localhost:' . $port; + $app_pid = $pid; } - $app_pid = $pid; my $tries = 5; my $error; + my $sel_class = delete $args->{selenium_class} || 'Test::WWW::Selenium'; my $sel; + while(!$sel && $tries--){ - sleep 1; - diag("Waiting for selenium server to start") - if $DEBUG; - - eval { - $sel = Test::WWW::Selenium-> - new(host => 'localhost', - port => 4444, - browser => $args->{browser} || '*firefox', - browser_url => 'http://localhost:3000/', - auto_stop => 0, - ); - }; - $error = $@; + sleep 1; + diag("Waiting for selenium server to start") + if $DEBUG; + + eval { + $sel = $sel_class->new( + host => delete $args->{selenium_host} || 'localhost', + port => delete $args->{selenium_port} || 4444, + browser => '*firefox', + browser_url => $uri, + auto_stop => 0, + %$args + ); + }; + $error = $@; } croak "Can't start selenium: $error" if $error; @@ -173,20 +243,27 @@ sub start { } END { - if($www_selenium){ - diag("Shutting down Selenium Server $sel_pid") if $DEBUG; - $www_selenium->do_command('shutDown'); - undef $www_selenium; - } if($sel_pid){ - diag("Killing Selenium Server $sel_pid") if $DEBUG; - kill 15, $sel_pid or diag "Killing Selenium: $!"; - undef $sel_pid; + if($www_selenium){ + diag("Shutting down Selenium Server $sel_pid") if $DEBUG; + $www_selenium->stop(); + $www_selenium->do_command('shutDown'); + undef $www_selenium; + } + diag("Killing Selenium Server $sel_pid") if $DEBUG; + kill 15, $sel_pid or diag "Killing Selenium: $!"; + undef $sel_pid; + + } elsif ($www_selenium) { + diag("Stopping Selenium Session $sel_pid") if $DEBUG; + $www_selenium->stop(); + undef $www_selenium; } + if($app_pid){ - diag("Killing catalyst server $app_pid") if $DEBUG; - kill 15, $app_pid or diag "Killing MyApp: $!"; - undef $app_pid; + diag("Killing catalyst server $app_pid") if $DEBUG; + kill 15, $app_pid or diag "Killing MyApp: $!"; + undef $app_pid; } diag("Waiting for children to die") if $DEBUG; waitpid $sel_pid, 0 if $sel_pid; @@ -200,6 +277,12 @@ Debugging messages are shown if C or C are set. C is the name of your application, uppercased. (This is the same syntax as Catalyst itself.) +C can be set to test against an externally running server, +in a similar manner to how L behaves. + +The port that the application sever runs on can be affected by C +in addition to being specifiable in the arguments passed to start. + =head1 DIAGNOSTICS =head2 Specify your app's name @@ -217,11 +300,12 @@ C is the name of your Catalyst app. =item * -Selenium website: L +Selenium website: L =item * Description of what you can do with the C<$sel> object: L +and L =item * @@ -231,6 +315,8 @@ If you don't need a real web browser: L =head1 AUTHOR +Ash Berlin C<< >> + Jonathan Rockway, C<< >> =head1 BUGS @@ -245,11 +331,11 @@ your bug as I make changes. Send me unified diffs against the git HEAD at: - git://git.jrock.us/Test-WWW-Selenium-Catalyst + git://github.com/jrockway/test-www-selenium-catalyst.git You can view the repository online at - http://git.jrock.us/?p=Test-WWW-Selenium-Catalyst.git;a=summary + http://github.com/jrockway/test-www-selenium-catalyst/tree/master Thanks in advance for your contributions! @@ -259,6 +345,8 @@ Thanks for mst for getting on my case to actually write this thing :) =head1 COPYRIGHT & LICENSE +Copyright 2009 Ash Berlin, all rights reserved. + Copyright 2006 Jonathan Rockway, all rights reserved. This program is free software; you can redistribute it and/or modify it