Bill Agee's blog

🤔 Reflections on test infrastructure, with a twist of user empathy.

Automatically capture browser screenshots after failed Python GhostDriver tests

GhostDriver is a fantastic tool, one which I've been happily using for a while now (and have briefly written about before).

I feel it's worth mentioning that troubleshooting GhostDriver tests can seem like a challenge in and of itself if you're used to having a browser GUI to help you visually pinpoint problems in your tests.

This post describes a technique intended to make GhostDriver troubleshooting easier: How to capture a screenshot automatically if your test raises an exception.

Just as in this blog post by Darrell Grainger, we'll be using the EventFiringWebDriver wrapper to take screenshots after test failures; but here we'll be using the Python WebDriver bindings rather than Java.

On that note, it's worth linking to the unit test script for EventFiringWebDriver found in the WebDriver Python bindings repo.

Here's the GhostDriver screenshot demo code - after running it, you should have a screenshot of the google.com homepage left behind in exception.png:

#!/usr/bin/env python

# * Note: phantomjs must be in your PATH
#
# This script:
# - Navigates to www.google.com
# - Intentionally raises an exception by searching for a nonexistent element
# - Leaves behind a screenshot in exception.png

import unittest
from selenium import webdriver
from selenium.webdriver.support.events import EventFiringWebDriver
from selenium.webdriver.support.events import AbstractEventListener

class ScreenshotListener(AbstractEventListener):
    def on_exception(self, exception, driver):
        screenshot_name = "exception.png"
        driver.get_screenshot_as_file(screenshot_name)
        print("Screenshot saved as '%s'" % screenshot_name)

class TestDemo(unittest.TestCase):
    def test_demo(self):

        pjsdriver = webdriver.PhantomJS("phantomjs")
        d = EventFiringWebDriver(pjsdriver, ScreenshotListener())

        d.get("http://www.google.com")
        d.find_element_by_css_selector("div.that-does-not-exist")

if __name__ == '__main__':
        unittest.main()

Comments