Introduction
While Rails makes testing a breeze, JavaScript testing requires a bit of extra work. This post was written for minitest, but it should be easy to adapt for RSpec.
Initial Setup: Capybara and Poltergeist
For integration testing, I use Capybara, an acceptance test framework that can be used to simulate user interaction. While this works great for testing standard pages, the default driver does not execute JavaScript. The built-in Selenium JavaScript driver launches Firefox and performs testing by clicking around inside the GUI, but this is less performant than a headless browser like PhantomJS. I use Poltergeist, a Capybara driver for PhantomJS.
To set up Capybara and Poltergeist, add them both to your gemfile and add the following lines to your test helper.
I like to create a JavaScriptUtilities module to make it easier to write JavaScript tests. All I have to do is call require_js in the test setup, and it takes care of switching the driver back to default afterwards.
Ajax Test Failures
I quickly found that Capybara was not always waiting for Ajax requests to complete. Ryan Bigg had a similar problem, but I was unable to get his solution to work. I came up with a kludge using HTML attributes. I set a waiting attribute to be true, wait for the ajaxSuccess event to be fired, and then set the waiting attribute to be false. The loop will not break until this attribute is set to false or it times out.
Conclusion
I hope this is helpful for those of you trying to write JavaScript tests. If you have any questions or comments, please let me know. You can find me on Twitter.