Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Selenium WebDriver 3.0

You're reading from   Mastering Selenium WebDriver 3.0 Boost the performance and reliability of your automated checks by mastering Selenium WebDriver

Arrow left icon
Product type Paperback
Published in Jun 2018
Publisher Packt
ISBN-13 9781788299671
Length 376 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Mark Collin Mark Collin
Author Profile Icon Mark Collin
Mark Collin
Arrow right icon
View More author details
Toc

Table of Contents (15) Chapters Close

Preface 1. Creating a Fast Feedback Loop FREE CHAPTER 2. Producing the Right Feedback When Failing 3. Exceptions Are Actually Oracles 4. The Waiting Game 5. Working with Effective Page Objects 6. Utilizing the Advanced User Interactions API 7. JavaScript Execution with Selenium 8. Keeping It Real 9. Hooking Docker into Selenium 10. Selenium – the Future 11. Other Books You May Enjoy Appendix A: Contributing to Selenium 1. Appendix B: Working with JUnit 2. Appendix C: Introduction to Appium

Downloading WebDriver binaries automatically

I came across this problem a few years ago, and at the time there wasn't an easy way to get hold of the binaries using Maven. I didn't find an elegant solution to this problem, so I did what anybody who is into open source software would do: I wrote a plugin to do it for me.

This plugin allows you to specify a series of driver binaries to automatically download and remove the manual setup steps. It also means that you can enforce the version of driver binaries that are used, which removes lots of intermittent issues caused by people using different versions of the binaries that can behave differently on different machines.

We are now going to enhance our project to use this plugin; the new project structure will look like this:

Let's start by tweaking our POM; we will use the following code to create a new property that we will call overwrite.binaries and a new property to set the version of the plugin:

<properties>
<project.build.sourceEncoding>UTF-
8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-
8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!-- Dependency versions -->
<selenium.version>3.12.0</selenium.version>
<testng.version>6.14.3</testng.version>
<!-- Plugin versions -->
<driver-binary-downloader-maven-plugin.version>1.0.17
</driver-binary-downloader-maven-plugin.version>
<maven-compiler-plugin.version>3.7.0
</maven-compiler-plugin.version>
<maven-failsafe-plugin.version>2.21.0
</maven-failsafe-plugin.version>
<!-- Configurable variables -->
<threads>1</threads>
<browser>firefox</browser>
<overwrite.binaries>false</overwrite.binaries>
</properties>

We then need to add the driver-binary-downloader plugin by using the following code:

<plugin>
<groupId>com.lazerycode.selenium</groupId>
<artifactId>driver-binary-downloader-maven-plugin</artifactId>
<version>${driver-binary-downloader-maven-plugin.version}
</version>
<configuration>
<rootStandaloneServerDirectory>${project.basedir}
/src/test/resources/selenium_standalone_binaries
</rootStandaloneServerDirectory>
<downloadedZipFileDirectory>${project.basedir}
/src/test/resources/selenium_standalone_zips
</downloadedZipFileDirectory>
<customRepositoryMap>${project.basedir}
/src/test/resources/RepositoryMap.xml
</customRepositoryMap>
<overwriteFilesThatExist>${overwrite.binaries}
</overwriteFilesThatExist>
</configuration>
<executions>
<execution>
<goals>
<goal>selenium</goal>
</goals>
</execution>
</executions>
</plugin>

Finally, we need to add some new system properties to our maven-failsafe-plugin configuration by using the following code:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<configuration>
<parallel>methods</parallel>
<threadCount>${threads}</threadCount>
<systemPropertyVariables>
<browser>${browser}</browser>
<!--Set properties passed in by the driver binary
downloader-->
<webdriver.chrome.driver>${webdriver.chrome.driver}
</webdriver.chrome.driver>
<webdriver.ie.driver>${webdriver.ie.driver}
</webdriver.ie.driver>
<webdriver.opera.driver>${webdriver.opera.driver}
</webdriver.opera.driver>
<webdriver.gecko.driver>${webdriver.gecko.driver}
</webdriver.gecko.driver>
<webdriver.edge.driver>${webdriver.edge.driver}
</webdriver.edge.driver>
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>

The plugin runs in the TEST_COMPILE phase by default. The order it is placed in the POM should not matter, as there shouldn't be any tests actually running in this phase. The new overwite.binaries property that we have added allows us to set the overwriteFilesThatExist configuration setting of the driver-binary-downloader-maven-plugin. By default, it will not overwrite files that already exist. This gives us an option to force the plugin to overwrite existing files if we want to download a new binary version or just refresh our existing binaries.

We have two more configuration settings that are just specifying file paths. The downloadedZipFileDirectory setting is used to specify the file path that will be used to download the binary ZIP files. The rootStandaloneServerDirectory setting is the file path where we extract the driver binaries.

Next, we will use customRepositoryMap to point at a customRepositoryMap.xml. This customRepositoryMap.xml is where download locations for all the binaries we want to download are stored.

Finally, we have added some system properties variables to maven-failsafe-plugin to expose the locations of the binaries when they have been downloaded. driver-binary-downloader-maven-plugin will set a Maven variable that will point to the location of the downloaded binaries. Even though it looks like the variables we are using to set our system properties don't exist, it will be fine.

This is where we have been slightly clever; we have set system properties that Selenium will use automatically to find the location of the driver binaries. This means that we don't need to add any additional code to make things work.

We now need to create RepositoryMap.xml to define the download locations for our binaries; we will probably also need to create the src/test/resources folder since we haven't used it before. The following code has a basic RepositoryMap.xml using the default download locations for the binaries:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<root>
<windows>
<driver id="internetexplorer">
<version id="3.9.0">
<bitrate sixtyfourbit="true">
<filelocation>http://selenium-
release.storage.googleapis.com/3.9/
IEDriverServer_x64_3.9.0.zip</filelocation>
<hash>c9f885b6a339f3f0039d670a23f998868f539e65
</hash>
<hashtype>sha1</hashtype>
</bitrate>
<bitrate thirtytwobit="true">
<filelocation>http://selenium-
release.storage.googleapis.com/3.9/
IEDriverServer_Win32_3.9.0.zip</filelocation>
<hash>dab42d7419599dd311d4fba424398fba2f20e883
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
<driver id="edge">
<version id="5.16299">
<bitrate sixtyfourbit="true" thirtytwobit="true">
<filelocation>https://download.microsoft.com/
download/D/4/1/D417998A-58EE-4EFE-A7CC-
39EF9E020768/MicrosoftWebDriver.exe
</filelocation>
<hash>60c4b6d859ee868ba5aa29c1e5bfa892358e3f96
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
<driver id="googlechrome">
<version id="2.37">
<bitrate thirtytwobit="true" sixtyfourbit="true">
<filelocation>
https://chromedriver.storage.googleapis.com/
2.37/chromedriver_win32.zip</filelocation>
<hash>fe708aac4eeb919a4ce26cf4aa52a2dacc666a2f
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
<driver id="operachromium">
<version id="2.35">
<bitrate sixtyfourbit="true">
<filelocation>https://github.com/operasoftware
/operachromiumdriver/releases/download/v.2.35
/operadriver_win64.zip</filelocation>
<hash>180a876f40dbc9734ebb81a3b6f2be35cadaf0cc
</hash>
<hashtype>sha1</hashtype>
</bitrate>
<bitrate thirtytwobit="true">
<filelocation>https://github.com/operasoftware/
operachromiumdriver/releases/download/v.2.35/
operadriver_win32.zip</filelocation>
<hash>55d43156716d7d1021733c2825e99896fea73815
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
<driver id="marionette">
<version id="0.20.0">
<bitrate sixtyfourbit="true">
<filelocation>
https://github.com/mozilla/geckodriver/
releases/download/v0.20.0/
geckodriver-v0.20.0-win64.zip</filelocation>
<hash>e96a24cf4147d6571449bdd279be65a5e773ba4c
</hash>
<hashtype>sha1</hashtype>
</bitrate>
<bitrate thirtytwobit="true">
<filelocation>
https://github.com/mozilla/geckodriver
/releases/download/v0.20.0/
geckodriver-v0.20.0-win32.zip</filelocation>
<hash>9aa5bbdc68acc93c244a7ba5111a3858d8cbc41d
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
</windows>
<linux>
<driver id="googlechrome">
<version id="2.37">
<bitrate sixtyfourbit="true">
<filelocation>https://chromedriver.storage.
googleapis.com/2.37/
chromedriver_linux64.zip</filelocation>
<hash>b8515d09bb2d533ca3b85174c85cac1e062d04c6
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
<driver id="operachromium">
<version id="2.35">
<bitrate sixtyfourbit="true">
<filelocation>
https://github.com/operasoftware/
operachromiumdriver/releases/download/
v.2.35/operadriver_linux64.zip</filelocation>
<hash>
f75845a7e37e4c1a58c61677a2d6766477a4ced2
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
<driver id="marionette">
<version id="0.20.0">
<bitrate sixtyfourbit="true">
<filelocation>
https://github.com/mozilla/geckodriver/
releases/download/v0.20.0/geckodriver-v0.20.0-
linux64.tar.gz</filelocation>
<hash>
e23a6ae18bec896afe00e445e0152fba9ed92007
</hash>
<hashtype>sha1</hashtype>
</bitrate>
<bitrate thirtytwobit="true">
<filelocation>
https://github.com/mozilla/geckodriver/
releases/download/v0.20.0/geckodriver-v0.20.0-
linux32.tar.gz</filelocation>
<hash>
c80eb7a07ae3fe6eef2f52855007939c4b655a4c
</hash>
<hashtype>sha1</hashtype>
</bitrate>
<bitrate arm="true">
<filelocation>
https://github.com/mozilla/geckodriver/
releases/download/v0.20.0/geckodriver-v0.20.0-
arm7hf.tar.gz</filelocation>
<hash>
2776db97a330c38bb426034d414a01c7bf19cc94
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
</linux>
<osx>
<driver id="googlechrome">
<version id="2.37">
<bitrate sixtyfourbit="true">
<filelocation>
https://chromedriver.storage.googleapis.com/
2.37/chromedriver_mac64.zip</filelocation>
<hash>
714e7abb1a7aeea9a8997b64a356a44fb48f5ef4
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
<driver id="operachromium">
<version id="2.35">
<bitrate sixtyfourbit="true">
<filelocation>
https://github.com/operasoftware/
operachromiumdriver/releases/download/v.2.35/
operadriver_mac64.zip</filelocation>
<hash>
66a88c856b55f6c89ff5d125760d920e0d4db6ff
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
<driver id="marionette">
<version id="0.20.0">
<bitrate thirtytwobit="true" sixtyfourbit="true">
<filelocation>
https://github.com/mozilla/geckodriver/
releases/download/v0.20.0/geckodriver-v0.20.0-
macos.tar.gz</filelocation>
<hash>
87a63f8adc2767332f2eadb24dedff982ac4f902
</hash>
<hashtype>sha1</hashtype>
</bitrate>
</version>
</driver>
</osx>
</root>
This is a big file; it may be easier to copy and paste the latest revision in the driver-binary-downloader README.md on GitHub: https://github.com/Ardesco/selenium-standalone-server-plugin/blob/master/README.md.

If you are on a corporate network that does not allow you to access the outside world, you can of course download the binaries and put them on a local file server. You can then update your RepositoryMap.xml to point at this local file server instead of the internet. This gives you a great deal of flexibility.

Right, let's run our project again to check that everything works; first of all use this code:

mvn clean verify -Dthreads=2 

You will notice that everything worked as normal, despite the fact that we are no longer setting the webdriver.gecko.driver system property on the command line. Next, let's see whether we can now select chrome and have everything still just work by using the following code:

mvn clean verify -Dthreads=2 -Dbrowser=chrome 

This time, you should see two Chrome browsers open up instead of Firefox ones. You may have noticed that the first time you ran this it downloaded a series of binaries, which may have slowed down the first run. This time around though, it had already downloaded them, so it just checked they were there and the test run completed a lot quicker. We no longer have to worry about setting any system properties because this is automatically being done by the plugin modifications we made in our POM file.

We can now give anybody access to our code, and when they check it and run it, things should just work.

You have been reading a chapter from
Mastering Selenium WebDriver 3.0 - Second Edition
Published in: Jun 2018
Publisher: Packt
ISBN-13: 9781788299671
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image