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. 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. The useful answer is neither.

The honest position holds two ideas at once. Selenium is not the right default for a new project. It is also not going anywhere. Holding both of those at once is the signal. Below are six questions I’d actually expect in a Selenium loop. The answers 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). They 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. The old protocol left subtle cross-browser behavioral drift wherever a translation happened. Day to day this shows up as W3C-shaped capabilities. Vendor-specific options carry a prefix like goog:chromeOptions. Timeouts are 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. It is not 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, it matters. “Governed by a spec, not a company” is a real argument. 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 is WebDriverWait paired with ExpectedConditions. It 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. It can also ignore specified exceptions while it polls. That makes it 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. 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. 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. Drop 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. Run tests in parallel against a shared or static driver, and threads overwrite each other’s session. You get failures that look like flake. They 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. A driver left sitting in the ThreadLocal leaks into whatever test lands on that thread next. That test 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. 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. That 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. That 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. Use 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. 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. Some candidates answer this with “I catch the exception and retry.” They 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. It uses @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. That 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. It was moved out of the core bindings to the community-run DotNetSeleniumExtras packages. There 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. The people who say so are usually comparing it to Playwright on a greenfield JavaScript project. That 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. It is the only one of the three major options with a Ruby binding, so a polyglot shop has no real alternative. Appium dominates native mobile automation, and it 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. 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. 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.