views:

989

answers:

3

I am trying to capture screenshots on test failure using selenium-client and rspec. I run this command:

$ spec my_spec.rb \
--require 'rubygems,selenium/rspec/reporting/selenium_test_report_formatter' \
--format=Selenium::RSpec::SeleniumTestReportFormatter:./report.html

It creates the report correctly when everything passes, since no screenshots are required. However, when the test fails, I get this message, and the report has blank screenshots:

WARNING: Could not capture HTML snapshot: execution expired
WARNING: Could not capture page screenshot: execution expired
WARNING: Could not capture system screenshot: execution expired
Problem while capturing system stateexecution expired

What is causing this 'execution expired' error? Am I missing something important in my spec? Here is the code for my_spec.rb:

require 'rubygems'
gem "rspec", "=1.2.8"
gem "selenium-client"
require "selenium/client"
require "selenium/rspec/spec_helper"

describe "Databases" do
    attr_reader :selenium_driver
    alias :page :selenium_driver

  before(:all) do
      @selenium_driver = Selenium::Client::Driver.new \
          :host => "192.168.0.10",
          :port => 4444,
          :browser => "*firefox",
          :url => "http://192.168.0.11/",
          :timeout_in_seconds => 10
  end

  before(:each) do
    @selenium_driver.start_new_browser_session
  end

  # The system capture need to happen BEFORE closing the Selenium session
  append_after(:each) do
    @selenium_driver.close_current_browser_session
  end

  it "backed up" do
    page.open "/SQLDBDetails.aspx
    page.click "btnBackup", :wait_for => :page
    page.text?("Pending Backup").should be_true
  end
end
A: 

Why not take the screenshot in the after function, but before you close the browser?

Patrick Lightbody
According to the documentation, the SeleniumTestReportFormatter is supposed to take care of the screenshots on failure. And it does (almost). Whenever a test fails, it tries to take a screenshot. The problem is that it takes the screenshot after the browser session is released.Manually taking the screenshot in the after function would be an acceptable workaround, but I couldn't find any documentation on how to do it with selenium-client and rspec. Do you know how to do it?
Thomas Albright
Sorry, I'm not familiar with SeleniumTestReportFormatter. I'm a Java guy :P However, there should be a "take screenshot" command. There certainly is in the Java client. It returns the screenshot as a base64 encoded string that you have to decode and write out to a file.
Patrick Lightbody
+1  A: 

I ran into that issue and was able to solve it by setting up the timeout for the driver. This can cause the Driver to end the Browser session before running into :after_each You are using 10 seconds, i am running fine with :timeout_in_seconds => 2000

hp
My problem isn't fixed by changing the timeout_in_seconds. In fact, timeout_in_seconds is what often catches a failing test in the first place. In this example, the test fails if the page does not load the "Pending Backup" text within a certain time. At that point, the test fails, so the SeleniumTestReportFormatter should grab a screenshot.If I increase the timeout_in_seconds command to 2000 seconds, that just makes the test take 2000 seconds before it fails, at which point I get the same error about not being able to grab the screenshot.
Thomas Albright
A: 

In order to get screenshots on error working I had to mod things a bit.

I moved the following code out of spec_helper (which I found in C:\Ruby\lib\ruby\gems\selenium-client-1.2.18\lib\selenium\rspec\spec_helper.rb):

    if actual_failure?
         Selenium::RSpec::SeleniumTestReportFormatter.capture_system_state(selenium_driver, self)
    end

and placed it into the append_after(:each) do section of my test's setup/teardown (before the line @selenium_driver.close_current_browser_session).

Hope this helps!

Dave H