View source
<?php
namespace Drupal\Tests\media\FunctionalJavascript;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Url;
use Drupal\editor\Entity\Editor;
use Drupal\field\Entity\FieldConfig;
use Drupal\file\Entity\File;
use Drupal\filter\Entity\FilterFormat;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\language\Entity\ContentLanguageSettings;
use Drupal\media\Entity\Media;
use Drupal\Tests\ckeditor\Traits\CKEditorTestTrait;
use Drupal\Tests\media\Traits\MediaTypeCreationTrait;
use Drupal\Tests\TestFileCreationTrait;
use Drupal\user\Entity\Role;
use Drupal\user\RoleInterface;
use Drupal\Core\Entity\Entity\EntityViewMode;
class CKEditorIntegrationTest extends WebDriverTestBase {
use CKEditorTestTrait;
use MediaTypeCreationTrait;
use TestFileCreationTrait;
protected $adminUser;
protected $media;
protected $host;
const RETURN_KEY = 13;
const SPACE_BAR = 32;
protected static $modules = [
'ckeditor',
'media',
'node',
'text',
'media_test_embed',
];
protected $defaultTheme = 'classy';
protected function setUp() : void {
parent::setUp();
FilterFormat::create([
'format' => 'test_format',
'name' => 'Test format',
'filters' => [
'filter_align' => [
'status' => TRUE,
],
'filter_caption' => [
'status' => TRUE,
],
'media_embed' => [
'status' => TRUE,
],
],
])
->save();
Editor::create([
'editor' => 'ckeditor',
'format' => 'test_format',
'settings' => [
'toolbar' => [
'rows' => [
[
[
'name' => 'All the things',
'items' => [
'Source',
'Bold',
'Italic',
'DrupalLink',
'DrupalUnlink',
'DrupalImage',
],
],
],
],
],
],
])
->save();
$this->adminUser = $this
->drupalCreateUser([
'use text format test_format',
'bypass node access',
]);
$this
->createMediaType('image', [
'id' => 'image',
]);
File::create([
'uri' => $this
->getTestFiles('image')[0]->uri,
])
->save();
$this->media = Media::create([
'bundle' => 'image',
'name' => 'Screaming hairy armadillo',
'field_media_image' => [
[
'target_id' => 1,
'alt' => 'default alt',
'title' => 'default title',
],
],
]);
$this->media
->save();
$this
->drupalCreateContentType([
'type' => 'blog',
]);
$this->host = $this
->createNode([
'type' => 'blog',
'title' => 'Animals with strange names',
'body' => [
'value' => '<drupal-media data-caption="baz" data-entity-type="media" data-entity-uuid="' . $this->media
->uuid() . '"></drupal-media>',
'format' => 'test_format',
],
]);
$this->host
->save();
$this
->drupalLogin($this->adminUser);
}
public function testOnlyDrupalMediaTagProcessed() {
$original_value = $this->host->body->value;
$this->host->body->value = str_replace('drupal-media', 'p', $original_value);
$this->host
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session = $this
->assertSession();
$this
->assertEmpty($assert_session
->waitForElementVisible('css', 'img[src*="image-test.png"]', 1000));
$assert_session
->elementNotExists('css', 'figure');
$this->host->body->value = $original_value;
$this->host
->save();
$this
->getSession()
->reload();
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'img[src*="image-test.png"]'));
$assert_session
->elementExists('css', 'figure');
}
public function testErrorMessages() {
$this->container
->get('state')
->set('test_media_filter_controller_throw_error', TRUE);
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session = $this
->assertSession();
$this
->assertEmpty($assert_session
->waitForElementVisible('css', 'img[src*="image-test.png"]', 1000));
$assert_session
->elementNotExists('css', 'figure');
$this
->assertNotEmpty($assert_session
->waitForText('An error occurred while trying to preview the media. Please save your work and reload this page.'));
$this->container
->get('state')
->set('test_media_filter_controller_throw_error', FALSE);
$this
->getSession()
->reload();
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'img[src*="image-test.png"]'));
$original_value = $this->host->body->value;
$this->host->body->value = str_replace($this->media
->uuid(), 'invalid_uuid', $original_value);
$this->host
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElement('css', 'drupal-media figure.caption-drupal-media .this-error-message-is-themeable'));
$this
->assertTrue($this->container
->get('theme_installer')
->install([
'classy',
]));
$this
->config('system.theme')
->set('default', 'classy')
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElement('css', 'drupal-media figure.caption-drupal-media .this-error-message-is-themeable.media-embed-error--missing-source'));
$assert_session
->responseContains('classy/css/components/media-embed-error.css');
$this->host->body->value = $original_value;
$this->host
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'img[src*="image-test.png"]'));
$assert_session
->elementNotExists('css', 'drupal-media figure.caption-drupal-media .this-error-message-is-themeable');
}
public function testPreviewUsesDefaultThemeAndIsClientCacheable() {
$this
->config('node.settings')
->set('use_admin_theme', TRUE)
->save();
$this->adminUser
->addRole($this
->drupalCreateRole([
'view the administration theme',
]));
$this->adminUser
->save();
$this
->config('system.theme')
->set('default', 'stable')
->set('admin', 'classy')
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session = $this
->assertSession();
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'img[src*="image-test.png"]'));
$element = $assert_session
->elementExists('css', '[data-media-embed-test-active-theme]');
$this
->assertSame('stable', $element
->getAttribute('data-media-embed-test-active-theme'));
$this
->assertGreaterThan(500, $this
->getLastPreviewRequestTransferSize());
$this
->pressEditorButton('source');
$this
->assertNotEmpty($assert_session
->waitForElement('css', 'textarea.cke_source'));
$this
->pressEditorButton('source');
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'img[src*="image-test.png"]'));
$this
->assertSame(0, $this
->getLastPreviewRequestTransferSize());
}
public function testEditableCaption() {
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
$original_value = $this->host->body->value;
$this->host->body->value = str_replace('data-caption="baz"', 'data-caption=""', $original_value);
$this->host
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForButton('Edit media'));
$assert_session
->elementExists('css', '.cke_widget_drupalmedia[aria-label="Screaming hairy armadillo"]');
$assert_session
->elementContains('css', 'figcaption', '');
$assert_session
->elementAttributeContains('css', 'figcaption', 'data-placeholder', 'Enter caption here');
$this
->fillFieldInMetadataDialogAndSubmit('attributes[alt]', 'Mama, life had just begun');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media img[alt*="Mama, life had just begun"]'));
$assert_session
->buttonExists('Edit media');
$assert_session
->elementContains('css', 'figcaption', '');
$assert_session
->elementAttributeContains('css', 'figcaption', 'data-placeholder', 'Enter caption here');
$original_value = $this->host->body->value;
$this->host->body->value = str_replace('data-caption=""', 'data-caption="baz"', $original_value);
$this->host
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($figcaption = $assert_session
->waitForElement('css', 'drupal-media figcaption'));
$this
->assertSame('baz', $figcaption
->getHtml());
$this
->openMetadataDialogWithKeyPress(static::SPACE_BAR);
$page
->uncheckField('hasCaption');
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($drupal_media = $assert_session
->waitForElementVisible('css', 'drupal-media'));
$result = $page
->waitFor(10, function () use ($drupal_media) {
return empty($drupal_media
->find('css', 'figcaption'));
});
$this
->assertTrue($result);
$this
->openMetadataDialogWithKeyPress(static::SPACE_BAR);
$page
->checkField('hasCaption');
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($drupal_media = $assert_session
->waitForElementVisible('css', 'drupal-media figcaption'));
$this
->assertNotEmpty($assert_session
->waitForElement('css', 'figcaption'));
$this
->setCaption('Caught in a <strong>landslide</strong>! No escape from <em>reality</em>!');
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session
->elementExists('css', 'figcaption > em');
$assert_session
->elementExists('css', 'figcaption > strong')
->click();
$this
->clickPathLinkByTitleAttribute("strong element");
$this
->pressEditorButton('bold');
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session
->elementExists('css', 'figcaption > em');
$assert_session
->elementNotExists('css', 'figcaption > strong');
$assert_session
->elementExists('css', 'figcaption > em')
->click();
$this
->clickPathLinkByTitleAttribute("em element");
$this
->pressEditorButton('italic');
$this
->pressEditorButton('source');
$source = $assert_session
->elementExists('css', 'textarea.cke_source');
$value = $source
->getValue();
$dom = Html::load($value);
$xpath = new \DOMXPath($dom);
$drupal_media = $xpath
->query('//drupal-media')[0];
$this
->assertSame('Caught in a landslide! No escape from reality!', $drupal_media
->getAttribute('data-caption'));
$poor_boy_text = "I'm just a <strong>poor boy</strong>, I need no sympathy!";
$drupal_media
->setAttribute("data-caption", $poor_boy_text);
$source
->setValue(Html::serialize($dom));
$this
->pressEditorButton('source');
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$figcaption = $assert_session
->waitForElement('css', 'figcaption');
$this
->assertNotEmpty($figcaption);
$this
->assertSame($poor_boy_text, $figcaption
->getHtml());
$strong = $figcaption
->find('css', 'strong');
$this
->assertNotEmpty($strong);
$strong
->click();
$this
->pressEditorButton('bold');
$this
->clickPathLinkByTitleAttribute("Caption element");
$this
->pressEditorButton('drupallink');
$field = $assert_session
->waitForElementVisible('xpath', '//input[@name="attributes[href]"]');
$this
->assertNotEmpty($field);
$field
->setValue('https://www.drupal.org');
$assert_session
->elementExists('css', 'button.form-submit')
->press();
$this
->getSession()
->switchToIFrame('ckeditor');
$figcaption = $assert_session
->waitForElement('css', 'figcaption');
$page = $this
->getSession()
->getPage();
$page
->waitFor(10, function () use ($figcaption) {
return $figcaption
->find('xpath', '//a[@href="https://www.drupal.org"]');
});
$assert_session
->elementExists('css', 'a', $figcaption)
->click();
$this
->clickPathLinkByTitleAttribute("a element");
$this
->pressEditorButton('drupallink');
$field = $assert_session
->waitForElementVisible('xpath', '//input[@name="attributes[href]"]');
$this
->assertNotEmpty($field);
$field
->setValue('https://www.drupal.org/project/drupal');
$assert_session
->elementExists('css', 'button.form-submit')
->press();
$this
->getSession()
->switchToIFrame('ckeditor');
$figcaption = $assert_session
->waitForElement('css', 'figcaption');
$page = $this
->getSession()
->getPage();
$page
->waitFor(10, function () use ($figcaption) {
return $figcaption
->find('xpath', '//a[@href="https://www.drupal.org/project/drupal"]');
});
$this
->pressEditorButton('source');
$source = $assert_session
->elementExists('css', "textarea.cke_source");
$value = $source
->getValue();
$this
->assertStringContainsString('https://www.drupal.org/project/drupal', $value);
$this
->assertStringNotContainsString('data-cke-saved-href', $value);
$assert_session
->buttonExists('Save')
->press();
$link = $assert_session
->elementExists('css', 'figcaption > a');
$this
->assertSame('https://www.drupal.org/project/drupal', $link
->getAttribute('href'));
$this
->assertSame("I'm just a poor boy, I need no sympathy!", $link
->getText());
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'figcaption'));
$this
->setCaption('Scaramouch, <em>Scaramouch</em>, will you do the <strong>Fandango</strong>?');
$this
->setCaption('');
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session
->elementContains('css', 'figcaption', '');
$assert_session
->elementAttributeContains('css', 'figcaption', 'data-placeholder', 'Enter caption here');
$this
->setCaption('Fin.');
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session
->elementContains('css', 'figcaption', 'Fin.');
}
public function testDialogAccess() {
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$allowed_html = "<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type='1 A I'> <li> <dl> <dt> <dd> <h2 id='jump-*'> <h3 id> <h4 id> <h5 id> <h6 id> <drupal-media data-entity-type data-entity-uuid data-view-mode>";
$filter_format = FilterFormat::load('test_format');
$filter_format
->setFilterConfig('filter_html', [
'status' => TRUE,
'settings' => [
'allowed_html' => $allowed_html,
],
])
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media', 2000));
$assert_session
->elementExists('css', '.cke_widget_drupalmedia[aria-label="Screaming hairy armadillo"]');
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->fieldNotExists('attributes[alt]');
$assert_session
->fieldNotExists('attributes[align]');
$assert_session
->fieldNotExists('hasCaption');
$assert_session
->pageTextContains('There is nothing to configure for this media.');
$assert_session
->pageTextNotContains('Edit the text format Test format to modify the attributes that can be overridden.');
$page
->pressButton('Close');
$this
->getSession()
->switchToIFrame('ckeditor');
Role::load(RoleInterface::AUTHENTICATED_ID)
->grantPermission('administer filters')
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media', 2000));
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->fieldNotExists('attributes[alt]');
$assert_session
->fieldNotExists('attributes[align]');
$assert_session
->fieldNotExists('hasCaption');
$assert_session
->pageTextContains('There is nothing to configure for this media. Edit the text format Test format to modify the attributes that can be overridden.');
$assert_session
->linkExists('Edit the text format Test format');
$page
->pressButton('Close');
$this
->getSession()
->switchToIFrame('ckeditor');
$allowed_html = str_replace('<drupal-media data-entity-type data-entity-uuid data-view-mode>', '<drupal-media alt data-align data-caption data-entity-type data-entity-uuid data-view-mode>', $allowed_html);
$filter_format
->setFilterConfig('filter_html', [
'status' => TRUE,
'settings' => [
'allowed_html' => $allowed_html,
],
])
->save();
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media', 2000));
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->fieldExists('attributes[alt]');
$assert_session
->fieldExists('attributes[data-align]');
$assert_session
->fieldExists('hasCaption');
$page
->pressButton('Close');
$this
->getSession()
->switchToIFrame('ckeditor');
FieldConfig::loadByName('media', 'image', 'field_media_image')
->setSetting('alt_field', FALSE)
->save();
$this->container
->get('cache.discovery')
->delete('entity_bundle_field_definitions:media:image:en');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media', 2000));
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->fieldNotExists('attributes[alt]');
$assert_session
->fieldExists('attributes[data-align]');
$assert_session
->fieldExists('hasCaption');
$page
->pressButton('Close');
$this
->getSession()
->switchToIFrame('ckeditor');
FieldConfig::loadByName('media', 'image', 'field_media_image')
->setSetting('alt_field', TRUE)
->save();
$this->container
->get('cache.discovery')
->delete('entity_bundle_field_definitions:media:image:en');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media', 2000));
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->fieldExists('attributes[alt]');
$assert_session
->fieldExists('attributes[data-align]');
$assert_session
->fieldExists('hasCaption');
$page
->pressButton('Close');
$this
->getSession()
->switchToIFrame('ckeditor');
$filter_format
->setFilterConfig('filter_caption', [
'status' => FALSE,
])
->setFilterConfig('filter_align', [
'status' => FALSE,
])
->save();
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media', 2000));
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->fieldNotExists('attributes[data-align]');
$assert_session
->fieldNotExists('hasCaption');
$assert_session
->fieldExists('attributes[alt]');
$page
->pressButton('Close');
$this
->getSession()
->switchToIFrame('ckeditor');
$filter_format
->setFilterConfig('filter_caption', [
'status' => TRUE,
])
->setFilterConfig('filter_align', [
'status' => TRUE,
])
->save();
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media', 2000));
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->fieldExists('attributes[data-align]');
$assert_session
->fieldExists('hasCaption');
$assert_session
->pageTextNotContains('There is nothing to configure for this media. Edit the text format Test format to modify the attributes that can be overridden.');
$assert_session
->fieldExists('attributes[alt]');
}
public function testAlt() {
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media img'));
$this
->pressEditorButton('source');
$this
->assertSourceAttributeSame('alt', NULL);
$this
->leaveSourceMode();
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media img[alt*="default alt"]'));
$this
->openMetadataDialogWithKeyPress(static::RETURN_KEY);
$assert_session
->elementAttributeContains('named', [
'field',
'attributes[alt]',
], 'placeholder', 'default alt');
$who_is_zartan = 'Zartan is the leader of the Dreadnoks.';
$page
->fillField('attributes[alt]', $who_is_zartan);
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media img[alt*="' . $who_is_zartan . '"]'));
$assert_session
->elementExists('css', '.cke_widget_drupalmedia[aria-label="Screaming hairy armadillo"]');
$this
->pressEditorButton('source');
$this
->assertSourceAttributeSame('alt', $who_is_zartan);
$this
->leaveSourceMode();
$this
->openMetadataDialog();
$assert_session
->fieldValueEquals('attributes[alt]', $who_is_zartan);
$cobra_commander_bio = 'The supreme leader of the terrorist organization Cobra';
$page
->fillField('attributes[alt]', $cobra_commander_bio);
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media img[alt*="' . $cobra_commander_bio . '"]'));
$this
->pressEditorButton('source');
$this
->assertSourceAttributeSame('alt', $cobra_commander_bio);
$this
->leaveSourceMode();
$this
->openMetadataDialogWithKeyPress(static::RETURN_KEY);
$assert_session
->fieldValueEquals('attributes[alt]', $cobra_commander_bio);
$page
->fillField('attributes[alt]', '"" ');
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media img[alt=""]'));
$this
->pressEditorButton('source');
$this
->assertSourceAttributeSame('alt', '""');
$this
->leaveSourceMode();
$this
->openMetadataDialog();
$page
->fillField('attributes[alt]', '');
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media img[alt*="default alt"]'));
$this
->pressEditorButton('source');
$this
->assertSourceAttributeSame('alt', NULL);
}
public function testTranslationAlt() {
\Drupal::service('module_installer')
->install([
'language',
'content_translation',
]);
$this
->resetAll();
ConfigurableLanguage::create([
'id' => 'fr',
])
->save();
ContentLanguageSettings::loadByEntityTypeBundle('media', 'image')
->setDefaultLangcode('en')
->setLanguageAlterable(TRUE)
->save();
$media = Media::create([
'bundle' => 'image',
'name' => 'Screaming hairy armadillo',
'field_media_image' => [
[
'target_id' => 1,
'alt' => 'default alt',
'title' => 'default title',
],
],
]);
$media
->save();
$media_fr = $media
->addTranslation('fr');
$media_fr->name = "Tatou poilu hurlant";
$media_fr->field_media_image
->setValue([
[
'target_id' => '1',
'alt' => "texte alternatif par défaut",
'title' => "titre alternatif par défaut",
],
]);
$media_fr
->save();
ContentLanguageSettings::loadByEntityTypeBundle('node', 'blog')
->setDefaultLangcode('en')
->setLanguageAlterable(TRUE)
->save();
$host = $this
->createNode([
'type' => 'blog',
'title' => 'Animals with strange names',
'body' => [
'value' => '<drupal-media data-caption="baz" data-entity-type="media" data-entity-uuid="' . $media
->uuid() . '"></drupal-media>',
'format' => 'test_format',
],
]);
$host
->save();
$translation = $host
->addTranslation('fr');
$translation->title = 'Animaux avec des noms étranges';
$translation->body->value = $host->body->value;
$translation->body->format = $host->body->format;
$translation
->save();
Role::load(RoleInterface::AUTHENTICATED_ID)
->grantPermission('translate any entity')
->save();
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
$this
->drupalGet('/fr/node/' . $host
->id() . '/edit');
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('xpath', '//img[contains(@alt, "texte alternatif par défaut")]'));
$assert_session
->elementExists('css', '.cke_widget_drupalmedia[aria-label="Tatou poilu hurlant"]');
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->elementAttributeContains('named', [
'field',
'attributes[alt]',
], 'placeholder', 'texte alternatif par défaut');
$qui_est_zartan = 'Zartan est le chef des Dreadnoks.';
$page
->fillField('attributes[alt]', $qui_est_zartan);
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('xpath', '//img[contains(@alt, "' . $qui_est_zartan . '")]'));
$this
->getSession()
->switchToIFrame();
$page
->pressButton('Save');
$assert_session
->elementExists('xpath', '//img[contains(@alt, "' . $qui_est_zartan . '")]');
}
public function testLinkability($drupalimage_is_enabled) {
if (!$drupalimage_is_enabled) {
$editor = Editor::load('test_format');
$settings = $editor
->getSettings();
$rows = $settings['toolbar']['rows'];
foreach ($rows as $row_key => $row) {
foreach ($row as $group_key => $group) {
foreach ($group['items'] as $item_key => $item) {
if ($item === 'DrupalImage') {
unset($settings['toolbar']['rows'][$row_key][$group_key]['items'][$item_key]);
}
}
}
}
$editor
->setSettings($settings);
$editor
->save();
}
$this->host->body->value .= '<p>The pirate is irate.</p><p>';
if ($drupalimage_is_enabled) {
$uri = $this->media->field_media_image->entity
->getFileUri();
$file_url_generator = \Drupal::service('file_url_generator');
$src = $file_url_generator
->generateString($uri);
$this->host->body->value .= '<a href="http://www.drupal.org/association"><img alt="drupalimage test image" data-entity-type="" data-entity-uuid="" src="' . $src . '" /></a></p>';
}
$this->host
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session = $this
->assertSession();
$drupalmedia = $assert_session
->waitForElementVisible('css', 'drupal-media');
$this
->assertNotEmpty($drupalmedia);
$drupalmedia
->click();
$this
->openContextMenu();
$this
->assignNameToCkeditorPanelIframe();
$this
->getSession()
->switchToIFrame('panel');
$this
->assertContextMenuItemNotExists('Edit Link');
$this
->assertContextMenuItemNotExists('Unlink');
$this
->closeContextMenu();
$this
->pressEditorButton('drupallink');
$assert_session
->waitForId('drupal-modal');
$field = $assert_session
->waitForElementVisible('xpath', '//input[@name="attributes[href]"]');
$this
->assertNotEmpty($field);
$field
->setValue('https://www.drupal.org');
$assert_session
->elementExists('css', 'button.form-submit')
->press();
$this
->getSession()
->switchToIFrame('ckeditor');
$link = $assert_session
->waitForElementVisible('css', 'a[href="https://www.drupal.org"]');
$this
->assertNotEmpty($link);
$drupalmedia = $assert_session
->waitForElementVisible('css', 'drupal-media');
$this
->assertNotEmpty($drupalmedia);
$drupalmedia
->click();
$this
->openContextMenu();
$this
->getSession()
->switchToIFrame('panel');
$this
->assertContextMenuItemExists('Edit Link');
$this
->assertContextMenuItemExists('Unlink');
$this
->closeContextMenu();
$this
->getSession()
->switchToIFrame();
$assert_session
->buttonExists('Save')
->press();
$assert_session
->elementExists('css', 'figure > a[href="https://www.drupal.org"] > .media--type-image > .field--type-image > img[src*="image-test.png"]');
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->pressEditorButton('drupallink');
$assert_session
->waitForId('drupal-modal');
$field = $assert_session
->waitForElementVisible('xpath', '//input[@name="attributes[href]"]');
$this
->assertNotEmpty($field);
$field
->setValue('https://wikipedia.org');
$assert_session
->elementExists('css', 'button.form-submit')
->press();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$link = $assert_session
->waitForElementVisible('css', 'body > a[href="https://wikipedia.org"]');
$this
->assertNotEmpty($link);
$assert_session
->elementExists('css', 'body > .cke_widget_drupalmedia > drupal-media > figure > a[href="https://www.drupal.org"]');
$drupalmedia = $assert_session
->waitForElementVisible('css', 'drupal-media');
$this
->assertNotEmpty($drupalmedia);
$drupalmedia
->click();
$this
->openContextMenu();
$this
->getSession()
->switchToIFrame();
$this
->assertEditorButtonEnabled('drupalunlink');
$this
->assignNameToCkeditorPanelIframe();
$this
->getSession()
->switchToIFrame('panel');
$this
->assertContextMenuItemExists('Edit Link');
$this
->assertContextMenuItemExists('Unlink');
$this
->getSession()
->switchToIFrame();
$this
->getSession()
->switchToIFrame('ckeditor');
$p = $assert_session
->waitForElementVisible('xpath', "//p[contains(text(), 'The pirate is irate')]");
$this
->assertNotEmpty($p);
$p
->click();
$this
->assertEditorButtonDisabled('drupalunlink');
$this
->getSession()
->switchToIFrame('panel');
$this
->assertContextMenuItemExists('Edit Link');
$this
->assertContextMenuItemExists('Unlink');
$this
->getSession()
->switchToIFrame();
$this
->getSession()
->switchToIFrame('ckeditor');
if ($drupalimage_is_enabled) {
$drupalimage = $assert_session
->waitForElementVisible('xpath', '//img[@alt="drupalimage test image"]');
$this
->assertNotEmpty($drupalimage);
$drupalimage
->click();
$this
->assertEditorButtonEnabled('drupalunlink');
$this
->getSession()
->switchToIFrame('panel');
$this
->assertContextMenuItemExists('Edit Link');
$this
->assertContextMenuItemExists('Unlink');
$this
->getSession()
->switchToIFrame();
$this
->getSession()
->switchToIFrame('ckeditor');
}
$drupalmedia
->click();
$this
->assertEditorButtonEnabled('drupalunlink');
$this
->getSession()
->switchToIFrame('panel');
$this
->assertContextMenuItemExists('Edit Link');
$this
->assertContextMenuItemExists('Unlink');
$this
->pressEditorButton('drupalunlink');
$this
->assertEditorButtonDisabled('drupalunlink');
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session
->elementNotExists('css', 'figure > a[href="https://www.drupal.org"] > .media--type-image > .field--type-image > img[src*="image-test.png"]');
$assert_session
->elementExists('css', 'figure .media--type-image > .field--type-image > img[src*="image-test.png"]');
if ($drupalimage_is_enabled) {
$drupalimage
->click();
$this
->assertEditorButtonEnabled('drupalunlink');
$this
->pressEditorButton('drupalunlink');
$this
->assertEditorButtonDisabled('drupalunlink');
$this
->getSession()
->switchToIFrame('ckeditor');
$assert_session
->elementNotExists('css', 'p > a[href="https://www.drupal.org/association"] > img[src*="image-test.png"]');
$assert_session
->elementExists('css', 'p > img[src*="image-test.png"]');
}
}
public function linkabilityProvider() {
return [
'linkability when `drupalimage` is enabled' => [
TRUE,
],
'linkability when `drupalimage` is disabled' => [
FALSE,
],
];
}
public function testEmbedPreviewAccess($media_embed_enabled, $can_use_format) {
$format = FilterFormat::create([
'format' => $this
->randomMachineName(),
'name' => $this
->randomString(),
'filters' => [
'filter_align' => [
'status' => TRUE,
],
'filter_caption' => [
'status' => TRUE,
],
'media_embed' => [
'status' => $media_embed_enabled,
],
],
]);
$format
->save();
$permissions = [
'bypass node access',
];
if ($can_use_format) {
$permissions[] = $format
->getPermissionName();
}
$this
->drupalLogin($this
->drupalCreateUser($permissions));
$text = '<drupal-media data-caption="baz" data-entity-type="media" data-entity-uuid="' . $this->media
->uuid() . '"></drupal-media>';
$route_parameters = [
'filter_format' => $format
->id(),
];
$options = [
'query' => [
'text' => $text,
'uuid' => $this->media
->uuid(),
],
];
$this
->drupalGet(Url::fromRoute('media.filter.preview', $route_parameters, $options));
$assert_session = $this
->assertSession();
if ($media_embed_enabled && $can_use_format) {
$assert_session
->elementExists('css', 'img');
$assert_session
->responseContains('baz');
}
else {
$assert_session
->responseContains('You are not authorized to access this page.');
}
}
public function previewAccessProvider() {
return [
'media_embed filter enabled' => [
TRUE,
TRUE,
],
'media_embed filter disabled' => [
FALSE,
TRUE,
],
'media_embed filter enabled, user not allowed to use text format' => [
TRUE,
FALSE,
],
];
}
public function testAlignment() {
$assert_session = $this
->assertSession();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElement('css', 'drupal-media img'));
$drupal_media = $assert_session
->elementExists('css', 'drupal-media');
$this
->assertFalse($drupal_media
->hasAttribute('data-align'));
$alignments = [
'right',
'left',
'center',
];
foreach ($alignments as $alignment) {
$this
->fillFieldInMetadataDialogAndSubmit('attributes[data-align]', $alignment);
$this
->assertNotEmpty($assert_session
->waitForElement('css', 'drupal-media img'));
$selector = sprintf('drupal-media[data-align="%s"] .caption-drupal-media.align-%s', $alignment, $alignment);
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', $selector, 2000));
$this
->pressEditorButton('source');
$this
->assertSourceAttributeSame('data-align', $alignment);
$this
->leaveSourceMode();
}
$this
->fillFieldInMetadataDialogAndSubmit('attributes[data-align]', 'none');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media .caption-drupal-media:not(.align-center)', 2000));
$drupal_media = $assert_session
->elementExists('css', 'drupal-media');
$this
->assertFalse($drupal_media
->hasAttribute('data-align'));
$this
->pressEditorButton('source');
$this
->assertNotEmpty($drupal_media = $this
->getDrupalMediaFromSource());
$this
->assertFalse($drupal_media
->hasAttribute('data-align'));
}
public function testViewMode() {
EntityViewMode::create([
'id' => 'media.view_mode_1',
'targetEntityType' => 'media',
'status' => TRUE,
'enabled' => TRUE,
'label' => 'View Mode 1',
])
->save();
EntityViewMode::create([
'id' => 'media.view_mode_2',
'targetEntityType' => 'media',
'status' => TRUE,
'enabled' => TRUE,
'label' => 'View Mode 2',
])
->save();
EntityViewMode::create([
'id' => 'media.view_mode_3',
'targetEntityType' => 'media',
'status' => TRUE,
'enabled' => TRUE,
'label' => 'View Mode 3',
])
->save();
EntityViewDisplay::create([
'id' => 'media.image.view_mode_1',
'targetEntityType' => 'media',
'status' => TRUE,
'bundle' => 'image',
'mode' => 'view_mode_1',
])
->save();
EntityViewDisplay::create([
'id' => 'media.image.view_mode_2',
'targetEntityType' => 'media',
'status' => TRUE,
'bundle' => 'image',
'mode' => 'view_mode_2',
])
->save();
$filter_format = FilterFormat::load('test_format');
$filter_format
->setFilterConfig('media_embed', [
'status' => TRUE,
'settings' => [
'default_view_mode' => 'view_mode_1',
'allowed_media_types' => [],
'allowed_view_modes' => [
'view_mode_1' => 'view_mode_1',
'view_mode_2' => 'view_mode_2',
'view_mode_3' => 'view_mode_3',
],
],
])
->save();
$expected_config_dependencies = [
'core.entity_view_mode.media.view_mode_1',
'core.entity_view_mode.media.view_mode_2',
'core.entity_view_mode.media.view_mode_3',
];
$dependencies = $filter_format
->getDependencies();
$this
->assertArrayHasKey('config', $dependencies);
$this
->assertSame($expected_config_dependencies, $dependencies['config']);
$page = $this
->getSession()
->getPage();
$assert_session = $this
->assertSession();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media'));
$assert_session
->elementExists('css', '.cke_widget_drupalmedia[aria-label="Screaming hairy armadillo"]');
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->optionExists('attributes[data-view-mode]', 'view_mode_1');
$assert_session
->optionExists('attributes[data-view-mode]', 'view_mode_2');
$assert_session
->optionNotExists('attributes[data-view-mode]', 'view_mode_3');
$assert_session
->selectExists('attributes[data-view-mode]')
->selectOption('view_mode_2');
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'article.media--view-mode-view-mode-2'));
$this
->pressEditorButton('source');
$this
->assertNotEmpty($drupal_media = $this
->getDrupalMediaFromSource());
$this
->assertSame('view_mode_2', $drupal_media
->getAttribute('data-view-mode'));
$this
->pressEditorButton('source');
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$filter_format
->setFilterConfig('media_embed', [
'status' => TRUE,
'settings' => [
'default_view_mode' => 'view_mode_1',
'allowed_media_types' => [],
'allowed_view_modes' => [
'view_mode_1' => 'view_mode_1',
],
],
])
->save();
$dependencies = $filter_format
->getDependencies();
$this
->assertArrayHasKey('config', $dependencies);
$this
->assertSame([
'core.entity_view_mode.media.view_mode_1',
], $dependencies['config']);
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media'));
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->fieldNotExists('attributes[data-view-mode]');
$page
->pressButton('Close');
$this
->getSession()
->switchToIFrame('ckeditor');
$filter_format
->setFilterConfig('media_embed', [
'status' => TRUE,
'settings' => [
'default_view_mode' => 'view_mode_1',
'allowed_media_types' => [],
'allowed_view_modes' => [
'view_mode_1' => 'view_mode_1',
'view_mode_2' => 'view_mode_2',
],
],
])
->save();
$expected_config_dependencies = [
'core.entity_view_mode.media.view_mode_1',
'core.entity_view_mode.media.view_mode_2',
];
$dependencies = $filter_format
->getDependencies();
$this
->assertArrayHasKey('config', $dependencies);
$this
->assertSame($expected_config_dependencies, $dependencies['config']);
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'drupal-media'));
$page
->pressButton('Edit media');
$this
->waitForMetadataDialog();
$assert_session
->optionExists('attributes[data-view-mode]', 'view_mode_1');
$assert_session
->optionExists('attributes[data-view-mode]', 'view_mode_2');
$assert_session
->selectExists('attributes[data-view-mode]')
->selectOption('view_mode_1');
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'article.media--view-mode-view-mode-1'));
$this
->pressEditorButton('source');
$this
->assertNotEmpty($drupal_media = $this
->getDrupalMediaFromSource());
$this
->assertFalse($drupal_media
->hasAttribute('data-view-mode'));
$original_value = $this->host->body->value;
$this->host->body->value = str_replace('data-caption="baz"', '', $original_value);
$this->host
->save();
$this
->drupalGet($this->host
->toUrl('edit-form'));
$this
->waitForEditor();
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', 'article.media--view-mode-view-mode-1'));
}
protected function waitForMetadataDialog() {
$page = $this
->getSession()
->getPage();
$this
->getSession()
->switchToIFrame();
$result = $page
->waitFor(10, function ($page) {
$metadata_editor = $page
->find('css', 'form.editor-media-dialog');
return !empty($metadata_editor);
});
$this
->assertTrue($result);
}
protected function fillFieldInMetadataDialogAndSubmit($locator, $value) {
$this
->openMetadataDialog();
$this
->getSession()
->getPage()
->fillField($locator, $value);
$this
->submitDialog();
$this
->getSession()
->switchToIFrame('ckeditor');
}
protected function openMetadataDialog() {
$this
->assertNotEmpty($embedded_media = $this
->assertSession()
->waitForElementVisible('css', 'drupal-media'));
$embedded_media
->pressButton('Edit media');
$this
->waitForMetadataDialog();
}
protected function openMetadataDialogWithKeyPress($char) {
$this
->assertNotEmpty($button = $this
->assertSession()
->waitForButton('Edit media'));
$button
->keyDown($char);
$this
->waitForMetadataDialog();
}
protected function leaveSourceMode() {
$this
->pressEditorButton('source');
$this
->assignNameToCkeditorIframe();
$this
->getSession()
->switchToIFrame('ckeditor');
}
protected function assertSourceAttributeSame($attribute, $value) {
$this
->assertNotEmpty($drupal_media = $this
->getDrupalMediaFromSource());
if ($value === NULL) {
$this
->assertFalse($drupal_media
->hasAttribute($attribute));
}
else {
$this
->assertSame($value, $drupal_media
->getAttribute($attribute));
}
}
protected function submitDialog() {
$this
->assertNotEmpty($dialog_buttons = $this
->assertSession()
->elementExists('css', 'div.ui-dialog-buttonpane'));
$dialog_buttons
->pressButton('Save');
}
protected function closeDialog() {
$page = $this
->getSession()
->getPage();
$page
->pressButton('Close');
$result = $page
->waitFor(10, function ($page) {
$metadata_editor = $page
->find('css', 'form.editor-media-dialog');
return empty($metadata_editor);
});
$this
->assertTrue($result);
}
protected function getLastPreviewRequestTransferSize() {
$this
->getSession()
->switchToIFrame();
$javascript = <<<JS
(function(){
return window.performance
.getEntries()
.filter(function (entry) {
return entry.initiatorType == 'xmlhttprequest' && entry.name.indexOf('/media/test_format/preview') !== -1;
})
.pop()
.transferSize;
})()
JS;
return $this
->getSession()
->evaluateScript($javascript);
}
protected function setCaption($text) {
$this
->getSession()
->switchToIFrame();
$select_and_edit_caption = "var editor = CKEDITOR.instances['edit-body-0-value'];\n var figcaption = editor.widgets.getByElement(editor.editable().findOne('figcaption'));\n figcaption.editables.caption.setData('" . $text . "')";
$this
->getSession()
->executeScript($select_and_edit_caption);
}
protected function assignNameToCkeditorPanelIframe() {
$javascript = <<<JS
(function(){
document.getElementsByClassName('cke_panel_frame')[0].id = 'panel';
})()
JS;
$this
->getSession()
->evaluateScript($javascript);
}
protected function openContextMenu($instance_id = 'edit-body-0-value') {
$this
->getSession()
->switchToIFrame();
$script = <<<JS
(function() {
var editor = CKEDITOR.instances["{<span class="php-variable">$instance_id</span>}"];
editor.contextMenu.open(editor.widgets.selected[0].element);
}());
JS;
$this
->getSession()
->executeScript($script);
}
protected function assertContextMenuItemExists($label) {
$this
->assertSession()
->elementExists('xpath', '//a[@aria-label="' . $label . '"]');
}
protected function assertContextMenuItemNotExists($label) {
$this
->assertSession()
->elementNotExists('xpath', '//a[@aria-label="' . $label . '"]');
}
protected function closeContextMenu($instance_id = 'edit-body-0-value') {
$this
->getSession()
->switchToIFrame();
$script = <<<JS
(function() {
var editor = CKEDITOR.instances["{<span class="php-variable">$instance_id</span>}"];
editor.contextMenu.hide();
}());
JS;
$this
->getSession()
->executeScript($script);
}
protected function clickPathLinkByTitleAttribute($text) {
$this
->getSession()
->switchToIFrame();
$selector = '//span[@id="cke_1_path"]//a[@title="' . $text . '"]';
$this
->assertSession()
->elementExists('xpath', $selector)
->click();
}
protected function getDrupalMediaFromSource() {
$value = $this
->assertSession()
->elementExists('css', 'textarea.cke_source')
->getValue();
$dom = Html::load($value);
$xpath = new \DOMXPath($dom);
$list = $xpath
->query('//drupal-media');
return count($list) > 0 ? $list[0] : NULL;
}
}