BlockFormMessagesTest.php 5.15 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php

namespace Drupal\Tests\layout_builder\FunctionalJavascript;

use Behat\Mink\Element\NodeElement;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
use Drupal\Tests\contextual\FunctionalJavascript\ContextualLinkClickTrait;
use WebDriver\Exception\UnknownError;

/**
 * Tests that messages appear in the off-canvas dialog with configuring blocks.
 *
 * @group layout_builder
 */
class BlockFormMessagesTest extends WebDriverTestBase {

  use ContextualLinkClickTrait;

  /**
   * {@inheritdoc}
   */
  public static $modules = [
    'layout_builder',
    'block',
    'node',
    'contextual',
  ];

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $this->createContentType(['type' => 'bundle_with_section_field']);
  }

  /**
   * Tests that validation messages are shown on the block form.
   */
  public function testValidationMessage() {
41
42
43
    // @todo Work out why this fixes random fails in this test.
    //    https://www.drupal.org/project/drupal/issues/3055982
    $this->getSession()->resizeWindow(800, 1000);
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    $assert_session = $this->assertSession();
    $page = $this->getSession()->getPage();

    $this->drupalLogin($this->drupalCreateUser([
      'access contextual links',
      'configure any layout',
      'administer node display',
      'administer node fields',
    ]));
    $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field';
    // Enable layout builder.
    $this->drupalPostForm(
      $field_ui_prefix . '/display/default',
      ['layout[enabled]' => TRUE],
      'Save'
    );
    $this->clickElementWhenClickable($page->findLink('Manage layout'));
    $assert_session->addressEquals($field_ui_prefix . '/display/default/layout');
62
    $this->clickElementWhenClickable($page->findLink('Add block'));
63
64
65
66
    $this->assertNotEmpty($assert_session->waitForElementVisible('css', '#drupal-off-canvas .block-categories'));
    $this->clickElementWhenClickable($page->findLink('Powered by Drupal'));
    $this->assertNotEmpty($assert_session->waitForElementVisible('css', '#drupal-off-canvas [name="settings[label]"]'));
    $page->findField('Title')->setValue('');
67
    $this->clickElementWhenClickable($page->findButton('Add block'));
68
69
    $this->assertMessagesDisplayed();
    $page->findField('Title')->setValue('New title');
70
    $page->pressButton('Add block');
71
72
    $block_css_locator = '#layout-builder .block-system-powered-by-block';
    $this->assertNotEmpty($assert_session->waitForElementVisible('css', $block_css_locator));
73

74
    $assert_session->assertNoElementAfterWait('css', '#drupal-off-canvas');
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
    $assert_session->assertWaitOnAjaxRequest();
    $this->drupalGet($this->getUrl());
    $this->clickElementWhenClickable($page->findButton('Save layout'));
    $this->assertNotEmpty($assert_session->waitForElement('css', 'div:contains("The layout has been saved")'));

    // Ensure that message are displayed when configuring an existing block.
    $this->drupalGet($field_ui_prefix . '/display/default/layout');
    $assert_session->assertWaitOnAjaxRequest();
    $this->clickContextualLink($block_css_locator, 'Configure', TRUE);
    $this->assertNotEmpty($assert_session->waitForElementVisible('css', '#drupal-off-canvas [name="settings[label]"]'));
    $page->findField('Title')->setValue('');
    $this->clickElementWhenClickable($page->findButton('Update'));
    $this->assertMessagesDisplayed();
  }

  /**
   * Asserts that the validation messages are shown correctly.
   */
  protected function assertMessagesDisplayed() {
    $assert_session = $this->assertSession();
    $page = $this->getSession()->getPage();
    $messages_locator = '#drupal-off-canvas .messages--error';
    $assert_session->assertWaitOnAjaxRequest();
    $this->assertNotEmpty($assert_session->waitForElement('css', $messages_locator));
    $assert_session->elementTextContains('css', $messages_locator, 'Title field is required.');
    /** @var \Behat\Mink\Element\NodeElement[] $top_form_elements */
    $top_form_elements = $page->findAll('css', '#drupal-off-canvas form > *');
    // Ensure the messages are the first top level element of the form.
    $this->assertTrue(stristr($top_form_elements[0]->getText(), 'Title field is required.') !== FALSE);
    $this->assertGreaterThan(4, count($top_form_elements));
  }

  /**
   * Attempts to click an element until it is in a clickable state.
   *
   * @param \Behat\Mink\Element\NodeElement $element
   *   The element to click.
   * @param int $timeout
   *   (Optional) Timeout in milliseconds, defaults to 10000.
   *
   * @todo Replace this method with general solution for random click() test
   *   failures in https://www.drupal.org/node/3032275.
   */
  protected function clickElementWhenClickable(NodeElement $element, $timeout = 10000) {
    $page = $this->getSession()->getPage();

    $result = $page->waitFor($timeout / 1000, function () use ($element) {
      try {
        $element->click();
        return TRUE;
      }
      catch (UnknownError $exception) {
        if (strstr($exception->getMessage(), 'not clickable') === FALSE) {
          // Rethrow any unexpected UnknownError exceptions.
          throw $exception;
        }
        return NULL;
      }
    });
    $this->assertTrue($result);
  }

}