Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\FunctionalJavascriptTests\Ajax;
|
Chris@0
|
4
|
Chris@17
|
5 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
Chris@0
|
6
|
Chris@0
|
7 /**
|
Chris@0
|
8 * Tests AJAX responses.
|
Chris@0
|
9 *
|
Chris@0
|
10 * @group Ajax
|
Chris@0
|
11 */
|
Chris@17
|
12 class AjaxTest extends WebDriverTestBase {
|
Chris@0
|
13
|
Chris@0
|
14 /**
|
Chris@0
|
15 * {@inheritdoc}
|
Chris@0
|
16 */
|
Chris@0
|
17 public static $modules = ['ajax_test'];
|
Chris@0
|
18
|
Chris@0
|
19 public function testAjaxWithAdminRoute() {
|
Chris@0
|
20 \Drupal::service('theme_installer')->install(['stable', 'seven']);
|
Chris@0
|
21 $theme_config = \Drupal::configFactory()->getEditable('system.theme');
|
Chris@0
|
22 $theme_config->set('admin', 'seven');
|
Chris@0
|
23 $theme_config->set('default', 'stable');
|
Chris@0
|
24 $theme_config->save();
|
Chris@0
|
25
|
Chris@0
|
26 $account = $this->drupalCreateUser(['view the administration theme']);
|
Chris@0
|
27 $this->drupalLogin($account);
|
Chris@0
|
28
|
Chris@0
|
29 // First visit the site directly via the URL. This should render it in the
|
Chris@0
|
30 // admin theme.
|
Chris@0
|
31 $this->drupalGet('admin/ajax-test/theme');
|
Chris@0
|
32 $assert = $this->assertSession();
|
Chris@0
|
33 $assert->pageTextContains('Current theme: seven');
|
Chris@0
|
34
|
Chris@0
|
35 // Now click the modal, which should also use the admin theme.
|
Chris@0
|
36 $this->drupalGet('ajax-test/dialog');
|
Chris@0
|
37 $assert->pageTextNotContains('Current theme: stable');
|
Chris@0
|
38 $this->clickLink('Link 8 (ajax)');
|
Chris@0
|
39 $assert->assertWaitOnAjaxRequest();
|
Chris@0
|
40
|
Chris@0
|
41 $assert->pageTextContains('Current theme: stable');
|
Chris@0
|
42 $assert->pageTextNotContains('Current theme: seven');
|
Chris@0
|
43 }
|
Chris@0
|
44
|
Chris@0
|
45 /**
|
Chris@0
|
46 * Test that AJAX loaded libraries are not retained between requests.
|
Chris@0
|
47 *
|
Chris@0
|
48 * @see https://www.drupal.org/node/2647916
|
Chris@0
|
49 */
|
Chris@0
|
50 public function testDrupalSettingsCachingRegression() {
|
Chris@0
|
51 $this->drupalGet('ajax-test/dialog');
|
Chris@0
|
52 $assert = $this->assertSession();
|
Chris@0
|
53 $session = $this->getSession();
|
Chris@0
|
54
|
Chris@0
|
55 // Insert a fake library into the already loaded library settings.
|
Chris@0
|
56 $fake_library = 'fakeLibrary/fakeLibrary';
|
Chris@0
|
57 $session->evaluateScript("drupalSettings.ajaxPageState.libraries = drupalSettings.ajaxPageState.libraries + ',$fake_library';");
|
Chris@0
|
58
|
Chris@0
|
59 $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
|
Chris@0
|
60 // Test that the fake library is set.
|
Chris@0
|
61 $this->assertContains($fake_library, $libraries);
|
Chris@0
|
62
|
Chris@0
|
63 // Click on the AJAX link.
|
Chris@0
|
64 $this->clickLink('Link 8 (ajax)');
|
Chris@0
|
65 $assert->assertWaitOnAjaxRequest();
|
Chris@0
|
66
|
Chris@0
|
67 // Test that the fake library is still set after the AJAX call.
|
Chris@0
|
68 $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
|
Chris@0
|
69 $this->assertContains($fake_library, $libraries);
|
Chris@0
|
70
|
Chris@0
|
71 // Reload the page, this should reset the loaded libraries and remove the
|
Chris@0
|
72 // fake library.
|
Chris@0
|
73 $this->drupalGet('ajax-test/dialog');
|
Chris@0
|
74 $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
|
Chris@0
|
75 $this->assertNotContains($fake_library, $libraries);
|
Chris@0
|
76
|
Chris@0
|
77 // Click on the AJAX link again, and the libraries should still not contain
|
Chris@0
|
78 // the fake library.
|
Chris@0
|
79 $this->clickLink('Link 8 (ajax)');
|
Chris@0
|
80 $assert->assertWaitOnAjaxRequest();
|
Chris@0
|
81 $libraries = $session->evaluateScript('drupalSettings.ajaxPageState.libraries');
|
Chris@0
|
82 $this->assertNotContains($fake_library, $libraries);
|
Chris@0
|
83 }
|
Chris@0
|
84
|
Chris@17
|
85 /**
|
Chris@17
|
86 * Tests that various AJAX responses with DOM elements are correctly inserted.
|
Chris@17
|
87 *
|
Chris@17
|
88 * After inserting DOM elements, Drupal JavaScript behaviors should be
|
Chris@17
|
89 * reattached and all top-level elements of type Node.ELEMENT_NODE need to be
|
Chris@17
|
90 * part of the context.
|
Chris@17
|
91 */
|
Chris@17
|
92 public function testInsertAjaxResponse() {
|
Chris@17
|
93 $render_single_root = [
|
Chris@17
|
94 'pre-wrapped-div' => '<div class="pre-wrapped">pre-wrapped<script> var test;</script></div>',
|
Chris@17
|
95 'pre-wrapped-span' => '<span class="pre-wrapped">pre-wrapped<script> var test;</script></span>',
|
Chris@17
|
96 'pre-wrapped-whitespace' => ' <div class="pre-wrapped-whitespace">pre-wrapped-whitespace</div>' . "\n",
|
Chris@17
|
97 'not-wrapped' => 'not-wrapped',
|
Chris@17
|
98 'comment-string-not-wrapped' => '<!-- COMMENT -->comment-string-not-wrapped',
|
Chris@17
|
99 'comment-not-wrapped' => '<!-- COMMENT --><div class="comment-not-wrapped">comment-not-wrapped</div>',
|
Chris@17
|
100 'svg' => '<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><rect x="0" y="0" height="10" width="10" fill="green"/></svg>',
|
Chris@17
|
101 'empty' => '',
|
Chris@17
|
102 ];
|
Chris@17
|
103 $render_multiple_root_unwrapper = [
|
Chris@17
|
104 'mixed' => ' foo <!-- COMMENT --> foo bar<div class="a class"><p>some string</p></div> additional not wrapped strings, <!-- ANOTHER COMMENT --> <p>final string</p>',
|
Chris@17
|
105 'top-level-only' => '<div>element #1</div><div>element #2</div>',
|
Chris@17
|
106 'top-level-only-pre-whitespace' => ' <div>element #1</div><div>element #2</div> ',
|
Chris@17
|
107 'top-level-only-middle-whitespace-span' => '<span>element #1</span> <span>element #2</span>',
|
Chris@17
|
108 'top-level-only-middle-whitespace-div' => '<div>element #1</div> <div>element #2</div>',
|
Chris@17
|
109 ];
|
Chris@17
|
110
|
Chris@17
|
111 // This is temporary behavior for BC reason.
|
Chris@17
|
112 $render_multiple_root_wrapper = [];
|
Chris@17
|
113 foreach ($render_multiple_root_unwrapper as $key => $render) {
|
Chris@17
|
114 $render_multiple_root_wrapper["$key--effect"] = '<div>' . $render . '</div>';
|
Chris@17
|
115 }
|
Chris@17
|
116
|
Chris@17
|
117 $expected_renders = array_merge(
|
Chris@17
|
118 $render_single_root,
|
Chris@17
|
119 $render_multiple_root_wrapper,
|
Chris@17
|
120 $render_multiple_root_unwrapper
|
Chris@17
|
121 );
|
Chris@17
|
122
|
Chris@17
|
123 // Checking default process of wrapping Ajax content.
|
Chris@17
|
124 foreach ($expected_renders as $render_type => $expected) {
|
Chris@17
|
125 $this->assertInsert($render_type, $expected);
|
Chris@17
|
126 }
|
Chris@17
|
127
|
Chris@17
|
128 // Checking custom ajaxWrapperMultipleRootElements wrapping.
|
Chris@17
|
129 $custom_wrapper_multiple_root = <<<JS
|
Chris@17
|
130 (function($, Drupal){
|
Chris@17
|
131 Drupal.theme.ajaxWrapperMultipleRootElements = function (elements) {
|
Chris@17
|
132 return $('<div class="my-favorite-div"></div>').append(elements);
|
Chris@17
|
133 };
|
Chris@17
|
134 }(jQuery, Drupal));
|
Chris@17
|
135 JS;
|
Chris@17
|
136 $expected = '<div class="my-favorite-div"><span>element #1</span> <span>element #2</span></div>';
|
Chris@17
|
137 $this->assertInsert('top-level-only-middle-whitespace-span--effect', $expected, $custom_wrapper_multiple_root);
|
Chris@17
|
138
|
Chris@17
|
139 // Checking custom ajaxWrapperNewContent wrapping.
|
Chris@17
|
140 $custom_wrapper_new_content = <<<JS
|
Chris@17
|
141 (function($, Drupal){
|
Chris@17
|
142 Drupal.theme.ajaxWrapperNewContent = function (elements) {
|
Chris@17
|
143 return $('<div class="div-wrapper-forever"></div>').append(elements);
|
Chris@17
|
144 };
|
Chris@17
|
145 }(jQuery, Drupal));
|
Chris@17
|
146 JS;
|
Chris@17
|
147 $expected = '<div class="div-wrapper-forever"></div>';
|
Chris@17
|
148 $this->assertInsert('empty', $expected, $custom_wrapper_new_content);
|
Chris@17
|
149 }
|
Chris@17
|
150
|
Chris@17
|
151 /**
|
Chris@17
|
152 * Assert insert.
|
Chris@17
|
153 *
|
Chris@17
|
154 * @param string $render_type
|
Chris@17
|
155 * Render type.
|
Chris@17
|
156 * @param string $expected
|
Chris@17
|
157 * Expected result.
|
Chris@17
|
158 * @param string $script
|
Chris@17
|
159 * Script for additional theming.
|
Chris@17
|
160 */
|
Chris@17
|
161 public function assertInsert($render_type, $expected, $script = '') {
|
Chris@17
|
162 // Check insert to block element.
|
Chris@17
|
163 $this->drupalGet('ajax-test/insert-block-wrapper');
|
Chris@17
|
164 $this->getSession()->executeScript($script);
|
Chris@17
|
165 $this->clickLink("Link html $render_type");
|
Chris@17
|
166 $this->assertWaitPageContains('<div class="ajax-target-wrapper"><div id="ajax-target">' . $expected . '</div></div>');
|
Chris@17
|
167
|
Chris@17
|
168 $this->drupalGet('ajax-test/insert-block-wrapper');
|
Chris@17
|
169 $this->getSession()->executeScript($script);
|
Chris@17
|
170 $this->clickLink("Link replaceWith $render_type");
|
Chris@17
|
171 $this->assertWaitPageContains('<div class="ajax-target-wrapper">' . $expected . '</div>');
|
Chris@17
|
172
|
Chris@17
|
173 // Check insert to inline element.
|
Chris@17
|
174 $this->drupalGet('ajax-test/insert-inline-wrapper');
|
Chris@17
|
175 $this->getSession()->executeScript($script);
|
Chris@17
|
176 $this->clickLink("Link html $render_type");
|
Chris@17
|
177 $this->assertWaitPageContains('<div class="ajax-target-wrapper"><span id="ajax-target-inline">' . $expected . '</span></div>');
|
Chris@17
|
178
|
Chris@17
|
179 $this->drupalGet('ajax-test/insert-inline-wrapper');
|
Chris@17
|
180 $this->getSession()->executeScript($script);
|
Chris@17
|
181 $this->clickLink("Link replaceWith $render_type");
|
Chris@17
|
182 $this->assertWaitPageContains('<div class="ajax-target-wrapper">' . $expected . '</div>');
|
Chris@17
|
183 }
|
Chris@17
|
184
|
Chris@17
|
185 /**
|
Chris@17
|
186 * Asserts that page contains an expected value after waiting.
|
Chris@17
|
187 *
|
Chris@17
|
188 * @param string $expected
|
Chris@17
|
189 * A needle text.
|
Chris@17
|
190 */
|
Chris@17
|
191 protected function assertWaitPageContains($expected) {
|
Chris@17
|
192 $page = $this->getSession()->getPage();
|
Chris@17
|
193 $this->assertTrue($page->waitFor(10, function () use ($page, $expected) {
|
Chris@17
|
194 // Clear content from empty styles and "processed" classes after effect.
|
Chris@17
|
195 $content = str_replace([' class="processed"', ' processed', ' style=""'], '', $page->getContent());
|
Chris@17
|
196 return stripos($content, $expected) !== FALSE;
|
Chris@17
|
197 }), "Page contains expected value: $expected");
|
Chris@17
|
198 }
|
Chris@17
|
199
|
Chris@0
|
200 }
|