Skip to content

Commit

Permalink
[#124] Added support for CKEditor 5. (#168)
Browse files Browse the repository at this point in the history
  • Loading branch information
tannguyen04 authored Dec 29, 2023
1 parent 8bb402f commit 08c7ebf
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 59 deletions.
67 changes: 28 additions & 39 deletions src/WysiwygTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace DrevOps\BehatSteps;

use Behat\Mink\Exception\ElementHtmlException;
use Behat\Mink\Exception\ElementNotFoundException;
use Behat\Mink\Exception\UnsupportedDriverActionException;

Expand All @@ -28,7 +29,6 @@ public function wysiwygFillField(string $field, string $value): void {

$page = $this->getSession()->getPage();
$element = $page->findField($field);

if ($element === NULL) {
throw new ElementNotFoundException($this->getSession()->getDriver(), 'form field', 'id|name|label|value|placeholder', $field);
}
Expand All @@ -40,53 +40,42 @@ public function wysiwygFillField(string $field, string $value): void {
catch (UnsupportedDriverActionException $exception) {
// For non-JS drivers process field in a standard way.
$element->setValue($value);

return;
}

// For a JS-capable driver, try to find WYSIWYG iframe as a child of the
// following sibling.
$iframe_xpath = $element->getXpath() . "/following-sibling::div[contains(@class, 'cke')]//iframe";
$page_iframe_elements = $driver->find($iframe_xpath);
if (empty($page_iframe_elements[0])) {
throw new ElementNotFoundException($this->getSession()->getDriver(), 'WYSIWYG form field', 'id|name|label|value|placeholder', $field);
$element_id = $element->getAttribute('id');
if (empty($element_id)) {
throw new ElementHtmlException('ID is empty', $driver, $element);
}

$iframe_element = reset($page_iframe_elements);

// @note: Selenium's frame() expects frame id as an HTML element "id"
// attribute value or as an 0-based index of the iframe on the page.
// WYSIWYG iframe does not contain HTML "id" attribute, so we need to find
// the index of the iframe on the page.
//
// Find all iframes on the page.
$page_iframe_elements = $driver->find('//iframe');
$parent_element = $element->getParent();

// Filter all iframes by finding parent WYSIWYG wrapper and comparing the
// iframe element being filtered to the found per-field iframe element from
// above.
// Note that, at this point, we are guaranteed to find at least one matching
// iframe element as an exception would be thrown otherwise.
$index = 0;
foreach ($page_iframe_elements as $page_iframe_element) {
$wrapper_xpath = $page_iframe_element->getXpath() . "/ancestor::div[contains(@class, 'cke')]";
$found_wrappers = $driver->find($wrapper_xpath);
if (!empty($found_wrappers) && $page_iframe_element->getOuterHtml() == $iframe_element->getOuterHtml()) {
break;
}
$index++;
}

// Select WYSIWYG iframe frame.
$driver->switchToIFrame((string) $index);
// Support Ckeditor 4.
$is_ckeditor_4 = !empty($driver->find($parent_element->getXpath() . "/div[contains(@class,'cke')]"));
if ($is_ckeditor_4) {
$this->getSession()
->executeScript("CKEDITOR.instances[\"$element_id\"].setData(\"$value\");");

// Type value as keys into 'body' of iframe.
foreach (str_split($value) as $char) {
$this->keyboardTriggerKey('//body', $char);
return;
}

// Reset frame to the default window.
$driver->switchToIFrame(NULL);
// Support Ckeditor 5.
$ckeditor_5_element_selector = ".{$parent_element->getAttribute('class')} .ck-editor__editable";
$this->getSession()
->executeScript(
"
const domEditableElement = document.querySelector(\"$ckeditor_5_element_selector\");
if (domEditableElement.ckeditorInstance) {
const editorInstance = domEditableElement.ckeditorInstance;
if (editorInstance) {
editorInstance.setData(\"$value\");
} else {
throw new Exception('Could not get the editor instance!');
}
} else {
throw new Exception('Could not find the element!');
}
");
}

/**
Expand Down
11 changes: 0 additions & 11 deletions tests/behat/features/wysisywg.feature

This file was deleted.

18 changes: 9 additions & 9 deletions tests/behat/features/wysiwyg.feature
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@d9
Feature: Check that WysiywgTrait works for or D9
@d9 @d10
Feature: Check that WysiywgTrait works.

@api @d10
@api
Scenario: Assert "When I fill in WYSIWYG "field" with "value"" works as expected
Given page content:
| title |
Expand All @@ -13,14 +13,14 @@ Feature: Check that WysiywgTrait works for or D9
And I press "Save"
Then I should see "[TEST] value"

@api @javascript @skipped
@api @javascript
Scenario: Assert "When I fill in WYSIWYG "field" with "value"" works as expected with JS driver
Given page content:
| title |
| [TEST] Page title |
| title |
| [TEST-JS-Driver] Page title |
And I am logged in as a user with the "administrator" role
And I edit "page" "[TEST] Page title"
When I fill in WYSIWYG "Body" with "[TEST] value"
And I edit "page" "[TEST-JS-Driver] Page title"
When I fill in WYSIWYG "Body" with "[TEST-JS-Driver] value"
And save screenshot
And I press "Save"
Then I should see "[TEST] value"
Then I should see "[TEST-JS-Driver] value"

0 comments on commit 08c7ebf

Please sign in to comment.