CtrlK
BlogDocsLog inGet started
Tessl Logo

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

Chrome DevTools Protocol version 99 support library for Selenium WebDriver Java bindings

Pending
Overview
Eval results
Files

network.mddocs/

Network Management

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.

Core Imports

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;

Capabilities

Network Handler

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

User Agent Override

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
}

Network Caching

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

Authentication Management

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

Request Filtering and Interception

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

Low-level Request Interception

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

Authentication Handling

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

Request and Response Manipulation

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

Protocol Types

Authentication Types

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

Request Interception Types

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

Usage Examples

Basic Network Monitoring

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

Request Modification

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

Response Mocking

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

Authentication Handling

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

User Agent Override

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

Authentication Management

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

Request Filtering

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

Error Handling

Network operations can encounter various error conditions:

  • Protocol errors: CDP communication failures
  • Request/response errors: Invalid HTTP data
  • Authentication failures: Invalid credentials or cancelled auth
  • Interception conflicts: Multiple interception handlers

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

Performance Considerations

  • Interception overhead: Request interception adds latency to all network requests
  • Memory usage: Large request/response bodies are held in memory during interception
  • Event processing: Network event handlers should be lightweight to avoid blocking
  • Cleanup: Always disable interception when not needed to restore normal performance

Install with Tessl CLI

npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v99

docs

events.md

index.md

javascript.md

logging.md

network.md

targets.md

tile.json