This is the multi-page printable view of this section.
Click here to print.
Return to the regular view of this page.
Getting started
If you are new to Selenium, we have a few resources that can help you get up to speed right away.
Selenium supports automation of all the major browsers in the market
through the use of WebDriver.
WebDriver is an API and protocol that defines a language-neutral interface
for controlling the behaviour of web browsers.
Each browser is backed by a specific WebDriver implementation, called a driver.
The driver is the component responsible for delegating down to the browser,
and handles communication to and from Selenium and the browser.
This separation is part of a conscious effort to have browser vendors
take responsibility for the implementation for their browsers.
Selenium makes use of these third party drivers where possible,
but also provides its own drivers maintained by the project
for the cases when this is not a reality.
The Selenium framework ties all of these pieces together
through a user-facing interface that enables the different browser backends
to be used transparently,
enabling cross-browser and cross-platform automation.
Selenium setup is quite different from the setup of other commercial tools.
Before you can start writing Selenium code, you have to
install the language bindings libraries for your language of choice, the browser you
want to use, and the driver for that browser.
Follow the links below to get up and going with Selenium WebDriver.
If you wish to start with a low-code/record and playback tool, please check
Selenium IDE
Once you get things working, if you want to scale up your tests, check out the
Selenium Grid.
1 - Install a Selenium library
Setting up the Selenium library for your favourite programming language.
First you need to install the Selenium bindings for your automation project.
The installation process for libraries depends on the language you choose to use.
Make sure you check the Selenium downloads page to make sure
you are using the latest version.
Requirements by language
View the minimum supported Java version here.
Installation of Selenium libraries for Java is accomplished using a build tool.
Maven
Specify the dependency in the project’s pom.xml
file:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
Gradle
Specify the dependency in the project build.gradle
file as testImplementation
:
testImplementation 'org.seleniumhq.selenium:selenium-java:4.8.0'
The minimum supported Python version for each Selenium version can be found
in Supported Python Versions
on PyPi
There are a couple different ways to install Selenium.
Pip
Download
Alternatively you can download the PyPI source archive
(selenium-x.x.x.tar.gz) and install it using setup.py:
Require in project
To use it in a project, add it to the requirements.txt
file:
A list of all supported frameworks for each version of Selenium
is available on Nuget
There are a few options for installing Selenium.
Packet Manager
Install-Package Selenium.WebDriver
.NET CLI
dotnet add package Selenium.WebDriver
CSProj
in the project’s csproj
file, specify the dependency as a PackageReference
in ItemGroup
:
<PackageReference Include="Selenium.WebDriver" Version="4.8.1" />
Additional considerations
Further items of note for using Visual Studio Code (vscode) and C#
Install the compatible .NET SDK as per the section above.
Also install the vscode extensions (Ctrl-Shift-X) for C# and NuGet.
Follow the instruction here
to create and run the “Hello World” console project using C#.
You may also create a NUnit starter project using the command line dotnet new NUnit
.
Make sure the file %appdata%\NuGet\nuget.config
is configured properly as some developers reported that it will be empty due to some issues.
If nuget.config
is empty, or not configured properly, then .NET builds will fail for Selenium Projects.
Add the following section to the file nuget.config
if it is empty:
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
</packageSources>
...
For more info about nuget.config
click here.
You may have to customize nuget.config
to meet you needs.
Now, go back to vscode, press Ctrl-Shift-P, and type “NuGet Add Package”, and enter the required Selenium packages such as Selenium.WebDriver
.
Press Enter and select the version.
Now you can use the examples in the documentation related to C# with vscode.
You can see the minimum required version of Ruby for any given Selenium version
on rubygems.org
Selenium can be installed two different ways.
Install manually
gem install selenium-webdriver
Add to project’s gemfile
gem 'selenium-webdriver', '= 4.8.0'
You can find the minimum required version of Node for any given version of Selenium in the
Node Support Policy
section on npmjs
Selenium is typically installed using npm.
Install locally
npm install selenium-webdriver
Add to project
In your project’s package.json
, add requirement to dependencies
:
"selenium-webdriver": "^4.8.1"
Use the Java bindings for Kotlin.
Next Step
Install the browser drivers
2 - Install browser drivers
Setting up your system to allow a browser to be automated.
Through WebDriver, Selenium supports all major browsers on the market
such as Chrome/Chromium, Firefox, Internet Explorer, Edge, and Safari.
Where possible, WebDriver drives the browser
using the browser’s built-in support for automation.
Since all the driver implementations except for Internet Explorer are provided by the
browser vendors themselves, they are not included in the standard Selenium distribution.
This section explains the basic requirements for getting started with the different browsers.
Read about more advanced options for starting a driver
in our driver configuration documentation.
Four Ways to Use Drivers
1. Selenium Manager (Beta)
Selenium v4.6
Selenium Manager helps you to get a working environment to run Selenium out of the box
(no additional downloads! no additional configurations!).
Selenium Manager attempts to obtain the most correct driver for any browser
supported by Selenium in a performant way.
Selenium Manager is currently “opt-in,” which means
that it is only used if code would otherwise fail.
That means if you manage drivers by one of the approaches below, Selenium Manager
will not be used.
2. Driver Management Software
Before Selenium Manager was created, many users turned to other projects to automatically
manage their drivers. Most of the functionality of these libraries exists natively in
the latest version of Selenium.
If you can’t use Selenium Manager because you are using
an older version of Selenium (please upgrade),
or need an advanced feature not yet implemented by Selenium Manager,
you might try one of these tools:
3. The PATH
Environment Variable
Note: we highly recommend removing drivers from PATH
and using Selenium Manager if possible.
This option first requires manually downloading the driver (See Quick Reference Section for links).
This is a flexible option to change location of drivers without having to update your code, and will work
on multiple machines without requiring that each machine put the drivers in the same place.
You can either place the drivers in a directory that is already listed in PATH
, or you can place them in a directory
and add it to PATH
.
To see what directories are already on PATH
, open a Terminal and execute:
If the location to your driver is not already in a directory listed,
you can add a new directory to PATH:
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
You can test if it has been added correctly by checking the version of the driver:
To see what directories are already on PATH
, open a Terminal and execute:
If the location to your driver is not already in a directory listed,
you can add a new directory to PATH:
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
You can test if it has been added correctly by checking the version of the driver:
To see what directories are already on PATH
, open a Command Prompt and execute:
If the location to your driver is not already in a directory listed,
you can add a new directory to PATH:
setx PATH "%PATH%;C:\WebDriver\bin"
You can test if it has been added correctly by checking the version of the driver:
chromedriver.exe --version
If your PATH
is configured correctly above,
you will see the version printed like:
ChromeDriver 111.0.5563.64 (c710e93d5b63b7095afe8c2c17df34408078439d-refs/branch-heads/5563@{#995})
If it is not found, you’ll see:
chromedriver.exe : The term 'chromedriver.exe' is not recognized as the name of a cmdlet, function, script file, or operable program
or
chromedriver: command not found
4. Hard Coded Location
Note: we highly recommend not directly referencing the drivers and using Selenium Manager if possible.
Similar to Option 3 above, you need to manually download the driver (See Quick Reference Section for links).
Specifying the location in the code itself has the advantage of not needing to figure out Environment Variables on
your system, but has the drawback of making the code much less flexible.
System.setProperty("webdriver.chrome.driver","/path/to/chromedriver");
ChromeDriver driver = new ChromeDriver();
from selenium.webdriver.chrome.service import Service
from selenium import webdriver
service = Service(executable_path="/path/to/chromedriver")
driver = webdriver.Chrome(service=service)
var driver = new ChromeDriver(@"C:\WebDriver\bin");
service = Selenium::WebDriver::Service.chrome(path: '/path/to/chromedriver')
driver = Selenium::WebDriver.for :chrome, service: service
const {Builder} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const service = new chrome.ServiceBuilder('/path/to/chromedriver');
const driver = new Builder().forBrowser('chrome').setChromeService(service).build();
import org.openqa.selenium.chrome.ChromeDriver
fun main(args: Array<String>) {
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver")
val driver = ChromeDriver()
}
Quick Reference
Browser |
Supported OS |
Maintained by |
Download |
Issue Tracker |
Chromium/Chrome |
Windows/macOS/Linux |
Google |
Downloads |
Issues |
Firefox |
Windows/macOS/Linux |
Mozilla |
Downloads |
Issues |
Edge |
Windows/macOS/Linux |
Microsoft |
Downloads |
Issues |
Internet Explorer |
Windows |
Selenium Project |
Downloads |
Issues |
Safari |
macOS High Sierra and newer |
Apple |
Built in |
Issues |
Note: The Opera driver no longer works with the latest functionality of Selenium and is currently officially unsupported.
Next Step
Create your first Selenium script
3 - Write your first Selenium script
Step-by-step instructions for constructing a Selenium script
Once you have Selenium installed and
Drivers installed, you’re ready to write Selenium code.
Eight Basic Components
Everything Selenium does is send the browser commands to do something or send requests for information.
Most of what you’ll do with Selenium is a combination of these basic commands:
1. Start the session
For more details on starting a session read our documentation on driver sessions
WebDriver driver = new ChromeDriver();
driver = webdriver.Chrome()
IWebDriver driver = new ChromeDriver();
driver = Selenium::WebDriver.for :chrome
driver = await new Builder().forBrowser('chrome').build();
2. Take action on browser
In this example we are navigating to a web page.
driver.get("https://www.selenium.dev/selenium/web/web-form.html");
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
There are a bunch of types of information about the browser you
can request, including window handles, browser size / position, cookies, alerts, etc.
String title = driver.getTitle();
var title = driver.Title;
let title = await driver.getTitle();
4. Establish Waiting Strategy
Synchronizing the code with the current state of the browser is one of the biggest challenges
with Selenium, and doing it well is an advanced topic.
Essentially you want to make sure that the element is on the page before you attempt to locate it
and the element is in an interactable state before you attempt to interact with it.
An implicit wait is rarely the best solution, but it’s the easiest to demonstrate here, so
we’ll use it as a placeholder.
Read more about Waiting strategies.
driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
driver.implicitly_wait(0.5)
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
driver.manage.timeouts.implicit_wait = 500
await driver.manage().setTimeouts({implicit: 500});
5. Find an element
The majority of commands in most Selenium sessions are element related, and you can’t interact
with one without first finding an element
WebElement textBox = driver.findElement(By.name("my-text"));
WebElement submitButton = driver.findElement(By.cssSelector("button"));
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
var textBox = driver.FindElement(By.Name("my-text"));
var submitButton = driver.FindElement(By.TagName("button"));
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
let textBox = await driver.findElement(By.name('my-text'));
let submitButton = await driver.findElement(By.css('button'));
@AfterEach
fun teardown() {
6. Take action on element
There are only a handful of actions to take on an element,
but you will use them frequently.
textBox.sendKeys("Selenium");
submitButton.click();
text_box.send_keys("Selenium")
submit_button.click()
textBox.SendKeys("Selenium");
submitButton.Click();
text_box.send_keys('Selenium')
submit_button.click
await textBox.sendKeys('Selenium');
await submitButton.click();
Elements store a lot of information that can be requested.
String value = message.getText();
var value = message.Text;
let value = await message.getText();
8. End the session
This ends the driver process, which by default closes the browser as well.
No more commands can be sent to this driver instance.
after(async () => await driver.quit());
assertEquals("Web form", title)
Putting everything together
Let’s combine these 8 things into a complete script with assertions that can be executed by a test runner.
package dev.selenium.getting_started;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class FirstScriptTest {
@Test
public void eightComponents() {
WebDriver driver = new ChromeDriver();
driver.get("https://www.selenium.dev/selenium/web/web-form.html");
String title = driver.getTitle();
assertEquals("Web form", title);
driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
WebElement textBox = driver.findElement(By.name("my-text"));
WebElement submitButton = driver.findElement(By.cssSelector("button"));
textBox.sendKeys("Selenium");
submitButton.click();
WebElement message = driver.findElement(By.id("message"));
String value = message.getText();
assertEquals("Received!", value);
driver.quit();
}
}
from selenium import webdriver
from selenium.webdriver.common.by import By
def test_eight_components():
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
title = driver.title
assert title == "Web form"
driver.implicitly_wait(0.5)
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
text_box.send_keys("Selenium")
submit_button.click()
message = driver.find_element(by=By.ID, value="message")
value = message.text
assert value == "Received!"
driver.quit()
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocs.GettingStarted
{
[TestClass]
public class FirstScriptTest
{
[TestMethod]
public void ChromeSession()
{
IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
var title = driver.Title;
Assert.AreEqual("Web form", title);
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
var textBox = driver.FindElement(By.Name("my-text"));
var submitButton = driver.FindElement(By.TagName("button"));
textBox.SendKeys("Selenium");
submitButton.Click();
var message = driver.FindElement(By.Id("message"));
var value = message.Text;
Assert.AreEqual("Received!", value);
driver.Quit();
}
}
}
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'First Script' do
it 'uses eight components' do
driver = Selenium::WebDriver.for :chrome
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
title = driver.title
expect(title).to eq('Web form')
driver.manage.timeouts.implicit_wait = 500
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
text_box.send_keys('Selenium')
submit_button.click
message = driver.find_element(id: 'message')
value = message.text
expect(value).to eq('Received!')
driver.quit
end
end
const {By, Builder, Browser} = require('selenium-webdriver');
const {suite} = require('selenium-webdriver/testing');
const assert = require("assert");
suite(function (env) {
describe('First script', function () {
let driver;
before(async function () {
driver = await new Builder().forBrowser('chrome').build();
});
after(async () => await driver.quit());
it('First Selenium script', async function () {
await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
let title = await driver.getTitle();
assert.equal("Web form", title);
await driver.manage().setTimeouts({implicit: 500});
let textBox = await driver.findElement(By.name('my-text'));
let submitButton = await driver.findElement(By.css('button'));
await textBox.sendKeys('Selenium');
await submitButton.click();
let message = await driver.findElement(By.id('message'));
let value = await message.getText();
assert.equal("Received!", value);
});
});
}, { browsers: [Browser.CHROME, Browser.FIREFOX]});
package dev.selenium.getting_started
import io.github.bonigarcia.wdm.WebDriverManager
import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
private lateinit var driver: WebDriver
@BeforeAll
fun setupAll() {
WebDriverManager.chromedriver().setup()
}
@BeforeEach
fun setup() {
driver = ChromeDriver()
}
@AfterEach
fun teardown() {
driver.quit()
}
@Test
fun eightComponents() {
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
val title = driver.title
assertEquals("Web form", title)
driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))
var textBox = driver.findElement(By.name("my-text"))
val submitButton = driver.findElement(By.cssSelector("button"))
textBox.sendKeys("Selenium")
submitButton.click()
val message = driver.findElement(By.id("message"))
val value = message.getText()
assertEquals("Received!", value)
}
}
Test Runners
If you are using Selenium for testing,
you will want to execute your Selenium code using test runner tools.
Many of the code examples in this documentation can be found in our example repositories.
There are multiple options in each language, but here is what we are using in our examples:
Install Mocha Test runner using below command in your terminal
and run your tests using below command
mocha firstScript.spec.js
Next Steps
Take what you’ve learned and build out your Selenium code.
As you find more functionality that you need, read up on the rest of our
WebDriver documentation.
4 - Upgrade to Selenium 4
Are you still using Selenium 3? This guide will help you upgrade to the latest release!
Upgrading to Selenium 4 should be a painless process if you are using one of the officially
supported languages (Ruby, JavaScript, C#, Python, and Java). There might be some cases where
a few issues can happen, and this guide will help you to sort them out. We will go through
the steps to upgrade your project dependencies and understand the major deprecations and
changes the version upgrade brings.
These are the steps we will follow to upgrade to Selenium 4:
- Preparing our test code
- Upgrading dependencies
- Potential errors and deprecation messages
Note: while Selenium 3.x versions were being developed, support for the W3C WebDriver standard
was implemented. Both this new protocol and the legacy JSON Wire Protocol were supported. Around
version 3.11, Selenium code became compliant with the level W3C 1 specification. The W3C compliant
code in the latest version of Selenium 3 will work as expected in Selenium 4.
Preparing our test code
Selenium 4 removes support for the legacy protocol and uses the W3C WebDriver standard by
default under the hood. For most things, this implementation will not affect end users.
The major exceptions are Capabilities
and the Actions
class.
Capabilities
If the test capabilities are not structured to be W3C compliant, may cause a session to not
be started. Here is the list of W3C WebDriver standard capabilities:
browserName
browserVersion
(replaces version
)
platformName
(replaces platform
)
acceptInsecureCerts
pageLoadStrategy
proxy
timeouts
unhandledPromptBehavior
An up-to-date list of standard capabilities can be found at
W3C WebDriver.
Any capability that is not contained in the list above, needs to include a vendor prefix.
This applies to browser specific capabilities as well as cloud vendor specific capabilities.
For example, if your cloud vendor uses build
and name
capabilities for your tests, you need
to wrap them in a cloud:options
block (check with your cloud vendor for the appropriate prefix).
Before
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
caps = Selenium::WebDriver::Remote::Capabilities.firefox
caps[:platform] = 'Windows 10'
caps[:version] = '92'
caps[:build] = my_test_build
caps[:name] = my_test_name
driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)
After
FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
capabilities = {
browserName: 'firefox',
browserVersion: '92',
platformName: 'Windows 10',
'cloud:options': {
build: myTestBuild,
name: myTestName,
}
}
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
options = Selenium::WebDriver::Options.firefox
options.browser_version = 'latest'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options[:build] = my_test_build
cloud_options[:name] = my_test_name
options.add_option('cloud:options', cloud_options)
driver = Selenium::WebDriver.for :remote, url: cloud_url, capabilities: options
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)
Find element(s) utility methods in Java
The utility methods to find elements in the Java bindings (FindsBy
interfaces) have been removed
as they were meant for internal use only. The following code samples explain this better.
Finding a single element with findElement*
driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));
Finding a multiple elements with findElements*
driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));
Upgrading dependencies
Check the subsections below to install Selenium 4 and have your project dependencies upgraded.
Java
The process of upgrading Selenium depends on which build tool is being used. We will cover the
most common ones for Java, which are Maven and
Gradle. The minimum Java version required is still 8.
Maven
<dependencies>
<!-- more dependencies ... -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<!-- more dependencies ... -->
</dependencies>
<dependencies>
<!-- more dependencies ... -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.4.0</version>
</dependency>
<!-- more dependencies ... -->
</dependencies>
After making the change, you could execute mvn clean compile
on the same directory where the
pom.xml
file is.
Gradle
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
useJUnitPlatform()
}
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.4.0'
}
test {
useJUnitPlatform()
}
After making the change, you could execute ./gradlew clean build
on the same directory where the build.gradle
file is.
To check all the Java releases, you can head to MVNRepository.
C#
The place to get updates for Selenium 4 in C# is NuGet. Under the
Selenium.WebDriver
package you
can get the instructions to update to the latest version. Inside of Visual Studio, through the
NuGet Package Manager you can execute:
PM> Install-Package Selenium.WebDriver -Version 4.4.0
Python
The most important change to use Python is the minimum required version. Selenium 4 will
require a minimum Python 3.7 or higher. More details can be found at the
Python Package Index. To upgrade from the
command line, you can execute:
pip install selenium==4.4.3
Ruby
The update details for Selenium 4 can be seen at the
selenium-webdriver
gem in RubyGems. To install the latest version, you can execute:
gem install selenium-webdriver
To add it to your Gemfile:
gem 'selenium-webdriver', '~> 4.4.0'
JavaScript
The selenium-webdriver package can be found at the Node package manager,
npmjs. Selenium 4 can be found
here. To install it, you
could either execute:
npm install selenium-webdriver
Or, update your package.json and run npm install
:
{
"name": "selenium-tests",
"version": "1.0.0",
"dependencies": {
"selenium-webdriver": "^4.4.0"
}
}
Potential errors and deprecation messages
Here is a set of code examples that will help to overcome the deprecation messages you might
encounter after upgrading to Selenium 4.
Java
Waits and Timeout
The parameters received in Timeout have switched from expecting (long time, TimeUnit unit)
to
expect (Duration duration)
.
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
Waits are also expecting different parameters now. WebDriverWait
is now expecting a Duration
instead of a long
for timeout in seconds and milliseconds. The withTimeout
and pollingEvery
utility methods from FluentWait
have switched from expecting (long time, TimeUnit unit)
to
expect (Duration duration)
.
new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
new WebDriverWait(driver, Duration.ofSeconds(3))
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
Merging capabilities is no longer changing the calling object
It was possible to merge a different set of capabilities into another set, and it was
mutating the calling object. Now, the result of the merge operation needs to be assigned.
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);
As a result, the options
object was getting modified.
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);
The result of the merge
call needs to be assigned to an object.
Firefox Legacy
Before GeckoDriver was around, the Selenium project had a driver implementation to automate
Firefox (version <48). However, this implementation is not needed anymore as it does not work
in recent versions of Firefox. To avoid major issues when upgrading to Selenium 4, the setLegacy
option will be shown as deprecated. The recommendation is to stop using the old implementation
and rely only on GeckoDriver. The following code will show the setLegacy
line deprecated after
upgrading.
FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);
BrowserType
The BrowserType
interface has been around for a long time, however it is getting
deprecated in favour of the new Browser
interface.
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);
C#
AddAdditionalCapability
is deprecated
Instead of it, AddAdditionalOption
is recommended. Here is an example showing this:
var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);
var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
Python
executable_path has been deprecated, please pass in a Service object
In Selenium 4, you’ll need to set the driver’s executable_path
from a Service object to prevent deprecation warnings. (Or don’t set the path and instead make sure that the driver you need is on the System PATH.)
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
driver = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, options=options)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)
Summary
We went through the major changes to be taken into consideration when upgrading to Selenium 4.
Covering the different aspects to cover when test code is prepared for the upgrade, including
suggestions on how to prevent potential issues that can show up when using the new version of
Selenium. To finalize, we also covered a set of possible issues that you can bump into after
upgrading, and we shared potential fixes for those issues.
This was originally posted at https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4