Test::WWW::Selenium::CGIApp - Test your CGIApp application with Selenium


Test-WWW-Selenium-CGIApp documentation Contained in the Test-WWW-Selenium-CGIApp distribution.

Index


Code Index:

NAME

Top

Test::WWW::Selenium::CGIApp - Test your CGIApp application with Selenium

DEVELOPER RELEASE

Top

This is a test release. It depends on a Java application (SeleniumRC), which can be unreliable. The API is still subject to change in incompatible ways in future versions.

Please report any problems to RT, the CGIApp mailing list, or the #cgiapp IRC channel on irc.perl.org. Thanks!

SYNOPSIS

Top

    use Test::WWW::Selenium::CGIApp 'MyApp';
    use Test::More tests => 2;

    my $sel = Test::WWW::Selenium::CGIApp->start; 
    $sel->open_ok('/');
    $sel->is_text_present_ok('Welcome to MyApp');

USE CASES

Top

This module could be helpful if you want to test a CGI::Application based project with Selenium and you don't want to involve a traditional web server such as Apache. It could be useful when working offline or on a personal desktop.

If you would rather test the application through a web-server, using Test::WWW::Selenium would be a better choice.

TECHNICAL OVERVIEW

Top

This module starts the SeleniumRC server and your CGIApp app so that you can test it with SeleniumRC. Once you've called Test::WWW::Selenium::CGIApp->start, everything is just like Test::WWW::Selenium|Test::WWW:Selenium.

METHODS

Top

start()

    my $sel = Test::WWW::Selenium::CGIApp->start(
        browser => "*firefox /usr/lib/firefox/firefox-bin",  # defaults to '*firefox'
    );




Starts the Selenium and CGIApp servers, and returns a pre-initialized, ready-to-use Test::WWW::Selenium object. Extra args are passed to Test::WWW::Selenium->new();

[NOTE] The selenium server is actually started when you use this module, and it's killed when your test exits.

sel_pid()

Returns the process ID of the Selenium Server.

app_pid()

Returns the process ID of the CGIApp server.

ENVIRONMENT

Top

Debugging messages are shown if TWS_DEBUG is set;

LIMITATIONS / TODOs

Top

* This module is a fork of Test::WWW::Selenium::Catalyst, but shares a lot of code. It would be nice if they more directly shared part of the same code base.

* Having more default settings for launching various browsers on different OSes would be nice. (And something that could be shared with Catalyst!)

* This module currently only supports dispatching through CGI::Application::Dispatch. It could be useful to support other styles.

DIAGNOSTICS

Top

Specify your app's name

You need to pass your app's module name as the argument to the use statement:

    use Test::WWW::Selenium::CGIApp 'MyApp';

MyApp is the module name of your App.

SEE ALSO

Top

*

Selenium website: http://www.openqa.org/

*

Description of what you can do with the $sel object: Test::WWW::Selenium

*

If you don't need a real web browser: Test::WWW::Mechanize::CGIApp

AUTHOR

Top

Mark Stosberg, <mark at summersault.com>

BUGS

Top

Please report any bugs or feature requests to bug-test-www-selenium-cgiapp at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-WWW-Selenium-CGIApp. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

ACKNOWLEDGEMENTS

Top

Thanks for Test::WWW::Selenium::Catalyst, which provided most of the code for this.

COPYRIGHT & LICENSE

Top


Test-WWW-Selenium-CGIApp documentation Contained in the Test-WWW-Selenium-CGIApp distribution.
package Test::WWW::Selenium::CGIApp;

use warnings;
use strict;
use Carp;
use Alien::SeleniumRC;
use Test::WWW::Selenium;
use Test::More;

local $SIG{CHLD} = 'IGNORE';

our $DEBUG = $ENV{TWS_DEBUG} || 0;
my $app; # app name (MyApp)
my $sel_pid; # pid of selenium server
my $app_pid; # pid of myapp server

our $VERSION = '0.10';


sub _start_server {
    # 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;
    }
    $sel_pid = $pid;
}

sub sel_pid { return $sel_pid }
sub app_pid { return $app_pid }

sub import {
    my ($class, $appname) = @_;
    croak q{Specify your app's name} if !$appname;
    $app = $appname;
    
    _start_server() or croak "Couldn't start selenium server";
    return 1;
}

sub start {
    my $class = shift;
    my %args  = @_;
    
    # start a CGIApp MyApp server
    eval("use $app");
    croak "Couldn't load $app: $@" if $@;
    
    my $pid;
    if(0 == ($pid = fork())){
	local $SIG{TERM} = sub {
	    diag("App server $$ going down (TERM)") if $DEBUG;
	    exit 0;
	};
	diag("App server running in $$") if $DEBUG;

    use CGI::Application::Dispatch::Server;
    CGI::Application::Dispatch::Server->new(
        port     => 3000,
        class    => $app,
        #    root_dir => '/home/mark/Documents/Summersault/hseller/alphasite/www',       
        root_dir => '/home/mark/Desktop',
    )->run;
	exit 1;
    }
    $app_pid = $pid;
    
    my $tries = 5;
    my $error;
    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     => '*firefox',
                browser_url => 'http://localhost:3000/',
                %args,
            );
        };
        $error = $@;
    }
    
    eval { $sel->start };
      croak "Can't start selenium: $@ (error from Test::WWW::Selenium->new(): $error)" if $@;
    
    return $sel;
}

END {
    if($sel_pid){
	diag("Killing Selenium Server $sel_pid") if $DEBUG;
	kill 15, $sel_pid or diag "Killing Selenium: $!";
	undef $sel_pid;
    }
    if($app_pid){
	diag("Killing application server $app_pid") if $DEBUG;
	kill 15, $app_pid or diag "Killing MyApp: $!";
	undef $app_pid;
    }
    diag("Waiting for forked processes to die") if $DEBUG;
    waitpid $sel_pid, 0 if $sel_pid;
    waitpid $app_pid, 0 if $app_pid;
}

1;