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.
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"));
}
});Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
