What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
If a Selenium Python script finds an element with find_element_by_name but clicking appears to do nothing, update the locator to the current documented form, wait until the control is visible and enabled, and then wait for the page state that proves the action succeeded:
from selenium.webdriver.common.by import By
button = driver.find_element(By.NAME, "target-name")
Finding a node, making it interactable, and confirming the application’s response are separate operations. A successful .click() call alone does not prove that a form was submitted, navigation occurred, or an event handler completed.
Use the current Selenium Python locator
The current Python API documents find_element(by, value) with the By.NAME strategy. The reviewed API reference does not document the legacy find_element_by_name method, so write new code as follows rather than depending on the old convenience method:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11from selenium.webdriver.common.by import By
element = driver.find_element(By.NAME, "target-name")
Replace target-name with the exact live name attribute. Selenium’s find_element call returns the first matching node. If several controls share that name, the first one might not be the control you intended.
#1 Best Overall
The Python API reference reviewed for this article is rolling documentation labeled Selenium 4.49.0 on September 29, 2026. It is safer to follow the API documented for your installed version than to infer a removal date for the legacy method.
A complete click-and-verify pattern
This example waits for clickability and then waits for an observable result. Change the URL, name, and success condition to match your page.
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
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()
wait = WebDriverWait(driver, 10) # example timeout; tune for your environment
try:
driver.get("https://example.com/form")
name_locator = (By.NAME, "target-name")
old_url = driver.current_url
button = wait.until(EC.element_to_be_clickable(name_locator))
button.click()
# Pick the signal that means success on this application.
try:
wait.until(EC.url_changes(old_url))
except TimeoutException:
# A page that stays on the same URL may expose a result element instead:
# wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".success")))
# or wait for a state change specific to the application.
raise
finally:
driver.quit()
element_to_be_clickable checks that the element is visible and enabled. It does not guarantee that an overlay will not intercept the pointer or that the application’s business action will succeed. The ten-second value is an example, not a universal setting.
Use the right success condition
- For navigation, save
driver.current_urlbefore clicking and wait withEC.url_changes. - For an in-place form, wait for a success message, a result row, or a changed attribute.
- For a button that becomes disabled, wait for that state rather than a URL change.
- For asynchronous requests, wait for the UI state the user sees after the request completes, not merely for the click call to return.
Why Selenium can find a control but appear to do nothing
The selector matches the wrong node
Check the live DOM, not an old page snapshot, and copy the exact name value. Count matches before clicking:
matches = driver.find_elements(By.NAME, "target-name")
print("matches:", len(matches))
for index, item in enumerate(matches):
print(index, item.tag_name, item.get_attribute("type"), item.is_displayed(), item.is_enabled())
If the count is zero, the page may still be loading, the attribute may differ from your assumption, or you may be in the wrong document. If the count is greater than one, use a more specific locator or select the intended match deliberately.
Rank #2
The browser is on the wrong page, window, or frame
Before locating the element, print the current URL and window handles. A newly opened tab or a redirect can leave WebDriver focused on a different browsing context than the one visible to you:
print(driver.current_url)
print(driver.title)
print(driver.window_handles)
print(driver.current_window_handle)
If the element is inside an iframe, switch into that frame first. Locate it again after switching:
frame = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "iframe.payment")))
driver.switch_to.frame(frame)
button = wait.until(EC.element_to_be_clickable((By.NAME, "target-name")))
button.click()
driver.switch_to.default_content()
When a click opens another window, switch to the new handle before searching there. When the page returns to the top document, use driver.switch_to.default_content(). A stored element from one frame or document is not automatically relocated in another.
The node exists but is not interactable yet
DOM presence only means that a node exists. It can still have zero size, be hidden by CSS, be disabled, or be waiting for application initialization. Selenium’s visibility condition requires presence plus non-zero width and height. Use the appropriate wait:
locator = (By.NAME, "target-name")
# Existence only
wait.until(EC.presence_of_element_located(locator))
# Visible, but not necessarily enabled
wait.until(EC.visibility_of_element_located(locator))
# Visible and enabled
button = wait.until(EC.element_to_be_clickable(locator))
Do not replace an explicit wait with a fixed time.sleep() unless you have a specific reason. A sleep can be too short on a slow run and unnecessarily long on a fast one.
Rank #3
An overlay receives the pointer
A cookie banner, modal, loading mask, sticky header, newsletter prompt, or chat widget can cover the target. Selenium describes ElementClickInterceptedException as occurring when the click would instead be received by a different element.
Inspect the screenshot and browser state at the moment of failure. Close the overlay through its real control, wait for it to disappear, or scroll the target into a usable position. Do not routinely force a JavaScript click: that can bypass the pointer event path and hide a genuine user-facing defect.
overlay = (By.CSS_SELECTOR, ".loading-mask")
wait.until(EC.invisibility_of_element_located(overlay))
button = wait.until(EC.element_to_be_clickable((By.NAME, "target-name")))
button.click()
If the overlay is optional, dismiss it using a stable locator and then re-find the target. A dismissal can trigger DOM replacement, making an earlier element reference stale.
The element reference became stale
StaleElementReferenceException commonly follows navigation, refreshes, dynamic rendering, or a frame refresh. WebDriver does not relocate a stored element automatically. Keep the locator, wait for the new state, and find the element again:
locator = (By.NAME, "target-name")
wait.until(EC.presence_of_element_located(locator))
# A framework update or navigation may replace the node here.
button = wait.until(EC.element_to_be_clickable(locator))
button.click()
Avoid carrying a WebElement through a known re-render. Re-establish the correct window or frame first, then locate a fresh reference.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →The click happened, but the application rejected the action
Client-side validation, a disabled business rule, a missing required field, or an event handler error can leave the page visually unchanged without a Selenium exception. Check the browser console and network logs where available, inspect validation text, and verify that the selected control is the intended submit or action element.
Rank #4
Diagnose the failure in a fixed order
- Confirm the API and value. Import
By, usedriver.find_element(By.NAME, value), and verify the exact live attribute. - Check match count. Use
find_elementsto detect zero or multiple matches before deciding that the click itself failed. - Confirm page and context. Print the URL, title, window handle, and handles; switch into the correct iframe or tab.
- Wait for readiness. Distinguish presence, visibility, and enabled state. Use
element_to_be_clickablefor the final pre-click condition. - Look for obstruction. Check the visible browser for banners, dialogs, masks, headers, and widgets that cover the click point.
- Re-find after updates. If the DOM changed, discard the old WebElement and locate it again.
- Verify the outcome. Wait for the URL, message, row, attribute, or other state that represents success on that page.
This order separates selector problems from timing, context, interaction, and application-response problems. The exact cause in your script still depends on its locator, markup, exception text, and post-click state.
Match common symptoms to the likely fix
| Symptom | What it usually means | First corrective action |
|---|---|---|
NoSuchElementException |
The selector does not match in the current document, or the page is not ready. | Check the exact name, wait for presence, and verify the frame or window. |
ElementClickInterceptedException |
Another element would receive the pointer. | Inspect and dismiss or wait out the overlay, then re-find the target. |
ElementNotInteractableException |
The node exists but is hidden, has no usable size, or cannot accept interaction. | Wait for visibility and enabled state; confirm you matched the visible control. |
StaleElementReferenceException |
The DOM or browsing context replaced the stored node. | Return to the correct context and locate a fresh element. |
| No exception, no visible change | The click may have reached the node, but the locator, validation, event handling, or expected-result check is wrong. | Inspect match count, validation state, console/network errors, and wait for an application-specific outcome. |
Make the script observable while debugging
Capture the state immediately before and after the click. This distinguishes a wrong page from a blocked pointer and from an application that accepted the event but produced no visible result.
print("before:", driver.current_url, driver.title)
print("displayed:", button.is_displayed(), "enabled:", button.is_enabled())
driver.save_screenshot("before-click.png")
button.click()
driver.save_screenshot("after-click.png")
print("after:", driver.current_url, driver.title)
Include the exception type, locator, current URL, frame/window information, and the expected post-click signal in test logs. Those details make a conditional diagnosis reproducible instead of treating every unchanged screen as the same bug.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsReliability and performance considerations
Choose bounded, purposeful waits
Use one explicit wait object with a timeout appropriate to your test environment. A very short timeout creates intermittent failures on slower CI workers; an excessive timeout delays genuine failures. Prefer a condition tied to the next state rather than a sequence of arbitrary sleeps.
Keep locators stable
A semantic name is often preferable to a generated class name, but it is not automatically unique. If a page has repeated names, combine strategies with a stable container, field type, or label relationship. Avoid selecting by a transient DOM position.
Best Value
Do not confuse a screenshot with proof of success
A screenshot is useful evidence of what was visible, but the test should assert a DOM, URL, or application state. A visually unchanged image can still accompany a network request or validation error, while a changed image does not identify which business condition was met.
Or skip the browser setup
When you only need a clean image of a page for debugging, documentation, or an artifact, ScreenshotNeo provides a single HTTP request instead of maintaining a browser session. Its capture flow accepts cookie and consent banners before removing more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Only clean shots are billed, while bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.
See the ScreenshotNeo API documentation for parameters. The same endpoint supports PNG, JPEG, WebP, and PDF output, full-page lazy-image loading, CSS-selector element captures, device and viewport settings, custom CSS or JavaScript, waits, request blocking, cookies, headers, authentication, geolocation, caching, signed links, asynchronous webhooks, bulk capture, usage data, and an OpenAPI specification.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
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}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('shot.webp', data);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account to try it with no card.
FAQ
Frequently Asked Questions
Should I replace every old locator immediately?
For new and maintained Python code, use the documented find_element(By.NAME, value) form. Migrate older calls when you touch that code, and verify behavior against the Selenium version installed in your environment.
Is a JavaScript click a reliable fix?
Usually not as a first remedy. It can bypass the real pointer path and conceal an overlay, disabled state, or layout defect. Fix the locator, context, readiness, or obstruction first; use JavaScript only when the application intentionally requires it and you understand the trade-off.
Why does the same script pass locally but fail in CI?
CI can load pages more slowly, use a different viewport, expose an overlay at a different position, or run with different browser and driver versions. Log the URL, context, match count, readiness state, exception, and screenshots around the click, then tune explicit waits to the CI environment.
What information is needed to identify the exact cause?
The locator and markup, Selenium and browser versions, current URL and frame/window, exception text or logs, and the observable state expected after the click. Without those details, several causes can produce the same unchanged screen.
Quick Recap
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.

