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 | * Steps definitions related with forms. | |
19 | * | |
20 | * @package core | |
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__ . '/../../../lib/behat/behat_base.php'); | |
a4534dce | 29 | require_once(__DIR__ . '/../../../lib/behat/behat_field_manager.php'); |
23ebc481 | 30 | |
2c376776 AN |
31 | use Behat\Gherkin\Node\{TableNode, PyStringNode}; |
32 | use Behat\Mink\Element\NodeElement; | |
33 | use Behat\Mink\Exception\{ElementNotFoundException, ExpectationException}; | |
23ebc481 DM |
34 | |
35 | /** | |
36 | * Forms-related steps definitions. | |
37 | * | |
920a3500 TH |
38 | * Note, Behat tests to verify that the steps defined here work as advertised |
39 | * are kept in admin/tool/behat/tests/behat. | |
40 | * | |
23ebc481 DM |
41 | * @package core |
42 | * @category test | |
43 | * @copyright 2012 David Monllaó | |
44 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
45 | */ | |
46 | class behat_forms extends behat_base { | |
47 | ||
48 | /** | |
49 | * Presses button with specified id|name|title|alt|value. | |
50 | * | |
23ebc481 | 51 | * @When /^I press "(?P<button_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb | 52 | * @throws ElementNotFoundException Thrown by behat_base::find |
46ac40cd | 53 | * @param string $button |
23ebc481 DM |
54 | */ |
55 | public function press_button($button) { | |
de316e8e | 56 | $this->execute('behat_general::i_click_on', [$button, 'button']); |
23ebc481 DM |
57 | } |
58 | ||
1ef6a5e3 RT |
59 | /** |
60 | * Press button with specified id|name|title|alt|value and switch to main window. | |
61 | * | |
62 | * @When /^I press "(?P<button_string>(?:[^"]|\\")*)" and switch to main window$/ | |
63 | * @throws ElementNotFoundException Thrown by behat_base::find | |
64 | * @param string $button | |
65 | */ | |
66 | public function press_button_and_switch_to_main_window($button) { | |
67 | // Ensures the button is present, before pressing. | |
68 | $buttonnode = $this->find_button($button); | |
69 | $buttonnode->press(); | |
70 | ||
71 | // Switch to main window. | |
72 | $this->getSession()->switchToWindow(behat_general::MAIN_WINDOW_NAME); | |
73 | } | |
74 | ||
23ebc481 | 75 | /** |
d1ac356a | 76 | * Fills a form with field/value data. |
23ebc481 | 77 | * |
a5254141 | 78 | * @Given /^I set the following fields to these values:$/ |
1f9ffbdb | 79 | * @throws ElementNotFoundException Thrown by behat_base::find |
23ebc481 DM |
80 | * @param TableNode $data |
81 | */ | |
a5254141 | 82 | public function i_set_the_following_fields_to_these_values(TableNode $data) { |
23ebc481 | 83 | |
f8f1bdc3 DM |
84 | // Expand all fields in case we have. |
85 | $this->expand_all_fields(); | |
86 | ||
23ebc481 DM |
87 | $datahash = $data->getRowsHash(); |
88 | ||
89 | // The action depends on the field type. | |
90 | foreach ($datahash as $locator => $value) { | |
a5254141 | 91 | $this->set_field_value($locator, $value); |
23ebc481 DM |
92 | } |
93 | } | |
94 | ||
920a3500 TH |
95 | /** |
96 | * Fills a form with field/value data. | |
97 | * | |
98 | * @Given /^I set the following fields in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" to these values:$/ | |
99 | * @throws ElementNotFoundException Thrown by behat_base::find | |
100 | * @param string $containerelement Element we look in | |
101 | * @param string $containerselectortype The type of selector where we look in | |
102 | * @param TableNode $data | |
103 | */ | |
104 | public function i_set_the_following_fields_in_container_to_these_values( | |
105 | $containerelement, $containerselectortype, TableNode $data) { | |
106 | ||
107 | // Expand all fields in case we have. | |
108 | $this->expand_all_fields(); | |
109 | ||
110 | $datahash = $data->getRowsHash(); | |
111 | ||
112 | // The action depends on the field type. | |
113 | foreach ($datahash as $locator => $value) { | |
114 | $this->set_field_value_in_container($locator, $value, $containerselectortype, $containerelement); | |
115 | } | |
116 | } | |
117 | ||
f8f1bdc3 DM |
118 | /** |
119 | * Expands all moodleform's fields, including collapsed fieldsets and advanced fields if they are present. | |
120 | * @Given /^I expand all fieldsets$/ | |
121 | */ | |
122 | public function i_expand_all_fieldsets() { | |
123 | $this->expand_all_fields(); | |
124 | } | |
125 | ||
126 | /** | |
127 | * Expands all moodle form fieldsets if they exists. | |
128 | * | |
129 | * Externalized from i_expand_all_fields to call it from | |
130 | * other form-related steps without having to use steps-group calls. | |
131 | * | |
132 | * @throws ElementNotFoundException Thrown by behat_base::find_all | |
133 | * @return void | |
134 | */ | |
135 | protected function expand_all_fields() { | |
20153f63 RT |
136 | // Expand only if JS mode, else not needed. |
137 | if (!$this->running_javascript()) { | |
138 | return; | |
139 | } | |
f8f1bdc3 | 140 | |
74c78e74 DM |
141 | // We already know that we waited for the DOM and the JS to be loaded, even the editor |
142 | // so, we will use the reduced timeout as it is a common task and we should save time. | |
f8f1bdc3 DM |
143 | try { |
144 | ||
1872cfcd TH |
145 | // Expand all fieldsets link - which will only be there if there is more than one collapsible section. |
146 | $expandallxpath = "//div[@class='collapsible-actions']" . | |
147 | "//a[contains(concat(' ', @class, ' '), ' collapseexpand ')]" . | |
74c78e74 | 148 | "[not(contains(concat(' ', @class, ' '), ' collapse-all '))]"; |
1872cfcd TH |
149 | // Else, look for the first expand fieldset link. |
150 | $expandonlysection = "//legend[@class='ftoggler']" . | |
151 | "//a[contains(concat(' ', @class, ' '), ' fheader ') and @aria-expanded = 'false']"; | |
152 | ||
153 | $collapseexpandlink = $this->find('xpath', $expandallxpath . '|' . $expandonlysection, | |
05a5d547 | 154 | false, false, behat_base::get_reduced_timeout()); |
8cda2e6f | 155 | $collapseexpandlink->click(); |
f8f1bdc3 DM |
156 | |
157 | } catch (ElementNotFoundException $e) { | |
74c78e74 DM |
158 | // The behat_base::find() method throws an exception if there are no elements, |
159 | // we should not fail a test because of this. We continue if there are not expandable fields. | |
f8f1bdc3 DM |
160 | } |
161 | ||
162 | // Different try & catch as we can have expanded fieldsets with advanced fields on them. | |
163 | try { | |
164 | ||
8cda2e6f DM |
165 | // Expand all fields xpath. |
166 | $showmorexpath = "//a[normalize-space(.)='" . get_string('showmore', 'form') . "']" . | |
167 | "[contains(concat(' ', normalize-space(@class), ' '), ' moreless-toggler')]"; | |
f8f1bdc3 | 168 | |
8cda2e6f | 169 | // We don't wait here as we already waited when getting the expand fieldsets links. |
74c78e74 DM |
170 | if (!$showmores = $this->getSession()->getPage()->findAll('xpath', $showmorexpath)) { |
171 | return; | |
172 | } | |
f8f1bdc3 | 173 | |
7cde2bb3 MN |
174 | if ($this->getSession()->getDriver() instanceof \DMore\ChromeDriver\ChromeDriver) { |
175 | // Chrome Driver produces unique xpaths for each element. | |
176 | foreach ($showmores as $showmore) { | |
177 | $showmore->click(); | |
178 | } | |
179 | } else { | |
180 | // Funny thing about this, with findAll() we specify a pattern and each element matching the pattern | |
181 | // is added to the array with of xpaths with a [0], [1]... sufix, but when we click on an element it | |
182 | // does not matches the specified xpath anymore (now is a "Show less..." link) so [1] becomes [0], | |
183 | // that's why we always click on the first XPath match, will be always the next one. | |
184 | $iterations = count($showmores); | |
185 | for ($i = 0; $i < $iterations; $i++) { | |
186 | $showmores[0]->click(); | |
187 | } | |
f8f1bdc3 DM |
188 | } |
189 | ||
190 | } catch (ElementNotFoundException $e) { | |
191 | // We continue with the test. | |
192 | } | |
193 | ||
194 | } | |
195 | ||
01e8bfd7 JO |
196 | /** |
197 | * Sets the field to wwwroot plus the given path. Include the first slash. | |
198 | * | |
199 | * @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to local url "(?P<field_path_string>(?:[^"]|\\")*)"$/ | |
200 | * @throws ElementNotFoundException Thrown by behat_base::find | |
201 | * @param string $field | |
202 | * @param string $path | |
203 | * @return void | |
204 | */ | |
205 | public function i_set_the_field_to_local_url($field, $path) { | |
206 | global $CFG; | |
207 | $this->set_field_value($field, $CFG->wwwroot . $path); | |
208 | } | |
209 | ||
23ebc481 | 210 | /** |
a5254141 | 211 | * Sets the specified value to the field. |
23ebc481 | 212 | * |
decf1e14 | 213 | * @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to "(?P<field_value_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb | 214 | * @throws ElementNotFoundException Thrown by behat_base::find |
46ac40cd DM |
215 | * @param string $field |
216 | * @param string $value | |
a5254141 | 217 | * @return void |
23ebc481 | 218 | */ |
a5254141 | 219 | public function i_set_the_field_to($field, $value) { |
c3f1e953 | 220 | $this->set_field_value($field, $value); |
23ebc481 DM |
221 | } |
222 | ||
920a3500 TH |
223 | /** |
224 | * Sets the specified value to the field. | |
225 | * | |
226 | * @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" to "(?P<field_value_string>(?:[^"]|\\")*)"$/ | |
227 | * @throws ElementNotFoundException Thrown by behat_base::find | |
228 | * @param string $field | |
229 | * @param string $containerelement Element we look in | |
230 | * @param string $containerselectortype The type of selector where we look in | |
231 | * @param string $value | |
232 | */ | |
233 | public function i_set_the_field_in_container_to($field, $containerelement, $containerselectortype, $value) { | |
234 | $this->set_field_value_in_container($field, $value, $containerselectortype, $containerelement); | |
235 | } | |
236 | ||
0cf72524 MG |
237 | /** |
238 | * Press the key in the field to trigger the javascript keypress event | |
239 | * | |
240 | * Note that the character key will not actually be typed in the input field | |
241 | * | |
242 | * @Given /^I press key "(?P<key_string>(?:[^"]|\\")*)" in the field "(?P<field_string>(?:[^"]|\\")*)"$/ | |
243 | * @throws ElementNotFoundException Thrown by behat_base::find | |
244 | * @param string $key either char-code or character itself, | |
245 | * may optionally be prefixed with ctrl-, alt-, shift- or meta- | |
246 | * @param string $field | |
247 | * @return void | |
248 | */ | |
249 | public function i_press_key_in_the_field($key, $field) { | |
250 | if (!$this->running_javascript()) { | |
8a6900ff | 251 | throw new DriverException('Key press step is not available with Javascript disabled'); |
0cf72524 MG |
252 | } |
253 | $fld = behat_field_manager::get_form_field_from_label($field, $this); | |
254 | $modifier = null; | |
255 | $char = $key; | |
256 | if (preg_match('/-/', $key)) { | |
257 | list($modifier, $char) = preg_split('/-/', $key, 2); | |
258 | } | |
259 | if (is_numeric($char)) { | |
260 | $char = (int)$char; | |
261 | } | |
262 | $fld->key_press($char, $modifier); | |
263 | } | |
264 | ||
9776f3dc JO |
265 | /** |
266 | * Sets the specified value to the field. | |
267 | * | |
e259795c | 268 | * @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" to multiline:$/ |
9776f3dc JO |
269 | * @throws ElementNotFoundException Thrown by behat_base::find |
270 | * @param string $field | |
271 | * @param PyStringNode $value | |
272 | * @return void | |
273 | */ | |
274 | public function i_set_the_field_to_multiline($field, PyStringNode $value) { | |
275 | $this->set_field_value($field, (string)$value); | |
276 | } | |
277 | ||
6c396b6b RT |
278 | /** |
279 | * Sets the specified value to the field with xpath. | |
280 | * | |
281 | * @Given /^I set the field with xpath "(?P<fieldxpath_string>(?:[^"]|\\")*)" to "(?P<field_value_string>(?:[^"]|\\")*)"$/ | |
282 | * @throws ElementNotFoundException Thrown by behat_base::find | |
283 | * @param string $field | |
284 | * @param string $value | |
285 | * @return void | |
286 | */ | |
287 | public function i_set_the_field_with_xpath_to($fieldxpath, $value) { | |
2c376776 | 288 | $this->set_field_node_value($this->find('xpath', $fieldxpath), $value); |
6c396b6b RT |
289 | } |
290 | ||
23ebc481 | 291 | /** |
d1ac356a | 292 | * Checks, the field matches the value. |
23ebc481 | 293 | * |
decf1e14 | 294 | * @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" matches value "(?P<field_value_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb | 295 | * @throws ElementNotFoundException Thrown by behat_base::find |
a5254141 | 296 | * @param string $field |
46ac40cd | 297 | * @param string $value |
a5254141 | 298 | * @return void |
23ebc481 | 299 | */ |
a5254141 | 300 | public function the_field_matches_value($field, $value) { |
23ebc481 | 301 | |
49d91129 | 302 | // Get the field. |
af4830a2 | 303 | $formfield = behat_field_manager::get_form_field_from_label($field, $this); |
23ebc481 DM |
304 | |
305 | // Checks if the provided value matches the current field value. | |
a5254141 DM |
306 | if (!$formfield->matches($value)) { |
307 | $fieldvalue = $formfield->get_value(); | |
23ebc481 | 308 | throw new ExpectationException( |
a5254141 | 309 | 'The \'' . $field . '\' value is \'' . $fieldvalue . '\', \'' . $value . '\' expected' , |
d9fddb0b AH |
310 | $this->getSession() |
311 | ); | |
312 | } | |
313 | } | |
314 | ||
315 | /** | |
d1ac356a | 316 | * Checks, the field does not match the value. |
267033a9 T |
317 | * |
318 | * @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" does not match value "(?P<field_value_string>(?:[^"]|\\")*)"$/ | |
319 | * @throws ExpectationException | |
320 | * @throws ElementNotFoundException Thrown by behat_base::find | |
321 | * @param string $field | |
322 | * @param string $value | |
267033a9 T |
323 | */ |
324 | public function the_field_does_not_match_value($field, $value) { | |
325 | ||
326 | // Get the field. | |
327 | $formfield = behat_field_manager::get_form_field_from_label($field, $this); | |
328 | ||
329 | // Checks if the provided value matches the current field value. | |
330 | if ($formfield->matches($value)) { | |
331 | throw new ExpectationException( | |
332 | 'The \'' . $field . '\' value matches \'' . $value . '\' and it should not match it' , | |
333 | $this->getSession() | |
334 | ); | |
335 | } | |
336 | } | |
337 | ||
920a3500 TH |
338 | /** |
339 | * Checks, the field matches the value. | |
340 | * | |
341 | * @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" matches value "(?P<field_value_string>(?:[^"]|\\")*)"$/ | |
342 | * @throws ElementNotFoundException Thrown by behat_base::find | |
343 | * @param string $field | |
344 | * @param string $containerelement Element we look in | |
345 | * @param string $containerselectortype The type of selector where we look in | |
346 | * @param string $value | |
347 | */ | |
348 | public function the_field_in_container_matches_value($field, $containerelement, $containerselectortype, $value) { | |
349 | ||
350 | // Get the field. | |
351 | $node = $this->get_node_in_container('field', $field, $containerselectortype, $containerelement); | |
352 | $formfield = behat_field_manager::get_form_field($node, $this->getSession()); | |
353 | ||
354 | // Checks if the provided value matches the current field value. | |
355 | if (!$formfield->matches($value)) { | |
356 | $fieldvalue = $formfield->get_value(); | |
357 | throw new ExpectationException( | |
358 | 'The \'' . $field . '\' value is \'' . $fieldvalue . '\', \'' . $value . '\' expected' , | |
359 | $this->getSession() | |
360 | ); | |
361 | } | |
362 | } | |
363 | ||
364 | /** | |
365 | * Checks, the field does not match the value. | |
366 | * | |
367 | * @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" does not match value "(?P<field_value_string>(?:[^"]|\\")*)"$/ | |
368 | * @throws ExpectationException | |
369 | * @throws ElementNotFoundException Thrown by behat_base::find | |
370 | * @param string $field | |
371 | * @param string $containerelement Element we look in | |
372 | * @param string $containerselectortype The type of selector where we look in | |
373 | * @param string $value | |
374 | */ | |
375 | public function the_field_in_container_does_not_match_value($field, $containerelement, $containerselectortype, $value) { | |
376 | ||
377 | // Get the field. | |
378 | $node = $this->get_node_in_container('field', $field, $containerselectortype, $containerelement); | |
379 | $formfield = behat_field_manager::get_form_field($node, $this->getSession()); | |
380 | ||
381 | // Checks if the provided value matches the current field value. | |
382 | if ($formfield->matches($value)) { | |
383 | throw new ExpectationException( | |
384 | 'The \'' . $field . '\' value matches \'' . $value . '\' and it should not match it' , | |
385 | $this->getSession() | |
386 | ); | |
387 | } | |
388 | } | |
389 | ||
267033a9 T |
390 | /** |
391 | * Checks, the field matches the value. | |
d9fddb0b | 392 | * |
267033a9 T |
393 | * @Then /^the field with xpath "(?P<xpath_string>(?:[^"]|\\")*)" matches value "(?P<field_value_string>(?:[^"]|\\")*)"$/ |
394 | * @throws ExpectationException | |
d9fddb0b AH |
395 | * @throws ElementNotFoundException Thrown by behat_base::find |
396 | * @param string $fieldxpath | |
397 | * @param string $value | |
398 | * @return void | |
399 | */ | |
400 | public function the_field_with_xpath_matches_value($fieldxpath, $value) { | |
401 | ||
402 | // Get the field. | |
403 | $fieldnode = $this->find('xpath', $fieldxpath); | |
404 | $formfield = behat_field_manager::get_form_field($fieldnode, $this->getSession()); | |
405 | ||
406 | // Checks if the provided value matches the current field value. | |
407 | if (!$formfield->matches($value)) { | |
408 | $fieldvalue = $formfield->get_value(); | |
409 | throw new ExpectationException( | |
410 | 'The \'' . $fieldxpath . '\' value is \'' . $fieldvalue . '\', \'' . $value . '\' expected' , | |
23ebc481 DM |
411 | $this->getSession() |
412 | ); | |
413 | } | |
414 | } | |
415 | ||
c3f1e953 | 416 | /** |
267033a9 | 417 | * Checks, the field does not match the value. |
c3f1e953 | 418 | * |
267033a9 | 419 | * @Then /^the field with xpath "(?P<xpath_string>(?:[^"]|\\")*)" does not match value "(?P<field_value_string>(?:[^"]|\\")*)"$/ |
c3f1e953 DM |
420 | * @throws ExpectationException |
421 | * @throws ElementNotFoundException Thrown by behat_base::find | |
267033a9 | 422 | * @param string $fieldxpath |
c3f1e953 DM |
423 | * @param string $value |
424 | * @return void | |
425 | */ | |
267033a9 | 426 | public function the_field_with_xpath_does_not_match_value($fieldxpath, $value) { |
c3f1e953 | 427 | |
c3f1e953 | 428 | // Get the field. |
267033a9 T |
429 | $fieldnode = $this->find('xpath', $fieldxpath); |
430 | $formfield = behat_field_manager::get_form_field($fieldnode, $this->getSession()); | |
c3f1e953 DM |
431 | |
432 | // Checks if the provided value matches the current field value. | |
a5254141 | 433 | if ($formfield->matches($value)) { |
c3f1e953 | 434 | throw new ExpectationException( |
267033a9 | 435 | 'The \'' . $fieldxpath . '\' value matches \'' . $value . '\' and it should not match it' , |
c3f1e953 DM |
436 | $this->getSession() |
437 | ); | |
438 | } | |
439 | } | |
440 | ||
441 | /** | |
d1ac356a | 442 | * Checks, the provided field/value matches. |
c3f1e953 DM |
443 | * |
444 | * @Then /^the following fields match these values:$/ | |
445 | * @throws ExpectationException | |
a5254141 | 446 | * @param TableNode $data Pairs of | field | value | |
c3f1e953 DM |
447 | */ |
448 | public function the_following_fields_match_these_values(TableNode $data) { | |
449 | ||
450 | // Expand all fields in case we have. | |
451 | $this->expand_all_fields(); | |
452 | ||
453 | $datahash = $data->getRowsHash(); | |
454 | ||
455 | // The action depends on the field type. | |
456 | foreach ($datahash as $locator => $value) { | |
a5254141 | 457 | $this->the_field_matches_value($locator, $value); |
c3f1e953 DM |
458 | } |
459 | } | |
460 | ||
461 | /** | |
d1ac356a | 462 | * Checks that the provided field/value pairs don't match. |
c3f1e953 DM |
463 | * |
464 | * @Then /^the following fields do not match these values:$/ | |
465 | * @throws ExpectationException | |
a5254141 | 466 | * @param TableNode $data Pairs of | field | value | |
c3f1e953 DM |
467 | */ |
468 | public function the_following_fields_do_not_match_these_values(TableNode $data) { | |
469 | ||
470 | // Expand all fields in case we have. | |
471 | $this->expand_all_fields(); | |
472 | ||
473 | $datahash = $data->getRowsHash(); | |
474 | ||
475 | // The action depends on the field type. | |
476 | foreach ($datahash as $locator => $value) { | |
477 | $this->the_field_does_not_match_value($locator, $value); | |
478 | } | |
479 | } | |
480 | ||
920a3500 TH |
481 | /** |
482 | * Checks, the provided field/value matches. | |
483 | * | |
484 | * @Then /^the following fields in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" match these values:$/ | |
485 | * @throws ExpectationException | |
486 | * @param string $containerelement Element we look in | |
487 | * @param string $containerselectortype The type of selector where we look in | |
488 | * @param TableNode $data Pairs of | field | value | | |
489 | */ | |
490 | public function the_following_fields_in_container_match_these_values( | |
491 | $containerelement, $containerselectortype, TableNode $data) { | |
492 | ||
493 | // Expand all fields in case we have. | |
494 | $this->expand_all_fields(); | |
495 | ||
496 | $datahash = $data->getRowsHash(); | |
497 | ||
498 | // The action depends on the field type. | |
499 | foreach ($datahash as $locator => $value) { | |
500 | $this->the_field_in_container_matches_value($locator, $containerelement, $containerselectortype, $value); | |
501 | } | |
502 | } | |
503 | ||
504 | /** | |
505 | * Checks that the provided field/value pairs don't match. | |
506 | * | |
507 | * @Then /^the following fields in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" do not match these values:$/ | |
508 | * @throws ExpectationException | |
509 | * @param string $containerelement Element we look in | |
510 | * @param string $containerselectortype The type of selector where we look in | |
511 | * @param TableNode $data Pairs of | field | value | | |
512 | */ | |
513 | public function the_following_fields_in_container_do_not_match_these_values( | |
514 | $containerelement, $containerselectortype, TableNode $data) { | |
515 | ||
516 | // Expand all fields in case we have. | |
517 | $this->expand_all_fields(); | |
518 | ||
519 | $datahash = $data->getRowsHash(); | |
520 | ||
521 | // The action depends on the field type. | |
522 | foreach ($datahash as $locator => $value) { | |
523 | $this->the_field_in_container_does_not_match_value($locator, $containerelement, $containerselectortype, $value); | |
524 | } | |
525 | } | |
526 | ||
23ebc481 DM |
527 | /** |
528 | * Checks, that given select box contains the specified option. | |
529 | * | |
23ebc481 | 530 | * @Then /^the "(?P<select_string>(?:[^"]|\\")*)" select box should contain "(?P<option_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb DM |
531 | * @throws ExpectationException |
532 | * @throws ElementNotFoundException Thrown by behat_base::find | |
23ebc481 | 533 | * @param string $select The select element name |
5f66d46e EL |
534 | * @param string $option The option text/value. Plain value or comma separated |
535 | * values if multiple. Commas in multiple values escaped with backslash. | |
23ebc481 DM |
536 | */ |
537 | public function the_select_box_should_contain($select, $option) { | |
538 | ||
1f9ffbdb | 539 | $selectnode = $this->find_field($select); |
5f66d46e EL |
540 | $multiple = $selectnode->hasAttribute('multiple'); |
541 | $optionsarr = array(); // Array of passed value/text options to test. | |
23ebc481 | 542 | |
5f66d46e EL |
543 | if ($multiple) { |
544 | // Can pass multiple comma separated, with valuable commas escaped with backslash. | |
545 | foreach (preg_replace('/\\\,/', ',', preg_split('/(?<!\\\),/', $option)) as $opt) { | |
546 | $optionsarr[] = trim($opt); | |
547 | } | |
548 | } else { | |
549 | // Only one option has been passed. | |
550 | $optionsarr[] = trim($option); | |
551 | } | |
552 | ||
553 | // Now get all the values and texts in the select. | |
554 | $options = $selectnode->findAll('xpath', '//option'); | |
555 | $values = array(); | |
556 | foreach ($options as $opt) { | |
557 | $values[trim($opt->getValue())] = trim($opt->getText()); | |
23ebc481 DM |
558 | } |
559 | ||
5f66d46e EL |
560 | foreach ($optionsarr as $opt) { |
561 | // Verify every option is a valid text or value. | |
562 | if (!in_array($opt, $values) && !array_key_exists($opt, $values)) { | |
563 | throw new ExpectationException( | |
564 | 'The select box "' . $select . '" does not contain the option "' . $opt . '"', | |
565 | $this->getSession() | |
566 | ); | |
567 | } | |
568 | } | |
23ebc481 DM |
569 | } |
570 | ||
571 | /** | |
572 | * Checks, that given select box does not contain the specified option. | |
573 | * | |
23ebc481 | 574 | * @Then /^the "(?P<select_string>(?:[^"]|\\")*)" select box should not contain "(?P<option_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb DM |
575 | * @throws ExpectationException |
576 | * @throws ElementNotFoundException Thrown by behat_base::find | |
23ebc481 | 577 | * @param string $select The select element name |
5f66d46e EL |
578 | * @param string $option The option text/value. Plain value or comma separated |
579 | * values if multiple. Commas in multiple values escaped with backslash. | |
23ebc481 DM |
580 | */ |
581 | public function the_select_box_should_not_contain($select, $option) { | |
582 | ||
1f9ffbdb | 583 | $selectnode = $this->find_field($select); |
5f66d46e EL |
584 | $multiple = $selectnode->hasAttribute('multiple'); |
585 | $optionsarr = array(); // Array of passed value/text options to test. | |
23ebc481 | 586 | |
5f66d46e EL |
587 | if ($multiple) { |
588 | // Can pass multiple comma separated, with valuable commas escaped with backslash. | |
589 | foreach (preg_replace('/\\\,/', ',', preg_split('/(?<!\\\),/', $option)) as $opt) { | |
590 | $optionsarr[] = trim($opt); | |
591 | } | |
592 | } else { | |
593 | // Only one option has been passed. | |
594 | $optionsarr[] = trim($option); | |
595 | } | |
596 | ||
597 | // Now get all the values and texts in the select. | |
598 | $options = $selectnode->findAll('xpath', '//option'); | |
599 | $values = array(); | |
600 | foreach ($options as $opt) { | |
601 | $values[trim($opt->getValue())] = trim($opt->getText()); | |
602 | } | |
603 | ||
604 | foreach ($optionsarr as $opt) { | |
605 | // Verify every option is not a valid text or value. | |
606 | if (in_array($opt, $values) || array_key_exists($opt, $values)) { | |
607 | throw new ExpectationException( | |
608 | 'The select box "' . $select . '" contains the option "' . $opt . '"', | |
609 | $this->getSession() | |
610 | ); | |
611 | } | |
612 | } | |
613 | } | |
614 | ||
615 | /** | |
c3f1e953 | 616 | * Generic field setter. |
5f66d46e | 617 | * |
c3f1e953 DM |
618 | * Internal API method, a generic *I set "VALUE" to "FIELD" field* |
619 | * could be created based on it. | |
5f66d46e | 620 | * |
c3f1e953 DM |
621 | * @param string $fieldlocator The pointer to the field, it will depend on the field type. |
622 | * @param string $value | |
623 | * @return void | |
5f66d46e | 624 | */ |
c3f1e953 | 625 | protected function set_field_value($fieldlocator, $value) { |
c3f1e953 DM |
626 | // We delegate to behat_form_field class, it will |
627 | // guess the type properly as it is a select tag. | |
af4830a2 | 628 | $field = behat_field_manager::get_form_field_from_label($fieldlocator, $this); |
c3f1e953 | 629 | $field->set_value($value); |
23ebc481 DM |
630 | } |
631 | ||
2c376776 AN |
632 | /** |
633 | * Generic field setter to be used by chainable steps. | |
634 | * | |
635 | * @param NodeElement $fieldnode | |
636 | * @param string $value | |
637 | */ | |
638 | public function set_field_node_value(NodeElement $fieldnode, string $value): void { | |
639 | $this->ensure_node_is_visible($fieldnode); | |
640 | $field = behat_field_manager::get_form_field($fieldnode, $this->getSession()); | |
641 | $field->set_value($value); | |
642 | } | |
643 | ||
920a3500 TH |
644 | /** |
645 | * Generic field setter. | |
646 | * | |
647 | * Internal API method, a generic *I set "VALUE" to "FIELD" field* | |
648 | * could be created based on it. | |
649 | * | |
650 | * @param string $fieldlocator The pointer to the field, it will depend on the field type. | |
651 | * @param string $value the value to set | |
652 | * @param string $containerselectortype The type of selector where we look in | |
653 | * @param string $containerelement Element we look in | |
654 | */ | |
655 | protected function set_field_value_in_container($fieldlocator, $value, $containerselectortype, $containerelement) { | |
920a3500 | 656 | $node = $this->get_node_in_container('field', $fieldlocator, $containerselectortype, $containerelement); |
2c376776 | 657 | $this->set_field_node_value($node, $value); |
920a3500 TH |
658 | } |
659 | ||
2b964e1d AN |
660 | /** |
661 | * Select a value from single select and redirect. | |
662 | * | |
663 | * @Given /^I select "(?P<singleselect_option_string>(?:[^"]|\\")*)" from the "(?P<singleselect_name_string>(?:[^"]|\\")*)" singleselect$/ | |
664 | */ | |
665 | public function i_select_from_the_singleselect($option, $singleselect) { | |
eb9ca848 RT |
666 | |
667 | $this->execute('behat_forms::i_set_the_field_to', array($this->escape($singleselect), $this->escape($option))); | |
2b964e1d AN |
668 | |
669 | if (!$this->running_javascript()) { | |
bf4c3ee0 | 670 | // Press button in the specified select container. |
bc7a5953 RT |
671 | $containerxpath = "//div[" . |
672 | "(contains(concat(' ', normalize-space(@class), ' '), ' singleselect ') " . | |
673 | "or contains(concat(' ', normalize-space(@class), ' '), ' urlselect ')". | |
674 | ") and ( | |
675 | .//label[contains(normalize-space(string(.)), '" . $singleselect . "')] " . | |
676 | "or .//select[(./@name='" . $singleselect . "' or ./@id='". $singleselect . "')]" . | |
677 | ")]"; | |
bf4c3ee0 | 678 | |
eb9ca848 RT |
679 | $this->execute('behat_general::i_click_on_in_the', |
680 | array(get_string('go'), "button", $containerxpath, "xpath_element") | |
681 | ); | |
2b964e1d | 682 | } |
2b964e1d AN |
683 | } |
684 | ||
dda64b6f DW |
685 | /** |
686 | * Select item from autocomplete list. | |
687 | * | |
688 | * @Given /^I click on "([^"]*)" item in the autocomplete list$/ | |
689 | * | |
690 | * @param string $item | |
691 | */ | |
692 | public function i_click_on_item_in_the_autocomplete_list($item) { | |
d29be320 | 693 | $xpathtarget = "//ul[@class='form-autocomplete-suggestions']//*[contains(concat('|', string(.), '|'),'|" . $item . "|')]"; |
dda64b6f DW |
694 | |
695 | $this->execute('behat_general::i_click_on', [$xpathtarget, 'xpath_element']); | |
dda64b6f DW |
696 | } |
697 | ||
698 | /** | |
699 | * Open the auto-complete suggestions list (Assuming there is only one on the page.). | |
700 | * | |
701 | * @Given /^I open the autocomplete suggestions list$/ | |
702 | */ | |
703 | public function i_open_the_autocomplete_suggestions_list() { | |
704 | $csstarget = ".form-autocomplete-downarrow"; | |
705 | $this->execute('behat_general::i_click_on', [$csstarget, 'css_element']); | |
706 | } | |
0fc30827 HN |
707 | |
708 | /** | |
709 | * Expand the given autocomplete list | |
710 | * | |
711 | * @Given /^I expand the "(?P<field_string>(?:[^"]|\\")*)" autocomplete$/ | |
712 | * | |
713 | * @param string $field Field name | |
714 | */ | |
715 | public function i_expand_the_autocomplete($field) { | |
716 | $csstarget = '.form-autocomplete-downarrow'; | |
717 | $node = $this->get_node_in_container('css_element', $csstarget, 'form_row', $field); | |
718 | $this->ensure_node_is_visible($node); | |
719 | $node->click(); | |
720 | } | |
721 | ||
722 | /** | |
723 | * Assert the given option exist in the given autocomplete list | |
724 | * | |
725 | * @Given /^I should see "(?P<option_string>(?:[^"]|\\")*)" in the list of options for the "(?P<field_string>(?:[^"]|\\")*)" autocomplete$$/ | |
726 | * | |
727 | * @param string $option Name of option | |
728 | * @param string $field Field name | |
729 | */ | |
730 | public function i_should_see_in_the_list_of_option_for_the_autocomplete($option, $field) { | |
731 | $xpathtarget = "//div[contains(@class, 'form-autocomplete-selection') and contains(.//div, '" . $option . "')]"; | |
732 | $node = $this->get_node_in_container('xpath_element', $xpathtarget, 'form_row', $field); | |
733 | $this->ensure_node_is_visible($node); | |
734 | } | |
23ebc481 | 735 | } |