Bugzilla – Attachment 41156 Details for
Bug 14536
PageObject-pattern base implementation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14536 - PageObject-pattern base implementation
Bug-14536---PageObject-pattern-base-implementation.patch (text/plain), 31.75 KB, created by
Olli-Antti Kivilahti
on 2015-07-24 14:03:14 UTC
(
hide
)
Description:
Bug 14536 - PageObject-pattern base implementation
Filename:
MIME Type:
Creator:
Olli-Antti Kivilahti
Created:
2015-07-24 14:03:14 UTC
Size:
31.75 KB
patch
obsolete
>From ad9195ad3a5e142d604bdc80680151a06f0b9d3d Mon Sep 17 00:00:00 2001 >From: Olli-Antti Kivilahti <olli-antti.kivilahti@jns.fi> >Date: Fri, 10 Jul 2015 11:06:53 +0000 >Subject: [PATCH] Bug 14536 - PageObject-pattern base implementation > >This patch introduces: > >-PageObject base classes for OPAC and Intra, and example tests. More example tests > in Buugg 14540, where setting test context is easier. >-a interactive debug script to drive PageObjects more easily. > >------------------ >PageObjects are used to make robust and reusable integration test components to >test various front-end features. PageObjects load a Selenium::Remote::Driver >implementation, phantomjs by default and use this to do scripted user actions >in the browser, >eg. clicking HTML-elements, accepting popup dialogs, entering text to input >fields. > >PageObjects encapsulate those very low-level operations into clear and easily >usable actions or services, like doPasswordLogin(). >PageObjects also seamlessly deal with navigation from one page to another, eg. > my $mainpage = t::lib::Page::Mainpage->new(); > $mainpage->doPasswordLogin('admin', '1234')->gotoPatrons()-> > searchPatrons({keywordSearch => "Jane Doe"}); > >PageObjects make doing integration tests so great! >You can google for the specifics of PageObject patterns and there are a ton of >great tutorials explaining their function. > >Now PageObjects also have a debugging system where you can get the server >response in a title+cookies+html-dump and a screenshot of the browser session. >see t::lib::Page for more info! > >--------------------- >Interactive debugger at misc/devel/interactiveWebDriverShell.pl loads the >desired PageObject with the needed parameters to the debugger context and makes >dynamic UserAgent scripting easy and fun! >--- > misc/devel/interactiveWebDriverShell.pl | 190 +++++++++++++++++++++ > t/db_dependent/Koha/Auth.t | 72 ++++++++ > t/lib/Page.pm | 287 ++++++++++++++++++++++++++++++++ > t/lib/Page/Intra.pm | 106 ++++++++++++ > t/lib/Page/Mainpage.pm | 45 +++++ > t/lib/Page/Opac.pm | 100 +++++++++++ > t/lib/Page/Opac/OpacMain.pm | 60 +++++++ > 7 files changed, 860 insertions(+) > create mode 100755 misc/devel/interactiveWebDriverShell.pl > create mode 100644 t/db_dependent/Koha/Auth.t > create mode 100644 t/lib/Page.pm > create mode 100644 t/lib/Page/Intra.pm > create mode 100644 t/lib/Page/Mainpage.pm > create mode 100644 t/lib/Page/Opac.pm > create mode 100644 t/lib/Page/Opac/OpacMain.pm > >diff --git a/misc/devel/interactiveWebDriverShell.pl b/misc/devel/interactiveWebDriverShell.pl >new file mode 100755 >index 0000000..fdd5eb5 >--- /dev/null >+++ b/misc/devel/interactiveWebDriverShell.pl >@@ -0,0 +1,190 @@ >+#!/usr/bin/perl -d >+ >+# Copyright 2015 KohaSuomi >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+=head1 NAME >+ >+interactiveWebDriverShell.pl >+ >+=head1 SYNOPSIS >+ >+ misc/devel/interactiveWebDriverShell.pl -p mainpage.pl >+ >+Prepares a perl debugger session with the requested PageObject loaded. >+Then you can easily guide the UserAgent through the web session. >+ >+=cut >+ >+use Modern::Perl; >+ >+use Getopt::Long qw(:config no_ignore_case); >+use Data::Dumper; >+ >+my ($help, $page, $list, @params, @login); >+ >+GetOptions( >+ "h|help" => \$help, >+ "p|page=s" => \$page, >+ "P|params=s{,}" => \@params, >+ "L|login=s{,}" => \@login, >+ "l|list" => \$list, >+); >+ >+my $help_msg = <<HELP; >+ >+interactiveWebDriverShell.pl >+ >+ Prepares a perl debugger session with the requested PageObject loaded. >+ Then you can easily guide the UserAgent through the web session. >+ >+ You should install Term::ReadLine::Gnu for a more pleasant debugging experience. >+ >+ -h --help This help! >+ >+ -p --page Which PageObject matching the given page you want to preload? >+ >+ -P --params List of parameters the PageObject must have. >+ >+ -L --login List of userid and password to automatically login to Koha. Eg: >+ ./interactiveWebDriverShell.pl -L admin 1234 -p members/moremember.pl -P 12 >+ >+ -l --list Lists available PageObjects and their matching --page -parameter >+ values. >+ >+EXAMPLE INVOCATIONS: >+ >+./interactiveWebDriverShell.pl -p mainpage.pl -L admin 1234 >+./interactiveWebDriverShell.pl -p members/moremember.pl -P 1 -L admin 1234 >+ >+USAGE: >+ >+Start the session from your shell >+ ..\$ misc/devel/interactiveWebDriverShell.pl -p mainpage.pl >+or >+Start the session from your shell with parameters >+ ..\$ misc/devel/interactiveWebDriverShell.pl -p members/moremember.pl -P 12 >+ >+Continue to the breakpoint set in this script >+ DB<1> c >+ >+The PageObject is bound to variable \$po, >+and the Selenium::Remote::Driver-implementation to \$d. >+Then all you need to do is start navigating the web! >+ DB<2> \$po->isPasswordLoginAvailable()->doPasswordLogin('admin','1234'); >+ >+ DB<3> \$ele = \$d->find_element('input[value="Save"]'); >+ >+Note! Do not use "my \$ele = 123;" in the debugger session, because that doesn't >+work as excepted, simply use "\$ele = 123;". >+ >+HELP >+ >+if ($help) { >+ print $help_msg; >+ exit; >+} >+unless ($page || $list) { >+ print $help_msg; >+ exit; >+} >+ >+my $supportedPageObjects = { >+################################################################################ >+ ########## STAFF CONFIGURATIONS ########## >+################################################################################ >+ 'mainpage.pl' => >+ { package => "t::lib::Page::Mainpage", >+ urlEndpoint => "mainpage.pl", >+ status => "OK", >+ params => "none", >+ }, >+ "members/moremember.pl" => >+ { package => "t::lib::Page::Members::Moremember", >+ urlEndpoint => "members/moremember.pl", >+ status => "not implemented", >+ params => ["borrowernumber"], >+ }, >+ "members/member-flags.pl" => >+ { package => "t::lib::Page::Members::MemberFlags", >+ urlEndpoint => "members/member-flags.pl", >+ status => "not implemented", >+ params => ["borrowernumber"], >+ }, >+################################################################################ >+ ########## OPAC CONFIGURATIONS ########## >+################################################################################ >+ "opac/opac-main.pl" => >+ { package => "t::lib::Page::Opac::OpacMain", >+ urlEndpoint => "opac/opac-main.pl", >+ status => "OK", >+ }, >+}; >+################################################################################ >+ ########## END OF PAGE CONFIGURATIONS ########## >+################################################################################ >+ >+listSupportedPageObjects ($supportedPageObjects) if $list; >+my ($po, $d) = deployPageObject($supportedPageObjects, $page, \@params, \@login) if $page; >+ >+ >+ >+print "--Debugging--\n"; >+$DB::single = 1; #Breakpoint here >+$DB::single = 1; >+ >+ >+ >+sub listSupportedPageObjects { >+ my ($supportedPageObjects) = @_; >+ print Data::Dumper::Dumper($supportedPageObjects); >+ exit; >+} >+sub deployPageObject { >+ my ($supportedPageObjects, $page, $params, $login) = @_; >+ >+ ##Find correct PageObject deployment rules >+ my $pageObjectMapping = $supportedPageObjects->{$page}; >+ die "No PageObject mapped to --page '$page'. See --list to list available PageObjects.\n" unless $pageObjectMapping; >+ >+ ##Dynamically load package >+ my $package = $pageObjectMapping->{package}; >+ eval "require $package"; >+ >+ ##Fill required parameters >+ my $poParams = {}; >+ if (ref($pageObjectMapping->{params}) eq 'ARRAY') { >+ foreach my $paramName (@{$pageObjectMapping->{params}}) { >+ $poParams->{$paramName} = shift(@$params); >+ die "Insufficient parameters given, parameter '$paramName' unsatisfied.\n" unless $poParams->{$paramName}; >+ } >+ } >+ >+ ##Check if the status is OK >+ die "PageObject status for '$page' is not 'OK'. Current status '".$pageObjectMapping->{status}."'.\nPlease implement the missing PageObject.\n" unless $pageObjectMapping->{status} eq 'OK'; >+ >+ ##Create PageObject >+ my $po = $package->new($poParams); >+ >+ ##Password login if desired >+ eval { >+ $po->isPasswordLoginAvailable->doPasswordLogin($login->[0], $login->[1]) if scalar(@$login); >+ }; if ($@) { >+ print "Password login unavailable.\n"; >+ } >+ >+ return ($po, $po->getDriver()); >+} >diff --git a/t/db_dependent/Koha/Auth.t b/t/db_dependent/Koha/Auth.t >new file mode 100644 >index 0000000..d9a1f2a >--- /dev/null >+++ b/t/db_dependent/Koha/Auth.t >@@ -0,0 +1,72 @@ >+#!/usr/bin/env perl >+ >+# Copyright 2015 Open Source Freedom Fighters >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Test::More; >+use Try::Tiny; #Even Selenium::Remote::Driver uses Try::Tiny :) >+ >+use t::lib::Page::Mainpage; >+ >+use t::db_dependent::TestObjects::Borrowers::BorrowerFactory; >+ >+##Setting up the test context >+my $testContext = {}; >+ >+my $password = '1234'; >+my $borrowerFactory = t::db_dependent::TestObjects::Borrowers::BorrowerFactory->new(); >+my $borrowers = $borrowerFactory->createTestGroup([ >+ {firstname => 'Olli-Antti', >+ surname => 'Kivi', >+ cardnumber => '1A01', >+ branchcode => 'CPL', >+ flags => '1', #superlibrarian, not exactly a very good way of doing permission testing? >+ userid => 'mini_admin', >+ password => $password, >+ }, >+ ], undef, $testContext); >+ >+##Test context set, starting testing: >+eval { #run in a eval-block so we don't die without tearing down the test context >+ >+ testPasswordLogin(); >+ >+}; >+if ($@) { #Catch all leaking errors and gracefully terminate. >+ warn $@; >+ tearDown(); >+ exit 1; >+} >+ >+##All tests done, tear down test context >+tearDown(); >+done_testing; >+ >+sub tearDown { >+ t::db_dependent::TestObjects::ObjectFactory->tearDownTestContext($testContext); >+} >+ >+###################################################### >+ ### STARTING TEST IMPLEMENTATIONS ### >+###################################################### >+ >+sub testPasswordLogin { >+ my $mainpage = t::lib::Page::Mainpage->new(); >+ $mainpage->isPasswordLoginAvailable()->doPasswordLogin($borrowers->{'1A01'}->{userid}, $password)->quit(); >+} >\ No newline at end of file >diff --git a/t/lib/Page.pm b/t/lib/Page.pm >new file mode 100644 >index 0000000..d81eb2e >--- /dev/null >+++ b/t/lib/Page.pm >@@ -0,0 +1,287 @@ >+package t::lib::Page; >+ >+# Copyright 2015 Open Source Freedom Fighters >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use Test::More; >+ >+use C4::Context; >+ >+use t::lib::WebDriverFactory; >+ >+use Koha::Exception::BadParameter; >+use Koha::Exception::SystemCall; >+ >+=head NAME t::lib::Page >+ >+=head SYNOPSIS >+ >+PageObject-pattern parent class. Extend this to implement specific pages shown to our users. >+ >+PageObjects are used to make robust and reusable integration test components to test >+various front-end features. PageObjects load a Selenium::Remote::Driver implementation, >+phantomjs by default and use this to do scripted user actions in the browser, >+eg. clicking HTML-elements, accepting popup dialogs, entering text to input fields. >+ >+PageObjects encapsulate those very low-level operations into clear and easily usable >+actions or services, like doPasswordLogin(). >+PageObjects also seamlessly deal with navigation from one page to another, eg. >+ my $mainpage = t::lib::Page::Mainpage->new(); >+ $mainpage->doPasswordLogin('admin', '1234')->gotoPatrons()-> >+ searchPatrons({keywordSearch => "Jane Doe"}); >+ >+=head Class variables >+ >+Selenium::Remote::Driver driver, contains the driver implementation used to run these tests >+t::Page::Common::Header header, the header page component (not implemented) >+t::Page::Common::Footer footer, the footer page component (not implemented) >+Scalar userInteractionDelay, How many milliseconds to wait for javascript >+ to stop processing by default after user actions? >+ >+=head DEBUGGING >+ >+Set Environment value >+ $ENV{KOHA_PAGEOBJECT_DEBUG} = 1; >+Before creating the first PageObject to enable debugging. >+Debugging output is written to /tmp/PageObjectDebug/ by default, but you can change it >+using the same environment variable >+ $ENV{KOHA_PAGEOBJECT_DEBUG} = "/tmp/generalDebugging/"; >+ >+=cut >+ >+sub new { >+ my ($class, $params) = @_; >+ $params = _mergeDefaultConfig($params); >+ >+ my $self = {}; >+ bless($self, $class); >+ unless ($params->{driver}) { >+ my ($driver) = t::lib::WebDriverFactory::getUserAgentDrivers({phantomjs => $params}); >+ $self->{driver} = $driver; >+ } >+ $self->{type} = $params->{type}; #This parameter is mandatory. _mergeDefaultConfig() dies without it. >+ $self->{resource} = $params->{resource} || '/'; >+ $self->{resource} .= "?".join('&', @{$params->{getParams}}) if $params->{getParams}; >+ $self->{header} = $params->{header} || undef; >+ $self->{footer} = $params->{footer} || undef; >+ >+ $self->{userInteractionDelay} = $params->{userInteractionDelay} || 500; >+ >+ $self->{driver}->set_window_size(1280, 960); >+ $self->{driver}->get( $self->{resource} ); >+ >+ $self->debugSetEnvironment(); #If debugging is enabled >+ >+ return $self; >+} >+ >+=head rebrandFromPageObject >+When we are getting redirected from one page to another we rebrand the existing PageObject >+as another PageObject to have the new page's services available. >+=cut >+ >+sub rebrandFromPageObject { >+ my ($class, $self) = @_; >+ bless($self, $class); >+ return $self; >+} >+ >+=head _mergeDefaultConfig >+ >+@THROWS Koha::Exception::BadParameter >+=cut >+ >+sub _mergeDefaultConfig { >+ my ($params) = @_; >+ unless (ref($params) eq 'HASH' && $params->{type}) { >+ Koha::Exception::BadParameter->throw(error => "t::lib::Page:> When instantiating Page-objects, you must define the 'type'-parameter."); >+ } >+ >+ my $testServerConfigs = C4::Context->config('testservers'); >+ my $conf = $testServerConfigs->{ $params->{type} }; >+ Koha::Exception::BadParameter->throw(error => "t::lib::Page:> Unknown 'type'-parameter '".$params->{type}."'. Values 'opac', 'staff' and 'rest' are supported.") >+ unless $conf; >+ #Merge given $params-config on top of the $KOHA_CONF's testservers-directives >+ @$conf{keys %$params} = values %$params; >+ return $conf; >+} >+ >+=head quit >+Wrapper for Selenium::Remote::Driver->quit(), >+Delete the session & close open browsers. >+ >+When ending this browser session, it is polite to quit, or there is a risk of leaving >+floating test browsers floating around. >+=cut >+ >+sub quit { >+ my ($self) = @_; >+ $self->getDriver()->quit(); >+} >+ >+=head pause >+Wrapper for Selenium::Remote::Driver->pause(), >+=cut >+ >+sub pause { >+ my ($self, $pauseMillis) = @_; >+ $self->getDriver()->pause($pauseMillis); >+ return $self; >+} >+ >+=head isPasswordLoginAvailable >+ >+ $page->isPasswordLoginAvailable(); >+ >+@RETURN t::lib::Page-object >+@CROAK if password login is unavailable. >+=cut >+ >+sub isPasswordLoginAvailable { >+ my $self = shift; >+ my $d = $self->getDriver(); >+ $self->debugTakeSessionSnapshot(); >+ >+ _getPasswordLoginElements($d); >+ ok(($d->get_title() =~ /Log in to Koha/), "PasswordLogin available"); >+ return $self; >+} >+ >+sub doPasswordLogin { >+ my ($self, $username, $password) = @_; >+ my $d = $self->getDriver(); >+ $self->debugTakeSessionSnapshot(); >+ >+ my ($submitButton, $useridInput, $passwordInput) = _getPasswordLoginElements($d); >+ $useridInput->send_keys($username); >+ $passwordInput->send_keys($password); >+ $submitButton->click(); >+ $self->debugTakeSessionSnapshot(); >+ >+ my $cookies = $d->get_all_cookies(); >+ my @cgisessid = grep {$_->{name} eq 'CGISESSID'} @$cookies; >+ >+ ok(($d->get_title() !~ /Log in to Koha/ && #No longer in the login page >+ $d->get_title() !~ /Access denied/ && >+ $cgisessid[0]) #Cookie CGISESSID defined! >+ , "PasswordLogin succeeded"); >+ >+ return $self; #After a succesfull password login, we are directed to the same page we tried to access. >+} >+ >+sub _getPasswordLoginElements { >+ my $d = shift; >+ my $submitButton = $d->find_element('#submit'); >+ my $useridInput = $d->find_element('#userid'); >+ my $passwordInput = $d->find_element('#password'); >+ return ($submitButton, $useridInput, $passwordInput); >+} >+ >+sub doPasswordLogout { >+ my ($self, $username, $password) = @_; >+ my $d = $self->getDriver(); >+ $self->debugTakeSessionSnapshot(); >+ >+ #Click the dropdown menu to make the logout-link visible >+ my $logged_in_identifierA = $d->find_element('#drop3'); #What a nice and descriptive HTML element name! >+ $logged_in_identifierA->click(); >+ >+ #Logout >+ my $logoutA = $d->find_element('#logout'); >+ $logoutA->click(); >+ >+ ok(($d->get_title() =~ /Log in to Koha/), "PasswordLogout succeeded"); >+ return $self; #After a succesfull password logout, we are still in the same page we did before logout. >+} >+ >+################################################ >+ ## INTRODUCING OBJECT ACCESSORS ## >+################################################ >+sub setDriver { >+ my ($self, $driver) = @_; >+ $self->{driver} = $driver; >+} >+sub getDriver { >+ my ($self) = @_; >+ return $self->{driver}; >+} >+ >+################################################ >+ ## INTRODUCING TESTING HELPERS ## >+################################################ >+sub debugSetEnvironment { >+ my ($self) = @_; >+ if ($ENV{KOHA_PAGEOBJECT_DEBUG}) { >+ $self->{debugSessionId} = sprintf("%03i",rand(999)); >+ $self->{debugSessionTmpDirectory} = "/tmp/PageObjectDebug/"; >+ $self->{debugSessionTmpDirectory} = $ENV{KOHA_PAGEOBJECT_DEBUG} if (not(ref($ENV{KOHA_PAGEOBJECT_DEBUG})) && length($ENV{KOHA_PAGEOBJECT_DEBUG}) > 1); >+ my $error = system(("mkdir", "-p", $self->{debugSessionTmpDirectory})); >+ Koha::Exception::SystemCall->throw(error => "Trying to create a temporary directory for PageObject debugging session '".$self->{debugSessionId}."' failed:\n $?") >+ if $error; >+ $self->{debugInternalCounter} = 1; >+ >+ print "\n\n--Starting PageObject debugging session '".$self->{debugSessionId}."'\n\n"; >+ } >+} >+ >+sub debugTakeSessionSnapshot { >+ my ($self) = @_; >+ if ($ENV{KOHA_PAGEOBJECT_DEBUG}) { >+ my ($actionIdentifier, $actionFile) = $self->_debugGetSessionIdentifier(2); >+ >+ $self->_debugWriteHTML($actionIdentifier, $actionFile); >+ $self->_debugWriteScreenshot($actionIdentifier, $actionFile); >+ $self->{debugInternalCounter}++; >+ } >+} >+ >+sub _debugGetSessionIdentifier { >+ my ($self, $callerDepth) = @_; >+ $callerDepth = $callerDepth || 2; >+ ##Create a unique and descriptive identifier for this program state. >+ my ($package, $filename, $line, $subroutine) = caller($callerDepth); #Get where we are called from >+ $subroutine = $2 if ($subroutine =~ /(::|->)([^:->]+)$/); #Get the last part of the package, the subroutine name. >+ my $actionIdentifier = "[session '".$self->{debugSessionId}."', counter '".sprintf("%03i",$self->{debugInternalCounter})."', caller '$subroutine']"; >+ my $actionFile = $self->{debugSessionId}.'_'.sprintf("%03i",$self->{debugInternalCounter}).'_'.$subroutine; >+ return ($actionIdentifier, $actionFile); >+} >+ >+sub _debugWriteHTML { >+ require Data::Dumper; >+ my ($self, $actionIdentifier, $actionFile) = @_; >+ my $d = $self->getDriver(); >+ >+ ##Write the current Response data >+ open(my $fh, ">:encoding(UTF-8)", $self->{debugSessionTmpDirectory}.$actionFile.'.html') >+ or die "Trying to open a filehandle for PageObject debugging output $actionIdentifier:\n $@"; >+ print $fh $d->get_title()."\n"; >+ print $fh "ALL COOKIES DUMP:\n".Data::Dumper::Dumper($d->get_all_cookies()); >+ print $fh $d->get_page_source()."\n"; >+ close $fh; >+} >+ >+sub _debugWriteScreenshot { >+ my ($self, $actionIdentifier, $actionFile) = @_; >+ my $d = $self->getDriver(); >+ >+ ##Write a screenshot of the view to file. >+ my $ok = $d->capture_screenshot($self->{debugSessionTmpDirectory}.$actionFile.'.png'); >+ Koha::Exception::SystemCall->throw(error => "Cannot capture a screenshot for PageObject $actionIdentifier") >+ unless $ok; >+} >+1; #Make the compiler happy! >\ No newline at end of file >diff --git a/t/lib/Page/Intra.pm b/t/lib/Page/Intra.pm >new file mode 100644 >index 0000000..da1308f >--- /dev/null >+++ b/t/lib/Page/Intra.pm >@@ -0,0 +1,106 @@ >+package t::lib::Page::Intra; >+ >+# Copyright 2015 Open Source Freedom Fighters >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use Test::More; >+ >+use C4::Context; >+ >+use t::lib::WebDriverFactory; >+ >+use Koha::Exception::BadParameter; >+use Koha::Exception::SystemCall; >+ >+use base qw(t::lib::Page); >+ >+=head NAME t::lib::Page::Intra >+ >+=head SYNOPSIS >+ >+PageObject-pattern parent class for Intranet-pages (staff client). Extend this to implement specific pages shown to our users. >+ >+=cut >+ >+=head isPasswordLoginAvailable >+ >+ $page->isPasswordLoginAvailable(); >+ >+@RETURN t::lib::Page-object >+@CROAK if password login is unavailable. >+=cut >+ >+sub isPasswordLoginAvailable { >+ my $self = shift; >+ my $d = $self->getDriver(); >+ $self->debugTakeSessionSnapshot(); >+ >+ _getPasswordLoginElements($d); >+ ok(($d->get_title() =~ /Log in to Koha/), "PasswordLogin available"); >+ return $self; >+} >+ >+sub doPasswordLogin { >+ my ($self, $username, $password) = @_; >+ my $d = $self->getDriver(); >+ $self->debugTakeSessionSnapshot(); >+ >+ my ($submitButton, $useridInput, $passwordInput) = _getPasswordLoginElements($d); >+ $useridInput->send_keys($username); >+ $passwordInput->send_keys($password); >+ $submitButton->click(); >+ $self->debugTakeSessionSnapshot(); >+ >+ my $cookies = $d->get_all_cookies(); >+ my @cgisessid = grep {$_->{name} eq 'CGISESSID'} @$cookies; >+ >+ ok(($d->get_title() !~ /Log in to Koha/ && #No longer in the login page >+ $d->get_title() !~ /Access denied/ && >+ $cgisessid[0]) #Cookie CGISESSID defined! >+ , "PasswordLogin succeeded"); >+ >+ return $self; #After a succesfull password login, we are directed to the same page we tried to access. >+} >+ >+sub _getPasswordLoginElements { >+ my $d = shift; >+ my $submitButton = $d->find_element('#submit'); >+ my $useridInput = $d->find_element('#userid'); >+ my $passwordInput = $d->find_element('#password'); >+ return ($submitButton, $useridInput, $passwordInput); >+} >+ >+sub doPasswordLogout { >+ my ($self, $username, $password) = @_; >+ my $d = $self->getDriver(); >+ $self->debugTakeSessionSnapshot(); >+ >+ #Click the dropdown menu to make the logout-link visible >+ my $logged_in_identifierA = $d->find_element('#drop3'); #What a nice and descriptive HTML element name! >+ $logged_in_identifierA->click(); >+ >+ #Logout >+ my $logoutA = $d->find_element('#logout'); >+ $logoutA->click(); >+ $self->debugTakeSessionSnapshot(); >+ >+ ok(($d->get_title() =~ /Log in to Koha/), "PasswordLogout succeeded"); >+ return $self; #After a succesfull password logout, we are still in the same page we did before logout. >+} >+ >+1; #Make the compiler happy! >\ No newline at end of file >diff --git a/t/lib/Page/Mainpage.pm b/t/lib/Page/Mainpage.pm >new file mode 100644 >index 0000000..2da4bf9 >--- /dev/null >+++ b/t/lib/Page/Mainpage.pm >@@ -0,0 +1,45 @@ >+package t::lib::Page::Mainpage; >+ >+# Copyright 2015 Open Source Freedom Fighters >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use base qw(t::lib::Page); >+ >+=head NAME t::lib::Page::Mainpage >+ >+=head SYNOPSIS >+ >+Mainpage PageObject providing page functionality as a service! >+ >+=cut >+ >+sub new { >+ my ($class, $params) = @_; >+ unless (ref($params) eq 'HASH') { >+ $params = {}; >+ } >+ $params->{resource} = '/cgi-bin/koha/mainpage.pl'; >+ $params->{type} = 'staff'; >+ my $self = $class->SUPER::new($params); >+ >+ return $self; >+} >+ >+ >+1; #Make the compiler happy! >\ No newline at end of file >diff --git a/t/lib/Page/Opac.pm b/t/lib/Page/Opac.pm >new file mode 100644 >index 0000000..5c0f7e1 >--- /dev/null >+++ b/t/lib/Page/Opac.pm >@@ -0,0 +1,100 @@ >+package t::lib::Page::Opac; >+ >+# Copyright 2015 Open Source Freedom Fighters >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use Test::More; >+ >+use C4::Context; >+ >+use t::lib::WebDriverFactory; >+ >+use Koha::Exception::BadParameter; >+use Koha::Exception::SystemCall; >+ >+use base qw(t::lib::Page); >+ >+=head NAME t::lib::Page::Opac >+ >+=head SYNOPSIS >+ >+PageObject-pattern parent class for OPAC-pages. Extend this to implement specific pages shown to our users. >+ >+=cut >+ >+=head isPasswordLoginAvailable >+ >+ $page->isPasswordLoginAvailable(); >+ >+@RETURN t::lib::Page-object >+@CROAK if password login is unavailable. >+=cut >+ >+sub isPasswordLoginAvailable { >+ my $self = shift; >+ my $d = $self->getDriver(); >+ $self->debugTakeSessionSnapshot(); >+ >+ _getPasswordLoginElements($d); >+ ok(1, "PasswordLogin available"); >+ return $self; >+} >+ >+sub doPasswordLogin { >+ my ($self, $username, $password) = @_; >+ my $d = $self->getDriver(); >+ $self->debugTakeSessionSnapshot(); >+ >+ my ($submitButton, $useridInput, $passwordInput) = _getPasswordLoginElements($d); >+ $useridInput->send_keys($username); >+ $passwordInput->send_keys($password); >+ $submitButton->click(); >+ $self->debugTakeSessionSnapshot(); >+ >+ my $cookies = $d->get_all_cookies(); >+ my @cgisessid = grep {$_->{name} eq 'CGISESSID'} @$cookies; >+ >+ my $loggedinusernameSpan = $d->find_element('span.loggedinusername'); >+ ok(($cgisessid[0]), "PasswordLogin succeeded"); #We have the element && Cookie CGISESSID defined! >+ >+ return $self; #After a succesfull password login, we are directed to the same page we tried to access. >+} >+ >+sub _getPasswordLoginElements { >+ my $d = shift; >+ my $submitButton = $d->find_element('form#auth input[value="Log in"]'); >+ my $useridInput = $d->find_element('#userid'); >+ my $passwordInput = $d->find_element('#password'); >+ return ($submitButton, $useridInput, $passwordInput); >+} >+ >+sub doPasswordLogout { >+ my ($self, $username, $password) = @_; >+ my $d = $self->getDriver(); >+ $self->debugTakeSessionSnapshot(); >+ >+ #Logout >+ my $logoutA = $d->find_element('#logout'); >+ $logoutA->click(); >+ $self->debugTakeSessionSnapshot(); >+ >+ ok(($d->get_title() =~ /Log in to your account/), "PasswordLogout succeeded"); >+ return $self; #After a succesfull password logout, we are still in the same page we did before logout. >+} >+ >+1; #Make the compiler happy! >\ No newline at end of file >diff --git a/t/lib/Page/Opac/OpacMain.pm b/t/lib/Page/Opac/OpacMain.pm >new file mode 100644 >index 0000000..33c67af >--- /dev/null >+++ b/t/lib/Page/Opac/OpacMain.pm >@@ -0,0 +1,60 @@ >+package t::lib::Page::Opac::OpacMain; >+ >+# Copyright 2015 Open Source Freedom Fighters >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use Scalar::Util qw(blessed); >+ >+use base qw(t::lib::Page::Opac); >+ >+use Koha::Exception::BadParameter; >+ >+=head NAME t::lib::Page::Opac::OpacMain >+ >+=head SYNOPSIS >+ >+PageObject providing page functionality as a service! >+ >+=cut >+ >+=head new >+ >+ my $opacmain = t::lib::Page::Opac::OpacMain->new(); >+ >+Instantiates a WebDriver and loads the opac/opac-main.pl. >+@PARAM1 HASHRef of optional and MANDATORY parameters >+MANDATORY extra parameters: >+ none atm. >+ >+@RETURNS t::lib::Page::Opac::OpacMain, ready for user actions! >+=cut >+ >+sub new { >+ my ($class, $params) = @_; >+ unless (ref($params) eq 'HASH' || (blessed($params) && $params->isa('t::lib::Page') )) { >+ $params = {}; >+ } >+ $params->{resource} = '/cgi-bin/koha/opac-main.pl'; >+ $params->{type} = 'opac'; >+ >+ my $self = $class->SUPER::new($params); >+ >+ return $self; >+} >+ >+1; #Make the compiler happy! >\ No newline at end of file >-- >1.9.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 14536
:
41023
|
41052
|
41057
|
41121
|
41156
|
41254
|
41460
|
41524
|
41525
|
41534
|
41678
|
42060
|
42111
|
42118
|
42136
|
42160
|
42433
|
42435
|
42716
|
44410
|
47254
|
63245