Webdriver Event Listener example

Webdriver events are helpful to view the events triggered by webdriver. It also plays an important role in analyzing results and helps us in debugging issues if we encounter any.

Selenium webdriver has ability to track different events such as 'beforeNavigateTo' , 'afterNavigateTo' , 'beforeClickOn' , 'afterClickOn', 'onException' and so on. When ever we develop test scripts we can write our own implementation for handling events during the execution.

For example, we can count the number of clicks that we have performed in the script by adding logic to count clicks after each click 'afterClickOn'. We can also when ever there is an exception using 'onException'.

Let us now look into example by taking the help of class "EventFiringWebDriver" - which is a wrapper around an arbitrary WebDriver instance which supports registering of a WebDriverEventListener for logging purposes.

Now firstly we have to initialize 'EventFiringWebDriver' by passing webdriver instance and then we need to register event listener for EventFiringWebDriver instance.

We also need to provide implementation for the events. We can do this by two ways, which ever is needed for our project.

One way is by using WebDriverEventListener Interface If we use this, it will implement all the events that are supported by Webdriver.

An example for this is shown below, when we use this, it will implement all the events like 'beforeNavigateTo', 'afterNavigateTo', 'beforeClickOn' , 'afterClickOn', 'onException' and more such events

package com.example;

/*************************************** PURPOSE **********************************

 - This class implements the WebDriverEventListener, which is included under events.
 The purpose of implementing this interface is to override all the methods and define certain useful  Log statements 
 which would be displayed/logged as the application under test is being run.

 Do not call any of these methods, instead these methods will be invoked automatically
 as an when the action done (click, findBy etc). 

 */

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.events.WebDriverEventListener;

public class WebEventListener implements WebDriverEventListener {

	public void beforeNavigateTo(String url, WebDriver driver) {
		System.out.println("Before navigating to: '" + url + "'");
	}

	public void afterNavigateTo(String url, WebDriver driver) {
		System.out.println("Navigated to:'" + url + "'");
	}

	public void beforeChangeValueOf(WebElement element, WebDriver driver) {
		System.out.println("Value of the:" + element.toString()
				+ " before any changes made");
	}

	public void afterChangeValueOf(WebElement element, WebDriver driver) {
		System.out.println("Element value changed to: " + element.toString());
	}

	public void beforeClickOn(WebElement element, WebDriver driver) {
		System.out.println("Trying to click on: " + element.toString());
	}

	public void afterClickOn(WebElement element, WebDriver driver) {
		System.out.println("Clicked on: " + element.toString());
	}

	public void beforeNavigateBack(WebDriver driver) {
		System.out.println("Navigating back to previous page");
	}

	public void afterNavigateBack(WebDriver driver) {
		System.out.println("Navigated back to previous page");
	}

	public void beforeNavigateForward(WebDriver driver) {
		System.out.println("Navigating forward to next page");
	}

	public void afterNavigateForward(WebDriver driver) {
		System.out.println("Navigated forward to next page");
	}

	public void onException(Throwable error, WebDriver driver) {
		System.out.println("Exception occured: " + error);
	}

	public void beforeFindBy(By by, WebElement element, WebDriver driver) {
		System.out.println("Trying to find Element By : " + by.toString());
	}

	public void afterFindBy(By by, WebElement element, WebDriver driver) {
		System.out.println("Found Element By : " + by.toString());
	}

	/*
	 * non overridden methods of WebListener class
	 */
	public void beforeScript(String script, WebDriver driver) {
	}

	public void afterScript(String script, WebDriver driver) {
	}

}
And other way is by using Class AbstractWebDriverEventListener If we use this class we can include only those events which we are interested.

An example for this is shown below, if you observer we have implemented only 5 events, 'beforeNavigateTo', 'afterNavigateTo', 'beforeClickOn' , 'afterClickOn' and 'onException'

package com.example;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.events.AbstractWebDriverEventListener;

public class WebEventListener extends AbstractWebDriverEventListener {

	public void beforeNavigateTo(String url, WebDriver driver) {
		System.out.println("Before navigating to: '" + url + "'");
	}

	public void afterNavigateTo(String url, WebDriver driver) {
		System.out.println("Navigated to:'" + url + "'");
	}

	public void beforeClickOn(WebElement element, WebDriver driver) {
		System.out.println("Trying to click on: " + element.toString());
	}

	public void afterClickOn(WebElement element, WebDriver driver) {
		System.out.println("Clicked on: " + element.toString());
	}

	public void onException(Throwable error, WebDriver driver) {
		System.out.println("Error occurred: " + error);
	}
}

Now let us try to use in our program. From the above two options, here we will use 'AbstractWebDriverEventListener' and implement the above 5 methods to understand the example

package com.example;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.events.EventFiringWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class EventListenerExample {

	private WebDriver driver;
	private EventFiringWebDriver e_driver;
	private WebEventListener eventListener;
	private WebDriverWait wait;
	private String appURL = "http://www.google.com";
	public int waitTime = 10;
	private String headerText = "One account. All of Google.";
	private String errMessage = "The email and password you entered don't match.";

	@BeforeClass()
	public void setUp() {

		// Initializing instance of Firefox WebDriver
		driver = new FirefoxDriver();
		wait = new WebDriverWait(driver, waitTime);

		// Initializing EventFiringWebDriver using Firefox WebDriver instance
		e_driver = new EventFiringWebDriver(driver);

		// Now create object of EventListerHandler to register it with EventFiringWebDriver
		eventListener = new WebEventListener();

		e_driver.register(eventListener);
	
		e_driver.manage().window().maximize();
		e_driver.get(appURL);
	}

	@Test
	public void testEventsONE() {
		System.out.println("***** Executing Test ONE ***** ");
		e_driver.findElement(By.linkText("Gmail")).click();
		String pageHeaderText = e_driver.findElement(By.tagName("h1")).getText();
		Assert.assertTrue(pageHeaderText.equalsIgnoreCase(headerText));
	}

	@Test
	public void testEventsTWO()  {
		System.out.println("***** Executing Test Two ***** ");
		//Entering user name and clicking on next
		e_driver.findElement(By.id("Email")).sendKeys("username");
		e_driver.findElement(By.id("next")).click();
		
		wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("Passwd")));
		//Entering password and clicking on sign-in
		e_driver.findElement(By.id("Passwd")).sendKeys("password");
		e_driver.findElement(By.id("signIn")).click();
		
		//Get the error message and validate it
		String pageHeaderText = e_driver.findElement(By.id("errormsg_0_Passwd")).getText();
		Assert.assertTrue(pageHeaderText.equalsIgnoreCase(errMessage));
	}

	@AfterClass()
	public void tearDown() {
		if (e_driver != null) {
			e_driver.quit();
		}
	}

}

In the above example, 'setUp' method has driver.get(appURL) which will trigger 'beforeNavigateTo' and 'afterNavigateTo' methods and prints the URL. 'testEventsONE' and 'testEventsTWO' test methods has multiple events which will trigger 'beforeClickOn' and 'afterClickOn' events.

After executing the above program, below is the output :

[TestNG] Running:
  C:\Users\Easy\AppData\Local\Temp\testng-eclipse-310156716\testng-customsuite.xml

Before navigating to:- 'http://www.google.com'
Navigated to:-'https://www.google.co.in/?gfe_rd=cr&ei=dymBVv6EBrPv8weejrnwDg&gws_rd=ssl... Executing Test ONE ***** 
Trying to click on:-  link text: Gmail
Clicked on:-  link text: Gmail
***** Executing Test Two ***** 
Trying to click on:-  id: next
Clicked on:-  id: next
Trying to click on:-  id: signIn
Clicked on:-  id: signIn
PASSED: testEventsONE
PASSED: testEventsTWO

===============================================
    Default test
    Tests run: 2, Failures: 0, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

People often ask the difference between WebDriverEventListener and Log4j, Here both are used for logging purposes BUT, WebDriverEventListener will trigger ONLY webdriver events and Using Log4j we will print all the messages that we provide and along with webdriver events.

Try executing both the ways that are explained above. Do let us know if you need anything more on this.

Selenium Tutorials: 
Log4j Tutorials: 

Add new comment