3 namespace Drupal\Tests\settings_tray\FunctionalJavascript;
5 use Drupal\settings_tray_test\Plugin\Block\SettingsTrayFormAnnotationIsClassBlock;
6 use Drupal\settings_tray_test\Plugin\Block\SettingsTrayFormAnnotationNoneBlock;
7 use Drupal\user\Entity\Role;
10 * Testing opening and saving block forms in the off-canvas dialog.
12 * @group settings_tray
14 class SettingsTrayBlockFormTest extends SettingsTrayTestBase {
19 public static $modules = [
28 protected function setUp() {
31 $user = $this->createUser([
33 'access contextual links',
38 $this->drupalLogin($user);
42 * Tests opening off-canvas dialog by click blocks and elements in the blocks.
44 public function testBlocks() {
45 foreach ($this->getBlockTests() as $test) {
46 call_user_func_array([$this, 'doTestBlocks'], $test);
51 * Tests opening off-canvas dialog by click blocks and elements in the blocks.
53 protected function doTestBlocks($theme, $block_plugin, $new_page_text, $element_selector, $label_selector, $button_text, $toolbar_item, $permissions) {
55 $this->grantPermissions(Role::load(Role::AUTHENTICATED_ID), $permissions);
58 // Some asserts can be based on this value, so it should not be the same
59 // for different blocks, because it can be saved in the site config.
60 $new_page_text = $new_page_text . ' ' . $theme . ' ' . $block_plugin;
62 $web_assert = $this->assertSession();
63 $page = $this->getSession()->getPage();
64 $this->enableTheme($theme);
65 $block = $this->placeBlock($block_plugin);
66 $block_selector = $this->getBlockSelector($block);
67 $block_id = $block->id();
68 $this->drupalGet('user');
70 $link = $web_assert->waitForElement('css', "$block_selector .contextual-links li a");
71 $this->assertEquals('Quick edit', $link->getHtml(), "'Quick edit' is the first contextual link for the block.");
72 $destination = (string) $this->loggedInUser->toUrl()->toString();
73 $this->assertContains("/admin/structure/block/manage/$block_id/settings-tray?destination=$destination", $link->getAttribute('href'));
75 if (isset($toolbar_item)) {
76 // Check that you can open a toolbar tray and it will be closed after
77 // entering edit mode.
78 if ($element = $page->find('css', "#toolbar-administration a.is-active")) {
79 // If a tray was open from page load close it.
81 $this->waitForNoElement("#toolbar-administration a.is-active");
83 $page->find('css', $toolbar_item)->click();
84 $this->assertElementVisibleAfterWait('css', "{$toolbar_item}.is-active");
86 $this->enableEditMode();
87 if (isset($toolbar_item)) {
88 $this->waitForNoElement("{$toolbar_item}.is-active");
90 $this->openBlockForm($block_selector);
91 switch ($block_plugin) {
92 case 'system_powered_by_block':
93 // Confirm "Display Title" is not checked.
94 $web_assert->checkboxNotChecked('settings[label_display]');
95 // Confirm Title is not visible.
96 $this->assertEquals($this->isLabelInputVisible(), FALSE, 'Label is not visible');
97 $page->checkField('settings[label_display]');
98 $this->assertEquals($this->isLabelInputVisible(), TRUE, 'Label is visible');
99 // Fill out form, save the form.
100 $page->fillField('settings[label]', $new_page_text);
104 case 'system_branding_block':
105 // Fill out form, save the form.
106 $page->fillField('settings[site_information][site_name]', $new_page_text);
109 case 'settings_tray_test_class':
110 $web_assert->elementExists('css', '[data-drupal-selector="edit-settings-some-setting"]');
114 if (isset($new_page_text)) {
115 $page->pressButton($button_text);
116 // Make sure the changes are present.
117 $new_page_text_locator = "$block_selector $label_selector:contains($new_page_text)";
118 $this->assertElementVisibleAfterWait('css', $new_page_text_locator);
119 // The page is loaded with the new change but make sure page is
120 // completely loaded.
121 $this->assertPageLoadComplete();
124 $this->openBlockForm($block_selector);
126 $this->disableEditMode();
127 // Canvas should close when editing module is closed.
128 $this->waitForOffCanvasToClose();
130 $this->enableEditMode();
132 // Open block form by clicking a element inside the block.
133 // This confirms that default action for links and form elements is
135 $this->openBlockForm("$block_selector {$element_selector}", $block_selector);
136 $web_assert->elementTextContains('css', '.contextual-toolbar-tab button', 'Editing');
137 $web_assert->elementAttributeContains('css', '.dialog-off-canvas-main-canvas', 'class', 'js-settings-tray-edit-mode');
138 // Simulate press the Escape key.
139 $this->getSession()->executeScript('jQuery("body").trigger(jQuery.Event("keyup", { keyCode: 27 }));');
140 $this->waitForOffCanvasToClose();
141 $this->getSession()->wait(100);
142 $this->getSession()->executeScript("jQuery('[data-quickedit-entity-id]').trigger('mouseleave')");
143 $this->getSession()->getPage()->find('css', static::TOOLBAR_EDIT_LINK_SELECTOR)->mouseOver();
144 $this->assertEditModeDisabled();
145 $this->assertNotEmpty($web_assert->waitForElement('css', '#drupal-live-announce:contains(Exited edit mode)'));
146 $this->waitForNoElement('.contextual-toolbar-tab button:contains(Editing)');
147 $web_assert->elementAttributeNotContains('css', '.dialog-off-canvas-main-canvas', 'class', 'js-settings-tray-edit-mode');
149 // Clean up test data so each test does not impact the next.
152 user_role_revoke_permissions(Role::AUTHENTICATED_ID, $permissions);
157 * Creates tests for ::testBlocks().
159 public function getBlockTests() {
161 foreach ($this->getTestThemes() as $theme) {
163 "$theme: block-powered" => [
165 'block_plugin' => 'system_powered_by_block',
166 'new_page_text' => 'Can you imagine anyone showing the label on this block',
167 'element_selector' => 'span a',
168 'label_selector' => 'h2',
169 'button_text' => 'Save Powered by Drupal',
170 'toolbar_item' => '#toolbar-item-user',
173 "$theme: block-branding" => [
175 'block_plugin' => 'system_branding_block',
176 'new_page_text' => 'The site that will live a very short life',
177 'element_selector' => "a[rel='home']:last-child",
178 'label_selector' => "a[rel='home']:last-child",
179 'button_text' => 'Save Site branding',
180 'toolbar_item' => '#toolbar-item-administration',
181 ['administer site configuration'],
183 "$theme: block-search" => [
185 'block_plugin' => 'search_form_block',
186 'new_page_text' => NULL,
187 'element_selector' => '#edit-submit',
188 'label_selector' => 'h2',
189 'button_text' => 'Save Search form',
190 'toolbar_item' => NULL,
193 // This is the functional JS test coverage accompanying
194 // \Drupal\Tests\settings_tray\Functional\SettingsTrayTest::testPossibleAnnotations().
195 "$theme: " . SettingsTrayFormAnnotationIsClassBlock::class => [
197 'block_plugin' => 'settings_tray_test_class',
198 'new_page_text' => NULL,
199 'element_selector' => 'span',
200 'label_selector' => NULL,
201 'button_text' => NULL,
202 'toolbar_item' => NULL,
205 // This is the functional JS test coverage accompanying
206 // \Drupal\Tests\settings_tray\Functional\SettingsTrayTest::testPossibleAnnotations().
207 "$theme: " . SettingsTrayFormAnnotationNoneBlock::class => [
209 'block_plugin' => 'settings_tray_test_none',
210 'new_page_text' => NULL,
211 'element_selector' => 'span',
212 'label_selector' => NULL,
213 'button_text' => NULL,
214 'toolbar_item' => NULL,
224 * Tests enabling and disabling Edit Mode.
226 public function testEditModeEnableDisable() {
227 foreach ($this->getTestThemes() as $theme) {
228 $this->enableTheme($theme);
229 $block = $this->placeBlock('system_powered_by_block');
230 foreach (['contextual_link', 'toolbar_link'] as $enable_option) {
231 $this->drupalGet('user');
232 $this->assertEditModeDisabled();
233 switch ($enable_option) {
235 case 'contextual_link':
236 $this->clickContextualLink($this->getBlockSelector($block), "Quick edit");
237 $this->waitForOffCanvasToOpen();
238 $this->assertEditModeEnabled();
242 $this->enableEditMode();
245 $this->disableEditMode();
247 // Make another page request to ensure Edit mode is still disabled.
248 $this->drupalGet('user');
249 $this->assertEditModeDisabled();
250 // Make sure on this page request it also re-enables and disables
252 $this->enableEditMode();
253 $this->disableEditMode();
259 * Test that validation errors appear in the off-canvas dialog.
261 public function testValidationMessages() {
262 $page = $this->getSession()->getPage();
263 $web_assert = $this->assertSession();
264 foreach ($this->getTestThemes() as $theme) {
265 $this->enableTheme($theme);
266 $block = $this->placeBlock('settings_tray_test_validation');
267 $this->drupalGet('user');
268 $this->enableEditMode();
269 $this->openBlockForm($this->getBlockSelector($block));
270 $page->pressButton('Save Block with validation error');
271 $web_assert->assertWaitOnAjaxRequest();
272 // The settings_tray_test_validation test plugin form always has a
274 $web_assert->elementContains('css', '#drupal-off-canvas', 'Sorry system error. Please save again');
275 $this->disableEditMode();
283 protected function getTestThemes() {
284 // Remove 'seven' theme. Setting Tray "Edit Mode" will not work with 'seven'
285 // because it removes all contextual links the off-canvas dialog should.
286 return array_filter(parent::getTestThemes(), function ($theme) {
287 return $theme !== 'seven';