WebDriver Event Listener : Take Screenshot On Exception

When you execute selenium automation testing scripts, there are a lot of times that you want to do something when an event happened. For example:

  1. Take screenshots when an exception occurred.
  2. Monitor and track the web element status after some action takes place.
  3. Log data before or after an action.
  4. Log the navigation url to check if the navigation logic is correct.
  5. Log web element status to check if the javascript executes correctly.

In this article, we will show you how to use the webdriver event listener and how to take screenshots when an exception happened in selenium test scripts.

1. Selenium Provide Below Interface Or Class For Event Listening.

  1. WebDriverEventListener: This is an interface.
  2. AbstractWebDriverEventListener: This is an abstract class.
  3. EventFiringWebDriver: This is the wrapper class for the webdriver object, after wrapping, you can register the event listener object to it.

1.1 Steps To Register Event Listener.

  1. Create a Listener class either by implementing the WebDriverEventListener interface like below.
    public class Dev2qaWebDriverEventListener implements WebDriverEventListener
    {
          ......
    }

    Or extend AbstractWebDriverEventListener abstract class like below.

    public class Dev2qaWebDriverEventListener extends AbstractWebDriverEventListener
    {
         ......
    }
  2. The difference between the above two methods is that you need to implement all methods when choose to implement the WebDriverEventListener interface, and you only need to implement the methods you need when choosing to extend the AbstractWebDriverEventListener abstract class. You can click here to see a detailed introduction for the methods of the above interface or abstract class.
  3. Implement the listening event java code in the related event method. Such as beforeClickOn(WebElement webElement, WebDriver driver) or onException(Throwable error, WebDriver driver) like below.
    @Override
    public void beforeClickOn(WebElement webElement, WebDriver driver) {
    	System.out.println("Before click, lement text : " + webElement.getText() + " , tag name: " + webElement.getTagName());
    }
    
  4. Wrap the webdriver object to create the EventFiringWebDriver object.
    /* Initiate Firefox driver. */
    this.webDriver = new FirefoxDriver();
    		
    /* Initiate wrapping object. */
    this.eventWebDriver = new EventFiringWebDriver(this.webDriver);
  5. Create a new event listener object for the class in step1.
    /* Create a event listener object. */
    this.eventListener = new Dev2qaWebDriverEventListener();
  6. Register event listener to the EventFiringWebDriver object.
    /* Register event listener. */
    this.eventWebDriver.register(eventListener);

1.2 Code Example.

  1. There are two java classes and two Html pages in the below example.
  2. Dev2qaWebDriverEventListener.java: This is the event listener class, it extends AbstractWebDriverEventListener class. It only implements some of the AbstractWebDriverEventListener class methods. In most of the implemented class methods, it only prints out log info. And in the onException method, it will take a screenshot and save it to C:\\Workspace\\webdriverEventListenerScreenshot.png.
    public class Dev2qaWebDriverEventListener extends AbstractWebDriverEventListener {
    
    	@Override
    	public void afterClickOn(WebElement webElement, WebDriver driver) {
    		System.out.println("afterClickOn trigger, " + this.getWebElementInfo(webElement));
    	}
    
    	@Override
    	public void afterFindBy(By by, WebElement webElement, WebDriver driver) {
    		System.out.println("afterFindBy trigger, Condition : " + by.toString() + this.getWebElementInfo(webElement));
    	}
    
    	@Override
    	public void afterNavigateBack(WebDriver driver) {
    		System.out.println("afterNavigateBack trigger.");
    	}
    
    	@Override
    	public void afterNavigateTo(String url, WebDriver driver) {
    		System.out.println("afterNavigateTo trigger, navigate to : " + url);
    	}
    
    	@Override
    	public void beforeClickOn(WebElement webElement, WebDriver driver) {
    		System.out.println("beforeClickOn trigger, " + this.getWebElementInfo(webElement));
    	}
    
    	@Override
    	public void beforeFindBy(By by, WebElement webElement, WebDriver driver) {
    		
    		System.out.println("beforeFindBy trigger, Condition : " + by.toString() + this.getWebElementInfo(webElement));
    	}
    
    	@Override
    	public void beforeNavigateTo(String url, WebDriver driver) {
    		System.out.println("beforeNavigateTo trigger , navigate to : " + url);
    	}
    
    	@Override
    	public void onException(Throwable throwable, WebDriver driver) {
    		try
    		{
    			/* Take screenshot when exception happened. */
    			File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    			/* save screenshot to file. */
    			FileUtils.copyFile(scrFile, new File("C:\\Workspace\\webdriverEventListenerScreenshot.png"));
    		}catch(IOException ex)
    		{
    			ex.printStackTrace();
    		}
    	}
    
    	@Override
    	public void beforeNavigateBack(WebDriver driver) {
    		System.out.println("beforeNavigateBack trigger. ");
    	}
    
    	@Override
    	public void afterChangeValueOf(WebElement element, WebDriver driver) {
    		System.out.println("afterChangeValueOf trigger. " + this.getWebElementInfo(element));
    	}
    
    	@Override
    	public void beforeChangeValueOf(WebElement element, WebDriver driver) {
    		System.out.println("beforeChangeValueOf trigger. " + this.getWebElementInfo(element));
    	}
    	
    	
    	/* This is a util method that can print webelement's information in console. */
    	private String getWebElementInfo(WebElement element)
    	{
    		String ret = "";
    		if(element!=null)
    		{
    			ret = "element name: " + element.getAttribute("name") + " , element value: " + element.getAttribute("value") + " , tag name : " + element.getTagName();
    		}
    		return ret;
    	}
    }
  3. WebDriverEventListenerExample.java: This is a TestNG class, it creates the event listener, EventFiringWebDriver object, and registers the listener to the object. All of the initialization java code in the @BeforeClass decorated method is as below.
    @BeforeClass
    /* Initiate listener, webdriver and regiser listener. */
    public void beforeClass() {
    		
    	/* Initiate Firefox driver. */
    	this.driver = new FirefoxDriver();
    		
    	/* Initiate wrapper class object. */
    	this.eventWebDriver = new EventFiringWebDriver(this.driver);
    
    	/* Create a event listener object. */
    	eventListener = new Dev2qaWebDriverEventListener();
    
    	/* Register listener. */
    	this.eventWebDriver.register(eventListener);
    	
    	/* Maximaze Firefox browser window. */
    	this.eventWebDriver.manage().window().maximize();
    }
  4. Below is the test method.
    @Test
    public void testWebDriverEventListener() {
    	/* Browse an example page. Test script will automatically input user name and password and then click submit button.
    	 * When submit there will popup a javascript Alert dialog. To run this example, you should copy below page to your C:/WorkSpace directory. */
    	this.eventWebDriver.get("file://C:/WorkSpace/webdriverEventListener.html");
    		
    	/* Input username.*/
    	By userNameById = By.id("userName");
    	WebElement userNameWebElement = this.eventWebDriver.findElement(userNameById);
    	userNameWebElement.sendKeys("Jerry");
    		
    	/* Input password.*/
    	By passwordById = By.id("password");
    	WebElement passwordWebElement = this.eventWebDriver.findElement(passwordById);
    	passwordWebElement.sendKeys("dev2qa.com");
    		
    	/* Click submit. This will trigger a javascript alert and then submit the form. */
    	By submitById = By.id("submitBtn");
    	WebElement submitWebElement = this.eventWebDriver.findElement(submitById);
    		
    	/* Because after click submit button, current page change to webdriverEventListenerSuccess.html.
    	 * There is no submit button element in webdriverEventListenerSuccess.html, so there will throw an exception
    	 * in the listener's afterClickOn method. Then the listener's onException method will be triggered.
    	 * And it will take a screenshot and save to hard disk.
    	 * */
    	submitWebElement.click();
    	
    }
  5. webdriverEventListener.html: Below is the page source code. You can input the username and password on this page. After that when you click the submit button, it will go to another page webdriverEventListenerSuccess.html. To run this java example, you need to save these two Html pages under C:/WorkSpace/webdriver/EventListener folder.
    <form action="webdriverEventListenerSuccess.html" method="post">
    UserName: <input type="text" id="userName" name="userName"/><br/>
    Password: <input type="password" id="password" name="password"/><br/>
    <input type="submit" value="Submit" id="submitBtn" name="submitBtn"/>
    </form>

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.