Bug 21233: Add Koha::Exceptions::Password
[koha.git] / t / lib / Selenium.pm
blobb5b13744856f1da13554f047f6923d77276f781b
1 package t::lib::Selenium;
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>.
19 use Modern::Perl;
20 use Carp qw( croak );
21 use JSON qw( from_json );
23 use C4::Context;
25 use base qw(Class::Accessor);
26 __PACKAGE__->mk_accessors(qw(login password base_url opac_base_url selenium_addr selenium_port driver));
28 sub capture {
29 my ( $class, $driver ) = @_;
31 my $lutim_server = q|https://framapic.org|; # Thanks Framasoft!
32 $driver->capture_screenshot('selenium_failure.png');
33 my $from_json = from_json qx{curl -s -F "format=json" -F "file=\@selenium_failure.png" -F "delete-day=1" $lutim_server};
34 if ( $from_json ) {
35 print STDERR "\nSCREENSHOT: $lutim_server/" . $from_json->{msg}->{short} . "\n";
39 sub new {
40 my ( $class, $params ) = @_;
41 my $self = {};
42 my $config = $class->config;
43 $self->{login} = $params->{login} || $config->{login};
44 $self->{password} = $params->{password} || $config->{password};
45 $self->{base_url} = $params->{base_url} || $config->{base_url};
46 $self->{opac_base_url} = $params->{opac_base_url} || $config->{opac_base_url};
47 $self->{selenium_addr} = $params->{selenium_addr} || $config->{selenium_addr};
48 $self->{selenium_port} = $params->{selenium_port} || $config->{selenium_port};
49 $self->{driver} = Selenium::Remote::Driver->new(
50 port => $self->{selenium_port},
51 remote_server_addr => $self->{selenium_addr},
52 error_handler => sub {
53 my ( $driver, $selenium_error ) = @_;
54 print STDERR "\nSTRACE:";
55 my $i = 1;
56 while ( (my @call_details = (caller($i++))) ){
57 print STDERR "\t" . $call_details[1]. ":" . $call_details[2] . " in " . $call_details[3]."\n";
59 print STDERR "\n";
60 $class->capture( $driver );
61 croak $selenium_error;
64 return bless $self, $class;
67 sub config {
68 return {
69 login => $ENV{KOHA_USER} || 'koha',
70 password => $ENV{KOHA_PASS} || 'koha',
71 base_url => ( $ENV{KOHA_INTRANET_URL} || C4::Context->preference("staffClientBaseURL") ) . "/cgi-bin/koha/",
72 opac_base_url => ( $ENV{KOHA_OPAC_URL} || C4::Context->preference("OPACBaseURL") ) . "/cgi-bin/koha/",
73 selenium_addr => $ENV{SELENIUM_ADDR} || 'localhost',
74 selenium_port => $ENV{SELENIUM_PORT} || 4444,
78 sub auth {
79 my ( $self, $login, $password ) = @_;
81 $login ||= $self->login;
82 $password ||= $self->password;
83 my $mainpage = $self->base_url . 'mainpage.pl';
85 $self->driver->get($mainpage);
86 $self->fill_form( { userid => $login, password => $password } );
87 my $login_button = $self->driver->find_element('//input[@id="submit"]');
88 $login_button->submit();
91 sub opac_auth {
92 my ( $self, $login, $password ) = @_;
94 $login ||= $self->login;
95 $password ||= $self->password;
96 my $mainpage = $self->opac_base_url . 'opac-main.pl';
98 $self->driver->get($mainpage);
99 $self->fill_form( { userid => $login, password => $password } );
100 $self->submit_form;
103 sub fill_form {
104 my ( $self, $values ) = @_;
105 while ( my ( $id, $value ) = each %$values ) {
106 my $element = $self->driver->find_element('//*[@id="'.$id.'"]');
107 my $tag = $element->get_tag_name();
108 if ( $tag eq 'input' ) {
109 $self->driver->find_element('//input[@id="'.$id.'"]')->send_keys($value);
110 } elsif ( $tag eq 'select' ) {
111 $self->driver->find_element('//select[@id="'.$id.'"]/option[@value="'.$value.'"]')->click;
116 sub submit_form {
117 my ( $self ) = @_;
119 my $default_submit_selector = '//fieldset[@class="action"]/input[@type="submit"]';
120 $self->click_when_visible( $default_submit_selector );
123 sub click {
124 my ( $self, $params ) = @_;
125 my $xpath_selector;
126 if ( exists $params->{main} ) {
127 $xpath_selector = '//div[@id="'.$params->{main}.'"]';
128 } elsif ( exists $params->{main_class} ) {
129 $xpath_selector = '//div[@class="'.$params->{main_class}.'"]';
131 if ( exists $params->{href} ) {
132 if ( ref( $params->{href} ) ) {
133 for my $k ( keys %{ $params->{href} } ) {
134 if ( $k eq 'ends-with' ) {
135 # ends-with version for xpath version 1
136 my $ends_with = $params->{href}{"ends-with"};
137 $xpath_selector .= '//a[substring(@href, string-length(@href) - string-length("'.$ends_with.'") + 1 ) = "'.$ends_with.'"]';
138 # ends-with version for xpath version 2
139 #$xpath_selector .= '//a[ends-with(@href, "'.$ends_with.'") ]';
141 } else {
142 die "Only ends-with is supported so far ($k)";
145 } else {
146 $xpath_selector .= '//a[contains(@href, "'.$params->{href}.'")]';
149 if ( exists $params->{id} ) {
150 $xpath_selector .= '//*[@id="'.$params->{id}.'"]';
152 $self->click_when_visible( $xpath_selector );
155 sub click_when_visible {
156 my ( $self, $xpath_selector ) = @_;
157 $self->driver->set_implicit_wait_timeout(20000);
158 my ($visible, $elt);
159 while ( not $visible ) {
160 $elt = $self->driver->find_element($xpath_selector);
161 $visible = $elt->is_displayed;
162 $self->driver->pause(1000) unless $visible;
164 $elt->click;
167 =head1 NAME
169 t::lib::Selenium - Selenium helper module
171 =head1 SYNOPSIS
173 my $s = t::lib::Selenium->new;
174 my $driver = $s->driver;
175 my $base_url = $s->base_url;
176 $s->auth;
177 $driver->get($s->base_url . 'mainpage.pl');
178 $s->fill_form({ input_id => 'value' });
180 =head1 DESCRIPTION
182 The goal of this module is to group the different actions we need
183 when we use automation test using Selenium
185 =head1 METHODS
187 =head2 new
189 my $s = t::lib::Selenium->new;
191 Constructor - Returns the object Selenium
192 You can pass login, password, base_url, selenium_addr, selenium_port
193 If not passed, the environment variables will be used
194 KOHA_USER, KOHA_PASS, KOHA_INTRANET_URL, SELENIUM_ADDR SELENIUM_PORT
195 Or koha, koha, syspref staffClientBaseURL, localhost, 4444
197 =head2 auth
199 $s->auth;
201 Will login into Koha.
203 =head2 fill_form
205 $driver->get($url)
206 $s->fill_form({
207 input_id => 'value',
208 element_id => 'other_value',
211 Will fill the different elements of a form.
212 The keys must be element ids (input and select are supported so far)
213 The values must a string.
215 =head2 submit_form
217 $s->submit_form;
219 It will submit the form using the submit button present in in the fieldset with a clas="action".
220 It should be the default way. If it does not work you should certainly fix the Koha interface.
222 =head2 click
224 $s->click
226 This is a bit dirty for now but will evolve depending on the needs
227 3 parameters possible but only the following 2 forms are used:
228 $s->click({ href => '/module/script.pl?foo=bar', main => 'doc3' }); # Sometimes we have doc or doc3. To make sure we are not going to hit a link in the header
229 $s->click({ id => 'element_id });
231 =head2 click_when_visible
233 $c->click_when_visible
235 Should always be called to avoid the "An element could not be located on the page" error
237 =head2 capture
238 $c->capture
240 Capture a screenshot and upload it using the excellent lut.im service provided by framasoft
241 The url of the image will be printed on STDERR (it should be better to return it instead)
243 =head1 AUTHORS
245 Jonathan Druart <jonathan.druart@bugs.koha-community.org>
247 Alex Buckley <alexbuckley@catalyst.net.nz>
249 Koha Development Team
251 =head1 COPYRIGHT
253 Copyright 2017 - Koha Development Team
255 =head1 LICENSE
257 This file is part of Koha.
259 Koha is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
260 the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
262 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.
264 You should have received a copy of the GNU General Public License along with Koha; if not, see <http://www.gnu.org/licenses>.
266 =cut