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'); | |
29 | ||
30 | use Behat\Behat\Context\Step\Given as Given, | |
31 | Behat\Behat\Context\Step\When as When, | |
32 | Behat\Behat\Context\Step\Then as Then, | |
33 | Behat\Gherkin\Node\TableNode as TableNode, | |
34 | Behat\Mink\Element\NodeElement as NodeElement, | |
35 | Behat\Mink\Exception\ExpectationException as ExpectationException, | |
36 | Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException; | |
37 | ||
38 | /** | |
39 | * Forms-related steps definitions. | |
40 | * | |
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 |
23ebc481 DM |
53 | */ |
54 | public function press_button($button) { | |
1f9ffbdb DM |
55 | |
56 | // Ensures the button is present. | |
57 | $buttonnode = $this->find_button($button); | |
58 | $buttonnode->press(); | |
23ebc481 DM |
59 | } |
60 | ||
61 | /** | |
62 | * Fills a moodle form with field/value data. | |
63 | * | |
23ebc481 | 64 | * @Given /^I fill the moodle form with:$/ |
1f9ffbdb | 65 | * @throws ElementNotFoundException Thrown by behat_base::find |
23ebc481 DM |
66 | * @param TableNode $data |
67 | */ | |
68 | public function i_fill_the_moodle_form_with(TableNode $data) { | |
69 | ||
70 | $datahash = $data->getRowsHash(); | |
71 | ||
72 | // The action depends on the field type. | |
73 | foreach ($datahash as $locator => $value) { | |
74 | ||
75 | unset($fieldnode); | |
76 | ||
1f9ffbdb DM |
77 | // Getting the NodeElement. |
78 | $fieldnode = $this->find_field($locator); | |
23ebc481 DM |
79 | |
80 | // Gets the field type from a parent node. | |
81 | $field = $this->get_field($fieldnode, $locator); | |
82 | ||
83 | // Delegates to the field class. | |
23ebc481 DM |
84 | $field->set_value($value); |
85 | } | |
86 | } | |
87 | ||
88 | /** | |
89 | * Fills in form field with specified id|name|label|value. | |
90 | * | |
23ebc481 | 91 | * @When /^I fill in "(?P<field_string>(?:[^"]|\\")*)" with "(?P<value_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb | 92 | * @throws ElementNotFoundException Thrown by behat_base::find |
23ebc481 DM |
93 | */ |
94 | public function fill_field($field, $value) { | |
1f9ffbdb DM |
95 | |
96 | $fieldnode = $this->find_field($field); | |
97 | $fieldnode->setValue($value); | |
23ebc481 DM |
98 | } |
99 | ||
100 | /** | |
101 | * Selects option in select field with specified id|name|label|value. | |
102 | * | |
23ebc481 | 103 | * @When /^I select "(?P<option_string>(?:[^"]|\\")*)" from "(?P<select_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb | 104 | * @throws ElementNotFoundException Thrown by behat_base::find |
23ebc481 DM |
105 | */ |
106 | public function select_option($option, $select) { | |
23ebc481 | 107 | |
1f9ffbdb | 108 | $selectnode = $this->find_field($select); |
23ebc481 | 109 | $selectnode->selectOption($option); |
1f9ffbdb DM |
110 | |
111 | // Adding a click as Selenium requires it to fire some JS events. | |
23ebc481 DM |
112 | $selectnode->click(); |
113 | } | |
114 | ||
115 | /** | |
116 | * Checks checkbox with specified id|name|label|value. | |
117 | * | |
23ebc481 | 118 | * @When /^I check "(?P<option_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb | 119 | * @throws ElementNotFoundException Thrown by behat_base::find |
23ebc481 DM |
120 | */ |
121 | public function check_option($option) { | |
1f9ffbdb DM |
122 | |
123 | $checkboxnode = $this->find_field($option); | |
124 | $checkboxnode->check(); | |
23ebc481 DM |
125 | } |
126 | ||
127 | /** | |
128 | * Unchecks checkbox with specified id|name|label|value. | |
129 | * | |
23ebc481 | 130 | * @When /^I uncheck "(?P<option_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb | 131 | * @throws ElementNotFoundException Thrown by behat_base::find |
23ebc481 DM |
132 | */ |
133 | public function uncheck_option($option) { | |
1f9ffbdb DM |
134 | |
135 | $checkboxnode = $this->find_field($option); | |
136 | $checkboxnode->uncheck(); | |
23ebc481 DM |
137 | } |
138 | ||
139 | /** | |
140 | * Checks that the form element field have the specified value. | |
141 | * | |
23ebc481 | 142 | * @Then /^the "(?P<field_string>(?:[^"]|\\")*)" field should match "(?P<value_string>(?:[^"]|\\")*)" value$/ |
1f9ffbdb DM |
143 | * @throws ExpectationException |
144 | * @throws ElementNotFoundException Thrown by behat_base::find | |
23ebc481 DM |
145 | * @param mixed $locator |
146 | * @param mixed $value | |
147 | */ | |
148 | public function the_field_should_match_value($locator, $value) { | |
149 | ||
1f9ffbdb | 150 | $fieldnode = $this->find_field($locator); |
23ebc481 DM |
151 | |
152 | // Gets the field instance. | |
153 | $field = $this->get_field($fieldnode, $locator); | |
154 | ||
155 | // Checks if the provided value matches the current field value. | |
156 | if ($value != $field->get_value()) { | |
157 | throw new ExpectationException( | |
158 | 'The \'' . $locator . '\' value is \'' . $field->get_value() . '\'' , | |
159 | $this->getSession() | |
160 | ); | |
161 | } | |
162 | } | |
163 | ||
164 | /** | |
165 | * Checks, that checkbox with specified in|name|label|value is checked. | |
166 | * | |
23ebc481 | 167 | * @Then /^the "(?P<checkbox_string>(?:[^"]|\\")*)" checkbox should be checked$/ |
1f9ffbdb | 168 | * @see Behat\MinkExtension\Context\MinkContext |
23ebc481 DM |
169 | */ |
170 | public function assert_checkbox_checked($checkbox) { | |
23ebc481 DM |
171 | $this->assertSession()->checkboxChecked($checkbox); |
172 | } | |
173 | ||
174 | /** | |
175 | * Checks, that checkbox with specified in|name|label|value is unchecked. | |
176 | * | |
23ebc481 | 177 | * @Then /^the "(?P<checkbox_string>(?:[^"]|\\")*)" checkbox should not be checked$/ |
1f9ffbdb | 178 | * @see Behat\MinkExtension\Context\MinkContext |
23ebc481 DM |
179 | */ |
180 | public function assert_checkbox_not_checked($checkbox) { | |
23ebc481 DM |
181 | $this->assertSession()->checkboxNotChecked($checkbox); |
182 | } | |
183 | ||
184 | /** | |
185 | * Checks, that given select box contains the specified option. | |
186 | * | |
23ebc481 | 187 | * @Then /^the "(?P<select_string>(?:[^"]|\\")*)" select box should contain "(?P<option_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb DM |
188 | * @throws ExpectationException |
189 | * @throws ElementNotFoundException Thrown by behat_base::find | |
23ebc481 DM |
190 | * @param string $select The select element name |
191 | * @param string $option The option text/value | |
192 | */ | |
193 | public function the_select_box_should_contain($select, $option) { | |
194 | ||
1f9ffbdb | 195 | $selectnode = $this->find_field($select); |
23ebc481 DM |
196 | |
197 | $regex = '/' . preg_quote($option, '/') . '/ui'; | |
198 | if (!preg_match($regex, $selectnode->getText())) { | |
199 | throw new ExpectationException( | |
200 | 'The select box "' . $select . '" does not contains the option "' . $option . '"', | |
201 | $this->getSession() | |
202 | ); | |
203 | } | |
204 | ||
205 | } | |
206 | ||
207 | /** | |
208 | * Checks, that given select box does not contain the specified option. | |
209 | * | |
23ebc481 | 210 | * @Then /^the "(?P<select_string>(?:[^"]|\\")*)" select box should not contain "(?P<option_string>(?:[^"]|\\")*)"$/ |
1f9ffbdb DM |
211 | * @throws ExpectationException |
212 | * @throws ElementNotFoundException Thrown by behat_base::find | |
23ebc481 DM |
213 | * @param string $select The select element name |
214 | * @param string $option The option text/value | |
215 | */ | |
216 | public function the_select_box_should_not_contain($select, $option) { | |
217 | ||
1f9ffbdb | 218 | $selectnode = $this->find_field($select); |
23ebc481 DM |
219 | |
220 | $regex = '/' . preg_quote($option, '/') . '/ui'; | |
221 | if (preg_match($regex, $selectnode->getText())) { | |
222 | throw new ExpectationException( | |
223 | 'The select box "' . $select . '" contains the option "' . $option . '"', | |
224 | $this->getSession() | |
225 | ); | |
226 | } | |
227 | } | |
228 | ||
229 | /** | |
230 | * Gets an instance of the form element field. | |
231 | * | |
232 | * @param NodeElement $fieldnode The current node | |
233 | * @param string $locator Just to send an exception that makes sense for the user | |
234 | * @return behat_form_field | |
235 | */ | |
236 | protected function get_field(NodeElement $fieldnode, $locator) { | |
237 | global $CFG; | |
238 | ||
23ebc481 DM |
239 | // Get the field type. |
240 | $type = $this->get_node_type($fieldnode, $locator); | |
241 | $classname = 'behat_form_' . $type; | |
242 | ||
243 | // Fallsback on the default form field if nothing specific exists. | |
244 | $classpath = $CFG->libdir . '/behat/form_field/' . $classname . '.php'; | |
245 | if (!file_exists($classpath)) { | |
246 | $classname = 'behat_form_field'; | |
247 | $classpath = $CFG->libdir . '/behat/form_field/' . $classname . '.php'; | |
248 | } | |
249 | ||
250 | // Returns the instance. | |
251 | require_once($classpath); | |
252 | return new $classname($this->getSession(), $fieldnode); | |
253 | } | |
254 | ||
255 | /** | |
256 | * Recursive method to find the field type. | |
257 | * | |
258 | * Depending on the field the felement class node is a level or in another. We | |
259 | * look recursively for a parent node with a 'felement' class to find the field type. | |
260 | * | |
261 | * @throws ExpectationException | |
262 | * @param NodeElement $fieldnode The current node | |
263 | * @param string $locator Just to send an exception that makes sense for the user | |
264 | * @return mixed String or NodeElement depending if we have reached the felement node | |
265 | */ | |
266 | protected function get_node_type(NodeElement $fieldnode, $locator) { | |
267 | ||
23ebc481 DM |
268 | // We look for a parent node with 'felement' class. |
269 | if ($class = $fieldnode->getParent()->getAttribute('class')) { | |
270 | ||
271 | if (strstr($class, 'felement') != false) { | |
272 | // Remove 'felement f' from class value. | |
273 | return substr($class, 10); | |
274 | } | |
275 | ||
276 | // Stop propagation through the DOM, something went wrong!. | |
277 | if (strstr($class, 'fcontainer') != false) { | |
278 | throw new ExpectationException('No field type for ' . $locator . ' found, ensure the field exists', $this->getSession()); | |
279 | } | |
280 | } | |
281 | ||
282 | return $this->get_node_type($fieldnode->getParent(), $locator); | |
283 | } | |
284 | ||
285 | } |