MDL-67668 behat: Add inplace editable field type
authorAndrew Nicols <andrew@nicols.co.uk>
Wed, 17 Jun 2020 05:45:15 +0000 (13:45 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Mon, 23 Nov 2020 01:01:19 +0000 (09:01 +0800)
This commit promotes the Inplace Editable field to a first-class form
element by introducing a new partial selector for inplace editable
fields, and teaching the field manager how to recognise these, then
introducing a new field type which can handle setting values for this
field.

admin/tool/behat/tests/behat/inplaceeditable.feature [new file with mode: 0644]
lib/behat/behat_field_manager.php
lib/behat/classes/partial_named_selector.php
lib/behat/form_field/behat_form_field.php
lib/behat/form_field/behat_form_inplaceeditable.php [new file with mode: 0644]

diff --git a/admin/tool/behat/tests/behat/inplaceeditable.feature b/admin/tool/behat/tests/behat/inplaceeditable.feature
new file mode 100644 (file)
index 0000000..014c5f5
--- /dev/null
@@ -0,0 +1,30 @@
+@tool_behat
+Feature: Verify that the inplace editable field works as expected
+  In order to use behat step definitions
+  As a test write
+  I need to ensure that the inplace editable works in forms
+
+  Background:
+    Given the following "course" exists:
+      | fullname  | Course 1 |
+      | shortname | C1       |
+    And the following "activities" exist:
+      | activity | course | name                | idnumber |
+      | forum    | C1     | My first forum      | forum1   |
+      | assign   | C1     | My first assignment | assign1  |
+      | quiz     | C1     | My first quiz       | quiz1    |
+    And I log in as "admin"
+    And I am on "Course 1" course homepage with editing mode on
+
+  @javascript
+  Scenario: Using an inplace editable updates the name of an activity
+    When I set the field "Edit title" in the "My first assignment" "activity" to "Coursework submission"
+    Then I should see "Coursework submission"
+    And I should not see "My first assignment"
+    But I should see "My first forum"
+    And I should see "My first quiz"
+    And I set the field "Edit title" in the "Coursework submission" "activity" to "My first assignment"
+    And I should not see "Coursework submission"
+    But I should see "My first assignment"
+    And I should see "My first forum"
+    And I should see "My first quiz"
index 6d9b4c7..1a807a2 100644 (file)
@@ -48,7 +48,6 @@ class behat_field_manager {
      * @return behat_form_field
      */
     public static function get_form_field_from_label($label, RawMinkContext $context) {
-
         // There are moodle form elements that are not directly related with
         // a basic HTML form field, we should also take care of them.
         // The DOM node.
@@ -172,6 +171,10 @@ class behat_field_manager {
         } else if ($tagname == 'select') {
             // Select tag.
             return 'select';
+        } else if ($tagname == 'span') {
+            if ($fieldnode->hasAttribute('data-inplaceeditable') && $fieldnode->getAttribute('data-inplaceeditable')) {
+                return 'inplaceeditable';
+            }
         }
 
         // We can not provide a closer field type.
index 18c1526..74054ee 100644 (file)
@@ -135,7 +135,7 @@ class behat_partial_named_selector extends \Behat\Mink\Selector\PartialNamedSele
      */
     protected static $moodleselectors = array(
         'activity' => <<<XPATH
-.//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')][normalize-space(.) = %locator% ]
+.//li[contains(concat(' ', normalize-space(@class), ' '), ' activity ')][descendant::*[contains(normalize-space(.), %locator%)]]
 XPATH
         , 'block' => <<<XPATH
 .//*[@data-block][contains(concat(' ', normalize-space(@class), ' '), concat(' ', %locator%, ' ')) or
@@ -262,6 +262,11 @@ XPATH
 .//*[@data-passwordunmask='wrapper']
     /descendant::input[@id = %locator% or @id = //label[contains(normalize-space(string(.)), %locator%)]/@for]
 XPATH
+        ,
+             'inplaceeditable' => <<<XPATH
+.//descendant::span[@data-inplaceeditable][descendant::a[%titleMatch%]]
+XPATH
+        ,
         ],
     ];
 
index ff85a2f..c2aeee7 100644 (file)
@@ -25,8 +25,8 @@
 
 // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
 
-use Behat\Mink\Session as Session,
-    Behat\Mink\Element\NodeElement as NodeElement;
+use Behat\Mink\Element\NodeElement;
+use Behat\Mink\Session;
 
 /**
  * Representation of a form field.
@@ -38,7 +38,10 @@ use Behat\Mink\Session as Session,
  * @copyright  2012 David MonllaĆ³
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class behat_form_field {
+class behat_form_field implements behat_session_interface {
+
+    // All of the functionality of behat_base is shared with form fields via the behat_session_trait trait.
+    use behat_session_trait;
 
     /**
      * @var Session Behat session.
@@ -55,6 +58,16 @@ class behat_form_field {
      */
     protected $fieldlocator = false;
 
+    /**
+     * Returns the Mink session.
+     *
+     * @param   string|null $name name of the session OR active session will be used
+     * @return  \Behat\Mink\Session
+     */
+    public function getSession($name = null) {
+        return $this->session;
+    }
+
 
     /**
      * General constructor with the node and the session to interact with.
diff --git a/lib/behat/form_field/behat_form_inplaceeditable.php b/lib/behat/form_field/behat_form_inplaceeditable.php
new file mode 100644 (file)
index 0000000..57cc8b7
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Custom interaction with inplace editable elements.
+ *
+ * @package    core_form
+ * @category   test
+ * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
+
+require_once(__DIR__  . '/behat_form_text.php');
+
+/**
+ * Custom interaction with inplace editable elements.
+ *
+ * @package    core_form
+ * @category   test
+ * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class behat_form_inplaceeditable extends behat_form_text {
+    /**
+     * Sets the value to a field.
+     *
+     * @param string $value
+     * @return void
+     */
+    public function set_value($value) {
+        // Require JS to run this step.
+        self::require_javascript();
+
+        // Click to enable editing.
+        self::execute(
+            'behat_general::i_click_on_in_the',
+            [
+                '[data-inplaceeditablelink]',
+                'css_element',
+                $this->field,
+                'NodeElement',
+            ]
+        );
+
+        // Note: It is not possible to use the NodeElement->keyDown() and related functions because
+        // this can trigger a focusOnElement call each time.
+        // Instead use the behat_base::type_keys() function.
+
+        // The inplace editable selects all existing content on focus.
+        // Clear the existing value.
+        self::type_keys($this->session, [behat_keys::BACKSPACE]);
+
+        // Type in the new value, followed by ENTER to save the value.
+        self::type_keys($this->session, array_merge(
+            str_split($value),
+            [behat_keys::ENTER]
+        ));
+    }
+}