Selenide with BrowserMob Proxy

The following is a guide to use BrowserMob Proxy to capture network traffic with Selenide as the test automation framework.

This is useful to understand how the web application interacts with clients, servers, databases or other systems.

BrowserMob Proxy

The following has been extracted from the BrowserMob Proxy website (as of 2016-07-01) to give context as to why this is so useful.

BrowserMob proxy is based on technology developed in the Selenium open source project and a commercial load testing and monitoring service originally called BrowserMob and now part of Neustar.

The proxy is a free (Apache 2.0 license) utility that works well with Selenium or can be used independently.

It can capture performance data for web apps (via the HAR format), as well as manipulate browser behavior and traffic, such as whitelisting and blacklisting content, simulating network traffic and latency, and rewriting HTTP requests and responses.

Maven

MVNRepository - BrowserMob Proxy Parent Project

There are two versions of BrowserMob Proxy.

The current version is 2.1.1 (as of 2016-05-29).

<dependency>
    <groupId>net.lightbody.bmp</groupId>
    <artifactId>browsermob-core</artifactId>
    <version>2.1.1</version>
</dependency>

Selenide Custom WebDriver

Selenide provides a factory class that can create a custom WebDriver instance.

1. Create a BrowserMob Proxy class that can be accessed by the custom WebDriver and the JUnit test.

import net.lightbody.bmp.BrowserMobProxyServer;

public final class Bmp {
    private Bmp() {}
    
    public static BrowserMobProxyServer proxyServer = null;
}

2. Create the WebDriverProvider implementation class.

Below is an example using Firefox as the browser and assigning BrowserMob Proxy as the Selenium Proxy server.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;

import com.codeborne.selenide.WebDriverProvider;

import net.lightbody.bmp.client.ClientUtil;

public class BmpFirefox implements WebDriverProvider {
    @Override
    public WebDriver createDriver(DesiredCapabilities desiredCapabilities) {
        DesiredCapabilities capabilities = DesiredCapabilities.firefox();
        capabilities.setCapability(CapabilityType.PROXY, 
				ClientUtil.createSeleniumProxy(Bmp.proxyServer));
        return new FirefoxDriver(capabilities);
    }
}

3. Set the System Property selenide.browser to assign the custom WebDriver to the Selenide WebDriverRunner.

Via Command-Line: java -Dselenide.browser=class.path.to.BmpFirefox

Via Code: System.setProperty("selenide.browser", "class.path.to.BmpFirefox");

4. Below is an example of how to use the proxy server in a JUnit test.

import static com.codeborne.selenide.Selenide.$;

import java.io.File;
import java.io.IOException;

import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.By;

import com.codeborne.selenide.Selenide;

import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.core.har.Har;
import net.lightbody.bmp.proxy.CaptureType;

/**
 * Example of using BrowserMob Proxy with Selenide.
 * <p>
 * Demonstrates the following:
 * <ul>
 * <li>Using a custom WebDriver with Selenide.</li>
 * <li>Starting and Stopping the Proxy Server.</li>
 * <li>Capturing and Writing of the network traffic to a file.</li>
 * </ul>
 */
public class BrowserMobProxyTest {

    @BeforeClass
    public static void init() {
        // Setup Selenide to use the custom WebDriver.
        System.setProperty("selenide.browser", "demo.BmpFirefox");
    }

    @Test
    public void bmpTest() throws IOException {
        Har har = null;

        // Instantiate a new proxy server.
        Bmp.proxyServer = new BrowserMobProxyServer();

        // Start the proxy server to capture network traffic.
        // The start() can receive a port number,
        // if no value is passed then it
        // defaults to "0".
        // The value of "0" indicates that the proxy 
        // server will use a random port.
        Bmp.proxyServer.start(0);
        
        // Enables the capturing of all content types.
        // This can be fine-tuned to get specific content data.
        // Reference:
        // net.lightbody.bmp.proxy.CaptureType
        Bmp.proxyServer.setHarCaptureTypes(CaptureType
                .getAllContentCaptureTypes());

        // Create a new HTTP Archive to store the 
        // requests and response details.
        Bmp.proxyServer.newHar("example.com");

        // Navigate to the "Example Domain" website.
        Selenide.navigator.open("http://www.example.com");

        // Go to the Internet Assigned Numbers Authority (IANA) page.
        $(By.linkText("More information...")).click();

        // Get the current HTTP requests and responses from when the proxy
        // server started up to now.
        har = Bmp.proxyServer.getHar();

        // Write the results of the HAR to a local file.
        har.writeTo(new File("example.har"));

        // Stop capturing the network traffic.
        Bmp.proxyServer.stop();
    }
}

This will navigate to the Example Domain, click on the More information link then display the IANA page.

All network traffic during this test is captured and saved to the example.har file.

This can then be viewed by a HAR Viewer, there are some examples below.

HAR Viewer by Software is hard
http://www.softwareishard.com/blog/har-viewer/

HTTP Archiver for Google Chrome
https://chrome.google.com/webstore/detail/http-archive-viewer/ebbdbdmhegaoooipfnjikefdpeoaidml?hl=en

References