Selenium Exceptions and Errors
Find Your Error
| Your error message | It means | Fix |
|---|---|---|
stale element reference: element is not attached to the page document |
The element was re-created; your reference is dead | StaleElementReferenceException → |
no such element: Unable to locate element |
Selenium searched the current context and found nothing | NoSuchElementException → |
element click intercepted... Other element would receive the click |
Something is on top of your element | Element Not Clickable → |
Expected condition failed: waiting for... |
The wait condition never came true | TimeoutException → |
element not interactable |
Found it — but it's hidden/disabled/zero-size | ElementNotInteractable → |
This version of ChromeDriver only supports Chrome version X |
Driver/browser version mismatch | SessionNotCreatedException → |
NullPointerException on a @FindBy field |
Missing PageFactory.initElements() |
NullPointerException → |
NoClassDefFoundError / ClassNotFoundException |
Class missing at runtime — or static init failed | ClassNotFound vs NoClassDefFound → |
matches more than one step definition |
Duplicate Cucumber step definitions | Ambiguous & Undefined Steps → |
| Passes locally, fails in Jenkins | Environment difference (headless/viewport/timing) | CI-Only Failures → |
The Decision Tree
Most Selenium failures resolve in 30 seconds if you ask these in order.
Did Selenium find the element?
- No →
NoSuchElementException→ wrong locator, timing, or iframe - Yes → continue
Can Selenium interact with it?
- No, it's hidden/disabled →
ElementNotInteractableException→ wrong wait condition - No, something's on top →
ElementClickInterceptedException→ overlay/loader - No, the reference is dead →
StaleElementReferenceException→ re-locate it - Yes → continue
Did it work locally but not in CI?
Headless viewport (800×600), timing, or test data → CI failures
The Four "Can't Find / Can't Use" Exceptions
The distinction that solves most confusion.
| Exception | Selenium… | Root problem |
|---|---|---|
| NoSuchElement | couldn't find it | Locator / timing / iframe |
| Timeout | condition never passed | Wrong condition |
| NotInteractable | found it, can't use it | Element state |
| ClickIntercepted | found it, something's on top | Element overlap |
The progression is diagnostic. If you fix a NoSuchElement and now get NotInteractable, that's progress — you've moved from a locator problem to a state problem.
The Three Root Causes Behind ~90% of Failures
Nearly every error above traces back to one of these.
Timing ⭐
Your script is faster than the page. The fix is never Thread.sleep() — it's a condition-based explicit wait that adapts to any machine speed.
Wrong wait condition ⭐
presenceOfElementLocated only means "in the DOM." It passes while the element is still invisible — then your click fails with a different error, sending you down the wrong path entirely.
| Before you… | Wait for |
|---|---|
| read text / assert | visibilityOfElementLocated |
| click | elementToBeClickable |
| read an attribute only | presenceOfElementLocated |
Caching elements ⭐
Storing WebElement objects (in Page Objects or a List) creates references that die the moment the DOM updates.
// ❌ Caches a reference — stale on the next re-render
@FindBy(id = "user") private WebElement user;
// ✅ Store the locator, resolve on demand
private By user = By.id("user");
This one habit eliminates most stale-element and NullPointer failures at once.
The 60-Second Diagnosis
Before changing any code, open DevTools (F12):
document.querySelectorAll("#your-locator").length
| Result | Meaning |
|---|---|
0 |
Not in the DOM — wrong locator, or not rendered yet |
1 |
It exists — so it's timing or context (iframe), not the locator |
2+ |
Multiple matches — Selenium takes the first one |
document.querySelectorAll("iframe").length // > 0? Suspect an iframe.
Ten seconds. Saves an hour. Most people skip this and start adding sleeps.
Debugging in CI (Where You Can't See)
Headless CI gives you no browser to watch — so make the failure explain itself.
@AfterMethod
public void captureOnFailure(ITestResult result) {
if (result.getStatus() == ITestResult.FAILURE) {
File shot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
String html = driver.getPageSource(); // often MORE useful than the screenshot
// save both, attach to the report, archive in Jenkins
}
}
Page source beats a screenshot for locator problems — a screenshot shows the element is there; the source shows you why your selector missed it.
Errors That Are Actually Bugs ⚠️
Not every failure is your test's fault. Before you "fix" it, ask whether the app is telling you something.
| The error | Might mean |
|---|---|
ElementClickIntercepted by a modal |
A real user can't click it either |
ElementNotInteractable, isEnabled() = false |
Form validation is correctly blocking it |
| Element missing after an action | The feature is broken |
This matters more than it sounds. A JavaScript click "fixes" an intercepted click by bypassing the overlay — and ships the user-facing bug. You've automated around the defect your test existed to catch.
Always ask: could a real user do this? If not, you've found a bug, not a flaky test.
FAQs
What are the most common Selenium exceptions?
NoSuchElementException, StaleElementReferenceException, ElementClickInterceptedException, TimeoutException, and ElementNotInteractableException — plus SessionNotCreatedException from driver mismatches.
What causes most Selenium failures?
Three things: timing (script faster than page), the wrong wait condition, and caching WebElement references.
How do I stop tests being flaky?
Replace sleeps with condition-based explicit waits, store By locators rather than WebElement objects, and make test data independent.
Why do tests fail only in Jenkins?
Headless defaults to an 800×600 viewport, CI timing differs, and CI has no cookies or local test data. Set --window-size=1920,1080 first.
Should I use a JavaScript click to fix intercepted clicks?
Rarely. It bypasses the overlay, so your test passes while a real user still can't click the button — hiding a genuine bug.
All Troubleshooting Guides
| Guide | Covers |
|---|---|
| StaleElementReferenceException | Dead references, the loop trap, POM caching |
| NoSuchElementException | Timing, iframes, dynamic locators |
| Element Not Clickable at Point | Overlays, sticky headers, JS-click caution |
| TimeoutException & NotInteractable | Wait conditions, element state |
| SessionNotCreatedException | Driver/browser version mismatch |
| NullPointerException | PageFactory, initElements(), ThreadLocal |
| ClassNotFound vs NoClassDefFound | Classpath, static init failures |
| Cucumber Ambiguous & Undefined Steps | Glue paths, duplicate step definitions |
| Passes Locally, Fails in Jenkins | Headless, viewport, CI data |
Related
- Complete Selenium Guide — the full learning path
- Selenium Waits — the fix for most of these
- Scenario-Based Questions — real-world failures
- Complete Jenkins Guide — CI/CD