follow me icons

Sunday, September 26, 2010

Screenshots capture using capybara and webdriver

Recently, I stumble upon a task on how to automatically capture a screenshot when one of my cucumber scenario fails. I use capybara and webdriver for my automation test.

I found several solutions which include to use a program called scrot in ubuntu and to use another gem http://github.com/mocoso/cucumber-screenshot. However, I run my automation test in both Windows and Ubuntu and therefore I need a way to be able to capture screenshot in both OS.

Webdriver fortunately already has this module implemented in the driver class. Although this only supports firefox browser, it is enough for me as I run the automation in Hudson with firefox and I would want to embed the screenshot in the cucumber html report.

After do |scenario| 
if scenario.failed?
File.open("./screenshots/#{scenario.name}.jpeg",'wb') do |f|
f.write(Base64.decode64(page.driver.browser.screenshot_as(:base64)))
end
end
end

The webdriver class already has the save_screenshot methods, but it does not work in Windows and therefore you need to write the file as byte.

The above code will automatically capture a screenshot whenever the scenario.failed? is true. This is very useful for error reporting because if you run your test in Hudson, you would not be able to see your test running.

8 comments:

  1. where should we write following code for getting screenshot.I mean in which file and its location?

    After do |scenario| if scenario.failed? File.open("./screenshots/#{scenario.name}.jpeg", 'wb') do |f| f.write(Base64.decode64(page.driver.browser.screenshot_as(:base64))) end endend

    ReplyDelete
  2. Hi Muhammad,

    That's a good question. I should have put more information on that.

    I created a file called "screenshots.rb" and I put the above code in that file.

    Then in my env.rb, I put the following code:

    require 'features/support/patches/screenshots'

    to load the screenshots.rb.

    ReplyDelete
  3. I am getting the following error.Need your suggestion on it

    No such file or directory - support/patches/screenshots/Login to Ma.jpeg

    ./support/patches/screenshots.rb:3:in `initialize'
    ./support/patches/screenshots.rb:3:in `open'
    ./support/patches/screenshots.rb:3:in `After':in `initialize'
    ./support/patches/screenshots.rb:3:in `initialize'
    ./support/patches/screenshots.rb:3:in `open'
    ./support/patches/screenshots.rb:3:in `After':in `open'
    ./support/patches/screenshots.rb:3:in `initialize'
    ./support/patches/screenshots.rb:3:in `open'
    ./support/patches/screenshots.rb:3:in `After':in `After'

    ReplyDelete
  4. I am not sure about that error. But it seems that your scenario filename has a space "Login to Ma.jpeg"
    'support/patches/screenshots/Login to Ma.jpeg' and that could be the reason for 'no such file or directory' errors.

    You can try changing the code to use the same name first instead of using 'scenario.name' to see if it works.

    '
    After do |scenario|
    if scenario.failed?
    File.open("./screenshots/test.jpeg",'wb') do |f|
    f.write(Base64.decode64(page.driver.browser.screenshot_as(:base64)))
    end
    end
    end
    '

    Let me know if it works or not. Could you also provide me with more information on how you run your script or any other information about the errors?

    ReplyDelete
  5. No It doesnot work.Do we need any specific gem for it.

    My feature file is placed in feature folder
    SCreenshot.rb is in features\support\patches\

    I am using the command like that

    cucumber RSGMappingStaticFieldsMedHx094.feature -r support -r step_definition --format html --out=aaa.html

    and getting the following error

    No such file or directory - ./screenshots/LogintoMappingTool.jpeg (Errno::ENOENT)
    ./features/support/patches/screenshots.rb:3:in `initialize'
    ./features/support/patches/screenshots.rb:3:in `open'
    ./features/support/patches/screenshots.rb:3:in `After'
    No such file or directory - ./screenshots/Ma.jpeg (Errno::ENOENT)
    ./support/patches/screenshots.rb:3:in `initialize'
    ./support/patches/screenshots.rb:3:in `open'
    ./support/patches/screenshots.rb:3:in `After'
    uninitialized constant CucumberScreenshot::World::RAILS_ROOT (NameError)
    ./lib/ruby/gems/1.8/gems/activesupport-2.3.9/lib/active_support/dependencies.rb:466:in `load_missing_constant'
    C:/Ruby187/lib/ruby/gems/1.8/gems/activesupport-2.3.9/lib/active_support/dependencies.rb:106:in `const_missing'
    C:/Ruby187/lib/ruby/gems/1.8/gems/cucumber-screenshot-0.3.4/lib/cucumber_screenshot/world.rb:9:in `base_screenshot_directory_name'
    C:/Ruby187/lib/ruby/gems/1.8/gems/cucumber-screenshot-0.3.4/lib/cucumber_screenshot/world.rb:12:in `screenshot'
    C:/Users/mtahir/Desktop/cucumberexamplerun/features/support/cucumber_screenshot_env.rb:7:in `After'

    ReplyDelete
  6. Sorted now actually location was wrong.

    Thanks
    M

    ReplyDelete
  7. How can we take the whole browser screenshot, not the page alone. I want the whole desktop screenshot when a scenario fails.

    ReplyDelete