a61ea8a3d788e87338bc0eac7d3a9e6f007446cd
[yaffs-website] / web / core / modules / contextual / tests / src / FunctionalJavascript / EditModeTest.php
1 <?php
2
3 namespace Drupal\Tests\contextual\FunctionalJavascript;
4
5 use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
6
7 /**
8  * Tests edit mode.
9  *
10  * @group contextual
11  */
12 class EditModeTest extends JavascriptTestBase {
13
14   /**
15    * CSS selector for Drupal's announce element.
16    */
17   const ANNOUNCE_SELECTOR = '#drupal-live-announce';
18
19   /**
20    * {@inheritdoc}
21    */
22   public static $modules = [
23     'node',
24     'block',
25     'user',
26     'system',
27     'breakpoint',
28     'toolbar',
29     'contextual',
30   ];
31
32   /**
33    * {@inheritdoc}
34    */
35   protected function setUp() {
36     parent::setUp();
37
38     $this->drupalLogin($this->createUser([
39       'administer blocks',
40       'access contextual links',
41       'access toolbar',
42     ]));
43     $this->placeBlock('system_powered_by_block', ['id' => 'powered']);
44   }
45
46   /**
47    * Tests enabling and disabling edit mode.
48    */
49   public function testEditModeEnableDisalbe() {
50     $web_assert = $this->assertSession();
51     $page = $this->getSession()->getPage();
52     // Get the page twice to ensure edit mode remains enabled after a new page
53     // request.
54     for ($page_get_count = 0; $page_get_count < 2; $page_get_count++) {
55       $this->drupalGet('user');
56       $expected_restricted_tab_count = 1 + count($page->findAll('css', '[data-contextual-id]'));
57
58       // After the page loaded we need to additionally wait until the settings
59       // tray Ajax activity is done.
60       $web_assert->assertWaitOnAjaxRequest();
61
62       if ($page_get_count == 0) {
63         $unrestricted_tab_count = $this->getTabbableElementsCount();
64         $this->assertGreaterThan($expected_restricted_tab_count, $unrestricted_tab_count);
65
66         // Enable edit mode.
67         // After the first page load the page will be in edit mode when loaded.
68         $this->pressToolbarEditButton();
69       }
70
71       $this->assertAnnounceEditMode();
72       $this->assertSame($expected_restricted_tab_count, $this->getTabbableElementsCount());
73
74       // Disable edit mode.
75       $this->pressToolbarEditButton();
76       $this->assertAnnounceLeaveEditMode();
77       $this->assertSame($unrestricted_tab_count, $this->getTabbableElementsCount());
78       // Enable edit mode again.
79       $this->pressToolbarEditButton();
80       // Finally assert that the 'edit mode enabled' announcement is still
81       // correct after toggling the edit mode at least once.
82       $this->assertAnnounceEditMode();
83       $this->assertSame($expected_restricted_tab_count, $this->getTabbableElementsCount());
84     }
85
86   }
87
88   /**
89    * Presses the toolbar edit mode.
90    */
91   protected function pressToolbarEditButton() {
92     $edit_button = $this->getSession()->getPage()->find('css', '#toolbar-bar div.contextual-toolbar-tab button');
93     $edit_button->press();
94   }
95
96   /**
97    * Asserts that the correct message was announced when entering edit mode.
98    */
99   protected function assertAnnounceEditMode() {
100     $web_assert = $this->assertSession();
101     // Wait for contextual trigger button.
102     $web_assert->waitForElementVisible('css', '.contextual trigger');
103     $web_assert->elementContains('css', static::ANNOUNCE_SELECTOR, 'Tabbing is constrained to a set of');
104     $web_assert->elementNotContains('css', static::ANNOUNCE_SELECTOR, 'Tabbing is no longer constrained by the Contextual module.');
105   }
106
107   /**
108    * Assert that the correct message was announced when leaving edit mode.
109    */
110   protected function assertAnnounceLeaveEditMode() {
111     $web_assert = $this->assertSession();
112     $page = $this->getSession()->getPage();
113     // Wait till all the contextual links are hidden.
114     $page->waitFor(1, function () use ($page, $web_assert) {
115       return empty($page->find('css', '.contextual .trigger.visually-hidden'));
116     });
117     $web_assert->elementContains('css', static::ANNOUNCE_SELECTOR, 'Tabbing is no longer constrained by the Contextual module.');
118     $web_assert->elementNotContains('css', static::ANNOUNCE_SELECTOR, 'Tabbing is constrained to a set of');
119   }
120
121   /**
122    * Gets the number of elements that are tabbable.
123    *
124    * @return int
125    *   The number of tabbable elements.
126    */
127   protected function getTabbableElementsCount() {
128     // Mark all tabbable elements.
129     $this->getSession()->executeScript("jQuery(':tabbable').attr('data-marked', '');");
130     // Count all marked elements.
131     $count = count($this->getSession()->getPage()->findAll('css', "[data-marked]"));
132     // Remove set attributes.
133     $this->getSession()->executeScript("jQuery('[data-marked]').removeAttr('data-marked');");
134     return $count;
135   }
136
137 }