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:
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:
<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:
<% 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 URLs:
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 URLs 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.