How does Selenium's shared W3C error code help you triage a failure another language's client reported?
answer
- One report, two spellings
- Normalise before you compare
- The wire names the condition
- Suffix conventions differ by binding
- Client-side give-ups have no remote code
basics
~20 sThe remote end names every failure with the same fixed code whatever client asked, so mapping both reports back to that code tells you immediately whether two suites hit one browser-side condition or two different problems.
solid answer
~40 sSelenium's remote end reports failures using a fixed list of W3C error codes such as `no such element`, `element click intercepted` and `stale element reference`. That code does not depend on the client; only the class it is raised as does. So a Ruby report of `Selenium::WebDriver::Error::ElementClickInterceptedError` and a Java report of `ElementClickInterceptedException` are the same browser-side condition, and the binding is eliminated as a suspect straight away. Watch the naming conventions: Java, Python and C# use an `Exception` suffix while Ruby and JavaScript use `Error`, and the C# wait timeout is spelled `WebDriverTimeoutException`. Also separate remote failures from client-side ones — a wait that gave up in your own process has no server-side code behind it.
code
java · 18 linesimport org.openqa.selenium.By;
import org.openqa.selenium.ElementClickInterceptedException;
import org.openqa.selenium.WebDriver;
public final class AppointmentBooking {
private AppointmentBooking() {
}
public static String bookFirstFreeSlot(WebDriver driver) {
try {
driver.findElement(By.cssSelector("#appointment-grid .slot--free")).click();
return "booked";
} catch (ElementClickInterceptedException e) {
return e.getMessage();
}
}
}go deeper
Recall that Selenium failures carry a standard name such as no such element, and that this name is the same whichever language reported it. Recognise the common codes when you see them.
Explain the mapping: the remote end returns a code string, and each client wraps that code in its own exception type, so the class name changes across bindings while the code does not.
Show the triage. Normalise both reports to the code, use the driver's message to locate the obstruction, separate client-side give-ups from remote failures, and only then compare the two suites' own code and timing.
Push it into practice across teams: standardise on reporting the error code in failure output so cross-language suites are comparable, and stop teams from re-diagnosing one condition twice under two names.
## Two names, one failure Selenium's remote end reports a failure by naming it with a **fixed string code** drawn from the W3C WebDriver error list — `no such element`, `stale element reference`, `element click intercepted`, `element not interactable`, `no such window`, `no such frame`, `invalid selector`, `timeout`, `session not created`, `invalid session id`, `javascript error` and the rest. That code does not depend on which client asked. What depends on the client is the **class the code is raised as** in your own code. That single fact is the whole triage technique. When the Ruby suite for the **veterinary appointment book** reports `Selenium::WebDriver::Error::ElementClickInterceptedError` on the confirm button and the Java suite reports `ElementClickInterceptedException` on the same button, those are not two different bugs to investigate. They are one browser-side condition — something is covering the element at the point the click would land — reported through two different local wrappers. ## The mapping, client by client | Error code | Java and Python | C# | Ruby | JavaScript | |---|---|---|---|---| | `no such element` | `NoSuchElementException` | `NoSuchElementException` | `Error::NoSuchElementError` | `error.NoSuchElementError` | | `stale element reference` | `StaleElementReferenceException` | `StaleElementReferenceException` | `Error::StaleElementReferenceError` | `error.StaleElementReferenceError` | | `element click intercepted` | `ElementClickInterceptedException` | `ElementClickInterceptedException` | `Error::ElementClickInterceptedError` | `error.ElementClickInterceptedError` | | `timeout` | `TimeoutException` | `WebDriverTimeoutException` | `Error::TimeoutError` | `error.TimeoutError` | Two patterns fall out of that table: - **Suffix convention differs.** Java, Python and C# end the type name in `Exception`; Ruby and JavaScript end it in `Error`. Nothing behavioural rides on that. - **A few names are not mechanical translations.** The C# client's wait timeout is spelled `WebDriverTimeoutException`, so a candidate grepping a C# stack trace for `TimeoutException` may conclude wrongly that the failure is unrelated. - **Every binding also has a base type** that all of these inherit from, so a catch-all handler exists in each language even where the specific names differ. ## Triaging a cross-language report 1. **Extract the code, not the class.** Read the failure name back to its W3C code before you compare anything. `NoSuchElementError` and `NoSuchElementException` are both `no such element`. 2. **Compare the message and the command.** The message text is written by the driver, so two clients hitting the same condition on the same browser version produce closely comparable text — that is where the intercepting element or the offending selector is named. 3. **Ask whether the failure is remote or local at all.** A wait that gave up in your own process is raised by the client, not returned by the remote end; there is no server-side code behind it, and comparing it to a remote failure is a category error. 4. **Only then compare the two suites' code.** If the codes match, the difference is in the page, the data or the timing of the two tests, not in the binding. ## A worked example The Python suite books the 09:20 consultation reliably; the Java suite fails intermittently on the same environment. Both failures reduce to `element click intercepted`. Because the code is identical, the binding is not the variable — and the investigation moves to what differs in the two tests: the Java run maximises the window later, so a sticky clinic-hours banner is still overlapping the confirm button when the click lands. The fix belongs in the Java test, and it would have been invisible to anyone comparing exception class names. ## The misreading to avoid The error code is a name for a **condition**, not a diagnosis of a cause. `no such element` means the remote end could not find a match at the moment it looked; it does not say whether the selector is wrong, the page had not rendered, or the search ran in the wrong frame. Parity gets you as far as "the same thing happened to both clients" — genuinely valuable, because it eliminates the binding as a suspect immediately — and no further.
- Two suites in different languages report the same error code. What do you investigate next?The tests, not the bindings. Since the condition is identical, the difference lies in the page state, the data or the timing each suite creates: window size, when the run navigates, which fixture it seeded. Compare the driver's message text too, because it usually names the intercepting element or the offending selector.
- Is every Selenium exception the result of a remote error code?No. Some are raised entirely in the client, most commonly when a wait gives up before its condition held. There is no server-side code behind those, so comparing them with a remote failure is a category error and will send the investigation in the wrong direction.
- How far does the error code take you toward a root cause?It names a condition, not a cause. A no such element result means the remote end found no match at the instant it looked; it does not say whether the selector is wrong, the page had not rendered, or the search ran in the wrong frame. It eliminates the binding as a variable and narrows the search.
saying these in an interview costs you the question
- Treats different exception names as different bugs
- Assumes error codes are invented by each client
- Reads the error code as a root-cause diagnosis
- Greps a C# trace for TimeoutException and finds nothing
- Confuses a client-side wait give-up with a remote failure