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.

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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from 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.

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.

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

Use the right success condition

  • For navigation, save driver.current_url before clicking and wait with EC.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.

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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

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.

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

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.

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

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.

Diagnose the failure in a fixed order

  1. Confirm the API and value. Import By, use driver.find_element(By.NAME, value), and verify the exact live attribute.
  2. Check match count. Use find_elements to detect zero or multiple matches before deciding that the click itself failed.
  3. Confirm page and context. Print the URL, title, window handle, and handles; switch into the correct iframe or tab.
  4. Wait for readiness. Distinguish presence, visibility, and enabled state. Use element_to_be_clickable for the final pre-click condition.
  5. Look for obstruction. Check the visible browser for banners, dialogs, masks, headers, and widgets that cover the click point.
  6. Re-find after updates. If the DOM changed, discard the old WebElement and locate it again.
  7. 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Reliability 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.

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.

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

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.

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

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.

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.