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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

When a Selenium Java button will not click, start with the exception text and the page state—not with a JavaScript click or a longer sleep. A reliable fix identifies whether the element is present, visible, enabled, unobstructed and still attached to the current DOM, then waits for the state required by the action and verifies the result.

Selenium’s native element click scrolls an out-of-viewport element into view and checks interactability. If the element’s center is covered, WebDriver can raise an intercepted-click error. An element can also exist in the DOM while remaining hidden, disabled or impossible to scroll into view. The exact diagnosis depends on your locator, markup, browser and Selenium version.

Read the exception before changing the code

Save the complete exception, including its message and stack trace. The wording usually narrows the investigation.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

ElementClickInterceptedException

Selenium associates this error with an element whose center is obscured. Inspect the rendered page at the failure point for a modal, loading layer, sticky banner, animation, cookie prompt or another control positioned above the button. These are possible causes, not assumptions about every page. The official element-interaction documentation explains that Selenium reports an intercepted click when the center is obscured.

ElementNotInteractableException

The locator may have found a hidden duplicate, a disabled control, or an element that cannot be scrolled into the viewport. Selenium’s Java API describes a non-interactable element as including one that is not displayed or whose center cannot be scrolled into view. See the 4.28.0 API definition; other Selenium releases can differ in API details.

Intermittent failures

If identical runs sometimes pass and sometimes fail, suspect a race between the test and asynchronous rendering. Page-load completion does not guarantee that later JavaScript updates, animations or network requests have finished. Selenium’s waiting guidance explains why fixed sleeps can be either too short or unnecessarily slow.

Use an explicit wait for the state you actually need

Choose the condition that matches the action. Presence means the node has been added; visibility means it is rendered; enabled state means the application permits the action; disappearance of a known overlay means the target is no longer covered.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Locate the control with a stable identifier such as an ID, accessible role or test attribute. Avoid position-based selectors that can match a hidden responsive duplicate.
  2. Wait for the relevant condition with a bounded timeout.
  3. Locate the element after a framework update if the page replaces it.
  4. Click with WebElement.click().
  5. Wait for and assert the observable result.
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement button = wait.until(
    ExpectedConditions.elementToBeClickable(By.id("submit"))
);
button.click();
wait.until(ExpectedConditions.urlContains("/success"));

elementToBeClickable is a useful preliminary check, not proof that an application-specific overlay cannot interfere. If the click is still intercepted, identify the blocking layer and wait for that layer to disappear instead of retrying the same command blindly.

Wait for an overlay to disappear

By spinner = By.cssSelector(".loading-overlay");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));
wait.until(ExpectedConditions.invisibilityOfElementLocated(spinner));
WebElement button = wait.until(
    ExpectedConditions.elementToBeClickable(By.cssSelector("button[type='submit']"))
);
button.click();

If the overlay is removed from the DOM rather than hidden, invisibilityOfElementLocated handles that state as well. Use the page’s actual selector.

Wait for a disabled button to become enabled

By submit = By.id("submit");
WebElement button = wait.until(ExpectedConditions.presenceOfElementLocated(submit));
wait.until(driver -> button.isDisplayed() && button.isEnabled());
button.click();

For applications that replace the node after validation, reacquire it inside the wait to avoid a stale reference:

wait.until(driver -> {
    WebElement current = driver.findElement(submit);
    return current.isDisplayed() && current.isEnabled();
});
driver.findElement(submit).click();

Check that your locator targets the intended control

A valid DOM match is not necessarily the visible button. Responsive layouts commonly render desktop and mobile controls together, while component libraries may retain hidden templates. In browser developer tools, inspect every match and confirm:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • It is the visible control in the current viewport.
  • It has the expected text, role, ID or test attribute.
  • It is not disabled by an HTML disabled attribute or application state.
  • Required fields and prerequisite selections are complete.
  • The element has not been replaced since you found it.

When an update replaces the button, an old WebElement reference can become stale. Perform the update, then locate the new element and click it. If the page has several matches, narrow the selector rather than selecting the first result.

Inspect what covers the button

For an intercepted click, pause execution or capture diagnostic information at the failure point. Check the button’s center in the rendered page, not just the DOM tree. A transparent element, animation layer or fixed header can cover the center while the button still appears visible.

Useful checks include the browser’s computed styles, element rectangles and a temporary screenshot. Confirm whether the suspected blocker disappears after a consent action, animation completion or loading event. Interact with the correct visible control when a modal or banner is intentionally part of the flow; do not hide it merely to force the test through.

Choose the interaction API deliberately

Native element click

WebElement.click() follows Selenium’s ordinary scrolling and interactability checks and is the default for a normal button. It best tests whether a user could operate the control through standard WebDriver interaction.

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

Actions API

Use Actions when the behavior genuinely requires a pointer sequence such as moving to a menu before clicking:

new Actions(driver)
    .moveToElement(button)
    .click()
    .perform();

The Selenium interaction documentation distinguishes this pointer sequence from a normal element click. It does not make an obscured or disabled control valid.

JavaScript click

A JavaScript-triggered click can bypass hit-testing and other normal interaction behavior. Treat it as a page-specific diagnostic or last resort, not a reflexive fix. A test may pass while a real user still cannot see or operate the button. First correct timing, visibility, obstruction and locator problems.

Verify the result, not just the method call

A completed click() call does not prove that navigation, a form submission or a state update succeeded. Selenium’s WebElement API advises callers to verify navigation after a native click. Select an assertion that represents the application contract:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • URL or title changes after navigation.
  • A success heading, confirmation message or receipt appears.
  • The dialog closes and a result row is visible.
  • A button changes state or becomes disabled after submission.
button.click();
WebElement confirmation = wait.until(
    ExpectedConditions.visibilityOfElementLocated(By.cssSelector("[role='status']"))
);
Assertions.assertEquals("Saved", confirmation.getText());

Common failure patterns and fixes

Symptom Likely condition Action
Intercepted click The center is covered Find the covering element; wait for it to disappear or use the intended visible control.
Not interactable Hidden, disabled or not scrollable Check visibility, enabled state, viewport and duplicate matches.
Passes only with a long sleep Asynchronous race Replace the sleep with a bounded wait for the specific state.
Fails after filling a form Button or component was replaced Locate the current element after the update.
Click returns but nothing changes Wrong control or unverified outcome Confirm the locator and assert the expected URL, message or state.

Timeouts, retries and reliability

Keep waits bounded and tailored to the operation. A ten-second wait is an example, not a universal value; choose a limit that reflects the application’s normal response time and fail clearly when it is exceeded. Do not combine large implicit waits with many explicit waits without understanding the compounded delays. Retrying an intercepted click without changing page state usually repeats the same failure. If you retry, capture the exception and inspect whether the blocker or DOM changed.

For diagnosis, record the browser and driver versions, Selenium version, URL, locator, viewport and exception message. This information matters because documentation and API behavior can vary between releases. The official material cited here describes general WebDriver behavior; the page’s current markup is required for a definitive cause.

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

Or skip the browser setup

If your goal is a clean page image rather than an interactive test, ScreenshotNeo provides a website screenshot API and MCP server. One request captures a URL as PNG, JPEG, WebP or PDF. It accepts cookie or consent banners like a visitor, then removes 60-plus known consent platforms, newsletter popups and chat widgets before capture. You can turn each step off.

Only clean shots are billed. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and each response reports the result with X-Page-Verdict and X-Billed headers. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

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

For the complete parameter list, see the ScreenshotNeo documentation. A direct call is:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Equivalent Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Equivalent Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also supports full-page and selector captures, lazy-image loading, device presets and custom viewports, dark mode, retina scale, PDF paper and page options, custom CSS or JavaScript, clicks before capture, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed links, asynchronous webhooks, bulk capture of 100 URLs per call, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs also work.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan, and yearly billing gives two months free. Sign up free to try it without a card.

Frequently Asked Questions

Should I always use JavaScript to click a Selenium button?

No. Use the native click after fixing timing, visibility, locator and obstruction issues; JavaScript can bypass behavior your test should validate.

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

Why does a button exist but still throw ElementNotInteractableException?

DOM presence does not imply display, enabled state or scrollability. Check for hidden duplicates, disabled state and viewport access.

What should I log when the failure is intermittent?

Record the full exception, locator, URL, browser and driver versions, Selenium version, viewport and the page state or overlay visible at failure time.

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.