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 easy debugging in later stages of Test Execution.
=> Check ALL Selenium Tutorials Here.
What You Will Learn:
Implementation Of Webdriver Listeners
There are majorly two types of Listeners:
- Webdriver Listeners
- 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:
- WebDriverEventListener which is an interface that has some predefined methods for tracking Webdriver events. It requires us to implement ALL the methods predefined in the Interface.
- AbstractWebDriverEventListener Class 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 finding 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 finding 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 after script 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 the name “Listeners”. Inside that package, create a class called “WebdriverListeners” and let it implement “WebDriverEventListener”.
The UI should look like the below:
Hover your mouse over the red line with Error, the Eclipse should throw the below suggestion to import “WebDriverEventListener”. Click on Import.
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 listed and described above.
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
Event-1: This records the event beforeNavigateTo and afterNavigateTo, and performs the actions written in the two blocks accordingly.
Event-2: This records the event beforeFindBy and afterFindBy, and performs 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 the 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 the same as Event-1
Event-9: This is the same as Event-2
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 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 the 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”
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 implementing just six events, it will discard others and only display the log for the ones mentioned.
Console Window View
As you can see in 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.