Chrome DevTools Protocol version 99 support library for Selenium WebDriver Java bindings
—
Network traffic monitoring, request interception, authentication handling, and response manipulation for comprehensive network control. Enables advanced testing scenarios including API mocking, authentication testing, and performance monitoring.
import org.openqa.selenium.devtools.v99.V99Network;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.Command;
import org.openqa.selenium.devtools.Event;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.http.Filter;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.Credentials;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.net.URI;Creates a network operations handler for Chrome DevTools Protocol v99.
/**
* Creates network operations handler for CDP v99
* @param devTools - DevTools client instance
*/
public V99Network(DevTools devTools);Override the browser's user agent string for testing different client configurations.
/**
* Set user agent override using string
* @param userAgent - User agent string
*/
public void setUserAgent(String userAgent);
/**
* Set user agent override using configuration object
* @param userAgent - User agent configuration
*/
public void setUserAgent(UserAgent userAgent);
/**
* Override browser user agent string (internal)
* @param userAgent - User agent configuration
* @return Command to set user agent override
*/
protected Command<Void> setUserAgentOverride(UserAgent userAgent);
/**
* User agent configuration
*/
public class UserAgent {
public UserAgent(String userAgent);
public String userAgent(); // User agent string
public UserAgent acceptLanguage(String acceptLanguage);
public Optional<String> acceptLanguage(); // Accept-Language header value
public UserAgent platform(String platform);
public Optional<String> platform(); // Platform identifier
}Control browser network cache behavior for testing scenarios.
/**
* Enable browser network caching
* @return Command to enable caching
*/
protected Command<Void> enableNetworkCaching();
/**
* Disable browser network caching
* @return Command to disable caching
*/
protected Command<Void> disableNetworkCaching();Manage HTTP authentication for different URI patterns.
/**
* Add authentication handler for matching URIs
* @param whenThisMatches - Predicate to match URIs needing authentication
* @param useTheseCredentials - Supplier providing credentials for matched URIs
*/
public void addAuthHandler(Predicate<URI> whenThisMatches, Supplier<Credentials> useTheseCredentials);
/**
* Disable network interception and clear authentication handlers
*/
public void disable();Configure custom request/response filtering and traffic interception.
/**
* Reset network filter to default (no filtering)
*/
public void resetNetworkFilter();
/**
* Intercept all network traffic with custom filter
* @param filter - HTTP filter to process requests/responses
*/
public void interceptTrafficWith(Filter filter);
/**
* Prepare the network domain for traffic interception
*/
public void prepareToInterceptTraffic();Enable and disable request interception for monitoring and modifying network traffic.
/**
* Enable request interception for all URL patterns
* @return Command to enable fetch interception
*/
protected Command<Void> enableFetchForAllPatterns();
/**
* Disable request interception
* @return Command to disable fetch interception
*/
protected Command<Void> disableFetch();
/**
* Get event for paused requests during interception
* @return Event handler for paused requests
*/
public Event<RequestPaused> requestPausedEvent();Handle HTTP authentication challenges during request interception.
/**
* Get event for authentication required scenarios
* @return Event handler for auth challenges
*/
protected Event<AuthRequired> authRequiredEvent();
/**
* Extract origin URL from authentication challenge
* @param authRequired - Authentication challenge event
* @return Origin URL requiring authentication
*/
protected String getUriFrom(AuthRequired authRequired);
/**
* Continue request with authentication credentials
* @param authRequired - Authentication challenge event
* @param credentials - Username and password
* @return Command to provide credentials
*/
protected Command<Void> continueWithAuth(AuthRequired authRequired, UsernameAndPassword credentials);
/**
* Cancel authentication request
* @param authRequired - Authentication challenge event
* @return Command to cancel authentication
*/
protected Command<Void> cancelAuth(AuthRequired authRequired);Modify or fulfill intercepted requests and responses.
/**
* Convert paused request to Selenium HTTP objects
* @param pausedReq - Intercepted request data
* @return Either HTTP request or response object
*/
public Either<HttpRequest, HttpResponse> createSeMessages(RequestPaused pausedReq);
/**
* Extract request ID from paused request
* @param pausedReq - Paused request event
* @return Request ID string
*/
protected String getRequestId(RequestPaused pausedReq);
/**
* Continue request without modifications
* @param pausedRequest - Paused request to continue
* @return Command to continue unchanged
*/
protected Command<Void> continueWithoutModification(RequestPaused pausedRequest);
/**
* Continue request with modifications
* @param pausedReq - Paused request to modify
* @param req - Modified HTTP request
* @return Command to continue with changes
*/
protected Command<Void> continueRequest(RequestPaused pausedReq, HttpRequest req);
/**
* Fulfill request with custom response
* @param pausedReq - Paused request to fulfill
* @param res - Custom HTTP response
* @return Command to fulfill with custom response
*/
protected Command<Void> fulfillRequest(RequestPaused pausedReq, HttpResponse res);/**
* Authentication challenge event data
*/
public class AuthRequired {
/**
* Get request ID that triggered auth challenge
* @return Request ID
*/
public RequestId getRequestId();
/**
* Get authentication challenge details
* @return Challenge information
*/
public AuthChallenge getAuthChallenge();
}
/**
* Authentication challenge details
*/
public class AuthChallenge {
/**
* Get origin requiring authentication
* @return Origin URL
*/
public String getOrigin();
/**
* Get authentication scheme (Basic, Digest, etc.)
* @return Auth scheme
*/
public String getScheme();
/**
* Get realm for authentication
* @return Realm string
*/
public Optional<String> getRealm();
}
/**
* Authentication response configuration
*/
public class AuthChallengeResponse {
public enum Response {
PROVIDECREDENTIALS,
CANCELAUTH
}
public AuthChallengeResponse(Response response, Optional<String> username, Optional<String> password);
}/**
* Paused request event data during interception
*/
public class RequestPaused {
/**
* Get unique request identifier
* @return Request ID
*/
public RequestId getRequestId();
/**
* Get HTTP request details
* @return Request object
*/
public Request getRequest();
/**
* Get response status code if response is being intercepted
* @return Optional status code
*/
public Optional<Integer> getResponseStatusCode();
/**
* Get response headers if response is being intercepted
* @return Optional response headers
*/
public Optional<List<HeaderEntry>> getResponseHeaders();
/**
* Get response error reason if request failed
* @return Optional error reason
*/
public Optional<String> getResponseErrorReason();
}
/**
* HTTP request representation
*/
public class Request {
/**
* Get HTTP method
* @return Method string (GET, POST, etc.)
*/
public String getMethod();
/**
* Get request URL
* @return URL string
*/
public String getUrl();
/**
* Get request headers
* @return Headers map
*/
public Map<String, String> getHeaders();
/**
* Get POST data if present
* @return Optional POST data
*/
public Optional<String> getPostData();
}
/**
* HTTP header entry
*/
public class HeaderEntry {
public HeaderEntry(String name, String value);
public String getName();
public String getValue();
}import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v99.V99Domains;
DevTools devTools = ...; // from ChromeDriver
V99Domains domains = new V99Domains(devTools);
// Disable caching for consistent testing
devTools.send(domains.network().disableNetworkCaching());
// Enable request interception
devTools.send(domains.network().enableFetchForAllPatterns());
// Monitor all requests
devTools.addListener(domains.network().requestPausedEvent(), pausedRequest -> {
if (pausedRequest.getResponseStatusCode().isPresent()) {
// This is a response being intercepted
System.out.println("Response: " + pausedRequest.getRequest().getUrl() +
" -> " + pausedRequest.getResponseStatusCode().get());
} else {
// This is a request being intercepted
System.out.println("Request: " + pausedRequest.getRequest().getMethod() +
" " + pausedRequest.getRequest().getUrl());
}
// Continue without modification
devTools.send(domains.network().continueWithoutModification(pausedRequest));
});// Enable interception
devTools.send(domains.network().enableFetchForAllPatterns());
devTools.addListener(domains.network().requestPausedEvent(), pausedRequest -> {
// Only modify requests, not responses
if (pausedRequest.getResponseStatusCode().isEmpty()) {
Request originalRequest = pausedRequest.getRequest();
// Modify API requests to point to test server
if (originalRequest.getUrl().contains("/api/")) {
HttpRequest modifiedRequest = createHttpRequest(
originalRequest.getMethod(),
originalRequest.getUrl().replace("api.prod.com", "api.test.com"),
originalRequest.getHeaders(),
originalRequest.getPostData().orElse(null)
);
devTools.send(domains.network().continueRequest(pausedRequest, modifiedRequest));
} else {
devTools.send(domains.network().continueWithoutModification(pausedRequest));
}
} else {
devTools.send(domains.network().continueWithoutModification(pausedRequest));
}
});devTools.send(domains.network().enableFetchForAllPatterns());
devTools.addListener(domains.network().requestPausedEvent(), pausedRequest -> {
// Only handle requests (not responses)
if (pausedRequest.getResponseStatusCode().isEmpty()) {
String url = pausedRequest.getRequest().getUrl();
// Mock specific API endpoints
if (url.contains("/api/users")) {
String mockResponse = """
{
"users": [
{"id": 1, "name": "Test User", "email": "test@example.com"}
]
}
""";
HttpResponse response = createHttpResponse(
200,
mockResponse,
List.of(
new AbstractMap.SimpleEntry<>("Content-Type", "application/json"),
new AbstractMap.SimpleEntry<>("Access-Control-Allow-Origin", "*")
)
);
devTools.send(domains.network().fulfillRequest(pausedRequest, response));
} else {
devTools.send(domains.network().continueWithoutModification(pausedRequest));
}
} else {
devTools.send(domains.network().continueWithoutModification(pausedRequest));
}
});// Listen for authentication challenges
devTools.addListener(domains.network().authRequiredEvent(), authRequired -> {
String origin = domains.network().getUriFrom(authRequired);
System.out.println("Authentication required for: " + origin);
// Provide credentials
UsernameAndPassword credentials = new UsernameAndPassword("testuser", "testpass");
devTools.send(domains.network().continueWithAuth(authRequired, credentials));
// Or cancel authentication:
// devTools.send(domains.network().cancelAuth(authRequired));
});
// Enable interception to trigger auth events
devTools.send(domains.network().enableFetchForAllPatterns());// Simple user agent override
domains.network().setUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15");
// Or using configuration object for more control
UserAgent mobileUserAgent = new UserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15")
.acceptLanguage("en-US,en;q=0.9")
.platform("iPhone");
domains.network().setUserAgent(mobileUserAgent);
// Now all requests will use the mobile user agent// Add authentication for specific API endpoints
domains.network().addAuthHandler(
uri -> uri.getHost().equals("api.secure.com"),
() -> new UsernameAndPassword("apiuser", "secret123")
);
// Add authentication for multiple patterns
domains.network().addAuthHandler(
uri -> uri.getPath().startsWith("/admin/"),
() -> new UsernameAndPassword("admin", "adminpass")
);
// Enable interception to trigger auth handling
domains.network().prepareToInterceptTraffic();
// Cleanup when done
domains.network().disable(); // Clears all auth handlers// Prepare for traffic interception
domains.network().prepareToInterceptTraffic();
// Set up custom filter for request modification
Filter customFilter = next -> req -> {
// Add custom headers to all requests
req.addHeader("X-Test-Mode", "true");
req.addHeader("X-Request-Time", String.valueOf(System.currentTimeMillis()));
// Continue with the modified request
return next.execute(req);
};
// Apply the filter to all network traffic
domains.network().interceptTrafficWith(customFilter);
// Reset to default behavior when done
domains.network().resetNetworkFilter();Network operations can encounter various error conditions:
Handle errors through proper exception handling and event monitoring:
try {
devTools.send(domains.network().enableFetchForAllPatterns());
} catch (DevToolsException e) {
System.err.println("Failed to enable network interception: " + e.getMessage());
}
// Monitor for failed requests
devTools.addListener(domains.network().requestPausedEvent(), pausedRequest -> {
if (pausedRequest.getResponseErrorReason().isPresent()) {
System.err.println("Request failed: " + pausedRequest.getRequest().getUrl() +
" - " + pausedRequest.getResponseErrorReason().get());
}
// Always continue or fulfill to avoid hanging requests
devTools.send(domains.network().continueWithoutModification(pausedRequest));
});Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v99