Debugging Poltergeist and PhantomJS

Posted by Anton Katunin on 27 May 2015
Tags: code

Recently at Opensight we had weird issue with our integration tests. When we run single test it succeeds, but when whole suit it fails.

It was failing on the same "terms and conditions" page where we expect 'Accept' button: could not find element Accept

click_button 'Accept'

So we started digging. First of all I've verified that response from all requests is the same.

after_filter do
  puts response.body
end

And in fact it was the same all the time.

The next step was to verify what html is received by PhantomJS

puts "html=#{page.html}"
click_button 'Accept'

Strangely enough the first time it was proper html, but after it was empty html.

<html><head></head><body></body></html>

Very strange indeed. The next step was to debug PhantomJS and Poltergeist.

Poltergeist has the option to debug network requests, so we can print to log.

page.driver.network_traffic.each do |r|
  r.response_parts.each do |resp|
    puts resp.inspect
  end
end
page.driver.clear_network_traffic
click_button 'Accept'

After looking at response code, we've found that the first request it gets 200 Ok response code. But the following requests to the same page 304 Non modified.

Aha! Bingo! It looks it's something to do with caching. Let's try to enable disk-cache.

Capybara.register_driver :poltergeist do |app|
  Capybara::Poltergeist::Driver.new(app,
    :phantomjs_options => ['--disk-cache=true'],
  )
end
Capybara.javascript_driver = :poltergeist

Bingo Two!! Now the whole test suit works as expected.

Summary

It seems like a bug in PhantomJS 2.0 so that cache is not stored, while it should be.


Read next:

Circular dependency in Rails