skip to content

In Selenium 4, what replaces the Selenium 3 DesiredCapabilities object when you start a local Chrome session?

level: juniorimportance: must knowfreq 78%

answer

  1. Selenium 4 configures sessions per browser
  2. One object per browser, not a shared bag
  3. The class name ends in Options
  4. ChromeOptions, FirefoxOptions, EdgeOptions
  5. Pass it straight to the driver constructor

basics

~10 s

A browser Options object. In Selenium 4 you build ChromeOptions, FirefoxOptions or EdgeOptions and pass it to the driver constructor; DesiredCapabilities is no longer how a local session is configured.

solid answer

~40 s

In Selenium 4 you configure a session with a browser `Options` object: `ChromeOptions`, `FirefoxOptions`, `EdgeOptions` or `SafariOptions`. You build one, set what the test needs on it — `addArguments("--window-size=1440,900")` for a switch, `setAcceptInsecureCerts(true)`, `setPageLoadStrategy(...)` — and hand it straight to the driver with `new ChromeDriver(options)`. Each Options class implements `Capabilities`, so the same object satisfies any API that asks for capabilities, and the browser-specific parts are serialised under the right prefixed key without you spelling it out. `DesiredCapabilities` still exists as a plain capability bag and Selenium 3 code that builds one still compiles, which is why the old shape survives an upgrade and only fails when the session starts. If a standard capability arrives from configuration, merge it with `options.merge(caps)` and pass the Options object on.

code

java · 22 lines
java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ListingFilterTest {

    public static void main(String[] args) {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--window-size=1440,900");
        options.setAcceptInsecureCerts(true);
        WebDriver driver = new ChromeDriver(options);
        try {
            driver.get("https://homes.example.com/search");
            driver.findElement(By.id("min-bedrooms")).sendKeys("3");
            driver.findElement(By.id("apply-filters")).click();
            System.out.println(driver.findElements(By.className("listing-card")).size());
        } finally {
            driver.quit();
        }
    }
}

go deeper

for a junior

Recall the three names you will meet daily, ChromeOptions, FirefoxOptions and EdgeOptions, and that one of them goes into the driver constructor. Being able to write six lines that start a configured Chrome session is the bar here.

for a middle

Explain that each Options class is a Capabilities implementation, what its typed setters produce in the session request, and why Selenium 3 DesiredCapabilities code still compiles yet fails the moment a session starts.

for a senior

Show that you would centralise session configuration in one factory the whole suite calls, and that you can migrate capabilities arriving from configuration files without leaving invalid key names behind in them.

for a principal

Be ready to argue what belongs in code versus configuration for browser setup across several teams, and how you prevent each team inventing its own capability keys that only fail in someone else's pipeline.

## What an Options object is In **Selenium 4** you configure a browser session with a browser-specific **Options** object rather than a generic capability bag. `ChromeOptions`, `FirefoxOptions`, `EdgeOptions` and `SafariOptions` are ordinary Java objects with typed setters; you build one, set what the session needs, and pass it to the driver constructor. For a **real-estate listing-filter** test that means the window size, the certificate policy and any browser switch live in one object built once, not in a map of strings assembled per test. Each of these classes is also a `Capabilities` implementation. `ChromeOptions` extends `ChromiumOptions`, which extends `AbstractDriverOptions`, which extends `MutableCapabilities` — so anywhere the Selenium API asks for capabilities, an Options object satisfies it. That is the shape of the whole migration: a typed builder that is still usable through the untyped interface. ## The ones you will actually use | Browser | Options class | Prefixed bucket it produces | |---|---|---| | Chrome | `ChromeOptions` | `goog:chromeOptions` | | Firefox | `FirefoxOptions` | `moz:firefoxOptions` | | Edge | `EdgeOptions` | `ms:edgeOptions` | | Safari | `SafariOptions` | `safari:` prefixed keys | You never write those bucket names yourself. Adding a Chrome switch with `options.addArguments("--window-size=1440,900")` is what puts it in the Chrome bucket; that is the value of the typed API over hand-assembled strings. ## What the setters give you - **Typed standard setters** — `setAcceptInsecureCerts(boolean)`, `setPageLoadStrategy(...)`, `setBrowserVersion(String)` — write the standard W3C capability names, and cannot misspell them. - **`addArguments(String...)`** on `ChromeOptions`, `FirefoxOptions` and `EdgeOptions` passes command-line switches to the browser process itself. A switch is not a capability; it is browser configuration carried inside the browser-specific bucket. - **`FirefoxOptions.addPreference(String, Object)`** does the equivalent job for Firefox preferences. - **`setBinary(...)`** points at a specific browser executable when the default is not the one you want. - **`setCapability(String, Object)`** is still there for anything with no typed setter, and it is the one call in this list that can produce an invalid name. ## Doing the migration 1. Find the driver factory. A Selenium 3 suite almost always has one place that builds capabilities and constructs the driver; that is the only file most upgrades need to touch. 2. Replace the `DesiredCapabilities` bag with the Options class for the browser it starts. 3. Move each key onto a typed setter, one at a time. Browser switches become `addArguments`; standard capabilities become their typed setter. 4. Pass the object to the constructor: `new ChromeDriver(options)`. 5. Run one listing-filter test, then delete the now-unused `DesiredCapabilities` import so nobody copies the old shape back in. ```java ChromeOptions options = new ChromeOptions(); options.addArguments("--window-size=1440,900"); options.setAcceptInsecureCerts(true); WebDriver driver = new ChromeDriver(options); driver.get("https://homes.example.com/search?minBeds=3&maxPrice=450000"); ``` ## What happened to DesiredCapabilities It still exists. `DesiredCapabilities` in Selenium 4 is a mutable capability bag, and Selenium 3 code that builds one compiles unchanged against the Selenium 4 client. What is gone is its **role**: it is no longer how you configure and start a browser session. That distinction matters during an upgrade, because it explains a confusing symptom — the build is green and every test still fails at the session request. The check moved out of the compiler and into the new-session call. If a legitimate standard capability arrives from outside your code — a value read from configuration, say — you do not have to abandon the typed object to carry it. Build the Options object, then merge the bag into it and pass the Options object on: - `options.merge(caps);` folds the entries of a `Capabilities` instance into the Options object. - After merging, the Options object is still the thing you construct the driver with. - Anything in that bag with a non-standard, unprefixed name will still be refused, so merging is a way to carry values across, not a way to keep old key names alive. ## Mistakes that survive compilation - Setting a Chrome switch with `setCapability("chromeOptions", ...)` instead of `ChromeOptions.addArguments(...)`. It compiles; it does not start a session. - Assuming one Options class covers every browser. `EdgeOptions` and `ChromeOptions` are both Chromium-based, but Firefox and Safari have their own classes, and a suite that runs several browsers needs a factory that returns the right one. - Treating the upgrade as a dependency bump. Changing the version in the build file is the smallest part; the driver factory is where the actual work is. - Building a fresh Options object per test and drifting between them, so two listing-filter tests quietly run with different window sizes.

  • Why can a ChromeOptions object be used anywhere the Selenium API asks for capabilities?
    Because `ChromeOptions` extends `MutableCapabilities` and therefore implements `Capabilities`. The typed builder and the untyped interface are the same object, which is what makes the migration cheap: you build configuration once with setters that cannot misspell a key, and pass it wherever capabilities are wanted.
  • A Selenium 3 suite reads capability names out of a properties file. What changes at upgrade?
    That file becomes a source of invalid keys no compiler can check. Map each entry onto a typed Options setter, keep only genuinely standard capability names as free-form strings, and move anything browser-specific into the Options object. Otherwise the suite fails at the session request with a key that never appears in code.
  • Does DesiredCapabilities still exist in Selenium 4?
    Yes, as an ordinary mutable capability bag, and old code that builds one compiles unchanged. What is gone is its role as the way to configure a browser session. Keys it carries are validated when the session request is made, so the failure moves from build time to run time.

saying these in an interview costs you the question

  • Believes DesiredCapabilities was deleted from Selenium 4 entirely
  • Sets Chrome switches with setCapability rather than ChromeOptions.addArguments
  • Thinks one Options class covers every browser the suite drives
  • Says the upgrade only needs a new dependency version and no code change
  • Confuses browser command-line switches with W3C capabilities