From ad9195ad3a5e142d604bdc80680151a06f0b9d3d Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti 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 . + +=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 = < 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 . + +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 . + +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 . + +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 . + +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 . + +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 . + +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