Commit 2ded5d0f authored by catch's avatar catch
Browse files

Issue #3517024 by acbramley: Convert ckEditor5EditorHeightTest to WebDriver test

parent 9a2e10ea
Loading
Loading
Loading
Loading
Loading
+137 −0
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

namespace Drupal\Tests\ckeditor5\FunctionalJavascript;

use Drupal\editor\Entity\Editor;
use Drupal\Tests\ckeditor5\Traits\CKEditor5TestTrait;

/**
 * Tests ckeditor height respects field rows config.
 *
 * @group ckeditor5
 * @internal
 */
class CKEditor5HeightTest extends CKEditor5TestBase {

  use CKEditor5TestTrait;

  /**
   * Tests editor height respects rows config.
   */
  public function testCKEditor5Height(): void {
    $this->addNewTextFormat();
    /** @var \Drupal\editor\Entity\Editor $editor */
    $editor = Editor::load('ckeditor5');
    $editor->setSettings([
      'toolbar' => [
        'items' => [
          'sourceEditing',
        ],
      ],
      'plugins' => [
        'ckeditor5_sourceEditing' => [
          'allowed_tags' => [],
        ],
      ],
    ])->save();
    $this->drupalGet('/node/add/page');
    $this->waitForEditor();

    // We expect height to be 320, but test to ensure that it's greater
    // than 300. We want to ensure that we don't hard code a very specific
    // value because tests might break if styles change (line-height, etc).
    // Note that the default height for CKEditor5 is 47px.
    $this->assertGreaterThan(300, $this->getEditorHeight());
    // Check source editing height.
    $this->pressEditorButton('Source');
    $assert = $this->assertSession();
    $this->assertNotNull($assert->waitForElementVisible('css', '.ck-source-editing-area'));
    $this->assertGreaterThan(300, $this->getEditorHeight(TRUE));

    // Test the max height of the editor is less that the window height.
    $body = \str_repeat('<p>Llamas are cute.</p>', 100);
    $node = $this->drupalCreateNode([
      'body' => $body,
    ]);
    $this->drupalGet($node->toUrl('edit-form'));
    $this->assertLessThan($this->getWindowHeight(), $this->getEditorHeight());

    // Check source editing has a scroll bar.
    $this->pressEditorButton('Source');
    $this->assertNotNull($assert->waitForElementVisible('css', '.ck-source-editing-area'));
    $this->assertTrue($this->isSourceEditingScrollable());

    // Double the editor row count.
    \Drupal::service('entity_display.repository')->getFormDisplay('node', 'page')
      ->setComponent('body', [
        'type' => 'text_textarea_with_summary',
        'settings' => [
          'rows' => 18,
        ],
      ])
      ->save();
    // Check the height of the editor again.
    $this->drupalGet('/node/add/page');
    $this->waitForEditor();
    // We expect height to be 640, but test to ensure that it's greater
    // than 600. We want to ensure that we don't hard code a very specific
    // value because tests might break if styles change (line-height, etc).
    // Note that the default height for CKEditor5 is 47px.
    $this->assertGreaterThan(600, $this->getEditorHeight());
  }

  /**
   * Gets the height of ckeditor.
   */
  private function getEditorHeight(bool $sourceEditing = FALSE): int {
    $selector = $sourceEditing ? '.ck-source-editing-area' : '.ck-editor__editable';
    $javascript = <<<JS
      return document.querySelector('$selector').clientHeight;
    JS;
    return $this->getSession()->evaluateScript($javascript);
  }

  /**
   * Gets the window height.
   */
  private function getWindowHeight(): int {
    $javascript = <<<JS
      return window.innerHeight;
    JS;
    return $this->getSession()->evaluateScript($javascript);
  }

  /**
   * Checks that the source editing element is scrollable.
   */
  private function isSourceEditingScrollable(): bool {
    $javascript = <<<JS
      (function () {
        const element = document.querySelector('.ck-source-editing-area textarea');
        const style = window.getComputedStyle(element);
        if (
          element.scrollHeight > element.clientHeight &&
          style.overflow !== 'hidden' &&
          style['overflow-y'] !== 'hidden' &&
          style.overflow !== 'clip' &&
          style['overflow-y'] !== 'clip'
        ) {
          if (
            element === document.scrollingElement ||
            (style.overflow !== 'visible' &&
              style['overflow-y'] !== 'visible')
          ) {
            return true;
          }
        }

        return false;
      })();
    JS;
    $evaluateScript = $this->getSession()->evaluateScript($javascript);
    return $evaluateScript;
  }

}
+0 −241
Original line number Diff line number Diff line
// cspell:ignore sourceediting

module.exports = {
  '@tags': ['core', 'ckeditor5'],
  before(browser) {
    browser
      .drupalInstall({ installProfile: 'testing' })
      .drupalInstallModule('ckeditor5', true)
      .drupalInstallModule('field_ui')
      .drupalInstallModule('node', true);

    // Set fixed (desktop-ish) size to ensure a maximum viewport.
    browser.window.resize(1920, 1080);
  },
  after(browser) {
    browser.drupalUninstall();
  },
  'Ensure CKEditor respects field widget row value': (browser) => {
    browser.drupalLoginAsAdmin(() => {
      browser
        // Create new input format.
        .drupalRelativeURL('/admin/config/content/formats/add')
        .waitForElementVisible('[data-drupal-selector="edit-name"]')
        .updateValue('[data-drupal-selector="edit-name"]', 'test')
        .waitForElementVisible('#edit-name-machine-name-suffix')
        .click(
          '[data-drupal-selector="edit-editor-editor"] option[value=ckeditor5]',
        )
        // Wait for CKEditor 5 settings to be visible.
        .waitForElementVisible(
          '[data-drupal-selector="edit-editor-settings-toolbar"]',
        )
        .click('.ckeditor5-toolbar-button-sourceEditing') // Select the Source Editing button.
        // Hit the down arrow key to move it to the toolbar.
        .perform(function () {
          return this.actions().sendKeys(browser.Keys.ARROW_DOWN);
        })
        // Wait for new source editing vertical tab to be present before continuing.
        .waitForElementVisible(
          '[href*=edit-editor-settings-plugins-ckeditor5-sourceediting]',
        )
        .submitForm('input[type="submit"]')
        .waitForElementVisible('[data-drupal-messages]')
        .assert.textContains('[data-drupal-messages]', 'Added text format')
        // Create new content type.
        .drupalRelativeURL('/admin/structure/types/add')
        .waitForElementVisible('[data-drupal-selector="edit-name"]')
        .updateValue('[data-drupal-selector="edit-name"]', 'test')
        .waitForElementVisible('#edit-name-machine-name-suffix') // Wait for machine name to update.
        .submitForm('input[type="submit"]')
        .waitForElementVisible('[data-drupal-messages]')
        .assert.textContains(
          '[data-drupal-messages]',
          'The content type test has been added',
        )
        // Navigate to the create content page and measure height of the editor.
        .drupalRelativeURL('/node/add/test')
        .waitForElementVisible('.ck-editor__editable')
        .execute(
          // eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
          function () {
            const height = document.querySelector(
              '.ck-editor__editable',
            ).clientHeight;

            // We expect height to be 320, but test to ensure that it's greater
            // than 300. We want to ensure that we don't hard code a very specific
            // value because tests might break if styles change (line-height, etc).
            // Note that the default height for CKEditor5 is 47px.
            return height > 300;
          },
          [],
          (result) => {
            browser.assert.ok(
              result.value,
              'Editor height is set to 9 rows (default).',
            );
          },
        )
        .click('.ck-source-editing-button')
        .waitForElementVisible('.ck-source-editing-area')
        .execute(
          // eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
          function () {
            const height = document.querySelector(
              '.ck-source-editing-area',
            ).clientHeight;

            // We expect height to be 320, but test to ensure that it's greater
            // than 300. We want to ensure that we don't hard code a very specific
            // value because tests might break if styles change (line-height, etc).
            // Note that the default height for CKEditor5 is 47px.
            return height > 300;
          },
          [],
          (result) => {
            browser.assert.ok(
              result.value,
              'Source editing height is set to 9 rows (default).',
            );
          },
        )

        // Navigate to the create content page and measure max-height of the editor.
        .drupalRelativeURL('/node/add/test')
        .execute(
          // eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
          function () {
            window.Drupal.CKEditor5Instances.forEach((instance) => {
              instance.setData('<p>Llamas are cute.</p>'.repeat(100));
            });

            const height = document.querySelector(
              '.ck-editor__editable',
            ).clientHeight;

            return height < window.innerHeight;
          },
          [],
          (result) => {
            browser.assert.ok(
              result.value,
              'Editor area should never exceed full viewport.',
            );
          },
        )
        // Source Editor textarea should have vertical scrollbar when needed.
        .click('.ck-source-editing-button')
        .waitForElementVisible('.ck-source-editing-area')
        .execute(
          // eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
          function () {
            function isScrollableY(element) {
              const style = window.getComputedStyle(element);

              if (
                element.scrollHeight > element.clientHeight &&
                style.overflow !== 'hidden' &&
                style['overflow-y'] !== 'hidden' &&
                style.overflow !== 'clip' &&
                style['overflow-y'] !== 'clip'
              ) {
                if (
                  element === document.scrollingElement ||
                  (style.overflow !== 'visible' &&
                    style['overflow-y'] !== 'visible')
                ) {
                  return true;
                }
              }

              return false;
            }

            return isScrollableY(
              document.querySelector('.ck-source-editing-area textarea'),
            );
          },
          [],
          (result) => {
            browser.assert.strictEqual(
              result.value,
              true,
              'Source Editor textarea should have vertical scrollbar when needed.',
            );
          },
        )

        // Double the editor row count.
        .drupalRelativeURL('/admin/structure/types/manage/test/form-display')
        .waitForElementVisible(
          '[data-drupal-selector="edit-fields-body-settings-edit"]',
        )
        .click('[data-drupal-selector="edit-fields-body-settings-edit"]')
        .waitForElementVisible(
          '[data-drupal-selector="edit-fields-body-settings-edit-form-settings-rows"]',
        )
        .updateValue(
          '[data-drupal-selector="edit-fields-body-settings-edit-form-settings-rows"]',
          '18',
        )
        // Save field settings.
        .click(
          '[data-drupal-selector="edit-fields-body-settings-edit-form-actions-save-settings"]',
        )
        .waitForElementVisible(
          '[data-drupal-selector="edit-fields-body"] .field-plugin-summary',
        )
        .click('[data-drupal-selector="edit-submit"]')
        .waitForElementVisible('[data-drupal-messages]')
        .assert.textContains(
          '[data-drupal-messages]',
          'Your settings have been saved',
        )

        // Navigate to the create content page and measure height of the editor.
        .drupalRelativeURL('/node/add/test')
        .execute(
          // eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
          function () {
            const height = document.querySelector(
              '.ck-editor__editable',
            ).clientHeight;

            // We expect height to be 640, but test to ensure that it's greater
            // than 600. We want to ensure that we don't hard code a very specific
            // value because tests might break if styles change (line-height, etc).
            // Note that the default height for CKEditor5 is 47px.
            return height > 600;
          },
          [],
          (result) => {
            browser.assert.ok(result.value, 'Editor height is set to 18 rows.');
          },
        )
        .click('.ck-source-editing-button')
        .waitForElementVisible('.ck-source-editing-area')
        .execute(
          // eslint-disable-next-line func-names, prefer-arrow-callback, no-shadow
          function () {
            const height = document.querySelector(
              '.ck-source-editing-area',
            ).clientHeight;

            // We expect height to be 640, but test to ensure that it's greater
            // than 600. We want to ensure that we don't hard code a very specific
            // value because tests might break if styles change (line-height, etc).
            // Note that the default height for CKEditor5 is 47px.
            return height > 600;
          },
          [],
          (result) => {
            browser.assert.ok(
              result.value,
              'Source editing height is set to 18 rows (default).',
            );
          },
        );
    });
  },
};