weekly release 2.7dev
[moodle.git] / lib / tests / behat / behat_forms.php
CommitLineData
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
28require_once(__DIR__ . '/../../../lib/behat/behat_base.php');
a4534dce 29require_once(__DIR__ . '/../../../lib/behat/behat_field_manager.php');
23ebc481
DM
30
31use Behat\Behat\Context\Step\Given as Given,
32 Behat\Behat\Context\Step\When as When,
33 Behat\Behat\Context\Step\Then as Then,
34 Behat\Gherkin\Node\TableNode as TableNode,
35 Behat\Mink\Element\NodeElement as NodeElement,
36 Behat\Mink\Exception\ExpectationException as ExpectationException,
37 Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
38
39/**
40 * Forms-related steps definitions.
41 *
42 * @package core
43 * @category test
44 * @copyright 2012 David MonllaĆ³
45 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46 */
47class behat_forms extends behat_base {
48
49 /**
50 * Presses button with specified id|name|title|alt|value.
51 *
23ebc481 52 * @When /^I press "(?P<button_string>(?:[^"]|\\")*)"$/
1f9ffbdb 53 * @throws ElementNotFoundException Thrown by behat_base::find
46ac40cd 54 * @param string $button
23ebc481
DM
55 */
56 public function press_button($button) {
1f9ffbdb
DM
57
58 // Ensures the button is present.
59 $buttonnode = $this->find_button($button);
60 $buttonnode->press();
23ebc481
DM
61 }
62
63 /**
64 * Fills a moodle form with field/value data.
65 *
23ebc481 66 * @Given /^I fill the moodle form with:$/
1f9ffbdb 67 * @throws ElementNotFoundException Thrown by behat_base::find
23ebc481
DM
68 * @param TableNode $data
69 */
70 public function i_fill_the_moodle_form_with(TableNode $data) {
71
f8f1bdc3
DM
72 // Expand all fields in case we have.
73 $this->expand_all_fields();
74
23ebc481
DM
75 $datahash = $data->getRowsHash();
76
77 // The action depends on the field type.
78 foreach ($datahash as $locator => $value) {
79
a4534dce 80 // Getting the node element pointed by the label.
1f9ffbdb 81 $fieldnode = $this->find_field($locator);
23ebc481
DM
82
83 // Gets the field type from a parent node.
051e9663 84 $field = behat_field_manager::get_form_field($fieldnode, $this->getSession());
23ebc481
DM
85
86 // Delegates to the field class.
d1e55a47 87 $field->set_value($value);
23ebc481
DM
88 }
89 }
90
f8f1bdc3
DM
91 /**
92 * Expands all moodleform's fields, including collapsed fieldsets and advanced fields if they are present.
93 * @Given /^I expand all fieldsets$/
94 */
95 public function i_expand_all_fieldsets() {
96 $this->expand_all_fields();
97 }
98
99 /**
100 * Expands all moodle form fieldsets if they exists.
101 *
102 * Externalized from i_expand_all_fields to call it from
103 * other form-related steps without having to use steps-group calls.
104 *
105 * @throws ElementNotFoundException Thrown by behat_base::find_all
106 * @return void
107 */
108 protected function expand_all_fields() {
109
fb99ef1d
DM
110 // We ensure that all the editors are loaded and we can interact with them.
111 $this->ensure_editors_are_loaded();
112
f8f1bdc3
DM
113 // behat_base::find() throws an exception if there are no elements, we should not fail a test because of this.
114 try {
115
8cda2e6f
DM
116 // Expand fieldsets link.
117 $collapseexpandlink = $this->find('xpath', "//div[@class='collapsible-actions']" .
118 "/descendant::a[contains(concat(' ', @class, ' '), ' collapseexpand ')]" .
119 "[not(contains(concat(' ', @class, ' '), ' collapse-all '))]"
120 );
121 $collapseexpandlink->click();
f8f1bdc3
DM
122
123 } catch (ElementNotFoundException $e) {
8cda2e6f 124 // We continue if there are not expandable fields.
f8f1bdc3
DM
125 }
126
127 // Different try & catch as we can have expanded fieldsets with advanced fields on them.
128 try {
129
8cda2e6f
DM
130 // Expand all fields xpath.
131 $showmorexpath = "//a[normalize-space(.)='" . get_string('showmore', 'form') . "']" .
132 "[contains(concat(' ', normalize-space(@class), ' '), ' moreless-toggler')]";
f8f1bdc3 133
8cda2e6f
DM
134 // We don't wait here as we already waited when getting the expand fieldsets links.
135 $showmores = $this->getSession()->getPage()->findAll('xpath', $showmorexpath);
f8f1bdc3 136
8cda2e6f
DM
137 // Funny thing about this, with findAll() we specify a pattern and each element matching the pattern is added to the array
138 // with of xpaths with a [0], [1]... sufix, but when we click on an element it does not matches the specified xpath
139 // anymore (now is a "Show less..." link) so [1] becomes [0], that's why we always click on the first XPath match,
140 // will be always the next one.
f8f1bdc3
DM
141 $iterations = count($showmores);
142 for ($i = 0; $i < $iterations; $i++) {
143 $showmores[0]->click();
144 }
145
146 } catch (ElementNotFoundException $e) {
147 // We continue with the test.
148 }
149
150 }
151
23ebc481
DM
152 /**
153 * Fills in form field with specified id|name|label|value.
154 *
23ebc481 155 * @When /^I fill in "(?P<field_string>(?:[^"]|\\")*)" with "(?P<value_string>(?:[^"]|\\")*)"$/
1f9ffbdb 156 * @throws ElementNotFoundException Thrown by behat_base::find
46ac40cd
DM
157 * @param string $field
158 * @param string $value
23ebc481
DM
159 */
160 public function fill_field($field, $value) {
1f9ffbdb
DM
161
162 $fieldnode = $this->find_field($field);
163 $fieldnode->setValue($value);
23ebc481
DM
164 }
165
166 /**
167 * Selects option in select field with specified id|name|label|value.
168 *
23ebc481 169 * @When /^I select "(?P<option_string>(?:[^"]|\\")*)" from "(?P<select_string>(?:[^"]|\\")*)"$/
1f9ffbdb 170 * @throws ElementNotFoundException Thrown by behat_base::find
46ac40cd
DM
171 * @param string $option
172 * @param string $select
23ebc481
DM
173 */
174 public function select_option($option, $select) {
23ebc481 175
1f9ffbdb 176 $selectnode = $this->find_field($select);
28abad1a 177
d1e55a47
DM
178 // We delegate to behat_form_field class, it will
179 // guess the type properly as it is a select tag.
180 $selectformfield = behat_field_manager::get_form_field($selectnode, $this->getSession());
181 $selectformfield->set_value($option);
23ebc481
DM
182 }
183
fb624374
DM
184 /**
185 * Selects the specified id|name|label from the specified radio button.
186 *
187 * @When /^I select "(?P<radio_button_string>(?:[^"]|\\")*)" radio button$/
188 * @throws ElementNotFoundException Thrown by behat_base::find
5cde7298 189 * @param string $radio The radio button id, name or label value
fb624374
DM
190 */
191 public function select_radio($radio) {
192
193 $radionode = $this->find_radio($radio);
194 $radionode->check();
195
196 // Adding a click as Selenium requires it to fire some JS events.
cd7ea8f0
DM
197 if ($this->running_javascript()) {
198 $radionode->click();
199 }
fb624374
DM
200 }
201
23ebc481
DM
202 /**
203 * Checks checkbox with specified id|name|label|value.
204 *
23ebc481 205 * @When /^I check "(?P<option_string>(?:[^"]|\\")*)"$/
1f9ffbdb 206 * @throws ElementNotFoundException Thrown by behat_base::find
46ac40cd 207 * @param string $option
23ebc481
DM
208 */
209 public function check_option($option) {
1f9ffbdb 210
d1e55a47
DM
211 // We don't delegate to behat_form_checkbox as the
212 // step is explicitly saying I check.
1f9ffbdb
DM
213 $checkboxnode = $this->find_field($option);
214 $checkboxnode->check();
23ebc481
DM
215 }
216
217 /**
218 * Unchecks checkbox with specified id|name|label|value.
219 *
23ebc481 220 * @When /^I uncheck "(?P<option_string>(?:[^"]|\\")*)"$/
1f9ffbdb 221 * @throws ElementNotFoundException Thrown by behat_base::find
46ac40cd 222 * @param string $option
23ebc481
DM
223 */
224 public function uncheck_option($option) {
1f9ffbdb 225
d1e55a47
DM
226 // We don't delegate to behat_form_checkbox as the
227 // step is explicitly saying I uncheck.
1f9ffbdb
DM
228 $checkboxnode = $this->find_field($option);
229 $checkboxnode->uncheck();
23ebc481
DM
230 }
231
232 /**
233 * Checks that the form element field have the specified value.
234 *
23ebc481 235 * @Then /^the "(?P<field_string>(?:[^"]|\\")*)" field should match "(?P<value_string>(?:[^"]|\\")*)" value$/
1f9ffbdb
DM
236 * @throws ExpectationException
237 * @throws ElementNotFoundException Thrown by behat_base::find
46ac40cd
DM
238 * @param string $locator
239 * @param string $value
23ebc481
DM
240 */
241 public function the_field_should_match_value($locator, $value) {
242
1f9ffbdb 243 $fieldnode = $this->find_field($locator);
23ebc481 244
49d91129 245 // Get the field.
051e9663 246 $field = behat_field_manager::get_form_field($fieldnode, $this->getSession());
49d91129 247 $fieldvalue = $field->get_value();
23ebc481
DM
248
249 // Checks if the provided value matches the current field value.
15c7fb4a 250 if (trim($value) != trim($fieldvalue)) {
23ebc481 251 throw new ExpectationException(
49d91129 252 'The \'' . $locator . '\' value is \'' . $fieldvalue . '\', \'' . $value . '\' expected' ,
23ebc481
DM
253 $this->getSession()
254 );
255 }
256 }
257
258 /**
259 * Checks, that checkbox with specified in|name|label|value is checked.
260 *
23ebc481 261 * @Then /^the "(?P<checkbox_string>(?:[^"]|\\")*)" checkbox should be checked$/
1f9ffbdb 262 * @see Behat\MinkExtension\Context\MinkContext
46ac40cd 263 * @param string $checkbox
23ebc481
DM
264 */
265 public function assert_checkbox_checked($checkbox) {
23ebc481
DM
266 $this->assertSession()->checkboxChecked($checkbox);
267 }
268
269 /**
270 * Checks, that checkbox with specified in|name|label|value is unchecked.
271 *
23ebc481 272 * @Then /^the "(?P<checkbox_string>(?:[^"]|\\")*)" checkbox should not be checked$/
1f9ffbdb 273 * @see Behat\MinkExtension\Context\MinkContext
46ac40cd 274 * @param string $checkbox
23ebc481
DM
275 */
276 public function assert_checkbox_not_checked($checkbox) {
23ebc481
DM
277 $this->assertSession()->checkboxNotChecked($checkbox);
278 }
279
280 /**
281 * Checks, that given select box contains the specified option.
282 *
23ebc481 283 * @Then /^the "(?P<select_string>(?:[^"]|\\")*)" select box should contain "(?P<option_string>(?:[^"]|\\")*)"$/
1f9ffbdb
DM
284 * @throws ExpectationException
285 * @throws ElementNotFoundException Thrown by behat_base::find
23ebc481
DM
286 * @param string $select The select element name
287 * @param string $option The option text/value
288 */
289 public function the_select_box_should_contain($select, $option) {
290
1f9ffbdb 291 $selectnode = $this->find_field($select);
23ebc481
DM
292
293 $regex = '/' . preg_quote($option, '/') . '/ui';
294 if (!preg_match($regex, $selectnode->getText())) {
295 throw new ExpectationException(
296 'The select box "' . $select . '" does not contains the option "' . $option . '"',
297 $this->getSession()
298 );
299 }
300
301 }
302
303 /**
304 * Checks, that given select box does not contain the specified option.
305 *
23ebc481 306 * @Then /^the "(?P<select_string>(?:[^"]|\\")*)" select box should not contain "(?P<option_string>(?:[^"]|\\")*)"$/
1f9ffbdb
DM
307 * @throws ExpectationException
308 * @throws ElementNotFoundException Thrown by behat_base::find
23ebc481
DM
309 * @param string $select The select element name
310 * @param string $option The option text/value
311 */
312 public function the_select_box_should_not_contain($select, $option) {
313
1f9ffbdb 314 $selectnode = $this->find_field($select);
23ebc481
DM
315
316 $regex = '/' . preg_quote($option, '/') . '/ui';
317 if (preg_match($regex, $selectnode->getText())) {
318 throw new ExpectationException(
319 'The select box "' . $select . '" contains the option "' . $option . '"',
320 $this->getSession()
321 );
322 }
323 }
324
23ebc481 325}