CtrlK
BlogDocsLog inGet started
Tessl Logo

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

Java bindings for Chrome DevTools Protocol version 101, enabling browser automation and debugging capabilities through CDP integration

Pending
Overview
Eval results
Files

target.mddocs/

Target Management

The target domain provides browser target and session management capabilities for handling multiple tabs, windows, browser contexts, and complex automation scenarios requiring fine-grained control over browser instances.

Capabilities

V101Target

Target management implementation that provides commands for attaching to, detaching from, and monitoring browser targets.

/**
 * Target management for browser contexts and sessions in CDP version 101
 * Implements the Target interface for managing browser targets and sessions
 */
public class V101Target implements Target {
    
    /**
     * Creates a new target handler instance
     */
    public V101Target();
    
    /**
     * Detach from a specific target
     * @param sessionId Optional session ID to detach from
     * @param targetId Optional target ID to detach from
     * @return Command to execute the detachment operation
     */
    public Command<Void> detachFromTarget(Optional<SessionID> sessionId, Optional<TargetID> targetId);
    
    /**
     * Get information about all available targets
     * @return Command that returns a list of target information objects
     */
    public Command<List<TargetInfo>> getTargets();
    
    /**
     * Attach to a specific target for debugging and control
     * @param targetId ID of the target to attach to
     * @return Command that returns a session ID for the attached target
     */
    public Command<SessionID> attachToTarget(TargetID targetId);
    
    /**
     * Enable automatic attachment to new targets as they are created
     * @return Command to enable auto-attach functionality
     */
    public Command<Void> setAutoAttach();
    
    /**
     * Get an event stream for target detachment notifications
     * @return Event that fires when targets are detached
     */
    public Event<TargetID> detached();
}

Usage Examples:

import org.openqa.selenium.devtools.v101.V101Target;
import org.openqa.selenium.devtools.idealized.target.model.*;

// Create target handler
V101Target target = new V101Target();

// Enable auto-attach for new targets
devTools.send(target.setAutoAttach());

// Get all available targets
List<TargetInfo> targets = devTools.send(target.getTargets());
System.out.println("Found " + targets.size() + " targets:");

for (TargetInfo targetInfo : targets) {
    System.out.println("Target: " + targetInfo.getType() + 
                      " - " + targetInfo.getTitle() + 
                      " (" + targetInfo.getUrl() + ")");
}

// Find and attach to a specific page target
Optional<TargetInfo> pageTarget = targets.stream()
    .filter(t -> "page".equals(t.getType()))
    .filter(t -> t.getUrl().contains("example.com"))
    .findFirst();

if (pageTarget.isPresent()) {
    SessionID sessionId = devTools.send(target.attachToTarget(pageTarget.get().getTargetId()));
    System.out.println("Attached to target with session ID: " + sessionId);
    
    // Use the session for target-specific operations
    
    // Detach when done
    devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.of(pageTarget.get().getTargetId())));
}

// Listen for target detachment events
devTools.addListener(target.detached(), targetId -> {
    System.out.println("Target detached: " + targetId);
});

TargetInfo

Information about a browser target including its type, state, and relationships.

/**
 * Represents information about a browser target
 * Contains target identification, type, state, and relationship data
 */
public class TargetInfo {
    
    /**
     * Get the unique identifier for this target
     * @return TargetID uniquely identifying this target
     */
    public TargetID getTargetId();
    
    /**
     * Get the type of target (page, background_page, service_worker, etc.)
     * @return String representing the target type
     */
    public String getType();
    
    /**
     * Get the title of the target (usually the page title)
     * @return String containing the target title
     */
    public String getTitle();
    
    /**
     * Get the URL associated with this target
     * @return String containing the target URL
     */
    public String getUrl();
    
    /**
     * Check if this target has an attached debugging client
     * @return Boolean indicating if target is attached
     */
    public Boolean getAttached();
    
    /**
     * Get the ID of the target that opened this target
     * @return Optional TargetID of the opener target
     */
    public Optional<TargetID> getOpenerId();
    
    /**
     * Get the browser context ID this target belongs to
     * @return Optional BrowserContextID for the target's context
     */
    public Optional<BrowserContextID> getBrowserContextId();
}

Target Types:

  • "page" - Regular web page or tab
  • "background_page" - Extension background page
  • "service_worker" - Service worker instance
  • "shared_worker" - Shared worker instance
  • "browser" - Browser instance itself
  • "other" - Other target types

Usage Example:

// Analyze target hierarchy and relationships
List<TargetInfo> targets = devTools.send(target.getTargets());

for (TargetInfo targetInfo : targets) {
    System.out.println("=== Target Info ===");
    System.out.println("ID: " + targetInfo.getTargetId());
    System.out.println("Type: " + targetInfo.getType());
    System.out.println("Title: " + targetInfo.getTitle());
    System.out.println("URL: " + targetInfo.getUrl());
    System.out.println("Attached: " + targetInfo.getAttached());
    
    if (targetInfo.getOpenerId().isPresent()) {
        System.out.println("Opened by: " + targetInfo.getOpenerId().get());
    }
    
    if (targetInfo.getBrowserContextId().isPresent()) {
        System.out.println("Browser Context: " + targetInfo.getBrowserContextId().get());
    }
    
    System.out.println();
}

ID Wrapper Types

Type-safe wrappers for various target-related identifiers.

/**
 * Wrapper for target identifiers ensuring type safety
 */
public class TargetID {
    /**
     * Create a target ID from a string identifier
     * @param id String representation of the target ID
     */
    public TargetID(String id);
    
    /**
     * Get the string representation of this target ID
     * @return String ID that can be used in CDP commands
     */
    public String toString();
}

/**
 * Wrapper for session identifiers ensuring type safety
 */
public class SessionID {
    /**
     * Create a session ID from a string identifier
     * @param id String representation of the session ID
     */
    public SessionID(String id);
    
    /**
     * Get the string representation of this session ID
     * @return String ID that can be used in CDP commands
     */
    public String toString();
}

/**
 * Wrapper for browser context identifiers ensuring type safety
 */
public class BrowserContextID {
    /**
     * Create a browser context ID from a string identifier
     * @param id String representation of the context ID
     */
    public BrowserContextID(String id);
    
    /**
     * Get the string representation of this browser context ID
     * @return String ID that can be used in CDP commands
     */
    public String toString();
}

CDP Protocol Commands

The underlying CDP Target domain commands used by V101Target:

// From org.openqa.selenium.devtools.v101.target.Target
public static Command<GetTargetsResponse> getTargets();
public static Command<AttachToTargetResponse> attachToTarget(TargetID targetId, Optional<Boolean> flatten);
public static Command<Void> detachFromTarget(Optional<SessionID> sessionId, Optional<TargetID> targetId);
public static Command<Void> setAutoAttach(Boolean autoAttach, Boolean waitForDebuggerOnStart, Optional<Boolean> flatten);
public static Event<DetachedFromTargetEvent> detachedFromTarget();

Response Types:

/**
 * Response from Target.getTargets command
 */
public class GetTargetsResponse {
    public List<TargetInfo> getTargetInfos();
}

/**
 * Response from Target.attachToTarget command
 */
public class AttachToTargetResponse {
    public SessionID getSessionId();
}

/**
 * Event data when a target is detached
 */
public class DetachedFromTargetEvent {
    public SessionID getSessionId();
    public Optional<TargetID> getTargetId();
}

Advanced Usage Patterns

Multi-Tab Management

// Manage multiple browser tabs/windows
List<TargetInfo> allTargets = devTools.send(target.getTargets());

// Filter for page targets only
List<TargetInfo> pageTargets = allTargets.stream()
    .filter(t -> "page".equals(t.getType()))
    .collect(Collectors.toList());

System.out.println("Found " + pageTargets.size() + " page targets");

// Attach to each page target for monitoring
Map<TargetID, SessionID> activeSessions = new HashMap<>();

for (TargetInfo pageTarget : pageTargets) {
    try {
        SessionID sessionId = devTools.send(target.attachToTarget(pageTarget.getTargetId()));
        activeSessions.put(pageTarget.getTargetId(), sessionId);
        System.out.println("Attached to: " + pageTarget.getTitle());
    } catch (Exception e) {
        System.err.println("Failed to attach to target " + pageTarget.getTargetId() + ": " + e.getMessage());
    }
}

// Later, detach from all sessions
activeSessions.forEach((targetId, sessionId) -> {
    try {
        devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.of(targetId)));
        System.out.println("Detached from target: " + targetId);
    } catch (Exception e) {
        System.err.println("Failed to detach from target " + targetId + ": " + e.getMessage());
    }
});

Target Discovery and Filtering

// Advanced target discovery with filtering and categorization
public class TargetManager {
    private final V101Target target;
    private final DevTools devTools;
    
    public TargetManager(DevTools devTools) {
        this.devTools = devTools;
        this.target = new V101Target();
    }
    
    public List<TargetInfo> findPagesByURL(String urlPattern) {
        List<TargetInfo> targets = devTools.send(target.getTargets());
        return targets.stream()
            .filter(t -> "page".equals(t.getType()))
            .filter(t -> t.getUrl().matches(urlPattern))
            .collect(Collectors.toList());
    }
    
    public List<TargetInfo> findTargetsByType(String targetType) {
        List<TargetInfo> targets = devTools.send(target.getTargets());
        return targets.stream()
            .filter(t -> targetType.equals(t.getType()))
            .collect(Collectors.toList());
    }
    
    public Map<String, List<TargetInfo>> categorizeTargets() {
        List<TargetInfo> targets = devTools.send(target.getTargets());
        return targets.stream()
            .collect(Collectors.groupingBy(TargetInfo::getType));
    }
    
    public Optional<TargetInfo> findMainPage() {
        List<TargetInfo> targets = devTools.send(target.getTargets());
        return targets.stream()
            .filter(t -> "page".equals(t.getType()))
            .filter(t -> !t.getOpenerId().isPresent()) // No opener = main page
            .findFirst();
    }
}

// Usage
TargetManager targetManager = new TargetManager(devTools);

// Find all pages matching a pattern
List<TargetInfo> apiPages = targetManager.findPagesByURL(".*api\\.example\\.com.*");

// Categorize all targets
Map<String, List<TargetInfo>> targetsByType = targetManager.categorizeTargets();
targetsByType.forEach((type, targets) -> {
    System.out.println(type + ": " + targets.size() + " targets");
});

// Find the main page
Optional<TargetInfo> mainPage = targetManager.findMainPage();
if (mainPage.isPresent()) {
    System.out.println("Main page: " + mainPage.get().getTitle());
}

Auto-Attach Monitoring

// Set up automatic attachment monitoring for new targets
devTools.send(target.setAutoAttach());

// Listen for new targets being created and attached
devTools.addListener(target.detached(), targetId -> {
    System.out.println("Target detached: " + targetId);
    
    // Could trigger cleanup or reconnection logic here
    handleTargetDetachment(targetId);
});

// Periodically check target status
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(() -> {
    try {
        List<TargetInfo> currentTargets = devTools.send(target.getTargets());
        System.out.println("Current target count: " + currentTargets.size());
        
        // Monitor for unexpected target changes
        long pageCount = currentTargets.stream()
            .filter(t -> "page".equals(t.getType()))
            .count();
            
        if (pageCount == 0) {
            System.err.println("Warning: No page targets found!");
        }
        
    } catch (Exception e) {
        System.err.println("Error checking targets: " + e.getMessage());
    }
}, 0, 5, TimeUnit.SECONDS);

Error Handling and Recovery

// Robust target management with error handling
public class RobustTargetManager {
    private final V101Target target;
    private final DevTools devTools;
    private final Set<SessionID> activeSessions = ConcurrentHashMap.newKeySet();
    
    public SessionID attachToTargetSafely(TargetID targetId) {
        try {
            SessionID sessionId = devTools.send(target.attachToTarget(targetId));
            activeSessions.add(sessionId);
            return sessionId;
        } catch (Exception e) {
            System.err.println("Failed to attach to target " + targetId + ": " + e.getMessage());
            return null;
        }
    }
    
    public void detachFromTargetSafely(SessionID sessionId, TargetID targetId) {
        try {
            devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.of(targetId)));
            activeSessions.remove(sessionId);
        } catch (Exception e) {
            System.err.println("Failed to detach from target " + targetId + ": " + e.getMessage());
        }
    }
    
    public void cleanupAllSessions() {
        for (SessionID sessionId : activeSessions) {
            try {
                devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.empty()));
            } catch (Exception e) {
                System.err.println("Error during cleanup of session " + sessionId + ": " + e.getMessage());
            }
        }
        activeSessions.clear();
    }
    
    public List<TargetInfo> getTargetsSafely() {
        try {
            return devTools.send(target.getTargets());
        } catch (Exception e) {
            System.err.println("Error getting targets: " + e.getMessage());
            return Collections.emptyList();
        }
    }
}

Install with Tessl CLI

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

docs

entry-point.md

events.md

index.md

javascript.md

logging.md

network.md

target.md

tile.json