Bug 26922: Regression tests
[koha.git] / t / db_dependent / selenium / basic_workflow.t
blobc4bb0310c542d3faa092eec410ce0519f0bbc261
1 #!/usr/bin/perl
3 # This file is part of Koha.
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20 # wget https://selenium-release.storage.googleapis.com/2.53/selenium-server-standalone-2.53.1.jar # Does not work with 3.4, did not test the ones between
21 # sudo apt-get install xvfb firefox-esr
22 # SELENIUM_PATH=/home/vagrant/selenium-server-standalone-2.53.1.jar
23 # Xvfb :1 -screen 0 1024x768x24 2>&1 >/dev/null &
24 # DISPLAY=:1 java -jar $SELENIUM_PATH
26 # Then you can execute the test file.
28 # If you get:
29 # Wide character in print at /usr/local/share/perl/5.20.2/Test2/Formatter/TAP.pm line 105.
30 # # 'Koha › Patrons › Add patron test_patron_surname (Adult)'
31 # # doesn't match '(?^u:Patron details for test_patron_surname)'
33 # Ignore and retry (FIXME LATER...)
35 use Modern::Perl;
37 use Time::HiRes qw(gettimeofday);
38 use POSIX qw(strftime);
39 use C4::Context;
40 use C4::Biblio qw( AddBiblio ); # We shouldn't use it
42 use Koha::CirculationRules;
44 use Test::More tests => 22;
45 use MARC::Record;
46 use MARC::Field;
48 use t::lib::Selenium;
50 my $dbh = C4::Context->dbh;
52 my $number_of_biblios_to_insert = 3;
53 our $sample_data = {
54 category => {
55 categorycode => 'TEST_CAT',
56 description => 'test cat description',
57 enrolmentperiod => '12',
58 category_type => 'A'
60 patron => {
61 surname => 'test_patron_surname',
62 cardnumber => '4242424242',
63 userid => 'test_username',
64 password => '1BetterPassword',
65 password2 => '1BetterPassword'
67 itemtype => {
68 itemtype => 'IT4TEST',
69 description => 'Just an itemtype for tests',
70 rentalcharge => 0,
71 notforloan => 0,
73 issuingrule => {
74 categorycode => 'test_cat',
75 itemtype => 'IT4test',
76 branchcode => undef,
77 maxissueqty => '5',
78 issuelength => '5',
79 lengthunit => 'days',
80 renewalperiod => '5',
81 reservesallowed => '5',
82 onshelfholds => '1',
83 opacitemholds => 'Y',
86 our ( $borrowernumber, $start, $prev_time, $cleanup_needed );
88 $dbh->do(q|INSERT INTO itemtypes(itemtype) VALUES (?)|, undef, $sample_data->{itemtype}{itemtype});
90 SKIP: {
91 eval { require Selenium::Remote::Driver; };
92 skip "Selenium::Remote::Driver is needed for selenium tests.", 22 if $@;
94 $cleanup_needed = 1;
96 open my $fh, '>>', '/tmp/output.txt';
98 my $s = t::lib::Selenium->new;
100 my $driver = $s->driver;
101 my $base_url = $s->base_url;
103 $start = gettimeofday;
104 $prev_time = $start;
105 $driver->get($base_url."mainpage.pl");
106 like( $driver->get_title(), qr(Log in to Koha), );
107 $s->auth;
108 time_diff("main");
110 $driver->get($base_url.'admin/categories.pl');
111 like( $driver->get_title(), qr(Patron categories), );
112 $driver->find_element('//a[@id="newcategory"]')->click;
113 like( $driver->get_title(), qr(New category), );
114 $s->fill_form( $sample_data->{category} );
115 $driver->find_element('//fieldset[@class="action"]/input[@type="submit"]')->click;
117 time_diff("add patron category");
118 $driver->get($base_url.'/members/memberentry.pl?op=add&amp;categorycode='.$sample_data->{category}{categorycode});
119 like( $driver->get_title(), qr(Add .*$sample_data->{category}{description}), );
120 $s->fill_form( $sample_data->{patron} );
121 $driver->find_element('//button[@id="saverecord"]')->click;
122 like( $driver->get_title(), qr(Patron details for $sample_data->{patron}{surname}), );
124 ####$driver->get($base_url.'/members/members-home.pl');
125 ####fill_form( $driver, { searchmember => $sample_data->{patron}{cardnumber} } );
126 ####$driver->find_element('//div[@id="header_search"]/div/form/input[@type="submit"]')->click;
127 ####like( $driver->get_title(), qr(Patron details for), );
129 time_diff("add patron");
131 $borrowernumber = $dbh->selectcol_arrayref(q|SELECT borrowernumber FROM borrowers WHERE userid=?|, {}, $sample_data->{patron}{userid} )->[0];
133 my @biblionumbers;
134 for my $i ( 1 .. $number_of_biblios_to_insert ) {
135 my $biblio = MARC::Record->new();
136 my $title = 'test biblio '.$i;
137 if ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
138 $biblio->append_fields(
139 MARC::Field->new('200', ' ', ' ', a => 'test biblio '.$i),
140 MARC::Field->new('200', ' ', ' ', f => 'test author '.$i),
142 } else {
143 $biblio->append_fields(
144 MARC::Field->new('245', ' ', ' ', a => 'test biblio '.$i),
145 MARC::Field->new('100', ' ', ' ', a => 'test author '.$i),
148 my ($biblionumber, $biblioitemnumber) = AddBiblio($biblio, '');
149 push @biblionumbers, $biblionumber;
152 time_diff("add biblio");
154 my $itemtype = $sample_data->{itemtype};
156 my $issuing_rules = $sample_data->{issuingrule};
157 Koha::CirculationRules->set_rules(
159 categorycode => $issuing_rules->{categorycode},
160 itemtype => $issuing_rules->{itemtype},
161 branchcode => $issuing_rules->{branchcode},
162 rules => {
163 maxissueqty => $issuing_rules->{maxissueqty},
164 issuelength => $issuing_rules->{issuelength},
165 lengthunit => $issuing_rules->{lengthunit},
166 renewalperiod => $issuing_rules->{renewalperiod},
167 reservesallowed => $issuing_rules->{reservesallowed},
168 onshelfholds => $issuing_rules->{onshelfholds},
169 opacitemholds => $issuing_rules->{opacitemholds},
176 for my $biblionumber ( @biblionumbers ) {
177 $driver->get($base_url."/cataloguing/additem.pl?biblionumber=$biblionumber");
178 like( $driver->get_title(), qr(test biblio \d+ by test author), );
179 my $form = $driver->find_element('//form[@name="f"]');
180 my $inputs = $driver->find_child_elements($form, '//input[@type="text"]');
181 for my $input ( @$inputs ) {
182 next if $input->is_hidden();
184 my $id = $input->get_attribute('id');
185 next unless $id =~ m|^tag_952_subfield|;
187 my $v;
189 # FIXME This is based on default values
190 if ( $id =~ m|^tag_952_subfield_g| # price
191 or $id =~ m|^tag_952_subfield_v| ) # replacementprice
193 $v = '42'; # It's a price
195 elsif (
196 $id =~ m|^tag_952_subfield_f| #tag_952_subfield_g
198 # It's a varchar(10)
199 $v = 't_value_x';
201 elsif (
202 $id =~ m|^tag_952_subfield_w| # replacementpricedate
204 $v = strftime("%Y-%m-%d", localtime);
206 elsif (
207 $id =~ m|^tag_952_subfield_d| # dateaccessioned
209 $v = ""; # The input has been prefilled with %Y-%m-%d already
211 elsif (
212 $id =~ m|^tag_952_subfield_3| # materials
214 $v = ""; # We don't want the checkin/checkout to need confirmation if CircConfirmItemParts is on
216 else {
217 $v = 't_value_bib' . $biblionumber;
219 $input->send_keys( $v );
222 $driver->find_element('//input[@name="add_submit"]')->click;
223 like( $driver->get_title(), qr($biblionumber.*Items) );
225 $dbh->do(q|UPDATE items SET notforloan=0 WHERE biblionumber=?|, {}, $biblionumber );
226 $dbh->do(q|UPDATE biblioitems SET itemtype=? WHERE biblionumber=?|, {}, $itemtype->{itemtype}, $biblionumber);
227 $dbh->do(q|UPDATE items SET itype=? WHERE biblionumber=?|, {}, $itemtype->{itemtype}, $biblionumber);
230 time_diff("add items");
232 my $nb_of_checkouts = 0;
233 for my $biblionumber ( @biblionumbers ) {
234 $driver->get($base_url."/circ/circulation.pl?borrowernumber=".$borrowernumber);
235 $driver->find_element('//input[@id="barcode"]')->send_keys('t_value_bib'.$biblionumber);
236 $driver->find_element('//fieldset[@id="circ_circulation_issue"]/button[@type="submit"]')->click;
237 $nb_of_checkouts++;
238 like( $driver->get_title(), qr(Checking out to $sample_data->{patron}{surname}) );
239 is( $driver->find_element('//a[@href="#checkouts"]')->get_attribute('text'), $nb_of_checkouts.' Checkout(s)', );
242 time_diff("checkout");
244 for my $biblionumber ( @biblionumbers ) {
245 $driver->get($base_url."/circ/returns.pl");
246 $driver->find_element('//input[@id="barcode"]')->send_keys('t_value_bib'.$biblionumber);
247 $driver->find_element('//*[@id="circ_returns_checkin"]/div[2]/div[1]/div[2]/button')->click;
248 like( $driver->get_title(), qr(Check in test biblio \d+) );
251 time_diff("checkin");
253 #Place holds
254 $driver->get($base_url."/reserve/request.pl?borrowernumber=$borrowernumber&biblionumber=".$biblionumbers[0]);
255 $driver->find_element('//form[@id="hold-request-form"]//button[@type="submit"]')->click; # Biblio level
256 $driver->pause(1000); # This seems wrong, since bug 19618 the hold is created async with an AJAX call. Not sure what is happening here but the next statements are exectuted before the hold is created and the count is wrong (still 0)
257 my $patron = Koha::Patrons->find($borrowernumber);
258 is( $patron->holds->count, 1, );
260 $driver->get($base_url."/reserve/request.pl?borrowernumber=$borrowernumber&biblionumber=".$biblionumbers[1]);
261 $driver->find_element('//form[@id="hold-request-form"]//input[@type="radio"]')->click; # Item level, there is only 1 item per bib so we are safe
262 $driver->find_element('//form[@id="hold-request-form"]//button[@type="submit"]')->click;
263 $driver->pause(1000);
264 is( $patron->holds->count, 2, );
266 time_diff("holds");
268 close $fh;
269 $driver->quit();
272 END {
273 cleanup() if $cleanup_needed;
276 sub cleanup {
277 my $dbh = C4::Context->dbh;
278 $dbh->do(q|DELETE FROM issues where borrowernumber=?|, {}, $borrowernumber);
279 $dbh->do(q|DELETE FROM old_issues where borrowernumber=?|, {}, $borrowernumber);
280 for my $i ( 1 .. $number_of_biblios_to_insert ) {
281 $dbh->do(qq|DELETE items, biblio FROM biblio INNER JOIN items ON biblio.biblionumber = items.biblionumber WHERE biblio.title = "test biblio$i"|);
283 $dbh->do(q|DELETE FROM borrowers WHERE userid = ?|, {}, $sample_data->{patron}{userid});
284 $dbh->do(q|DELETE FROM categories WHERE categorycode = ?|, {}, $sample_data->{category}{categorycode});
285 for my $i ( 1 .. $number_of_biblios_to_insert ) {
286 $dbh->do(qq|DELETE FROM biblio WHERE title = "test biblio $i"|);
288 $dbh->do(q|DELETE FROM itemtypes WHERE itemtype=?|, undef, $sample_data->{itemtype}{itemtype});
289 $dbh->do(q|DELETE FROM circulation_rules WHERE categorycode=? AND itemtype=? AND branchcode=?|, undef, $sample_data->{issuingrule}{categorycode}, $sample_data->{issuingrule}{itemtype}, $sample_data->{issuingrule}{branchcode});
292 sub time_diff {
293 my $lib = shift;
294 my $now = gettimeofday;
295 warn "CP $lib = " . sprintf("%.2f", $now - $prev_time ) . "\n";
296 $prev_time = $now;