Chrome DevTools Protocol (CDP) bindings for Java - version 110, enabling advanced browser automation features like network interception, console event handling, JavaScript execution, and target management.
—
Access to browser logs including console messages, network logs, and other diagnostic information using Chrome DevTools Protocol v110.
High-level interface for CDP logging functionality providing type-safe access to browser logging operations.
/**
* Log domain implementation for CDP v110 logging operations
*/
public class v110Log implements org.openqa.selenium.devtools.idealized.log.Log {
/**
* Initialize log domain (no parameters required)
*/
public v110Log();
}Enable and disable browser logging to start collecting log entries.
/**
* Enable log domain to start collecting entries
* @return Command to enable logging
*/
public Command<Void> enable();
/**
* Clear all collected log entries
* @return Command to clear logs
*/
public Command<Void> clear();Usage Example:
import org.openqa.selenium.devtools.v110.v110Log;
v110Log log = new v110Log();
// Enable logging
devTools.send(log.enable());
// Navigate to page that generates logs
driver.get("https://example.com");
// Clear logs if needed
devTools.send(log.clear());Monitor browser log entries as they are generated with detailed event information.
/**
* Get log entry added events
* @return Event stream for log entries
*/
public Event<org.openqa.selenium.devtools.idealized.log.model.LogEntry> entryAdded();Usage Example:
import org.openqa.selenium.devtools.idealized.log.model.LogEntry;
import org.openqa.selenium.logging.LogEntry as SeleniumLogEntry;
// Enable logging
devTools.send(log.enable());
// Add log entry listener
devTools.addListener(log.entryAdded(), logEntry -> {
String source = logEntry.getSource();
SeleniumLogEntry seleniumEntry = logEntry.getEntry();
System.out.println("Log Source: " + source);
System.out.println("Level: " + seleniumEntry.getLevel());
System.out.println("Timestamp: " + new Date(seleniumEntry.getTimestamp()));
System.out.println("Message: " + seleniumEntry.getMessage());
System.out.println("---");
});
// Navigate to trigger log generation
driver.get("https://example.com");Internal conversion between CDP and Java logging levels for proper log categorization.
/**
* Convert CDP log level to Java logging level
* @param level CDP log level
* @return Java logging Level
*/
private Level fromCdpLevel(LogEntry.Level level);
/**
* Convert CDP timestamp to Java timestamp
* @param timestamp CDP timestamp
* @return Java timestamp in milliseconds
*/
private long fromCdpTimestamp(Timestamp timestamp);Direct access to CDP Log domain for low-level logging operations.
import org.openqa.selenium.devtools.v110.log.Log;
/**
* Enable log domain
*/
public static Command<Void> enable();
/**
* Disable log domain
*/
public static Command<Void> disable();
/**
* Clear browser logs
*/
public static Command<Void> clear();
/**
* Start violations reporting
*/
public static Command<Void> startViolationsReporting(List<ViolationSetting> config);
/**
* Stop violations reporting
*/
public static Command<Void> stopViolationsReporting();
/**
* Log entry added event
*/
public static Event<EntryAdded> entryAdded();import org.openqa.selenium.devtools.v110.log.model.*;
import org.openqa.selenium.devtools.idealized.log.model.*;
import org.openqa.selenium.logging.LogEntry;
import java.util.logging.Level;
/**
* CDP log entry
*/
public class org.openqa.selenium.devtools.v110.log.model.LogEntry {
/**
* Log source (console, network, security, etc.)
*/
LogEntrySource getSource();
/**
* Log level (verbose, info, warning, error)
*/
LogEntryLevel getLevel();
/**
* Log message text
*/
String getText();
/**
* Log entry timestamp
*/
Timestamp getTimestamp();
/**
* Source URL if applicable
*/
Optional<String> getUrl();
/**
* Line number in source if applicable
*/
Optional<Integer> getLineNumber();
/**
* Stack trace if applicable
*/
Optional<StackTrace> getStackTrace();
/**
* Network request ID if from network source
*/
Optional<NetworkRequestId> getNetworkRequestId();
/**
* Worker ID if from worker source
*/
Optional<String> getWorkerId();
/**
* Additional arguments
*/
Optional<List<RemoteObject>> getArgs();
}
/**
* Idealized log entry (high-level)
*/
public class org.openqa.selenium.devtools.idealized.log.model.LogEntry {
/**
* Log source as string
*/
String getSource();
/**
* Selenium log entry with standard format
*/
LogEntry getEntry();
}
/**
* Log entry source enumeration
*/
public enum LogEntrySource {
XML, JAVASCRIPT, NETWORK, STORAGE, APPCACHE, RENDERING,
SECURITY, DEPRECATION, WORKER, VIOLATION, INTERVENTION,
RECOMMENDATION, OTHER
}
/**
* Log entry level enumeration
*/
public enum LogEntryLevel {
VERBOSE, INFO, WARNING, ERROR
}/**
* Log entry added event
*/
public class EntryAdded {
/**
* The log entry that was added
*/
org.openqa.selenium.devtools.v110.log.model.LogEntry getEntry();
}
/**
* Violation setting for performance monitoring
*/
public class ViolationSetting {
/**
* Violation type name
*/
String getName();
/**
* Threshold value in milliseconds
*/
Number getThreshold();
}import org.openqa.selenium.devtools.v110.runtime.model.Timestamp;
import org.openqa.selenium.devtools.v110.runtime.model.StackTrace;
import org.openqa.selenium.devtools.v110.runtime.model.RemoteObject;
/**
* Network request identifier
*/
public class NetworkRequestId {
String toString();
}
/**
* CDP timestamp
*/
public class Timestamp {
Number toJson();
String toString();
}v110Log log = new v110Log();
devTools.send(log.enable());
// Process different types of log entries
devTools.addListener(log.entryAdded(), logEntry -> {
String source = logEntry.getSource();
LogEntry seleniumEntry = logEntry.getEntry();
Level level = seleniumEntry.getLevel();
String message = seleniumEntry.getMessage();
// Process based on source
switch (source.toLowerCase()) {
case "console":
processConsoleLog(level, message);
break;
case "network":
processNetworkLog(level, message);
break;
case "security":
processSecurityLog(level, message);
break;
case "javascript":
processJavaScriptLog(level, message);
break;
default:
processGenericLog(source, level, message);
}
});
// Navigate and observe logs
driver.get("https://example.com");// Filter and handle only error-level logs
devTools.addListener(log.entryAdded(), logEntry -> {
LogEntry seleniumEntry = logEntry.getEntry();
if (seleniumEntry.getLevel().equals(Level.SEVERE)) {
System.err.println("ERROR LOG DETECTED:");
System.err.println("Source: " + logEntry.getSource());
System.err.println("Message: " + seleniumEntry.getMessage());
System.err.println("Time: " + new Date(seleniumEntry.getTimestamp()));
// Take screenshot or other diagnostic action
if (logEntry.getSource().equals("javascript")) {
takeScreenshotOnError();
}
}
});import org.openqa.selenium.devtools.v110.log.model.ViolationSetting;
// Set up performance violation monitoring
List<ViolationSetting> violationSettings = Arrays.asList(
new ViolationSetting("longTask", 50), // Long tasks > 50ms
new ViolationSetting("longLayout", 30), // Layout > 30ms
new ViolationSetting("blockedEvent", 100), // Blocked events > 100ms
new ViolationSetting("blockedParser", 100), // Blocked parser > 100ms
new ViolationSetting("handler", 150), // Event handlers > 150ms
new ViolationSetting("recurringHandler", 250) // Recurring handlers > 250ms
);
devTools.send(Log.startViolationsReporting(violationSettings));
// Monitor for performance violations in logs
devTools.addListener(log.entryAdded(), logEntry -> {
String message = logEntry.getEntry().getMessage();
if (logEntry.getSource().equals("violation")) {
System.out.println("PERFORMANCE VIOLATION: " + message);
// Parse violation details and take action
if (message.contains("longTask")) {
System.out.println("Long task detected - consider code splitting");
} else if (message.contains("longLayout")) {
System.out.println("Long layout detected - check CSS complexity");
}
}
});// Analyze network-related log entries
devTools.addListener(log.entryAdded(), logEntry -> {
if (logEntry.getSource().equals("network")) {
String message = logEntry.getEntry().getMessage();
Level level = logEntry.getEntry().getLevel();
// Check for common network issues
if (message.contains("ERR_CONNECTION_REFUSED")) {
System.err.println("Connection refused error detected");
} else if (message.contains("ERR_NAME_NOT_RESOLVED")) {
System.err.println("DNS resolution error detected");
} else if (message.contains("Mixed Content")) {
System.err.println("Mixed content security issue detected");
} else if (level.equals(Level.WARNING) && message.contains("CORS")) {
System.err.println("CORS issue detected: " + message);
}
}
});import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
// Collect logs in structured format
ConcurrentLinkedQueue<StructuredLogEntry> collectedLogs = new ConcurrentLinkedQueue<>();
AtomicInteger errorCount = new AtomicInteger(0);
AtomicInteger warningCount = new AtomicInteger(0);
devTools.addListener(log.entryAdded(), logEntry -> {
String source = logEntry.getSource();
LogEntry seleniumEntry = logEntry.getEntry();
Level level = seleniumEntry.getLevel();
// Create structured log entry
StructuredLogEntry structured = new StructuredLogEntry(
source,
level,
seleniumEntry.getMessage(),
seleniumEntry.getTimestamp(),
driver.getCurrentUrl()
);
collectedLogs.offer(structured);
// Update counters
if (level.equals(Level.SEVERE)) {
errorCount.incrementAndGet();
} else if (level.equals(Level.WARNING)) {
warningCount.incrementAndGet();
}
});
// Later, analyze collected logs
public void analyzeLogs() {
System.out.println("Total logs collected: " + collectedLogs.size());
System.out.println("Errors: " + errorCount.get());
System.out.println("Warnings: " + warningCount.get());
// Group by source
Map<String, List<StructuredLogEntry>> logsBySource = collectedLogs.stream()
.collect(Collectors.groupingBy(StructuredLogEntry::getSource));
logsBySource.forEach((source, logs) -> {
System.out.println(source + ": " + logs.size() + " entries");
});
}
// Helper class for structured logging
class StructuredLogEntry {
private final String source;
private final Level level;
private final String message;
private final long timestamp;
private final String url;
public StructuredLogEntry(String source, Level level, String message, long timestamp, String url) {
this.source = source;
this.level = level;
this.message = message;
this.timestamp = timestamp;
this.url = url;
}
// Getters...
public String getSource() { return source; }
public Level getLevel() { return level; }
public String getMessage() { return message; }
public long getTimestamp() { return timestamp; }
public String getUrl() { return url; }
}Logging operations may encounter various error conditions:
import org.openqa.selenium.devtools.DevToolsException;
// Handle log domain enablement failures
try {
devTools.send(log.enable());
} catch (DevToolsException e) {
System.err.println("Failed to enable logging: " + e.getMessage());
// Continue without logging
}
// Handle log processing errors
devTools.addListener(log.entryAdded(), logEntry -> {
try {
processLogEntry(logEntry);
} catch (Exception e) {
System.err.println("Error processing log entry: " + e.getMessage());
// Continue processing other entries
}
});
// Handle violations reporting failures
try {
devTools.send(Log.startViolationsReporting(violationSettings));
} catch (DevToolsException e) {
System.err.println("Failed to start violations reporting: " + e.getMessage());
// Continue without performance violation monitoring
}Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v110