---
title: Speed Up JavaScript Capybara Specs by Blacklisting URLs
teaser: Speed up your tests by telling Capybara WebKit not to hit external APIs.
tags: web,testing,performance
author: Simon Taranto
published_on: 2014-11-14
---

On a project recently, our full test suite began to crawl (taking ~9 minutes
instead of less than 1) on our local machines running OS X but ran normally on
CI. This slowdown took our productivity to near zero. We discovered our
Capybara specs with `js: true` set were the culprit but we couldn't figure out
why.

## Finding the Problem

We needed to get more information from the tests so we set the `javascript_driver`
to `debug` mode. When using Capybara Webkit, that change looked like:

```ruby
Capybara.javascript_driver = :webkit_debug
```

After this change, when running the tests, we saw more verbose log output
revealing that the tests were running slowly due to loading external Typekits.
The specific problem was the following line in our `application.html.erb`
layout:

```html
<script type="text/javascript" src="//use.typekit.net/nco0znv.js"></script>
```

## Fixing the Problem

We didn't need to load fonts in specs so we made the below change as our first
solution to the problem:

```erb
<% unless Rails.env.test? %>
  <script type="text/javascript" src="//use.typekit.net/nco0znv.js"></script>
<% end %>
```

This update did the trick and we were back to sub-1-minute full suite runs. But,
editing the layout only for the tests felt dirty.

## A Better Way

Capybara Webkit provides a handy way to limit specific external requests.
Instead of wrapping the `script` tag in a conditional we did the following in
our `spec/rails_helper.rb` to block calls to particular <abbr title="Uniform
Resource Locator">URL</abbr>s:

```ruby
config.before(:each, js: true) do
  page.driver.browser.url_blacklist = ["http://use.typekit.net"]
end
```

With this configuration in place all requests to the listed <abbr title="Uniform
Resource Locator">URL</abbr>s return a response with an empty body and an http
status of 200. We could then remove the environment check from the layout.
Blacklisting the URL at the request level provided the added benefit of a more
thorough integration test. The environment check approach could allow for
missing methods or typos within the `unless` block that would not be surfaced
until in production.

## What's next

Read the [documentation] to learn how to get more verbose logs from Capybara.

[documentation]: https://github.com/thoughtbot/capybara-webkit/wiki/Reporting-Crashes
