Sometimes the built-in conditions aren't enough. You need to wait for an element's attribute to change, for a progress bar to reach 100%, or for AJAX calls to complete. Write your own.
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// Wait until an element's attribute has a specific value
wait.until(driver -> {
WebElement el = driver.findElement(By.id("progress-bar"));
String width = el.getCssValue("width");
return width.equals("100%");
});
// Wait until dropdown options are loaded
wait.until(driver -> {
List<WebElement> options = driver.findElements(
By.cssSelector("#country-select option"));
return options.size() > 1; // More than just "Select..."
});import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.JavascriptExecutor;
public class CustomConditions {
public static ExpectedCondition<Boolean> attributeToBe(
By locator, String attribute, String value) {
return driver -> {
try {
String actual = driver.findElement(locator)
.getAttribute(attribute);
return value.equals(actual);
} catch (Exception e) {
return false;
}
};
}
public static ExpectedCondition<Boolean> pageLoadComplete() {
return driver -> {
JavascriptExecutor js = (JavascriptExecutor) driver;
return js.executeScript("return document.readyState")
.equals("complete");
};
}
}
// Usage:
wait.until(CustomConditions.attributeToBe(
By.id("status"), "class", "completed"));
wait.until(CustomConditions.pageLoadComplete());Custom ExpectedConditions are a great interview talking point. "How do you handle scenarios where built-in waits aren't enough?" — mention lambda-based custom conditions.
Key Point: Write custom conditions with lambdas when built-in ExpectedConditions don't cover your scenario.