From d6a181e20c514a7670a8726660f2d7d408333e4c Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 19 Dec 2024 11:50:55 -0800 Subject: [PATCH] fix: waitForCondition should not call predicate after it returned true --- .../playwright/impl/WaitableRace.java | 18 ++++++++++-------- .../playwright/TestBrowserContextBasic.java | 7 +++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/WaitableRace.java b/playwright/src/main/java/com/microsoft/playwright/impl/WaitableRace.java index ed3b76604..d315988d7 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/WaitableRace.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/WaitableRace.java @@ -20,6 +20,7 @@ class WaitableRace implements Waitable { private final Collection> waitables; + private Waitable firstReady; WaitableRace(Collection> waitables) { this.waitables = waitables; @@ -27,8 +28,12 @@ class WaitableRace implements Waitable { @Override public boolean isDone() { - for (Waitable w : waitables) { + if (firstReady != null) { + return true; + } + for (Waitable w : waitables) { if (w.isDone()) { + firstReady = w; return true; } } @@ -37,14 +42,11 @@ public boolean isDone() { @Override public T get() { - assert isDone(); - dispose(); - for (Waitable w : waitables) { - if (w.isDone()) { - return w.get(); - } + try { + return firstReady.get(); + } finally { + dispose(); } - throw new IllegalStateException("At least one element must be ready"); } @Override diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextBasic.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextBasic.java index d967562fb..29aa3de77 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextBasic.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextBasic.java @@ -299,6 +299,13 @@ void waitForConditionPageClosed(BrowserContext context) { assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage()); } + @Test + void waitForConditionThatMayChangeToFalse(BrowserContext context) { + int[] var = {0}; + context.waitForCondition(() -> ++var[0] == 1); + assertEquals(1, var[0], "The predicate should be called only once."); + } + @Test void shouldPropagateCloseReasonToPendingActions(Browser browser) { BrowserContext context = browser.newContext();