QA
Mid-level QAFrameworks & Design PatternsFree question

How do you build a driver factory for cross-browser and remote execution?

60-second answer

A driver factory is a class, following the factory pattern, that creates the right WebDriver based on configuration, so tests never call new ChromeDriver directly. It reads the browser name, headless flag and execution mode, local or remote, builds the matching options, and returns either a local driver or a RemoteWebDriver pointing at Selenium Grid or a cloud provider like BrowserStack. Adding a new browser or environment then means changing one class. Combined with a ThreadLocal manager, it supports parallel cross-browser runs.

Explanation

  • Input: browser (chrome, firefox, edge, safari), headless, remote URL, platform/version capabilities.
  • Output: configured WebDriver.
  • Keep common options (window size, timeouts, downloads) in one place.
  • For cloud providers, add vendor capabilities (bstack:options) from environment variables.

Example

mvn test -Dbrowser=firefox -Dremote=http://grid:4444 runs the same suite on the Firefox nodes of our Docker Grid.

Sample code

public final class DriverFactory {
    public static WebDriver create(String browser) {
        boolean headless = Boolean.parseBoolean(Config.get("headless"));
        MutableCapabilities options = switch (browser.toLowerCase()) {
            case "firefox" -> { var o = new FirefoxOptions(); if (headless) o.addArguments("-headless"); yield o; }
            case "edge"    -> { var o = new EdgeOptions();    if (headless) o.addArguments("--headless=new"); yield o; }
            default        -> { var o = new ChromeOptions();  if (headless) o.addArguments("--headless=new");
                                o.addArguments("--window-size=1920,1080"); yield o; }
        };
        String remote = Config.get("remote");
        try {
            return remote != null && !remote.isBlank()
                ? new RemoteWebDriver(new URL(remote), options)
                : switch (browser.toLowerCase()) {
                    case "firefox" -> new FirefoxDriver((FirefoxOptions) options);
                    case "edge"    -> new EdgeDriver((EdgeOptions) options);
                    default        -> new ChromeDriver((ChromeOptions) options);
                };
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("Bad remote URL: " + remote, e);
        }
    }
}