Debugging Capybara: screenshot of error page on CircleCI

Debugging Capybara: screenshot of error page on CircleCI

Having real screenshot of a failed integration spec can save hours of debugging. We had screenshot with error on the local development environment, and wanted to have it on Continuous Integration server.

Luckily for us, it’s a real no-brainer, if you use CircleCI. There is no need for custom S3 upload or some additional services. It’s just a configuration matter.

CircleCI has a concept of $CIRCLE_ARTIFACTS folder. You can put any file into this folder, and it will show all files in this folder after build is finished.

Configuring spec_helper.rb

Put this snippet into spec_helper.rb file(RSpec 3):

RSpec.configure do |config|

  # ... other configuration options

  def save_timestamped_screenshot(page, meta)
    filename = File.basename(meta[:file_path])
    line_number = meta[:line_number]

    time_now = Time.now
    timestamp = "#{time_now.strftime('%Y-%m-%d-%H-%M-%S.')}#{'%03d' % (time_now.usec/1000).to_i}"

    screenshot_name = "screenshot-#{filename}-#{line_number}-#{timestamp}.png"
    screenshot_path = "#{ENV.fetch('CIRCLE_ARTIFACTS', Rails.root.join('tmp/capybara'))}/#{screenshot_name}"

    page.save_screenshot(screenshot_path)

    puts "\n  Screenshot: #{screenshot_path}"
  end

  config.after(:each) do |example|
    if example.metadata[:js]
      save_timestamped_screenshot(Capybara.page, example.metadata) if example.exception
    end
  end

  # ... other configuration options
end

In RSpec 2 example is implicit parameter, so config.after(:each) should be slightly different:

  config.after(:each) do
    if example.metadata[:js]
      save_timestamped_screenshot(Capybara.page, example.metadata) if example.exception
    end
  end

This configuration should work for webkit, selenium, and poltergeist drivers.

Usage

Running within CircleCI environment this script will save all screenshots with integration specs failures in the $CIRCLE_ARTIFACTS folder. Here is how it looks like: brightbytes:brightbytes #19159 - CircleCI 2015-11-11 13-09-30 You can open the link and see how scenario failed on the CI.

For development environment it stores all screenshots within tmp/capybara of your Rails root folder, and outputs “Screenshot path-to-file” into the console, so it’s easy to find and check it. On the Mac it’s just:

$ open path-to-file

That’s it, folks! Hope, you will save a lot of debugging hours with this simple trick.