You are here

public function CKEditorIntegrationTest::testEditableCaption in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/media/tests/src/FunctionalJavascript/CKEditorIntegrationTest.php \Drupal\Tests\media\FunctionalJavascript\CKEditorIntegrationTest::testEditableCaption()

Tests caption editing in the CKEditor widget.

File

core/modules/media/tests/src/FunctionalJavascript/CKEditorIntegrationTest.php, line 312

Class

CKEditorIntegrationTest
@coversDefaultClass \Drupal\media\Plugin\CKEditorPlugin\DrupalMedia @group media

Namespace

Drupal\Tests\media\FunctionalJavascript

Code

public function testEditableCaption() {
  $page = $this
    ->getSession()
    ->getPage();
  $assert_session = $this
    ->assertSession();

  // Test that setting caption to blank string doesn't break 'Edit media'
  // button.
  $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'));

  // Test `aria-label` attribute appears on the widget wrapper.
  $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');

  // Test if you leave the caption blank, but change another attribute,
  // such as the alt text, the editable caption is still there and the edit
  // button still exists.
  $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');

  // Restore caption in saved body value.
  $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');

  // Assert that figcaption element exists within the drupal-media element.
  $this
    ->assertNotEmpty($figcaption = $assert_session
    ->waitForElement('css', 'drupal-media figcaption'));
  $this
    ->assertSame('baz', $figcaption
    ->getHtml());

  // Test that disabling the caption in the metadata dialog removes it
  // from the drupal-media element.
  $this
    ->openMetadataDialogWithKeyPress(static::SPACE_BAR);
  $page
    ->uncheckField('hasCaption');
  $this
    ->submitDialog();
  $this
    ->getSession()
    ->switchToIFrame('ckeditor');
  $this
    ->assertNotEmpty($drupal_media = $assert_session
    ->waitForElementVisible('css', 'drupal-media'));

  // Wait for element to update without figcaption.
  $result = $page
    ->waitFor(10, function () use ($drupal_media) {
    return empty($drupal_media
      ->find('css', 'figcaption'));
  });

  // Will be true if no figcaption exists within the drupal-media element.
  $this
    ->assertTrue($result);

  // Test that enabling the caption in the metadata dialog adds an editable
  // caption to the embedded media.
  $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'));

  // Type into the widget's caption element.
  $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();

  // Select the <strong> element and unbold it.
  $this
    ->clickPathLinkByTitleAttribute("strong element");
  $this
    ->pressEditorButton('bold');
  $this
    ->getSession()
    ->switchToIFrame('ckeditor');
  $assert_session
    ->elementExists('css', 'figcaption > em');
  $assert_session
    ->elementNotExists('css', 'figcaption > strong');

  // Select the <em> element and unitalicize it.
  $assert_session
    ->elementExists('css', 'figcaption > em')
    ->click();
  $this
    ->clickPathLinkByTitleAttribute("em element");
  $this
    ->pressEditorButton('italic');

  // The "source" button should reveal the HTML source in a state matching
  // what is shown in the CKEditor widget.
  $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'));

  // Change the caption by modifying the HTML source directly. When exiting
  // "source" mode, this should be respected.
  $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());

  // Select the <strong> element that we just set in "source" mode. This
  // proves that it was indeed rendered by the CKEditor widget.
  $strong = $figcaption
    ->find('css', 'strong');
  $this
    ->assertNotEmpty($strong);
  $strong
    ->click();
  $this
    ->pressEditorButton('bold');

  // Insert a link into the caption.
  $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();

  // Wait for the live preview in the CKEditor widget to finish loading, then
  // edit the link; no `data-cke-saved-href` attribute should exist on it.
  $this
    ->getSession()
    ->switchToIFrame('ckeditor');
  $figcaption = $assert_session
    ->waitForElement('css', 'figcaption');
  $page = $this
    ->getSession()
    ->getPage();

  // Wait for AJAX refresh.
  $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();

  // Wait for AJAX refresh.
  $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);

  // Save the entity.
  $assert_session
    ->buttonExists('Save')
    ->press();

  // Verify the saved entity when viewed also contains the captioned media.
  $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());

  // Edit it again, type a different caption in the widget.
  $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>?');

  // Erase the caption in the CKEditor Widget, verify the <figcaption> still
  // exists and contains placeholder text, then type something else.
  $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.');
}