What Is New In Selenium 4 And What Is Deprecated In It?
Tags: selenium, java, automation, testing
Published: 2021-03-01 09:08:00

> This article is a part of our Content Hub. For more in-depth resources, check out our content hub on [Selenium 4](https://www.lambdatest.com/learning-hub/selenium-4?utm_source=dev&utm_medium=Blog&utm_campaign=Himanshu-1032021&utm_term=Himanshu).

Selenium 4 has been gaining immense attention since the time it was publicly announced by Simon Stewart, the founding member of Selenium in August 2018. Though there are no updates on the official release date of a stable version of Selenium 4, developers and Selenium explorers, have the opportunity to try out Selenium 4 features by downloading the [Alpha version of Selenium 4](https://www.selenium.dev/downloads/). So what is new in Selenium 4, and where does Selenium 3 vs. Selenium 4 comparison stand in terms of features?

 ![](https://www.lambdatest.com/blog/wp-content/uploads/2021/01/image8-300x169.gif)

In this blog, we deep dive into what is new in Selenium 4 and analyze some of the ‘awesome’ Selenium 4 Alpha Features. At the time of writing this article, Selenium 4.0.0-alpha-7 was the latest Alpha release of Selenium 4. If you are someone looking to migrate from Selenium 3 to Selenium 4, this blog will act as a guide to understand what is deprecated in Selenium 4. A look at the deprecations in Selenium 4 will help in ensuring that migration from Selenium 3 to Selenium 4 is a lot smoother!

If you are looking out for the Selenium 4 Server (Grid), version v. 4.0.0-alpha-7 can be downloaded from [here](https://selenium-release.storage.googleapis.com/4.0-alpha-7/selenium-server-4.0.0-alpha-7.jar).

 
## What is new in Selenium 4?

Selenium 4 is packed with excellent features like relative locators, improved Selenium Grid architecture, and a super-useful Selenium IDE, to name a few. The most significant under-the-hood change in Selenium 4 is W3C compliance of WebDriver APIs, which boils down to less flaky and more stable cross browser tests.

Excited to try out Selenium 4 (Alpha)?

Here are some of the significant changes that you will experience with Selenium 4:

### Selenium WebDriver W3C Standardization

In Selenium’s earlier versions (i.e., Selenium 3), the JSON Wire Protocol was responsible for communication between the web browser and the test code. This led to the additional overhead of encoding and decoding the API requests using the W3C protocol. This is set to change with WebDriver in Selenium 4, as the WebDriver APIs adopt the W3C standardization.

Since major browser drivers such as geckodriver, chromedriver, etc., follow the W3C standard, the WebDriver in Selenium 4 will directly communicate with the web browser.  
Selenium vs. [WebDriver W3C protocol](https://www.lambdatest.com/blog/selenium4-w3c-webdriver-protocol/) has co-existed along with JSON Wire Protocol; it will be the default protocol in Selenium 4. JSON Wire Protocol will be deprecated in Selenium 4.

The [native support for Opera and PhantomJS](https://www.selenium.dev/selenium/docs/api/javascript/page/Changes.html) is removed in Selenium 4, as their WebDriver implementations are no longer under development. The Opera browser is based on Chromium, and users looking to test their implementation on Opera can opt for testing on the Chrome browser. PhantomJS users can opt for testing on Firefox and Chrome in the headless mode.

WebDriver W3C Protocol is the biggest architectural change that will take effect in Selenium 4, and WebDriver W3C standardization will result in more stable cross browser tests than the previous releases of Selenium!

### Improved and Optimized Selenium Grid

The Selenium Grid, which is used for distributed test execution, is based on the Hub-Node architecture. However, the Hub and Node(s) need to be separately started when performing the automation tests. This will be a thing of the passé, as the Hub and Node are packed in a single jar file. Once the server is started, it acts both as Hub and Node. The earlier releases of Selenium Grid supported Router, Session Map, and Distributor processes. The [Selenium Grid 4](https://www.lambdatest.com/blog/selenium-grid-4-tutorial-for-distributed-testing/?utm_source=dev&utm_medium=Blog&utm_campaign=Himanshu-1032021&utm_term=Himanshu), with a more scalable and traceable infrastructure, supports four processes – Router, Session Map, Distributor, and Node.

The Grid will now support IPV6 addresses, and users can communicate with the Grid using the HTTPS protocol. It would be much easier to use configuration files with the improved Selenium Grid, as users can configure the Grid using human-understandable [TOML (Tom’s Obvious, Minimal Language)](https://github.com/toml-lang/toml) language.

The Grid in Selenium 4 sports an improved user-friendly GUI. The support for [Docker in Selenium Grid 4](https://github.com/SeleniumHQ/docker-selenium) makes it easier to use on Virtual Machines (VMs). Users also have the flexibility of deploying the Selenium Grid on Kubernetes. Selenium Grid 4 can be extremely useful in the DevOps process since it supports tools like AWS, Azure, and more.

The enthusiastic Selenium user-community will keep a close watch on what’s in store with the super-improved [Grid in Selenium 4](https://github.com/SeleniumHQ/selenium/wiki/Selenium-Grid-4).

### Enhanced Selenium 4 IDE

Automation test engineers with the familiarity of record and playback testing would have come across the Selenium IDE. It is a simple turn-key solution that is web-ready and works out of the box. Selenium IDE, which was earlier available only as a Firefox extension, did not have enough exciting features.

With Selenium 4, the Selenium IDE is finally ‘useful,’ as it is available for major web browsers like Chrome and Firefox. The plugin (or web extension) for Selenium IDE is expected to arrive soon on the MS Edge Store.

The Selenium IDE can be used to come up with better tests, as it supports a control-flow mechanism (i.e., usage of if..else, while, etc.). Along with a shiny and user-friendly user interface, Selenium IDE in Selenium 4 also comes with a SIDE tool (Selenium IDE Runner) that lets you run a .side project on a Node.js platform. The SIDE Runner can execute cross browser tests in parallel, either on a local Selenium Grid or a cloud-based Selenium Grid like LambdaTest.  
The backup element locator strategy is followed in scenarios where the web element could not be located using the specified element locator. This makes the tests executed on the Selenium IDE more stable and reliable.

The automation tests recorded using the Selenium IDE can be now be exported as code for all official language bindings like Java, C#, Python, .NET, and JavaScript. This can be useful for black-box testers who want to enter the field of automation testing but have limited implementation knowledge in Selenium! The configuration files (in the .yml format) used by the SIDE runner can be easily customized for realizing parallel testing on the Selenium IDE.

### Enhanced Documentation

The official documentation of Selenium 4 is exhaustive, and the content layout makes it easy to reach the desired information in a few clicks. Since Selenium 4 is still in the Alpha stage, the enhanced documentation helps understand how new features (and APIs) in Selenium 4 can be used in the test code.

[Selenium 4 documentation](https://seleniumhq.github.io/docs/site/en/) covers all the aspects of Selenium Grid 4, Selenium IDE, and WebDiver W3C protocol. Automation testers can use the documentation to get acquainted with the new APIs offered by Selenium 4.

### Simplification to open new browser Windows and Tabs

There are a number of scenarios where you would want to open a new browser (or tab) and perform a certain set of actions in the newly opened window/tab. In Selenium 3, you have to create a new Web Driver object and then switch to the new window (or tab) using its unique WindowHandle to perform subsequent actions in that window (or tab).

Selenium 4 provides a new API newWindow that lets you create a new window (or tab) and automatically switches to it. Since the new window or tab is created in the same session, it avoids creating a new WebDriver object.

For creating a new tab in Selenium 4 and switching to it, pass WindowType.TAB to _newWindow()_ method. For creating a new Window in Selenium 4 and switching to it, pass WindowType.WINDOW to _newWindow()_ method. As each browser window in Selenium has a unique _WindowHandle_ ( or ID ), the required _WindowHandle_ should be passed to the _switchTo().window()_ method to switch between the different windows.

- Open a new Window in Selenium 4

```
driver.get("https://www.google.com/");
// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW);
// Opens LambdaTest homepage in the newly opened window
driver.navigate().to("https://www.lambdatest.com/");
```
 
 
- Open a new Tab in Selenium 4

```
driver.get("https://www.google.com/");
// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.TAB);
// Opens LambdaTest homepage in the newly opened tab
driver.navigate().to("https://www.lambdatest.com/");
```
 

### Relative Locators

In Selenium 3, there was no short-cut (or specific methods) to locate WebElements relative to the nearby elements. The introduction of relative locators is one of the Selenium 4 Alpha features that will ease locating WebElements based on the visual location relative to other DOM elements.

Relative locators, also called Friendly locators, help locate WebElements that are near to, left of, right of, above, and below a specified element. The relative locator methods support the usage with the withTagName (in Selenium 4 Java) or with\_tag\_name (in Selenium 4 Python). Here are the five relative locators that are available in Selenium 4 (Alpha):

| Relative Locator | Description |
| --- | --- |
| above | The required WebElement is ‘above’ a specified (or particular) element. |
| below | The required WebElement is ‘below’ a specified (or particular) element. |
| to\_left\_of | The required WebElement is ‘to the left of’ a specified (or particular) element. |
| to\_right\_of | The required WebElement is ‘to the right of’ a specified (or particular) element. |
| near | The required WebElement is ‘at most 50 pixels’ away from the specified (or particular) element. |

To learn how to use relative locators to locate WebElements relative to a specified element in the DOM, you can refer to our earlier blogs on [Selenium 4 Relative Locator](https://www.lambdatest.com/blog/selenium-4-relative-locator/?utm_source=dev&utm_medium=Blog&utm_campaign=Himanshu-1032021&utm_term=Himanshu) and [Selenium 4 for Python](https://www.lambdatest.com/blog/selenium-with-python/?utm_source=dev&utm_medium=Blog&utm_campaign=Himanshu-1032021&utm_term=Himanshu).

**Monitoring**

Processes related to logging and request tracing are quite optimized in Selenium 4. These optimizations help in accelerating the debugging process, which eventually aid in delivering a better quality test script.

**TakeElementScreenshot**

In Selenium 3, there was a provision to capture a screenshot of the entire web page. Selenium 4 onwards, there is a new option to capture screenshots of a particular WebElement. Hence, there is no need to use third-party tools like Shutterbug, Ashot, etc. (like in Selenium 3) for capturing a screenshot of WebElement.

The newly introduced method in Selenium 4 captures the screenshot of an element for the current browsing context. The screenshot returned by the WebDriver [endpoint](https://www.w3.org/TR/webdriver/#take-element-screenshot) is encoded in the Base64 format.

This is how you can capture WebElement Screenshot in Selenium 4 (for Java):

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;
 
public void test_LambdaTest_take_screenshot() throws IOException
{
    driver.navigate().to("https://accounts.lambdatest.com/login");
    driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
    driver.manage().window().maximize();
 
    try {
        WebElement element = driver.findElement(By.cssSelector(".btn"));
        File scrFile = ((TakesScreenshot)element).getScreenshotAs(OutputType.FILE);
        File dstFile = new File("./loginbutton.png");
        FileUtils.copyFile(scrFile, dstFile);
        Thread.sleep(2000);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}
```

We captured the screenshot of the WebElement’ login button’ on the [LambdaTest Sign-in](https://accounts.lambdatest.com/login) page in the implementation shown above. Shown below is the captured WebElement screenshot:

 ![](https://www.lambdatest.com/blog/wp-content/uploads/2021/01/image1-300x34.png)

The captured screenshot is stored in the location where the Eclipse/IntelliJ IDEA project resides in your machine.

### Chrome DevTools

Selenium 4 (Alpha) provides native support for the Chrome DevTools Protocol through the ‘DevTools’ interface. As the name indicates, the support is available only for the Chrome browser. CDP tools are used to get Chrome Development properties such as Fetch, Application Cache, Network, Performance, Profiler, and more.

Chrome DevTools, a set of web developer tools, provides APIs through which QA engineers and developers can edit pages on-the-fly and diagnose issues faster. These operations help in making websites efficient and quicker.

Chrome DevTools APIs can be used for emulating geolocation and emulating network conditions. We have covered the following topics in Selenium 4 in greater detail:

* [Emulate Geolocation and Network Conditions in Selenium 4 Python](https://www.lambdatest.com/blog/selenium-with-python/?utm_source=dev&utm_medium=Blog&utm_campaign=Himanshu-1032021&utm_term=Himanshu)
* [Emulating Geolocation in Selenium 4 with Java](https://www.lambdatest.com/blog/geolocation-testing-with-selenium-using-examples/?utm_source=dev&utm_medium=Blog&utm_campaign=Himanshu-1032021&utm_term=Himanshu) 

Native support for Chrome DevTools Protocol through the DevTools interface is one of the promising Selenium 4 Alpha Features that would help optimize websites through features like geolocation testing, emulating (or faking) different network conditions, and more.

## What Is Deprecated And Changed In Selenium 4?

The significant enhancements in Selenium 4 are also accompanied by a couple of deprecations in this version of Selenium. It is important to note that only breaking changes in Selenium 4 will impact the test code migration from Selenium 3 to Selenium 4.

The [Selenium 4 changelog (for Java)](https://github.com/SeleniumHQ/selenium/blob/trunk/java/CHANGELOG) and [Selenium 4 changelog (for .NET)](https://github.com/SeleniumHQ/selenium/blob/trunk/dotnet/CHANGELOG) are good starting points to understand what’s new and what’s deprecated in Selenium 4.

Here is the brief list of what is deprecated in Selenium 4:

### Deprecation of DesiredCapabilities

In Selenium 3, we make extensive use of the DesiredCapabilities when working with a RemoteWebDriver. This is required for setting the browser capabilities so that tests can be run on a cloud-based Selenium Grid like LambdaTest. With Selenium 4, we bid adieu to DesiredCapabilities.

Capabilities objects are now replaced with Options, and we need to create an Options object to use the Driver class. With Selenium 4, we need to set the necessary test requirements (i.e., browser and OS combinations) and pass the object to the Driver constructor. Henceforth, the following Options object would be used for setting the browser-specific capabilities:

- Chrome – ChromeOptions
- Firefox – FirefoxOptions
- Internet Explorer (IE) – InternetExplorerOptions
- Safari – SafariOptions
- Microsoft Edge – EdgeOptions

Here are the examples that demonstrate the usage of the ‘Options’ object for setting browser capabilities:

- ChromeDriver (Selenium 3) 🡪 ChromeOptions (Selenium 4)

![](https://www.lambdatest.com/blog/wp-content/uploads/2021/01/image2-300x300.jpg)

a. Cloud-based Selenium Grid

```java
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
import org.openqa.selenium.remote.RemoteWebDriver;
 
public void testSetUp() throws Exception
{
        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");
}
```

b. Local Selenium Grid

```java
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
 
public void testSetUp()
{
        ChromeOptions options = new ChromeOptions();
        options.setAcceptInsecureCerts(true);
        driver.get("https://www.lambdatest.com");
}
```

- FirefoxDriver (Selenium 3) 🡪 FirefoxOptions (Selenium 4)

 ![](https://www.lambdatest.com/blog/wp-content/uploads/2021/01/image3-300x300.jpg)

a. Cloud-based Selenium Grid

```java
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
import org.openqa.selenium.remote.RemoteWebDriver;
 
 
public void testSetUp() throws Exception
{
        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");
}
```

b. Local Selenium Grid

```java
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
 
public void testSetUp()
{
        FirefoxOptions options = new FirefoxOptions();
        options.setAcceptInsecureCerts(true);
        driver.get("https://www.lambdatest.com");
 
}
```

- IEDriver (Selenium 3) 🡪 InternetExplorerOptions (Selenium 4)

 ![](https://www.lambdatest.com/blog/wp-content/uploads/2021/01/image4.png)

a. Cloud-based Selenium Grid

```java
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
import org.openqa.selenium.remote.RemoteWebDriver;
 
public void testSetUp() throws Exception
{
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.setAcceptInsecureCerts(true);
 
        options.setCapability("build", "Testing IE Options [Selenium 4]");
        options.setCapability("name", "Testing IE Options [Selenium 4]");
        options.setCapability("platformName", "Windows 10");
        options.setCapability("browserName", "Internet Explorer");
        options.setCapability("browserVersion", "11.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");
}
```

b. Local Selenium Grid

```java
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
 
public void testSetUp()
{
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.setAcceptInsecureCerts(true);
        driver.get("https://www.lambdatest.com");
}
```

- SafariDriver (Selenium 3) 🡪 SafariOptions (Selenium 4)

 ![](https://www.lambdatest.com/blog/wp-content/uploads/2021/01/image5.png)

a. Cloud-based Selenium Grid

```java
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
import org.openqa.selenium.remote.RemoteWebDriver;
 
public void testSetUp() throws Exception {
        SafariOptions options = new SafariOptions();
        options.setAcceptInsecureCerts(true);
 
        options.setCapability("build", "Testing Safari Options [Selenium 4]");
        options.setCapability("name", "Testing Safari Options [Selenium 4]");
        options.setCapability("platformName", "macOS High Sierra");
        options.setCapability("browserName", "Safari");
        options.setCapability("browserVersion", "11.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");
}
```

b. Local Selenium Grid

```java
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
 
public void testSetUp()
{
        SafariOptions options = new SafariOptions();
        options.setAcceptInsecureCerts(true);
        driver.get("https://www.lambdatest.com");
}
```

- EdgeDriver (Selenium 3) 🡪 EdgeOptions (Selenium 4)

 ![](https://www.lambdatest.com/blog/wp-content/uploads/2021/01/image6.jpg)

a. Cloud-based Selenium Grid

```java
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
 
public void testSetUp() throws Exception
{
        EdgeOptions options = new EdgeOptions();
        options.setAcceptInsecureCerts(true);
 
        options.setCapability("build", "Testing Edge Options [Selenium 4]");
        options.setCapability("name", "Testing Edge Options [Selenium 4]");
        options.setCapability("platformName", "OS X Yosemite");
        options.setCapability("browserName", " MicrosoftEdge");
        options.setCapability("browserVersion", "81.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");
}
```

b. Local Selenium Grid

```java
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
 
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
 
public void testSetUp()
{
        EdgeOptions options = new EdgeOptions();
        options.setAcceptInsecureCerts(true);
        driver.get("https://www.lambdatest.com");
}
```

### The FindsBy Method

The methods [FindElement](https://github.com/SeleniumHQ/selenium/blob/trunk/java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java#L326) and [FindElements](https://github.com/SeleniumHQ/selenium/blob/trunk/java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java#L335) implemented by the RemoteWebDriver class are used for locating a single WebElement and a list of WebElements, respectively. The FindsBy interfaces are a part of the org.openqa.selenium.internal package is deprecated in Selenium 4.

The changes are internal to the Selenium framework, and Selenium users can continue using the FindElement(By) and FindElements(By) as used in Selenium 3.

The sample usage of FindElement and FindElements method in Java is shown below:

```java
WebElement eid = driver.findElement(By.id("email"));
WebElement pswd = driver.findElement(By.name("password"));
WebElement sbmtBtn = driver.findElement(By.xpath("//input[@value="submit"]");
```

```java
List<webelement> elem_signUpForm = driver.findElements(By.className("cell-body-textinput"));
List<webelement> elem_address = driver.findElements(By.name("Address"));
```

### New additions to the Actions Class

Actions Class in Selenium provides several methods for performing a single action or a series of actions on the WebElements present in the DOM. Mouse actions (e.g., click, double click, etc.) and Keyboard actions (e.g., keyUp, keyDown, sendKeys) are the two broad categories of Actions.  
For demonstration, we will port the examples demonstrated in the [Action class in Selenium](https://www.lambdatest.com/blog/what-is-actions-class-in-selenium/?utm_source=dev&utm_medium=Blog&utm_campaign=Himanshu-1032021&utm_term=Himanshu) blog from Selenium 3 to Selenium 4.

With Selenium 4, new methods are added to the Actions class, which replaces the classes under the org.openqa.selenium.interactions package.

- Click

_click(WebElement)_ is the new method added to the Actions class and it serves as the replacement of moveToElement(onElement).click() method.

Like the method in the versions before Selenium 4, click(WebElement) is used for clicking a web element.

**Example:**

```java
public void test_LambdaTest_click_demo() throws InterruptedException
{
    driver.navigate().to("https://www.amazon.in/");
    driver.manage().window().maximize();
 
    try {
        //create an object for the Actions class and pass the driver argument
        Actions action = new Actions(driver);
 
        //specify the locator of the search box in which the product has to be typed
        WebElement elementToType = driver.findElement(By.cssSelector("#twotabsearchtextbox"));
 
        //pass the value of the product
        action.sendKeys(elementToType, "iphone").build().perform();
 
        //specify the locator of the search button
        WebElement elementToClick = driver.findElement(By.xpath("//input[@value='Go']"));
 
        Thread.sleep(5000);
 
        //perform a mouse click on the search button
       action.click(elementToClick).build().perform();
 
        Thread.sleep(5000);
 
        //verify the title of the website after searching the product
        assertEquals(driver.getTitle(), "Amazon.in : iphone");
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}
```

- DoubleClick

The method moveToElement(element).doubleClick() used for double clicking on a WebElement is replaced with a [doubleClick(WebElement)](https://github.com/SeleniumHQ/selenium/blob/0f197cbd4fa9acdd2ac3ddebbe0cc9b4ca26bff8/java/client/src/com/thoughtworks/selenium/webdriven/commands/DoubleClick.java#L37) method in Selenium 4.

We demonstrate the usage of DoubleClick along with the _ContextClick_ method.

- ContextClick

The method moveToElement(onElement).contextClick() used for right clicking on a WebElement is now replaced with the [contextClick(WebElement)](https://github.com/SeleniumHQ/selenium/blob/0f197cbd4fa9acdd2ac3ddebbe0cc9b4ca26bff8/java/client/src/org/openqa/selenium/interactions/ContextClickAction.java#L49) method in Selenium 4.

**Example (DoubleClick and ContextClick):**

```java
public void test_LambdaTest_context_click_demo() throws InterruptedException 
{
    driver.navigate().to("https://www.amazon.in/");
    driver.manage().window().maximize();
 
    try {
        //create an object for the Actions class and pass the driver argument
        Actions action = new Actions(driver);
 
        WebElement element = driver.findElement(By.xpath("//a[.='Mobiles']"));
       action.doubleClick(element).build().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().build().perform();
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}
```

- ClickAndHold

The method moveToElement(Element).clickAndHold() used for clicking on a WebElement without performing the Release action is replaced with [clickAndHold(WebElement)](https://github.com/SeleniumHQ/selenium/blob/0f197cbd4fa9acdd2ac3ddebbe0cc9b4ca26bff8/java/client/src/org/openqa/selenium/interactions/ClickAndHoldAction.java#L50).

We demonstrate the usage of ClickAndHold along with the Release method.

- Release

The release() method, which is used for releasing the pressed mouse button, has been a part of the org.openqa.selenium.interactions.ButtonReleaseAction class. In Selenium 4, the method is a part of the Actions class.

**Example (ClickAndHold and Release):**

```java
public void test_LambdaTest_click_hold_demo() 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();
 
    try {
        //create an object for the Actions class and pass the driver argument
        Actions action = new Actions(driver);
 
        WebElement elem_source = driver.findElement(By.xpath("//li[text()= 'C']"));
        WebElement elem_destination = driver.findElement(By.xpath("//li[text()= 'A']"));
 
        action.clickAndHold(elem_source).release(elem_destination).build().perform();
        Thread.sleep(2000);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}
```

### Modifications to the ‘FluentWait’ Class

FluentWait in Selenium is used for performing a Selenium wait for an element when there is no certainty of the time it would take to be visible or clickable. As seen in the FluentWait in Selenium example (with Selenium 3), the withTimeOut() method takes two parameters – int and TimeUnit.

```
.withTimeout(60, SECONDS) // this defines the total amount of time to wait for
```

The pollingEvery() method takes two parameters – int and TimeUnit (e.g. SECONDS).

```
.pollingEvery(2, SECONDS) // this defines the polling frequency
```
 
- **Example – FluentWait in Selenium 3**

```java
Wait<WebDriver> fluentWait = new FluentWait<WebDriver>(driver)
       .withTimeout(60, SECONDS) // this defines the total amount of time to wait for
       .pollingEvery(2, SECONDS) // this defines the polling frequency
       .ignoring(NoSuchElementException.class); // this defines the exception to ignore 
    
    WebElement foo = fluentWait.until(new Function<WebDriver, WebElement>()
    {
        public WebElement apply(WebDriver driver)  //in this method defined your own subjected conditions for which we need to wait for
        {  
            return driver.findElement(By.id("foo"));
        }
    }
    );
```

With Selenium 4, the methods withTimeout() and pollingEvery() that are a part of the FluentWait class have been modified. The [pollingEvery()](https://github.com/SeleniumHQ/selenium/blob/trunk/java/client/src/org/openqa/selenium/support/ui/FluentWait.java#L149) method only accepts one parameter – Duration. The Duration can be in Seconds, MilliSeconds, NanoSeconds, Hours, Days, etc. On similar lines, the [withTimeOut()](https://github.com/SeleniumHQ/selenium/blob/trunk/java/client/src/org/openqa/selenium/support/ui/FluentWait.java#L112) method also takes only one parameter – Duration.

- Example – FluentWait in Selenium 4

```java
Wait<WebDriver> fluentWait = new FluentWait<WebDriver>(driver)
       .withTimeout(Duration.ofSeconds(120)) // this defines the total amount of time to wait for
       .pollingEvery(Duration.ofMillis(2000)) // this defines the polling frequency
       .ignoring(NoSuchElementException.class); // this defines the exception to ignore 
    
    WebElement foo = fluentWait.until(new Function<WebDriver, WebElement>()
    {
        public WebElement apply(WebDriver driver)  //in this method defined your own subjected conditions for which we need to wait for
        {  
            return driver.findElement(By.id("foo"));
        }
    }
    );
```

## Selenium 3 Vs. Selenium 4 – The final showdown

When it comes to Selenium 3 vs Selenium 4 comparison, the introduction of the WebDriver W3C protocol (and retiring of JSON Wire Protocol) is one of the significant architectural changes that will redefine the Selenium framework experience.

Apart from this significant under-the-hood change, other great Selenium 4 Alpha features such as the introduction of relative locators, Selenium Grid optimization, super-useful Selenium IDE (on Chrome and Firefox), and native support for the CDP (Chrome DevTools) protocol makes Selenium 4 experience much better in comparison to Selenium 3.

## Conclusion

![](https://www.lambdatest.com/blog/wp-content/uploads/2021/01/image9.gif)

To make the most out of the Selenium 4 Alpha features, it is recommended to perform testing on a scalable and reliable cloud-based Selenium 4 Grid like LambdaTest to execute in parallel across different browser and OS combinations. With this approach, you can perform [geolocation testing on the Selenium 4 Grid](https://www.lambdatest.com/blog/selenium-4-capabilities/?utm_source=dev&utm_medium=Blog&utm_campaign=Himanshu-1032021&utm_term=Himanshu) in 53 different countries.

Though Selenium 4 is still in the Alpha stage, the newly introduced features help accelerate testing activities, which was not possible with Selenium 3. 

Have you tried Selenium 4 (Alpha)? If yes, do let us know what features you liked the most, along with the overall experience of working with Selenium 4!

**Happy Testing ☺**