diff --git a/core/modules/system/tests/modules/js_ajax_test/js/js_ajax_test.ajax.es6.js b/core/modules/system/tests/modules/js_ajax_test/js/js_ajax_test.ajax.es6.js
index 116bad83f1..271b4e30b4 100644
--- a/core/modules/system/tests/modules/js_ajax_test/js/js_ajax_test.ajax.es6.js
+++ b/core/modules/system/tests/modules/js_ajax_test/js/js_ajax_test.ajax.es6.js
@@ -26,4 +26,24 @@
`
${JSON.stringify(data)}
`,
);
};
+
+ /**
+ * Test Ajax execution Order.
+ *
+ * @param {Drupal.Ajax} [ajax]
+ * {@link Drupal.Ajax} object created by {@link Drupal.Ajax}.
+ * @param {object} response
+ * The response from the Ajax request.
+ * @param {string} response.selector
+ * A jQuery selector string.
+ */
+ Drupal.AjaxCommands.prototype.jsAjaxTestInsertPromise = function(ajax, response) {
+ const exec = $.Deferred();
+ setTimeout(() => {
+ this.insert(ajax, response);
+ exec.resolve();
+ }, Math.random() * 500);
+
+ return exec.promise();
+ };
})(jQuery, Drupal);
diff --git a/core/modules/system/tests/modules/js_ajax_test/js/js_ajax_test.ajax.js b/core/modules/system/tests/modules/js_ajax_test/js/js_ajax_test.ajax.js
index 4d71a2f381..e85a19b153 100644
--- a/core/modules/system/tests/modules/js_ajax_test/js/js_ajax_test.ajax.js
+++ b/core/modules/system/tests/modules/js_ajax_test/js/js_ajax_test.ajax.js
@@ -15,4 +15,16 @@
};
$domElement.html("".concat(JSON.stringify(data), "
"));
};
+
+ Drupal.AjaxCommands.prototype.jsAjaxTestInsertPromise = function (ajax, response) {
+ var _this = this;
+
+ var exec = $.Deferred();
+ setTimeout(function () {
+ _this.insert(ajax, response);
+
+ exec.resolve();
+ }, Math.random() * 500);
+ return exec.promise();
+ };
})(jQuery, Drupal);
\ No newline at end of file
diff --git a/core/modules/system/tests/modules/js_ajax_test/src/Ajax/JsAjaxTestCommandInsertPromise.php b/core/modules/system/tests/modules/js_ajax_test/src/Ajax/JsAjaxTestCommandInsertPromise.php
new file mode 100644
index 0000000000..ce63306c24
--- /dev/null
+++ b/core/modules/system/tests/modules/js_ajax_test/src/Ajax/JsAjaxTestCommandInsertPromise.php
@@ -0,0 +1,27 @@
+ 'jsAjaxTestInsertPromise',
+ 'method' => 'append',
+ 'selector' => $this->selector,
+ 'data' => $this->getRenderedContent(),
+ 'settings' => $this->settings,
+ ];
+ }
+
+}
diff --git a/core/modules/system/tests/modules/js_ajax_test/src/Form/JsAjaxTestForm.php b/core/modules/system/tests/modules/js_ajax_test/src/Form/JsAjaxTestForm.php
index 567d4158d6..735d57fbd1 100644
--- a/core/modules/system/tests/modules/js_ajax_test/src/Form/JsAjaxTestForm.php
+++ b/core/modules/system/tests/modules/js_ajax_test/src/Form/JsAjaxTestForm.php
@@ -3,9 +3,11 @@
namespace Drupal\js_ajax_test\Form;
use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\AppendCommand;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\js_ajax_test\Ajax\JsAjaxTestCommand;
+use Drupal\js_ajax_test\Ajax\JsAjaxTestCommandInsertPromise;
/**
* Test form for js_ajax_test
@@ -43,6 +45,21 @@ public function buildForm(array $form, FormStateInterface $form_state) {
'wrapper' => 'js_ajax_test_form_wrapper',
],
];
+
+ // Button to test for the waitForButton() assertion.
+ $form['test_execution_order_button'] = [
+ '#type' => 'submit',
+ '#value' => $this->t('Execute commands button'),
+ '#button_type' => 'primary',
+ '#ajax' => [
+ 'callback' => [static::class, 'executeCommands'],
+ 'progress' => [
+ 'type' => 'throbber',
+ 'message' => NULL,
+ ],
+ 'wrapper' => 'js_ajax_test_form_wrapper',
+ ],
+ ];
return $form;
}
@@ -54,6 +71,22 @@ public static function addButton(array $form, FormStateInterface $form_state) {
->addCommand(new JsAjaxTestCommand());
}
+ /**
+ * Ajax callback for the "Execute commands button" button.
+ */
+ public static function executeCommands(array $form, FormStateInterface $form_state) {
+ $selector = '#js_ajax_test_form_wrapper';
+ $response = new AjaxResponse();
+
+ $response->addCommand(new AppendCommand($selector, '1'));
+ $response->addCommand(new JsAjaxTestCommandInsertPromise($selector, '2'));
+ $response->addCommand(new AppendCommand($selector, '3'));
+ $response->addCommand(new AppendCommand($selector, '4'));
+ $response->addCommand(new JsAjaxTestCommandInsertPromise($selector, '5'));
+
+ return $response;
+ }
+
/**
* {@inheritdoc}
*/
diff --git a/core/tests/Drupal/Nightwatch/Tests/ajaxExecutionOrderTest.js b/core/tests/Drupal/Nightwatch/Tests/ajaxExecutionOrderTest.js
new file mode 100644
index 0000000000..3efbf3935c
--- /dev/null
+++ b/core/tests/Drupal/Nightwatch/Tests/ajaxExecutionOrderTest.js
@@ -0,0 +1,31 @@
+module.exports = {
+ '@tags': ['core', 'ajax'],
+ before(browser) {
+ browser.drupalInstall().drupalLoginAsAdmin(() => {
+ browser
+ .drupalRelativeURL('/admin/modules')
+ .setValue('input[type="search"]', 'JS Ajax test')
+ .waitForElementVisible(
+ 'input[name="modules[js_ajax_test][enable]"]',
+ 1000,
+ )
+ .click('input[name="modules[js_ajax_test][enable]"]')
+ .click('input[type="submit"]'); // Submit module form.
+ });
+ },
+ after(browser) {
+ browser.drupalUninstall();
+ },
+ 'Test Execution Order': browser => {
+ browser
+ .drupalRelativeURL('/js_ajax_test')
+ .waitForElementVisible('body', 1000)
+ .click('[data-drupal-selector="edit-test-execution-order-button"]')
+ .waitForElementVisible('body', 1000)
+ .assert.containsText(
+ '#js_ajax_test_form_wrapper',
+ '12345',
+ 'Execution order confirmed',
+ );
+ },
+};