Howdy developers, testers, and continuous integrators. Do you have a project involving selenium scripts to automate browser tests? Would you like to integrate those tests into your CI/CD pipeline, but aren't sure how to install browsers and webdrivers on your build server? Do you want me to stop asking rhetorical questions?
If you answered yes to any of the previous questions, read on to learn the spells to cast in your .travis.yml
file to make this happen.
A Frustrating Evening
Tonight I was working on my personal browser automation framework, LuluTest (which can be found here, I always welcome contributors). In the early days of LuluTest, I only worried about driving a Chrome browser, and never worried about other browsers.
However, because LuluTest aims to help users of all browsers, I decided it was time to implement support for Firefox (no IE or Safari yet, baby steps). In TDD fashion, I copied some old tests that were using Chrome and ran them with Firefox. Eventually, everything worked locally, and I pushed the changes to Github.
But to my chagrin, TravisCI reported a failed build. I realized it was because there was no Firefox browser or Geckodriver installed on the build server, and I began to weep. My weeping was because I remember the frustration involved in hooking up Chrome and chromedriver in Travis, and I knew it was going to be a long night.
Luckily for you, I've decided to spare everyone else the pain and show you exactly how to get Chrome, Firefox, and their relevant drivers into your build server (assuming you're using TravisCI, though I imagine the steps would be the same for other CI/CD servers).
Overview of what we'll do
Webdrivers are executables that allow us to programatically manipulate a web browser. If you've been writing browser automation tests with Selenium for long, you know that you need to either pass the path of these executables to your Webdriver
instantiations, or have the path in your system PATH variable for the test scripts to work.
This is easy enough when you're writing tests at home on your personal computer, but if we're CI/CD proponents, we want our tests to run in a build server as well. So we'll need to update or .travis.yml
file to install the relevant browsers and drivers. This all seems straightforward enough, but I spent at least an hour getting this right when really it should've taken ten minutes at most. So let me help you save some time.
Chrome and Firefox browsers
First, let's install the Google Chrome and Mozilla Firefox web browsers on our build server. In your .travis.yml
file, in the addons
section, put:
addons:
chrome: stable
firefox: latest
Why are these both slightly different from each other? I have no idea but it drives me crazy.
Luckily for us, this is all we need to do to install the browsers themselves. Installing the drivers is a little bit more involved.
Chromedriver
We're going to use the wget
program to download the chromedriver distro from Google. Then we'll unzip the distro, remove the archive, and make the driver executable.
Installation
Under the install
section of your .travis.yml
file, write:
install:
- wget -N https://chromedriver.storage.googleapis.com/80.0.3987.106/chromedriver_linux64.zip -P ~/
Depending on when you read this article, the version number might not be the most current. Since we used stable
to install the Chrome browser, we need to use the relevant driver as well. First, look up what the current version of Chrome is, then go to https://chromedriver.storage.googleapis.com/ and find the relevant version.
After you've located the version, find the relevant distro (most likely Linux, but maybe you're build server is Windows) and append it to the URL. The pattern for the URL you want to use in your wget
command is https://chromedriver.storage.googleapis.com/[RELEVANT_VERSION]/[RELEVANT_FILE]
Also note the -P ~/
at the end of the line. This downloads the compressed file to our build server's home directory. I do this because I have no earthly idea where the heck TravisCI is installing things, so I always explicitly denote what directory I want things done in.
Unzip and Clean Up
the next line in your install
section should look like this:
- unzip ~/chromedriver_linux64.zip -d ~/
Again, the -d ~/
is ensuring that the files are unzipped to the home directory. Now that we've decompressed, we'll remove the archive. This part isn't exactly necessary, but I do it anyway:
- rm ~/chromedriver_linux64.zip
Finally, let's move the executable to the /usr/local/share/
directory. Altogether, what we've done looks like this:
- wget -N https://chromedriver.storage.googleapis.com/80.0.3987.106/chromedriver_linux64.zip -P ~/
- unzip ~/chromedriver_linux64.zip -d ~/
- rm ~/chromedriver_linux64.zip
- sudo mv -f ~/chromedriver /usr/local/share/
Making the driver accessible
Now that chromedriver is in our share
directory, we need to give it executable permission, then put it in our bin directory. First, we'll use chmod
:
- sudo chmod +x /usr/local/share/chromedriver
And finally, we'll make the chromedriver executable by the build server by making a symbolic link to it in usr/local/bin
:
- sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
And that's all she wrote.
Geckodriver
Geckdriver is to Firefox what Chromedriver is to Chrome. Why? I don't know, I'm not a doctor. Anyway, the strategy for getting Geckodriver all hooked up in TravisCI is the same, but there's two tiny little differences.
Installation
The first difference is the pattern of the URL we'll feed to our wget
command. To find the latest version of Geckodriver, go to https://github.com/mozilla/geckodriver and click "releases" under "Downloads in the README. This will automatically link to the current version, which we'll use in our URL. The wget
command is:
- wget -N https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz -P ~/
Note the pattern here is download/[VERSION]/geckodriver-[VERSION]-[RELEVANT OS].[FILE EXTENSION]
. Again, note the use of -P ~/
.
Unzip and Clean Up
This download is a tarball unlike the last installation which was a zip for some reason. Because of this, the second difference is that the command to extract the archive is a little different (but not complicatedly so). Let's also remove the archive afterwards:
- tar -xzf ~/geckodriver-v0.26.0-linux64.tar.gz -C ~/
- rm ~/geckodriver-v0.26.0-linux64.tar.gz
Making the driver accessible
Everything is pretty much the same as last time from here. We'll move geckodriver
, give it execute permission, and put it in /usr/local/bin
:
- sudo mv -f ~/geckodriver /usr/local/share
- sudo chmod +x /usr/local/share/geckodriver
- sudo ln -s /usr/local/share/geckodriver /usr/local/bin/geckodriver
And voila, you should now be able to run your automated browser tests on TravisCI.
Conclusion
This all seems straightforward, but I spent too much time on it, piecing together disparate answers across SO and other parts of the internet. I hope someone out there found this helpful. Altogether, these are the things we added to our .travis.yml
file in this article:
addons:
chrome: stable
firefox: latest
install:
- wget -N https://chromedriver.storage.googleapis.com/80.0.3987.106/chromedriver_linux64.zip -P ~/
- unzip ~/chromedriver_linux64.zip -d ~/
- rm ~/chromedriver_linux64.zip
- sudo mv -f ~/chromedriver /usr/local/share/
- sudo chmod +x /usr/local/share/chromedriver
- sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
- wget -N https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz -P ~/
- tar -xzf ~/geckodriver-v0.26.0-linux64.tar.gz -C ~/
- rm ~/geckodriver-v0.26.0-linux64.tar.gz
- sudo mv -f ~/geckodriver /usr/local/share
- sudo chmod +x /usr/local/share/geckodriver
- sudo ln -s /usr/local/share/geckodriver /usr/local/bin/geckodriver