55 Minutes

Welcome to the 55 Minutes blog.
55 Minutes is a web development consultancy in San Francisco building apps for design-led businesses and startups. On this blog we discuss the technology tools of our trade: Ruby on Rails, Django, Sass, OS X, and more.

Running capybara-webkit Specs with Jenkins CI

The capybara-webkit gem is a great way to test the JavaScript aspects of a Rails application. We wanted to take our tests to the next level by automating them with the Jenkins continuous integration server, but getting WebKit to run in a headless Linux environment was a bit tricky. Here’s how we did it.

Our setup

We have Jenkins deployed with the following stack:

1. Install Qt libraries

As we had already encountered on our development machines, the capybara-webkit gem won’t even install unless we have the necessary Qt libraries.

$ gem install capybara-webkit
Fetching: capybara-webkit-1.0.0.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing capybara-webkit:
  ERROR: Failed to build gem native extension.

    /home/deployer/.rbenv/versions/2.0.0-p247/bin/ruby extconf.rb
Command 'qmake -spec linux-g++' not available

Installing these libraries involves a different set of commands for each operating system, and is documented on the capybara-webkit GitHub wiki. For our Ubuntu 12.04 LTS setup, here’s what we had to do:

# as root
aptitude -y install libicu48 libqtwebkit-dev

2. Install xvfb and use it to invoke rspec

The tricker problem is that WebKit requires a display.

bundle exec rake spec
...
webkit_server: cannot connect to X server

This isn’t an issue when running specs on our Mac development environments, but on a headless Linux continuous integration server, a workaround is needed.

This workaround is a utility called Xvfb, or “X virtual framebuffer”.

# as root
aptitude -y install xvfb

To use it, we had to change how we invoke rspec by wrapping it with the xvfb-run command. Here’s the solution we added to each of our Jenkins jobs:

if type xvfb-run; then
  DISPLAY=localhost:1.0 xvfb-run bundle exec rake spec
else
  bundle exec rake spec
fi

Now our capybara-webkit specs run great on our CI server.

More best practices for Rails and Jenkins

If you’re setting up Jenkins for the first time, or looking for ways to improve your existing Rails CI approach, check out these additional resources:

  1. jenkins-ci.sh is the bash script that Jenkins invokes to test each of our Rails projects. It ensures the required Ruby is installed, creates and migrates the database as necessary, runs Rspec via xvfb, and generates a Brakeman security vulnerability report.
  2. vagrant-jenkins is a recipe for provisioning a DigitalOcean VPS and fully installing and configuring a Jenkins CI server with Rbenv, PostgreSQL, Nginx, and all the techniques described in this post. Fork the project and give it a shot!
comments powered by Disqus