---
title: 'capybara-webkit doesn''t like #fork'
teaser: Tips for using capybara-webkit with cucumber suites and forking.
tags: web,open source,unix,javascript,ruby,rails,capybara-webkit
author: Jon Yurek
published_on: 2011-10-13
---

Recently, when helping to convert a feature suite to use
[capybara-webkit](https://github.com/thoughtbot/capybara-webkit), we ran into a
problem where, about halfway through, the tests would start erroring out with
[`Errno::EPIPE`](http://www.ruby-doc.org/core-1.9.2/Errno.html).

`Errno::EPIPE` is a "Broken Pipe" error. [A pipe in Unix is a way for data to
flow](http://www.economist.com/node/2724348) from one process to another, and a
broken pipe means that one end of the pipe isn't connected anymore. In this
case, the pipe was broken because the webkit-server process that capybara-webkit
uses went away. And since well-behaved processes don't normally go away unless
you ask them to, we assumed it was crashing.

With a little of digging, we found the feature that was causing the problem.
Annoyingly, the error never popped up when the feature was run alone, meaning it
was the interaction of multiple features or steps. After whittling away the
options, we found the right situation to force the error: a feature using
capybara-webkit followed by one specific scenario in a different feature (which,
oddly, didn't use any Javascript at all). Being able to reliably reproduce the
error is a big step towards finding a solution.

Knowing what scenario we were dealing with, we could find the specific step that
was the source of the problem. The step makes a call to
[`fork`](http://www.ruby-doc.org/core-1.9.2/Kernel.html#method-i-fork). The way
that capybara-webkit closes the browser when the tests are over is by using an
[`at_exit`](http://www.ruby-doc.org/core-1.9.2/Kernel.html#method-i-at_exit)
hook, which is called when Ruby is just about to close. Forking a process clones
everything about it, including, in the case of Ruby, its `at_exit` hooks. So,
what happened was that the fork executed what it needed to execute and then
exited like normal, but it meant that it took the webkit-server process with it
because of the `at_exit` hooks it inherited, leaving no browser to run the
javascript-enabled features.

This was good news, though. The webkit-server process wasn't crashing! It was
behaving exactly like it was expected to, but just a little premature. To get
around the `at_exit` hooks, we call
[`exit!`](http://www.ruby-doc.org/core-1.9.2/Kernel.html#method-i-exit-21) in
the forked process, which specifically bypasses `at_exit` hooks. This lets our
fork get on with its work, and it keeps the server running for the rest of the
test suite to use.

So, if you're in the position where you have to fork in a cucumber suite and
you're using capybara-webkit, make sure you `exit!` from the fork, and you'll
save yourself some headaches. If you can help fix this problem for good, [pull
requests are welcome](https://github.com/thoughtbot/capybara-webkit/issues/192).
