Selenium Interview Questions (with Sample Answers)

Six Selenium interview questions with sample answers for 2026 QA and SDET loops, including the parallelism trap that separates seniors from tutorial readers.

Most candidates walk into a Selenium question with one of two prepared attitudes, and both of them lose. The first is nostalgia: Selenium is the industry standard, it has been around since 2004, everything else is a fad. The second is dismissal: nobody starts new projects on Selenium, it’s slow, Playwright won. An interviewer asking about Selenium in 2026 is usually checking which of those two reflexes you reach for, because the useful answer is neither.

The honest position is that Selenium is not the right default for a new project and is also not going anywhere, and holding both of those at once is the signal. Below are six questions I’d actually expect in a Selenium loop, with the answers that separate someone who has maintained a WebDriver suite from someone who has read about one. This is one spoke of the 2026 QA & SDET interview questions guide; if you want the framework comparison instead, that’s Playwright vs Cypress vs Selenium.

Version details below are current as of Selenium 4.46 (July 2026) and move quickly, so treat them as a snapshot.

Fundamentals

What changed in Selenium 4, and why does W3C compliance matter?

Selenium 4 dropped the legacy JSON Wire Protocol and became fully W3C WebDriver compliant. There is no longer a translation layer sitting between the client binding and the browser driver. The client speaks a standardized protocol that every compliant driver interprets identically, where the old protocol left subtle cross-browser behavioral drift wherever a translation happened. Day to day this shows up as W3C-shaped capabilities, with vendor-specific options carrying a prefix like goog:chromeOptions, and timeouts expressed as a Duration.

The part worth saying out loud is the longevity argument. Selenium’s protocol is a W3C standard governed by a specification that browsers implement, rather than one company’s internal API. That is the durable contrast with Playwright, which drives Chromium through an extended DevTools Protocol originating with a single vendor. For everyday testing the difference is small and you should say so. For a decision about what an enterprise standardizes on for the next ten years, “governed by a spec, not a company” is a real argument, and knowing that is what separates a considered answer from “Selenium is old.”

Implicit, explicit, and fluent waits: when do you use each?

An implicit wait is global. You set it once on the driver and it applies a polling timeout to every element lookup. An explicit wait, WebDriverWait paired with ExpectedConditions, waits for a specific condition on a specific element, which is what you want for anything dynamic. A fluent wait is an explicit wait with a configurable polling interval and the ability to ignore specified exceptions while it polls, which is the tool for a value that flickers through transient states while a single-page app re-renders it.

The anti-pattern is mixing implicit and explicit waits, and this is the fastest filter in the question. Both mechanisms poll. Combine them and the implicit timeout leaks into the explicit wait’s internal element lookups, so your effective timeouts become unpredictable and roughly additive. You get waits that feel wrong and slowdowns nobody on the team can explain. The current guidance is to set the implicit wait to zero and drive everything through explicit waits, dropping to a fluent wait only when you need a custom cadence or need to swallow a stale-element exception between polls.

Practical scenarios

How do you run a Selenium suite in parallel without corrupting sessions?

A WebDriver instance is not thread-safe. The moment you run tests in parallel against a shared or static driver, threads overwrite each other’s session and you get failures that look like flake, only reproduce under load, and never reproduce on your laptop. The fix is to give each thread its own driver behind a ThreadLocal:

public final class DriverFactory {
    private static final ThreadLocal<WebDriver> TL = new ThreadLocal<>();
    public static void init()     { TL.set(new ChromeDriver()); }
    public static WebDriver get() { return TL.get(); }
    public static void quit()     { if (TL.get() != null) { TL.get().quit(); TL.remove(); } }
}

The detail that signals experience is in the teardown. You call remove() on the ThreadLocal, not just quit() on the driver. Test frameworks reuse pooled threads, and a driver left sitting in the ThreadLocal leaks into whatever test lands on that thread next, which inherits a dead session and fails for reasons that have nothing to do with the code under test.

The other half of the answer is capacity. Your TestNG thread-count has to match the slots your Selenium Grid actually has, because eight threads against four browser slots simply queues four of them and buys you nothing. If you can also explain why Playwright sidesteps this hazard by design through process isolation, you have turned a Selenium question into a cross-framework answer, which is usually where the interviewer wanted to end up.

How do you handle Shadow DOM, iframes, and stale elements?

Shadow DOM got first-class support in Selenium 4. element.getShadowRoot() returns a search context you query with CSS selectors, which retired the old JavaScript-executor workaround. Two caveats are worth naming: only CSS selectors work inside a shadow root, and closed roots still require JavaScript. Iframes use driver.switchTo().frame(...) by name, index, or element reference, with defaultContent() to climb back out.

The one that catches people is StaleElementReferenceException. It means the element handle you are holding points at a DOM node that has since detached, because the page reloaded or a single-page app re-rendered between the moment you located the element and the moment you used it. The correct handling is not a try-catch reflex. It is to stop caching element references across anything that mutates the DOM, and to re-locate at the point of use. Wrap the recovery in ExpectedConditions.refreshed(...) when you genuinely need it. Candidates who answer this with “I catch the exception and retry” are describing a symptom management strategy; candidates who answer “I stopped holding references across renders” are describing a fix.

Senior signals

Do you still use PageFactory?

No, and being able to explain why is a senior signal.

The Page Object Model itself is sound: one class per page holding its locators and actions, so tests speak in methods rather than selectors. PageFactory is a specific implementation of that idea, @FindBy annotations plus PageFactory.initElements, which creates lazy element proxies. Its proxies re-find an element only on first access, so on any app that re-renders you still hit stale-element exceptions, which is exactly the failure the pattern appeared to promise to hide. It also buries locators behind reflection and composes badly with explicit waits.

The status differs by binding, and knowing that is a good detail to carry in. In .NET, PageFactory has been deprecated since Selenium 3.11 and was moved out of the core bindings to the community-run DotNetSeleniumExtras packages, where it survives on community maintenance rather than as part of Selenium proper. In Java it still ships and still works, but it is discouraged rather than removed. Either way the recommendation is the same: keep the Page Object, drop PageFactory, store By locators rather than WebElement fields, and re-locate fresh inside each wait-wrapped method. Page Objects yes, PageFactory no.

Is Selenium dying?

No, and the people who say so are usually comparing it to Playwright on a greenfield JavaScript project, which is the single context where Selenium is genuinely the wrong pick.

Widen the frame and it looks different. Selenium has the broadest language bindings of any browser automation tool and is the only one of the three major options with a Ruby binding, so a polyglot shop has no real alternative. Appium, which dominates native mobile automation, is built on the WebDriver protocol, so a team standardized on Selenium gets web and native mobile under one protocol and one set of patterns. And if you are an enterprise with a ten-thousand-test suite that works, “rewrite it in Playwright” is a two-year project with no new features at the end of it.

Where Selenium loses is equally clear, and you should say this part too rather than sounding like an advocate. It carries more setup overhead than Playwright even after Selenium Manager closed most of the driver-management gap. It has no built-in auto-waiting, so naive suites flake more. It is generally slower because of its per-command round trips, though WebDriver BiDi is narrowing that.

How to prepare

If your loop is Selenium-specific, the prep that pays:

  • Run a suite in parallel until it breaks. Set up four threads against a shared driver, watch the sessions corrupt, then fix it with ThreadLocal. One afternoon of this gives you a better answer to the parallelism question than any amount of reading, because you will have seen the failure mode.
  • Set your implicit wait to zero on an existing project and convert the failures to explicit waits. You will find the timeout interactions faster than you expect.
  • Know your Grid’s capacity numbers. Interviewers ask “how many tests can you run at once” and expect you to reason from node slots rather than guess.
  • Have the verdict rehearsed. Practice saying where Selenium wins and where it loses in about ninety seconds, without drifting into either nostalgia or dismissal.

Structured practice on the framework itself: Udemy’s Selenium courses cover the Grid and parallelization surface faster than assembling it from official docs.