How to Click a Button with Selenium: Examples
Find a button with a reliable Selenium locator, wait for it to become clickable, and fix common click failures with runnable Python, Java, and other examples.
To click a button with Selenium, locate the intended element and call its click() method. In Python:
from selenium.webdriver.common.by import By
button = driver.find_element(By.ID, "submit")
button.click()
The locator must match the intended button, and dynamic pages may need an explicit wait before the click. Selenium’s click operation scrolls an out-of-view element into view, checks that it is interactable, then clicks its center. If an overlay covers that point, Selenium can report that the click was intercepted.
This guide shows the basic call, locator choices, waits, equivalent Java code, troubleshooting, and a screenshot option for inspecting page state. See the Selenium element interactions documentation.
1. Find the button and click it
Use a locator that identifies the intended control uniquely and is likely to remain stable as the page changes. Selenium supports ID, name, CSS selector, XPath, class name, tag name, link text, and partial link text. The official locator guide describes these strategies.
from selenium.webdriver.common.by import By
button = driver.find_element(By.ID, "submit")
button.click()
find_element returns the first matching element. If the locator matches several controls, that first match may not be the one you intend. Choose a narrower locator or search within a relevant parent.
Common locator examples in Python
from selenium.webdriver.common.by import By
# A stable, unique ID
submit = driver.find_element(By.ID, "submit")
# A name attribute
continue_button = driver.find_element(By.NAME, "continue")
# A CSS selector, such as a button with a data attribute
save = driver.find_element(By.CSS_SELECTOR, 'button[data-action="save"]')
# XPath when the desired control is identified by its text
confirm = driver.find_element(By.XPATH, "//button[normalize-space()='Confirm']")
# Scope a repeated locator to a particular form
form = driver.find_element(By.ID, "billing-form")
form_submit = form.find_element(By.CSS_SELECTOR, "button[type='submit']")
form_submit.click()
Prefer ID or name when it is stable and unique. CSS is concise for attributes and structure. XPath can express relationships and text conditions, but long paths tied to page layout are often brittle. A class name can work when it uniquely identifies the control; generic classes frequently match many elements. For link text, use link locators for links, not buttons.
2. Wait until the button is ready
Page navigation reaching its configured ready state does not guarantee that a JavaScript-rendered button is visible and usable. Wait for the state the next action requires instead of guessing with a fixed sleep. Selenium’s waiting strategies explain the race between page state and automation, and why fixed sleeps can be too short or waste session time.
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "submit"))
)
button.click()
element_to_be_clickable waits for the element to be visible and enabled. Use a condition that matches the next action: presence if it only needs to exist in the DOM, visibility if it must be shown, and clickability before a click. Explicit-wait APIs and supported conditions vary by binding and version; consult that binding’s documentation. In particular, Selenium’s Expected Conditions page notes that Selenium 4 .NET no longer supports the Expected Conditions classes, while Ruby commonly uses blocks or lambdas.
Wait for an overlay to disappear
If a modal, cookie banner, sticky header, or loading layer is in front of the button, wait for that obstruction to go away before finding and clicking the target:
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
wait = WebDriverWait(driver, 10)
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, ".loading-overlay")))
button = wait.until(EC.element_to_be_clickable((By.ID, "submit")))
button.click()
Replace the selector with one for the actual overlay on the page. If the overlay requires a user decision, handle that UI state as the test is meant to: dismiss it, accept it, or otherwise expose the target. Then locate the button again, since a rerender may replace the old element.
3. Equivalent Java example
The same locate-then-click pattern in Java uses findElement and a Selenium locator:
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
WebElement button = driver.findElement(By.id("submit"));
button.click();
A Java explicit wait can wait for the control to be clickable:
import java.time.Duration;
import org.openqa.selenium.By;
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));
WebElement button = wait.until(
ExpectedConditions.elementToBeClickable(By.id("submit"))
);
button.click();
These snippets assume a configured Selenium WebDriver named driver. Driver setup depends on the browser and project. Selenium’s official documentation covers installation and language bindings.
4. Other useful click patterns
Click by CSS selector
button = driver.find_element(By.CSS_SELECTOR, "form#login button[type='submit']")
button.click()
Keep selectors specific enough to identify the intended element, without depending on incidental nesting that may change.
Choose among multiple matching buttons
buttons = driver.find_elements(By.CSS_SELECTOR, "button.primary")
if len(buttons) != 1:
raise RuntimeError(f"Expected one primary button, found {len(buttons)}")
buttons[0].click()
find_elements returns all matches (or an empty list). Checking the count makes ambiguity visible instead of silently clicking the first result.
Verify the result after clicking
A click call completing does not prove the application performed the expected action. Wait for a result such as a changed URL, a confirmation element, or a dialog:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
button.click()
WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "success-message"))
)
Use an observable condition tied to the intended outcome. This makes the automation easier to diagnose when the application rejects a submission or responds more slowly than expected.
5. Troubleshoot common click errors
| Symptom | Likely cause | What to do |
|---|---|---|
NoSuchElementException |
The locator does not match, the page is not at the expected state, or the element has not been added yet. | Check the locator against the current DOM, confirm the correct page or frame, and wait for presence or visibility when the page renders asynchronously. |
ElementClickInterceptedException |
Another element covers the button’s center point, such as a modal, sticky header, or banner. | Identify and handle the covering UI or wait for it to disappear. Then find the target again and click. Selenium documents the center-point behavior in its interaction guide. |
ElementNotInteractableException |
The locator found an element that is hidden, disabled, or otherwise not usable, or it found the wrong element type. | Confirm the match is the intended button, wait for visibility and enabled state, and inspect whether the page requires another step before interaction. See Selenium’s error troubleshooting guide. |
StaleElementReferenceException |
The page rerendered or navigated after the element was located, so that reference no longer points to the current DOM. | Wait for the relevant page state, locate the element again, and then click. Avoid keeping element references across actions that replace page content. |
| The click runs but nothing appears to happen | The application may need more time, a prerequisite may be missing, or the click may not have caused the expected transition. | Wait for an observable result, such as a confirmation message or URL change. Check whether the button is disabled and whether validation messages appeared. |
| The wrong button is clicked | A broad locator matched multiple elements and Selenium selected the first. | Use a unique attribute or scope the lookup to a form, dialog, or other relevant parent. When using find_elements, assert the expected count. |
Selenium’s normal element click is designed to interact with the page as a user would. If it fails because the target is covered, first determine why the page is in that state. Do not substitute a JavaScript-triggered click as a routine workaround: it can bypass the interaction conditions the test should be checking.
6. Reliability, speed, and session cost
- Wait for meaningful state: a short explicit wait on the needed condition is easier to reason about than a fixed delay. Choose a timeout appropriate to the application and environment.
- Keep locators stable: use unique IDs or deliberate test-facing attributes when available. Avoid selectors based on fragile layout details or repeated styling classes.
- Make outcomes observable: after clicking, wait for the expected state so failures point to a real condition rather than an arbitrary pause.
- Reduce unnecessary waiting: fixed sleeps can waste browser-session time when the page is already ready. Explicit waits proceed as soon as their condition is met.
- Diagnose before retrying: blindly repeating a click can submit a form twice or trigger a second action. Establish whether the first click took effect before retrying.
There is no single correct timeout for every page. It depends on application behavior and the environment running the browser; choose a bounded wait and report a useful failure when the condition does not occur.
7. Inspect the page with a screenshot
When a click is intercepted or the wrong control seems to be targeted, a screenshot can help show overlays, layout, and the visible state. For a local Selenium session, capture the browser’s current view with the WebDriver API:
# Python, with driver already configured and on the page to inspect
driver.save_screenshot("page.png")
For a full-page capture or a remote URL without setting up a browser session, ScreenshotNeo is a website screenshot API and MCP server for developers. Its request options include full-page capture, viewport settings, waits, custom headers and cookies, and more. See the ScreenshotNeo API documentation for parameters.
Or skip the browser setup
Use one GET request to capture a page as an image. This cURL example saves a WebP screenshot:
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}`);
Cookie and consent banners are accepted like a visitor and removed before the screenshot; newsletter popups and chat widgets are also removed. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, inspect page info, and capture PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Every feature is on every plan. See the API docs and MCP documentation.
Sign up for ScreenshotNeo to get 1,000 free screenshots a month with no card.
Frequently asked questions
Should I use Selenium’s JavaScript click instead?
Usually, use Selenium’s element click(), which checks visibility and interactability. A JavaScript click can skip those user-oriented conditions. Diagnose overlays, disabled state, and timing before considering a different interaction.
Does a successful click() mean the form succeeded?
No. Wait for a result that proves the expected behavior, such as a confirmation element or navigation to the expected page.
Can Selenium click a link with the same method?
Yes. Locate the link element and call click(). Use a link locator such as link text when that is the clearest stable way to identify it.
Which locator should I start with?
Start with a stable, unique ID or name if the page provides one. Use CSS or XPath when you need to identify the control by attributes, text, or its relationship to a parent.


