HomeServiceContact
Quality Engineering
min read
May 31, 2023
May 31, 2023

CKEditor 4 vs. CKEditor 5: Behat Testing Techniques

CKEditor 4 vs. CKEditor 5: Behat Testing Techniques
Table of contents

Drupal, a powerful and adaptable Content Management System (CMS), enables users to create and maintain complicated websites effortlessly. It is an open-source platform with numerous modules and themes, empowering developers to build specialized and feature-rich websites.

The CKEditor, a well-known and frequently used WYSIWYG editor, is one of the fundamental parts of Drupal. By offering a user-friendly interface with formatting options, image insertion, link creation, and other rich text editing capabilities, Drupal CKEditor improves the experience of editing material.

Drupal users can make their websites more engaging and visually pleasing by generating and editing content with the CKEditor. As Drupal versions are upgraded, CKEditor is also updated. The latest version released with Drupal 10 is CKEditor 5. In this blog, we will discuss Behat test techniques for both CKEditor 4 and CKEditor 5. 

CKEditor 4 vs. CKEditor 5

In Drupal, the "CKEditor" module is responsible for integrating the CKEditor WYSIWYG (What You See Is What You Get) editor into Drupal's content creation interface. CKEditor allows users to create rich, formatted text content without requiring knowledge of HTML or CSS.

CKEditor 4 is built on a monolithic architecture, meaning that all of its features and functionality are contained in a single JavaScript file. It uses DOM manipulation techniques to perform editing actions and provides a rich set of plugins and features that can be used to extend its functionality.

On the other hand, CKEditor 5 has a flexible design that allows you to add or remove features as needed. It uses a system called virtual DOM to speed up editing and works well with modern web technologies like React and Angular. Its modern and user-friendly interface is more accessible than CKEditor 4, streamlining the editing experience.

Moving from CKEditor 4 to CKEditor 5 might require changes to the DOM structure. However, it's worth considering that CKEditor5 has a newer and more adaptable DOM structure, designed to be more versatile and provide a seamless editing experience for developers and end-users. This allows for greater control over the final product. 

Automate Behat test for CKEditor 4

CKEditor 4 and CKEditor 5 have significant differences in their DOM structures, which can impact Behat automation. Here's an explanation with an example: 

CKEditor 4

The DOM structure in CKEditor 4 is relatively simple, and each text area is represented as a single iframe element. To enter text into the editor using Behat, you can simply locate the iframe element and send keys to it. 

Example Behat test step


When I fill in "Summary" field with following:
"""
   Lorem ipsum dolor sit amet, consectetur adipiscing elit
   Nam hendrerit nisi sed sollicitudin pellentesque. Nunc posuere purus rhoncus pulvinar aliquam.
   Ut aliquet tristique nisl vitae volutpat. Nulla aliquet porttitor venenatis.
   Donec a dui et dui fringilla consectetur id nec Nunc posuere purus rhoncus pulvinar aliquam massa.
"""

Behat custom context for CKEditor 4


/**
 * @When I fill in :arg1 field with following:
 * @throws Exception
 */
 public function fillCKEditor($label, PyStringNode $value) {
  // Search for TextEditor based on the label.
  $editor = $this->getSession()->getPage()->findField($label);
  if (empty($editor)) {
    throw new ExpectationException('Could not find WYSIWYG with locator: ' . $label, $this->getSession());
  }
  // Find id of CKEditor Instance.
  $fieldId = $editor->getAttribute('id');
  if (empty($fieldId)) {
    throw new Exception('Could not find an id for field with locator: ' . $label);
  }
  // Add value in CKEditor.
  $this->getSession()
    ->executeScript("CKEditor.instances[\"$fieldId\"].setData(\"$value\");");
} 

This works great with CKEditor 4. But when we try the above custom context for CKEditor 5  we get the following error. 


ReferenceError: CKEditor is not defined
         at <anonymous>:1:1 (Behat\Mink\Exception\DriverException)
Behat custom context

Why do we get this error

In CKEditor 5 it is not represented as a single iframe element. Instead the editor is composed of multiple div elements each with its own set of classes and attributes. To enter text into the editor using Behat you must locate the appropriate div element with ck-editor__editable class and use that to locate the specific editor instance and send keys to it. 

ckeditor 4

Path to resolution

To address the error mentioned above it is necessary to create a separate Behat custom context that is specifically designed for CKEditor 5. 

The function uses JavaScript to interact with the CKEditor instance on the page. It constructs a CSS selector to locate the CKEditor field based on the machine name of the field (i.e. label parameter) then retrieves the CKEditor instance using 


document.querySelector(""$editor"").CKEditorInstance

Finally it sets the data value of the CKEditor instance using editorInstance.setData(""$string"");

Example Behat test step 


When I fill in "field-summary" field with following:
"""
   Lorem ipsum dolor sit amet, consectetur adipiscing elit
   Nam hendrerit nisi sed sollicitudin pellentesque. Nunc posuere purus rhoncus pulvinar aliquam.
   Ut aliquet tristique nisl vitae volutpat. Nulla aliquet porttitor venenatis.
   Donec a dui et dui fringilla consectetur id nec Nunc posuere purus rhoncus pulvinar aliquam massa.
"""


Behat custom context for CKEditor5


/**
 * @When I fill in :arg1 field with following:
 * @throws Exception
 */
 public function fillCKEditor($label, PyStringNode $value) {

  $editor = "div.js-form-item-$label-0-value .ck-editor__editable";
  $this->getSession()
    ->executeScript(
      "
      var domEditableElement = document.querySelector(\"$editor\");
      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!');
      }
      ");
}				

The code is available on Github

Conclusion

CKEditor is a feature-rich WYSIWYG editor that offers an intuitive interface and powerful functionality for content creators from beginners to experienced professionals. 

It helps users create beautiful and sophisticated content with ease without requiring proficiency in HTML or CSS. This versatile tool offers a range of customization options making it the perfect choice for anyone looking to create professional-grade content.

When working with Behat/Mink remember to have a separate custom context for CKEditor 5 as it requires different scripting than CKEditor 4. The custom context provided in this blog demonstrates how to achieve it with CKEditor 5 in Behat/Mink.

Written by
Editor
No art workers.
We'd love to talk about your business objectives