|
27 | 27 | import java.time.Clock;
|
28 | 28 | import java.time.Duration;
|
29 | 29 | import java.time.Instant;
|
| 30 | +import java.time.temporal.ChronoUnit; |
30 | 31 | import java.util.ArrayList;
|
31 | 32 | import java.util.Collection;
|
32 | 33 | import java.util.List;
|
33 |
| -import java.util.concurrent.CompletableFuture; |
34 |
| -import java.util.concurrent.ExecutionException; |
35 | 34 | import java.util.concurrent.TimeUnit;
|
36 | 35 | import java.util.function.Function;
|
37 | 36 | import java.util.function.Supplier;
|
@@ -203,71 +202,44 @@ public FluentWait<T> ignoring(Class<? extends Throwable> firstType,
|
203 | 202 | */
|
204 | 203 | @Override
|
205 | 204 | public <V> V until(Function<? super T, V> isTrue) {
|
206 |
| - try { |
207 |
| - return CompletableFuture.supplyAsync(checkConditionInLoop(isTrue)) |
208 |
| - .get(deriveSafeTimeout(), TimeUnit.MILLISECONDS); |
209 |
| - } catch (ExecutionException cause) { |
210 |
| - if (cause.getCause() instanceof RuntimeException) { |
211 |
| - throw (RuntimeException) cause.getCause().fillInStackTrace(); |
212 |
| - } else if (cause.getCause() instanceof Error) { |
213 |
| - throw (Error) cause.getCause(); |
214 |
| - } |
215 |
| - |
216 |
| - throw new RuntimeException(cause); |
217 |
| - } catch (InterruptedException cause) { |
218 |
| - Thread.currentThread().interrupt(); |
219 |
| - throw new RuntimeException(cause); |
220 |
| - } catch (java.util.concurrent.TimeoutException cause) { |
221 |
| - throw new TimeoutException("Supplied function might have stalled", cause); |
222 |
| - } |
223 |
| - } |
224 |
| - |
225 |
| - private <V> Supplier<V> checkConditionInLoop(Function<? super T, V> isTrue) { |
226 |
| - return () -> { |
227 |
| - Instant end = clock.instant().plus(timeout); |
228 |
| - |
229 |
| - Throwable lastException; |
230 |
| - while (true) { |
231 |
| - //noinspection ProhibitedExceptionCaught |
232 |
| - try { |
233 |
| - V value = isTrue.apply(input); |
234 |
| - if (value != null && (Boolean.class != value.getClass() || Boolean.TRUE.equals(value))) { |
235 |
| - return value; |
236 |
| - } |
| 205 | + Instant end = clock.instant().plus(timeout); |
237 | 206 |
|
238 |
| - // Clear the last exception; if another retry or timeout exception would |
239 |
| - // be caused by a false or null value, the last exception is not the |
240 |
| - // cause of the timeout. |
241 |
| - lastException = null; |
242 |
| - } catch (Throwable e) { |
243 |
| - lastException = propagateIfNotIgnored(e); |
| 207 | + Throwable lastException; |
| 208 | + while (true) { |
| 209 | + try { |
| 210 | + V value = isTrue.apply(input); |
| 211 | + if (value != null && (Boolean.class != value.getClass() || Boolean.TRUE.equals(value))) { |
| 212 | + return value; |
244 | 213 | }
|
245 | 214 |
|
246 |
| - // Check the timeout after evaluating the function to ensure conditions |
247 |
| - // with a zero timeout can succeed. |
248 |
| - if (end.isBefore(clock.instant())) { |
249 |
| - String message = messageSupplier != null ? messageSupplier.get() : null; |
| 215 | + // Clear the last exception; if another retry or timeout exception would |
| 216 | + // be caused by a false or null value, the last exception is not the |
| 217 | + // cause of the timeout. |
| 218 | + lastException = null; |
| 219 | + } catch (Throwable e) { |
| 220 | + lastException = propagateIfNotIgnored(e); |
| 221 | + } |
250 | 222 |
|
251 |
| - String timeoutMessage = String.format( |
252 |
| - "Expected condition failed: %s (tried for %d second(s) with %d milliseconds interval)", |
253 |
| - message == null ? "waiting for " + isTrue : message, |
254 |
| - timeout.getSeconds(), interval.toMillis()); |
255 |
| - throw timeoutException(timeoutMessage, lastException); |
256 |
| - } |
| 223 | + // Check the timeout after evaluating the function to ensure conditions |
| 224 | + // with a zero timeout can succeed. |
| 225 | + if (end.isBefore(clock.instant())) { |
| 226 | + String message = messageSupplier != null ? |
| 227 | + messageSupplier.get() : null; |
257 | 228 |
|
258 |
| - try { |
259 |
| - sleeper.sleep(interval); |
260 |
| - } catch (InterruptedException e) { |
261 |
| - Thread.currentThread().interrupt(); |
262 |
| - throw new WebDriverException(e); |
263 |
| - } |
| 229 | + String timeoutMessage = String.format( |
| 230 | + "Expected condition failed: %s (tried for %d second(s) with %d milliseconds interval)", |
| 231 | + message == null ? "waiting for " + isTrue : message, |
| 232 | + timeout.getSeconds(), interval.toMillis()); |
| 233 | + throw timeoutException(timeoutMessage, lastException); |
264 | 234 | }
|
265 |
| - }; |
266 |
| - } |
267 | 235 |
|
268 |
| - /** This timeout is somewhat arbitrary. */ |
269 |
| - private long deriveSafeTimeout() { |
270 |
| - return this.timeout.toMillis() + this.interval.toMillis(); |
| 236 | + try { |
| 237 | + sleeper.sleep(interval); |
| 238 | + } catch (InterruptedException e) { |
| 239 | + Thread.currentThread().interrupt(); |
| 240 | + throw new WebDriverException(e); |
| 241 | + } |
| 242 | + } |
271 | 243 | }
|
272 | 244 |
|
273 | 245 | private Throwable propagateIfNotIgnored(Throwable e) {
|
|
0 commit comments