Java bindings for Chrome DevTools Protocol version 102, providing programmatic access to Chrome browser debugging and automation capabilities
—
Handles network operations, request/response interception, authentication, and user agent management. This domain enables comprehensive network monitoring and manipulation capabilities for advanced automation scenarios.
Main class for network operations and request interception. Extends the idealized Network interface to provide v102-specific implementations for network control and monitoring.
/**
* Handles network operations, request/response interception, and authentication
*/
public class V102Network extends Network<AuthRequired, RequestPaused> {
/**
* Creates a new V102Network instance with the specified DevTools connection
* @param devTools DevTools connection instance (required)
*/
public V102Network(DevTools devTools);
/**
* Sets a custom user agent override for all requests
* @param userAgent UserAgent configuration with user agent string, language, and platform
* @return Command to set user agent override
*/
protected Command<Void> setUserAgentOverride(UserAgent userAgent);
/**
* Enables network caching for all requests
* @return Command to enable network caching
*/
protected Command<Void> enableNetworkCaching();
/**
* Disables network caching for all requests
* @return Command to disable network caching
*/
protected Command<Void> disableNetworkCaching();
/**
* Enables fetch interception for all request patterns
* Intercepts both REQUEST and RESPONSE stages
* @return Command to enable fetch interception
*/
protected Command<Void> enableFetchForAllPatterns();
/**
* Disables fetch interception
* @return Command to disable fetch interception
*/
protected Command<Void> disableFetch();
/**
* Returns the authentication required event for handling HTTP auth challenges
* @return Event for authentication requests
*/
protected Event<AuthRequired> authRequiredEvent();
/**
* Returns the request paused event for intercepted requests
* @return Event for paused requests during interception
*/
public Event<RequestPaused> requestPausedEvent();
/**
* Extracts URI from authentication required event
* @param authRequired Authentication required event
* @return String URI that requires authentication
*/
protected String getUriFrom(AuthRequired authRequired);
/**
* Continues with authentication using provided credentials
* @param authRequired Authentication required event
* @param credentials Username and password for authentication
* @return Command to provide authentication credentials
*/
protected Command<Void> continueWithAuth(AuthRequired authRequired, UsernameAndPassword credentials);
/**
* Cancels authentication request
* @param authRequired Authentication required event to cancel
* @return Command to cancel authentication
*/
protected Command<Void> cancelAuth(AuthRequired authRequired);
/**
* Creates Selenium HTTP messages from paused request
* @param pausedReq Paused request event
* @return Either HttpRequest or HttpResponse depending on interception stage
*/
public Either<HttpRequest, HttpResponse> createSeMessages(RequestPaused pausedReq);
/**
* Extracts request ID from paused request
* @param pausedReq Paused request event
* @return String request identifier
*/
protected String getRequestId(RequestPaused pausedReq);
/**
* Continues intercepted request without modification
* @param pausedRequest Paused request to continue
* @return Command to continue request unchanged
*/
protected Command<Void> continueWithoutModification(RequestPaused pausedRequest);
/**
* Continues intercepted request with modifications
* @param pausedReq Original paused request
* @param req Modified HTTP request to send instead
* @return Command to continue with modified request
*/
protected Command<Void> continueRequest(RequestPaused pausedReq, HttpRequest req);
/**
* Fulfills intercepted request with custom response
* @param pausedReq Original paused request
* @param res Custom HTTP response to return
* @return Command to fulfill request with custom response
*/
protected Command<Void> fulfillRequest(RequestPaused pausedReq, HttpResponse res);
}Usage Examples:
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v102.V102Domains;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
// Setup
ChromeDriver driver = new ChromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();
V102Domains domains = new V102Domains(devTools);
// Enable network interception
devTools.send(domains.network().enableFetchForAllPatterns());
// Listen for intercepted requests
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
// Get request/response from the paused request
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
if (message.isLeft()) {
// Handle intercepted request
HttpRequest request = message.left();
System.out.println("Intercepted request: " + request.getMethod() + " " + request.getUri());
// Continue without modification
devTools.send(domains.network().continueWithoutModification(pausedRequest));
} else {
// Handle intercepted response
HttpResponse response = message.right();
System.out.println("Intercepted response: " + response.getStatus());
// Continue without modification
devTools.send(domains.network().continueWithoutModification(pausedRequest));
}
});
// Navigate to trigger network activity
driver.get("https://example.com");
// Cleanup
devTools.send(domains.network().disableFetch());import org.openqa.selenium.remote.http.HttpMethod;
import java.net.URI;
// Enable interception and modify requests
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
if (message.isLeft()) {
HttpRequest originalRequest = message.left();
// Modify specific requests
if (originalRequest.getUri().toString().contains("/api/data")) {
// Create modified request
HttpRequest modifiedRequest = new HttpRequest(
HttpMethod.GET,
originalRequest.getUri().toString() + "?modified=true"
);
// Copy headers from original request
originalRequest.getHeaderNames().forEach(headerName -> {
originalRequest.getHeaders(headerName).forEach(headerValue -> {
modifiedRequest.addHeader(headerName, headerValue);
});
});
// Add custom header
modifiedRequest.addHeader("X-Modified-By", "Selenium");
// Continue with modified request
devTools.send(domains.network().continueRequest(pausedRequest, modifiedRequest));
} else {
// Continue original request unchanged
devTools.send(domains.network().continueWithoutModification(pausedRequest));
}
}
});import org.openqa.selenium.remote.http.HttpResponse;
// Fulfill requests with custom responses
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
if (message.isLeft()) {
HttpRequest request = message.left();
// Intercept specific API calls and return mock data
if (request.getUri().toString().contains("/api/user/profile")) {
String mockResponse = "{\"id\": 123, \"name\": \"Mock User\", \"email\": \"mock@example.com\"}";
HttpResponse customResponse = new HttpResponse();
customResponse.setStatus(200);
customResponse.addHeader("Content-Type", "application/json");
customResponse.setContent(mockResponse.getBytes());
// Fulfill with custom response
devTools.send(domains.network().fulfillRequest(pausedRequest, customResponse));
} else {
devTools.send(domains.network().continueWithoutModification(pausedRequest));
}
}
});import org.openqa.selenium.devtools.idealized.Network.UserAgent;
// Set custom user agent
UserAgent customAgent = new UserAgent(
"MyApp/1.0 (Custom Selenium Agent)",
"en-US,en;q=0.9",
"Linux x86_64"
);
devTools.send(domains.network().setUserAgentOverride(customAgent));
// Disable caching for testing
devTools.send(domains.network().disableNetworkCaching());
// Navigate with custom user agent and no caching
driver.get("https://httpbin.org/user-agent");
// Re-enable caching
devTools.send(domains.network().enableNetworkCaching());import org.openqa.selenium.UsernameAndPassword;
// Handle HTTP authentication challenges
devTools.addListener(domains.network().authRequiredEvent(), (authRequired) -> {
String uri = domains.network().getUriFrom(authRequired);
System.out.println("Authentication required for: " + uri);
// Provide credentials
UsernameAndPassword credentials = new UsernameAndPassword("username", "password");
devTools.send(domains.network().continueWithAuth(authRequired, credentials));
// Or cancel authentication:
// devTools.send(domains.network().cancelAuth(authRequired));
});
// Navigate to a site that requires authentication
driver.get("https://httpbin.org/basic-auth/username/password");The V102Network class interacts with several generated CDP protocol classes:
// Generated CDP network classes (available at runtime)
class Network {
static Command<Void> setUserAgentOverride(String userAgent, String acceptLanguage, String platform, Optional<String> userAgentMetadata);
static Command<Void> setCacheDisabled(boolean cacheDisabled);
}
// Network request representation
class Request {
String getMethod();
String getUrl();
Map<String, String> getHeaders();
Optional<String> getPostData();
}// Generated CDP fetch classes (available at runtime)
class Fetch {
static Command<Void> enable(Optional<List<RequestPattern>> patterns, Optional<Boolean> handleAuthRequests);
static Command<Void> disable();
static Event<AuthRequired> authRequired();
static Event<RequestPaused> requestPaused();
static Command<Void> continueRequest(RequestId requestId, Optional<String> url, Optional<String> method, Optional<String> postData, Optional<List<HeaderEntry>> headers, Optional<Boolean> interceptResponse);
static Command<Void> fulfillRequest(RequestId requestId, int responseCode, Optional<List<HeaderEntry>> responseHeaders, Optional<String> binaryResponseHeaders, Optional<String> body, Optional<String> responsePhrase);
static Command<Void> continueWithAuth(RequestId requestId, AuthChallengeResponse authChallengeResponse);
static Command<GetResponseBodyResponse> getResponseBody(RequestId requestId);
}
// Authentication required event
class AuthRequired {
RequestId getRequestId();
AuthChallenge getAuthChallenge();
}
class AuthChallenge {
String getOrigin();
String getScheme();
String getRealm();
}
// Request paused event
class RequestPaused {
RequestId getRequestId();
Request getRequest();
Optional<Integer> getResponseStatusCode();
Optional<String> getResponseErrorReason();
Optional<List<HeaderEntry>> getResponseHeaders();
}
// Request and response data structures
class RequestPattern {
RequestPattern(Optional<String> urlPattern, Optional<String> resourceType, Optional<RequestStage> requestStage);
}
enum RequestStage {
REQUEST, RESPONSE
}
class HeaderEntry {
HeaderEntry(String name, String value);
String getName();
String getValue();
}
class AuthChallengeResponse {
enum Response {
PROVIDECREDENTIALS, CANCELAUTH, DEFAULT
}
AuthChallengeResponse(Response response, Optional<String> username, Optional<String> password);
}// Selenium network types
class UserAgent {
String userAgent();
String acceptLanguage();
String platform();
}
class UsernameAndPassword {
String username();
String password();
}
class HttpRequest {
HttpRequest(HttpMethod method, String uri);
HttpMethod getMethod();
URI getUri();
void addHeader(String name, String value);
Iterable<String> getHeaderNames();
Iterable<String> getHeaders(String name);
Supplier<InputStream> getContent();
}
class HttpResponse {
void setStatus(int status);
int getStatus();
void addHeader(String name, String value);
Iterable<String> getHeaderNames();
Iterable<String> getHeaders(String name);
void setContent(byte[] content);
Supplier<InputStream> getContent();
}
class Either<L, R> {
boolean isLeft();
boolean isRight();
L left();
R right();
}// Log all network requests
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
if (message.isLeft()) {
HttpRequest request = message.left();
System.out.println(String.format(
"Request: %s %s",
request.getMethod(),
request.getUri()
));
}
devTools.send(domains.network().continueWithoutModification(pausedRequest));
});// Analyze response data
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
if (message.isRight()) {
HttpResponse response = message.right();
System.out.println(String.format(
"Response: %d for request %s",
response.getStatus(),
domains.network().getRequestId(pausedRequest)
));
// Log response headers
response.getHeaderNames().forEach(headerName -> {
response.getHeaders(headerName).forEach(headerValue -> {
System.out.println(" " + headerName + ": " + headerValue);
});
});
}
devTools.send(domains.network().continueWithoutModification(pausedRequest));
});// Intercept only specific types of requests
devTools.addListener(domains.network().requestPausedEvent(), (pausedRequest) -> {
Either<HttpRequest, HttpResponse> message = domains.network().createSeMessages(pausedRequest);
if (message.isLeft()) {
HttpRequest request = message.left();
String uri = request.getUri().toString();
if (uri.contains("/api/") && request.getMethod().equals("POST")) {
// Handle API POST requests specially
handleApiPostRequest(pausedRequest, request);
} else if (uri.endsWith(".css") || uri.endsWith(".js")) {
// Block static resources for faster testing
HttpResponse blockedResponse = new HttpResponse();
blockedResponse.setStatus(204); // No Content
devTools.send(domains.network().fulfillRequest(pausedRequest, blockedResponse));
} else {
devTools.send(domains.network().continueWithoutModification(pausedRequest));
}
}
});Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v102