Java bindings for Chrome DevTools Protocol version 101, enabling browser automation and debugging capabilities through CDP integration
—
The network domain provides comprehensive control over HTTP traffic including request/response interception, authentication handling, user agent manipulation, and caching control for advanced testing scenarios.
Main network handler that extends the base Network class with version-specific CDP implementations.
/**
* Network interception, authentication, and traffic manipulation for CDP version 101
* Extends Network with AuthRequired and RequestPaused event types
*/
public class V101Network extends Network<AuthRequired, RequestPaused> {
/**
* Creates a new network handler instance
* @param devTools DevTools instance for CDP communication
*/
public V101Network(DevTools devTools);
}Inherited Methods from Network Base Class:
/**
* Set a simple user agent string override
* @param userAgent User agent string to use for all requests
*/
public void setUserAgent(String userAgent);
/**
* Set a comprehensive user agent configuration with additional properties
* @param userAgent UserAgent object with user agent, accept language, and platform
*/
public void setUserAgent(UserAgent userAgent);
/**
* Add an authentication handler for HTTP basic/digest authentication
* @param whenThisMatches Predicate to match URIs that need authentication
* @param useTheseCredentials Supplier providing credentials when needed
*/
public void addAuthHandler(Predicate<URI> whenThisMatches, Supplier<Credentials> useTheseCredentials);
/**
* Set up traffic interception with a custom filter
* @param filter Filter implementation to intercept and modify requests/responses
*/
public void interceptTrafficWith(Filter filter);
/**
* Enable traffic interception for all requests and responses
* Prepares the network domain for traffic monitoring
*/
public void prepareToInterceptTraffic();
/**
* Remove traffic interception and reset to normal network behavior
*/
public void resetNetworkFilter();
/**
* Disable the network domain and clean up all interception and auth handlers
*/
public void disable();/**
* User agent configuration with support for additional browser properties
* Immutable builder pattern for constructing user agent overrides
*/
public class UserAgent {
/**
* Create a user agent configuration with the specified user agent string
* @param userAgent The user agent string to use
*/
public UserAgent(String userAgent);
/**
* Add accept language preference to the user agent configuration
* @param acceptLanguage Accept-Language header value (e.g., "en-US,en;q=0.9")
* @return New UserAgent instance with accept language set
*/
public UserAgent acceptLanguage(String acceptLanguage);
/**
* Add platform information to the user agent configuration
* @param platform Platform string (e.g., "Windows", "MacOS", "Linux")
* @return New UserAgent instance with platform set
*/
public UserAgent platform(String platform);
/**
* Get the user agent string
* @return The configured user agent string
*/
public String userAgent();
/**
* Get the accept language configuration
* @return Optional accept language string
*/
public Optional<String> acceptLanguage();
/**
* Get the platform configuration
* @return Optional platform string
*/
public Optional<String> platform();
}Usage Examples:
import org.openqa.selenium.devtools.v101.V101Network;
import org.openqa.selenium.devtools.idealized.Network.UserAgent;
import org.openqa.selenium.UsernameAndPassword;
// Create network handler
V101Network network = new V101Network(devTools);
// Simple user agent override
network.setUserAgent("Mozilla/5.0 (compatible; TestBot/1.0)");
// Comprehensive user agent configuration
UserAgent customAgent = new UserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
.acceptLanguage("en-US,en;q=0.9,es;q=0.8")
.platform("Win32");
network.setUserAgent(customAgent);
// Authentication for specific domains
network.addAuthHandler(
uri -> uri.getHost().equals("secure.example.com"),
() -> new UsernameAndPassword("testuser", "testpass")
);
// Traffic interception
network.interceptTrafficWith(request -> {
System.out.println("Intercepting: " + request.getUri());
// Modify request headers
request.addHeader("X-Test-Header", "automation");
// Continue with modified request
return next -> {
HttpResponse response = next.execute(request);
System.out.println("Response status: " + response.getStatus());
return response;
};
});
// Enable interception
network.prepareToInterceptTraffic();
// Navigate and monitor traffic
driver.get("https://example.com");
// Clean up
network.disable();/**
* Username and password credentials for HTTP authentication
*/
public class UsernameAndPassword implements Credentials {
public UsernameAndPassword(String username, String password);
public String username();
public String password();
}Authentication Patterns:
// Pattern 1: Domain-specific authentication
network.addAuthHandler(
uri -> uri.getHost().endsWith(".internal.company.com"),
() -> new UsernameAndPassword("internal-user", "internal-pass")
);
// Pattern 2: Path-based authentication
network.addAuthHandler(
uri -> uri.getPath().startsWith("/admin/"),
() -> new UsernameAndPassword("admin", "admin-password")
);
// Pattern 3: Multiple authentication schemes
network.addAuthHandler(
uri -> uri.getHost().equals("api.service1.com"),
() -> new UsernameAndPassword("service1-key", "service1-secret")
);
network.addAuthHandler(
uri -> uri.getHost().equals("api.service2.com"),
() -> new UsernameAndPassword("service2-user", "service2-pass")
);
// Pattern 4: Dynamic credential lookup
network.addAuthHandler(
uri -> uri.getHost().contains("test"),
() -> {
// Look up credentials from configuration or external source
String host = getCurrentHost(); // Your implementation
return credentialStore.getCredentials(host);
}
);/**
* Filter interface for intercepting and modifying HTTP traffic
*/
public interface Filter {
/**
* Intercept and potentially modify an HTTP request
* @param request The HTTP request being made
* @return Function that executes the request and returns the response
*/
Function<Function<HttpRequest, HttpResponse>, HttpResponse> filter(HttpRequest request);
}
/**
* HTTP request representation for interception
*/
public interface HttpRequest {
String getMethod();
String getUri();
Map<String, List<String>> getHeaders();
Optional<InputStream> getContent();
void addHeader(String name, String value);
void setHeader(String name, String value);
void removeHeader(String name);
}
/**
* HTTP response representation for interception
*/
public interface HttpResponse {
int getStatus();
Map<String, List<String>> getHeaders();
Optional<InputStream> getContent();
void addHeader(String name, String value);
void setHeader(String name, String value);
}Traffic Interception Patterns:
// Pattern 1: Request modification
network.interceptTrafficWith(request -> {
// Add custom headers to all requests
request.addHeader("X-Automation-Tool", "Selenium");
request.addHeader("X-Test-Run-ID", testRunId);
return next -> next.execute(request);
});
// Pattern 2: Response inspection and modification
network.interceptTrafficWith(request -> {
return next -> {
HttpResponse response = next.execute(request);
// Log response details
System.out.println("Response from " + request.getUri() + ": " + response.getStatus());
// Could modify response headers or content here
if (response.getStatus() >= 400) {
System.err.println("HTTP Error: " + response.getStatus());
}
return response;
};
});
// Pattern 3: Conditional interception
network.interceptTrafficWith(request -> {
if (request.getUri().contains("/api/")) {
// Only intercept API calls
request.addHeader("Authorization", "Bearer " + getApiToken());
return next -> {
long startTime = System.currentTimeMillis();
HttpResponse response = next.execute(request);
long duration = System.currentTimeMillis() - startTime;
System.out.println("API call to " + request.getUri() +
" took " + duration + "ms, status: " + response.getStatus());
return response;
};
} else {
// Pass through non-API requests unchanged
return next -> next.execute(request);
}
});
// Pattern 4: Request blocking or stubbing
network.interceptTrafficWith(request -> {
if (request.getUri().contains("analytics") || request.getUri().contains("tracking")) {
// Block analytics/tracking requests
return next -> createMockResponse(200, "OK");
}
if (request.getUri().contains("/slow-endpoint")) {
// Mock slow endpoints for faster testing
return next -> createMockResponse(200, "{\"data\": \"mocked\"}");
}
return next -> next.execute(request);
});/**
* Enable network caching (default browser behavior)
* Allows the browser to cache responses according to HTTP cache headers
*/
protected Command<Void> enableNetworkCaching();
/**
* Disable network caching for all requests
* Forces fresh requests for all resources, useful for testing
*/
protected Command<Void> disableNetworkCaching();Usage Example:
// Disable caching for consistent test results
network.send(network.disableNetworkCaching());
// Run tests that need fresh data
driver.get("https://api.example.com/data");
// Re-enable caching if needed
network.send(network.enableNetworkCaching());The underlying CDP protocol types used by the network domain:
/**
* CDP Fetch.authRequired event data
* Triggered when HTTP authentication is required
*/
public class AuthRequired {
public RequestId getRequestId();
public Request getRequest();
public AuthChallenge getAuthChallenge();
}
/**
* CDP Fetch.requestPaused event data
* Triggered when a request is intercepted and paused
*/
public class RequestPaused {
public RequestId getRequestId();
public Request getRequest();
public Optional<String> getFrameId();
public ResourceType getResourceType();
public Optional<Integer> getResponseStatusCode();
public Optional<String> getResponseErrorReason();
public Optional<List<HeaderEntry>> getResponseHeaders();
}
/**
* CDP authentication challenge information
*/
public class AuthChallenge {
public String getSource(); // "Server" or "Proxy"
public String getOrigin();
public String getScheme(); // "Basic" or "Digest"
public String getRealm();
}
/**
* CDP HTTP header entry
*/
public class HeaderEntry {
public HeaderEntry(String name, String value);
public String getName();
public String getValue();
}
/**
* CDP request pattern for interception
*/
public class RequestPattern {
public RequestPattern(Optional<String> urlPattern, Optional<ResourceType> resourceType, Optional<RequestStage> requestStage);
public Optional<String> getUrlPattern();
public Optional<ResourceType> getResourceType();
public Optional<RequestStage> getRequestStage();
}The V101Network class internally uses these CDP Fetch domain commands:
// Fetch domain commands for traffic interception
public static Command<Void> Fetch.enable(Optional<List<RequestPattern>> patterns, Optional<Boolean> handleAuthRequests);
public static Command<Void> Fetch.disable();
public static Command<Void> Fetch.continueRequest(RequestId requestId, Optional<String> url, Optional<String> method, Optional<String> postData, Optional<List<HeaderEntry>> headers, Optional<Boolean> interceptResponse);
public static Command<Void> Fetch.fulfillRequest(RequestId requestId, Integer responseCode, Optional<List<HeaderEntry>> responseHeaders, Optional<String> binaryResponseHeaders, Optional<String> body, Optional<String> responsePhrase);
public static Command<Void> Fetch.continueWithAuth(RequestId requestId, AuthChallengeResponse authChallengeResponse);
public static Command<GetResponseBodyResponse> Fetch.getResponseBody(RequestId requestId);
public static Event<AuthRequired> Fetch.authRequired();
public static Event<RequestPaused> Fetch.requestPaused();
// Network domain commands for configuration
public static Command<Void> Network.setUserAgentOverride(String userAgent, Optional<String> acceptLanguage, Optional<String> platform, Optional<Object> userAgentMetadata);
public static Command<Void> Network.setCacheDisabled(Boolean cacheDisabled);// Monitor network performance and identify slow requests
network.interceptTrafficWith(request -> {
return next -> {
long startTime = System.nanoTime();
HttpResponse response = next.execute(request);
long duration = System.nanoTime() - startTime;
long durationMs = duration / 1_000_000;
if (durationMs > 5000) { // Log requests taking > 5 seconds
System.out.println("Slow request detected: " + request.getUri() +
" took " + durationMs + "ms");
}
return response;
};
});// Comprehensive request/response logging for debugging
network.interceptTrafficWith(request -> {
System.out.println(">>> REQUEST: " + request.getMethod() + " " + request.getUri());
request.getHeaders().forEach((name, values) ->
System.out.println(">>> " + name + ": " + String.join(", ", values)));
return next -> {
HttpResponse response = next.execute(request);
System.out.println("<<< RESPONSE: " + response.getStatus());
response.getHeaders().forEach((name, values) ->
System.out.println("<<< " + name + ": " + String.join(", ", values)));
return response;
};
});Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v101