WebDriver Listeners In Selenium

What are WebDriver Listeners? Why do we need Listeners in Selenium Automation Testing? This Tutorial Answers these Questions In Detail with Sample Code Examples:

Listeners, as the name suggests, “listen” to any event that is prescribed in the Selenium code. For instance, if you want to know what happens before you click any element; before and after you navigate to an element, or what happens when an exception is thrown and the test fails, Listeners come in handy.

The practical use of Listeners in Selenium Automation Testing could be to log the order of actions and to take the screenshot as and when an Exception is thrown. This facilitates for easy debugging in later stages of Test Execution.

=> Check ALL Selenium Tutorials Here.

WebDriver Listeners in Selenium

Implementation Of Webdriver Listeners

There are majorly two types of Listeners:

  1. Webdriver Listeners
  2. TestNG Listeners

We will first understand how Webdriver Listeners work. In this tutorial, our focus will be on the Webdriver Event Listener.

Why Do We Use Webdriver Event Listener?

With the help of Webdriver, we’re able to trigger a lot of events on the Browser and Web Elements. It keeps a track of all the events that are triggered while execution and can help us in debugging when the execution is complete.

There are two ways in which we can implement the Webdriver Event Listeners:

  1. WebDriverEventListener which is an interface that has some predefined methods for tracking the Webdriver events. It requires us to implement ALL the methods predefined in the Interface.
  2. AbstractWebDriverEventListener Class which provides us with the facility of implementing only those methods in which we are interested.

#1) WebDriverEventListener Interface

Predefined Methods used to implement the WebDriverEventListener Interface are enlisted below:

(i) void beforeChangeValueOf(WebElement arg0, WebDriver arg1,CharSequence[] arg2)

This method is triggered when we perform either the sendKeys() or clear() operation on the Web Element. [For instance, driver.findElement(By.id(“Login”)).clear()], and is triggered BEFORE performing the operation on the Web Element.

Parameters:

arg0= Web Element
arg1=driver

(ii) void afterChangeValueOf(WebElement arg0, WebDriver arg1,CharSequence[] arg2)

This method is triggered when we perform either the sendKeys() or clear() operation on the Web Element. [For instance, driver.findElement(By.id(“Login”)).clear()], and is triggered AFTER performing the operation on the Web Element.

Parameters:

arg0= Web Element
arg1=driver

(iii) void beforeClickOn(WebElement arg0, WebDriver arg1)

This method is triggered BEFORE we click on any Web Element.

Parameters:

arg0= Web Element
arg1=driver

(iv) void afterClickOn(WebElement arg0, WebDriver arg1)

This method is triggered AFTER we click on any Web Element.

Parameters:

arg0= Web Element
arg1=driver

(v) void beforeNavigateTo(String arg0, WebDriver arg1)

This method is triggered when we use navigate().to(String URL)[ For instance, navigate().to(“https://www.google.com”) ], and is triggered BEFORE navigating to the URL.

Parameters:

arg0= URL
arg1=driver

(vi) void afterNavigateTo(String arg0, WebDriver arg1)

This method is triggered when we use navigate().to(String URL)[ For instance, navigate().to(“https://www.google.com”) ], and is triggered AFTER navigating to the URL.

Parameters:

arg0= URL
arg1=driver

(vii) void beforeNavigateBack(WebDriver arg0)

This method is triggered when we use the command navigate().back(). It takes place BEFORE redirecting the user to the previous page.

Parameters:

arg0=driver

(viii) void afterNavigateBack(WebDriver arg0)

This method is triggered when we use the command navigate().back(). It takes place AFTER redirecting the user to the previous page.

Parameters:

arg0=driver

(ix) void beforeNavigateForward(WebDriver arg0)

This method is triggered when we use the command navigate().forward(). It takes place BEFORE redirecting the user to the next page.

Parameters:

arg0=driver

(x) void afterNavigateBack(WebDriver arg0)

This method is triggered when we use the command navigate().forward(). It takes place AFTER redirecting the user to the next page.

Parameters:

arg0=driver

(xi) void beforeNavigateRefresh(WebDriver arg0)

This method is triggered when we use the command navigate().refresh(). It takes place BEFORE refreshing the current page.

Parameters:

arg0=driver

(xii) void afterNavigateRefresh(WebDriver arg0)

This method is triggered when we use the command navigate().refresh(). It takes place AFTER refreshing the current page.

Parameters:

arg0=driver

(xiii) void beforeFindBy(By arg0, WebElement arg1, WebDriver arg2)

This method is triggered when we use the command driver.findElement(By.id(“Some id or any other locator”)). It takes place BEFORE find the Web Element.

Parameters:

arg0=locator
arg1=Web Element
arg2=driver

(xiv) void afterFindBy(By arg0, WebElement arg1, WebDriver arg2)

This method is triggered when we use the command driver.findElement(By.id(“Some id or any other locator”)). It takes place AFTER find the Web Element.

Parameters:

arg0=locator
arg1=Web Element
arg2=driver

(xv) void onException(Throwable arg0, WebDriver arg1)

This method is thrown whenever an exception is thrown. For instance, if the Webdriver is not able to find the element, it will trigger this method and would execute whatever code is written inside it.

Parameters:

arg0=Exception
arg1= driver

(xvi) void beforeAlertAccept(WebDriver arg0)

This method is triggered whenever there is an alert box shown on the screen and is triggered right BEFORE clicking on the “OK or ACCEPT” button.

Parameters:

arg0=driver

(xvii) void afterAlertAccept(WebDriver arg0)

This method is triggered whenever there is an alert box shown on the screen and is triggered right AFTER clicking on the “OK or ACCEPT” button.

Parameters:

arg0=driver

(xviii) void beforeAlertDismiss(WebDriver arg0)

This method is triggered whenever there is an alert box shown on the screen and is triggered right BEFORE clicking on the “CANCEL” button.

Parameters:

arg0=driver

(xix) void afterAlertDismiss(WebDriver arg0)

This method is triggered whenever there is an alert box shown on the screen and is triggered right AFTER clicking on the “CANCEL” button.

Parameters:

arg0=driver

These are all the methods that are available with WebDriverEventListener. There are other two methods beforeScript and afterScript but we are not going to cover those in this tutorial.

Steps to Implement Listeners with the help of “WebDriverEventListener” Interface in Eclipse:

Step#1: Create a package with name as “Listeners”. Inside that package, create a class called “WebdriverListeners” and let it implement “WebDriverEventListener”.

The UI should look like below:

Create a package with name as “Listeners

Hover your mouse over the red line with Error, the Eclipse should throw the below suggestion to import “WebDriverEventListener”. Click on Import.

Error message to import “WebDriverEventListener”

The error on the WebDriverEventListener is exited but you will see the below error on the “WebDriverListeners” class. Move the cursor over the error and you will see a suggestion to add Unimplemented methods. Click on it, and you will see all the methods are listed and described above.

the methods listed

Please note that we have added the System.out.println line to every method for demonstration purposes.

Sample Code-1

package Listeners;

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

public class WebDriverListeners implements WebDriverEventListener {

	@Override
	public void afterAlertAccept(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("After Alert Accept "+arg0.toString() );
	}

	@Override
	public void afterAlertDismiss(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("After Alert Dismiss "+ arg0);
		
	}

	@Override
	public void afterChangeValueOf(WebElement arg0, WebDriver arg1,
			CharSequence[] arg2) {
		// TODO Auto-generated method stub
		System.out.println("After value change of" +arg0);
		
	}

	@Override
	public void afterClickOn(WebElement arg0, WebDriver arg1) {
		// TODO Auto-generated method stub
		System.out.println("After clicked"+arg0);
	}

	@Override
	public void afterFindBy(By arg0, WebElement arg1, WebDriver arg2) {
		// TODO Auto-generated method stub
		System.out.println("After Find By"+arg1);
		
	}

	@Override
	public void afterNavigateBack(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("After Navigate Back");
	}

	@Override
	public void afterNavigateForward(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("After Navigate Forward");
	}

	@Override
	public void afterNavigateRefresh(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("On Navigating Refresh");
	}

	@Override
	public void afterNavigateTo(String arg0, WebDriver arg1) {
		// TODO Auto-generated method stub
		System.out.println("On Navigating To"+arg0);
		
	}

	@Override
	public void afterScript(String arg0, WebDriver arg1) {
		// TODO Auto-generated method stub
		System.out.println("After Script");
	}

	@Override
	public void beforeAlertAccept(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("Before Alert Accept");
	}

	@Override
	public void beforeAlertDismiss(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("Before Alert Dismiss");
	}

	@Override
	public void beforeChangeValueOf(WebElement arg0, WebDriver arg1,
			CharSequence[] arg2) {
		// TODO Auto-generated method stub
		System.out.println("Before Change Value of"+arg0);
	}

	@Override
	public void beforeClickOn(WebElement arg0, WebDriver arg1) {
		// TODO Auto-generated method stub
		System.out.println("Before Click on"+arg0);
	}

	@Override
	public void beforeFindBy(By arg0, WebElement arg1, WebDriver arg2) {
		// TODO Auto-generated method stub
		System.out.println("Before Find By"+arg0);
	}

	@Override
	public void beforeNavigateBack(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("Before Navigate Back");
	}

	@Override
	public void beforeNavigateForward(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("Before Navigate Forward");
	}

	@Override
	public void beforeNavigateRefresh(WebDriver arg0) {
		// TODO Auto-generated method stub
		System.out.println("Before Navigate Refresh");
	}

	@Override
	public void beforeNavigateTo(String arg0, WebDriver arg1) {
		// TODO Auto-generated method stub
		System.out.println("Before Navigate To"+arg0);
	}

	@Override
	public void beforeScript(String arg0, WebDriver arg1) {
		// TODO Auto-generated method stub
		System.out.println("Before Script");
	}

	@Override
	public void onException(Throwable arg0, WebDriver arg1) {
		// TODO Auto-generated method stub
		System.out.println("On Exception"+arg0);
	}

}

Step#2: Create class Listeners_Tests and make sure that it has the main method inside the class. Let it extend the WebDriverListeners class so that the listener class can perform an operation on the browser commands prescribed for certain events.

Please copy-paste the below code in the Listeners_Tests class. Run the below code like the Java Application.

Sample Code-2

package Listeners;

import java.util.Arrays;

import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.events.EventFiringWebDriver;

public class Listeners_Tests extends WebDriverListeners{

	static WebElement e;
	static ChromeDriver driver;

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub

		System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");

		/*Setting the capabilities of Chrome Driver*/
		try {
			DesiredCapabilities capabilities = DesiredCapabilities.chrome();
			Proxy proxy = new Proxy();
			String proxyServer = String.format("AProxyIDontWantToDisplay", System.getenv("proxy.username"), 
System.getenv("proxy.password"));
			proxy.setHttpProxy(proxyServer);
			capabilities.setCapability("proxy", proxy);
			ChromeOptions options = new ChromeOptions();
			options.addArguments(Arrays.asList
("--no-sandbox","--ignore-certificate-errors","--homepage=about:blank","--no-first-run"));
			options.addArguments("disable-infobars");
			capabilities.setCapability(ChromeOptions.CAPABILITY, options);
			driver = new ChromeDriver(capabilities);
		} 
		
		catch (Exception e) {
			
			throw new Error(e);
		}

		/*---- Creating the instance of EventFiringWebDriver Class----*/
		
		EventFiringWebDriver eventRecorder = new EventFiringWebDriver(driver); 
		
		/*---- Creating the instance of parent class "WebdriverListeners" class----*/
		
		WebDriverListeners eCapture = new WebDriverListeners();
		
		/* The below step registers the listeners for logging purpose*/
		
		eventRecorder.register(eCapture);
		
		//Event One
		System.out.println("This is recording Event-One");
		eventRecorder.navigate().to("https://www.google.com");
		
		//Event Two
		System.out.println("This is recording Event-Two");
		eventRecorder.findElement(By.xpath("//a[text()='Sign in']")).click();
		
		//Event Three
		System.out.println("This is recording Event-Three");
		eventRecorder.findElement(By.id("identifierId")).clear();
		
		Thread.sleep(5000);
		
		//Event Four
		System.out.println("This is recording Event-Four");
		eventRecorder.findElement(By.id("identifierId")).sendKeys("abc@gmail.com");
		
		Thread.sleep(5000);
		
		//Event Five
		System.out.println("This is recording Event-Five");
		eventRecorder.navigate().back();
		
		//Event Six
		System.out.println("This is recording Event-Six");
		eventRecorder.navigate().forward();
		
		//Event Seven
		System.out.println("This is recording Event-Seven");
		eventRecorder.navigate().refresh();
		
		//Event Eight
		System.out.println("This is recording Event-Eight");
		eventRecorder.get("https://www.irctc.co.in/eticketing/loginHome.jsf");
		
		//Event Nine
		System.out.println("This is recording Event-Nine");
		eventRecorder.findElement(By.id("loginbutton")).click();

		try {
			Alert alert = eventRecorder.switchTo().alert();

			// check if alert exists
			// TODO find better way
			alert.getText();
			
			//Event Ten
			System.out.println("This is recording Event-Ten");
			alert.accept();
		} catch (Exception e) {
		}
		Thread.sleep(3000);
		eventRecorder.findElement(By.id("loginbutton")).click();
		try {
			Alert alert = eventRecorder.switchTo().alert();

			// check if alert exists
			// TODO find better way
			alert.getText();
			
			//Event Eleven
			System.out.println("This is recording Event-Eleven");
			alert.dismiss();
		} catch (Exception e) {
		}
		
		//Intentionally giving wrong id so it triggers onException Listener--> Event Twelve
		System.out.println("This is recording Event-Twelve");
		eventRecorder.findElement(By.id("loginbutn")).click();
		
	}

}

After the run has been successfully completed, please check the contents logged in the console. We shall be going to every event listed in the code above.

Snippet#1 of the console

Snippet#1 of the console

Event-1: This records the event beforeNavigateTo and afterNavigateTo, and perform the actions written in the two blocks accordingly.

Event-2: This records the event beforeFindBy and afterFindBy, and perform the actions written in the two blocks accordingly. The event after these two events covers beforeClick and afterClick events.

Event-3: This records the beforeChangeValueOf and afterChangeValue of events.

Event-4: This is same as Event-3

Event-5: This records beforeNavigateBack and afterNavigateBack events.

Event-6: This records beforeNavigateForward and afterNavigateForward events.

Event-7: This records beforeNavigateRefresh and afterNavigateRefresh events.

Event-8: This is same as Event-1

Event-9: This is same as Event-2

Snippet#2 of the console

Snippet#2 of the console

Event-10: This records the events like beforeAlertAccept and afterAlertAccept.

Event-11: This records the events like beforeAlertDismiss and afterAlertDismiss.

Event-12: This records the events like onException, and throws the message.

I hope the brief description of the listeners will give you an idea about how the Webdriver Listeners work. As we have earlier said that with the help of WebDriverEventListener, we must implement all the methods available with this interface.

However, with the help of class AbstractWebDriverEventListener, we can choose which events we want to implement.

#2) AbstractWebDriverEventListener Class

Steps to Implement Listeners using “AbstractWebDriverEventListener” Class:

Step#1

Create a class “AbstractWebDriverListener” and let it extend the class “AbstractWebDriverEventListener

AbstractWebDriverListener

As you can see, unlike “WebDriverEventListener”, this class when extended doesn’t throw an error to add unimplemented methods. You can select whichever methods you want to implement in your project.

Copy and paste the below code:

Sample Code-3

package Listeners;

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

public class AbstractWebDriverListeners extends AbstractWebDriverEventListener{

	public void afterChangeValueOf(WebElement arg0, WebDriver arg1,
			CharSequence[] arg2) {
		// TODO Auto-generated method stub
		System.out.println("After value change of" +arg0);
		
	}

	public void afterClickOn(WebElement arg0, WebDriver arg1) {
		// TODO Auto-generated method stub
		System.out.println("After clicked"+arg0);
	}

	public void afterFindBy(By arg0, WebElement arg1, WebDriver arg2) {
		// TODO Auto-generated method stub
		System.out.println("After Find By"+arg1);
		
	}

	public void beforeChangeValueOf(WebElement arg0, WebDriver arg1,
			CharSequence[] arg2) {
		// TODO Auto-generated method stub
		System.out.println("Before Change Value of"+arg0);
	}

	public void beforeClickOn(WebElement arg0, WebDriver arg1) {
		// TODO Auto-generated method stub
		System.out.println("Before Click on"+arg0);
	}

	public void beforeFindBy(By arg0, WebElement arg1, WebDriver arg2) {
		// TODO Auto-generated method stub
		System.out.println("Before Find By"+arg0);
	}
}

Step#2

Create a new class with the name “AbstractListeners_Test” and inside it, create the instance of “AbstractWebDriverListeners” class.

Copy-paste the below code inside this class.

Sample Code-4

package Listeners;

import java.util.Arrays;

import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.events.EventFiringWebDriver;

public class AbstractListeners_Tests extends WebDriverListeners{

	static WebElement e;
	static ChromeDriver driver;

	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub

		System.setProperty("webdriver.chrome.driver", "E:\\chromedriver.exe");

		/*Setting the capabilities of Chrome Driver*/
		try {
			DesiredCapabilities capabilities = DesiredCapabilities.chrome();
			Proxy proxy = new Proxy();
			String proxyServer = String.format("AProxyIDontWantToDisplay", System.getenv("proxy.username"), 
System.getenv("proxy.password"));
			proxy.setHttpProxy(proxyServer);
			capabilities.setCapability("proxy", proxy);
			ChromeOptions options = new ChromeOptions();
			options.addArguments(Arrays.asList
("--no-sandbox","--ignore-certificate-errors","--homepage=about:blank","--no-first-run"));
			options.addArguments("disable-infobars");
			capabilities.setCapability(ChromeOptions.CAPABILITY, options);
			driver = new ChromeDriver(capabilities);
		} 
		
		catch (Exception e) {
			
			throw new Error(e);

		}

		/*---- Creating the instance of EventFiringWebDriver Class----*/
		
		EventFiringWebDriver eventRecorder = new EventFiringWebDriver(driver); 
		
		/*---- Creating the instance of parent class "AbstractWebdriverListeners" class----*/
		
		AbstractWebDriverListeners eCapture = new AbstractWebDriverListeners();
		
		/* The below step registers the listeners for logging purpose*/
		
		eventRecorder.register(eCapture);
		
		//Event One
		System.out.println("This is recording Event-One");
		eventRecorder.navigate().to("https://www.google.com");
		
		//Event Two
		System.out.println("This is recording Event-Two");
		eventRecorder.findElement(By.xpath("//a[text()='Sign in']")).click();
		
		//Event Three
		System.out.println("This is recording Event-Three");
		eventRecorder.findElement(By.id("identifierId")).clear();
		
		Thread.sleep(5000);
		
		//Event Four
		System.out.println("This is recording Event-Four");
		eventRecorder.findElement(By.id("identifierId")).sendKeys("abc@gmail.com");
		
		Thread.sleep(5000);
		
		//Event Five
		System.out.println("This is recording Event-Five");
		eventRecorder.navigate().back();
		
		//Event Six
		System.out.println("This is recording Event-Six");
		eventRecorder.navigate().forward();
		
		//Event Seven
		System.out.println("This is recording Event-Seven");
		eventRecorder.navigate().refresh();
		
		//Event Eight
		System.out.println("This is recording Event-Eight");
		eventRecorder.get("https://www.irctc.co.in/eticketing/loginHome.jsf");
		
		//Event Nine
		System.out.println("This is recording Event-Nine");
		eventRecorder.findElement(By.id("loginbutton")).click();

		try {
			Alert alert = eventRecorder.switchTo().alert();

			// check if alert exists
			// TODO find better way
			alert.getText();
			
			//Event Ten
			System.out.println("This is recording Event-Ten");
			alert.accept();
		} catch (Exception e) {
		}
		Thread.sleep(3000);
		eventRecorder.findElement(By.id("loginbutton")).click();
		try {
			Alert alert = eventRecorder.switchTo().alert();

			// check if alert exists
			// TODO find better way
			alert.getText();
			
			//Event Eleven
			System.out.println("This is recording Event-Eleven");
			alert.dismiss();
		} catch (Exception e) {
		}
		
		//Intentionally giving wrong id so it triggers onException Listener--> Event Twelve
		System.out.println("This is recording Event-Twelve");
		eventRecorder.findElement(By.id("loginbutn")).click();
		
	}

}

This class also has the events recorded earlier, but since we have limited our Listener class to implement just six events, it will discard others and only display the log for the ones mentioned.

Console Window View

Console Window View

As you can see the yellow marked areas in the above image, only the methods that have been implemented in the AbstractWebDriverListeners Class have been triggered.

Conclusion

WebDriver Listeners are the interfaces that listen to a browser event and respond to it accordingly. If you implement it with the help of WebDriverEventListener, you have to implement all the methods involved with this interface

If you implement WebDriver Listener with the help of the AbstractWebDriverEventListener class, you can choose the methods you want to implement.

=> Visit Here To Learn Selenium From Scratch.