🕵️ Lightweight utility to intercept WebDriver and WebElement method calls.

Overview

Lightweight utility to intercept webdriver and webelement method calls. Supports both Selenium and Appium drivers

About | To Get Started | Installation


About

Spydriver is a utility library which helps in intercepting all webdriver and webelement method calls and enables us to perform any operation before and after the method is executed.

spydriver.gif

How?:

Creating the listener object:

 SpyDriverListener listener = new SpyDriverListener() {

        @Override
        public void beforeDriverCommandExecuted(DriverCommand command) {
            System.out.println("[webdriver] Before " + command.getMethod().getName() +" => id: "+ command.getId());
            //Perform any action
        }
        
        @Override
        public void afterDriverCommandExecuted(DriverCommandResult command) {
            System.out.println("[webdriver] After " + command.getMethod().getName() +" => id: "+ command.getId());
            //Perform any action
        }
        
        @Override
        public void onException(DriverCommandException command) {
             //Perform any action
        }
        
        @Override
        public void beforeElementCommandExecuted(ElementCommand command) {
            System.out.println("[webelement] Before " + command.getMethod().getName() +" => id: "+ command.getId());
            //Perform any action
        }
        
        @Override
        public void afterElementCommandExecuted(ElementCommandResult command) {
            System.out.println("[webelement] After " + command.getMethod().getName() +" => id: "+ command.getId());
            //Perform any action
        }
        
        @Override
        public void onException(ElementCommandException command) {
            //Perform any action
        }
    }

Creating the spy driver object:

SpyDriver spyDriver = new SpyDriver(new FirefoxDriver(), //Any webdriver object(supports both Selenium and Appium)
        SpyDriverOptions.builder().listener(listener).build());// Listener that we have created above
WebDriver driver = spyDriver.getSpyDriver();
//now the driver object can be used in the test to get the events via listeners

It's also possible to add any number of listeners later using

spyDriver.addListener(listener);

That's it. Now you can use the driver object in your test and it will log each and every method name that is invoked in the driver object.

Example:

driver.get("https://the-internet.herokuapp.com/");
driver.manage().window().setSize(new Dimension(1000, 400));
driver.findElement(By.partialLinkText("Inputs")).click();
driver.findElement(By.cssSelector("[type=\"number\"]")).sendKeys("1222");
driver.quit();

Output:

[webdriver] Before get => id: a1275da9-f10b-4ab6-a268-3b963b83dc4a
[webdriver] After get => id: a1275da9-f10b-4ab6-a268-3b963b83dc4a
[webdriver] Before setSize => id: 4aff25ac-8c30-496b-a299-76a4bd1b0dbe
[webdriver] After setSize => id: 4aff25ac-8c30-496b-a299-76a4bd1b0dbe
[webdriver] Before findElement => id: 9d7e9167-6f5b-4f13-9f29-66c2e0239889
[webdriver] After findElement => id: 9d7e9167-6f5b-4f13-9f29-66c2e0239889
[webelement] Before click => id: 57247a4e-5be9-4af3-b9fa-c9142bacce67
[webelement] After click => id: 57247a4e-5be9-4af3-b9fa-c9142bacce67
[webdriver] Before findElement => id: 8d57434c-6c02-4e41-934f-86771fce9226
[webdriver] After findElement => id: 8d57434c-6c02-4e41-934f-86771fce9226
[webelement] Before sendKeys => id: 0233e88f-6e89-47a0-aa60-a3f3b94319c9
[webelement] After sendKeys => id: 0233e88f-6e89-47a0-aa60-a3f3b94319c9
[webdriver] Before quit => id: aa31341e-c464-4789-98f2-bb0aaa5cec87
[webdriver] After quit => id: aa31341e-c464-4789-98f2-bb0aaa5cec87

Check SpyDriverExample.java for more usage.

Hooks:

beforeDriverCommandExecuted:

Invoked before the webdriver method is called. Parameter: DriverCommand

driver.get("https://www.google.com");

public void beforeDriverCommandExecuted(DriverCommand command) {
    System.out.println(command.getMethod().getName()); // prints "get"
    System.out.println(command.getArguments()[0]); // prints "https://www.google.com"
    Webdriver originalDriver = command.getDriver(); // return the original driver object that is being spied.
    
    Thread.sleep(2000); //Wait 2s before calling the get method
    //You can add any cutom logic here in blocking mode   
}

afterDriverCommandExecuted:

Invoked after the webdriver method is called. It also holds the return value from the original method call.

Parameter: DriverCommandResult

//sample driver method
driver.getTitle();

public void afterDriverCommandExecuted(DriverCommandResult command) {
    System.out.println(command.getMethod().getName()); // prints "getTitle"
    System.out.println(command.getArguments()); // prints "[]" (because there are no parameters)
    System.out.println(command.getResult()); // prints "Google"
    Webdriver originalDriver = command.getDriver(); // return the original driver object that is being spied.
}
//sample driver method
driver.findElement(By.cssSelector("body"));

public void afterDriverCommandExecuted(DriverCommandResult command) {
    System.out.println(command.getMethod().getName()); // prints "findElement"
    By locator = (By) command.getArguments()[0];
    WebElement locatedElement = (WebElement) command.getResult();
    Webdriver originalDriver = command.getDriver(); // return the original driver object that is being spied.
}
//sample driver method
driver.manage().window().getSize();

public void afterDriverCommandExecuted(DriverCommandResult command) {
    System.out.println(command.getMethod().getName()); // prints "getSize"
    System.out.println(command.getArguments()); // prints "[]" (because there are no parameters)
    Dimension size = (Dimension) command.getResult(); // returns the current window size
    Webdriver originalDriver = command.getDriver(); // return the original driver object that is being spied.
}

onException:

Invoked if any exception is thrown while calling the webdriver method.

Parameter: DriverCommandException

//sample driver method
driver.get("some-invalid-url");

public void onException(DriverCommandException command) {
    System.out.println(command.getMethod().get()); // prints "get"
    System.out.println(command.getArguments()[0]); // prints "some-invalid-url"
    System.out.println(command.getException().getMessage()); // Malformed URL: URL constructor: some-invalid-url is not a valid URL.
    Webdriver originalDriver = command.getDriver(); // return the original driver object that is being spied.
}

beforeElementCommandExecuted:

Invoked before any method is called in WebElement object.

Parameter: ElementCommand

//sample driver method
WebElement element = driver.findElement(By.cssSelector(".username"));
element.sendKeys("Test", " ", "Ninja");

public void beforeElementCommandExecuted(ElementCommand command) {
    System.out.println(command.getMethod().getName()); // prints "sendKeys"
    System.out.println(command.getArguments()[0]); // prints ["Test", " ", "Ninja"]
    Webdriver originalDriver = command.getDriver(); // return the original driver object that is being spied.
    Webdriver originalElement = command.getElement(); // return the original element object that is being spied.
    By locator = command.getLocator(); // returns the locator used to find the original element (By.cssSelector(".username")).
}
//sample driver method
WebElement element = driver.findElement(By.cssSelector(".username"));
element.click();

public void beforeElementCommandExecuted(ElementCommand command) {
    System.out.println(command.getMethod().getName()); // prints "click"
    System.out.println(command.getArguments()); // prints "[]"
    Webdriver originalDriver = command.getDriver(); // return the original driver object that is being spied.
    Webdriver originalElement = command.getElement(); // return the original element object that is being spied.
    By locator = command.getLocator(); // returns the locator used to find the original element (By.cssSelector(".username")).
}

afterElementCommandExecuted:

Invoked after any method is called in WebElement object.

Parameter: ElementCommandResult

//sample driver method
WebElement element = driver.findElement(By.cssSelector(".username"));
String username = element.getAttribute("value");

public void afterElementCommandExecuted(ElementCommandResult command) {
    System.out.println(command.getMethod().getName()); // prints "getAttribute"
    System.out.println(command.getArguments()[0]); // prints ["value"]
    System.out.println(command.getResult()); // prints "Test Ninaje"
    Webdriver originalDriver = command.getDriver(); // return the original driver object that is being spied.
    Webdriver originalElement = command.getElement(); // return the original element object that is being spied.
    By locator = command.getLocator(); // returns the locator used to find the original element (By.cssSelector(".username"))
}

onException:

Invoked if any exception is thrown while calling the webelement method.

Parameter: ElementCommandException

//sample driver method
WebElement element = driver.findElement(By.cssSelector(".hidden"));
element.click();

public void onException(ElementCommandException command) {
    System.out.println(command.getMethod().getName()); // prints "click"
    System.out.println(command.getException().getMessage()); // prints "element not visile"
    Webdriver originalDriver = command.getDriver(); // return the original driver object that is being spied.
    Webdriver originalElement = command.getElement(); // return the original element object that is being spied.
    By locator = command.getLocator(); // returns the locator used to find the original element (By.cssSelector(".hidden"))
}

Installation:

Maven:

<dependency>
  <groupId>io.github.sudharsan-selvaraj</groupId>
  <artifactId>spydriver</artifactId>
  <version>1.1.0</version>
</dependency> 

Gradle:

implementation group: 'io.github.sudharsan-selvaraj', name: 'spydriver', version: '1.1.0'
You might also like...

IntelliJ IDEA and JUnit: Writing, Finding, and Running Tests

IntelliJ IDEA and JUnit: Writing, Finding, and Running Tests 📼 Webinar https://blog.jetbrains.com/idea/2021/11/live-stream-recording-intellij-idea-an

Jul 23, 2022

Toolkit for testing multi-threaded and asynchronous applications

ConcurrentUnit A simple, zero-dependency toolkit for testing multi-threaded code. Supports Java 1.6+. Introduction ConcurrentUnit was created to help

Dec 30, 2022

Library that allows tests written in Java to follow the BDD style introduced by RSpec and Jasmine.

J8Spec J8Spec is a library that allows tests written in Java to follow the BDD style introduced by RSpec and Jasmine. More details here: j8spec.github

Feb 17, 2022

A modern testing and behavioural specification framework for Java 8

Introduction If you're a Java developer and you've seen the fluent, modern specification frameworks available in other programming languages such as s

Sep 12, 2022

Serenity BDD is a test automation library designed to make writing automated acceptance tests easier, and more fun.

Serenity BDD is a test automation library designed to make writing automated acceptance tests easier, and more fun.

That feeling you get when you know you can trust your tests Serenity BDD is a library designed to make writing automated acceptance tests easier, and

Dec 28, 2022

A Java architecture test library, to specify and assert architecture rules in plain Java

A Java architecture test library, to specify and assert architecture rules in plain Java

ArchUnit is a free, simple and extensible library for checking the architecture of your Java code. That is, ArchUnit can check dependencies between pa

Jan 2, 2023

Fluent assertions for Java and Android

What is Truth? Truth makes your test assertions and failure messages more readable. Similar to AssertJ, it natively supports many JDK and Guava types,

Jan 5, 2023

A browser automation framework and ecosystem.

A browser automation framework and ecosystem.

Selenium Selenium is an umbrella project encapsulating a variety of tools and libraries enabling web browser automation. Selenium specifically provide

Jan 7, 2023
Comments
  • How to cast it to ThreadLocal webdriver

    How to cast it to ThreadLocal webdriver

    Currently Webdriver is created using Type ThreadLocal, How to add spyDriver to this driver instance?

     private final ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
     webDriver.set(new ChromeDriver());
    
    opened by DeChrish 1
Releases(v1.1.1)
Owner
Sudharsan Selvaraj
Senior Test Engineer | Automation enthusiast | TestNinja
Sudharsan Selvaraj
A sample repo to help you intercept network with Java-TestNG on LambdaTest cloud. Run Selenium tests with TestNG on LambdaTest platform.

How to intercept network with Java-TestNG on LambdaTest cloud Environment Setup Global Dependencies Install Maven Or Install Maven with Homebrew (Easi

null 12 Oct 23, 2022
Ready-to-use UI Test Automation Architecture using Java and Selenium WebDriver.

Selenium Test Automation Boilerplate Ready-to-use UI Test Automation Architecture using Java and Selenium WebDriver. Languages and Frameworks The proj

Tahanima Chowdhury 133 Dec 26, 2022
A collection of bite size examples for using chrome DevTools protocol commands with Selenium Webdriver v4.

selenium-devtools-guide A collection of bite size examples for using chrome DevTools protocol commands with Selenium Webdriver v4. Chrome Devtools Pro

Sudharsan Selvaraj 4 Aug 12, 2021
Ghost Driver is an implementation of the Remote WebDriver Wire protocol, using PhantomJS as back-end

Ghost Driver is an implementation of the Remote WebDriver Wire protocol, using PhantomJS as back-end

Ivan De Marino 1.9k Dec 15, 2022
This repository contains example codes which will help you to know how to use selenium webdriver.

❓ What is this Repository about? This repo has example codes with Selenium 4 features. Websites used for testing are: automationpractice.com, saucedem

Mohammad Faisal Khatri 86 Dec 30, 2022
Selenium Webdriver: Page Object Model (POM) With Page Factory

Prepare Web Testing Instance or Environment Selenium Webdriver: Page Object Model (POM) With Page Factory Prerequisite software Download & Install JDK

Hiro Mia 14 Oct 18, 2022
Utility to automatically manage all web element waits and enables to write wait-free selenium tests.

selenium-auto-wait selenium-auto-wait automatically manages all weblement waits and makes you to write wait free selenium tests. Features Waits till e

Sudharsan Selvaraj 31 Nov 1, 2022
Lightweight analysis tool for detecting mutability in Java classes

What is Mutability Detector? Mutability Detector is designed to analyse Java classes and report on whether instances of a given class are immutable. I

Mutability Detector 234 Dec 29, 2022
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.

Testcontainers Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium we

null 6.7k Jan 9, 2023
JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.

pact-jvm JVM implementation of the consumer driven contract library pact. From the Ruby Pact website: Define a pact between service consumers and prov

Pact Foundation 962 Dec 31, 2022