This is the #1 mistake and the #1 interview question on waits. When you mix them, timeouts become unpredictable.
// BAD — DO NOT mix implicit and explicit waits
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));
// What happens:
// Explicit wait polls every 500ms. Each poll calls findElement().
// But findElement() has 10-second implicit wait.
// So each FAILED poll takes 10 seconds, not 500ms.
// Effective timeout could be 200+ seconds instead of 15!The Selenium documentation explicitly says: "Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times." Choose one: implicit wait globally OR explicit waits everywhere. The recommended approach is explicit waits only.
// BAD — using presence when you need to CLICK
// Element is present in DOM but behind a loading overlay!
WebElement btn = wait.until(
ExpectedConditions.presenceOfElementLocated(
By.id("submit-btn")));
btn.click(); // ElementClickInterceptedException!
// GOOD — use elementToBeClickable for click actions
WebElement btn2 = wait.until(
ExpectedConditions.elementToBeClickable(
By.id("submit-btn")));
btn2.click(); // Works!// BAD — timeouts scattered in every test
new WebDriverWait(driver, Duration.ofSeconds(10));
new WebDriverWait(driver, Duration.ofSeconds(15));
new WebDriverWait(driver, Duration.ofSeconds(10));
// GOOD — define constants in a config class
public class TestConfig {
public static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10);
public static final Duration LONG_TIMEOUT = Duration.ofSeconds(30);
public static final Duration SHORT_TIMEOUT = Duration.ofSeconds(3);
}
WebDriverWait wait = new WebDriverWait(driver, TestConfig.DEFAULT_TIMEOUT);Rule of thumb: presenceOfElementLocated for hidden elements (CSRF tokens, hidden inputs). visibilityOfElementLocated for reading text. elementToBeClickable for clicking buttons. invisibilityOfElementLocated for spinners.
Q: Why should you not mix implicit and explicit waits?
A: When both are set, explicit wait's polling calls findElement() internally. If implicit wait is also active, each failed poll waits the full implicit wait duration. So a 10-second explicit wait with 500ms polling would normally make 20 attempts. But with a 10-second implicit wait, each attempt takes 10 seconds — making the effective timeout 200 seconds instead of 10. The Selenium documentation explicitly warns against this.
Key Point: Never mix implicit and explicit waits. Use the right ExpectedCondition for the right action. Centralize timeout values.