summaryrefslogtreecommitdiffstatshomepage
path: root/core/modules/toolbar/tests/src/FunctionalJavascript/ToolbarIntegrationTest.php
blob: dcf0ff6d79c3b7ea45a564f698c3f6f676aeee60 (plain) (blame)
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
<?php

declare(strict_types=1);

namespace Drupal\Tests\toolbar\FunctionalJavascript;

use Behat\Mink\Element\NodeElement;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;

/**
 * Tests the JavaScript functionality of the toolbar.
 *
 * @group toolbar
 */
class ToolbarIntegrationTest extends WebDriverTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = ['toolbar', 'node'];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * Tests if the toolbar can be toggled with JavaScript.
   */
  public function testToolbarToggling(): void {
    $admin_user = $this->drupalCreateUser([
      'access toolbar',
      'administer site configuration',
      'access content overview',
    ]);
    $this->drupalLogin($admin_user);

    // Set size for horizontal toolbar.
    $this->getSession()->resizeWindow(1200, 600);
    $this->drupalGet('<front>');
    $this->assertNotEmpty($this->assertSession()->waitForElement('css', 'body.toolbar-horizontal'));
    $this->assertNotEmpty($this->assertSession()->waitForElementVisible('css', '.toolbar-tray'));

    $page = $this->getSession()->getPage();

    // Test that it is possible to toggle the toolbar tray.
    $content_link = $page->findLink('Content');
    $manage_link = $page->find('css', '#toolbar-item-administration');

    // Start with open tray.
    $this->waitAndAssertAriaPressedState($manage_link, TRUE);
    $this->assertTrue($content_link->isVisible(), 'Toolbar tray is open by default.');

    // Click to close.
    $manage_link->click();
    $this->waitAndAssertAriaPressedState($manage_link, FALSE);
    $this->assertFalse($content_link->isVisible(), 'Toolbar tray is closed after clicking the "Manage" link.');

    // Click to open.
    $manage_link->click();
    $this->waitAndAssertAriaPressedState($manage_link, TRUE);
    $this->assertTrue($content_link->isVisible(), 'Toolbar tray is visible again after clicking the "Manage" button a second time.');

    // Test toggling the toolbar tray between horizontal and vertical.
    $tray = $page->findById('toolbar-item-administration-tray');
    $this->assertFalse($tray->hasClass('toolbar-tray-vertical'), 'Toolbar tray is not vertically oriented by default.');
    $page->pressButton('Vertical orientation');
    $this->assertTrue($tray->hasClass('toolbar-tray-vertical'), 'After toggling the orientation the toolbar tray is now displayed vertically.');

    $page->pressButton('Horizontal orientation');
    $this->assertTrue($tray->hasClass('toolbar-tray-horizontal'), 'After toggling the orientation a second time the toolbar tray is displayed horizontally again.');
  }

  /**
   * Tests that the orientation toggle is not shown for empty toolbar items.
   */
  public function testEmptyTray(): void {
    // Granting access to the toolbar but not any administrative menu links will
    // result in an empty toolbar tray for the "Manage" toolbar item.
    $admin_user = $this->drupalCreateUser([
      'access toolbar',
    ]);
    $this->drupalLogin($admin_user);

    // Set size for horizontal toolbar.
    $this->getSession()->resizeWindow(1200, 600);
    $this->drupalGet('<front>');
    $this->assertNotEmpty($this->assertSession()->waitForElement('css', 'body.toolbar-horizontal'));
    $this->assertNotEmpty($this->assertSession()->waitForElementVisible('css', '.toolbar-tray'));

    // Test that the orientation toggle does not appear.
    $page = $this->getSession()->getPage();
    $tray = $page->findById('toolbar-item-administration-tray');
    $this->assertTrue($tray->hasClass('toolbar-tray-horizontal'), 'Toolbar tray is horizontally oriented by default.');
    $this->assertSession()->elementNotExists('css', '#toolbar-item-administration-tray .toolbar-menu');
    $this->assertSession()->elementNotExists('css', '#toolbar-item-administration-tray .toolbar-toggle-orientation');
    $button = $page->findButton('Vertical orientation');
    $this->assertFalse($button->isVisible(), 'Orientation toggle from other tray is not visible');
  }

  /**
   * Asserts that an element's `aria-pressed` attribute matches expected state.
   *
   * Uses `waitFor()` to pause until either the condition is met or the timeout
   * of `1` second has passed.
   *
   * @param \Behat\Mink\Element\NodeElement $element
   *   The element to be tested.
   * @param bool $expected
   *   The expected value of `aria-pressed`, as a boolean.
   *
   * @throws ExpectationFailedException
   */
  private function waitAndAssertAriaPressedState(NodeElement $element, bool $expected): void {
    $this->assertTrue(
      $this
        ->getSession()
        ->getPage()
        ->waitFor(1, function () use ($element, $expected): bool {
          // Get boolean representation of `aria-pressed`.
          // TRUE if `aria-pressed="true"`, FALSE otherwise.
          $actual = $element->getAttribute('aria-pressed') == 'true';

          // Exit `waitFor()` when $actual == $expected.
          return $actual == $expected;
        })
    );
  }

}