Master Selenium 4: Replace DesiredCapabilities with Options and Unlock New Actions

This guide explains Selenium 4's deprecation of DesiredCapabilities, shows how to use Options for Chrome, Firefox, IE and Safari, demonstrates the updated Actions API for clicks, double‑clicks, right‑clicks and drag‑and‑drop, and details the FluentWait syntax changes with code examples.

FunTester
FunTester
FunTester
Master Selenium 4: Replace DesiredCapabilities with Options and Unlock New Actions

Deprecation of DesiredCapabilities

In Selenium 3 DesiredCapabilities was used with RemoteWebDriver to configure browser features. Selenium 4 replaces it with browser‑specific Options objects (e.g., ChromeOptions, FirefoxOptions) that are passed directly to the driver constructor.

Chrome Options

Remote (Cloud)

import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
import java.net.MalformedURLException;

ChromeOptions options = new ChromeOptions();
options.setAcceptInsecureCerts(true);
options.setCapability("build", "Testing Chrome Options [Selenium 4]");
options.setCapability("name", "Testing Chrome Options [Selenium 4]");
options.setCapability("platformName", "Windows 10");
options.setCapability("browserName", "Chrome");
options.setCapability("browserVersion", "latest");

try {
    driver = new RemoteWebDriver(
        new URL("http://" + username + ":" + access_key + "@hub.lambdatest.com/wd/hub"),
        ((Capabilities) options));
} catch (MalformedURLException e) {
    System.out.println("Invalid grid URL");
}

driver.get("https://www.lambdatest.com");

Local

import org.openqa.selenium.chrome.ChromeOptions;

ChromeOptions options = new ChromeOptions();
options.setAcceptInsecureCerts(true);

driver = new ChromeDriver(options);

driver.get("https://www.lambdatest.com");

Firefox Options

Remote (Cloud)

import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
import java.net.MalformedURLException;

FirefoxOptions options = new FirefoxOptions();
options.setAcceptInsecureCerts(true);
options.setCapability("build", "Testing Firefox Options [Selenium 4]");
options.setCapability("name", "Testing Firefox Options [Selenium 4]");
options.setCapability("platformName", "Windows 10");
options.setCapability("browserName", "Firefox");
options.setCapability("browserVersion", "68.0");

try {
    driver = new RemoteWebDriver(
        new URL("http://" + username + ":" + access_key + "@hub.lambdatest.com/wd/hub"),
        ((Capabilities) options));
} catch (MalformedURLException e) {
    System.out.println("Invalid grid URL");
}

driver.get("https://www.lambdatest.com");

Local

import org.openqa.selenium.firefox.FirefoxOptions;

FirefoxOptions options = new FirefoxOptions();
options.setAcceptInsecureCerts(true);

driver = new FirefoxDriver(options);

driver.get("https://www.lambdatest.com");

FindsBy Interface

The FindsBy interface in org.openqa.selenium.internal is deprecated in Selenium 4. Users should continue to use the standard driver.findElement(By…) and driver.findElements(By…) methods.

WebElement email = driver.findElement(By.id("email"));
WebElement password = driver.findElement(By.name("password"));
WebElement submitBtn = driver.findElement(By.xpath("//input[@value='submit']"));

List<WebElement> signUpForm = driver.findElements(By.className("cell-body-textinput"));
List<WebElement> address = driver.findElements(By.name("Address"));

New Actions API in Selenium 4

The Actions class now provides direct element‑specific methods, eliminating the need for separate moveToElement(...) calls.

Left Click

public void testLeftClick() throws InterruptedException {
    driver.navigate().to("https://www.amazon.in/");
    driver.manage().window().maximize();
    Actions action = new Actions(driver);
    WebElement searchBox = driver.findElement(By.cssSelector("#twotabsearchtextbox"));
    action.sendKeys(searchBox, "iphone").perform();
    WebElement goBtn = driver.findElement(By.xpath("//input[@value='Go']"));
    Thread.sleep(5000);
    action.click(goBtn).perform();
    Thread.sleep(5000);
    assertEquals(driver.getTitle(), "Amazon.in : iphone");
}

Double Click and Right Click

public void testDoubleRightClick() throws InterruptedException {
    driver.navigate().to("https://www.amazon.in/");
    driver.manage().window().maximize();
    Actions action = new Actions(driver);
    WebElement mobilesLink = driver.findElement(By.xpath("//a[.='Mobiles']"));
    action.doubleClick(mobilesLink).perform();
    Thread.sleep(5000);
    assertEquals(driver.getTitle(), "Mobile Phones: Buy New Mobiles Online at Best Prices in India | Buy Cell Phones Online - Amazon.in");
    driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
    action.contextClick().perform();
}

Drag and Drop

public void testDragAndDrop() throws InterruptedException {
    driver.navigate().to("https://selenium08.blogspot.com/2020/01/click-and-hold.html");
    driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
    driver.manage().window().maximize();
    Actions action = new Actions(driver);
    WebElement source = driver.findElement(By.xpath("//li[text()='C']"));
    WebElement target = driver.findElement(By.xpath("//li[text()='A']"));
    action.clickAndHold(source).release(target).perform();
    Thread.sleep(2000);
}

FluentWait Changes

In Selenium 4 the withTimeout and pollingEvery methods accept a single java.time.Duration argument instead of separate numeric and TimeUnit parameters.

Selenium 3 Example

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
        .withTimeout(60, SECONDS)
        .pollingEvery(2, SECONDS)
        .ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(By.id("foo"));
    }
});

Selenium 4 Example

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
        .withTimeout(Duration.ofSeconds(120))
        .pollingEvery(Duration.ofMillis(2000))
        .ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(By.id("foo"));
    }
});
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaAutomationtestingSeleniumActionsWebDriverFluentWait
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.