From eb8c8d4802e98b168a1dcb4cb74d2b83f396d520 Mon Sep 17 00:00:00 2001
From: catch <catch56@gmail.com>
Date: Fri, 14 Oct 2022 11:54:26 +0100
Subject: [PATCH] Issue #3315227 by alexpott, Spokje, andypost, quietone:
 Drupal\Tests\views\FunctionalJavascript\Plugin\views\Handler\FilterTest is
 failing a lot at the moment

---
 .../FunctionalJavascriptTests/JSWebAssert.php | 14 +--------
 core/tests/Drupal/Tests/DocumentElement.php   | 30 +++++++++++++++++++
 2 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
index 0a3c49385547..9db43998c646 100644
--- a/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
+++ b/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
@@ -12,7 +12,6 @@
 use PHPUnit\Framework\Constraint\IsNull;
 use PHPUnit\Framework\Constraint\LogicalNot;
 use WebDriver\Exception;
-use WebDriver\Exception\CurlExec;
 
 // cspell:ignore interactable
 
@@ -156,18 +155,7 @@ public function waitForText($text, $timeout = 10000) {
    *   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;
+    return $this->session->getPage()->waitFor($timeout / 1000, $callback);
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/DocumentElement.php b/core/tests/Drupal/Tests/DocumentElement.php
index d7b1617f254f..5d6def89cb56 100644
--- a/core/tests/Drupal/Tests/DocumentElement.php
+++ b/core/tests/Drupal/Tests/DocumentElement.php
@@ -7,7 +7,10 @@
 namespace Drupal\Tests;
 
 use Behat\Mink\Driver\BrowserKitDriver;
+use Behat\Mink\Element\Element;
 use Behat\Mink\Element\TraversableElement;
+use Drupal\FunctionalJavascriptTests\WebDriverCurlService;
+use WebDriver\Exception\CurlExec;
 
 /**
  * Document element.
@@ -85,4 +88,31 @@ public function getText() {
     return parent::getText();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function waitFor($timeout, $callback) {
+    // Wraps waits in a function to catch curl exceptions to continue waiting.
+    WebDriverCurlService::disableRetry();
+    $count = 0;
+    $wrapper = function (Element $element) use ($callback, &$count) {
+      $count++;
+      try {
+        return call_user_func($callback, $element);
+      }
+      catch (CurlExec $e) {
+        return NULL;
+      }
+    };
+    $result = parent::waitFor($timeout, $wrapper);
+    if (!$result && $count < 2) {
+      // If the callback or the system is really slow, then it might have only
+      // fired once. In this case it is better to trigger it once more as the
+      // page state has probably changed while the callback is running.
+      return call_user_func($callback, $this);
+    }
+    WebDriverCurlService::enableRetry();
+    return $result;
+  }
+
 }
-- 
GitLab