click() looks like the simplest method in Selenium's API, and most of the time it is. The complexity shows up when it silently fails: the element exists, your locator is correct, and the click still does not register, or worse, it lands on the wrong thing entirely.
This guide covers the click() method itself, when to reach for the Actions class instead, and the handful of failure patterns, ElementClickInterceptedException, overlays, hidden elements, that account for nearly every "the click did not work" report.
Here is what we will cover:
THE SHORT ANSWER
How to click in Selenium, at a glance:
• click() is the default. It works on any element that is visible, enabled, and not obstructed.
• Use Actions.click() when you need to chain a hover or key press together with the click.
• contextClick() simulates a right-click and doubleClick() simulates a double-click, both through the Actions class.
• A JavaScript executor click bypasses visibility checks entirely. Treat it as a last resort, not a default.
• Most "the click does not work" failures are ElementClickInterceptedException from an overlay, not a broken locator.
The comparison table and troubleshooting section below cover exactly when each approach is the right call.
The Selenium click command, click(), is a method on the WebElement interface. Call it on a located element and Selenium simulates a real user click: a left mouse click, fired only if the element is visible, enabled, and not covered by anything else at that point on the page. You will find it in almost every Selenium test script; whether you are validating a navigation flow or triggering a JavaScript event, click() is what makes that interaction happen.
The rule of thumb: if a real user can click it, you can test it with click(). The cases where that is not enough, an intercepted click, a hidden element, a race against the page still loading, are what the rest of this guide is about. For the fundamentals of Selenium itself, our Selenium testing tutorial covers WebDriver, Grid, and IDE from the ground up.
Most click examples stop at the click itself, which hides the part that actually matters: confirming the click did something. Here is a full example, navigating to a page, waiting for a real element, clicking it, and asserting the result.
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;
WebDriver driver = new ChromeDriver();
driver.get("https://katalon.com");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement trialBtn = wait.until(
ExpectedConditions.elementToBeClickable(By.linkText("Start free trial"))
);
trialBtn.click();
wait.until(ExpectedConditions.urlContains("open-true-platform"));
assert driver.getCurrentUrl().contains("open-true-platform") : "Click did not navigate to the signup flow";
driver.quit();
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()
driver.get("https://katalon.com")
wait = WebDriverWait(driver, timeout=10)
trial_btn = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "Start free trial")))
trial_btn.click()
wait.until(EC.url_contains("open-true-platform"))
assert "open-true-platform" in driver.current_url, "Click did not navigate to the signup flow"
driver.quit()
Notice the elementToBeClickable wait before the click, not just a presence check. That single choice is what separates a stable click from a flaky one; our guide to explicit wait in Selenium covers why.
One caveat on the Java version: the built-in assert keyword does nothing unless the JVM runs with the -ea flag, silently passing even on a real failure if that flag is missing. It works for a quick illustration like this one, but a real test suite should use JUnit's or TestNG's own assertion methods instead, which do not depend on a launch flag to actually run.
Selenium gives you five ways to trigger something that looks like a click. They are not interchangeable, and reaching for the wrong one either misses the interaction you meant to test or hides a real bug behind a passing test.
| Selenium Click Methods Five ways to trigger a click, and when each one is the right call. |
|
|---|---|
| click() | The default method on any WebElement. Simulates a real left-click if the element is visible, enabled, and not obscured. Start here; reach for the alternatives below only when it fails or the interaction itself needs to be non-standard. |
| Actions.click() | The same left-click, built through the Actions class instead of called directly on the element. Useful when you need to chain it with another interaction, a hover first, or a key held down during the click, or when a plain click() gets intercepted but a synthesized one succeeds. |
| contextClick() | Simulates a right-click, opening whatever context menu your application renders. Only useful if the app implements its own custom menu; the browser's native right-click menu is outside what Selenium can inspect or interact with. |
| doubleClick() | Simulates two rapid clicks. Needed for UI patterns that specifically listen for a double-click event, inline text editing, file-manager-style icons, a single click() will not trigger that behavior. |
| JavaScript executor | Runs arguments[0].click() directly in the browser, bypassing Selenium's visibility and interactability checks entirely. It will "click" elements a real user could not reach, which can mask genuine bugs. Use it as a last resort for a persistent ElementClickInterceptedException, never as a default. |
contextClick() and doubleClick() both deserve more depth than a quick mention here. Our dedicated guide to double-clicking and right-clicking in Selenium covers full Java and Python examples for both, plus the failure modes specific to each.
The syntax is rarely the problem. A click that "does not work" is almost always one of these.
ElementClickInterceptedException. Selenium found the element and computed where to click, but a different element sits on top of that point, a cookie banner, a sticky header, a modal, so the click hits the overlay instead. Scroll the target into a part of the page the overlay does not cover, then retry the wait and click:
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementClickInterceptedException;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
try {
driver.findElement(By.id("checkout-button")).click();
} catch (ElementClickInterceptedException e) {
WebElement checkoutBtn = driver.findElement(By.id("checkout-button"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: 'center'});", checkoutBtn);
wait.until(ExpectedConditions.elementToBeClickable(checkoutBtn)).click();
}
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import ElementClickInterceptedException
wait = WebDriverWait(driver, timeout=10)
try:
driver.find_element(By.ID, "checkout-button").click()
except ElementClickInterceptedException:
checkout_btn = driver.find_element(By.ID, "checkout-button")
driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", checkout_btn)
wait.until(EC.element_to_be_clickable((By.ID, "checkout-button"))).click()
Waits and timing. The element is in the DOM before it is actually interactable, a classic race condition. Wait for elementToBeClickable, not just presence; see the full breakdown in our explicit wait guide.
Hidden elements. An element with zero size or display: none cannot receive a real click, Selenium will correctly refuse it. A JavaScript executor click can "succeed" against a hidden element anyway, which is one more reason not to default to it: a test that passes against an element no user could ever see or click is worse than a test that fails honestly.
Scrolling. An element outside the current viewport will not register a standard click. Actions.moveToElement() scrolls automatically before interacting; a manual scrollIntoView({block: 'center'}) via the JavaScript executor works too, and is safer than the default scrollIntoView(true), which can scroll the target behind a sticky header.
When not to reach for a JavaScript click. It bypasses the same visibility and interactability checks that make Selenium's click meaningful in the first place. Defaulting to it hides real problems: if an overlay blocks a real customer from clicking a button, that is a product bug, not a test problem, and a JS click will paper over it with a green checkmark. Reserve it for scrolling elements into view, or as a last-resort workaround for a confirmed, non-blocking test-environment artifact, not as the default way to click.
Katalon builds on Selenium and Appium, adding a keyword-driven layer on top of the click methods above. Instead of writing raw Selenium code, a single keyword like WebUI.click(findTestObject ('ObjectName')) handles the click, and Katalon automatically retries it when an overlay briefly intercepts the target, the same failure the troubleshooting section above walks through manually.
The same keyword-driven approach covers every click type in this guide, not just the standard click. WebUI.doubleClick() WebUI.doubleClick() and WebUI.rightClick() mirror Actions.doubleClick() and contextClick(), without the extra chaining, and inherit the same retry logic. See the WebUI Double-click docs and WebUI Right-click docs for the full keyword reference, or the double-clicking and right-clicking in Selenium guide above for side-by-side examples against the Actions class.
A few reasons teams already using Selenium adopt Katalon for this specific problem:
To go deeper, the free Using Built-in Keywords in Katalon course covers test objects and reusable keywords, and the Katalon WebUI.click() docs explain the retry behavior in full.
📝 Tired of hand-writing retry logic for every intercepted click? Start a free trial and see Katalon's built-in click retry and self-healing locators handle it automatically.