CKEditor5TestBase.php

Same filename and directory in other branches
  1. 9 core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5TestBase.php
  2. 11.x core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5TestBase.php

Namespace

Drupal\Tests\ckeditor5\FunctionalJavascript

File

core/modules/ckeditor5/tests/src/FunctionalJavascript/CKEditor5TestBase.php

View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\ckeditor5\FunctionalJavascript;

use Behat\Mink\Element\TraversableElement;
use Drupal\editor\Entity\Editor;
use Drupal\filter\Entity\FilterFormat;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
use Drupal\user\RoleInterface;
// cspell:ignore esque

/**
 * Base class for testing CKEditor 5.
 *
 * @ingroup testing
 * @internal
 */
abstract class CKEditor5TestBase extends WebDriverTestBase {
  
  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'node',
    'ckeditor5',
  ];
  
  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';
  
  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    $this->drupalCreateContentType([
      'type' => 'page',
    ]);
    $this->drupalLogin($this->drupalCreateUser([
      'administer filters',
      'create page content',
      'edit own page content',
    ]));
  }
  
  /**
   * Add and save a new text format using CKEditor 5.
   */
  protected function addNewTextFormat($name = 'ckeditor5') : void {
    FilterFormat::create([
      'format' => $name,
      'roles' => [
        RoleInterface::AUTHENTICATED_ID,
      ],
      'name' => $name,
      'filters' => [
        'filter_html' => [
          'status' => TRUE,
          'settings' => [
            'allowed_html' => '<br> <p> <h2> <h3> <h4> <h5> <h6> <strong> <em>',
          ],
        ],
        'filter_align' => [
          'status' => TRUE,
        ],
        'filter_caption' => [
          'status' => TRUE,
        ],
      ],
    ])->save();
    Editor::create([
      'editor' => $name,
      'format' => $name,
      'image_upload' => [
        'status' => FALSE,
      ],
    ])->save();
  }
  
  /**
   * Create a new text format using CKEditor 5.
   */
  public function createNewTextFormat($page, $assert_session, $name = 'ckeditor5') {
    $this->drupalGet('admin/config/content/formats/add');
    $page->fillField('name', $name);
    $assert_session->waitForText('Machine name');
    $this->assertNotEmpty($assert_session->waitForText($name));
    $page->checkField('roles[authenticated]');
    if ($name === 'ckeditor5') {
      // Enable the HTML filter, at least one HTML restricting filter is needed
      // before CKEditor 5 can be enabled.
      $this->assertTrue($page->hasUncheckedField('filters[filter_html][status]'));
      $page->checkField('filters[filter_html][status]');
      // Add the tags that must be included in the html filter for CKEditor 5.
      $allowed_html_field = $assert_session->fieldExists('filters[filter_html][settings][allowed_html]');
      $allowed_html_field->setValue('<p> <br>');
    }
    $page->selectFieldOption('editor[editor]', $name);
    $assert_session->assertExpectedAjaxRequest(1);
  }
  
  /**
   * Save the new text format.
   */
  public function saveNewTextFormat($page, $assert_session) {
    $page->pressButton('Save configuration');
    $this->assertTrue($assert_session->waitForText('Added text format'), "Confirm new text format saved");
  }
  
  /**
   * Trigger a keyup event on the selected element.
   *
   * @param string $selector
   *   The css selector for the element.
   * @param string $key
   *   The keyCode.
   */
  protected function triggerKeyUp(string $selector, string $key) {
    $script = <<<JS
(function (selector, key) {
  const btn = document.querySelector(selector);
    btn.dispatchEvent(new KeyboardEvent('keydown', { key }));
    btn.dispatchEvent(new KeyboardEvent('keyup', { key }));
})('{<span class="php-variable">$selector</span>}', '{<span class="php-variable">$key</span>}')

JS;
    $options = [
      'script' => $script,
      'args' => [],
    ];
    $this->getSession()
      ->getDriver()
      ->getWebDriverSession()
      ->execute($options);
  }
  
  /**
   * Decorates ::fieldValueEquals() to force DrupalCI to provide useful errors.
   *
   * @param string $field
   *   Field id|name|label|value.
   * @param string $value
   *   Field value.
   * @param \Behat\Mink\Element\TraversableElement $container
   *   Document to check against.
   *
   * @throws \Behat\Mink\Exception\ExpectationException
   *
   * @see \Behat\Mink\WebAssert::fieldValueEquals()
   */
  protected function assertHtmlEsqueFieldValueEquals($field, $value, ?TraversableElement $container = NULL) {
    $assert_session = $this->assertSession();
    $node = $assert_session->fieldExists($field, $container);
    $actual = $node->getValue();
    $regex = '/^' . preg_quote($value, '/') . '$/ui';
    $message = sprintf('The field "%s" value is "%s", but "%s" expected.', $field, htmlspecialchars($actual), htmlspecialchars($value));
    $assert_session->assert((bool) preg_match($regex, $actual), $message);
  }
  
  /**
   * Checks that no real-time validation errors are present.
   *
   * @throws \Behat\Mink\Exception\ElementNotFoundException
   */
  protected function assertNoRealtimeValidationErrors() : void {
    $assert_session = $this->assertSession();
    $this->assertSame('', $assert_session->elementExists('css', '[data-drupal-selector="ckeditor5-realtime-validation-messages-container"]')
      ->getHtml());
  }

}

Classes

Title Deprecated Summary
CKEditor5TestBase Base class for testing CKEditor 5.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.