Testing Rails Applications with Capybara Webkit

Modern applications use Javascript. You can make rich user interfaces that are faster and more responsive.

Since we all do TDD, we need to test our Javascript. There are plenty of approaches. It used to be a pain, but there’s no excuse any more.

If you’re using Capybara to go through the UI of a modern web application, perhaps with Cucumber, there’s going to be Javascript in that UI and you need to run it.

The default driver for Capybara is Rack::Test, which is pretty simple. It can follow redirects and do 90% of what you need but the remaining 10% is the shiny part, the Javascript part.

As an example, say you have a form that uses Javascript to auto-fill an “account name” field based on what you fill in for the “email address” field. If you used Capybara with just Rack::Test, the integration test won’t pass.

Selenium runs your test in a real browser. Someone took the time to write software that starts up Firefox, which is hard enough as a user, installs an extension so you can remote control it, and exposes a JSON REST API so you can communicate with it from your tests. It works with Capybara. All of that’s awesome.

However, it’s slow. There’s also no real API for assessing what went wrong.

So, thoughtbot made Capybara Webkit.

Capybara Webkit is fast. It uses the Webkit engine, not a real browser UI. You can do console.log output. You can see errors in standard output.

It’s mostly easy to install.

Gemfile:

gem "capybara-webkit"

features/support/env.rb:

Capybara.javascript_driver = :webkit

However, you also have to install Qt. Instructions for OS X and Linux are in the README. If you’re on Windows, God help you.

Capybara Webkit is still young, however.

All the tests are asynchronous so you still need Capybara’s retrying methods.

It’s much younger than Selenium so there are some bugs that they’ve worked out that we haven’t. The issues queue is very active.

Capybara Webkit is built around a cool library called QtWebkit, which is a headless browser acting as a server that listens for commands using a lightweight socket layer. So when you boot up your test suite, that server also starts in a background process. Our Ruby driver implements the Capybara API and communicates with that server.

Webkit is open source, powers Safari, Chrome, and other browsers. It’s fast and standards-compliant.

It’s not a browser itself, and calling it a browser engine is even a stretch. It’s really a set of libraries for building a browser. It’s not packaged as a standalone library.

There is no ‘WebKit’ as a single library. We use QtWebKit because it’s the most complete at filling in the blanks to make a unified browser library.

Qt is a C++ library and a bunch of tools to make C++ development suck less.

QtWebkit appears like it was written so that Nokia could build a mobile Webkit browser. It has lots of injection points and hooks, a nice API, and is well documented. Webkit itself is not documented so this was a big win. Instead of building a browser with it, we used it to build a test harness.