1
0
mirror of https://github.com/moodle/moodle.git synced 2025-04-07 09:23:31 +02:00

Merge branch 'MDL-75887-master' of https://github.com/andrewnicols/moodle

This commit is contained in:
Jun Pataleta 2022-10-12 09:23:32 +08:00
commit be9a0c8f35
6 changed files with 168 additions and 17 deletions

@ -26,6 +26,7 @@
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
use Behat\Testwork\Environment\Environment;
use Behat\Mink\Exception\DriverException;
/**
* Helper to get behat contexts.
@ -115,6 +116,34 @@ class behat_context_helper {
return null;
}
/**
* Find all Behat contexts which match the specified context class name prefix.
*
* Moodle uses a consistent class naming scheme for all Behat contexts, whereby the context name is in the format:
*
* behat_{component}
*
* This method will return all contexts which match the specified prefix.
*
* For example, to find all editors, you would pass in 'behat_editor', and this might return:
* - behat_editor_atto
* - behat_editor_textarea
*
* @param string $prefix The prefix to search for
* @return \Behat\Behat\Context\Context[]
*/
public static function get_prefixed_contexts(string $prefix): array {
if (!is_a(self::$environment, \Behat\Behat\Context\Environment\InitializedContextEnvironment::class)) {
throw new DriverException(
'Cannot get prefixed contexts - the environment is not an InitializedContextEnvironment'
);
}
return array_filter(self::$environment->getContexts(), function($context) use ($prefix): bool {
return (strpos(get_class($context), $prefix) === 0);
});
}
/**
* Check for any theme override of the specified class name.
*

@ -1049,6 +1049,29 @@ EOF;
$this->look_for_exceptions();
}
/**
* Execute a function in a specific behat context.
*
* For example, to call the 'set_editor_value' function for all editors, you would call:
*
* behat_base::execute_in_matching_contexts('editor', 'set_editor_value', ['Some value']);
*
* This would find all behat contexts whose class name starts with 'behat_editor_' and
* call the 'set_editor_value' function on that context.
*
* @param string $prefix
* @param string $method
* @param array $params
*/
public static function execute_in_matching_contexts(string $prefix, string $method, array $params): void {
$contexts = behat_context_helper::get_prefixed_contexts("behat_{$prefix}_");
foreach ($contexts as $context) {
if (method_exists($context, $method) && is_callable([$context, $method])) {
call_user_func_array([$context, $method], $params);
}
}
}
/**
* Get the actual user in the behat session (note $USER does not correspond to the behat session's user).
* @return mixed

@ -0,0 +1,37 @@
<?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/>.
/**
* Editor interface for setting editor values.
*
* @package behat
* @category test
* @copyright 2022 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_behat;
interface settable_editor {
/**
* Set the editor value.
*
* @param string $editorid The id of the editor within the page
* @param string $value The intended content of the editor
*/
public function set_editor_value(string $editorid, string $value): void;
}

@ -32,7 +32,6 @@ require_once(__DIR__ . '/behat_form_textarea.php');
/**
* Moodle editor field.
*
* @todo Support for multiple editors
* @package core_form
* @category test
* @copyright 2012 David Monllaó
@ -44,26 +43,18 @@ class behat_form_editor extends behat_form_textarea {
* Sets the value to a field.
*
* @param string $value
* @return void
*/
public function set_value($value) {
public function set_value($value): void {
$editorid = $this->field->getAttribute('id');
if ($this->running_javascript()) {
$value = addslashes($value);
// This will be transported in JSON, which doesn't allow newlines in strings, so we must escape them.
$value = str_replace("\n", "\\n", $value);
$js = '
(function() {
var editor = Y.one(document.getElementById("'.$editorid.'editable"));
if (editor) {
editor.setHTML("' . $value . '");
}
editor = Y.one(document.getElementById("'.$editorid.'"));
editor.set("value", "' . $value . '");
})();
';
behat_base::execute_script_in_session($this->session, $js);
behat_base::execute_in_matching_contexts('editor', 'set_editor_value', [
$editorid,
$value,
]);
} else {
parent::set_value($value);
}
@ -106,4 +97,3 @@ class behat_form_editor extends behat_form_textarea {
return $this->text_matches($expectedvalue) || $this->text_matches('<p>' . $expectedvalue . '</p>');
}
}

@ -28,6 +28,7 @@ use Behat\Behat\Hook\Scope\BeforeScenarioScope;
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
require_once(__DIR__ . '/../../../../behat/behat_base.php');
require_once(__DIR__ . '/../../../../behat/classes/settable_editor.php');
/**
* Steps definitions to deal with the atto text editor
@ -37,7 +38,30 @@ require_once(__DIR__ . '/../../../../behat/behat_base.php');
* @copyright 2014 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_editor_atto extends behat_base {
class behat_editor_atto extends behat_base implements \core_behat\settable_editor {
/**
* Set the value for the editor.
*
* @param string $editorid
* @param string $value
*/
public function set_editor_value(string $editorid, string $value): void {
$js = <<<EOF
(function() {
const editableEditor = document.getElementById("${editorid}editable");
if (editableEditor && editableEditor.classList.contains('editor_atto_content')) {
editableEditor.innerHTML = "${value}";
}
const editor = document.getElementById("${editorid}");
if (editor) {
editor.value = "${value}";
}
})();
EOF;
$this->execute_script($js);
}
/**
* Select the text in an Atto field.

@ -0,0 +1,48 @@
<?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/>.
/**
* Moodle textarea editor field.
*
* @package core_form
* @category test
* @copyright 2022 Andrew Lyons <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../../behat/behat_base.php');
require_once(__DIR__ . '/../../../../behat/classes/settable_editor.php');
class behat_editor_textarea extends behat_base implements \core_behat\settable_editor {
/**
* Set the value for the editor.
*
* @param string $editorid
* @param string $value
*/
public function set_editor_value(string $editorid, string $value): void {
$js = <<<EOF
(function() {
const editor = document.getElementById("${editorid}");
if (editor && editor.tagName.toLowerCase() === 'textarea') {
editor.value = "${value}";
}
})();
EOF;
$this->execute_script($js);
}
}