View source
<?php
namespace Drupal\Tests\layout_builder\FunctionalJavascript;
use Behat\Mink\Element\NodeElement;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block_content\Entity\BlockContentType;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
use Drupal\Tests\contextual\FunctionalJavascript\ContextualLinkClickTrait;
class LayoutBuilderDisableInteractionsTest extends WebDriverTestBase {
use ContextualLinkClickTrait;
protected static $modules = [
'block',
'block_content',
'filter',
'filter_test',
'layout_builder',
'node',
'search',
'contextual',
];
protected $defaultTheme = 'classy';
protected function setUp() : void {
parent::setUp();
$this
->createContentType([
'type' => 'bundle_with_section_field',
]);
$this
->createNode([
'type' => 'bundle_with_section_field',
'title' => 'The first node title',
'body' => [
[
'value' => 'Node body',
],
],
]);
$bundle = BlockContentType::create([
'id' => 'basic',
'label' => 'Basic block',
'revision' => 1,
]);
$bundle
->save();
block_content_add_body_field($bundle
->id());
BlockContent::create([
'type' => 'basic',
'info' => 'Block with link',
'body' => [
'value' => '<a id="link-that-should-be-disabled" href="/search/node">Take me away</a>',
'format' => 'full_html',
],
])
->save();
BlockContent::create([
'type' => 'basic',
'info' => 'Block with iframe',
'body' => [
'value' => '<iframe id="iframe-that-should-be-disabled" width="1" height="1" src="https://www.youtube.com/embed/gODZzSOelss" frameborder="0"></iframe>',
'format' => 'full_html',
],
])
->save();
}
public function testFormsLinksDisabled() {
$this
->getSession()
->resizeWindow(1200, 1200);
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
$this
->drupalLogin($this
->drupalCreateUser([
'configure any layout',
'administer node display',
'administer node fields',
'search content',
'access contextual links',
]));
$field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field';
$this
->drupalGet("{$field_ui_prefix}/display");
$this
->submitForm([
'layout[enabled]' => TRUE,
], 'Save');
$assert_session
->linkExists('Manage layout');
$this
->clickLink('Manage layout');
$this
->addBlock('Search form', '#layout-builder .search-block-form');
$this
->addBlock('Block with link', '#link-that-should-be-disabled');
$this
->addBlock('Block with iframe', '#iframe-that-should-be-disabled');
$this
->assertLinksFormIframeNotInteractive();
$page
->pressButton('Save layout');
$this
->clickLink('Manage layout');
$this
->assertLinksFormIframeNotInteractive();
$this
->assertContextualLinksClickable();
$this
->drupalGet("{$field_ui_prefix}/display/default");
$this
->submitForm([
'layout[allow_custom]' => TRUE,
], 'Save');
$this
->drupalGet('node/1/layout');
$this
->assertLinksFormIframeNotInteractive();
$this
->assertContextualLinksClickable();
}
protected function addBlock($block_link_text, $rendered_locator) {
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', '#layout-builder a:contains(\'Add block\')'));
$this
->clickLink('Add block');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', '#drupal-off-canvas'));
$assert_session
->assertWaitOnAjaxRequest();
$assert_session
->linkExists($block_link_text);
$this
->clickLink($block_link_text);
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', ".layout-builder-add-block"));
$assert_session
->assertWaitOnAjaxRequest();
$page
->pressButton('Add block');
$this
->assertNotEmpty($assert_session
->waitForElement('css', $rendered_locator));
}
protected function assertElementUnclickable(NodeElement $element) {
try {
$element
->click();
$tag_name = $element
->getTagName();
$this
->fail(new FormattableMarkup("@tag_name was clickable when it shouldn't have been", [
'@tag_name' => $tag_name,
]));
} catch (\Exception $e) {
$this
->assertStringContainsString('is not clickable at point', $e
->getMessage());
}
}
protected function assertLinksFormIframeNotInteractive() {
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
$this
->assertNotEmpty($assert_session
->waitForElement('css', '.block-search'));
$searchButton = $assert_session
->buttonExists('Search');
$this
->assertElementUnclickable($searchButton);
$assert_session
->linkExists('Take me away');
$this
->assertElementUnclickable($page
->findLink('Take me away'));
$iframe = $assert_session
->elementExists('css', '#iframe-that-should-be-disabled');
$this
->assertElementUnclickable($iframe);
}
protected function assertContextualLinksClickable() {
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
$this
->drupalGet($this
->getUrl());
$this
->clickContextualLink('.block-field-blocknodebundle-with-section-fieldbody [data-contextual-id^="layout_builder_block"]', 'Configure');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', '.ui-dialog-titlebar [title="Close"]'));
$page
->pressButton('Close');
$assert_session
->assertNoElementAfterWait('css', '#drupal-off-canvas');
$this
->clickContextualLink('.block-field-blocknodebundle-with-section-fieldbody [data-contextual-id^="layout_builder_block"]', 'Configure');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', '#drupal-off-canvas'));
$page
->pressButton('Close');
$assert_session
->assertNoElementAfterWait('css', '#drupal-off-canvas');
$this
->assertContextualLinkRetainsMouseup();
}
protected function assertContextualLinkRetainsMouseup() {
$assert_session = $this
->assertSession();
$page = $this
->getSession()
->getPage();
$body_field_selector = '.block-field-blocknodebundle-with-section-fieldbody';
$body_block = $page
->find('css', $body_field_selector);
$this
->assertNotEmpty($body_block);
$body_block_top_position = $this
->getElementVerticalPosition($body_field_selector, 'top');
$body_block_contextual_link_button = $body_block
->find('css', '.trigger');
$this
->assertNotEmpty($body_block_contextual_link_button);
if ($body_block_contextual_link_button
->hasClass('visually-hidden')) {
$this
->toggleContextualTriggerVisibility($body_field_selector);
}
$body_block
->pressButton('Open configuration options');
$body_block
->clickLink('Configure');
$this
->assertNotEmpty($assert_session
->waitForElementVisible('css', '#drupal-off-canvas'));
$assert_session
->assertWaitOnAjaxRequest();
$this
->movePointerTo('#iframe-that-should-be-disabled');
$new_body_block_bottom_position = $this
->getElementVerticalPosition($body_field_selector, 'bottom');
$iframe_top_position = $this
->getElementVerticalPosition('#iframe-that-should-be-disabled', 'top');
$minimum_distance_mouse_moved = $iframe_top_position - $new_body_block_bottom_position;
$this
->assertGreaterThan(200, $minimum_distance_mouse_moved, 'The mouse moved at least 200 pixels');
$new_body_block_top_position = $this
->getElementVerticalPosition($body_field_selector, 'top');
$distance_body_block_moved = abs($body_block_top_position - $new_body_block_top_position);
$this
->assertGreaterThan($distance_body_block_moved * 20, $minimum_distance_mouse_moved);
}
protected function getElementVerticalPosition($css_selector, $position_type) {
$this
->assertContains($position_type, [
'top',
'bottom',
], 'Expected position type.');
return (int) $this
->getSession()
->evaluateScript("document.querySelector('{$css_selector}').getBoundingClientRect().{$position_type} + window.pageYOffset");
}
protected function movePointerTo($selector) {
$driver_session = $this
->getSession()
->getDriver()
->getWebDriverSession();
$element = $driver_session
->element('css selector', $selector);
$driver_session
->moveto([
'element' => $element
->getID(),
]);
}
}