How To Upgrade to Selenium 4
Sauce AI for Test Authoring: Move from intent to execution in second.|xBack to ResourcesBlogPosted October 12, 2021
How To Upgrade to Selenium 4
The Selenium squad has spent a full amount of clip making the upgrade process as painless as potential. A few things have been deprecated, so you might hit a couple of issues while upgrading, especially if you have progress usance functionality in your testing framework. This usher will show you how to move from Selenium 3 to Selenium 4.
Upgrading to Selenium 4 should be a painless process if you are using one of the officially supported speech (Ruby, JavaScript, C #, Python, and Java). There might be some example where a few issues can happen, and this guide will facilitate you to sort them out. We will go through the steps to upgrade your undertaking dependencies and understand the major deprecations and change the new version upgrade brings.
Note: while Selenium 3.x versions were be germinate, support for the W3C WebDriver touchstone was implemented. Both this new protocol and the legacy JSON Wire Protocol was supported. Around version 3.11, Selenium code become compliant with the Level 1 W3C Recommendation. W3C compliant code in the latest version of Selenium 3 will work as expected in Selenium 4.
Preparing our test codification
Selenium 4 remove support for the bequest protocol and uses the W3C WebDriver criterion by default under the tough. For most things, this effectuation will not involve end users. The major elision are Capabilities and the Actions class.
Capabilities
If the test capabilities are not structured to be W3C compliant, may make a session to not be started. Here is the list of W3C WebDriver standard capacity:
browserName
browserVersion (replaces version)
platformName (replaces platform)
acceptInsecureCerts
pageLoadStrategy
proxy
timeouts
unhandledPromptBehavior
An up-to-date tilt of standard capacity can be found atW3C WebDriver.
Any capability that is not contained in the tilt above, needs to include a vendor prefix. This hold to browser specific capabilities as well as. For example, if we use the build and name capability in our tests, we need to enclose them in a sauce: alternative block (a consummate example is demonstrate below).
From DesiredCapabilities to Browser Options
The use of browser Options rather of stable browser methods of DesiredCapabilities has been suggest since Selenium 3.8. Those static methods experience been withdraw in Selenium 4. This means that DesiredCapabilities.chrome () or DesiredCapabilities.firefox () and similar are not present anymore. See the examples below to transmigrate from those static methods to browser Options.
For example:
1DesiredCapabilities caps =DesiredCapabilities.chrome();2DesiredCapabilities caps =DesiredCapabilities.edge();3DesiredCapabilities caps =DesiredCapabilities.firefox();4DesiredCapabilities caps =DesiredCapabilities.internetExplorer();5DesiredCapabilities caps =DesiredCapabilities.safari();67// Are replaced by:89ChromeOptionsbrowserOptions=newChromeOptions();10EdgeOptionsbrowserOptions=newEdgeOptions();11FirefoxOptionsbrowserOptions=newFirefoxOptions();12InternetExplorerOptionsbrowserOptions=newInternetExplorerOptions();13SafariOptionsbrowserOptions=newSafariOptions();14
Using browserOptionssimplifies the configuration take to start a new session, allows setting browser-specific background (like headless in Chrome), and trim the chances of browser misconfiguration.
A complete illustration
Following, we can see a codification block with the old exercise of capability names and DesiredCapabilities. Followed by a block that demo how the code postulate to be updated.
The representative is shown in the different functionary languages supported by Selenium. When browser Options are preferred when uncommitted, platform and version are replaced by platformName and browserVersion, and Sauce Labs specific capabilities are placed inside a sauce: options cube.
Java
1DesiredCapabilities caps = DesiredCapabilities.chrome ();2DesiredCapabilities caps = DesiredCapabilities.edge ();3DesiredCapabilities caps = DesiredCapabilities.firefox ();4DesiredCapabilities caps = DesiredCapabilities.internetExplorer ();5DesiredCapabilities cap = DesiredCapabilities.safari ();67// Are replace by:89ChromeOptions browserOptions = new ChromeOptions ();10EdgeOptions browserOptions = new EdgeOptions ();11FirefoxOptions browserOptions = new FirefoxOptions ();12InternetExplorerOptions browserOptions = new InternetExplorerOptions ();13SafariOptions browserOptions = new SafariOptions ();14
JavaScript
1// Before:23caps ={};4caps[& # x27; browserName & # x27;]=& # x27; Firefox & # x27;;5caps[& # x27; platform & # x27;]=& # x27; Windows 10 & # x27;;6caps[& # x27; version & # x27;]=& # x27; 92 & # x27;;7caps[& # x27; build & # x27;]=myTestBuild;8caps[& # x27; name & # x27;]=myTestName;910//After:1112capableness={13browserName:& # x27; firefox & # x27;,14browserVersion:& # x27; 92 & # x27;,15platformName:& # x27; Windows 10 & # x27;,16& # x27; sauce: selection & # x27;:{17build:myTestBuild,18name:myTestName,19}20}21
C#
1// Before:23DesiredCapabilities crest = new DesiredCapabilities ();4caps.SetCapability (& quot; browserName & quot;, & quot; firefox & quot;);5caps.SetCapability (& quot; platform & quot;, & quot; Windows 10 & quot;);6caps.SetCapability (& quot; version & quot;, & quot; 92 & quot;);7caps.SetCapability (& quot; build & quot;, myTestBuild);8caps.SetCapability (& quot; name & quot;, myTestName);9var driver = new RemoteWebDriver (new Uri (SauceURL), capableness);1011// After:1213var browserOptions = new FirefoxOptions ();14browserOptions.PlatformName = & quot; Windows 10 & quot;;15browserOptions.BrowserVersion = & quot; 92 & quot;;16var sauceOptions = new Dictionary & lt; string, object & gt; ();17sauceOptions.Add (& quot; build & quot;, myTestBuild);18sauceOptions.Add (& quot; name & quot;, myTestName);19browserOptions.AddAdditionalOption (& quot; sauce: options & quot;, sauceOptions);20var driver = new RemoteWebDriver (new Uri (SauceURL), options);21
Ruby
1// Before:23caps = Selenium::WebDriver::Remote::Capabilities.firefox4caps[:platform]=& # x27; Windows 10 & # x27;5caps[:version]=& # x27; 92 & # x27;6caps[:build]=my_test_build7caps[:name]=my_test_name8driver = Selenium::WebDriver.for:remote, url: sauce_url,desired_capabilities: caps910// After:1112options = Selenium::WebDriver::Options.firefox13options.browser_version=& # x27; latest & # x27;14options.platform_name=& # x27; Windows 10 & # x27;15sauce_options={}16sauce_options[:build]=my_test_build17sauce_options[:name]=my_test_name18options.add_option(& # x27; sauce: choice & # x27;,sauce_options)19driver = Selenium::WebDriver.for:remote, url: sauce_url,capabilities: options20
Python
1// Before:23caps ={}4caps[& # x27; browserName & # x27;]=& # x27; firefox & # x27;5caps[& # x27; platform & # x27;]=& # x27; Windows 10 & # x27;6caps[& # x27; variant & # x27;]=& # x27; 92 & # x27;7caps[& # x27; build & # x27;]=my_test_build8caps[& # x27; name & # x27;]=my_test_name9driver = webdriver.Remote(sauce_url,desired_capabilities=caps)1011// After:1213from selenium.webdriver.firefox.options import Options asFirefoxOptions14options =FirefoxOptions()15options.browser_version=& # x27; 92 & # x27;16options.platform_name=& # x27; Windows 10 & # x27;17sauce_options={}18sauce_options[& # x27; build & # x27;]=my_test_build19sauce_options[& # x27; name & # x27;]=my_test_name20options.set_capability(& # x27; sauce: options & # x27;,sauce_options)21driver = webdriver.Remote(sauce_url, options=options)22
For more combinations and examples, check theSauce Labs program configurator.
Find element (s) utility methods in Java
The utility methods to discover component in the Java bindings (FindsByinterface) have been removed as they were meant for internal use only. The following code sample excuse this best.
Pro tip: Tools like SUSA can handle this autonomously — upload your app and get results without writing a single test script.
1// Before:23driver.findElementByClassName (& quot; className & quot;);4driver.findElementByCssSelector (& quot; .className & quot;);5driver.findElementById (& quot; elementId & quot;);6driver.findElementByLinkText (& quot; linkText & quot;);7driver.findElementByName (& quot; elementName & quot;);8driver.findElementByPartialLinkText (& quot; partialText & quot;);9driver.findElementByTagName (& quot; elementTagName & quot;);10driver.findElementByXPath (& quot; xPath & quot;);1112// After:1314driver.findElement (By.className (& quot; className & quot;));15driver.findElement (By.cssSelector (& quot; .className & quot;));16driver.findElement (By.id (& quot; elementId & quot;));17driver.findElement (By.linkText (& quot; linkText & quot;));18driver.findElement (By.name (& quot; elementName & quot;));19driver.findElement (By.partialLinkText (& quot; partialText & quot;));20driver.findElement (By.tagName (& quot; elementTagName & quot;));21driver.findElement (By.xpath (& quot; xPath & quot;));2223// All the findElements * hold been removed as well.2425//Before:2627driver.findElementsByClassName (& quot; className & quot;);28driver.findElementsByCssSelector (& quot; .className & quot;);29driver.findElementsById (& quot; elementId & quot;);30driver.findElementsByLinkText (& quot; linkText & quot;);31driver.findElementsByName (& quot; elementName & quot;);32driver.findElementsByPartialLinkText (& quot; partialText & quot;);33driver.findElementsByTagName (& quot; elementTagName & quot;);34driver.findElementsByXPath (& quot; xPath & quot;);3536// After:3738driver.findElements (By.className (& quot; className & quot;));39driver.findElements (By.cssSelector (& quot; .className & quot;));40driver.findElements (By.id (& quot; elementId & quot;));41driver.findElements (By.linkText (& quot; linkText & quot;));42driver.findElements (By.name (& quot; elementName & quot;));43driver.findElements (By.partialLinkText (& quot; partialText & quot;));44driver.findElements (By.tagName (& quot; elementTagName & quot;));45driver.findElements (By.xpath (& quot; xPath & quot;));46
Upgrading dependencies
Check the subsections below to install Selenium 4 and have your project dependencies upgraded.
Java
The process of upgrading Selenium look on which build tool is being used. We will continue the most common ones for Java, which areMaven and Gradle. The minimum Java version required is still 8.
Maven
1// Before:23<dependencies>4<!--more dependencies...-->5<dependency>6<groupId>org.seleniumhq.selenium</groupId>7<artifactId>selenium-java</artifactId>8<version>3.141.59</version>9</dependency>10<!--more habituation...-->11</dependencies>1213// After:1415<dependencies>16<!--more dependencies...-->17<dependency>18<groupId>org.seleniumhq.selenium</groupId>19<artifactId>selenium-java</artifactId>20<version>4.0.0</version>21</dependency>22<!--more dependencies...-->23</dependencies>24
After create the change, you could executemvn clean compileon the same directory where thepom.xml file is.
Gradle
1// Before:23plugins {4id & # x27; java & # x27;5}67group & # x27; org.example & # x27;8version & # x27; 1.0-SNAPSHOT & # x27;910deposit{11mavenCentral()12}1314dependencies{15testImplementation& # x27; org.junit.jupiter: junit-jupiter-api:5.7.0 & # x27;16testRuntimeOnly& # x27; org.junit.jupiter: junit-jupiter-engine:5.7.0 & # x27;17implementation group:& # x27; org.seleniumhq.selenium & # x27;,name:& # x27; selenium-java & # x27;,version:& # x27; 3.141.59 & # x27;18}1920test {21useJUnitPlatform()2223}2425// After:2627plugins {28id & # x27; java & # x27;29}3031group & # x27; org.example & # x27;32version & # x27; 1.0-SNAPSHOT & # x27;3334repositories{35mavenCentral()36}3738dependencies{39testImplementation& # x27; org.junit.jupiter: junit-jupiter-api:5.7.0 & # x27;40testRuntimeOnly& # x27; org.junit.jupiter: junit-jupiter-engine:5.7.0 & # x27;41effectuation group:& # x27; org.seleniumhq.selenium & # x27;,name:& # x27; selenium-java & # x27;,version:& # x27; 4.0.0 & # x27;42}4344test {45useJUnitPlatform()46}47
After making the change, you could fulfill ./gradlew clean build
on the same directory where the build.gradle file is.
To check all the Java releases, you can lead toMVNRepository.
C#
The place to get update for Selenium 4 in C # isNuGet. Under theSelenium.WebDriver packetyou can get the instructions to update to the latest version. Inside of Visual Studio, through the NuGet Package Manager you can execute:
PM & gt; Install-Package Selenium.WebDriver -Version 4.0.0
Python
The most crucial change to use Python is the minimum required variant. Selenium 4 will require a minimum Python 3.7 or high. More details can be found at thePython Package Index. To upgrade from the command line, you can execute:
pip install selenium==4.0.0
Ruby
The update details for Selenium 4 can be seen at theselenium-webdrivergem in RubyGems. To install the modish version, you can execute:
gem install selenium-webdriver
To add it to your Gemfile:
gem & # x27; selenium-webdriver & # x27;, & # x27; ~ & gt; 4.0.0 & # x27;
JavaScript
The selenium-webdriver package can be found at the Node package manager,npmjs. Selenium 4 can be foundhere. To install it, you could either execute:
npm install selenium-webdriver
Or, update your package. json and run npm install:
{
& quot; name & quot;: & quot; selenium-tests & quot;,
& quot; version & quot;: & quot; 1.0.0 & quot;,
& quot; dependencies & quot;: {
& quot; selenium-webdriver & quot;: & quot; ^4.0.0 & quot;
}
}
Possible Errors and Deprecation Messages
Here is a set of codification examples that will help to overcome the deprecation messages you might encounter after upgrading to Selenium 4.
Java
Waits and Timeout
The parameters obtain in Timeout have switched from expecting (long time, TimeUnit unit) to expect (Duration length).
1// Before:23driver.manage () .timeouts () .implicitlyWait (10, TimeUnit.SECONDS);4driver.manage () .timeouts () .setScriptTimeout (2, TimeUnit.MINUTES);5driver.manage () .timeouts () .pageLoadTimeout (10, TimeUnit.SECONDS);67// After:89driver.manage () .timeouts () .implicitlyWait (Duration.ofSeconds (10));10driver.manage () .timeouts () .scriptTimeout (Duration.ofMinutes (2));11driver.manage () .timeouts () .pageLoadTimeout (Duration.ofSeconds (10));12
Waits are also expecting different parameters now. WebDriverWait is now expecting a Duration instead of a long for timeout in seconds and millisecond. The withTimeout and pollingEvery utility methods from FluentWait have shift from expecting (long time, TimeUnit unit) to expect (Duration duration).
1// Before:23new WebDriverWait (driver, 3)4.until (ExpectedConditions.elementToBeClickable (By.cssSelector (& quot; # id & quot;)));56Wait & lt; WebDriver & gt; wait = new FluentWait & lt; WebDriver & gt; (driver)7.withTimeout (30, TimeUnit.SECONDS)8.pollingEvery (5, TimeUnit.SECONDS)9.ignoring (NoSuchElementException.class);1011// After:1213new WebDriverWait (driver, Duration.ofSeconds (3))14.until (ExpectedConditions.elementToBeClickable (By.cssSelector (& quot; # id & quot;)));1516Wait & lt; WebDriver & gt; wait = new FluentWait & lt; WebDriver & gt; (driver)17.withTimeout (Duration.ofSeconds (30))18.pollingEvery (Duration.ofSeconds (5))19.ignoring (NoSuchElementException.class);20
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 ring object. Now, the result of the merge operation want to be assigned.
1// Before:23MutableCapabilities potentiality = new MutableCapabilities ();4capabilities.setCapability (& quot; platformVersion & quot;, & quot; Windows 10 & quot;);5FirefoxOptions options = new FirefoxOptions ();6options.setHeadless (true);7options.merge (capableness);89// As a result, the options object was become modify.10// After:1112MutableCapabilities capabilities = new MutableCapabilities ();13capabilities.setCapability (& quot; platformVersion & quot;, & quot; Windows 10 & quot;);14FirefoxOptions pick = new FirefoxOptions ();15options.setHeadless (true);16options = options.merge (capacity);17
The resolution of themergecall needs to be allot to an objective.
Firefox Legacy
Before GeckoDriver was around, the Selenium labor had a driver implementation to automate Firefox (adaptation & lt; 48). However, this execution is not need anymore as it does not act in recent edition of Firefox. To avoid major issues when upgrading to Selenium 4, thesetLegacyselection will be shown as depreciate. The recommendation is to quit using the old implementation and rely only on GeckoDriver. The following code will show thesetLegacyline deprecated after upgrading.
FirefoxOptions options = new FirefoxOptions ();
options.setLegacy (true);
BrowserType
The BrowserType interface has be around for a long time, withal it is getting deprecated in favor of the new Browser interface.
1// Before:23MutableCapabilitiescapability=newMutableCapabilities();4potentiality.setCapability(& quot; browserVersion & quot;,& quot; 92 & quot;);5capabilities.setCapability(& quot; browserName & quot;,BrowserType.FIREFOX);67// After:89MutableCapabilitiescapacity=newMutableCapabilities();10capabilities.setCapability(& quot; browserVersion & quot;,& quot; 92 & quot;);11capabilities.setCapability(& quot; browserName & quot;,Browser.FIREFOX);12
C#
AddAdditionalCapability is depreciate. Instead, AddAdditionalOption is recommended. Here is an example showing this:
1// Before:23var browserOptions = new ChromeOptions ();4browserOptions.PlatformName = & quot; Windows 10 & quot;;5browserOptions.BrowserVersion = & quot; up-to-the-minute & quot;;6var sauceOptions = new Dictionary & lt; string, object & gt; ();7browserOptions.AddAdditionalCapability (& quot; sauce: options & quot;, sauceOptions, true);89// After:1011var browserOptions = new ChromeOptions ();12browserOptions.PlatformName = & quot; Windows 10 & quot;;13browserOptions.BrowserVersion = & quot; modish & quot;;14var sauceOptions = new Dictionary & lt; string, object & gt; ();15browserOptions.AddAdditionalOption (& quot; sauce: options & quot;, sauceOptions);16
Summary
We move 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 edition of Selenium. To finalize, we also covered a set of possible issues that you can bump into after upgrading, and we share potential fixture for those issues.
Sr. Developer Experience Engineer, Sauce Labs
Staff Software Engineer at Sauce Labs
Share this post
Automate This With SUSA
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.
Try SUSA FreeTest Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free
