Browser-level operations, page navigation, lifecycle management, and target control. This covers domains that manage browser windows, page navigation, and debugging target management.
Browser-level operations and window management for controlling browser instances and sessions.
namespace Protocol.Browser {
type BrowserContextID = string;
type WindowID = integer;
type WindowState = ('normal' | 'minimized' | 'maximized' | 'fullscreen');
interface GetVersionResponse {
protocolVersion: string;
product: string;
revision: string;
userAgent: string;
jsVersion: string;
}
interface GetBrowserContextsResponse {
browserContextIds: BrowserContextID[];
}
interface CreateBrowserContextRequest {
disposeOnDetach?: boolean;
proxyServer?: string;
proxyBypassList?: string;
originsWithUniversalNetworkAccess?: string[];
}
interface CreateBrowserContextResponse {
browserContextId: BrowserContextID;
}
interface GetWindowBoundsRequest {
windowId: WindowID;
}
interface GetWindowBoundsResponse {
bounds: Bounds;
}
interface SetWindowBoundsRequest {
windowId: WindowID;
bounds: Bounds;
}
interface Bounds {
left?: integer;
top?: integer;
width?: integer;
height?: integer;
windowState?: WindowState;
}
interface GetWindowForTargetRequest {
targetId?: Target.TargetID;
}
interface GetWindowForTargetResponse {
windowId: WindowID;
bounds: Bounds;
}
}Usage Example:
import Protocol from "devtools-protocol/types/protocol";
// Get browser version information
function getBrowserInfo(): Promise<Protocol.Browser.GetVersionResponse> {
// Implementation would send Browser.getVersion command
return Promise.resolve({
protocolVersion: "1.3",
product: "Chrome/91.0.4472.124",
revision: "@abc123",
userAgent: "Mozilla/5.0...",
jsVersion: "9.1.269.38"
});
}
// Create isolated browser context
const createContextRequest: Protocol.Browser.CreateBrowserContextRequest = {
disposeOnDetach: true,
proxyServer: "http://proxy.example.com:8080"
};
// Manage window bounds
const windowBounds: Protocol.Browser.Bounds = {
left: 100,
top: 100,
width: 1200,
height: 800,
windowState: 'normal'
};Page-level operations including navigation, lifecycle management, and resource handling.
namespace Protocol.Page {
type FrameId = string;
type LoaderId = string;
type NavigationId = string;
type TransitionType = ('link' | 'typed' | 'address_bar' | 'auto_bookmark' | 'auto_subframe' | 'manual_subframe' | 'generated' | 'auto_toplevel' | 'form_submit' | 'reload' | 'keyword' | 'keyword_generated' | 'other');
type ReferrerPolicy = ('noReferrer' | 'noReferrerWhenDowngrade' | 'origin' | 'originWhenCrossOrigin' | 'sameOrigin' | 'strictOrigin' | 'strictOriginWhenCrossOrigin' | 'unsafeUrl');
interface Frame {
id: FrameId;
parentId?: string;
loaderId: LoaderId;
name?: string;
url: string;
urlFragment?: string;
domainAndRegistry: string;
securityOrigin: string;
mimeType: string;
unreachableUrl?: string;
adFrameStatus?: AdFrameStatus;
secureContextType: SecureContextType;
crossOriginIsolatedContextType: CrossOriginIsolatedContextType;
gatedAPIFeatures: GatedAPIFeatures[];
}
interface NavigateRequest {
url: string;
referrer?: string;
transitionType?: TransitionType;
frameId?: FrameId;
referrerPolicy?: ReferrerPolicy;
}
interface NavigateResponse {
frameId: FrameId;
loaderId?: LoaderId;
errorText?: string;
}
interface ReloadRequest {
ignoreCache?: boolean;
scriptToEvaluateOnLoad?: string;
loaderId?: LoaderId;
}
interface GetResourceTreeResponse {
frameTree: FrameResourceTree;
}
interface FrameResourceTree {
frame: Frame;
childFrames?: FrameResourceTree[];
resources: FrameResource[];
}
interface FrameResource {
url: string;
type: Network.ResourceType;
mimeType: string;
lastModified?: Network.TimeSinceEpoch;
contentSize?: integer;
failed?: boolean;
canceled?: boolean;
}
interface DomContentEventFiredEvent {
timestamp: Network.MonotonicTime;
}
interface LoadEventFiredEvent {
timestamp: Network.MonotonicTime;
}
interface FrameNavigatedEvent {
frame: Frame;
type: NavigationType;
}
interface FrameStartedLoadingEvent {
frameId: FrameId;
}
interface FrameStoppedLoadingEvent {
frameId: FrameId;
}
interface LifecycleEvent {
frameId: FrameId;
loaderId: LoaderId;
name: string;
timestamp: Network.MonotonicTime;
}
}Usage Example:
import Protocol from "devtools-protocol/types/protocol";
// Navigate to a URL
const navigateRequest: Protocol.Page.NavigateRequest = {
url: "https://example.com",
referrerPolicy: 'origin',
transitionType: 'typed'
};
// Handle page lifecycle events
function onDomContentLoaded(event: Protocol.Page.DomContentEventFiredEvent) {
console.log("DOM content loaded at:", event.timestamp);
}
function onPageLoaded(event: Protocol.Page.LoadEventFiredEvent) {
console.log("Page fully loaded at:", event.timestamp);
}
function onFrameNavigated(event: Protocol.Page.FrameNavigatedEvent) {
console.log(`Frame navigated to: ${event.frame.url}`);
}
// Get page resource tree
function analyzePageResources(resourceTree: Protocol.Page.FrameResourceTree) {
console.log(`Main frame: ${resourceTree.frame.url}`);
console.log(`Resources: ${resourceTree.resources.length}`);
resourceTree.resources.forEach(resource => {
console.log(`- ${resource.url} (${resource.type}, ${resource.mimeType})`);
});
if (resourceTree.childFrames) {
resourceTree.childFrames.forEach(childFrame => {
analyzePageResources(childFrame);
});
}
}Debug target management and discovery for controlling multiple debugging contexts.
namespace Protocol.Target {
type TargetID = string;
type SessionID = string;
type BrowserContextID = string;
interface TargetInfo {
targetId: TargetID;
type: string;
title: string;
url: string;
attached: boolean;
openerId?: TargetID;
canAccessOpener: boolean;
openerFrameId?: Page.FrameId;
browserContextId?: BrowserContextID;
subtype?: string;
}
interface CreateTargetRequest {
url: string;
width?: integer;
height?: integer;
browserContextId?: BrowserContextID;
enableBeginFrameControl?: boolean;
newWindow?: boolean;
background?: boolean;
forTab?: boolean;
}
interface CreateTargetResponse {
targetId: TargetID;
}
interface AttachToTargetRequest {
targetId: TargetID;
flatten?: boolean;
}
interface AttachToTargetResponse {
sessionId: SessionID;
}
interface DetachFromTargetRequest {
sessionId?: SessionID;
targetId?: TargetID;
}
interface GetTargetsResponse {
targetInfos: TargetInfo[];
}
interface CreateBrowserContextRequest {
disposeOnDetach?: boolean;
proxyServer?: string;
proxyBypassList?: string;
originsWithUniversalNetworkAccess?: string[];
}
interface CreateBrowserContextResponse {
browserContextId: BrowserContextID;
}
interface TargetCreatedEvent {
targetInfo: TargetInfo;
}
interface TargetDestroyedEvent {
targetId: TargetID;
}
interface TargetCrashedEvent {
targetId: TargetID;
status: string;
errorCode: integer;
}
interface TargetInfoChangedEvent {
targetInfo: TargetInfo;
}
interface AttachedToTargetEvent {
sessionId: SessionID;
targetInfo: TargetInfo;
waitingForDebugger: boolean;
}
interface DetachedFromTargetEvent {
sessionId: SessionID;
targetId?: TargetID;
}
}Usage Example:
import Protocol from "devtools-protocol/types/protocol";
// Create a new target (tab/window)
const createTargetRequest: Protocol.Target.CreateTargetRequest = {
url: "about:blank",
width: 1024,
height: 768,
newWindow: false,
background: false
};
// Attach to a target for debugging
async function attachToTarget(targetId: string): Promise<string> {
const attachRequest: Protocol.Target.AttachToTargetRequest = {
targetId,
flatten: true
};
// Would return session ID for further communication
return "session_id_123";
}
// Handle target lifecycle events
function onTargetCreated(event: Protocol.Target.TargetCreatedEvent) {
const { targetInfo } = event;
console.log(`New target created: ${targetInfo.title} (${targetInfo.url})`);
}
function onTargetDestroyed(event: Protocol.Target.TargetDestroyedEvent) {
console.log(`Target destroyed: ${event.targetId}`);
}
function onTargetCrashed(event: Protocol.Target.TargetCrashedEvent) {
console.error(`Target crashed: ${event.targetId}, status: ${event.status}`);
}
// Manage multiple targets
async function listAllTargets(): Promise<Protocol.Target.TargetInfo[]> {
// Implementation would call Target.getTargets
return [
{
targetId: "target_1",
type: "page",
title: "Example Page",
url: "https://example.com",
attached: true,
canAccessOpener: false
}
];
}Inspector connection and session management for controlling debugging sessions.
namespace Protocol.Inspector {
interface DetachedEvent {
reason: string;
}
interface TargetCrashedEvent {}
interface TargetReloadedAfterCrashEvent {}
}import Protocol from "devtools-protocol/types/protocol";
class BrowserSessionManager {
private contexts: Map<string, Protocol.Browser.BrowserContextID> = new Map();
private targets: Map<string, Protocol.Target.TargetID> = new Map();
async createIsolatedContext(name: string): Promise<Protocol.Browser.BrowserContextID> {
const request: Protocol.Browser.CreateBrowserContextRequest = {
disposeOnDetach: true
};
// Implementation would send Browser.createBrowserContext
const response = { browserContextId: `context_${name}` };
this.contexts.set(name, response.browserContextId);
return response.browserContextId;
}
async createTabInContext(contextId: Protocol.Browser.BrowserContextID, url: string): Promise<Protocol.Target.TargetID> {
const request: Protocol.Target.CreateTargetRequest = {
url,
browserContextId: contextId,
newWindow: false,
background: false
};
// Implementation would send Target.createTarget
const response = { targetId: `target_${Date.now()}` };
this.targets.set(url, response.targetId);
return response.targetId;
}
async navigateTarget(targetId: Protocol.Target.TargetID, url: string): Promise<void> {
const request: Protocol.Page.NavigateRequest = {
url
};
// Implementation would send Page.navigate to the target
}
}import Protocol from "devtools-protocol/types/protocol";
import { ProtocolMapping } from "devtools-protocol/types/protocol-mapping";
class PageManager {
private frameTree: Protocol.Page.FrameResourceTree | null = null;
setupPageListeners() {
// Handle navigation events
this.onFrameNavigated = (event: ProtocolMapping.Events['Page.frameNavigated'][0]) => {
console.log(`Navigation: ${event.frame.url}`);
this.updateFrameTree();
};
// Handle lifecycle events
this.onLifecycleEvent = (event: ProtocolMapping.Events['Page.lifecycleEvent'][0]) => {
console.log(`Lifecycle: ${event.name} for frame ${event.frameId}`);
};
// Handle load events
this.onLoadEventFired = (event: ProtocolMapping.Events['Page.loadEventFired'][0]) => {
console.log(`Page loaded at: ${event.timestamp}`);
};
}
async reloadPage(ignoreCache: boolean = false): Promise<void> {
const request: Protocol.Page.ReloadRequest = {
ignoreCache,
scriptToEvaluateOnLoad: "console.log('Page reloaded');"
};
// Implementation would send Page.reload
}
private async updateFrameTree(): Promise<void> {
// Implementation would call Page.getResourceTree
this.frameTree = {
frame: {
id: "main_frame",
loaderId: "loader_123",
url: "https://example.com",
domainAndRegistry: "example.com",
securityOrigin: "https://example.com",
mimeType: "text/html",
secureContextType: "Secure",
crossOriginIsolatedContextType: "NotIsolated",
gatedAPIFeatures: []
},
resources: []
};
}
}import Protocol from "devtools-protocol/types/protocol";
class MultiTargetDebugger {
private sessions: Map<Protocol.Target.SessionID, Protocol.Target.TargetInfo> = new Map();
async attachToAllTargets(): Promise<void> {
// Get all available targets
const targets = await this.getAllTargets();
for (const target of targets) {
if (target.type === 'page' && !target.attached) {
const sessionId = await this.attachToTarget(target.targetId);
this.sessions.set(sessionId, target);
// Enable debugging for this target
await this.enableDebuggingForSession(sessionId);
}
}
}
private async getAllTargets(): Promise<Protocol.Target.TargetInfo[]> {
// Implementation would call Target.getTargets
return [];
}
private async attachToTarget(targetId: Protocol.Target.TargetID): Promise<Protocol.Target.SessionID> {
const request: Protocol.Target.AttachToTargetRequest = {
targetId,
flatten: true
};
// Implementation would send Target.attachToTarget
return `session_${Date.now()}`;
}
private async enableDebuggingForSession(sessionId: Protocol.Target.SessionID): Promise<void> {
// Enable domains for this session
// Implementation would send commands to the specific session
}
handleTargetEvents() {
this.onTargetCreated = (event: Protocol.Target.TargetCreatedEvent) => {
console.log(`New target: ${event.targetInfo.title}`);
// Automatically attach to new targets if needed
};
this.onTargetDestroyed = (event: Protocol.Target.TargetDestroyedEvent) => {
console.log(`Target destroyed: ${event.targetId}`);
// Clean up session if it exists
for (const [sessionId, targetInfo] of this.sessions.entries()) {
if (targetInfo.targetId === event.targetId) {
this.sessions.delete(sessionId);
break;
}
}
};
}
}