diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php index d185cc649ad..204f0c586e7 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php @@ -2,11 +2,13 @@ namespace Drupal\FunctionalJavascriptTests; +use Behat\Mink\Element\Element; use Behat\Mink\Element\NodeElement; use Behat\Mink\Exception\ElementHtmlException; use Behat\Mink\Exception\ElementNotFoundException; use Behat\Mink\Exception\UnsupportedDriverActionException; use Drupal\Tests\WebAssert; +use WebDriver\Exception\CurlExec; /** * Defines a class with methods for asserting presence of elements during tests. @@ -64,13 +66,9 @@ function isAjaxing(instance) { * @see \Behat\Mink\Element\ElementInterface::findAll() */ public function waitForElement($selector, $locator, $timeout = 10000) { - $page = $this->session->getPage(); - - $result = $page->waitFor($timeout / 1000, function () use ($page, $selector, $locator) { + return $this->waitForHelper($timeout, function (Element $page) use ($selector, $locator) { return $page->find($selector, $locator); }); - - return $result; } /** @@ -90,13 +88,9 @@ public function waitForElement($selector, $locator, $timeout = 10000) { * @see \Behat\Mink\Element\ElementInterface::findAll() */ public function waitForElementRemoved($selector, $locator, $timeout = 10000) { - $page = $this->session->getPage(); - - $result = $page->waitFor($timeout / 1000, function () use ($page, $selector, $locator) { + return (bool) $this->waitForHelper($timeout, function (Element $page) use ($selector, $locator) { return !$page->find($selector, $locator); }); - - return $result; } /** @@ -116,17 +110,13 @@ public function waitForElementRemoved($selector, $locator, $timeout = 10000) { * @see \Behat\Mink\Element\ElementInterface::findAll() */ public function waitForElementVisible($selector, $locator, $timeout = 10000) { - $page = $this->session->getPage(); - - $result = $page->waitFor($timeout / 1000, function () use ($page, $selector, $locator) { + return $this->waitForHelper($timeout, function (Element $page) use ($selector, $locator) { $element = $page->find($selector, $locator); if (!empty($element) && $element->isVisible()) { return $element; } return NULL; }); - - return $result; } /** @@ -137,18 +127,43 @@ public function waitForElementVisible($selector, $locator, $timeout = 10000) { * @param int $timeout * (Optional) Timeout in milliseconds, defaults to 10000. * - * @return \Behat\Mink\Element\NodeElement|null - * The page element node if found and visible, NULL if not. + * @return bool + * TRUE if not found, FALSE if found. */ public function waitForText($text, $timeout = 10000) { - $page = $this->session->getPage(); - return $page->waitFor($timeout / 1000, function () use ($page, $text) { + return (bool) $this->waitForHelper($timeout, function (Element $page) use ($text) { $actual = preg_replace('/\s+/u', ' ', $page->getText()); $regex = '/' . preg_quote($text, '/') . '/ui'; return (bool) preg_match($regex, $actual); }); } + /** + * Wraps waits in a function to catch curl exceptions to continue waiting. + * + * @param int $timeout + * Timeout in milliseconds. + * @param callable $callback + * Callback, which result is both used as waiting condition and returned. + * + * @return mixed + * The result of $callback. + */ + private function waitForHelper(int $timeout, callable $callback) { + WebDriverCurlService::disableRetry(); + $wrapper = function (Element $element) use ($callback) { + try { + return call_user_func($callback, $element); + } + catch (CurlExec $e) { + return NULL; + } + }; + $result = $this->session->getPage()->waitFor($timeout / 1000, $wrapper); + WebDriverCurlService::enableRetry(); + return $result; + } + /** * Waits for a button (input[type=submit|image|button|reset], button) with * specified locator and returns it. diff --git a/core/tests/Drupal/FunctionalJavascriptTests/WebDriverCurlService.php b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverCurlService.php index a5df8c61081..d467954f611 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/WebDriverCurlService.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/WebDriverCurlService.php @@ -14,6 +14,31 @@ */ class WebDriverCurlService extends CurlService { + /** + * Flag that indicates if retries are are enabled. + * + * @var bool + */ + private static $retry = TRUE; + + /** + * Enables retries. + * + * This is useful if the caller is implementing it's own waiting process. + */ + public static function enableRetry() { + static::$retry = TRUE; + } + + /** + * Disables retries. + * + * This is useful if the caller is implementing it's own waiting process. + */ + public static function disableRetry() { + static::$retry = TRUE; + } + /** * {@inheritdoc} */ @@ -22,7 +47,7 @@ public function execute($requestMethod, $url, $parameters = NULL, $extraOptions CURLOPT_FAILONERROR => TRUE, ]; $retries = 0; - while ($retries < 10) { + while ($retries < (static::$retry ? 10 : 1)) { try { $customHeaders = [ 'Content-Type: application/json;charset=UTF-8',