Commit | Line | Data |
---|---|---|
60a1ea56 DW |
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 | * Auto complete form field class. | |
19 | * | |
20 | * @package core_form | |
21 | * @category test | |
22 | * @copyright 2015 Damyon Wiese | |
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_text.php'); | |
29 | ||
30 | /** | |
31 | * Auto complete form field. | |
32 | * | |
33 | * @package core_form | |
34 | * @category test | |
35 | * @copyright 2015 Damyon Wiese | |
36 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
37 | */ | |
38 | class behat_form_autocomplete extends behat_form_text { | |
39 | ||
40 | /** | |
41 | * Sets the value to a field. | |
42 | * | |
43 | * @param string $value | |
44 | * @return void | |
45 | */ | |
46 | public function set_value($value) { | |
47 | if (!$this->running_javascript()) { | |
1d26a183 | 48 | throw new coding_exception('Setting the value of an autocomplete field requires javascript.'); |
60a1ea56 | 49 | } |
e994dea0 | 50 | |
f07d3b71 AN |
51 | // Clear all current selections. |
52 | $rootnode = $this->field->getParent()->getParent(); | |
53 | $selections = $rootnode->findAll('css', '.form-autocomplete-selection [role=option]'); | |
54 | foreach ($selections as $selection) { | |
55 | $selection->click(); | |
56 | $this->wait_for_pending_js(); | |
57 | } | |
e994dea0 | 58 | |
f07d3b71 AN |
59 | $allowscreation = $this->field->hasAttribute('data-tags') && !empty($this->field->getAttribute('data-tags')); |
60 | $hasmultiple = $this->field->hasAttribute('data-multiple') && !empty($this->field->getAttribute('data-multiple')); | |
e994dea0 | 61 | |
f07d3b71 AN |
62 | if ($hasmultiple && false !== strpos($value, ',')) { |
63 | // Commas have a special meaning as a value separator in 'multiple' autocomplete elements. | |
e994dea0 AN |
64 | // To handle this we break the value up by comma, and enter it in chunks. |
65 | $values = explode(',', $value); | |
66 | ||
67 | while ($value = array_shift($values)) { | |
f07d3b71 | 68 | $this->add_value(trim($value), $allowscreation); |
e994dea0 AN |
69 | } |
70 | } else { | |
f07d3b71 AN |
71 | $this->add_value(trim($value), $allowscreation); |
72 | } | |
73 | } | |
e994dea0 | 74 | |
f07d3b71 AN |
75 | /** |
76 | * Add a value to the autocomplete. | |
77 | * | |
78 | * @param string $value | |
79 | * @param bool $allowscreation | |
80 | */ | |
81 | protected function add_value(string $value, bool $allowscreation): void { | |
82 | $value = trim($value); | |
ba34d6e2 | 83 | |
f07d3b71 AN |
84 | // Click into the field. |
85 | $this->field->click(); | |
86 | ||
87 | // Remove any existing text. | |
88 | do { | |
89 | behat_base::type_keys($this->session, [behat_keys::BACKSPACE, behat_keys::DELETE]); | |
90 | } while (strlen($this->field->getValue()) > 0); | |
91 | $this->wait_for_pending_js(); | |
92 | ||
93 | // Type in the new value. | |
94 | behat_base::type_keys($this->session, str_split($value)); | |
95 | $this->wait_for_pending_js(); | |
96 | ||
97 | // If the autocomplete found suggestions, then it will have: | |
98 | // 1) marked itself as expanded; and | |
99 | // 2) have an aria-selected suggestion in the list. | |
100 | $expanded = $this->field->getAttribute('aria-expanded'); | |
101 | $suggestion = $this->field->getParent()->getParent()->find('css', '.form-autocomplete-suggestions > [aria-selected="true"]'); | |
102 | ||
103 | if ($expanded && null !== $suggestion) { | |
104 | // A suggestion was found. | |
105 | // Click on the first item in the list. | |
106 | $suggestion->click(); | |
107 | } else if ($allowscreation) { | |
108 | // Press the return key to create a new entry. | |
109 | behat_base::type_keys($this->session, [behat_keys::ENTER]); | |
110 | } else { | |
111 | throw new \InvalidArgumentException( | |
112 | "Unable to find '{$value}' in the list of options, and unable to create a new option" | |
113 | ); | |
e994dea0 | 114 | } |
f07d3b71 AN |
115 | |
116 | $this->wait_for_pending_js(); | |
117 | ||
118 | // Press the escape to close the autocomplete suggestions list. | |
119 | behat_base::type_keys($this->session, [behat_keys::ESCAPE]); | |
120 | $this->wait_for_pending_js(); | |
60a1ea56 DW |
121 | } |
122 | } |