or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

alerts.mdconfiguration.mddrivers.mdelements.mdindex.mdinteractions.mdjavascript.mdlocators.mdpage-objects.mdwaits.mdwebdriver.md

waits.mddocs/

0

# Waits and Conditions

1

2

Selenium provides sophisticated waiting mechanisms for handling dynamic content, including explicit waits with pre-built conditions and custom wait logic support.

3

4

## Capabilities

5

6

### WebDriverWait Class

7

8

Explicit wait implementation extending FluentWait for WebDriver-specific operations.

9

10

```java { .api }

11

/**

12

* WebDriverWait class for explicit waiting with WebDriver

13

* Extends FluentWait<WebDriver> with WebDriver-specific functionality

14

*/

15

class WebDriverWait extends FluentWait<WebDriver> {

16

/**

17

* Create WebDriverWait with specified timeout

18

* @param driver - WebDriver instance

19

* @param timeout - Duration to wait before timeout

20

*/

21

WebDriverWait(WebDriver driver, Duration timeout);

22

23

/**

24

* Create WebDriverWait with timeout and polling interval

25

* @param driver - WebDriver instance

26

* @param timeout - Duration to wait before timeout

27

* @param sleep - Polling interval duration

28

*/

29

WebDriverWait(WebDriver driver, Duration timeout, Duration sleep);

30

31

/**

32

* Wait until condition returns non-null/true value

33

* @param isTrue - Function that returns result when condition met

34

* @return Result of the condition function

35

* @throws TimeoutException if timeout reached

36

*/

37

<V> V until(Function<WebDriver, V> isTrue);

38

39

/**

40

* Wait until expected condition is met

41

* @param condition - ExpectedCondition to wait for

42

* @return Result of the expected condition

43

* @throws TimeoutException if timeout reached

44

*/

45

<V> V until(ExpectedCondition<V> condition);

46

}

47

```

48

49

### FluentWait Class

50

51

Generic fluent wait implementation with configurable timeout, polling, and exception handling.

52

53

```java { .api }

54

/**

55

* FluentWait class providing fluent interface for configurable waiting

56

* @param <T> - Type of object to wait on (typically WebDriver)

57

*/

58

class FluentWait<T> {

59

/**

60

* Create FluentWait for specified object

61

* @param input - Object to wait on

62

*/

63

FluentWait(T input);

64

65

/**

66

* Set maximum timeout duration

67

* @param timeout - Maximum time to wait

68

* @return FluentWait instance for chaining

69

*/

70

FluentWait<T> withTimeout(Duration timeout);

71

72

/**

73

* Set polling interval

74

* @param interval - Time between condition checks

75

* @return FluentWait instance for chaining

76

*/

77

FluentWait<T> pollingEvery(Duration interval);

78

79

/**

80

* Add exception type to ignore during waiting

81

* @param exceptionType - Exception class to ignore

82

* @return FluentWait instance for chaining

83

*/

84

FluentWait<T> ignoring(Class<? extends Throwable> exceptionType);

85

86

/**

87

* Add multiple exception types to ignore

88

* @param firstType - First exception type

89

* @param secondType - Second exception type

90

* @return FluentWait instance for chaining

91

*/

92

FluentWait<T> ignoring(Class<? extends Throwable> firstType, Class<? extends Throwable> secondType);

93

94

/**

95

* Set custom timeout message

96

* @param message - Message to include in TimeoutException

97

* @return FluentWait instance for chaining

98

*/

99

FluentWait<T> withMessage(String message);

100

101

/**

102

* Set custom timeout message with supplier

103

* @param messageSupplier - Function to generate timeout message

104

* @return FluentWait instance for chaining

105

*/

106

FluentWait<T> withMessage(Supplier<String> messageSupplier);

107

108

/**

109

* Wait until condition returns non-null/true value

110

* @param isTrue - Function that returns result when condition met

111

* @return Result of the condition function

112

* @throws TimeoutException if timeout reached

113

*/

114

<V> V until(Function<T, V> isTrue);

115

}

116

```

117

118

### ExpectedConditions Class

119

120

Utility class providing pre-built expected conditions for common wait scenarios.

121

122

```java { .api }

123

/**

124

* ExpectedConditions utility class with pre-built wait conditions

125

* All methods return ExpectedCondition instances for use with WebDriverWait

126

*/

127

class ExpectedConditions {

128

/**

129

* Wait for element to be present in DOM (not necessarily visible)

130

* @param locator - By locator for element

131

* @return ExpectedCondition for element presence

132

*/

133

static ExpectedCondition<WebElement> presenceOfElementLocated(By locator);

134

135

/**

136

* Wait for all elements to be present in DOM

137

* @param locator - By locator for elements

138

* @return ExpectedCondition for elements presence

139

*/

140

static ExpectedCondition<List<WebElement>> presenceOfAllElementsLocatedBy(By locator);

141

142

/**

143

* Wait for element to be visible (present in DOM and displayed)

144

* @param locator - By locator for element

145

* @return ExpectedCondition for element visibility

146

*/

147

static ExpectedCondition<WebElement> visibilityOfElementLocated(By locator);

148

149

/**

150

* Wait for existing element to become visible

151

* @param element - WebElement to wait for

152

* @return ExpectedCondition for element visibility

153

*/

154

static ExpectedCondition<WebElement> visibilityOf(WebElement element);

155

156

/**

157

* Wait for all elements to become visible

158

* @param elements - List of WebElements to wait for

159

* @return ExpectedCondition for all elements visibility

160

*/

161

static ExpectedCondition<List<WebElement>> visibilityOfAllElements(List<WebElement> elements);

162

163

/**

164

* Wait for all elements located by locator to become visible

165

* @param locator - By locator for elements

166

* @return ExpectedCondition for all elements visibility

167

*/

168

static ExpectedCondition<List<WebElement>> visibilityOfAllElementsLocatedBy(By locator);

169

170

/**

171

* Wait for element to be clickable (visible and enabled)

172

* @param locator - By locator for element

173

* @return ExpectedCondition for element clickability

174

*/

175

static ExpectedCondition<WebElement> elementToBeClickable(By locator);

176

177

/**

178

* Wait for existing element to be clickable

179

* @param element - WebElement to wait for

180

* @return ExpectedCondition for element clickability

181

*/

182

static ExpectedCondition<WebElement> elementToBeClickable(WebElement element);

183

184

/**

185

* Wait for element to be selected

186

* @param element - WebElement to check

187

* @return ExpectedCondition for element selection

188

*/

189

static ExpectedCondition<Boolean> elementToBeSelected(WebElement element);

190

191

/**

192

* Wait for element located by locator to be selected

193

* @param locator - By locator for element

194

* @return ExpectedCondition for element selection

195

*/

196

static ExpectedCondition<Boolean> elementSelectionStateToBe(By locator, boolean selected);

197

198

/**

199

* Wait for text to be present in element

200

* @param element - WebElement to check

201

* @param text - Text to wait for

202

* @return ExpectedCondition for text presence

203

*/

204

static ExpectedCondition<Boolean> textToBePresentInElement(WebElement element, String text);

205

206

/**

207

* Wait for text to be present in element located by locator

208

* @param locator - By locator for element

209

* @param text - Text to wait for

210

* @return ExpectedCondition for text presence

211

*/

212

static ExpectedCondition<Boolean> textToBePresentInElementLocated(By locator, String text);

213

214

/**

215

* Wait for specific text in element's value attribute

216

* @param locator - By locator for element

217

* @param text - Text to wait for in value

218

* @return ExpectedCondition for value text

219

*/

220

static ExpectedCondition<Boolean> textToBePresentInElementValue(By locator, String text);

221

222

/**

223

* Wait for page title to be exact match

224

* @param title - Expected page title

225

* @return ExpectedCondition for title match

226

*/

227

static ExpectedCondition<Boolean> titleIs(String title);

228

229

/**

230

* Wait for page title to contain text

231

* @param title - Text that title should contain

232

* @return ExpectedCondition for title containing text

233

*/

234

static ExpectedCondition<Boolean> titleContains(String title);

235

236

/**

237

* Wait for URL to be exact match

238

* @param url - Expected URL

239

* @return ExpectedCondition for URL match

240

*/

241

static ExpectedCondition<Boolean> urlToBe(String url);

242

243

/**

244

* Wait for URL to contain text

245

* @param fraction - Text that URL should contain

246

* @return ExpectedCondition for URL containing text

247

*/

248

static ExpectedCondition<Boolean> urlContains(String fraction);

249

250

/**

251

* Wait for URL to match regex pattern

252

* @param regex - Regular expression pattern

253

* @return ExpectedCondition for URL pattern match

254

*/

255

static ExpectedCondition<Boolean> urlMatches(String regex);

256

257

/**

258

* Wait for alert to be present

259

* @return ExpectedCondition for alert presence

260

*/

261

static ExpectedCondition<Alert> alertIsPresent();

262

263

/**

264

* Wait for element to become invisible or not present

265

* @param locator - By locator for element

266

* @return ExpectedCondition for element invisibility

267

*/

268

static ExpectedCondition<Boolean> invisibilityOfElementLocated(By locator);

269

270

/**

271

* Wait for element with text to become invisible

272

* @param locator - By locator for element

273

* @param text - Text that element should not contain

274

* @return ExpectedCondition for element invisibility

275

*/

276

static ExpectedCondition<Boolean> invisibilityOfElementWithText(By locator, String text);

277

278

/**

279

* Wait for attribute to contain specific value

280

* @param locator - By locator for element

281

* @param attribute - Attribute name

282

* @param value - Expected attribute value

283

* @return ExpectedCondition for attribute value

284

*/

285

static ExpectedCondition<Boolean> attributeContains(By locator, String attribute, String value);

286

287

/**

288

* Wait for attribute to be specific value

289

* @param locator - By locator for element

290

* @param attribute - Attribute name

291

* @param value - Expected attribute value

292

* @return ExpectedCondition for attribute value

293

*/

294

static ExpectedCondition<Boolean> attributeToBe(By locator, String attribute, String value);

295

296

/**

297

* Wait for frame to be available and switch to it

298

* @param frameLocator - Frame locator (string name/id or By locator)

299

* @return ExpectedCondition for frame availability

300

*/

301

static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(String frameLocator);

302

static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(By frameLocator);

303

304

/**

305

* Wait for number of windows to be specific count

306

* @param expectedNumberOfWindows - Expected window count

307

* @return ExpectedCondition for window count

308

*/

309

static ExpectedCondition<Boolean> numberOfWindowsToBe(int expectedNumberOfWindows);

310

311

/**

312

* Combine multiple conditions with AND logic

313

* @param conditions - ExpectedConditions to combine

314

* @return ExpectedCondition that passes when all conditions pass

315

*/

316

static ExpectedCondition<Boolean> and(ExpectedCondition<?>... conditions);

317

318

/**

319

* Combine multiple conditions with OR logic

320

* @param conditions - ExpectedConditions to combine

321

* @return ExpectedCondition that passes when any condition passes

322

*/

323

static ExpectedCondition<Boolean> or(ExpectedCondition<?>... conditions);

324

325

/**

326

* Negate an expected condition

327

* @param condition - ExpectedCondition to negate

328

* @return ExpectedCondition that passes when original condition fails

329

*/

330

static ExpectedCondition<Boolean> not(ExpectedCondition<?> condition);

331

}

332

```

333

334

## Usage Examples

335

336

### Basic WebDriverWait Usage

337

338

```java

339

import org.openqa.selenium.WebDriver;

340

import org.openqa.selenium.WebElement;

341

import org.openqa.selenium.By;

342

import org.openqa.selenium.chrome.ChromeDriver;

343

import org.openqa.selenium.support.ui.WebDriverWait;

344

import org.openqa.selenium.support.ui.ExpectedConditions;

345

import java.time.Duration;

346

347

WebDriver driver = new ChromeDriver();

348

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

349

350

try {

351

driver.get("https://example.com");

352

353

// Wait for element to be present and visible

354

WebElement submitButton = wait.until(

355

ExpectedConditions.visibilityOfElementLocated(By.id("submit"))

356

);

357

358

// Wait for element to be clickable before interaction

359

WebElement loginButton = wait.until(

360

ExpectedConditions.elementToBeClickable(By.id("login"))

361

);

362

loginButton.click();

363

364

// Wait for text to appear in element

365

WebElement statusMessage = driver.findElement(By.id("status"));

366

wait.until(ExpectedConditions.textToBePresentInElement(statusMessage, "Login successful"));

367

368

// Wait for page title change

369

wait.until(ExpectedConditions.titleIs("Dashboard - MyApp"));

370

371

// Wait for URL change

372

wait.until(ExpectedConditions.urlContains("/dashboard"));

373

374

} finally {

375

driver.quit();

376

}

377

```

378

379

### Advanced FluentWait Configuration

380

381

```java

382

import org.openqa.selenium.support.ui.FluentWait;

383

import org.openqa.selenium.NoSuchElementException;

384

import org.openqa.selenium.StaleElementReferenceException;

385

386

// Configure FluentWait with custom settings

387

FluentWait<WebDriver> fluentWait = new FluentWait<>(driver)

388

.withTimeout(Duration.ofSeconds(30))

389

.pollingEvery(Duration.ofMilliseconds(500))

390

.ignoring(NoSuchElementException.class)

391

.ignoring(StaleElementReferenceException.class)

392

.withMessage("Element was not found within 30 seconds");

393

394

// Use fluent wait with custom condition

395

WebElement dynamicElement = fluentWait.until(driver -> {

396

WebElement element = driver.findElement(By.id("dynamic-content"));

397

return element.isDisplayed() && !element.getText().isEmpty() ? element : null;

398

});

399

400

// Wait for complex condition

401

Boolean complexCondition = fluentWait.until(driver -> {

402

List<WebElement> items = driver.findElements(By.className("item"));

403

return items.size() >= 5 && items.stream().allMatch(WebElement::isDisplayed);

404

});

405

```

406

407

### Custom Expected Conditions

408

409

```java

410

import org.openqa.selenium.support.ui.ExpectedCondition;

411

412

// Custom condition: Wait for element to have specific CSS class

413

public static ExpectedCondition<Boolean> elementToHaveClass(By locator, String className) {

414

return driver -> {

415

WebElement element = driver.findElement(locator);

416

String classes = element.getAttribute("class");

417

return classes != null && classes.contains(className);

418

};

419

}

420

421

// Custom condition: Wait for element count to be specific number

422

public static ExpectedCondition<Boolean> numberOfElementsToBe(By locator, int expectedCount) {

423

return driver -> driver.findElements(locator).size() == expectedCount;

424

}

425

426

// Custom condition: Wait for element to be stale (removed from DOM)

427

public static ExpectedCondition<Boolean> stalenessOf(WebElement element) {

428

return driver -> {

429

try {

430

element.isEnabled(); // Any method call will throw if stale

431

return false;

432

} catch (StaleElementReferenceException e) {

433

return true;

434

}

435

};

436

}

437

438

// Usage of custom conditions

439

wait.until(elementToHaveClass(By.id("loading"), "complete"));

440

wait.until(numberOfElementsToBe(By.className("result-item"), 10));

441

wait.until(stalenessOf(oldElement));

442

```

443

444

### Combining Multiple Conditions

445

446

```java

447

// Wait for multiple conditions using AND

448

ExpectedCondition<Boolean> loginComplete = ExpectedConditions.and(

449

ExpectedConditions.titleIs("Dashboard"),

450

ExpectedConditions.presenceOfElementLocated(By.id("user-menu")),

451

ExpectedConditions.invisibilityOfElementLocated(By.id("loading-spinner"))

452

);

453

wait.until(loginComplete);

454

455

// Wait for any of multiple conditions using OR

456

ExpectedCondition<Boolean> pageReady = ExpectedConditions.or(

457

ExpectedConditions.presenceOfElementLocated(By.id("content")),

458

ExpectedConditions.presenceOfElementLocated(By.id("error-message"))

459

);

460

wait.until(pageReady);

461

462

// Use NOT to wait for condition to become false

463

wait.until(ExpectedConditions.not(

464

ExpectedConditions.attributeContains(By.id("status"), "class", "loading")

465

));

466

```

467

468

### Wait for AJAX and Dynamic Content

469

470

```java

471

// Wait for AJAX request to complete (jQuery example)

472

public static ExpectedCondition<Boolean> jQueryAjaxCompleted() {

473

return driver -> {

474

JavascriptExecutor js = (JavascriptExecutor) driver;

475

return (Boolean) js.executeScript("return jQuery.active === 0");

476

};

477

}

478

479

// Wait for element to stop moving (animations complete)

480

public static ExpectedCondition<Boolean> elementToStopMoving(By locator) {

481

return driver -> {

482

WebElement element = driver.findElement(locator);

483

Point location1 = element.getLocation();

484

try {

485

Thread.sleep(100);

486

} catch (InterruptedException e) {

487

Thread.currentThread().interrupt();

488

}

489

Point location2 = element.getLocation();

490

return location1.equals(location2);

491

};

492

}

493

494

// Wait for page to be fully loaded

495

public static ExpectedCondition<Boolean> pageToBeFullyLoaded() {

496

return driver -> {

497

JavascriptExecutor js = (JavascriptExecutor) driver;

498

return js.executeScript("return document.readyState").equals("complete");

499

};

500

}

501

502

// Usage

503

wait.until(jQueryAjaxCompleted());

504

wait.until(elementToStopMoving(By.id("animated-element")));

505

wait.until(pageToBeFullyLoaded());

506

```

507

508

### Error Handling and Retry Patterns

509

510

```java

511

// Retry pattern with multiple attempts

512

public WebElement findElementWithRetry(By locator, int maxAttempts) {

513

for (int attempt = 1; attempt <= maxAttempts; attempt++) {

514

try {

515

return wait.until(ExpectedConditions.presenceOfElementLocated(locator));

516

} catch (TimeoutException e) {

517

if (attempt == maxAttempts) {

518

throw new NoSuchElementException(

519

"Element not found after " + maxAttempts + " attempts: " + locator

520

);

521

}

522

// Refresh page or perform other recovery action

523

driver.navigate().refresh();

524

}

525

}

526

throw new IllegalStateException("Should not reach here");

527

}

528

529

// Wait with graceful degradation

530

public boolean waitForElementOptional(By locator, Duration timeout) {

531

try {

532

WebDriverWait shortWait = new WebDriverWait(driver, timeout);

533

shortWait.until(ExpectedConditions.presenceOfElementLocated(locator));

534

return true;

535

} catch (TimeoutException e) {

536

return false;

537

}

538

}

539

540

// Usage

541

WebElement element = findElementWithRetry(By.id("flaky-element"), 3);

542

boolean isPresent = waitForElementOptional(By.id("optional-element"), Duration.ofSeconds(5));

543

```

544

545

### Performance Considerations

546

547

```java

548

// Use shorter timeouts for fast-failing conditions

549

WebDriverWait shortWait = new WebDriverWait(driver, Duration.ofSeconds(2));

550

boolean isElementPresent = false;

551

try {

552

shortWait.until(ExpectedConditions.presenceOfElementLocated(By.id("fast-element")));

553

isElementPresent = true;

554

} catch (TimeoutException e) {

555

isElementPresent = false;

556

}

557

558

// Use longer timeouts for slow operations

559

WebDriverWait longWait = new WebDriverWait(driver, Duration.ofSeconds(30));

560

longWait.until(ExpectedConditions.textToBePresentInElementLocated(

561

By.id("slow-loading-content"), "Data loaded successfully"

562

));

563

564

// Optimize polling frequency based on expected timing

565

FluentWait<WebDriver> fastPolling = new FluentWait<>(driver)

566

.withTimeout(Duration.ofSeconds(10))

567

.pollingEvery(Duration.ofMilliseconds(100)); // Fast polling for quick changes

568

569

FluentWait<WebDriver> slowPolling = new FluentWait<>(driver)

570

.withTimeout(Duration.ofMinutes(2))

571

.pollingEvery(Duration.ofSeconds(2)); // Slow polling for long operations

572

```