Using Chrome in headless mode with Selenium and Python

February 7, 2018

In a personal project I have a few functional tests that cover most used features from an end user perspective.

Until now I’ve used Selenium and PhantomJS but starting with version 3.8.1 the support for PhantomJS is now deprecated and the recommendation is to run Firefox or Chrome in a headless mode.

I’m not a big fan of having important packages pinned for compatibility reasons and as soon as I got a bit of free time I decided to replace PhantomJS for Chrome and update Selenium to the latest version.

There are basically two ways of doing it, starting Chrome directly in headless mode and setting the driver to use it, or you can just use it along with ChromeDriver, in both cases you should have Chrome installed. I prefer the latter.

A lot of posts show that you should set the absolute path to the chromedriver file while setting the driver in your could. But you can skip that by just placing the file somewhere in your search path, like /usr/bin/.

Replacing PhantomJS for Chrome required just a few extra lines in my test setUp, it went from this:

self.browser = webdriver.PhantomJS()

To this:

chrome_options = webdriver.ChromeOptions()
self.browser = webdriver.Chrome(options=chrome_options)

The additional code is responsible for adding the headless and window-size arguments when instancing the browser.

And that’s pretty much all the changes required in my code.

A small change in my Travis CI configuration file, .travis.yml, was also required. Instead of downloading PhantomJS it should now download the ChromeDriver file and place it somewhere in the search path.

Just replaced this:

  - sudo curl --output /usr/local/bin/phantomjs

For this:

  - sudo curl --output /tmp/
  - sudo unzip /tmp/ -d /usr/local/bin/

I know I could have done this in a single step, but I prefer this way.

Oh, if you are new to Selenium don’t forget to close the browser in you tearDown phase. ;)