Capybara and Poltergeist: Snap!
11 Dec 2012
I’ve gotten a lot of mileage out of RSpec plus Capybara for integration testing my Ruby apps lately.
Executing JavaScript with Capybara used to be a pain, but I recently switched from capybara-webkit to Poltergeist as my JS test driver.
Poltergeist uses PhantomJS, which in my experience is faster than capybara-webkit and easier to install.1
Poltergeist supports the required Capybara driver API as well as a few additional features such as taking screenshots.
I wrote a little helper method around taking screenshots, which:
- generates a name for the output file (because I usually don’t care)
- puts the file in the trash for me (or in /tmp if there is no trash)
- renders the entire page (overridable when I just want the viewport)
- opens it in Preview (or whatever the default app for .png is)
Not ground breaking, but pretty cool in practice. I call it snap!
.2 Here’s the method:
def snap!(options={})
path = options.fetch :path, "~/.Trash"
file = options.fetch :file, "#{Time.now.to_i}.png"
full = options.fetch :full, true
path = File.expand_path path
path = "/tmp" if !File.exists?(path)
uri = File.join path, file
page.driver.render uri, full: full
system "open #{uri}"
end
Drop it anywhere that RSpec will load it3 and use it in your integration tests when your JavaScript is misbehaving:
feature "search autocomplete" do
scenario "from the homepage", js: true do
visit "/"
fill_in "search", with: "Jero"
snap!
expect(page).to have_content "Jerod Santo"
end
end
In this example, you could visually inspect whether the autocomplete is just not showing up at all or if it is showing up and just has the wrong content in it.
A fringe benefit of using the snap!
method is that it calls page.driver.render
, which will raise an error when the active driver doesn’t have the method.
Capybara’s default driver, RackTest, doesn’t have it so you’ll know right away if your test is just failing because you forgot the js: true
flag in the enclosing block.
That one has bit me more than once!