0
# Waiting and Expected Conditions
1
2
The waiting utilities provide robust mechanisms for handling dynamic web content with configurable timeouts, polling intervals, and a comprehensive set of predefined conditions. These tools are essential for reliable test automation in modern web applications with asynchronous behavior.
3
4
## Core Wait Interfaces
5
6
### Wait Interface
7
8
```java { .api }
9
public interface Wait<F> {
10
/**
11
* Wait until the function returns a truthy value or timeout occurs
12
* @param isTrue Function to evaluate repeatedly until it returns truthy value
13
* @return The return value of the function when truthy
14
* @throws TimeoutException if timeout occurs before condition is met
15
*/
16
<T> T until(Function<? super F, T> isTrue);
17
}
18
```
19
20
### ExpectedCondition Interface
21
22
```java { .api }
23
public interface ExpectedCondition<T> extends Function<WebDriver, T> {
24
// Marker interface that extends Function<WebDriver, T>
25
// Used with Wait.until() to wait for specific conditions
26
}
27
```
28
29
## WebDriverWait
30
31
```java { .api }
32
public class WebDriverWait extends FluentWait<WebDriver> {
33
/**
34
* Create WebDriverWait with timeout in seconds
35
* @param driver WebDriver instance
36
* @param timeOutInSeconds Maximum time to wait
37
*/
38
public WebDriverWait(WebDriver driver, long timeOutInSeconds);
39
40
/**
41
* Create WebDriverWait with timeout and polling interval
42
* @param driver WebDriver instance
43
* @param timeOutInSeconds Maximum time to wait
44
* @param sleepInMillis Polling interval in milliseconds
45
*/
46
public WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis);
47
48
/**
49
* Create WebDriverWait with custom clock and sleeper
50
*/
51
public WebDriverWait(WebDriver driver, Clock clock, Sleeper sleeper, long timeOutInSeconds, long sleepTimeOut);
52
53
protected RuntimeException timeoutException(String message, Throwable lastException);
54
}
55
```
56
57
### Basic WebDriverWait Usage
58
59
```java
60
import org.openqa.selenium.support.ui.WebDriverWait;
61
import org.openqa.selenium.support.ui.ExpectedConditions;
62
63
WebDriver driver = new ChromeDriver();
64
WebDriverWait wait = new WebDriverWait(driver, 10);
65
66
// Wait for element to be present
67
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("myElement")));
68
69
// Wait for element to be visible and clickable
70
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("submitBtn")));
71
72
// Wait for title to match
73
wait.until(ExpectedConditions.titleIs("Expected Page Title"));
74
```
75
76
## FluentWait
77
78
```java { .api }
79
public class FluentWait<T> implements Wait<T> {
80
/**
81
* Create FluentWait with input object
82
*/
83
public FluentWait(T input);
84
85
/**
86
* Create FluentWait with custom clock and sleeper
87
*/
88
public FluentWait(T input, Clock clock, Sleeper sleeper);
89
90
/**
91
* Set timeout duration (deprecated - use Duration version)
92
*/
93
public FluentWait<T> withTimeout(long duration, TimeUnit unit);
94
95
/**
96
* Set timeout duration
97
*/
98
public FluentWait<T> withTimeout(Duration timeout);
99
100
/**
101
* Set custom timeout message
102
*/
103
public FluentWait<T> withMessage(String message);
104
105
/**
106
* Set timeout message supplier
107
*/
108
public FluentWait<T> withMessage(Supplier<String> messageSupplier);
109
110
/**
111
* Set polling interval (deprecated - use Duration version)
112
*/
113
public FluentWait<T> pollingEvery(long duration, TimeUnit unit);
114
115
/**
116
* Set polling interval
117
*/
118
public FluentWait<T> pollingEvery(Duration interval);
119
120
/**
121
* Ignore collection of exception types during polling
122
*/
123
public <K extends Throwable> FluentWait<T> ignoreAll(Collection<Class<? extends K>> types);
124
125
/**
126
* Ignore single exception type during polling
127
*/
128
public FluentWait<T> ignoring(Class<? extends Throwable> exceptionType);
129
130
/**
131
* Ignore two exception types during polling
132
*/
133
public FluentWait<T> ignoring(Class<? extends Throwable> firstType, Class<? extends Throwable> secondType);
134
135
/**
136
* Wait until condition is true
137
*/
138
public <V> V until(Function<? super T, V> isTrue);
139
}
140
```
141
142
### FluentWait Usage Examples
143
144
```java
145
import org.openqa.selenium.support.ui.FluentWait;
146
import org.openqa.selenium.NoSuchElementException;
147
import java.time.Duration;
148
149
// Create custom FluentWait with detailed configuration
150
FluentWait<WebDriver> wait = new FluentWait<>(driver)
151
.withTimeout(Duration.ofSeconds(30))
152
.pollingEvery(Duration.ofMillis(500))
153
.ignoring(NoSuchElementException.class)
154
.ignoring(StaleElementReferenceException.class)
155
.withMessage("Element was not found within 30 seconds");
156
157
// Wait for custom condition
158
WebElement element = wait.until(driver -> {
159
WebElement el = driver.findElement(By.id("dynamic-element"));
160
return el.isDisplayed() && el.isEnabled() ? el : null;
161
});
162
163
// Wait for element attribute to have specific value
164
wait.until(driver -> {
165
WebElement el = driver.findElement(By.id("status"));
166
return "complete".equals(el.getAttribute("data-status"));
167
});
168
```
169
170
## ExpectedConditions Factory
171
172
The ExpectedConditions class provides a comprehensive set of predefined conditions for common waiting scenarios.
173
174
### Element Presence and Visibility
175
176
```java { .api }
177
public class ExpectedConditions {
178
/**
179
* Wait for element to be present in DOM
180
*/
181
public static ExpectedCondition<WebElement> presenceOfElementLocated(By locator);
182
183
/**
184
* Wait for element to be visible
185
*/
186
public static ExpectedCondition<WebElement> visibilityOfElementLocated(By locator);
187
188
/**
189
* Wait for specific element to be visible
190
*/
191
public static ExpectedCondition<WebElement> visibilityOf(WebElement element);
192
193
/**
194
* Wait for all elements to be visible
195
*/
196
public static ExpectedCondition<List<WebElement>> visibilityOfAllElementsLocatedBy(By locator);
197
public static ExpectedCondition<List<WebElement>> visibilityOfAllElements(WebElement... elements);
198
public static ExpectedCondition<List<WebElement>> visibilityOfAllElements(List<WebElement> elements);
199
200
/**
201
* Wait for all elements to be present
202
*/
203
public static ExpectedCondition<List<WebElement>> presenceOfAllElementsLocatedBy(By locator);
204
}
205
```
206
207
### Element Interaction States
208
209
```java { .api }
210
public class ExpectedConditions {
211
/**
212
* Wait for element to be clickable (visible and enabled)
213
*/
214
public static ExpectedCondition<WebElement> elementToBeClickable(By locator);
215
public static ExpectedCondition<WebElement> elementToBeClickable(WebElement element);
216
217
/**
218
* Wait for element to be selected
219
*/
220
public static ExpectedCondition<Boolean> elementToBeSelected(WebElement element);
221
public static ExpectedCondition<Boolean> elementToBeSelected(By locator);
222
223
/**
224
* Wait for element selection state to match expected value
225
*/
226
public static ExpectedCondition<Boolean> elementSelectionStateToBe(WebElement element, boolean selected);
227
public static ExpectedCondition<Boolean> elementSelectionStateToBe(By locator, boolean selected);
228
229
/**
230
* Wait for element to become stale (no longer attached to DOM)
231
*/
232
public static ExpectedCondition<Boolean> stalenessOf(WebElement element);
233
}
234
```
235
236
### Element Invisibility
237
238
```java { .api }
239
public class ExpectedConditions {
240
/**
241
* Wait for element to be invisible or not present
242
*/
243
public static ExpectedCondition<Boolean> invisibilityOfElementLocated(By locator);
244
245
/**
246
* Wait for element with specific text to be invisible
247
*/
248
public static ExpectedCondition<Boolean> invisibilityOfElementWithText(By locator, String text);
249
250
/**
251
* Wait for specific element to be invisible
252
*/
253
public static ExpectedCondition<Boolean> invisibilityOf(WebElement element);
254
255
/**
256
* Wait for all elements to be invisible
257
*/
258
public static ExpectedCondition<Boolean> invisibilityOfAllElements(WebElement... elements);
259
public static ExpectedCondition<Boolean> invisibilityOfAllElements(List<WebElement> elements);
260
}
261
```
262
263
### Text and Attribute Conditions
264
265
```java { .api }
266
public class ExpectedConditions {
267
/**
268
* Wait for element to contain specific text
269
*/
270
public static ExpectedCondition<Boolean> textToBePresentInElement(WebElement element, String text);
271
public static ExpectedCondition<Boolean> textToBePresentInElementLocated(By locator, String text);
272
273
/**
274
* Wait for element value attribute to contain text
275
*/
276
public static ExpectedCondition<Boolean> textToBePresentInElementValue(WebElement element, String text);
277
public static ExpectedCondition<Boolean> textToBePresentInElementValue(By locator, String text);
278
279
/**
280
* Wait for exact text match
281
*/
282
public static ExpectedCondition<Boolean> textToBe(By locator, String value);
283
284
/**
285
* Wait for text to match regex pattern
286
*/
287
public static ExpectedCondition<Boolean> textMatches(By locator, Pattern pattern);
288
289
/**
290
* Wait for attribute to have specific value
291
*/
292
public static ExpectedCondition<Boolean> attributeToBe(By locator, String attribute, String value);
293
public static ExpectedCondition<Boolean> attributeToBe(WebElement element, String attribute, String value);
294
295
/**
296
* Wait for attribute to contain value
297
*/
298
public static ExpectedCondition<Boolean> attributeContains(WebElement element, String attribute, String value);
299
public static ExpectedCondition<Boolean> attributeContains(By locator, String attribute, String value);
300
301
/**
302
* Wait for attribute to be non-empty
303
*/
304
public static ExpectedCondition<Boolean> attributeToBeNotEmpty(WebElement element, String attribute);
305
}
306
```
307
308
### Page and Browser State
309
310
```java { .api }
311
public class ExpectedConditions {
312
/**
313
* Wait for page title conditions
314
*/
315
public static ExpectedCondition<Boolean> titleIs(String title);
316
public static ExpectedCondition<Boolean> titleContains(String title);
317
318
/**
319
* Wait for URL conditions
320
*/
321
public static ExpectedCondition<Boolean> urlToBe(String url);
322
public static ExpectedCondition<Boolean> urlContains(String fraction);
323
public static ExpectedCondition<Boolean> urlMatches(String regex);
324
325
/**
326
* Wait for specific number of windows
327
*/
328
public static ExpectedCondition<Boolean> numberOfWindowsToBe(int expectedNumberOfWindows);
329
330
/**
331
* Wait for alert to be present
332
*/
333
public static ExpectedCondition<Alert> alertIsPresent();
334
}
335
```
336
337
### Frame Switching
338
339
```java { .api }
340
public class ExpectedConditions {
341
/**
342
* Wait for frame to be available and switch to it
343
*/
344
public static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(String frameLocator);
345
public static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(By locator);
346
public static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(int frameLocator);
347
public static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(WebElement frameLocator);
348
}
349
```
350
351
### Element Count Conditions
352
353
```java { .api }
354
public class ExpectedConditions {
355
/**
356
* Wait for specific number of elements
357
*/
358
public static ExpectedCondition<List<WebElement>> numberOfElementsToBe(By locator, Integer number);
359
360
/**
361
* Wait for number of elements to be more than specified
362
*/
363
public static ExpectedCondition<List<WebElement>> numberOfElementsToBeMoreThan(By locator, Integer number);
364
365
/**
366
* Wait for number of elements to be less than specified
367
*/
368
public static ExpectedCondition<List<WebElement>> numberOfElementsToBeLessThan(By locator, Integer number);
369
}
370
```
371
372
### Nested Element Conditions
373
374
```java { .api }
375
public class ExpectedConditions {
376
/**
377
* Wait for nested element visibility
378
*/
379
public static ExpectedCondition<List<WebElement>> visibilityOfNestedElementsLocatedBy(By parent, By childLocator);
380
public static ExpectedCondition<List<WebElement>> visibilityOfNestedElementsLocatedBy(WebElement element, By childLocator);
381
382
/**
383
* Wait for nested element presence
384
*/
385
public static ExpectedCondition<WebElement> presenceOfNestedElementLocatedBy(By locator, By childLocator);
386
public static ExpectedCondition<WebElement> presenceOfNestedElementLocatedBy(WebElement element, By childLocator);
387
388
/**
389
* Wait for nested elements presence
390
*/
391
public static ExpectedCondition<List<WebElement>> presenceOfNestedElementsLocatedBy(By parent, By childLocator);
392
}
393
```
394
395
### Logical Conditions
396
397
```java { .api }
398
public class ExpectedConditions {
399
/**
400
* Logical NOT of condition
401
*/
402
public static ExpectedCondition<Boolean> not(ExpectedCondition<?> condition);
403
404
/**
405
* Logical OR of conditions (any condition can be true)
406
*/
407
public static ExpectedCondition<Boolean> or(ExpectedCondition<?>... conditions);
408
409
/**
410
* Logical AND of conditions (all conditions must be true)
411
*/
412
public static ExpectedCondition<Boolean> and(ExpectedCondition<?>... conditions);
413
414
/**
415
* Refresh condition on stale element exception
416
*/
417
public static <T> ExpectedCondition<T> refreshed(ExpectedCondition<T> condition);
418
}
419
```
420
421
### JavaScript Conditions
422
423
```java { .api }
424
public class ExpectedConditions {
425
/**
426
* Wait for JavaScript to execute without throwing exceptions
427
*/
428
public static ExpectedCondition<Boolean> javaScriptThrowsNoExceptions(String javaScript);
429
430
/**
431
* Wait for JavaScript to return a non-null/non-empty value
432
*/
433
public static ExpectedCondition<Object> jsReturnsValue(String javaScript);
434
}
435
```
436
437
## Sleeper Interface
438
439
```java { .api }
440
public interface Sleeper {
441
/**
442
* Sleep for specified duration
443
*/
444
void sleep(Duration duration) throws InterruptedException;
445
446
/**
447
* Default system sleeper implementation
448
*/
449
Sleeper SYSTEM_SLEEPER = duration -> Thread.sleep(duration.toMillis());
450
}
451
```
452
453
## Advanced Waiting Patterns
454
455
### Custom ExpectedConditions
456
457
```java
458
// Custom condition for element to have specific CSS class
459
public class CustomConditions {
460
public static ExpectedCondition<Boolean> elementToHaveClass(WebElement element, String cssClass) {
461
return driver -> {
462
String classes = element.getAttribute("class");
463
return classes != null && classes.contains(cssClass);
464
};
465
}
466
467
public static ExpectedCondition<Boolean> pageLoadComplete() {
468
return driver -> {
469
JavascriptExecutor js = (JavascriptExecutor) driver;
470
return "complete".equals(js.executeScript("return document.readyState"));
471
};
472
}
473
}
474
475
// Usage
476
wait.until(CustomConditions.elementToHaveClass(element, "active"));
477
wait.until(CustomConditions.pageLoadComplete());
478
```
479
480
### Combining Wait Strategies
481
482
```java
483
// Wait for multiple conditions
484
WebDriverWait wait = new WebDriverWait(driver, 20);
485
486
// Wait for element to be both visible and contain specific text
487
wait.until(ExpectedConditions.and(
488
ExpectedConditions.visibilityOfElementLocated(By.id("message")),
489
ExpectedConditions.textToBePresentInElementLocated(By.id("message"), "Success")
490
));
491
492
// Wait for any of several possible error messages
493
wait.until(ExpectedConditions.or(
494
ExpectedConditions.visibilityOfElementLocated(By.className("error-message")),
495
ExpectedConditions.visibilityOfElementLocated(By.className("warning-message")),
496
ExpectedConditions.visibilityOfElementLocated(By.id("alert-box"))
497
));
498
```
499
500
### Exception Handling in Waits
501
502
```java
503
FluentWait<WebDriver> wait = new FluentWait<>(driver)
504
.withTimeout(Duration.ofSeconds(30))
505
.pollingEvery(Duration.ofSeconds(1))
506
.ignoring(NoSuchElementException.class)
507
.ignoring(StaleElementReferenceException.class)
508
.withMessage("Custom timeout message");
509
510
try {
511
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("dynamic-element")));
512
} catch (TimeoutException e) {
513
// Handle timeout - element never appeared
514
System.err.println("Element not found within timeout: " + e.getMessage());
515
}
516
```