capybara-webkit doesn't like #fork
Recently, when helping to convert a feature suite to use capybara-webkit, we ran into a problem where, about halfway through, the tests would start erroring out with
Errno::EPIPE is a "Broken Pipe" error. A pipe in Unix is a way for data to flow 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.
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. The way that capybara-webkit closes the browser when the tests are over is by using an
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
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! 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.