Skip to content

Commit

Permalink
MDL-67668 behat: Add inplace editable field type
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
andrewnicols committed Nov 23, 2020
1 parent 548da2c commit fd71823
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 5 deletions.
30 changes: 30 additions & 0 deletions admin/tool/behat/tests/behat/inplaceeditable.feature
@@ -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"
5 changes: 4 additions & 1 deletion lib/behat/behat_field_manager.php
Expand Up @@ -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.
Expand Down Expand Up @@ -172,6 +171,10 @@ public static function guess_field_type(NodeElement $fieldnode, Session $session
} 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.
Expand Down
7 changes: 6 additions & 1 deletion lib/behat/classes/partial_named_selector.php
Expand Up @@ -135,7 +135,7 @@ public function __construct() {
*/
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
Expand Down Expand Up @@ -262,6 +262,11 @@ public function __construct() {
.//*[@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
,
],
];

Expand Down
19 changes: 16 additions & 3 deletions lib/behat/form_field/behat_form_field.php
Expand Up @@ -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.
Expand All @@ -38,7 +38,10 @@
* @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.
Expand All @@ -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.
Expand Down
74 changes: 74 additions & 0 deletions lib/behat/form_field/behat_form_inplaceeditable.php
@@ -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]
));
}
}

0 comments on commit fd71823

Please sign in to comment.