From c77f79d0ce35ee53f0641b39cb256e7c4c116f26 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 12 Oct 2022 13:39:35 +0800 Subject: [PATCH 1/7] MDL-75982 editor_tiny: Add behat tests This commit starts to add Behat tests for the various features of TinyMCE. Please note that not all features are testable with Behat. --- .../plugins/media/tests/behat/image.feature | 28 ++ .../tiny/tests/behat/behat_editor_tiny.php | 389 +++++++++++++++++- .../tests/behat/fixtures/tinyscreenshot.png | Bin 0 -> 303123 bytes 3 files changed, 407 insertions(+), 10 deletions(-) create mode 100644 lib/editor/tiny/plugins/media/tests/behat/image.feature create mode 100644 lib/editor/tiny/tests/behat/fixtures/tinyscreenshot.png diff --git a/lib/editor/tiny/plugins/media/tests/behat/image.feature b/lib/editor/tiny/plugins/media/tests/behat/image.feature new file mode 100644 index 00000000000..fc9cb148f5b --- /dev/null +++ b/lib/editor/tiny/plugins/media/tests/behat/image.feature @@ -0,0 +1,28 @@ +@editor @editor_tiny @tiny_media @javascript +Feature: Use the TinyMCE editor to upload an image + In order to work with images + As a user + I need to be able to upload and manipulate images + + Scenario: Clicking on the Image button in the TinyMCE editor opens the image dialog + Given I log in as "admin" + And I open my profile in edit mode + When I click on the "Image" button for the "Description" TinyMCE editor + Then "Image properties" "dialogue" should exist + + Scenario: Browsing repositories in the TinyMCE editor shows the FilePicker + Given I log in as "admin" + And I open my profile in edit mode + When I click on the "Image" button for the "Description" TinyMCE editor + And I click on "Browse repositories" "button" in the "Image properties" "dialogue" + Then "File picker" "dialogue" should exist + + @_file_upload @test_tiny + Scenario: Browsing repositories in the TinyMCE editor shows the FilePicker + Given I log in as "admin" + And I open my profile in edit mode + When I click on the "Image" button for the "Description" TinyMCE editor + And I click on "Browse repositories" "button" in the "Image properties" "dialogue" + And I upload "/lib/editor/tiny/tests/behat/fixtures/tinyscreenshot.png" to the file picker for TinyMCE + # Note: This needs to be replaced with a label. + Then ".tiny_image_preview" "css_element" should be visible diff --git a/lib/editor/tiny/tests/behat/behat_editor_tiny.php b/lib/editor/tiny/tests/behat/behat_editor_tiny.php index b6741a0cca3..f0213ba7649 100644 --- a/lib/editor/tiny/tests/behat/behat_editor_tiny.php +++ b/lib/editor/tiny/tests/behat/behat_editor_tiny.php @@ -24,6 +24,9 @@ */ use Behat\Behat\Hook\Scope\BeforeScenarioScope; +use Behat\Mink\Element\NodeElement; +use Behat\Mink\Exception\DriverException; +use Behat\Mink\Exception\ExpectationException; // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php. require_once(__DIR__ . '/../../../../behat/behat_base.php'); @@ -36,6 +39,52 @@ require_once(__DIR__ . '/../../../../behat/behat_base.php'); * @copyright 2022 Andrew Lyons */ class behat_editor_tiny extends behat_base implements \core_behat\settable_editor { + /** + * Execute some JavaScript for a particular Editor instance. + * + * The editor instance is available on the 'instnace' variable. + * + * @param string $editorid The ID of the editor + * @param string $code The code to execute + */ + protected function execute_javascript_for_editor(string $editorid, string $code): void { + $js = << { + const instance = editor.getInstanceForElementId('${editorid}'); + {$code} + }); + EOF; + + $this->execute_script($js); + } + + /** + * Resolve some JavaScript for a particular Editor instance. + * + * The editor instance is available on the 'instnace' variable. + * The code should return a value by passing it to the `resolve` function. + * + * @param string $editorid The ID of the editor + * @param string $code The code to evaluate + * @return string|null|array + */ + protected function evaluate_javascript_for_editor(string $editorid, string $code) { + $js = << { + require(['editor_tiny/editor'], (editor) => { + const instance = editor.getInstanceForElementId('${editorid}'); + if (!instance) { + reject("Instance '${editorid}' not found"); + } + + {$code} + }); + }); + EOF; + + return $this->evaluate_script($js); + } + /** * Set the value for the editor. * @@ -51,17 +100,19 @@ class behat_editor_tiny extends behat_base implements \core_behat\settable_edito return; } - $js = << { - const instance = editor.getInstanceForElementId('${editorid}'); - if (instance) { - instance.setContent('${value}'); - instance.undoManager.add(); - } - }); - EOF; + $this->execute_javascript_for_editor($editorid, <<execute_script($js); + /** + * Store the current value of the editor, if it is a Tiny editor, to the textarea. + * + * @param string $editorid The ID of the editor. + */ + public function store_current_value(string $editorid): void { + $this->execute_javascript_for_editor($editorid, "instance?.save();"); } /** @@ -92,4 +143,322 @@ class behat_editor_tiny extends behat_base implements \core_behat\settable_edito $this->execute('behat_general::the_default_editor_is_set_to', ['tiny']); } + + /** + * Ensure that the editor_tiny tag is in use. + * + * This function should be used for any step defined in this file. + * + * @throws DriverException Thrown if the editor_tiny tag is not specified for this file + */ + protected function require_tiny_tags(): void { + // Ensure that this step only runs in TinyMCE tags. + if (!$this->has_tag('editor_tiny')) { + throw new DriverException( + 'TinyMCE tests using this step must have the @editor_tiny tag on either the scenario or feature.' + ); + } + } + + /** + * Get the Mink NodeElement of the