PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/web/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php

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