Wednesday, July 4, 2012

Creating a screen capture on every action

Someone recently commented on an article I wrote about generating a screen capture when an exception is thrown (see Generating a screen capture on exception thrown with Selenium 2).

Performing an action when an exception is thrown is built into the Selenium framework. You just need to create the action to generate a screen capture and hook it into the framework.

The Selenium framework comes with a WebDriverEventListener interface. In my article above I created an implementation of the WebDriverEventListener interface. To do this properly, you need to implement the following methods:
beforeNavigateTo(String url, WebDriver driver);
afterNavigateTo(String url, WebDriver driver);
beforeNavigateBack(WebDriver driver);
afterNavigateBack(WebDriver driver);
beforeNavigateForward(WebDriver driver);
afterNavigateForward(WebDriver driver);
beforeFindBy(By by, WebElement element, WebDriver driver);
afterFindBy(By by, WebElement element, WebDriver driver);
beforeClickOn(WebElement element, WebDriver driver);
afterClickOn(WebElement element, WebDriver driver);
beforeChangeValueOf(WebElement element, WebDriver driver);
afterChangeValueOf(WebElement element, WebDriver driver);
beforeScript(String script, WebDriver driver);
afterScript(String script, WebDriver driver);
onException(Throwable throwable, WebDriver driver);
In my screen capture when an exception is thrown, I put the necessary code to generate a screen capture in the onException method. You can see from the list above that you can have Selenium perform an action when other events occur. For example, if you wanted to do a screen capture after each click() action, you could write:

public void afterClickOn(WebElement element, WebDriver driver) {
    String filename = generateRandomFilenameFromWebElementAndDriver(element, driver);
    createScreenCaptureJPEG(filename);
}

I'll leave it to the reader to figure out how to create the generateRandomFilenameFromWebElementAndDriver. You might do something like use getCurrentUrl(), convert things like colon, slash, etc. into valid filename characters then append the web element getTagName() to the end of the filename.

Or you could do something tricky like have the beforeClickOn generate the filename and the afterClickOn use that filename to generate the screen capture.

If the event you want to trigger a screen capture is not listed above, there is no easy answer for how you would do it.

Initially, you might considering changing the WebDriverEventListener interface. But this would require a change to how Selenium works. Every time there is a new release of Selenium, you would have to merge your changes back in.

I would recommend submitting the changes as a new feature to the Selenium project to see if they'll incorporate it or wrap the Selenium methods with your own methods. For example, you would call your sendKeys() which could do a driver.sendKeys then do a screen capture.

3 comments:

  1. Thank you for this wonderful article. The listener in this case is when you actually invoke API on the registered driver instance. Would you know how to capture user activities (click, keypress, etc.) on the launch browser itslef back into the code? Meaning when you do driver.open("") on say forefox driver, a firefox instance will be launched and it says webdriver on red on the bottom. Now if you navigate to any webpage the driver is always up to date on the current URL. How do you register a listener that captures user's interactions in the java code? (Similar to record & play) I appreciate any pointers on this.

    ReplyDelete
  2. Shahryar, click the link above to go to the original article: http://darrellgrainger.blogspot.ca/2011/02/generating-screen-capture-on-exception.html.

    ReplyDelete
  3. Thanks for your reply. Just saw it after all these months. The event listener described here, captures the events generated by the Selenium API. For example, element.click() will notify the listener. I am still searching for a clean way to do the reverse. Meaning when the user clicks on an element, I would like to capture that event in Java code. Thanks,

    --Rex

    ReplyDelete

Note: Only a member of this blog may post a comment.