Implicit Wait vs Explicit Wait in Selenium

Understanding implicit wait vs explicit wait in Selenium is essential for building reliable browser automation tests. Modern websites load content dynamically, update page elements asynchronously, and respond differently depending on network speed or browser performance. As a result, Selenium may try to interact with an element before it is ready.

Waits help Selenium synchronize test execution with the application under test. However, implicit and explicit waits solve synchronization problems in different ways. Choosing the wrong approach can make tests slower, harder to debug, or more likely to fail unexpectedly.

In this guide, you will learn how implicit and explicit waits work, when to use each one, what mistakes to avoid, and how to create more stable Selenium tests.

Why Are Waits Necessary in Selenium?

Selenium WebDriver executes commands quickly. A web application, however, may need additional time to:

  • Load a page
  • Fetch data from an API
  • Render a modal window
  • Enable a button
  • Display a notification
  • Update a table
  • Complete an animation
  • Add an element to the DOM

Consider a test that opens a login page and immediately tries to click the sign-in button.

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

WebElement loginButton = driver.findElement(By.id("login-button"));
loginButton.click();

This may work when the page loads quickly. On a slower environment, Selenium may search for the button before it becomes available.

The result may be an exception such as:

NoSuchElementException

The test may pass locally but fail in continuous integration. It may also behave differently across browsers or devices.

This is one of the main causes of flaky Selenium tests.

A proper wait strategy allows the test to continue only when the required condition is satisfied.

What Is an Implicit Wait in Selenium?

An implicit wait tells Selenium WebDriver to wait for a specified amount of time when searching for an element.

Once configured, it applies globally to element searches performed by that WebDriver instance.

Java Implicit Wait Example

import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ImplicitWaitExample {

public static void main(String[] args) {
WebDriver driver = new ChromeDriver();

try {
driver.manage()
.timeouts()
.implicitlyWait(Duration.ofSeconds(10));

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

driver.findElement(By.id("dynamic-button")).click();
} finally {
driver.quit();
}
}
}

In this example, Selenium waits for up to 10 seconds while trying to find the element.

If the element appears after two seconds, Selenium continues immediately. It does not wait for the entire 10-second period.

If the element does not appear within the timeout, Selenium throws an exception.

Python Implicit Wait Example

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

try:
    driver.implicitly_wait(10)
    driver.get("https://example.com")

    driver.find_element(By.ID, "dynamic-button").click()
finally:
    driver.quit()

The same rule applies: Selenium repeatedly checks for the element until it is found or the timeout expires.

Advantages of Implicit Wait

Implicit waits are simple to configure. A single setting affects all element searches.

They can be useful when:

  • The application has predictable loading behavior
  • Most elements require a similar waiting period
  • The test suite is small
  • You need a basic synchronization mechanism
  • Elements are present shortly after page navigation

Implicit waits can also reduce repeated wait code in simple tests.

However, their convenience comes with limitations.

Disadvantages of Implicit Wait

Because an implicit wait applies globally, it does not describe what the test is actually waiting for.

It only waits for Selenium to locate an element. It does not necessarily wait for the element to become:

  • Visible
  • Clickable
  • Enabled
  • Selected
  • Updated
  • Free from an overlay
  • Ready for user interaction

An element may exist in the DOM but remain hidden. In that case, an implicit wait may succeed even though the following action still fails.

Implicit waits can also make troubleshooting more difficult. Every failed element search may consume the configured timeout, which can slow down the test suite.

For example, a 10-second implicit wait may delay negative tests that intentionally verify an element is absent.

What Is an Explicit Wait in Selenium?

An explicit wait tells Selenium to wait for a specific condition before continuing.

Instead of applying globally, it is used for a particular element or situation.

Explicit waits commonly use WebDriverWait together with predefined conditions.

These conditions may wait until:

  • An element is present
  • An element is visible
  • An element is clickable
  • Text appears
  • A URL changes
  • A title matches
  • An alert appears
  • A frame becomes available
  • An element disappears

This makes explicit waits more flexible than implicit waits.

Java Explicit Wait Example

import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ExplicitWaitExample {

    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

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

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

            WebElement button = wait.until(
                ExpectedConditions.elementToBeClickable(
                    By.id("dynamic-button")
                )
            );

            button.click();
        } finally {
            driver.quit();
        }
    }
}

This test does not continue merely because the button exists. It waits until the button is considered clickable.

Python Explicit Wait Example

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()

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

    wait = WebDriverWait(driver, 10)

    button = wait.until(
        EC.element_to_be_clickable((By.ID, "dynamic-button"))
    )

    button.click()
finally:
    driver.quit()

This example waits for the same condition using Python.

Selenium Academy teaches Selenium using Java, C#, Ruby, Python, and JavaScript, allowing learners to understand these concepts in the programming language most relevant to their automation work.

Common Explicit Wait Conditions

Explicit waits support many common browser automation scenarios.

Wait Until an Element Is Present

Use this when an element needs to exist in the DOM.

WebElement element = wait.until(
    ExpectedConditions.presenceOfElementLocated(
        By.id("result")
    )
);

Presence does not guarantee that the element is visible.

Wait Until an Element Is Visible

Use this when the user must be able to see the element.

WebElement message = wait.until(
    ExpectedConditions.visibilityOfElementLocated(
        By.className("success-message")
    )
);

Wait Until an Element Is Clickable

Use this before clicking buttons, links, or interactive controls.

WebElement submitButton = wait.until(
    ExpectedConditions.elementToBeClickable(
        By.id("submit")
    )
);

Wait Until Text Appears

Use this when an application updates text dynamically.

boolean updated = wait.until(
    ExpectedConditions.textToBePresentInElementLocated(
        By.id("status"),
        "Completed"
    )
);

Wait Until an Element Disappears

This is useful for loading indicators and overlays.

boolean spinnerGone = wait.until(
    ExpectedConditions.invisibilityOfElementLocated(
        By.id("loading-spinner")
    )
);

Wait Until an Alert Appears

wait.until(ExpectedConditions.alertIsPresent());
driver.switchTo().alert().accept();

Wait Until a Frame Is Available

wait.until(
ExpectedConditions.frameToBeAvailableAndSwitchToIt(
By.id("payment-frame")
)
);

These targeted conditions make test intent easier to understand.

Implicit Wait vs Explicit Wait in Selenium: Key Differences

The main difference is scope.

An implicit wait applies to all element searches performed by the driver. An explicit wait applies to a specific condition at a specific point in the test.

ComparisonImplicit WaitExplicit Wait
ScopeScopeLocal and condition-specific
Main purposeWait for an element to be foundWait for a defined condition
ConfigurationUsually set onceUsed where needed
FlexibilityLimitedHigh
ReadabilityLess descriptiveClearly communicates intent
Clearly communicates intentLimitedMore suitable
Suitable for dynamic pagesElement lookupVisibility, clickability, text, alerts, frames, and more
DebuggingCan be less transparentUsually easier to diagnose

An implicit wait answers this question:

How long should Selenium continue searching for an element?

An explicit wait answers a more specific question:

What exact condition must become true before the test continues?

Which Wait Should You Use?

For modern web applications, explicit waits are usually the better choice.

They give you more control and allow the test to wait for the condition that actually matters.

Use an explicit wait when:

  • A button becomes clickable after an API response
  • A loading spinner must disappear
  • A modal becomes visible
  • A table receives new rows
  • A notification message appears
  • A frame becomes available
  • A page redirects to a new URL
  • An element is present but not immediately usable

An implicit wait may be acceptable for simple test suites where element-loading behavior is consistent.

However, it should not be used as a replacement for condition-based synchronization.

Should You Combine Implicit and Explicit Waits?

Combining implicit and explicit waits is generally discouraged.

When both are active, their timeout behavior may interact in ways that make execution time difficult to predict.

Consider this example:

driver.manage()
      .timeouts()
      .implicitlyWait(Duration.ofSeconds(10));

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

If the explicit wait repeatedly searches for an element, the implicit wait may affect each search attempt.

As a result, a failure may take longer than expected.

A cleaner strategy is to use explicit waits consistently and keep the implicit wait at zero or avoid configuring it.

driver.manage()
      .timeouts()
      .implicitlyWait(Duration.ofSeconds(0));

Then create explicit waits for the individual conditions required by the test.

Why Thread.sleep() Is Not a Good Selenium Wait Strategy

A common beginner approach is to pause the test for a fixed amount of time.

Thread.sleep(5000);

This forces the test to wait for five seconds regardless of when the page becomes ready.

If the element appears after one second, the test wastes four seconds.

If the element needs six seconds, the test still fails.

Fixed sleeps create several problems:

  • Slower test execution
  • Unnecessary delays
  • Unstable behavior
  • Poor adaptability
  • Hard-to-maintain test code

Explicit waits are more efficient because they stop waiting as soon as the required condition becomes true.

A short fixed delay may occasionally be useful during debugging, but it should not be the main synchronization strategy in a production test suite.

Practical Example: Waiting for Search Results

Imagine a search page where results appear after the user submits a query.

A weak implementation may look like this:

driver.findElement(By.id("search-input"))
      .sendKeys("Selenium waits");

driver.findElement(By.id("search-button"))
      .click();

Thread.sleep(5000);

driver.findElement(By.cssSelector(".result-item"))
      .click();

A more reliable version uses explicit waits:

driver.findElement(By.id("search-input"))
      .sendKeys("Selenium waits");

driver.findElement(By.id("search-button"))
      .click();

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

WebElement firstResult = wait.until(
    ExpectedConditions.elementToBeClickable(
        By.cssSelector(".result-item")
    )
);

firstResult.click();

The improved version waits only as long as necessary and describes the expected browser state clearly.

Practical Example: Waiting for a Loading Spinner

Some applications display a loading indicator while processing data.

The test should usually wait for the spinner to disappear before interacting with the page.

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

wait.until(
    ExpectedConditions.invisibilityOfElementLocated(
        By.className("loading-spinner")
    )
);

WebElement report = wait.until(
    ExpectedConditions.visibilityOfElementLocated(
        By.id("report-content")
    )
);

This approach checks both sides of the transition:

  1. The loading indicator disappears.
  2. The required content becomes visible.

That is more reliable than waiting for an arbitrary number of seconds.

How Explicit Waits Help Prevent Flaky Tests

A flaky test passes and fails without a meaningful change in the application.

Timing problems are a major cause of flakiness.

Explicit waits reduce this risk by synchronizing test actions with observable application conditions.

They help prevent errors such as:

  • NoSuchElementException
  • ElementNotInteractableException
  • ElementClickInterceptedException
  • StaleElementReferenceException
  • TimeoutException

However, waits alone do not solve every flaky test.

A stable automation strategy should also include:

  • Reliable element locators
  • Independent test cases
  • Controlled test data
  • Clear page state
  • Appropriate browser cleanup
  • Reusable page objects
  • Meaningful timeout values
  • Helpful failure messages

Best Practices for Selenium Waits

Use Conditions That Match the Next Action

Do not wait only for presence when the next step is a click.

Instead of:

ExpectedConditions.presenceOfElementLocated(locator)

Use:

ExpectedConditions.elementToBeClickable(locator)

The wait condition should reflect what the test needs to do next.

Keep Timeout Values Reasonable

Very short timeouts can create false failures. Very long timeouts can hide real performance problems and slow down debugging.

Choose values based on:

  • Application behavior
  • Network conditions
  • Test environment
  • Browser performance
  • Business requirements

Not every test needs the same timeout.

Reuse Wait Logic

Repeated wait code can be placed in helper methods or page objects.

public WebElement waitUntilClickable(By locator) {
    return wait.until(
        ExpectedConditions.elementToBeClickable(locator)
    );
}

Then the test becomes easier to read:

waitUntilClickable(By.id("submit")).click();

Wait for State Changes, Not Time

Prefer observable conditions such as:

  • Spinner disappears
  • Button becomes enabled
  • URL changes
  • Text updates
  • Modal becomes visible

These conditions represent actual application behavior.

Avoid Hiding Performance Problems

A very long wait may allow a slow application to pass without drawing attention to a performance regression.

Record how long important actions take and investigate unexpected delays.

Add Clear Failure Context

A generic timeout error may not provide enough information.

Use descriptive helper methods, meaningful test names, screenshots, logs, and browser state details to simplify troubleshooting.

Common Selenium Wait Mistakes

Setting a Long Global Implicit Wait

A large implicit timeout affects every unsuccessful element search and can make the test suite unnecessarily slow.

Using Thread.sleep() Everywhere

Fixed delays increase execution time without guaranteeing reliability.

Waiting for Presence Before Clicking

An element can exist without being visible or clickable.

Mixing Multiple Wait Strategies

Combining implicit waits, explicit waits, and fixed sleeps can create unpredictable timing.

Ignoring Loading Overlays

A button may be visible but still covered by a spinner or modal layer.

Reusing Stale Elements

A page update may replace an existing DOM element. In that case, locate the element again after the update instead of continuing to use the old reference.

Learning Selenium Waits with Selenium Academy

Selenium Academy is an online learning platform for Selenium and Appium test automation.

The Selenium curriculum includes topics such as:

  • Selenium WebDriver
  • Identifying elements
  • Element interaction
  • Selenium waiting
  • Validation
  • Advanced element interaction
  • Windows, tabs, and iFrames
  • Alerts
  • Cookies
  • Screenshots
  • Design patterns
  • Avoiding flaky Selenium tests
  • Cross-browser testing
  • Selenium Grid
  • Jenkins and TeamCity integration

Selenium training is available in Java, C#, Ruby, Python, and JavaScript. Lessons include English and Turkish subtitles together with detailed text explanations.

You can review the complete curriculum through the Selenium course catalog.

Conclusion

The difference between implicit wait and explicit wait in Selenium comes down to control and specificity.

An implicit wait applies globally and gives Selenium additional time to locate elements. An explicit wait targets a specific condition, such as visibility, clickability, text changes, or the disappearance of a loading indicator.

For most modern and dynamic applications, explicit waits provide a clearer, more reliable, and more maintainable approach. By choosing conditions that reflect real application behavior, avoiding unnecessary fixed delays, and keeping wait logic reusable, you can significantly reduce flaky test failures.

To continue developing your Selenium automation skills, explore the Selenium Academy training platform and review the available topics in the Selenium course catalog.

Frequently Asked Questions

What is the main difference between implicit and explicit waits in Selenium?

An implicit wait applies globally when Selenium searches for elements. An explicit wait applies to a specific condition, such as waiting for an element to become visible or clickable.

Is explicit wait better than implicit wait?

Explicit wait is generally more suitable for dynamic web applications because it provides precise control over what Selenium should wait for.

Can implicit and explicit waits be used together?

They can technically be configured together, but combining them may create unpredictable timeout behavior. Using a consistent explicit wait strategy is usually easier to maintain.

Does an implicit wait wait for an element to become clickable?

No. An implicit wait primarily affects how long Selenium searches for an element. It does not guarantee that the element is visible, enabled, or clickable.

What is WebDriverWait in Selenium?

WebDriverWait is used to pause test execution until a specified condition becomes true or a timeout is reached.

Should I use Thread.sleep() in Selenium tests?

Fixed sleeps should generally be avoided because they always wait for the full duration and do not respond to the actual state of the application. Explicit waits are usually more reliable.

How do Selenium waits prevent flaky tests?

Waits synchronize test execution with dynamic page behavior. They reduce failures caused by Selenium attempting to interact with elements before those elements are ready.