Skip to main content

_ruby

Example

Let's start by including our requisite libraries (selenium-webdriver to drive the browser and rspec/expectations & RSpec::Matchers for our assertion) and wire up some simple setup and teardown methods.

# filename: screenshot.rb

require 'selenium-webdriver'
require 'rspec/expectations'
include RSpec::Matchers

def setup
@driver = Selenium::WebDriver.for :firefox
end

def teardown
@driver.quit
end

Next we'll want to create a method to execute our tests. This is where we'll capture when a failure occurs and take a screenshot.

def run
setup
begin
yield
rescue RSpec::Expectations::ExpectationNotMetError => error
puts error.message
@driver.save_screenshot "./#{Time.now.strftime("failshot__%d_%m_%Y__%H_%M_%S")}.png"
end
teardown
end

After calling setup and before calling teardown we wrap our test code execution (e.g., yield) in a rescue block. This handles the exception that a test failure will return. When a failure occurs the error message will get outputted to the terminal (just like it normally would) but now we are also capturing a screenshot through the help of Selenium's .save_screenshot method.

.save_screenshot accepts a filename as a string (e.g., 'failshot.png'). When this command executes it will save an image file to your local system in the current working directory.

Note the use of Time.now.strftime in the screenshot filename. This is adding a timestamp (down to the second) to the filename. This provides a (reasonably) unique file name and has the added benefit of listing the files in the order taken.

Now let's wire up our test.

run do
@driver.get 'http://the-internet.herokuapp.com'
expect(@driver.find_element(css: 'h1').text).to eql 'blah blah blah'
end

Expected Behavior

If we save this file and run it (ruby screenshot.rb from the command-line) here is what would happen:

  • Open the browser
  • Load the homepage of the-internet
  • Check the text of the page header and fail
  • Output a failure message in the terminal
  • Capture a timestamped screenshot in the current working directory
  • Close the browser

Summary

For more info on strftime (a.k.a. String Formatted Time) go here.

But if you want truly unique filenames, then you should use a unique ID in the filename instead of a timestamp (e.g., something like uuid). This will prevent screenshots from getting overwritten when you have two (or more) tests taking screenshots at the same time.