In Selenium 4, why can one test body drive Chrome, Firefox, Edge and Safari without a rewrite?
answer
- The same commands go to every driver
- One published specification, several implementations
- Only start-up differs, not the steps
- Each vendor ships its own driver
- Driver class plus options class
basics
~20 sBecause every one of those browsers is automated through the same W3C WebDriver command set. Only the driver and options objects built at start-up differ; finding elements, clicking, reading text and waiting are identical calls.
solid answer
~40 sSelenium 4 speaks the **W3C WebDriver** protocol, and each browser vendor ships a driver that implements it: `chromedriver`, `geckodriver`, `msedgedriver` and `safaridriver`. Because the command set is shared, the only browser-specific code in a lineup-planner suite is the pair of lines that build a driver — `new ChromeDriver(new ChromeOptions())` versus `new FirefoxDriver(new FirefoxOptions())` and so on. Everything after that is the same: locators, clicks, `getText()`, waits and assertions. The honest limits are that a browser with no conformant driver is not covered, some targets are tied to an operating system, and cross-browser rendering differences can still fail a test — which is usually the point of running it.
code
java · 8 linespublic static WebDriver driverFor(String browser) {
return switch (browser) {
case "firefox" -> new FirefoxDriver(new FirefoxOptions());
case "edge" -> new EdgeDriver(new EdgeOptions());
case "safari" -> new SafariDriver(new SafariOptions());
default -> new ChromeDriver(new ChromeOptions());
};
}go deeper
Be ready to name the four driver and options pairs and to say that the rest of the test is identical, because every browser is automated through the same standard command set.
Explain the mechanism: a specification each vendor driver implements, vendor-specific capabilities only at session creation, and start-up arguments as the one part that is not portable.
Show where portability stops in practice — platform-bound targets, layout and timing differences that surface real defects, and uneven support for newer standard surfaces — and keep conditionals out of test bodies.
Own the matrix decision: a shared body makes extra browsers cheap to write but not cheap to run, so decide how wide the matrix is and what evidence justifies each extra engine.
## One protocol underneath four browsers **Selenium 4** is a client for the **W3C WebDriver** protocol — a published specification for automating a browser from outside it. Each browser vendor ships a **driver** implementing that specification for their own browser: `chromedriver` for Chrome, `geckodriver` for Firefox, `msedgedriver` for Edge and `safaridriver` for Safari. Your test never talks to the browser; it sends commands such as *find element*, *click element* and *get element text* to the driver, and the driver does the browser-specific work behind that shared vocabulary. That is the entire reason one lineup-planner test body covers four browsers. The command your code sends to open the Saturday stage grid is the same command whichever driver receives it. ## What changes between browsers, and what does not | What | Changes per browser? | |---|---| | Driver class (`ChromeDriver`, `FirefoxDriver`, `EdgeDriver`, `SafariDriver`) | Yes | | Options class (`ChromeOptions`, `FirefoxOptions`, `EdgeOptions`, `SafariOptions`) | Yes | | Start-up arguments and profile preferences | Yes, these are vendor-specific | | Locators and find calls | No | | Clicks, typing, reading text and attributes | No | | Waits, page objects and assertions | No | So the browser-specific surface of a suite is small and concentrated. Everything a reviewer would call *the test* is browser-agnostic: - the locator that reaches the 21:00 slot on the Saturday stage, - the click that adds that act to a personal plan, - the wait for the plan panel to show the new entry, - the assertion that the plan now lists exactly one act at 21:00, - the page object modelling the stage grid, which knows nothing about which driver opened the session. A useful check when reviewing a change: if a diff that adds a browser touches anything beyond the driver factory and its configuration, the suite has probably grown a browser-specific branch that will drift. What a reviewer reads in a test should describe the lineup planner, not the engine rendering it. ## Where the driver binary comes from The driver is a separate executable, and since Selenium 4.6 the bundled **Selenium Manager** resolves a matching one automatically when no driver path is configured, so a first run on a new machine usually needs no manual download. Safari is the exception worth remembering: its driver is part of the Safari installation on macOS rather than something fetched per project. ## Where the portability claim honestly stops Being able to send the same commands is not the same as everything behaving identically. Be ready to name the limits: 1. **No driver, no coverage.** A browser whose vendor ships no conformant driver is simply not a Selenium target, however popular it is. 2. **Some targets are pinned to a platform.** Safari runs on macOS; Internet Explorer mode runs in Microsoft Edge on Windows. Portable test code still needs the right host. 3. **Rendering and timing differ.** A layout difference can move an element out of reach, and a slower engine can expose a race the fast one hid. These failures are usually real findings about the planner, not tooling noise. 4. **Newer surfaces arrive unevenly.** Standard additions such as **WebDriver BiDi** land browser by browser, so a shared harness should not depend on something only one family supports. 5. **Start-up options are not portable.** Command-line arguments and profile preferences belong to a specific browser, which is exactly why they live in that browser's options class and nowhere else. ## Structuring the planner suite for it The practical shape is a factory: one method returns a `WebDriver` for a browser name read from configuration, and every case takes the driver it is given. ```java WebDriver driver = driverFor(System.getProperty("browser", "chrome")); driver.get("https://lineup.example.test/2026/saturday"); ``` Two rules keep that honest. First, no `if (browser.equals("firefox"))` inside a test body — a conditional there means the suite has quietly become several different descriptions of the product. Second, keep the browser-specific arguments inside the factory, so adding a fifth target is one new branch in one file rather than an edit across the suite. ## What an interviewer is listening for At this level the expected answer is the shared protocol plus vendor drivers, stated plainly, with the observation that only driver construction is browser-specific. Adding the honest limits — platform-bound browsers, real rendering differences, uneven support for newer features — is what separates a memorised slogan from an answer that shows you have actually run a suite on more than one engine.
- If the commands are identical, why does each browser still need its own options class?Because start-up configuration is not standardised. Command-line arguments, profile preferences and binary paths are specific to a browser, so each vendor's options object carries its own keys and Selenium sends them under a vendor-prefixed capability. Only the automation commands after the session starts are shared.
- A lineup-planner test passes on Chrome and fails on Firefox. What is your first assumption?That the difference is real. Look at rendering and timing first: an element positioned differently, an overlay covering the click point, or a section that loads later. Only after ruling those out consider a driver-level difference, and never fix it with a browser conditional inside the test body.
- Does one shared test body mean you should run every case on every browser?No. The shared body makes the option cheap, not obligatory. Most teams run the full suite on one primary engine and a narrower path on the others, because each extra browser costs machines, wall-clock time and triage effort that grows with the size of the matrix.
saying these in an interview costs you the question
- Thinks each browser needs its own locator or click API
- Believes Selenium ships and launches its own browser build
- Assumes identical commands guarantee identical behaviour across engines
- Puts browser conditionals inside test bodies instead of the driver factory
- Expects Safari or Internet Explorer mode to run on any operating system