function JSWebAssert::assertExpectedAjaxRequest

Same name and namespace in other branches
  1. 11.x core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php \Drupal\FunctionalJavascriptTests\JSWebAssert::assertExpectedAjaxRequest()

Asserts that an AJAX request has been completed.

Parameters

int|null $count: (Optional) The number of completed AJAX requests expected.

int $timeout: (Optional) Timeout in milliseconds, defaults to 10000.

string $message: (optional) A message for exception.

Throws

\RuntimeException When the request is not completed. If left blank, a default message will be displayed.

1 call to JSWebAssert::assertExpectedAjaxRequest()
JSWebAssert::assertWaitOnAjaxRequest in core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
Waits for AJAX request to be completed.

File

core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php, line 55

Class

JSWebAssert
Defines a class with methods for asserting presence of elements during tests.

Namespace

Drupal\FunctionalJavascriptTests

Code

public function assertExpectedAjaxRequest(?int $count = NULL, $timeout = 10000, $message = 'Unable to complete AJAX request.') : void {
  // Wait for a very short time to allow page state to update after clicking.
  usleep(5000);
  $condition = <<<JS
      (function() {
        function isAjaxing(instance) {
          return instance && instance.ajaxing === true;
        }
        return (
          // Assert at least one AJAX request was started and completed.
          // For example, the machine name UI component does not use the Drupal
          // AJAX system, which means the other two checks below are inadequate.
          // @see Drupal.behaviors.machineName
          window.drupalActiveXhrCount === 0 && window.drupalCumulativeXhrCount >= 1 &&
          // Assert no AJAX request is running (via jQuery or Drupal) and no
          // animation is running.
          (typeof jQuery === 'undefined' || (jQuery.active === 0 && jQuery(':animated').length === 0)) &&
          (typeof Drupal === 'undefined' || typeof Drupal.ajax === 'undefined' || !Drupal.ajax.instances.some(isAjaxing))
        );
      }())
JS;
  $completed = $this->session
    ->wait($timeout, $condition);
  // Now that there definitely is no more AJAX request in progress, count the
  // number of AJAX responses.
  // @see core/modules/system/tests/modules/js_testing_ajax_request_test/js/js_testing_ajax_request_test.js
  // @see https://developer.mozilla.org/en-US/docs/Web/API/Performance/timeOrigin
  [
    $drupal_ajax_request_count,
    $browser_xhr_request_count,
    $page_hash,
  ] = $this->session
    ->evaluateScript(<<<JS
(function(){
  return [
    window.drupalCumulativeXhrCount,
    window.performance
      .getEntries()
      .filter(entry => entry.initiatorType === 'xmlhttprequest')
      .length,
    window.performance.timeOrigin
  ];
})()
JS
);
  // First invocation of ::assertWaitOnAjaxRequest() on this page: initialize.
  static $current_page_hash;
  static $current_page_ajax_response_count;
  if ($current_page_hash !== $page_hash) {
    $current_page_hash = $page_hash;
    $current_page_ajax_response_count = 0;
  }
  // Detect unnecessary AJAX request waits and inform the test author.
  if ($drupal_ajax_request_count === $current_page_ajax_response_count) {
    @trigger_error(sprintf('%s called unnecessarily in a test is deprecated in drupal:10.2.0 and will throw an exception in drupal:11.0.0. See https://www.drupal.org/node/3401201', __METHOD__), E_USER_DEPRECATED);
  }
  // Detect untracked AJAX requests. This will alert if the detection is
  // failing to provide an accurate count of requests.
  // @see core/modules/system/tests/modules/js_testing_ajax_request_test/js/js_testing_ajax_request_test.js
  if (!is_null($count) && $drupal_ajax_request_count !== $browser_xhr_request_count) {
    throw new \RuntimeException(sprintf('%d XHR requests through jQuery, but %d observed in the browser — this requires js_testing_ajax_request_test.js to be updated.', $drupal_ajax_request_count, $browser_xhr_request_count));
  }
  // Detect incomplete AJAX request.
  if (!$completed) {
    throw new \RuntimeException($message);
  }
  // Update the static variable for the next invocation, to allow detecting
  // unnecessary invocations.
  $current_page_ajax_response_count = $drupal_ajax_request_count;
  if (!is_null($count)) {
    Assert::assertSame($count, $drupal_ajax_request_count);
  }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.