MDL-66835 behat: steps for setting/checking fields in containers
authorTim Hunt <T.J.Hunt@open.ac.uk>
Thu, 3 Oct 2019 11:55:59 +0000 (12:55 +0100)
committerTim Hunt <T.J.Hunt@open.ac.uk>
Wed, 9 Oct 2019 12:26:05 +0000 (13:26 +0100)
admin/tool/behat/tests/behat/get_and_set_fields_in_containers.feature [new file with mode: 0644]
lib/tests/behat/behat_forms.php

diff --git a/admin/tool/behat/tests/behat/get_and_set_fields_in_containers.feature b/admin/tool/behat/tests/behat/get_and_set_fields_in_containers.feature
new file mode 100644 (file)
index 0000000..cbc84c3
--- /dev/null
@@ -0,0 +1,27 @@
+@tool_behat
+Feature: Behat steps for interacting with form work
+  In order to test my Moodle code
+  As a developer
+  I need the Behat steps for form elements to work reliably
+
+  @javascript
+  Scenario: Test fields in containers
+    Given the following "courses" exist:
+      | fullname | shortname |
+      | Course 1 | C1        |
+    When I log in as "admin"
+    And I am on "Course 1" course homepage
+    # Just get to any form.
+    And I navigate to "Edit settings" in current page administration
+    And I set the field "Course full name" in the "General" "fieldset" to "Frog"
+    And I set the following fields in the "Appearance" "fieldset" to these values:
+      | Show activity reports   | Yes |
+      | Number of announcements | 1   |
+    Then the field "Show activity reports" in the "Appearance" "fieldset" matches value "Yes"
+    And the field "Show activity reports" in the "Appearance" "fieldset" does not match value "No"
+    And the following fields in the "region-main" "region" match these values:
+      | Course full name        | Frog |
+      | Number of announcements | 1    |
+    And the following fields in the "region-main" "region" do not match these values:
+      | Course full name        | Course 1 |
+      | Number of announcements | 5        |
index 9d89a75..d81686e 100644 (file)
@@ -36,6 +36,9 @@ use Behat\Gherkin\Node\TableNode as TableNode,
 /**
  * Forms-related steps definitions.
  *
+ * Note, Behat tests to verify that the steps defined here work as advertised
+ * are kept in admin/tool/behat/tests/behat.
+ *
  * @package    core
  * @category   test
  * @copyright  2012 David MonllaĆ³
@@ -90,6 +93,29 @@ class behat_forms extends behat_base {
         }
     }
 
+    /**
+     * Fills a form with field/value data.
+     *
+     * @Given /^I set the following fields in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" to these values:$/
+     * @throws ElementNotFoundException Thrown by behat_base::find
+     * @param string $containerelement Element we look in
+     * @param string $containerselectortype The type of selector where we look in
+     * @param TableNode $data
+     */
+    public function i_set_the_following_fields_in_container_to_these_values(
+            $containerelement, $containerselectortype, TableNode $data) {
+
+        // Expand all fields in case we have.
+        $this->expand_all_fields();
+
+        $datahash = $data->getRowsHash();
+
+        // The action depends on the field type.
+        foreach ($datahash as $locator => $value) {
+            $this->set_field_value_in_container($locator, $value, $containerselectortype, $containerelement);
+        }
+    }
+
     /**
      * Expands all moodleform's fields, including collapsed fieldsets and advanced fields if they are present.
      * @Given /^I expand all fieldsets$/
@@ -195,6 +221,20 @@ class behat_forms extends behat_base {
         $this->set_field_value($field, $value);
     }
 
+    /**
+     * Sets the specified value to the field.
+     *
+     * @Given /^I set the field "(?P<field_string>(?:[^"]|\\")*)" in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" to "(?P<field_value_string>(?:[^"]|\\")*)"$/
+     * @throws ElementNotFoundException Thrown by behat_base::find
+     * @param string $field
+     * @param string $containerelement Element we look in
+     * @param string $containerselectortype The type of selector where we look in
+     * @param string $value
+     */
+    public function i_set_the_field_in_container_to($field, $containerelement, $containerselectortype, $value) {
+        $this->set_field_value_in_container($field, $value, $containerselectortype, $containerelement);
+    }
+
     /**
      * Press the key in the field to trigger the javascript keypress event
      *
@@ -284,7 +324,6 @@ class behat_forms extends behat_base {
      * @throws ElementNotFoundException Thrown by behat_base::find
      * @param string $field
      * @param string $value
-     * @return void
      */
     public function the_field_does_not_match_value($field, $value) {
 
@@ -300,6 +339,58 @@ class behat_forms extends behat_base {
         }
     }
 
+    /**
+     * Checks, the field matches the value.
+     *
+     * @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" matches value "(?P<field_value_string>(?:[^"]|\\")*)"$/
+     * @throws ElementNotFoundException Thrown by behat_base::find
+     * @param string $field
+     * @param string $containerelement Element we look in
+     * @param string $containerselectortype The type of selector where we look in
+     * @param string $value
+     */
+    public function the_field_in_container_matches_value($field, $containerelement, $containerselectortype, $value) {
+
+        // Get the field.
+        $node = $this->get_node_in_container('field', $field, $containerselectortype, $containerelement);
+        $formfield = behat_field_manager::get_form_field($node, $this->getSession());
+
+        // Checks if the provided value matches the current field value.
+        if (!$formfield->matches($value)) {
+            $fieldvalue = $formfield->get_value();
+            throw new ExpectationException(
+                    'The \'' . $field . '\' value is \'' . $fieldvalue . '\', \'' . $value . '\' expected' ,
+                    $this->getSession()
+            );
+        }
+    }
+
+    /**
+     * Checks, the field does not match the value.
+     *
+     * @Then /^the field "(?P<field_string>(?:[^"]|\\")*)" in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" does not match value "(?P<field_value_string>(?:[^"]|\\")*)"$/
+     * @throws ExpectationException
+     * @throws ElementNotFoundException Thrown by behat_base::find
+     * @param string $field
+     * @param string $containerelement Element we look in
+     * @param string $containerselectortype The type of selector where we look in
+     * @param string $value
+     */
+    public function the_field_in_container_does_not_match_value($field, $containerelement, $containerselectortype, $value) {
+
+        // Get the field.
+        $node = $this->get_node_in_container('field', $field, $containerselectortype, $containerelement);
+        $formfield = behat_field_manager::get_form_field($node, $this->getSession());
+
+        // Checks if the provided value matches the current field value.
+        if ($formfield->matches($value)) {
+            throw new ExpectationException(
+                    'The \'' . $field . '\' value matches \'' . $value . '\' and it should not match it' ,
+                    $this->getSession()
+            );
+        }
+    }
+
     /**
      * Checks, the field matches the value.
      *
@@ -391,6 +482,52 @@ class behat_forms extends behat_base {
         }
     }
 
+    /**
+     * Checks, the provided field/value matches.
+     *
+     * @Then /^the following fields in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" match these values:$/
+     * @throws ExpectationException
+     * @param string $containerelement Element we look in
+     * @param string $containerselectortype The type of selector where we look in
+     * @param TableNode $data Pairs of | field | value |
+     */
+    public function the_following_fields_in_container_match_these_values(
+            $containerelement, $containerselectortype, TableNode $data) {
+
+        // Expand all fields in case we have.
+        $this->expand_all_fields();
+
+        $datahash = $data->getRowsHash();
+
+        // The action depends on the field type.
+        foreach ($datahash as $locator => $value) {
+            $this->the_field_in_container_matches_value($locator, $containerelement, $containerselectortype, $value);
+        }
+    }
+
+    /**
+     * Checks that the provided field/value pairs don't match.
+     *
+     * @Then /^the following fields in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" do not match these values:$/
+     * @throws ExpectationException
+     * @param string $containerelement Element we look in
+     * @param string $containerselectortype The type of selector where we look in
+     * @param TableNode $data Pairs of | field | value |
+     */
+    public function the_following_fields_in_container_do_not_match_these_values(
+            $containerelement, $containerselectortype, TableNode $data) {
+
+        // Expand all fields in case we have.
+        $this->expand_all_fields();
+
+        $datahash = $data->getRowsHash();
+
+        // The action depends on the field type.
+        foreach ($datahash as $locator => $value) {
+            $this->the_field_in_container_does_not_match_value($locator, $containerelement, $containerselectortype, $value);
+        }
+    }
+
     /**
      * Checks, that given select box contains the specified option.
      *
@@ -497,6 +634,26 @@ class behat_forms extends behat_base {
         $field->set_value($value);
     }
 
+    /**
+     * Generic field setter.
+     *
+     * Internal API method, a generic *I set "VALUE" to "FIELD" field*
+     * could be created based on it.
+     *
+     * @param string $fieldlocator The pointer to the field, it will depend on the field type.
+     * @param string $value the value to set
+     * @param string $containerselectortype The type of selector where we look in
+     * @param string $containerelement Element we look in
+     */
+    protected function set_field_value_in_container($fieldlocator, $value, $containerselectortype, $containerelement) {
+
+        $node = $this->get_node_in_container('field', $fieldlocator, $containerselectortype, $containerelement);
+        // We delegate to behat_form_field class, it will
+        // guess the type properly as it is a select tag.
+        $field = behat_field_manager::get_form_field($node, $this->getSession());
+        $field->set_value($value);
+    }
+
     /**
      * Select a value from single select and redirect.
      *