CtrlK
BlogDocsLog inGet started
Tessl Logo

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

Chrome DevTools Protocol (CDP) bindings for Selenium WebDriver targeting Chromium version 85

Pending
Overview
Eval results
Files

logging.mddocs/

Browser Logging

Browser log capture and management for the Chrome DevTools Protocol v85. This functionality allows you to access browser logs with different severity levels and timestamps for debugging and monitoring purposes.

Capabilities

V85Log Class

The main class for browser log management implementing the idealized Log interface.

/**
 * Browser logging functionality for Chrome DevTools v85
 */
public class V85Log implements org.openqa.selenium.devtools.idealized.log.Log {
    /**
     * Creates a new V85Log instance
     */
    public V85Log();
}

Log Control

Enable, disable, and clear browser logs.

/**
 * Enables browser log collection
 * @return Command to enable logging
 */
public Command<Void> enable();

/**
 * Clears all collected browser logs
 * @return Command to clear logs
 */
public Command<Void> clear();

Usage Example:

import org.openqa.selenium.devtools.v85.V85Log;

V85Log log = domains.log();

// Enable log collection
devTools.send(log.enable());

// Clear existing logs
devTools.send(log.clear());

Log Event Monitoring

Monitor new log entries as they are added by the browser.

/**
 * Event fired when a new log entry is added
 * @return Event for new log entries
 */
public Event<org.openqa.selenium.devtools.idealized.log.model.LogEntry> entryAdded();

Usage Example:

// Listen for new log entries
devTools.addListener(log.entryAdded(), logEntry -> {
    System.out.printf("[%s] %s: %s%n",
        new Date(logEntry.getEntry().getTimestamp()),
        logEntry.getEntry().getLevel(),
        logEntry.getEntry().getMessage()
    );
    
    // Handle specific log levels
    if (logEntry.getEntry().getLevel() == Level.SEVERE) {
        handleSevereError(logEntry);
    }
});

Complete Logging Setup

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v85.V85Domains;
import java.util.logging.Level;

ChromeDriver driver = new ChromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();

V85Domains domains = new V85Domains(devTools);
V85Log log = domains.log();

// Enable logging
devTools.send(log.enable());

// Set up log monitoring
devTools.addListener(log.entryAdded(), logEntry -> {
    var entry = logEntry.getEntry();
    
    // Format log message
    String formattedLog = String.format(
        "[%s] %s - %s: %s",
        new Date(entry.getTimestamp()),
        logEntry.getSource(),
        entry.getLevel(),
        entry.getMessage()
    );
    
    // Route to appropriate handler based on level
    switch (entry.getLevel()) {
        case SEVERE:
            System.err.println("ERROR: " + formattedLog);
            logToErrorSystem(formattedLog);
            break;
            
        case WARNING:
            System.out.println("WARN: " + formattedLog);
            logToWarningSystem(formattedLog);
            break;
            
        case INFO:
            System.out.println("INFO: " + formattedLog);
            break;
            
        case FINEST:
            if (debugMode) {
                System.out.println("DEBUG: " + formattedLog);
            }
            break;
            
        default:
            System.out.println("LOG: " + formattedLog);
    }
});

// Navigate to page - logs will be captured
driver.get("https://example.com");

// Clear logs when needed
devTools.send(log.clear());

Log Level Conversion

The V85Log class automatically converts Chrome DevTools Protocol log levels to Java logging levels:

/**
 * Converts CDP log level to Java logging level
 * @param level - CDP log level
 * @return Java logging Level
 */
private Level fromCdpLevel(LogEntry.Level level);

Level Mapping:

  • verboseLevel.FINEST
  • infoLevel.INFO
  • warningLevel.WARNING
  • errorLevel.SEVERE
  • Default → Level.INFO

Timestamp Handling

/**
 * Converts CDP timestamp to Java long timestamp
 * @param timestamp - CDP timestamp
 * @return Java timestamp in milliseconds, or current time if parsing fails
 */
private long fromCdpTimestamp(Timestamp timestamp);

CDP Model Classes

LogEntry (CDP)

Raw log entry from the Chrome DevTools Protocol.

/**
 * Log entry from Chrome DevTools Protocol
 */
public class LogEntry {
    /**
     * Gets the log message source
     * @return Log source (e.g., "javascript", "network", "storage")
     */
    public Source getSource();
    
    /**
     * Gets the log level
     * @return Log severity level
     */
    public Level getLevel();
    
    /**
     * Gets the log message text
     * @return Log message content
     */
    public String getText();
    
    /**
     * Gets the timestamp when the log was created
     * @return Log timestamp
     */
    public Timestamp getTimestamp();
    
    /**
     * Gets the URL where the log originated (if applicable)
     * @return Source URL
     */
    public Optional<String> getUrl();
    
    /**
     * Gets the line number where the log originated (if applicable)
     * @return Line number in source
     */
    public Optional<Integer> getLineNumber();
    
    /**
     * Gets the stack trace for the log entry (if applicable)
     * @return Stack trace information
     */
    public Optional<StackTrace> getStackTrace();
    
    /**
     * Log severity levels in CDP
     */
    public enum Level {
        VERBOSE, INFO, WARNING, ERROR
    }
    
    /**
     * Log sources in CDP
     */
    public enum Source {
        XML, JAVASCRIPT, NETWORK, STORAGE, APPCACHE, RENDERING, 
        SECURITY, DEPRECATION, WORKER, VIOLATION, INTERVENTION, 
        RECOMMENDATION, OTHER
    }
}

LogEntry (Idealized)

Selenium's idealized log entry that wraps CDP log data.

/**
 * Selenium's idealized log entry wrapper
 */
public class org.openqa.selenium.devtools.idealized.log.model.LogEntry {
    /**
     * Creates a new idealized log entry
     * @param source - Log source as string
     * @param entry - Java LogEntry with level, timestamp, and message
     */
    public LogEntry(String source, org.openqa.selenium.logging.LogEntry entry);
    
    /**
     * Gets the log source
     * @return Source of the log entry
     */
    public String getSource();
    
    /**
     * Gets the wrapped Java log entry
     * @return Java LogEntry with standard logging information
     */
    public org.openqa.selenium.logging.LogEntry getEntry();
}

Selenium LogEntry

Standard Selenium log entry used by the idealized interface.

/**
 * Standard Selenium log entry
 */
public class org.openqa.selenium.logging.LogEntry {
    /**
     * Gets the log level
     * @return Java logging Level
     */
    public Level getLevel();
    
    /**
     * Gets the timestamp in milliseconds
     * @return Timestamp when log was created
     */
    public long getTimestamp();
    
    /**
     * Gets the log message
     * @return Log message text
     */
    public String getMessage();
}

Advanced Log Filtering

// Filter logs by source and level
devTools.addListener(log.entryAdded(), logEntry -> {
    String source = logEntry.getSource();
    Level level = logEntry.getEntry().getLevel();
    String message = logEntry.getEntry().getMessage();
    
    // Only process JavaScript errors and network issues
    if (source.equals("javascript") && level == Level.SEVERE) {
        handleJavaScriptError(logEntry);
    } else if (source.equals("network") && (level == Level.WARNING || level == Level.SEVERE)) {
        handleNetworkIssue(logEntry);
    }
    
    // Filter by message content
    if (message.contains("404") || message.contains("Failed to load")) {
        handleResourceError(logEntry);
    }
});

// Batch log processing
private final List<LogEntry> logBuffer = new ArrayList<>();
private final Timer logProcessor = new Timer();

devTools.addListener(log.entryAdded(), logEntry -> {
    synchronized (logBuffer) {
        logBuffer.add(logEntry);
        
        // Process logs in batches every 5 seconds
        if (logBuffer.size() == 1) {
            logProcessor.schedule(new TimerTask() {
                @Override
                public void run() {
                    processBatchedLogs();
                }
            }, 5000);
        }
    }
});

private void processBatchedLogs() {
    synchronized (logBuffer) {
        if (!logBuffer.isEmpty()) {
            // Process all buffered logs
            logBuffer.forEach(this::processLogEntry);
            logBuffer.clear();
        }
    }
}

Log Persistence

// Save logs to file
private final FileWriter logWriter = new FileWriter("browser-logs.txt", true);

devTools.addListener(log.entryAdded(), logEntry -> {
    try {
        String logLine = String.format(
            "%s [%s] %s: %s%n",
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(logEntry.getEntry().getTimestamp())),
            logEntry.getSource().toUpperCase(),
            logEntry.getEntry().getLevel(),
            logEntry.getEntry().getMessage()
        );
        
        logWriter.write(logLine);
        logWriter.flush();
    } catch (IOException e) {
        System.err.println("Failed to write log: " + e.getMessage());
    }
});

// Remember to close the writer when done
// logWriter.close();

Install with Tessl CLI

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

docs

events.md

index.md

javascript.md

logging.md

network.md

target.md

tile.json