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

targets.mddocs/

Target Management

Browser target (tab/window/iframe) management including attachment, detachment, and target enumeration for multi-context automation. Enables advanced browser automation scenarios involving multiple tabs, windows, and execution contexts.

Capabilities

Target Handler

Creates a target management handler for Chrome DevTools Protocol v99.

/**
 * Target management implementation for CDP v99
 * Implements the idealized Target interface
 */
public class V99Target implements org.openqa.selenium.devtools.idealized.target.Target;

Target Attachment and Detachment

Attach to and detach from browser targets for multi-context automation.

/**
 * Attach to a specific target for DevTools communication
 * @param targetId - ID of target to attach to
 * @return Command returning session ID for the attached target
 */
public Command<SessionID> attachToTarget(TargetID targetId);

/**
 * Detach from a target, ending DevTools communication
 * @param sessionId - Optional session ID to detach
 * @param targetId - Optional target ID to detach
 * @return Command to detach from target
 */
public Command<Void> detachFromTarget(Optional<SessionID> sessionId, Optional<TargetID> targetId);

/**
 * Enable automatic attachment to new targets
 * @return Command to enable auto-attach
 */
public Command<Void> setAutoAttach();

Target Discovery

List and discover available browser targets.

/**
 * Get list of all available targets
 * @return Command returning list of target information
 */
public Command<List<TargetInfo>> getTargets();

Target Events

Monitor target lifecycle events.

/**
 * Get event for when targets are detached
 * @return Event for target detachment
 */
public Event<TargetID> detached();

Protocol Types

Target Identification

/**
 * Unique identifier for browser targets
 */
public class TargetID {
    /**
     * Create target ID from string
     * @param id - Target ID string
     */
    public TargetID(String id);
    
    /**
     * Get target ID as string
     * @return Target ID string
     */
    public String toString();
}

/**
 * Session identifier for DevTools connections
 */
public class SessionID {
    /**
     * Create session ID from string
     * @param id - Session ID string  
     */
    public SessionID(String id);
    
    /**
     * Get session ID as string
     * @return Session ID string
     */
    public String toString();
}

/**
 * Browser context identifier
 */
public class BrowserContextID {
    /**
     * Create browser context ID from string
     * @param id - Context ID string
     */
    public BrowserContextID(String id);
    
    /**
     * Get context ID as string
     * @return Context ID string
     */
    public String toString();
}

Target Information

/**
 * Information about a browser target
 */
public class TargetInfo {
    /**
     * Create target information
     * @param targetId - Target identifier
     * @param type - Target type (page, background_page, etc.)
     * @param title - Target title
     * @param url - Target URL
     * @param attached - Whether target is attached
     * @param openerId - Optional opener target ID
     * @param browserContextId - Optional browser context ID
     */
    public TargetInfo(
        TargetID targetId,
        String type,
        String title,
        String url,
        Boolean attached, 
        Optional<TargetID> openerId,
        Optional<BrowserContextID> browserContextId
    );
    
    /**
     * Get target ID
     * @return Target identifier
     */
    public TargetID getTargetId();
    
    /**
     * Get target type
     * @return Type string (page, background_page, service_worker, etc.)
     */
    public String getType();
    
    /**
     * Get target title (usually page title)
     * @return Title string
     */
    public String getTitle();
    
    /**
     * Get target URL
     * @return URL string
     */
    public String getUrl();
    
    /**
     * Check if target is attached
     * @return True if attached to DevTools
     */
    public Boolean getAttached();
    
    /**
     * Get opener target ID if target was opened by another target
     * @return Optional opener target ID
     */
    public Optional<TargetID> getOpenerId();
    
    /**
     * Get browser context ID
     * @return Optional browser context ID
     */
    public Optional<BrowserContextID> getBrowserContextId();
}

Target Types

Common target types you may encounter:

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

Usage Examples

Basic Target Discovery

import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v99.V99Domains;
import org.openqa.selenium.devtools.idealized.target.model.TargetInfo;

DevTools devTools = ...; // from ChromeDriver
V99Domains domains = new V99Domains(devTools);

// Get all available targets
List<TargetInfo> targets = devTools.send(domains.target().getTargets());

System.out.println("Available targets:");
for (TargetInfo target : targets) {
    System.out.printf("  %s: %s (%s) - %s%n",
        target.getTargetId().toString(),
        target.getTitle(),
        target.getType(),
        target.getUrl()
    );
    
    if (target.getAttached()) {
        System.out.println("    [ATTACHED]");
    }
}

Multi-Tab Automation

// Open a new tab
((JavascriptExecutor) driver).executeScript("window.open('about:blank', '_blank');");

// Get updated target list
List<TargetInfo> targets = devTools.send(domains.target().getTargets());

// Find the new tab (page type, not attached)
TargetInfo newTab = targets.stream()
    .filter(target -> "page".equals(target.getType()))
    .filter(target -> !target.getAttached())
    .findFirst()
    .orElseThrow(() -> new RuntimeException("No new tab found"));

System.out.println("Found new tab: " + newTab.getTargetId());

// Attach to the new tab
SessionID sessionId = devTools.send(domains.target().attachToTarget(newTab.getTargetId()));
System.out.println("Attached with session ID: " + sessionId);

// Later, detach from the tab
devTools.send(domains.target().detachFromTarget(Optional.of(sessionId), Optional.of(newTab.getTargetId())));

Target Event Monitoring

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

// Monitor target detachment events
devTools.addListener(domains.target().detached(), targetId -> {
    System.out.println("Target detached: " + targetId.toString());
    
    // Clean up any resources associated with this target
    cleanupTargetResources(targetId);
});

// Monitor for new targets (would require additional Target domain events)
// Note: V99Target doesn't expose target creation events directly
// You would need to poll getTargets() or use lower-level CDP events

Selective Target Attachment

// Get all targets
List<TargetInfo> targets = devTools.send(domains.target().getTargets());

// Attach only to page targets that aren't already attached
List<SessionID> attachedSessions = new ArrayList<>();

for (TargetInfo target : targets) {
    if ("page".equals(target.getType()) && !target.getAttached()) {
        try {
            SessionID sessionId = devTools.send(domains.target().attachToTarget(target.getTargetId()));
            attachedSessions.add(sessionId);
            
            System.out.printf("Attached to page '%s' with session %s%n",
                target.getTitle(), sessionId.toString());
        } catch (Exception e) {
            System.err.println("Failed to attach to target " + target.getTargetId() + ": " + e.getMessage());
        }
    }
}

// Later, clean up all attachments
for (SessionID sessionId : attachedSessions) {
    try {
        devTools.send(domains.target().detachFromTarget(Optional.of(sessionId), Optional.empty()));
    } catch (Exception e) {
        System.err.println("Failed to detach session " + sessionId + ": " + e.getMessage());
    }
}

Target Filtering and Classification

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

// Classify targets by type
Map<String, List<TargetInfo>> targetsByType = targets.stream()
    .collect(Collectors.groupingBy(TargetInfo::getType));

targetsByType.forEach((type, targetList) -> {
    System.out.println(type + " targets (" + targetList.size() + "):");
    targetList.forEach(target -> {
        System.out.printf("  %s: %s%n", target.getTitle(), target.getUrl());
    });
});

// Find main page targets (excluding extension pages, workers, etc.)
List<TargetInfo> pageTargets = targets.stream()
    .filter(target -> "page".equals(target.getType()))
    .filter(target -> !target.getUrl().startsWith("chrome-extension://"))
    .collect(Collectors.toList());

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

Browser Context Management

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

// Group targets by browser context
Map<Optional<BrowserContextID>, List<TargetInfo>> targetsByContext = targets.stream()
    .collect(Collectors.groupingBy(TargetInfo::getBrowserContextId));

targetsByContext.forEach((contextId, targetList) -> {
    String contextName = contextId.map(id -> id.toString()).orElse("default");
    System.out.println("Browser context " + contextName + ":");
    
    targetList.forEach(target -> {
        System.out.printf("  %s (%s): %s%n", 
            target.getTitle(), target.getType(), target.getUrl());
    });
});

Target Hierarchy Tracking

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

// Build parent-child relationships
Map<TargetID, List<TargetInfo>> childTargets = targets.stream()
    .filter(target -> target.getOpenerId().isPresent())
    .collect(Collectors.groupingBy(target -> target.getOpenerId().get()));

// Find root targets (no opener)
List<TargetInfo> rootTargets = targets.stream()
    .filter(target -> target.getOpenerId().isEmpty())
    .collect(Collectors.toList());

// Display hierarchy
for (TargetInfo rootTarget : rootTargets) {
    displayTargetHierarchy(rootTarget, childTargets, 0);
}

private void displayTargetHierarchy(TargetInfo target, Map<TargetID, List<TargetInfo>> childMap, int depth) {
    String indent = "  ".repeat(depth);
    System.out.printf("%s%s (%s): %s%n", indent, target.getTitle(), target.getType(), target.getUrl());
    
    List<TargetInfo> children = childMap.getOrDefault(target.getTargetId(), Collections.emptyList());
    for (TargetInfo child : children) {
        displayTargetHierarchy(child, childMap, depth + 1);
    }
}

Error Handling

Target management operations can encounter various issues:

  • Invalid target IDs: Target may have been closed before attachment
  • Session conflicts: Multiple DevTools sessions on same target
  • Permission issues: Some targets may not allow attachment
  • Context mismatches: Targets in different browser contexts have different capabilities

Handle errors through proper exception handling:

try {
    List<TargetInfo> targets = devTools.send(domains.target().getTargets());
    
    for (TargetInfo target : targets) {
        if (shouldAttachToTarget(target)) {
            try {
                SessionID sessionId = devTools.send(domains.target().attachToTarget(target.getTargetId()));
                handleAttachedTarget(target.getTargetId(), sessionId);
            } catch (DevToolsException e) {
                System.err.println("Failed to attach to target " + target.getTargetId() + ": " + e.getMessage());
                // Continue with other targets
            }
        }
    }
} catch (DevToolsException e) {
    System.err.println("Failed to get targets: " + e.getMessage());
}

Performance Considerations

  • Target polling: Frequent getTargets() calls can impact performance
  • Session management: Too many attached sessions consume browser resources
  • Event processing: Target events should be processed efficiently
  • Memory usage: Maintaining references to many targets can consume memory
  • Network overhead: Remote debugging increases target-related network traffic

Security Considerations

  • Cross-origin restrictions: Some targets may be in different security contexts
  • Extension isolation: Extension targets have different permissions
  • Private browsing: Targets in private contexts may have restricted access
  • Iframe limitations: Some iframe targets may not allow external attachment

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