CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-seleniumhq-selenium--selenium-devtools-v102

Java bindings for Chrome DevTools Protocol version 102, providing programmatic access to Chrome browser debugging and automation capabilities

Pending
Overview
Eval results
Files

network-operations.mddocs/

Network Operations and Interception

Handles network operations, request/response interception, authentication, and user agent management. This domain enables comprehensive network monitoring and manipulation capabilities for advanced automation scenarios.

Capabilities

V102Network Class

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:

Basic Network Interception

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());

Request Modification

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));
        }
    }
});

Custom Response Fulfillment

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));
        }
    }
});

User Agent and Caching Control

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());

Authentication Handling

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");

CDP Protocol Classes

The V102Network class interacts with several generated CDP protocol classes:

Network Domain

// 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();
}

Fetch Domain

// 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 Integration Types

// 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();
}

Network Monitoring Patterns

Request Logging

// 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));
});

Response Analysis

// 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));
});

Conditional Interception

// 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

docs

console-logging.md

domain-management.md

index.md

javascript-execution.md

network-operations.md

runtime-events.md

target-management.md

tile.json