
| Current Path : /var/www/html/store/web/core/modules/ckeditor5/tests/src/Traits/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/html/store/web/core/modules/ckeditor5/tests/src/Traits/CKEditor5TestTrait.php |
<?php
namespace Drupal\Tests\ckeditor5\Traits;
use Behat\Mink\Element\NodeElement;
use Drupal\Component\Utility\Html;
// cspell:ignore downcasted
/**
* Provides methods to test CKEditor 5.
*
* This trait is meant to be used only by functional JavaScript test classes.
*/
trait CKEditor5TestTrait {
/**
* Gets CKEditor 5 instance data as a PHP DOMDocument.
*
* @return \DOMDocument
* The result of parsing CKEditor 5's data into a PHP DOMDocument.
*/
protected function getEditorDataAsDom(): \DOMDocument {
return Html::load($this->getEditorDataAsHtmlString());
}
/**
* Gets CKEditor 5 instance data as a HTML string.
*
* @return string
* The result of retrieving CKEditor 5's data.
*
* @see https://ckeditor.com/docs/ckeditor5/latest/api/module_editor-classic_classiceditor-ClassicEditor.html#function-getData
*/
protected function getEditorDataAsHtmlString(): string {
// We cannot trust on CKEditor updating the textarea every time model
// changes. Therefore, the most reliable way to get downcasted data is to
// use the CKEditor API.
$javascript = <<<JS
(function(){
return Drupal.CKEditor5Instances.get(Drupal.CKEditor5Instances.keys().next().value).getData();
})();
JS;
return $this->getSession()->evaluateScript($javascript);
}
/**
* Waits for CKEditor to initialize.
*/
protected function waitForEditor() {
$assert_session = $this->assertSession();
$this->assertNotEmpty($assert_session->waitForElement('css', '.ck-editor'));
}
/**
* Clicks a CKEditor button.
*
* @param string $name
* The name of the button, such as `drupallink`, `source`, etc.
*/
protected function pressEditorButton($name) {
$this->getEditorButton($name)->click();
}
/**
* Waits for a CKEditor button and returns it when available and visible.
*
* @param string $name
* The name of the button, such as `drupallink`, `source`, etc.
*
* @return \Behat\Mink\Element\NodeElement|null
* The page element node if found, NULL if not.
*/
protected function getEditorButton($name) {
$button = $this->assertSession()->waitForElementVisible('xpath', "//button[span[text()='$name']]");
$this->assertNotEmpty($button);
return $button;
}
/**
* Asserts a CKEditor button is disabled.
*
* @param string $name
* The name of the button, such as `drupallink`, `source`, etc.
*/
protected function assertEditorButtonDisabled($name) {
$button = $this->getEditorButton($name);
$this->assertTrue($button->hasAttribute('aria-disabled'));
$this->assertTrue($button->hasClass('ck-disabled'));
}
/**
* Asserts a CKEditor button is enabled.
*
* @param string $name
* The name of the button, such as `drupallink`, `source`, etc.
*/
protected function assertEditorButtonEnabled($name) {
$button = $this->getEditorButton($name);
$this->assertFalse($button->hasAttribute('aria-disabled'));
$this->assertFalse($button->hasClass('ck-disabled'));
}
/**
* Asserts a particular balloon is visible.
*
* @param string $balloon_content_selector
* A CSS selector.
*
* @return \Behat\Mink\Element\NodeElement
* The asserted balloon.
*/
protected function assertVisibleBalloon(string $balloon_content_selector): NodeElement {
$this->assertSession()->elementExists('css', '.ck-balloon-panel_visible');
$selector = ".ck-balloon-panel_visible .ck-balloon-rotator__content > .ck$balloon_content_selector";
$this->assertSession()->elementExists('css', $selector);
return $this->getSession()->getPage()->find('css', $selector);
}
/**
* Gets a button from the currently visible balloon.
*
* @param string $name
* The label of the button to find.
*
* @return \Behat\Mink\Element\NodeElement
* The requested button.
*/
protected function getBalloonButton(string $name): NodeElement {
$button = $this->getSession()->getPage()
->find('css', '.ck-balloon-panel_visible .ck-balloon-rotator__content')
->find('xpath', "//button[span[text()='$name']]");
$this->assertNotEmpty($button);
return $button;
}
/**
* Selects text inside an element.
*
* @param string $selector
* A CSS selector for the element which contents should be selected.
*/
protected function selectTextInsideElement(string $selector): void {
$javascript = <<<JS
(function() {
const el = document.querySelector(".ck-editor__main $selector");
const range = document.createRange();
range.selectNodeContents(el);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
})();
JS;
$this->getSession()->evaluateScript($javascript);
}
}