Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Wait for the state your next action requires, using a locator inside Selenium’s explicit wait. If JavaScript will add an element later, wait for it to appear; if it is already in the DOM but hidden, wait for visibility; and if your next step is a click, wait until it is visible and enabled. Then click the WebElement returned by the wait. This avoids the race between page navigation finishing and a JavaScript-driven page becoming ready for interaction.

Why Selenium can run before a JavaScript element is ready

A browser can report that navigation has reached the relevant readyState while JavaScript is still updating the page. In a single-page application, scripts may insert, reveal, enable, or replace elements after the initial document has loaded. A Selenium command that immediately looks for a late-added element can therefore run too soon.

Waiting for the whole page to finish loading is not the same as waiting for the specific control your test needs. Selenium’s Waiting Strategies documentation describes explicit waits as polling for a condition until it succeeds or the timeout is reached. This is generally a better synchronization rule than a fixed sleep: a sleep may end before a slow run is ready, or waste time when a fast run was ready much earlier.

Choose the condition according to the element’s current state and the action you intend to take. Presence, visibility, and clickability describe different things; they are not interchangeable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use the wait condition that matches the element’s state

What is happening Wait for What it establishes
The element has not yet been inserted into the DOM presenceOfElementLocated(locator) An element matching the locator exists in the DOM; it need not be visible.
The element exists but is hidden visibilityOfElementLocated(locator) The located element is displayed and visible.
The next action is a click elementToBeClickable(locator) The element is visible and enabled for clicking.

Selenium’s Expected Conditions guide and Java API document these conditions. A clickability wait is a useful readiness check, not a guarantee that every click will succeed: an overlay can still cover the target’s click point, for example.

Java example: wait for a late-loaded element, then click it

Use a By locator in the expected condition so Selenium can look for the element again on each poll. Do not call findElement before the element exists and expect that early lookup to wait for you.

import java.time.Duration;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LateElementClick {
    public static void clickSubmitWhenReady(WebDriver driver) {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

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

Call clickSubmitWhenReady(driver) after navigating to the page or triggering the action that will eventually reveal or create the submit button. The example assumes that driver is already initialized and on the correct page; it contains the imports and method for the wait-and-click operation.

The ten-second timeout is an example, not a measured recommendation for every application. Set a finite timeout appropriate to your test, and let a timeout fail visibly if the expected state never occurs. A timeout can expose a bad locator or a wrong assumption about the page, rather than silently allowing the test to continue in an invalid state.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If the element is added only after another click

Click the control that triggers the update, then wait for the newly added target. Selenium’s official waiting guide shows this pattern:

driver.findElement(By.id("adder")).click();

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement added = wait.until(
    ExpectedConditions.visibilityOfElementLocated(By.id("box0"))
);
added.click();

The important part is that the wait begins after the triggering action and keeps searching by locator. The guide also includes a two-second timeout in a demonstration; that example is not a universal timing recommendation. Use a condition that expresses the state your next operation needs, as above.

Presence, visibility, and clickability are different checks

Wait for presence when DOM insertion is the question

Use presenceOfElementLocated when you need to know that matching markup has been added, regardless of whether it is displayed. This is useful when the next step is a DOM-oriented check or when visibility will be handled separately. Presence alone does not mean a user can see or click the element.

Wait for visibility when the element is present but hidden

Use visibilityOfElementLocated when the application already has the element but reveals it later. For example, a page may include a control that starts hidden and becomes displayed after a user action. Waiting for presence would finish too early in that case because the element already existed before it became visible.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Wait for clickability when you intend to click

For a click, elementToBeClickable more directly expresses the needed state than presence alone: Selenium checks that the element is visible and enabled. If it remains disabled, the condition will not succeed just because its markup is present. Even a visible, enabled element can be obstructed at click time, so handle interception as a distinct failure rather than weakening the readiness condition without understanding the page.

Re-find elements when the page redraws them

A JavaScript update may replace an element rather than simply reveal the same node. A WebElement refers to a particular DOM element; it does not automatically relocate itself after the page changes. Holding a reference obtained before a redraw can lead to a stale-element error.

Prefer a wait condition that takes a locator when the target may not exist yet or may be replaced. Selenium can look it up during polling, and the element returned by until is the one to act on if the condition succeeds. Avoid storing a target reference early and assuming it remains valid through a render or navigation.

Keep implicit and explicit waits consistent

Use one clear waiting strategy for this synchronization problem. Selenium explicitly warns: “Do not mix implicit and explicit waits.” An implicit wait applies broadly to element lookups, while an explicit wait polls for a particular condition. Combining them can produce effective wait times that are difficult to predict. Selenium’s guide gives an example in which a ten-second implicit wait and a fifteen-second explicit wait can result in a timeout after twenty seconds.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For this pattern, leave implicit waiting at its default or otherwise avoid combining it with the explicit wait. The locator-based explicit condition gives the test a specific, observable reason to continue.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot the failure by identifying the state

Symptom Likely issue What to check
NoSuchElementException before the wait The test looked up the target before it was inserted, or the locator is wrong. Move the lookup into the wait condition and verify the locator against the page state after the triggering action.
Wait for presence succeeds, but the click cannot proceed The element exists but is hidden or disabled. Use visibility or clickability according to the required state; confirm the application actually reveals or enables the control.
StaleElementReferenceException The page replaced or redrew the node represented by the stored WebElement. Locate it again by By inside the wait rather than reusing the earlier reference.
ElementClickInterceptedException Another element or overlay is covering the target’s click point. Inspect the visible layout and overlay state; wait for the obstruction to be gone or for the intended UI state before retrying.
The click target remains disabled The application has not reached its enabled state, or the test’s readiness assumption is wrong. Wait for clickability and check what application state is supposed to enable the control.
The explicit wait times out The condition never became true before the configured deadline. Check the locator, the triggering action, the expected state, and whether the page actually loaded the target. Adjust the finite timeout only to suit the application, not to conceal a broken assumption.

Selenium’s Understanding Common Errors documentation covers interaction failures and stale references. Diagnose the state first; increasing the timeout cannot fix a wrong locator, a permanent overlay, or a target that the application never creates.

Or skip the browser setup

If your goal is to inspect or save a page screenshot rather than click a control in an interactive test, ScreenshotNeo offers a screenshot API. It is not a replacement for Selenium when the test must interact with a page; it can provide a capture without setting up a browser automation script.

One GET request returns an image or PDF. For example, this cURL request saves a WebP screenshot of Stripe:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. Before capture, it can accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and responses include X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. ScreenshotNeo is useful for screenshot capture, while Selenium remains the tool in this article’s code for clicking a dynamically loaded element.

Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month with no card.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.