Waits: Implicit, Explicit, Fluent

Never use Thread.sleep(). Use explicit waits for reliability.

Explicit Wait (recommended)

java
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.time.Duration;

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

// Wait for element to be clickable
WebElement btn = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));
btn.click();

// Wait for text to be present
wait.until(ExpectedConditions.textToBePresentInElementLocated(
    By.id("status"), "Success"
));

// Wait for URL to contain
wait.until(ExpectedConditions.urlContains("/dashboard"));

// Wait for invisibility
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("spinner")));

Fluent Wait

java
import org.openqa.selenium.support.ui.FluentWait;
import java.time.Duration;
import java.util.function.Function;

FluentWait<WebDriver> wait = new FluentWait<>(driver)
    .withTimeout(Duration.ofSeconds(30))
    .pollingEvery(Duration.ofMillis(500))
    .ignoring(NoSuchElementException.class);

WebElement result = wait.until(d -> d.findElement(By.id("result")));

Implicit Wait (set once, global)

java
// Set once in setup — applies to all findElement calls
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));