Bugzilla – Attachment 67433 Details for
Bug 19243
Selenium test for testing the administration module functionality - part 1
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 19243 - Followup moving common Selenium functions into a seperate module
Bug-19243---Followup-moving-common-Selenium-functi.patch (text/plain), 19.21 KB, created by
Alex Buckley
on 2017-09-29 02:38:36 UTC
(
hide
)
Description:
Bug 19243 - Followup moving common Selenium functions into a seperate module
Filename:
MIME Type:
Creator:
Alex Buckley
Created:
2017-09-29 02:38:36 UTC
Size:
19.21 KB
patch
obsolete
>From dbf335fe81d2ccdda4a25241c333509889c1cae9 Mon Sep 17 00:00:00 2001 >From: Alex Buckley <alexbuckley@catalyst.net.nz> >Date: Thu, 28 Sep 2017 00:04:29 +0000 >Subject: [PATCH] Bug 19243 - Followup moving common Selenium functions into a > seperate module > >In this patch a module t/lib/Selenium.pm has been created and it >contains the auth, patron_auth, patron_opac_auth, cleaup, time_difffunctions which are common to other Selenium text scripts. > >Also a function to wait for an element to be found before it is >interacted with was created and it is called pause_driver > >At present this pause_driver function throws an error in the test output >saying that it cannot find an element and then it fails. > >Test plan (this test plan includes how to install Selenium as well as how to run this test, for the benefit of people who have not got >Selenium installed on their machines): > >1. wget >https://selenium-release.storage.googleapis.com/2.53/selenium-server-standalone-2.53.0.jar > >2. vim /etc/apt/sources.list.d/firefox.list > >3. Paste into the file: >deb http://packages.linuxmint.com debian import > >4. sudo apt-get update > >5. sudo apt-get install firefox > >6. sudo apt-get install xvfb > >7. Set the SELENIUM_PATH vartiable: >SELENIUM_PATH=/home/vagrant/kohaclone/selenium-server-standalone-2.53.0.jar > >8. Xvfb :1 -screen 0 1024x768x24 2>&1 >/dev/null & > >9. DISPLAY=:1 java -jar $SELENIUM_PATH > >Note: This will start up the selenium server. Everytime you want to >shutdown this terminal window and want to restart Selenium just run >the step 9 command to restart the Selenium server > >10. Open a new terminal window and write in: >git clone https://github.com/gempesaw/Selenium-Remote-Driver >--branch build/master --single-branch --depth 1 > >11. cd Selenium-Remote-Driver > >12. perl Makefile.PL > >13. make > >14. make test > >15. sudo make install > >16. Now everything is installed and you can set up for running the >selenium tests > >17. Drop and recreate the Koha database and restart memcached > >18. Go through the web installer installing all sample data and >onboarding tool > >19. Create a superlibrarian user with the username koha and password >koha > >20. If your usual port configuration for the intranet and OPAC is >8081 and 8080 respectively then set the staffClientBaseURL and >OPACBaseURL system preferences to localhost:8080 and localhost:80 >respectively > >21. sudo koha-shell <instancename> > >22. perl t/db_dependent/selenium/administration_tasks.t > >23. The test should pass. >Note: The time_diff comments in the test output showing what the >test is doing > >Note: If you have issues with installing Selenium and >Selenium::Remote::Driver please write a comment on the bug report >and I will be more than happy to create a screencapture video >showing all the steps > >Note: Warns in front of the $driver->get_title() function have been >implemented because during troubleshooting they were found to be an >effective solution for stopping the test from failing due to not >being able to find an element on the page. If anyone can suggest an >alternative to using these warns please do > >Sponsored-By: Catalyst IT >--- > t/db_dependent/selenium/administration_tasks.t | 97 ++++--------- > t/lib/Selenium.pm | 185 +++++++++++++++++++++++++ > 2 files changed, 212 insertions(+), 70 deletions(-) > create mode 100644 t/lib/Selenium.pm > >diff --git a/t/db_dependent/selenium/administration_tasks.t b/t/db_dependent/selenium/administration_tasks.t >index 08c5a38..0ed8c81 100644 >--- a/t/db_dependent/selenium/administration_tasks.t >+++ b/t/db_dependent/selenium/administration_tasks.t >@@ -30,6 +30,8 @@ use C4::Biblio qw( AddBiblio ); # We shouldn't use it > use Test::More tests => 1; > use MARC::Record; > use MARC::Field; >+use t::lib::Selenium; >+use Selenium::Waiter qw/wait_until/; > > my $dbh = C4::Context->dbh; > my $login = 'koha'; >@@ -37,6 +39,7 @@ my $password = 'koha'; > my $base_url= 'http://'.C4::Context->preference("staffClientBaseURL")."/cgi-bin/koha/"; > my $opac_url= C4::Context->preference("OPACBaseURL"); > >+my $number_of_biblios_to_insert = 0; > our $sample_data = { > category => { > categorycode => 'test_cat', >@@ -71,13 +74,15 @@ SKIP: { > $prev_time = $start; > $driver->get($base_url."mainpage.pl"); > like( $driver->get_title(), qr(Log in to Koha), ); >- auth( $driver, $login, $password ); >- time_diff("main"); >+ t::lib::Selenium::auth( $driver, $login, $password ); >+ t::lib::Selenium::time_diff($prev_time, "main"); > > # Navigate to the Administration area and create an item type > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/div[1]/div[2]/div/ul/li[5]/a')->click; >- $driver->pause(20000); >- $driver->find_element_by_xpath('/html/body/div[4]/div/div/div[2]/div[1]/dl[1]/dt[2]/a')->click; >+ t::lib::Selenium::pause_driver($driver, '/html/body/div[4]/div/div/div[2]/div[1]/dl[1]/dt[2]/a'); >+# $driver->pause(20000); >+# $driver->find_element_by_xpath('/html/body/div[4]/div/div/div[2]/div[1]/dl[1]/dt[2]/a')->is_displayed; >+# $driver->find_element_by_xpath('/html/body/div[4]/div/div/div[2]/div[1]/dl[1]/dt[2]/a')->click; > $driver->pause(20000); > $driver->find_element('//a[@id="newitemtype"]')->click; > $driver->pause(20000); >@@ -85,9 +90,9 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[1]/ol[1]/li[2]/input')->send_keys("Digital Optical Disc"); > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[2]/input')->click; > if ( $driver->find_element('//a[@href="/cgi-bin/koha/admin/itemtypes.pl?op=add_form&itemtype=DVD"]')) { >- time_diff("Item type successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "Item type successfully added"); > } else { >- time_diff("Item type not added successfully"); >+ t::lib::Selenium::time_diff($prev_time, "Item type not added successfully"); > } > > # Add circulation/fine rules >@@ -103,7 +108,7 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/div[2]/form[3]/table/tbody/tr[2]/td[22]/input')->send_keys("4"); > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/div[2]/form[3]/table/tbody/tr[2]/td[23]/input')->send_keys("4"); > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/div[2]/form[3]/table/tbody/tr[2]/td[28]/button[1]')->click; >- time_diff("Circulation rule added"); >+ t::lib::Selenium::time_diff($prev_time, "Circulation rule added"); > > # Modify frameworks > $driver->pause(20000); >@@ -111,7 +116,6 @@ SKIP: { > $driver->pause(20000); > $driver->find_element_by_xpath('/html/body/div[4]/div/div/div[2]/div[2]/dl[1]/dt[1]/a')->click; > $driver->pause(20000); >- warn $driver->get_title(); > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/div[2]/table/tbody/tr[5]/td[3]/div/a')->click; > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/div[2]/table/tbody/tr[5]/td[3]/div/ul/li[1]/a')->click; > $driver->pause(20000); >@@ -128,7 +132,7 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[1]/ol/li[3]/input')->send_keys("Local Dewey"); > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[2]/input')->click; > $driver->pause(20000); >- time_diff("Added subfield to framework"); >+ t::lib::Selenium::time_diff($prev_time, "Added subfield to framework"); > > #Add library > $driver->get_title(); >@@ -147,9 +151,9 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/div[3]/div[1]/div[2]/label/select')->click; > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/div[3]/div[1]/div[2]/label/select/option[3]')->click; > if ($driver->find_element('//td[text()="Test library"]')) { >- time_diff("Library successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "Library successfully added"); > } else { >- time_diff("Library not successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "Library not successfully added"); > } > > >@@ -168,9 +172,9 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[1]/ol/li[4]/input')->send_keys("Hardcover"); > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[2]/input[2]')->click; > if ($driver->find_element('//td[text()="HBK"]')) { >- time_diff("Authorised value successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "Authorised value successfully added"); > } else { >- time_diff("Authorised value not successfully added"); >+ t::lib::Seleniumtime_diff($prev_time, "Authorised value not successfully added"); > } > > #Patron category >@@ -188,9 +192,9 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[2]/input')->click; > $driver->pause(20000); > if ($driver->find_element('//td[text()="AD"]')) { >- time_diff("Patron category successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "Patron category successfully added"); > } else { >- time_diff("Patron category not successfully added"); >+ t::lib::Selenium::time_diff(i$prev_time, "Patron category not successfully added"); > } > > #Add patron attribute type >@@ -206,11 +210,10 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[1]/ol/li[11]/select/option[2]')->click; > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[2]/input')->click; > $driver->pause(20000); >- warn $driver->get_title(); > if ($driver->find_element('//td[text()="DL"]')) { >- time_diff("Patron attribute type successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "Patron attribute type successfully added"); > } else { >- time_diff("Patron attribute type not successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "Patron attribute type not successfully added"); > } > > #Add Z39.50 target server >@@ -229,9 +232,9 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[2]/input')->click; > $driver->pause(20000); > if ($driver->find_element('//td[text()="consull.ull.ac.uk:210"]')) { >- time_diff("Z39.50 target successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "Z39.50 target successfully added"); > } else { >- time_diff("Z39.50 target not successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "Z39.50 target not successfully added"); > } > > #Add item circulation alerts >@@ -240,7 +243,7 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div/div[2]/div[1]/dl[2]/dt[6]/a')->click; > $driver->pause(20000); > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/div[2]/div[1]/table/tbody/tr[1]/td[1]')->click; >- time_diff("Added item circulation alert"); >+ t::lib::Selenium::time_diff($prev_time, "Added item circulation alert"); > > #Add city > $driver->find_element_by_xpath('/html/body/div[3]/a[2]')->click; >@@ -255,9 +258,9 @@ SKIP: { > $driver->find_element_by_xpath('/html/body/div[4]/div/div[1]/div/form/fieldset[2]/input')->click; > $driver->pause(20000); > if ($driver->find_element('//td[text()="Wellington"]')) { >- time_diff("City successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "City successfully added"); > } else { >- time_diff("City not successfully added"); >+ t::lib::Selenium::time_diff($prev_time, "City not successfully added"); > } > > close $fh; >@@ -265,52 +268,6 @@ SKIP: { > }; > > END { >- cleanup() if $cleanup_needed; >+ t::lib::Selenium::cleanup($sample_data,$number_of_biblios_to_insert,$borrowernumber) if $cleanup_needed; > }; > >-sub auth { >- my ( $driver, $login, $password) = @_; >- fill_form( $driver, { userid => 'koha', password => 'koha' } ); >- my $login_button = $driver->find_element('//input[@id="submit"]'); >- $login_button->submit(); >-} >- >-sub patron_auth { >- my ( $driver,$patronusername, $patronpassword) = @_; >- fill_form( $driver, { userid => $patronusername, password => $patronpassword } ); >- my $login_button = $driver->find_element('//input[@id="submit"]'); >- $login_button->submit(); >-} >- >-sub patron_opac_auth { >- my ( $driver,$patronusername, $patronpassword) = @_; >- fill_form( $driver, { userid => $patronusername, password => $patronpassword } ); >- my $login_button = $driver->find_element('//input[@value="Log in"]'); >- $login_button->submit(); >-} >- >-sub fill_form { >- my ( $driver, $values ) = @_; >- while ( my ( $id, $value ) = each %$values ) { >- my $element = $driver->find_element('//*[@id="'.$id.'"]'); >- my $tag = $element->get_tag_name(); >- if ( $tag eq 'input' ) { >- $driver->find_element('//input[@id="'.$id.'"]')->send_keys($value); >- } elsif ( $tag eq 'select' ) { >- $driver->find_element('//select[@id="'.$id.'"]/option[@value="'.$value.'"]')->click; >- } >- } >-} >- >-sub cleanup { >- my $dbh = C4::Context->dbh; >- $dbh->do(q|DELETE FROM categories WHERE categorycode = ?|, {}, $sample_data->{category}{categorycode}); >- $dbh->do(q|DELETE FROM borrowers WHERE userid = ?|, {}, $sample_data->{patron}{userid}); >-} >- >-sub time_diff { >- my $lib = shift; >- my $now = gettimeofday; >- warn "CP $lib = " . sprintf("%.2f", $now - $prev_time ) . "\n"; >- $prev_time = $now; >-} >diff --git a/t/lib/Selenium.pm b/t/lib/Selenium.pm >new file mode 100644 >index 0000000..9e05e70 >--- /dev/null >+++ b/t/lib/Selenium.pm >@@ -0,0 +1,185 @@ >+package t::lib::Selenium; >+ >+use Modern::Perl; >+ >+use Koha::Database; >+ >+use Carp; >+use Module::Load; >+use String::Random; >+use Time::HiRes qw(gettimeofday); >+use Selenium::Waiter qw/wait_until/; >+use Try::Tiny; >+ >+my $dbh = C4::Context->dbh; >+my $login = 'koha'; >+my $password = 'koha'; >+my $base_url= 'http://'.C4::Context->preference("staffClientBaseURL")."/cgi-bin/koha/"; >+ >+sub auth { >+ my ( $driver, $login, $password) = @_; >+ fill_form( $driver, { userid => 'koha', password => 'koha' } ); >+ my $login_button = $driver->find_element('//input[@id="submit"]'); >+ $login_button->submit(); >+} >+ >+sub patron_auth { >+ my ( $driver,$patronusername, $patronpassword) = @_; >+ fill_form( $driver, { userid => $patronusername, password => $patronpassword } ); >+ my $login_button = $driver->find_element('//input[@id="submit"]'); >+ $login_button->submit(); >+} >+ >+sub patron_opac_auth { >+ my ( $driver,$patronusername, $patronpassword) = @_; >+ fill_form( $driver, { userid => $patronusername, password => $patronpassword } ); >+ my $login_button = $driver->find_element('//input[@value="Log in"]'); >+ $login_button->submit(); >+} >+ >+sub fill_form { >+ my ( $driver, $values ) = @_; >+ while ( my ( $id, $value ) = each %$values ) { >+ my $element = $driver->find_element('//*[@id="'.$id.'"]'); >+ my $tag = $element->get_tag_name(); >+ if ( $tag eq 'input' ) { >+ $driver->find_element('//input[@id="'.$id.'"]')->send_keys($value); >+ } elsif ( $tag eq 'select' ) { >+ $driver->find_element('//select[@id="'.$id.'"]/option[@value="'.$value.'"]')->click; >+ } >+ } >+} >+ >+sub cleanup { >+ my ($sample_data, $number_of_biblios_to_insert,$borrowernumber) = @_; >+ my $dbh = C4::Context->dbh; >+ $dbh->do(q|DELETE FROM categories WHERE categorycode = ?|, {}, $sample_data->{category}{categorycode}); >+ $dbh->do(q|DELETE FROM borrowers WHERE userid = ?|, {}, $sample_data->{patron}{userid}); >+ for my $i ( 1 .. $number_of_biblios_to_insert ) { >+ $dbh->do(qq|DELETE FROM biblio WHERE title = "test biblio $i"|); >+ }; >+ >+ $dbh->do(q|DELETE FROM issues where borrowernumber=?|, {}, $borrowernumber); >+ $dbh->do(q|DELETE FROM old_issues where borrowernumber=?|, {},$borrowernumber); >+ for my $i ( 1 .. $number_of_biblios_to_insert ) { >+ $dbh->do(qq|DELETE items, biblio FROM biblio INNER JOIN items ON biblio.biblionumber = items.biblionumber WHERE biblio.title ="test biblio$i"|); >+ }; >+} >+ >+sub time_diff { >+ my ($prev_time, $lib) = (@_); >+ my $now = gettimeofday; >+ warn "CP $lib = " . sprintf("%.2f", $now - $prev_time ) . "\n"; >+ $prev_time = $now; >+} >+ >+sub pause_driver { >+ my ($driver, $element) = @_; >+ $driver->set_implicit_wait_timeout(30000); >+ my $elem_exists = wait_until {$driver->find_element_by_xpath('$element')}; >+ >+ if ($elem_exists) { >+ $driver->find_element_by_xpath('$element')->click; >+ } >+} >+ >+ >+=head1 NAME >+ >+t::lib::Selenium.pm - Koha module for common Selenium functions >+ >+=head1 SYNOPSIS >+ >+ >+=head1 DESCRIPTION >+ >+This Perl module >+ >+ >+This module automatically creates database records for you. >+If needed, records for foreign keys are created too. >+Values will be randomly generated if not passed to TestBuilder. >+Note that you should wrap these actions in a transaction yourself. >+ >+=head1 METHODS >+ >+=head2 new >+ >+ my $builder = t::lib::TestBuilder->new; >+ >+ Constructor - Returns the object TestBuilder >+ >+=head2 schema >+ >+ my $schema = $builder->schema; >+ >+ Getter - Returns the schema of DBIx::Class >+ >+=head2 delete >+ >+ $builder->delete({ >+ source => $source, >+ records => $patron, # OR: records => [ $patron, ... ], >+ }); >+ >+ Delete individual records, created by builder. >+ Returns the number of delete attempts, or undef. >+ >+=head2 build >+ >+ $builder->build({ source => $source_name, value => $value }); >+ >+ Create a test record in the table, represented by $source_name. >+ The name is required and must conform to the DBIx::Class schema. >+ Values may be specified by the optional $value hashref. Will be >+ randomized otherwise. >+ If needed, TestBuilder creates linked records for foreign keys. >+ Returns the values of the new record as a hashref, or undef if >+ the record could not be created. >+ >+ Note that build also supports recursive hash references inside the >+ value hash for foreign key columns, like: >+ value => { >+ column1 => 'some_value', >+ fk_col2 => { >+ columnA => 'another_value', >+ } >+ } >+ The hash for fk_col2 here means: create a linked record with build >+ where columnA has this value. In case of a composite FK the hashes >+ are merged. >+ >+ Realize that passing primary key values to build may result in undef >+ if a record with that primary key already exists. >+ >+=head2 build_object >+ >+Given a plural Koha::Object-derived class, it creates a random element, and >+returns the corresponding Koha::Object. >+ >+ my $patron = $builder->build_object({ class => 'Koha::Patrons' [, value => { ... }] }); >+ >+=head1 AUTHOR >+ >+Alex Buckley <alexbuckley@catalyst.net.nz> >+ >+Catalyst Koha Development Team >+ >+=head1 COPYRIGHT >+ >+Copyright 2017 - Catalyst IT >+ >+=head1 LICENSE >+ >+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>. >+ >+=cut >+ >+1; >-- >2.1.4
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 19243
:
66788
|
67433
|
67492
|
67493
|
67494
|
67495
|
67496
|
67497
|
68123
|
68124
|
68125
|
68832
|
68833
|
69757
|
69939
|
70160
|
70161
|
70162
|
70163
|
70164
|
70268
|
70269
|
70270