Running python tests with GhostDriver in Travis CI

on Feb 18, 2013 by Ramona

Selenium is great by itself, but its API grows every day - it’s not obvious anymore whether to use “type” or “typeKeys”. 

So Google has come up with a new API - WebDriver - which is integrated within Selenium 2.0. Rather than being a JavaScript application running within the browser, WebDriver uses whichever mechanism is most appropriate to control the browser - for Firefox, it’s an extension; for IE, WebDriver makes use of IE's Automation controls and so on. By changing the way the browser is controlled, WebDriver manages to overcome some of the restrictions put in place by the JavaScript security model.

Selenium WebDriver
Selenium 2.0 has integrated the WebDriver API, thus combining the advantages of both technologies - Selenium has support for many common situations you might want to test, and WebDriver drives the browser directly (unlike Selenium RC, which simply injects JavaScript into the browser), using the browser's built-in support for automation.
Hence, there is more to Selenium than it might seem at a first glance, and things have evolved over the years. The addition of WebDriver, iPhoneDriver, ChromeDriver, etc., has made it easier for test engineers to view Selenium as the tool of choice for automating testing on their products.
And the best is yet to come...
We all know that Selenium is a great tool, but we also know that sometimes it takes much more time than desired to actually see all tests have completely run.
So, how about a headless browser?
Running Selenium scripts headless is now easier than before, if using PhantomJS & GhostDriver. Of course, you can still use xvfb (or even better PyVirtualDisplay wrapper) for GUI headless tests.
GhostDriver is a pure JavaScript implementation of the WebDriver Wire Protocol for PhantomJS. It's a Remote WebDriver that uses PhantomJS as back-end. Ok, so what’s PhantomJS?
PhantomJS is a headless WebKit with JavaScript API. As you know, WebKit is the layout engine that Chrome, Safari and other browsers use. So, PhantomJS is a browser, but a headless one. This means that the rendered web pages are never actually displayed.
Let’s give it a try and see how can we set up the environment for GhostDriver & PhantomJS.
  1. PhantomJS
  • On Windows:
    • Download PhantomJS from here and extract it.
    • Add the folder to the system path and run phantomjs --version in a new command prompt. You should see the actual version (just to verify there are no errors so far).
  • On Linux (Ubuntu) - command line:
cd /usr/local/share
tar xjf phantomjs-1.8.1-linux-x86_64.tar.bz2
sudo ln -s /usr/local/share/phantomjs-1.8.1-linux-x86_64/bin/phantomjs /usr/local/share/phantomjs
sudo ln -s /usr/local/share/phantomjs-1.8.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs
sudo ln -s /usr/local/share/phantomjs-1.8.1-linux-x86_64/bin/phantomjs /usr/bin/phantomjs

It is important that you have installed version 1.8*, because GhostDriver is not integrated into PhantomJS’s older versions.

  1. Start GhostDriver by setting phantomjs --webdriver=PORT, where PORT can be any available port. You should see a successful message, indicating that GhostDriver is running on port PORT.
  2. Configure your test environment to use PhantomJS:
  • For example, create a folder structure like:
    • headless_testing, containing a subfolder test, where I will add my selenium scripts written with Python
    • Add the following two files inside test folder:
      • (but delete the first two lines - there's no need for these as we will place all py files in the same folder):
import sys
sys.path.insert(0, "utils")
  • Modify the file as follows:
    • replace port 8080 with the port where GhostDriver is running for you (line 59)
    • replace open("../config.ini") with open("test/config.ini"(line 40)
  • Add your own selenium python script to the same test folder. Make sure your methods are named as test_*, so that you can run them using unittest module.
  • Add a config.ini file in the test folder, containing driver=phantomjs. In this way, you’re telling Selenium it should use the headless PhantomJS browser. If you don't want your config.ini file to be mixed up with the python scripts, you could add it to a separate folder, and modify the file accordingly.
  • pip install discover ( the test discovery mechanism and load_tests protocol for unittest backported from Python 2.7 to work with Python 2.4 or more recent (including Python 3).)
Give it a try: while in headless_testing folder, open a command prompt window and run:
python -m unittest discover -s test --pattern=test*.py
GhostDriver in Travis CI
And since automation tests are most valuable in a CI server, here’s an example of how you could set up selenium scripts with PhantomJS on Travis CI.
  • Log in to Travis with GitHub and enable service hooks for the repositories you want added to Travis. More details here.
  • On your local machine, drill inside headless_testing folder and add a file called .travis.yml - this is the config file that will tell Travis how to run your selenium python scripts:


language: python

- "2.7"

install: "pip install -r requirements.txt --use-mirrors"

- "python -m unittest discover -s test --pattern=test*.py"

- "python test/"
  • Add this to the requirements.txt file (separate lines): selenium==2.28.0 and discover==0.4.0
  • The script is a script I created in order to be able to start GhostDriver and get the control back (so that you are able to run other commands from the command line as well). The content of this script is:


import os
os.system('phantomjs --webdriver=PORT 2>&1 > log.txt &')
#os.system('phantomjs --webdriver=PORT 2>&1 > /dev/null &')
  • Travis comes with PhantomJS configured, so no other action is needed in this direction.​​
  • Make sure to add the file inside headless_testing/test folder. What it does is that it starts a process in the background and it captures the output in the log.txt file. Adding the & ensures the fact that you will gain control back in the command line. Only two lines will be written inside the log file, so you shouldn’t worry about it too much.
  • Push the content of the headless_testing folder to GitHub (you might want to use a .gitignore file as well).
Travis will detect the new push and as soon as an worker is available, it will start building your code. You will be able to see the output in real time and enjoy the benefits of headless testing with PhantomJS&GhostDriver.
Please have a look as well at the GitHub repository we've created for PhantomJS&GhostDriver.

Tags: testing selenium python automated ci travis | Category: testing , python Back To Top

comments powered by Disqus