Selenium Version – 4.8.3 has implemented the fix for Chrome Version 111. As per the below changelog, we don’t need to add “–remote-allow-origins=*”, if we are using Selenium Version – 4.8.3.
Chrome Version 111 is recently released that has broken the Selenium Tests. In the current scenario, I’m using Selenium 4.8.0. You can see a simple Selenium test where we want to open a Chrome Browser and open Google.com failed.
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
public class ChromeTests {
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(20));
driver.get("https://www.google.com/");
String PageTiltle = driver.getTitle();
System.out.println("Page Title :"+PageTiltle);
driver.close();
}
}
The output of the above program is
Below is the screenshot of the Chrome Browser trying to open Google.com.
One of the solutions is to add “–remote-allow-origins=*” to ChromeOptions. The sample code is shown below:
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.time.Duration;
public class ChromeTests {
public static void main(String[] args) {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(20));
driver.get("https://www.google.com/");
String PageTiltle = driver.getTitle();
System.out.println("Page Title :"+PageTiltle);
driver.close();
}
}
By default, Selenium 4 is compatible with Chrome v75 and greater.
The output of the above program is
Hopefully, this trick will help you in your automation journey.
The previous tutorial explained running the tests in Selenium4 Grid using the Standalone option. One of the major advantages of Selenium Grid is the ability to run tests parallelly on multiple browsers simultaneously. Parallel testing helps to reduce execution time and efforts and results in a faster time to delivery.
In this tutorial, we will run the same set of tests on Chrome, Firefox, and Edge browsers sequentially initially to confirm that we can perform Cross Browser testing also
It is very important to construct our tests thread-safe in order to run them in parallel without a problem.
It is recommended to download the exe of various browsers in the same location where the Selenium WebDriver jar file is present. This is because Selenium 4 Alpha has the ability to automatically detect the WebDrivers present on the node machine. For this example, I have downloaded Chrome, Firefox, and edge drivers.
3. Start Selenium Server Jar
Open a command line terminal. Go to the location where these files are present
cd C:/Users/Vibha/Software/SeleniumGrid
Use the below command to run selenium-server standalone jar files.
It’s optional to mention the port number at the end of the command. By default, it will use port 4444. It is good practice to mention the port at the end to avoid any conflict between the ports.
4. Open Selenium Console
The server is listening on http://172.30.96.1:4445/ui/index.html which is the same as shown in the above image. This is a dynamic address, so make sure to get the address from the logs when Selenium Grid is started.
The Grid automatically identifies that the WebDrivers for Chrome and Firefox are present on the system.
5. Add dependencies to the project
In this example, we are using a Maven project, so are adding the dependencies to the POM.xml.
Creating an instance of the Remote WebDriver and passing the selenium endpoint and chrome options defined in it.
To run a Remote WebDriver client, we first need to connect to the RemoteWebDriver. We do this by pointing the URL to the address of the server running our tests. In order to customize our configuration, we set desired capabilities.
Below is an example of instantiating a remote WebDriver object pointing to our remote web server running our tests on Chrome, Firefox, and Edge. We have used @Parameters Annotation to pass the browser names to the tests.
import org.openqa.selenium.By;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
public class BaseTest {
protected static ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<RemoteWebDriver>();
public static String remote_url = "http://localhost:4445/";
public Capabilities capabilities;
@Parameters({"browser"})
@BeforeMethod
public void setDriver(String browser) throws MalformedURLException {
System.out.println("Test is running on "+browser);
if(browser.equals("firefox")) {
capabilities = new FirefoxOptions();
} else if (browser.equals("chrome")) {
capabilities = new ChromeOptions();
} else if (browser.equals("edge")) {
capabilities = new EdgeOptions();
}
driver.set(new RemoteWebDriver(new URL(remote_url), capabilities));
driver.get().get("https://opensource-demo.orangehrmlive.com/");
driver.get().manage().window().maximize();
driver.get().manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
WebDriverWait wait = new WebDriverWait(driver.get(), Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='divUsername']/span")));
}
public WebDriver getDriver() {
return driver.get();
}
@AfterMethod
public void closeBrowser() {
driver.get().quit();
driver.remove();
}
}
Selenium4ParallelDemo
This class contains the various tests that need to be executed.
InBaseTest class, I created ThreadLocal <>() webdriver (ThreadLocalMap) for thread-safe test execution
I got the TestNG parameter (browser)with @Parameterannotation.
BaseTest returns browser Capabilities based on browser name.
In BaseTest class, thegetDriver()method returns the created driver.
Selenium4ParallelDemoclass extends TestBase class and comprises their test code.
It is very easy to create testng.xml in the case of Eclipse. Right-click on the project, and select TestNG -> Convert to TestNG. It will create a basic testng.xml structure. We need to add the parameter name and value to it.
We are planning to run the test on 3 different browsers, so we are passing the name of the browser from this testng.xml using the parameter. This testng.xml will run the test sequentially. There is a minor change needs to be done in testng.xml that will run the tests parallelly.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Chrome Test">
<parameter name ="browser" value="chrome"/>
<classes>
<class name="org.example.Selenium4ParallelDemo"/>
</classes>
</test> <!-- Test -->
<test thread-count="5" name="Firefox Test">
<parameter name ="browser" value="firefox"/>
<classes>
<class name="org.example.Selenium4ParallelDemo"/>
</classes>
</test> <!-- Test -->
<test thread-count="5" name="Edge Test">
<parameter name ="browser" value="edge"/>
<classes>
<class name="org.example.Selenium4ParallelDemo"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
8. Run the tests from testng.xml
Right-Click on the testng.xml and selectRun As ->TestNG Suite.
9. Navigate to the sessions tab on the Selenium Grid UI upon running the command
It would reflect an active session.
10. Review the test execution result
There are 2 ways to see if the tests are getting executed or not. First, we can check in the command line. We can see the logs there as shown below.
The complete test execution result can be found in the console too.
The tests are TestNG ones, so we can also check the “Result of Running Suite“ tab also.
11. TestNG Report Generation
TestNG generates the test reports in the test-output folder.
We are interested in 2 reports – index.html and emailable-report.html.
Index.html
The below image shows that the tests are run sequentially.
Emailable-Report.html
This report is the summary report. It contains the summary of all the tests executed like, the number of tests passed, skipped, retried, and failed, and the execution time taken by each test.
Parallel Testing
Update the testng.xml for parallel testing. Add parallel=”tests” in the XML.
Updated testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests">
<test thread-count="5" name="Chrome Test">
<parameter name ="browser" value="chrome"/>
<classes>
<class name="org.example.Selenium4ParallelDemo"/>
</classes>
</test> <!-- Test -->
<test thread-count="5" name="Firefox Test">
<parameter name ="browser" value="firefox"/>
<classes>
<class name="org.example.Selenium4ParallelDemo"/>
</classes>
</test> <!-- Test -->
<test thread-count="5" name="Edge Test">
<parameter name ="browser" value="edge"/>
<classes>
<class name="org.example.Selenium4ParallelDemo"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
The below image shows that the tests were running on multiple browsers at the same time.
The console also shows that tests were started on all three browsers at the same time.
Index.html shows that methods run in chronological order. It can be seen that the setDriver() method for all 3 browsers was the first one to be executed.
Best Practices:
It is advisable to use nodes other than 4444 to run the tests. By using the different port numbers, we prevent the risk that the port is already in use on your system.
It is suggested to use RemoteWebDriver objects, as it is used to set which node (or machine) our test will run against.
Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!
Selenium Grid routes command received by the client to distant browser instances, allowing WebDriver scripts to be run on remote machines (virtual or real). Its goal is to make running tests in parallel on numerous machines as simple as possible.
Selenium Grid allows us to run tests on numerous workstations in parallel and centrally manage diverse browser versions and setups (instead of in each individual test).
Selenium Grid 4 makes use of a variety of new technologies to make scaling up easier while still allowing for local execution.
Selenium Grid 4 is a brand-new implementation that doesn’t use the same codebase as the previous version.
A Selenium Grid is made up of several components. Using a Grid role, you can start each one individually or all of them at once, depending on your needs.
Why do we need Selenium Grid?
Imagine we need to run 1000 tests and it takes 20 hrs to run these tests. With the help pf Selenium Grid, we can have 4 different machines (VMs or separate physical machines) to run those tests. We can roughly reduce the execution time to one-fourth, which means the test execution will be finished in 5 hrs.
Grid is also used to support running tests against multiple runtime environments, specifically, against different browsers at the same time. For example, a ‘grid’ of virtual machines can be set up with each supporting a different browser that the application to be tested must support. So, machine 1 has Google Chrome, machine 2, has Edge, and machine 3 has the latest Firefox. When the test suite is run, Selenium-Grid receives each test-browser combination and assigns each test to run against its required browser. Grid makes cross-browser and parallel testing very easy.
1. Standalone
The term “standalone” refers to the combination of all components that, in the view of the user, operate as if they were one. After launching it in Standalone mode, you’ll have a fully functional Grid of one.
Standalone is also the quickest way to get a Selenium Grid up and running. The server will be listening on http://localhost:4444 by default, and you should use that URL in your RemoteWebDriver tests. The server will look for available drivers in the System PATH and utilize them.
java -jar selenium-server-4.1.2.jar standalone
2. Hub and Nodes
It enables the classic Hub & Node(s) setup. These roles are suitable for small and middle-sized Grids.
Hub – A Hub is the union of the following components:
Router
Distributor
Session Map
New Session Queue
Event Bus
By default, the server will be listening on http://localhost:4444, and that’s the URL you should point your RemoteWebDriver tests.
java -jar selenium-server-4.1.2.jar hub
Node – One or more Nodes can be started in this setup, and the server will detect the available drivers that it can use from the System PATH.
Now, let us see how to run Selenium tests in Selenium Grid using the Standalone option.
Step 1 – Download driver.exe for the browsers
I have downloaded the driver.exe (chrome, gecko) in Downloads.
Step 2 – Download selenium-server jar
Go to Selenium Official website. Navigate to Downloads and it shows that the latest stable version of Selenium Grid is 4.3.0. Click on that and download the jar file. Make sure to keep the browsers.exe and selenium-server jar file in the same folder.
Step 3 – Execute selenium-server jar
Open a command line terminal. Use the below command to run selenium-server standalone jar files.
It’s optional to mention the port number at the end of the command. By default, it will use port 4444. It is good practice to mention the port at the end to avoid any conflict between the ports.
Step 4 – Add dependencies to the Maven project
Let us add the necessary dependencies to the pom.xml in the case of the Maven Project.
Creating an instance of the Remote WebDriver and passing the selenium endpoint and chrome options defined in it.
To run a Remote WebDriver client, we first need to connect to the RemoteWebDriver. We do this by pointing the URL to the address of the server running our tests. In order to customize our configuration, we set desired capabilities. Below is an example of instantiating a remote WebDriver object pointing to our remote web server running our tests on Chrome.
HelperClass
This class contains the initialization of the Remote web driver and the closing of the web driver.
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
public class HelperClass {
protected static ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<RemoteWebDriver>();
public static String remote_url = "http://localhost:4446";
@BeforeMethod
public void setDriver() throws MalformedURLException {
ChromeOptions options = new ChromeOptions();
driver.set(new RemoteWebDriver(new URL(remote_url), options));
driver.get().get("https://opensource-demo.orangehrmlive.com/");
driver.get().manage().window().maximize();
driver.get().manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
WebDriverWait wait = new WebDriverWait(driver.get(), Duration.ofSeconds(10));
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='divUsername']/span")));
}
public WebDriver getDriver() {
return driver.get();
}
@AfterMethod
public void closeBrowser() {
driver.get().quit();
driver.remove();
}
}
Selenium4GridTest
This class contains all the tests like login test, invalid credential, verify heading of the login page, verify LinkedIn link on the login page, and verify the heading of Forgot Password page.
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.openqa.selenium.By;
import org.testng.annotations.Test;
public class Selenium4GridTest extends HelperClass{
@Test
public void invalidCredentials() {
getDriver().findElement(By.xpath("//*[@id='txtUsername']")).sendKeys("1234");
getDriver().findElement(By.xpath("//*[@id='txtPassword']")).sendKeys("12342");
getDriver().findElement(By.xpath("//*[@id='btnLogin']")).click();
String actualErrorMessage = getDriver().findElement(By.xpath("//*[@id='spanMessage']")).getText();
System.out.println("Actual ErrorMessage :" + actualErrorMessage);
assertEquals(actualErrorMessage,"Invalid credentials");
}
@Test
public void loginPageHeading() {
String loginText = getDriver().findElement(By.xpath("//*[@id='logInPanelHeading']")).getText();
System.out.println("Actual loginText :" + loginText);
assertEquals(loginText,"LOGIN Panel");
}
@Test
public void forgotPasswordPageHeading() {
getDriver().findElement(By.xpath("//*[@id='forgotPasswordLink']/a")).click();
String forgetPasswordTitle= getDriver().findElement(By.xpath(" //*[@id='content']/div[1]/div[2]/h1")).getText();
System.out.println("Actual Page Title of Forgot Password Page :" + forgetPasswordTitle);
assertEquals(forgetPasswordTitle,"Forgot Your Password?");
}
@Test
public void verifyLinkedIn() {
Boolean linkedInIcon = getDriver().findElement(By.xpath("//*[@id='social-icons']/a[1]/img")).isEnabled();
System.out.println("Actual linkedIn Text :" + linkedInIcon);
assertTrue(linkedInIcon);
}
}
Step 6 – Create a testng.xml
It is very easy to create testng.xml for Eclipse IDE. Right-click on the project -> TestNG -> Convert to TestNG.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<classes>
<class name="org.example.Selenium4GridTest"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Step 7 – Execute the tests through the command line
To run it from the command prompt, open a command prompt and go to the project and run the following command:
mvn clean test
Step 8 – Execute the tests from testng.xml
We can right-click on testng.xml, and select Run As -> TestNG Suite.
Step 9 – Navigate to the sessions tab on the Selenium Grid UI upon running the command.
It would reflect an active session.
Step 10 – Review the test execution result
The logs can be viewed in the command prompt as shown below:
Step 11 – TestNG Report Generation
TestNG generates the test reports in test-output folder.
We are interested in index.html report. This report contains various information, like time taken by each step in the test, time taken by each test, testng.xml, and number of tests passed or failed.
Emailable-Report.html
The output reports in TestNG reporting look like below as all tests are passed:
Congratulations!! We are able to run Selenium 4 tests on the new Selenium 4 Grid. Happy Learning!!
Docker is an open platform for developing, shipping, and running applications. Docker provides the ability to package and run an application in a loosely isolated environment called a container. A container is a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI. You can connect a container to one or more networks, attach storage to it, or even create a new image based on its current state.
By default, a container is relatively well isolated from other containers and its host machine It contains multiple components such as Docker Daemon, Docker Clients, Docker Registry, and Docker Compose. It works on a client-server architecture. The Docker client communicates with the Docker Daemon handles the complex part of building, running, and distributing the Docker containers.
Docker Desktop is an easy-to-install application for your Mac or Windows environment that enables you to build and share containerized applications and microservices. Docker Desktop includes the Docker daemon (dockerd), the Docker client (docker), Docker Compose, Docker Content Trust, Kubernetes, and Credential Helper.
Why use Selenium with Docker for web application testing
When Selenium is used with Docker, there is no need to install the necessary browsers and browser drivers on the host machine. Overall, it is significantly quicker to get started with Selenium web automation testing using pre-made Docker containers. A range of Docker images (with Selenium) on the Docker Hub can be used by running a few commands on the terminal. Some of these images on the Docker Hub were developed and maintained by Selenium HQ.
One of the most common uses of Docker containers in selenium testing is cross-browser testing. Setting up test setups with all of the Browser-OS combinations gets difficult. These can be set up on the go and taken down once the tests are completed using Docker containers.
Another use of Docker containers in Selenium testing is parallel testing. Because there are so many sorts of tests to conduct, doing them sequentially takes a long time. As a result, parallelizing the testing saves time and provides faster feedback. Parallel testing, on the other hand, necessitates a significant amount of infrastructure setup. This would have a direct bearing on the price. Multiple containers can be launched on a single server using docker containers, making the most of the underlying hardware while also allowing for concurrent testing
Let’s discuss how to set up docker and run selenium tests on it.
Setting up Window Docker
Step 1 – Download the Docker Installer
Docker provides an installer for Windows which can be downloaded from the official docker website.
Step 2 – Install Docker
Launch the installer by double-clicking on it. Select the Enable Hyper-V Windows Features option on the configuration page.
If the user account and admin accounts are different, the user account must be added to the docker-users group as shown below:
To do that, you will need to run Computer Management as an administrator and navigate to Local Users and Groups > Groups > docker-users. Then right-click to add the user to the group. You will need to log and log back in for the changes to take effect.
Step 3 – Start Docker Desktop
After the installation process is complete, the tool does not start automatically. To start the Docker tool, search for the tool, and select Docker Desktop in your desktop search results or Docker desktop can be started from the start menu.
Docker is free for small businesses, personal usage, education and non-commercial purposes.
Step 4 – Verify the installation of Desktop Docker
To see if Docker is correctly configured, run the following line in Command Prompt. The version of Docker installed on the system is provided.
docker --version
Running Selenium Tests in Docker
The Docker Desktop can execute a few docker images after it is installed. You can either build a Docker image from the scratch, or start with a pre-configured base image from the Docker hub and add to it.
Run the following command to download a copy of the image onto the system.
docker pull selenium/standalone-firefox
Step 2 – Running the Selenium Webdriver Docker container
Upon pulling the selenium/standalone-firefox image onto the system, start the container by running the following command:
docker run -d -p 4444:4444 -v /dev/shm:/dev/shm selenium/standalone-firefox
The above command starts a container from the image specified in detached mode (background mode). It also maps Port 4444 on the container to Port 4444 on your local browser.
Open the browser and navigate to http://localhost:4444/. It reflects Selenium Grid UI, as shown below.
I have created a base class where the WebDriver is initialized and at the end is closed.
import io.github.bonigarcia.wdm.WebDriverManager;
import org.junit.After;
import org.junit.Before;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.MalformedURLException;
import java.net.URL;
public class BaseTest {
protected static ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<>();
public static String remote_url_firefox = "http://localhost:4444/wd/hub";
@Before
public void setDriver() throws MalformedURLException {
WebDriverManager.firefoxdriver().setup();
FirefoxOptions options = new FirefoxOptions();
options.addArguments("window-size=1920,1200");
driver.set(new RemoteWebDriver(new URL(remote_url_firefox), options));
driver.get().get("https://opensource-demo.orangehrmlive.com/");
}
public WebDriver getDriver() {
return driver.get();
}
@After
public void closeBrowser() {
driver.get().quit();
driver.remove();
}
}
The below class contains the various tests. The tests are related to verifying the login to the application, verifying the title of current page, verifying the error message generated on providing the invalid credentials, verifying the linkedIn link, verifying the heading of forgot password page.
Selenium is moved from version 3 to version 4 which is quite a huge step. What does this change means? It means that few of the old features of Selenium 3 are depreciated in Selenium 4 as well some new features are added to it also. I’m trying to explain few of the latest updates done in Selenium 4.
Selenium 3 – This is the latest version of Selenium3 available.
Managing Selenium Grid is now smooth and easy as there will no longer be any need to set up and start hubs and nodes separately. The grid can be deployed in 3 modes:
Standalone – Standalone is the union of all components, and to the user’s eyes, they are executed as one. A fully functional Grid of one is available after starting it in the Standalone mode. By default, the server will be listening on http://localhost:4444, and that’s the URL you should point your RemoteWebDriver tests. The server will detect the available drivers that it can use from the System PATH.
Hub and Node – It enables the classic Hub & Node(s) setup. These roles are suitable for small and middle-sized Grids
Distributed – On Distributed mode, each component needs to be started on its own. This setup is more suitable for large Grids.
Grid will now support IPv6 addresses and one can communicate with the Grid using the HTTPS protocol. In Grid 4, the configuration files used for spinning up the grid instances can be written in TOML (Tom’s Obvious, Minimal Language) which will make it easier for humans to understand.
The new Selenium Grid comes with Docker support. It also supports advanced tools like AWS, Azure, and much more, useful in the DevOps process. Now Grid has a more user-friendly UI and contains relevant information related to the session, running, capacity, etc.
2. Simplification to open a new Windows browser 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 switching to the new tab, pass WindowType.TAB to newWindow() method and for creating a new window, pass WindowType.WINDOW to newWindow() method.
public class NewWindowDemo {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver",
"C:\\Users\\Vibha\\Software\\chromedriver_win32_93.0.4577.15\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.bing.com/");
System.out.println("New Page - Bing is opened");
// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW);
// Opens duckduckgo homepage in the new opened window
driver.navigate().to("https://www.duckduckgo.com/");
System.out.println("New Page - DuckDuckGo is opened");
driver.quit();
}
}
Open a new Tab in Selenium 4
public class NewTabDemo {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver",
"C:\\Users\\Vibha\\Software\\chromedriver_win32_93.0.4577.15\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.bing.com/");
System.out.println("New Page - Bing is opened");
// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.TAB);
// Opens duckduckgo homepage in the new opened window
driver.navigate().to("https://www.duckduckgo.com/");
System.out.println("New Tab is opened with DuckDuckGo");
driver.quit();
}
}
3. Relative Locators
Selenium 4 brings Relative Locators which are previously called as Friendly Locators. This functionality was added to help you locate elements that are nearby other elements. The Available Relative Locators are:
above below toLeftOf toRightOf near findElement method now accepts a new method withTagName() which returns a RelativeLocator.
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 is encoded in the Base64 format.
This is how you can capture WebElement Screenshot in Selenium 4 (for Java):
import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class ScreenshotDemo {
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.selenium.dev/");
try {
WebElement logo = driver.findElement(By.xpath("//*[@id='td-cover-block-0']/div/div/div/div/h1"));
File source = ((TakesScreenshot) logo).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("./Screenshots/logo" + System.currentTimeMillis() + ".png"));
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("The Screenshot is taken and saved under Screenshots folder");
driver.quit();
}
}
5. 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 the Selenium 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(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.
doubleClick(WebElement)
This method is added to replace moveToElement(element).doubleClick(). It will perform a double click on an element.
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
public class DoubleClick {
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
// Navigate to Url
driver.get("https://demo.guru99.com/test/simple_context_menu.html");
// Store 'doubleClickButton' button web element
WebElement doubleClickButton = driver.findElement(By.xpath("//*[@id='authentication']/button"));
Actions actionProvider = new Actions(driver);
// Perform double-click action on the element
actionProvider.doubleClick(doubleClickButton).build().perform();
Alert alert = driver.switchTo().alert();
System.out.println("Alert Text\n" +alert.getText());
alert.accept();
driver.close();
}
}
The output of the above program is
clickAndHold(WebElement)
This method will replace the moveToElement(onElement).clickAndHold(). It is used to click on an element without releasing the click.
contextClick(WebElement)
This method will replace moveToElement(onElement).contextClick(). It will perform the right click operation.
release()
This method (user for releasing the pressed mouse button) was initially a part of org.openqa.selenium.interactions.ButtonReleaseAction class. Now with the updated version of Selenium, it has been moved to the Actions class.
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
public class clickAndHold {
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
// Navigate to Url
driver.get("https://crossbrowsertesting.github.io/drag-and-drop.html");
driver.manage().window().maximize();
// Find element xpath which we need to drag
WebElement from = driver.findElement(By.id("draggable"));
// Find element xpath where we need to drop
WebElement to = driver.findElement(By.id("droppable"));
Actions actionProvider = new Actions(driver);
// Perform click-and-hold action on the element
actionProvider.clickAndHold(from).build().perform();
// Move to drop Webelement
actionProvider.clickAndHold(to).build().perform();
//Release drop element
actionProvider.release(to).build().perform();
}
}
The output of the above program is
6. Deprecation of Desired Capabilities
In Selenium 3, desired Capabilities were primarily used in the test scripts to define the test environment (browser name, version, operating system) for execution on the Selenium Grid.
In Selenium 4, capabilities objects are replaced with Options. This means testers now need to create an Options object, set test requirements, and pass the object to the Driver constructor.
Listed below are the Options objects to be used going forward for defining browser-specific capabilities:
Firefox – FirefoxOptions Chrome – ChromeOptions Internet Explorer (IE) – InternetExplorerOptions Microsoft Edge – EdgeOptions Safari – SafariOptions
Below is an example of Options
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class ChromeOptionsHeadless {
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setBrowserVersion("100");
chromeOptions.setPlatformName("Windows 10");
WebDriver driver = new ChromeDriver(chromeOptions);
driver.get("https://duckduckgo.com/");
System.out.println("Title of Page :" + driver.getTitle());
// Close the driver
driver.close();
}
}
The output of the above program is
Similarly, we can create the action class for other browsers like Firefox.
FirefoxOptions options = new FirefoxOptions();
// Create an object of WebDriver class and pass the Firefox Options object as an argument
WebDriver driver = new FirefoxDriver(options);
7. Chrome Dev Tools
In the new version of Selenium, they have made some internal changes in the API. Earlier in Selenium 3, the Chrome driver extends directly to the Remote Web Driver class. But now in Selenium 4, the Chrome driver class extends to Chromium Driver. Chromium Driver class has some predefined methods to access the dev tool.
Note: Chromium Driver extends the Remote Web driver class.
By using the API, we can perform the following operations:
This tutorial explains the steps to run the Selenium tests for Chrome browser and Firefox in headless mode. We are going to run the tests in Selenium 4.
There are 2 ways to add dependencies to the Selenium project.
Once the Selenium and WebDriverManager folders are downloaded, unzip the folder. Once the zip file is extracted, reference these jar files in the project. For this, navigate to project properties and click Build Path-> Configure Build Path in Eclipse. Click “Add External Jars“. After clicking on “Add External JARs“, selected all the extracted JARs. The JARs files are present in the project.
Add the below dependencies to pom.xml or build.gradle
A headless browser is like any other browser, but without a Head/GUI (Graphical User Interface). A headless browser is used to automate the browser without launching the browser. While the tests are running, we could not see the browser, but we can see the test results coming on the console.
We know that to execute Selenium automation scripts on browsers like edge, we must download the binary files of EDGE driver – msedgedriver. After this, we need to set the path to these binaries in the automation script or add the classpath location. Here, we want to execute Selenium WebDriver automation scripts on the Microsoft Edge browser, then you need first to download msedgedriver.exe and then use the System.setProperty method to set its path as follows:
// Set the path of EdgeDriver
System.setProperty("webdriver.edge.driver",
"C:\\Users\\Vibha\\Software\\edgedriver_win64\\msedgedriver.exe");
The complete program looks like as shown below:
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
public class EdgeHeadlessInSelenium4 {
public static void main(String[] args) {
// Set the path of EdgeDriver
System.setProperty("webdriver.edge.driver",
"C:\\Users\\Vibha\\Software\\edgedriver_win64\\msedgedriver.exe");
// Create an object of Edge Options class
EdgeOptions edgeOptions = new EdgeOptions();
// pass the argument –headless to Edge Options class.
edgeOptions.addArguments("--headless");
// Create an object of WebDriver class and pass the Edge Options object as
// an argument
WebDriver driver = new EdgeDriver(edgeOptions);
System.out.println("Executing Edge Driver in Headless mode..");
driver.get("https://duckduckgo.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
How to run headless Microsoft Edge Tests in Selenium using WebDriverManager?
WebDriverManager has an automated way to download browser executables(exes) or binaries. It supports different browsers like Chrome, Firefox, Microsoft Edge, Internet Explorer, Opera, or PhantomJS.
WebDriverManager.edgedriver().setup: checks for the latest version of the specified WebDriver binary. If the binaries are not present on the machine, then it will download the WebDriver binaries. Next, it instantiates the Selenium WebDriver instance with the EdgeDriver.
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class EdgeHeadlessWithWebDriverManagerInSelenium4 {
public static void main(String[] args) {
// WebDriverManager downloads Edge browser executables or binaries.
WebDriverManager.edgedriver().setup();
// Create an object of Edge Options class
EdgeOptions edgeOptions = new EdgeOptions();
// pass the argument –headless to Edge Options class.
edgeOptions.addArguments("--headless");
// Create an object of WebDriver class and pass the Edge Options object as
// an argument
WebDriver driver = new EdgeDriver(edgeOptions);
System.out.println("Executing Edge Driver in Headless mode..");
driver.get("https://www.bing.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!
This tutorial explains the steps to disable infobar warning generated by Selenium for running tests in Chrome. Selenium tests run on Chrome shows a warning message – “Chrome is being controlled by automated test software as shown in the below image.“
We want to run the Selenium tests on Chrome, but without the above-shown warning message. This can be achieved by using excludeSwitches.
import java.util.Arrays;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class ChromeDisableInfobars {
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
// Create an object of Chrome Options class
ChromeOptions chromeOptions = new ChromeOptions();
// prevents Chrome from displaying the notification 'Chrome is being controlled
// by automated software'
chromeOptions.setExperimentalOption("excludeSwitches", Arrays.asList("enable-automation"));
// Create an object of WebDriver class and pass the Chrome Options object as an
// argument
WebDriver driver = new ChromeDriver(chromeOptions);
driver.get("https://duckduckgo.com/");
System.out.println("Title of Page :" + driver.getTitle());
// close the browser
driver.quit();
}
}
This tutorial explains the steps to run the Selenium tests on Firefox browser in headless mode. We are going to run the tests in Selenium. To run the Selenium tests on Chrome browser in headless mode, refer this tutorial.
To start with, we need to add dependencies to the project.
Download the latest version of WebDriverManager (Download this if you want to use WebDriverManager to download browser executables(exes) or binaries automatically, then skip downloading FireFox Binary).
Add the below dependencies to pom.xml or build.gradle.
A headless browser is like any other browser, but without a GUI (Graphical User Interface). A headless browser is used to automate the browser without launching the browser. While the tests are running, we could not see the browser, but we can see the test results coming on the console. This makes the test execution faster than normal execution. This is suitable for parallel testing as UI tests needs a lot of memory and resources.
The path of Gecko Driver (used for Firefox browser) needs to be set up in the Test using System.setProperty().Here, we use the methods setHeadless(true) of the FirfoxOptions class provided by Selenium WebDriver.
The complete program looks like as shown below:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
public class FirefoxOptionsHeadless1 {
public static void main(String[] args) {
// Set the path of GeckoDriver
System.setProperty("webdriver.gecko.driver",
"C:\\Users\\Vibha\\Software\\geckodriver\\geckodriver.exe");
// Create an object of Firefox Options class
FirefoxOptions options = new FirefoxOptions();
// Set Firefox Headless mode as TRUE
options.setHeadless(true);
// Create an object of WebDriver class and pass the Firefox Options object
// as an argument
WebDriver driver = new FirefoxDriver(options);
// Navigate to site url
driver.get("https://duckduckgo.com/");
System.out.println("Executing Firefox Driver in Headless mode..");
System.out.println("Page Title : " + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
How to run headless Firefox Tests in Selenium using WebDriverManager?
WebDriverManager.firefoxdriver().setup(): checks for the latest version of the specified WebDriver binary. If the binaries are not present on the machine, then it will download the WebDriver binaries. In this case, it is not needed to download Firefox binary and set up the path
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class FirefoxOptionsHeadless2 {
public static void main(String[] args) {
WebDriverManager.firefoxdriver().setup();
// Create an object of Firefox Options class
FirefoxOptions options = new FirefoxOptions();
// Set Firefox Headless mode as TRUE
options.setHeadless(true);
// Create an object of Firefox Driver class and pass the Firefox Options object
// as an argument
WebDriver driver = new FirefoxDriver(options);
// Navigate to the url
driver.get("https://duckduckgo.com/");
System.out.println("Executing Firefox Driver in Headless mode..");
System.out.println("Page Title : " + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
Congratulations!! We have run the tests in headless mode in FireFox.
Internet Explorer is going away in near future. But still it is a browser which holds around 1% of browser market share. When anyone refers to automated browser testing, it somehow means that the testing will be performed on the latest browsers like Chrome, Firefox, etc. But along with these browsers, it is also expected to work on Internet Explorer (IE).
The Internet Explorer driver that is used by Selenium Tests can be downloaded from here.
In order to run the Selenium Tests on IE, it is needed to set the %PATH%.
How to add %PATH%
Go To -> View Advanced System Settings -> Environment Variables ->Clicks on the Path and add the path where IE binary is located on the machine.
How to run tests using Selenium IE driver in Selenium Java?
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
public class IEDemo {
public WebDriver driver;
@Before
public void setUp() {
System.setProperty("webdriver.ie.driver",
"C:\\Users\\Vibha\\Software\\IEDriverServer_x64_2.39.0\\IEDriverServer.exe");
driver = new InternetExplorerDriver();
}
@Test
public void verifyPageTitle() {
System.out.println("Opening Internet Explorer Web Browser");
driver.get("https://www.bing.com/");
System.out.println("Title of Page : " + driver.getTitle());
Assert.assertEquals(driver.getTitle(), "Bing");
}
@Test
public void verifyPageUrl() {
System.out.println("Opening Internet Explorer Web Browser");
driver.get("https://www.bing.com/");
System.out.println("URL of Page : " + driver.getCurrentUrl());
Assert.assertEquals(driver.getCurrentUrl(), "https://www.bing.com/");
}
@After
public void tearDown() {
// Close the driver
driver.close();
}
}
Execution
The string webdriver.ie.driver is set to the location which contains the Selenium IE driver. The InternetExplorerDriver method is used for instantiating the IE driver class.
The test method is implemented under the @Test annotation.
In the tearDown method, the resources held by IE driver are freed using the close() method in Selenium.
Congratulations!! We are able to open an Internet Explorer browser and perform tests. Happy Learning!!
The traditional way to use any browser in Selenium tests is to download browser binaries and we need to set the path of these files in our script like below or its location should be added to the classpath.
The process of manually downloading and managing these drivers for each operating systems is very painful. We also have to check when new versions of the binaries are released / new browsers versions are released. We should check the compatibility for all the executables and add it.
How to download all the driver executables automatically ???
The automatic download of the drivers can be done by WebDriverManager. WebDriverManager is a library that allows controlling web browsers programmatically. It provides a cross-browser API that can be used to drive web browsers (e.g., Chrome, Edge, or Firefox, among others) using different programming languages (e.g., Java, JavaScript, Python, C#, or Ruby). The primary use of Selenium WebDriver is implementing automated tests for web applications.
The communication between the WebDriver API and the driver binary is done using a standard protocol called W3C WebDriver (formerly the so-called JSON Wire Protocol). Then, the communication between the driver and the browser is done using the native capabilities of each browser.
How To add WebDriverManager to a Selenium project manually?
Download the latest version of WebDriverManager from here.
It will download a zip file. Now extract the jar/zip file. It will show various jar under the folder, as shown below:
Once we extract the zip file, we have to reference these jar files in our project. For this, navigate to project properties and click Build Path-> Configure Build Path in Eclipse
Click “Add External Jars” as per the steps highlighted below to include all the WebDriverManager jars extracted.
After clicking on the “Add External JARs“, all the selected extracted JARs are added to the project.
When this finishes, the project references show these referenced jars in the project explorer as highlighted below, and they are ready to be consumed in the Selenium test scripts.
Chrome
The below code snippet shows a quick usage of WebDriverManager with Chrome:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class Demo {
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
// Create an object of Chrome Options class
ChromeOptions chromeOptions = new ChromeOptions();
// Create an object of WebDriver class and pass the Chrome Options object as
// an argument
WebDriver driver = new ChromeDriver(chromeOptions);
System.out.println("Executing Chrome Driver");
driver.get("https://www.bing.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
FireFox Driver
The below code snippet shows a quick usage of WebDriverManager with FireFox:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class FireFoxDemo {
public static void main(String[] args) {
WebDriverManager.firefoxdriver().setup();
// Create an object of Firefox Options class
FirefoxOptions firefoxOptions = new FirefoxOptions();
// Create an object of WebDriver class and pass the Firefox Options object
// as an argument
WebDriver driver = new FirefoxDriver(firefoxOptions);
System.out.println("Executing Firefox Driver");
driver.get("https://www.bing.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
Microsoft Edge
The below code snippet shows a quick usage of WebDriverManager with Microsoft Edge:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class EdgeDemo {
public static void main(String[] args) {
WebDriverManager.edgedriver().setup();
// Create an object of Edge Options class
EdgeOptions edgeOptions = new EdgeOptions();
// Create an object of WebDriver class and pass the Edge Options object
// as an argument
WebDriver driver = new EdgeDriver(edgeOptions);
System.out.println("Executing Microsoft Edge Driver");
driver.get("https://www.bing.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
How to instantiate a specific browser version using WebDriverManager?
WebDriverManager provides an ability to download specific version of browser. For example, the latest chromedriver version is 100.0.4896.20 (released on 2022-03-04). But if we want an earlier version, say, Chromedriver version 98.0.4758.102, we have to add the following code.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class Demo {
public static void main(String[] args) {
WebDriverManager.chromedriver().driverVersion("98.0.4758.102").setup();
// Create an object of Chrome Options class
ChromeOptions chromeOptions = new ChromeOptions();
// Create an object of WebDriver class and pass the Chrome Options object as
// an argument
WebDriver driver = new ChromeDriver(chromeOptions);
System.out.println("Executing Chrome Driver");
driver.get("https://www.bing.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
As we can see from the above screenshot, as a result of executing the above program, the Chromedriver started successfully. We can see the details of starting the chrome driver instance in the first line of output. Here we have set the Chrome version to “98.0.4758.102″.
Congratulations!! We have learnt to download drivers automatically.