Explorar el Código

Initial commit for bindings

Aditya Ivaturi hace 16 años
commit
6406864371
Se han modificado 16 ficheros con 862 adiciones y 0 borrados
  1. 5 0
      .includepath
  2. 17 0
      .project
  3. 5 0
      Changes
  4. 9 0
      MANIFEST
  5. 19 0
      Makefile.PL
  6. 56 0
      README
  7. 8 0
      driver-example.pl
  8. 12 0
      ignore.txt
  9. 283 0
      lib/Selenium/Remote/Commands.pm
  10. 218 0
      lib/Selenium/Remote/Driver.pm
  11. 122 0
      lib/Selenium/Remote/RemoteConnection.pm
  12. 10 0
      t/00-load.t
  13. 55 0
      t/boilerplate.t
  14. 13 0
      t/manifest.t
  15. 18 0
      t/pod-coverage.t
  16. 12 0
      t/pod.t

+ 5 - 0
.includepath

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<includepath>
+  <includepathentry path="${resource_loc:/Selenium-Remote-Driver/lib}" />
+</includepath>
+

+ 17 - 0
.project

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Selenium-Remote-Driver</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.epic.perleditor.perlbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.epic.perleditor.perlnature</nature>
+	</natures>
+</projectDescription>

+ 5 - 0
Changes

@@ -0,0 +1,5 @@
+Revision history for Selenium-Remote-Driver
+
+0.01    Date/time
+        First version, released on an unsuspecting world.
+

+ 9 - 0
MANIFEST

@@ -0,0 +1,9 @@
+Changes
+MANIFEST
+Makefile.PL
+README
+lib/Selenium/Remote/Driver.pm
+t/00-load.t
+t/manifest.t
+t/pod-coverage.t
+t/pod.t

+ 19 - 0
Makefile.PL

@@ -0,0 +1,19 @@
+use inc::Module::Install;
+
+name     'Selenium-Remote-Driver';
+all_from 'lib/Selenium/Remote/Driver.pm';
+author   q{"Aditya Ivaturi" <"ivaturi@gmail.com">};
+license  'perl';
+
+build_requires 'Test::More';
+build_requires 'LWP::UserAgent';
+build_requires 'HTTP::Headers';
+build_requires 'HTTP::Request';
+build_requires 'Carp';
+build_requires 'JSON';
+build_requires 'String::TT';
+
+auto_install;
+
+WriteAll;
+

+ 56 - 0
README

@@ -0,0 +1,56 @@
+Perl Bindings for Selenium 2.0 Remote Driver
+
+This is a very early (read alpha) work of Perl Bindings for Selenium 
+2.0 bindings. This binding will not work with the 1.0 version of 
+Selenium. Please use WWW::Selenium from CPAN if you're interested in
+1.0 bindings. 
+
+The wire protocol is going to change soon in Selenium remote server
+implementation & this code is currently only going to work with 
+alpha1 release of Selenium Remote Server. 
+
+Some of the code & most of the test suites are pretty much boiler 
+plate, so if you really want to play with bleeding edge code, download 
+the code & play with it.
+
+INSTALLATION
+
+To install this module, run the following commands:
+
+	perl Makefile.PL
+	make
+	make test
+	make install
+
+SUPPORT AND DOCUMENTATION
+
+After installing, you can find documentation for this module with the
+perldoc command.
+
+    perldoc Selenium::Remote::Driver
+
+You can also look for information at:
+
+    RT, CPAN's request tracker
+        http://rt.cpan.org/NoAuth/Bugs.html?Dist=Selenium-Remote-Driver
+
+    AnnoCPAN, Annotated CPAN documentation
+        http://annocpan.org/dist/Selenium-Remote-Driver
+
+    CPAN Ratings
+        http://cpanratings.perl.org/d/Selenium-Remote-Driver
+
+    Search CPAN
+        http://search.cpan.org/dist/Selenium-Remote-Driver/
+
+
+LICENSE AND COPYRIGHT
+
+Copyright (C) 2010 "Aditya Ivaturi"
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of either: the GNU General Public License as published
+by the Free Software Foundation; or the Artistic License.
+
+See http://dev.perl.org/licenses/ for more information.
+

+ 8 - 0
driver-example.pl

@@ -0,0 +1,8 @@
+use Selenium::Remote::Driver;
+
+#my $driver = new Selenium::Remote::Driver;
+my $driver = new Selenium::Remote::Driver(browser_name => 'internet explorer',
+                                          platform => 'WINDOWS');
+$driver->get("http://www.google.com");
+print $driver->get_title();
+$driver->quit();

+ 12 - 0
ignore.txt

@@ -0,0 +1,12 @@
+blib*
+Makefile
+Makefile.old
+Build
+Build.bat
+_build*
+pm_to_blib*
+*.tar.gz
+.lwpcookies
+cover_db
+pod2htm*.tmp
+Selenium-Remote-Driver-*

+ 283 - 0
lib/Selenium/Remote/Commands.pm

@@ -0,0 +1,283 @@
+package Selenium::Remote::Commands;
+
+use strict;
+use warnings;
+
+use String::TT qw/tt/;
+
+sub new {
+    my $class = shift;
+    my $self = {
+        'addCookie' => {
+                        'method' => 'POST',
+                        'url' => "session/[% session_id %]/[% context %]/cookie"
+        },
+        'goBack' => {
+                      'method' => 'POST',
+                      'url'    => "session/[% session_id %]/[% context %]/back"
+        },
+        'clearElement' => {
+               'method' => 'POST',
+               'url' =>
+                 "session/[% session_id %]/[% context %]/element/[% id %]/clear"
+        },
+        'clickElement' => {
+               'method' => 'POST',
+               'url' =>
+                 "session/[% session_id %]/[% context %]/element/[% id %]/click"
+        },
+        'close' => {
+                     'method' => 'DELETE',
+                     'url'    => "session/[% session_id %]/[% context %]/window"
+        },
+        'getCurrentUrl' => {
+                           'method' => 'GET',
+                           'url' => "session/[% session_id %]/[% context %]/url"
+        },
+        'deleteAllCookies' => {
+                        'method' => 'DELETE',
+                        'url' => "session/[% session_id %]/[% context %]/cookie"
+        },
+        'deleteCookie' => {
+             'method' => 'DELETE',
+             'url' => "session/[% session_id %]/[% context %]/cookie/[% name %]"
+        },
+        'dragElement' => {
+                'method' => 'POST',
+                'url' =>
+                  "session/[% session_id %]/[% context %]/element/[% id %]/drag"
+        },
+        'elementEquals' => {
+            'method' => 'GET',
+            'url' =>
+"session/[% session_id %]/[% context %]/element/[% id %]/equals/[% other %]"
+        },
+        'executeScript' => {
+                       'method' => 'POST',
+                       'url' => "session/[% session_id %]/[% context %]/execute"
+        },
+        'findElement' => {
+                       'method' => 'POST',
+                       'url' => "session/[% session_id %]/[% context %]/element"
+        },
+        'findElements' => {
+                      'method' => 'POST',
+                      'url' => "session/[% session_id %]/[% context %]/elements"
+        },
+        'findChildElement' => {
+            'method' => 'POST',
+            'url' =>
+"session/[% session_id %]/[% context %]/element/[% id %]/element/[% using %]"
+        },
+        'findChildElements' => {
+            'method' => 'POST',
+            'url' =>
+"session/[% session_id %]/[% context %]/element/[% id %]/elements/[% using %]"
+        },
+        'goForward' => {
+                       'method' => 'POST',
+                       'url' => "session/[% session_id %]/[% context %]/forward"
+        },
+        'get' => {
+                   'method' => 'POST',
+                   'url'    => "session/[% session_id %]/[% context %]/url"
+        },
+        'getActiveElement' => {
+                'method' => 'POST',
+                'url' => "session/[% session_id %]/[% context %]/element/active"
+        },
+        'getAllCookies' => {
+                        'method' => 'GET',
+                        'url' => "session/[% session_id %]/[% context %]/cookie"
+        },
+        'getCurrentWindowHandle' => {
+                 'method' => 'GET',
+                 'url' => "session/[% session_id %]/[% context %]/window_handle"
+        },
+        'getElementAttribute' => {
+            'method' => 'GET',
+            'url' =>
+"session/[% session_id %]/[% context %]/element/[% id %]/attribute/[% name %]"
+        },
+        'getElementLocation' => {
+            'method' => 'GET',
+            'url' =>
+              "session/[% session_id %]/[% context %]/element/[% id %]/location"
+        },
+        'getElementSize' => {
+                'method' => 'GET',
+                'url' =>
+                  "session/[% session_id %]/[% context %]/element/[% id %]/size"
+        },
+        'getElementText' => {
+                'method' => 'GET',
+                'url' =>
+                  "session/[% session_id %]/[% context %]/element/[% id %]/text"
+        },
+        'getElementValue' => {
+               'method' => 'GET',
+               'url' =>
+                 "session/[% session_id %]/[% context %]/element/[% id %]/value"
+        },
+        'getSpeed' => {
+                        'method' => 'GET',
+                        'url' => "session/[% session_id %]/[% context %]/speed"
+        },
+        'getElementTagName' => {
+                'method' => 'GET',
+                'url' =>
+                  "session/[% session_id %]/[% context %]/element/[% id %]/name"
+        },
+        'getTitle' => {
+                        'method' => 'GET',
+                        'url' => "session/[% session_id %]/[% context %]/title"
+        },
+        'getElementValueOfCssProperty' => {
+            'method' => 'GET',
+            'url' =>
+"session/[% session_id %]/[% context %]/element/[% id %]/css/[% property_name %]"
+        },
+        'getVisible' => {
+                       'method' => 'GET',
+                       'url' => "session/[% session_id %]/[% context %]/visible"
+        },
+        'getWindowHandles' => {
+                'method' => 'GET',
+                'url' => "session/[% session_id %]/[% context %]/window_handles"
+        },
+        'hoverOverElement' => {
+               'method' => 'POST',
+               'url' =>
+                 "session/[% session_id %]/[% context %]/element/[% id %]/hover"
+        },
+        'isElementDisplayed' => {
+            'method' => 'GET',
+            'url' =>
+"session/[% session_id %]/[% context %]/element/[% id %]/displayed"
+        },
+        'isElementEnabled' => {
+             'method' => 'GET',
+             'url' =>
+               "session/[% session_id %]/[% context %]/element/[% id %]/enabled"
+        },
+        'isElementSelected' => {
+            'method' => 'GET',
+            'url' =>
+              "session/[% session_id %]/[% context %]/element/[% id %]/selected"
+        },
+        'newSession' => {
+                          'method' => 'POST',
+                          'url'    => 'session'
+        },
+        'getPageSource' => {
+                        'method' => 'GET',
+                        'url' => "session/[% session_id %]/[% context %]/source"
+        },
+        'quit' => {
+                    'method' => 'DELETE',
+                    'url'    => "session/[% session_id %]"
+        },
+        'refresh' => {
+                       'method' => 'POST',
+                       'url' => "session/[% session_id %]/[% context %]/refresh"
+        },
+        'screenshot' => {
+                    'method' => 'GET',
+                    'url' => "session/[% session_id %]/[% context %]/screenshot"
+        },
+        'sendKeysToElement' => {
+               'method' => 'POST',
+               'url' =>
+                 "session/[% session_id %]/[% context %]/element/[% id %]/value"
+        },
+        'setElementSelected' => {
+            'method' => 'POST',
+            'url' =>
+              "session/[% session_id %]/[% context %]/element/[% id %]/selected"
+        },
+        'setSpeed' => {
+                        'method' => 'POST',
+                        'url' => "session/[% session_id %]/[% context %]/speed"
+        },
+        'setVisible' => {
+                       'method' => 'POST',
+                       'url' => "session/[% session_id %]/[% context %]/visible"
+        },
+        'submitElement' => {
+              'method' => 'POST',
+              'url' =>
+                "session/[% session_id %]/[% context %]/element/[% id %]/submit"
+        },
+        'switchToFrame' => {
+                'method' => 'POST',
+                'url' => "session/[% session_id %]/[% context %]/frame/[% id %]"
+        },
+        'switchToWindow' => {
+             'method' => 'POST',
+             'url' => "session/[% session_id %]/[% context %]/window/[% name %]"
+        },
+        'toggleElement' => {
+              'method' => 'POST',
+              'url' =>
+                "session/[% session_id %]/[% context %]/element/[% id %]/toggle"
+        },
+    };
+
+    bless $self, $class or die "Can't bless $class: $!";
+    return $self;
+}
+
+# This method will replace the template & return
+sub getParams {
+    my ($self, $command, $args) = @_;
+    if (!(defined $args->{'session_id'})) {
+        return;
+    }
+    my $data = {};
+
+    # TT does lexical template replacement, so we need exact name of the vars.
+    my $session_id = $args->{'session_id'};
+    my $context = (defined $args->{'context'}) ? $args->{'context'} : 'context';
+    my $id      = $args->{'id'};
+    my $name    = $args->{'name'};
+    my $using   = $args->{'using'};
+
+    $data->{'method'} = $self->{$command}->{'method'};
+    $data->{'url'}    = tt $self->{$command}->{'url'};
+
+    return $data;
+}
+
+1;
+
+__END__
+
+=head1 SEE ALSO
+
+For more information about Selenium , visit the website at
+L<http://code.google.com/p/selenium/>.
+
+=head1 BUGS
+
+The Selenium issue tracking system is available online at
+L<http://code.google.com/p/selenium/issues/list>.
+
+=head1 AUTHOR
+
+Perl Bindings for Remote Driver by Aditya Ivaturi <ivaturi@gmail.com>
+
+=head1 LICENSE
+
+Copyright (c) 2010 Juniper Networks, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.

+ 218 - 0
lib/Selenium/Remote/Driver.pm

@@ -0,0 +1,218 @@
+package Selenium::Remote::Driver;
+
+use strict;
+use warnings;
+
+use Carp qw(croak);
+
+use Selenium::Remote::RemoteConnection;
+use Selenium::Remote::Commands;
+
+=head1 NAME
+
+Selenium::Remote::Driver - Perl Client for Selenium Remote Driver
+
+=cut
+
+=head1 SYNOPSIS
+
+    use Selenium::Remote::Driver;
+    
+    my $driver = new Selenium::Remote::Driver;
+    $driver->get("http://www.google.com");
+    print $driver->get_title();
+    $driver->quit();
+
+=cut
+
+=head1 DESCRIPTION
+
+Selenium is a test tool that allows you to write
+automated web application UI tests in any programming language against
+any HTTP website using any mainstream JavaScript-enabled browser. This module is
+an implementation of the Perl Bindings (client) for the Remote driver that
+Selenium provides. You can find bindings for other languages at this location:
+
+L<http://code.google.com/p/selenium/>
+
+This module sends commands directly to the Server using simple HTTP requests.
+Using this module together with the Selenium Server, you can automatically
+control any supported browser.
+
+To use this module, you need to have already downloaded and started
+the Selenium Server.  (The Selenium Server is a Java application.)
+
+=cut
+
+sub new {
+    my ($class, %args) = @_;
+    my $commands = new Selenium::Remote::Commands;
+
+    # Set the defaults if user doesn't send any
+    my $self = {
+          remote_server_addr => delete $args{remote_server_addr} || 'localhost',
+          browser_name       => delete $args{browser_name}       || 'firefox',
+          platform           => delete $args{platform}           || 'ANY',
+          port               => delete $args{port}               || '4444',
+          javascript         => delete $args{javascript}         || JSON::true,
+          version            => delete $args{version}            || '',
+          session_id         => undef,
+          remote_conn        => undef,
+          commands           => $commands,
+    };
+    bless $self, $class or die "Can't bless $class: $!";
+
+    # Connect to remote server & establish a new session
+    $self->{remote_conn} =
+      new Selenium::Remote::RemoteConnection($self->{remote_server_addr},
+                                             $self->{port});
+    $self->new_session();
+
+    if (!(defined $self->{session_id})) {
+        croak "Could not establish a session with the remote server\n";
+    }
+
+    return $self;
+}
+
+# When a command is processed by the remote server & a result is sent back, it
+# also includes other relevant info. We strip those & just return the value we're
+# interested in.
+sub _get_command_result {
+    my ($self, @args) = @_;
+    my $resp = $self->{remote_conn}->request(@args);
+    if (defined $resp->{'value'}) {
+        return $resp->{'value'};
+    }
+    else {
+        return;
+    }
+}
+
+sub new_session {
+    my $self = shift;
+    my $args = {
+                 'browserName'       => $self->{browser_name},
+                 'platform'          => $self->{platform},
+                 'javascriptEnabled' => $self->{javascript},
+                 'version'           => $self->{version},
+    };
+    my $resp =
+      $self->{remote_conn}->request(
+                                  $self->{commands}->{'newSession'}->{'method'},
+                                  $self->{commands}->{'newSession'}->{'url'},
+                                  $args,
+      );
+    if ((defined $resp->{'sessionId'}) && $resp->{'sessionId'} ne '') {
+        $self->{session_id} = $resp->{'sessionId'};
+    }
+}
+
+sub quit {
+    my $self = shift;
+
+    my $args = { 'session_id' => $self->{'session_id'}, };
+    my $data = $self->{commands}->getParams('quit', $args);
+
+    if ($data) {
+        $self->{remote_conn}->request($data->{'method'}, $data->{'url'});
+    }
+    else {
+        croak "Couldn't retrieve command settings properly\n";
+    }
+}
+
+sub navigate {
+    my ($self, $url) = @_;
+    $self->get($url);
+}
+
+sub get {
+    my ($self, $url) = @_;
+    my $command = 'get';
+    my $args    = { 'session_id' => $self->{'session_id'}, };
+    my $data    = $self->{commands}->getParams($command, $args);
+
+    if ($data) {
+        $self->{remote_conn}->request($data->{'method'}, $data->{'url'}, $url);
+    }
+    else {
+        croak "Couldn't retrieve command $command settings\n";
+    }
+}
+
+sub get_title {
+    my $self    = shift;
+    my $command = 'getTitle';
+    my $args    = { 'session_id' => $self->{'session_id'}, };
+    my $data    = $self->{commands}->getParams($command, $args);
+
+    if ($data) {
+        return $self->_get_command_result($data->{'method'}, $data->{'url'});
+    }
+    else {
+        croak "Couldn't retrieve command $command settings\n";
+    }
+}
+
+sub go_back {
+    my $self    = shift;
+    my $command = 'goBack';
+    my $args    = { 'session_id' => $self->{'session_id'}, };
+    my $data    = $self->{commands}->getParams($command, $args);
+
+    if ($data) {
+        $self->{remote_conn}->request($data->{'method'}, $data->{'url'});
+    }
+    else {
+        croak "Couldn't retrieve command $command settings\n";
+    }
+}
+
+sub go_forward {
+    my $self    = shift;
+    my $command = 'goForward';
+    my $args    = { 'session_id' => $self->{'session_id'}, };
+    my $data    = $self->{commands}->getParams($command, $args);
+
+    if ($data) {
+        $self->{remote_conn}->request($data->{'method'}, $data->{'url'});
+    }
+    else {
+        croak "Couldn't retrieve command $command settings\n";
+    }
+}
+
+1;
+
+__END__
+
+=head1 SEE ALSO
+
+For more information about Selenium , visit the website at
+L<http://code.google.com/p/selenium/>.
+
+=head1 BUGS
+
+The Selenium issue tracking system is available online at
+L<http://code.google.com/p/selenium/issues/list>.
+
+=head1 AUTHOR
+
+Perl Bindings for Remote Driver by Aditya Ivaturi <ivaturi@gmail.com>
+
+=head1 LICENSE
+
+Copyright (c) 2010 Juniper Networks, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.

+ 122 - 0
lib/Selenium/Remote/RemoteConnection.pm

@@ -0,0 +1,122 @@
+package Selenium::Remote::RemoteConnection;
+
+use strict;
+use warnings;
+
+use LWP::UserAgent;
+use HTTP::Headers;
+use HTTP::Request;
+use Carp qw(croak);
+use JSON;
+#use Data::Dumper;
+
+sub new {
+    my ($class, $remote_srvr, $port) = @_;
+    
+    my $self = {
+                 remote_server_addr => $remote_srvr,
+                 port               => $port,
+    };
+    bless $self, $class or die "Can't bless $class: $!";
+    
+    # Add extra code to ping the remote server to see if it is alive.
+
+    return $self;
+}
+
+sub request {
+    my ($self, $method, $url, $params) = @_;
+    my $content = '';
+    my $fullurl = '';
+
+    # Construct full url.
+    if ($url =~ m/^http/g) {
+        $fullurl = $url;
+    }
+    else {
+        $fullurl =
+            "http://"
+          . $self->{remote_server_addr} . ":"
+          . $self->{port}
+          . "/wd/hub/$url";
+    }
+
+    #print "Full URL: $fullurl\n";
+
+    if ((defined $params) && $params ne '') {
+        my $json = new JSON;
+        $content = "[" . $json->allow_nonref->utf8->encode($params) . "]";
+    }
+
+    # HTTP request
+    my $ua = LWP::UserAgent->new;
+    my $header =
+      HTTP::Headers->new(Content_Type => 'application/json; charset=utf-8');
+    $header->header('Accept' => 'application/json');
+    my $request = HTTP::Request->new($method, $fullurl, $header, $content);
+    my $response = $ua->request($request);
+
+    #return $response;
+    return $self->_process_response($response);
+}
+
+sub _process_response {
+    my ($self, $response) = @_;
+    my $data = "";    #returned data from server
+
+    if ($response->is_redirect) {
+        return $self->request('GET', $response->header('location'));
+    }
+    elsif (($response->is_success) && ($response->code == 200)) {
+        $data = from_json($response->content);
+        if ($data->{'error'} eq 'true') {
+            croak "Error occurred in server while processing request: $data";
+        }
+        return $data;
+    }
+    elsif (   ($response->is_success)
+           && (($response->code == 200) || ($response->code == 204))) {
+
+        # Nothing to do.
+    }
+    elsif ($response->code == 404) {
+        croak "No such command.";
+    }
+    else {
+        croak "Remote server error with status = " . $response->code;
+    }
+}
+
+1;
+
+__END__
+
+=head1 SEE ALSO
+
+For more information about Selenium , visit the website at
+L<http://code.google.com/p/selenium/>.
+
+=head1 BUGS
+
+The Selenium issue tracking system is available online at
+L<http://code.google.com/p/selenium/issues/list>.
+
+=head1 AUTHOR
+
+Perl Bindings for Remote Driver by Aditya Ivaturi <ivaturi@gmail.com>
+
+=head1 LICENSE
+
+Copyright (c) 2010 Juniper Networks, Inc
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.

+ 10 - 0
t/00-load.t

@@ -0,0 +1,10 @@
+#!perl -T
+
+use Test::More tests => 1;
+
+BEGIN {
+    use_ok( 'Selenium::Remote::Driver' ) || print "Bail out!
+";
+}
+
+diag( "Testing Selenium::Remote::Driver $Selenium::Remote::Driver::VERSION, Perl $], $^X" );

+ 55 - 0
t/boilerplate.t

@@ -0,0 +1,55 @@
+#!perl -T
+
+use strict;
+use warnings;
+use Test::More tests => 3;
+
+sub not_in_file_ok {
+    my ($filename, %regex) = @_;
+    open( my $fh, '<', $filename )
+        or die "couldn't open $filename for reading: $!";
+
+    my %violated;
+
+    while (my $line = <$fh>) {
+        while (my ($desc, $regex) = each %regex) {
+            if ($line =~ $regex) {
+                push @{$violated{$desc}||=[]}, $.;
+            }
+        }
+    }
+
+    if (%violated) {
+        fail("$filename contains boilerplate text");
+        diag "$_ appears on lines @{$violated{$_}}" for keys %violated;
+    } else {
+        pass("$filename contains no boilerplate text");
+    }
+}
+
+sub module_boilerplate_ok {
+    my ($module) = @_;
+    not_in_file_ok($module =>
+        'the great new $MODULENAME'   => qr/ - The great new /,
+        'boilerplate description'     => qr/Quick summary of what the module/,
+        'stub function definition'    => qr/function[12]/,
+    );
+}
+
+TODO: {
+  local $TODO = "Need to replace the boilerplate text";
+
+  not_in_file_ok(README =>
+    "The README is used..."       => qr/The README is used/,
+    "'version information here'"  => qr/to provide version information/,
+  );
+
+  not_in_file_ok(Changes =>
+    "placeholder date/time"       => qr(Date/time)
+  );
+
+  module_boilerplate_ok('lib/Selenium/Remote/Driver.pm');
+
+
+}
+

+ 13 - 0
t/manifest.t

@@ -0,0 +1,13 @@
+#!perl -T
+
+use strict;
+use warnings;
+use Test::More;
+
+unless ( $ENV{RELEASE_TESTING} ) {
+    plan( skip_all => "Author tests not required for installation" );
+}
+
+eval "use Test::CheckManifest 0.9";
+plan skip_all => "Test::CheckManifest 0.9 required" if $@;
+ok_manifest();

+ 18 - 0
t/pod-coverage.t

@@ -0,0 +1,18 @@
+use strict;
+use warnings;
+use Test::More;
+
+# Ensure a recent version of Test::Pod::Coverage
+my $min_tpc = 1.08;
+eval "use Test::Pod::Coverage $min_tpc";
+plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
+    if $@;
+
+# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
+# but older versions don't recognize some common documentation styles
+my $min_pc = 0.18;
+eval "use Pod::Coverage $min_pc";
+plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
+    if $@;
+
+all_pod_coverage_ok();

+ 12 - 0
t/pod.t

@@ -0,0 +1,12 @@
+#!perl -T
+
+use strict;
+use warnings;
+use Test::More;
+
+# Ensure a recent version of Test::Pod
+my $min_tp = 1.22;
+eval "use Test::Pod $min_tp";
+plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
+
+all_pod_files_ok();