Commit | Line | Data |
---|---|---|
23ebc481 DM |
1 | <?php |
2 | // This file is part of Moodle - http://moodle.org/ | |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | /** | |
18 | * Single select form field class. | |
19 | * | |
20 | * @package core_form | |
21 | * @category test | |
22 | * @copyright 2012 David Monllaó | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
25 | ||
26 | // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. | |
27 | ||
28 | require_once(__DIR__ . '/behat_form_field.php'); | |
29 | ||
30 | /** | |
31 | * Single select form field. | |
32 | * | |
33 | * @package core_form | |
34 | * @category test | |
35 | * @copyright 2012 David Monllaó | |
36 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
37 | */ | |
38 | class behat_form_select extends behat_form_field { | |
39 | ||
40 | /** | |
41 | * Sets the value of a single select. | |
42 | * | |
d1e55a47 DM |
43 | * Seems an easy select, but there are lots of combinations |
44 | * of browsers and operative systems and each one manages the | |
45 | * autosubmits and the multiple option selects in a diferent way. | |
46 | * | |
23ebc481 DM |
47 | * @param string $value |
48 | * @return void | |
49 | */ | |
50 | public function set_value($value) { | |
28abad1a | 51 | |
d1e55a47 DM |
52 | // In some browsers we select an option and it triggers all the |
53 | // autosubmits and works as expected but not in all of them, so we | |
54 | // try to catch all the possibilities to make this function work as | |
55 | // expected. | |
56 | ||
57 | // Get the internal id of the element we are going to click. | |
58 | // This kind of internal IDs are only available in the selenium wire | |
59 | // protocol, so only available using selenium drivers, phantomjs and family. | |
28abad1a | 60 | if ($this->running_javascript()) { |
d1e55a47 DM |
61 | $currentelementid = $this->get_internal_field_id(); |
62 | } | |
28abad1a | 63 | |
d1e55a47 DM |
64 | // Here we select an option. |
65 | $this->field->selectOption($value); | |
1fb97157 | 66 | |
d1e55a47 DM |
67 | // With JS disabled this is enough and we finish here. |
68 | if (!$this->running_javascript()) { | |
69 | return; | |
70 | } | |
38976081 | 71 | |
d1e55a47 DM |
72 | // With JS enabled we add more clicks as some selenium |
73 | // drivers requires it to fire JS events. | |
38976081 | 74 | |
d1e55a47 DM |
75 | // In some browsers the selectOption actions can perform a form submit or reload page |
76 | // so we need to ensure the element is still available to continue interacting | |
77 | // with it. We don't wait here. | |
78 | $selectxpath = $this->field->getXpath(); | |
79 | if (!$this->session->getDriver()->find($selectxpath)) { | |
80 | return; | |
81 | } | |
28abad1a | 82 | |
d1e55a47 DM |
83 | // We also check the selenium internal element id, if it have changed |
84 | // we are dealing with an autosubmit that was already executed, and we don't to | |
85 | // execute anything else as the action we wanted was already performed. | |
86 | if ($currentelementid != $this->get_internal_field_id()) { | |
87 | return; | |
88 | } | |
89 | ||
90 | // We also check that the option is still there. We neither wait. | |
91 | $valueliteral = $this->session->getSelectorsHandler()->xpathLiteral($value); | |
92 | $optionxpath = $selectxpath . "/descendant::option[(./@value=$valueliteral or normalize-space(.)=$valueliteral)]"; | |
93 | if (!$this->session->getDriver()->find($optionxpath)) { | |
94 | return; | |
95 | } | |
96 | ||
97 | // Single select sometimes needs an extra click in the option. | |
98 | if (!$this->field->hasAttribute('multiple')) { | |
99 | ||
100 | // Using the driver direcly because Element methods are messy when dealing | |
101 | // with elements inside containers. | |
102 | $optionnodes = $this->session->getDriver()->find($optionxpath); | |
103 | if ($optionnodes) { | |
104 | current($optionnodes)->click(); | |
28abad1a | 105 | } |
d1e55a47 DM |
106 | |
107 | } else { | |
108 | // Multiple ones needs the click in the select. | |
109 | $this->field->click(); | |
110 | ||
111 | // We ensure that the option is still there. | |
112 | if (!$this->session->getDriver()->find($optionxpath)) { | |
113 | return; | |
114 | } | |
115 | ||
116 | // Repeating the select as some drivers (chrome that I know) are moving | |
117 | // to another option after the general select field click above. | |
118 | $this->field->selectOption($value); | |
28abad1a | 119 | } |
23ebc481 DM |
120 | } |
121 | ||
122 | /** | |
123 | * Returns the text of the current value. | |
124 | * | |
125 | * @return string | |
126 | */ | |
127 | public function get_value() { | |
128 | $selectedoption = $this->field->find('xpath', '//option[@selected="selected"]'); | |
129 | return $selectedoption->getText(); | |
130 | } | |
131 | } |