Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Microsoft Playwright ChannelOwner

From Leeroopedia
Knowledge Sources
Domains Browser Automation, Client-Server Architecture
Last Updated 2026-02-12 00:00 GMT

Overview

Concrete tool for serving as the base class for all client-side Playwright objects that communicate with the server over protocol channels, provided by the Playwright library.

Description

ChannelOwner is the abstract base class for every client-side Playwright object (Page, BrowserContext, Frame, ElementHandle, etc.). It extends EventEmitter and manages the bidirectional communication channel between client and server. Key responsibilities include:

  • Channel proxy creation: Creates a Proxy-based channel object that intercepts method calls, validates parameters through protocol validators, and routes them through the connection's sendMessageToServer().
  • Object tree management: Maintains a parent-child tree of ChannelOwner objects via _objects map, with methods for adoption (_adopt) and disposal (_dispose).
  • Subscription management: Overrides on, off, addListener, removeListener, and prependListener to automatically send subscription updates to the server when listeners are added or removed.
  • API call wrapping: The _wrapApiCall() method provides instrumentation, stack trace capture, logging, and error enrichment for all API calls.
  • Serialization: Custom toJSON() for safe Jest/debugging output.

An ApiZone type tracks the current API call context including name, stack frames, internal flag, and error state.

Usage

ChannelOwner is not used directly by end users. It is the foundational base class that all Playwright client objects inherit from. Understanding it is essential for comprehending how the Playwright client-server protocol works.

Code Reference

Source Location

Signature

export abstract class ChannelOwner<T extends channels.Channel = channels.Channel> extends EventEmitter {
  readonly _connection: Connection;
  readonly _type: string;
  readonly _guid: string;
  readonly _channel: T;
  readonly _initializer: channels.InitializerTraits<T>;
  _logger: Logger | undefined;
  readonly _instrumentation: ClientInstrumentation;
  _wasCollected: boolean;

  constructor(parent: ChannelOwner | Connection, type: string, guid: string, initializer: channels.InitializerTraits<T>);

  _setEventToSubscriptionMapping(mapping: Map<string, string>): void;
  on(event: string | symbol, listener: Listener): this;
  addListener(event: string | symbol, listener: Listener): this;
  prependListener(event: string | symbol, listener: Listener): this;
  off(event: string | symbol, listener: Listener): this;
  removeListener(event: string | symbol, listener: Listener): this;
  _adopt(child: ChannelOwner<any>): void;
  _dispose(reason: 'gc' | undefined): void;
  _debugScopeState(): any;
  async _wrapApiCall<R>(func: (apiZone: ApiZone) => Promise<R>, options?: { internal?: boolean; title?: string }): Promise<R>;
}

Import

import { ChannelOwner } from 'playwright-core/src/client/channelOwner';

I/O Contract

Inputs

Name Type Required Description
parent Connection Yes The parent object or connection instance
type string Yes The protocol type name (e.g., 'Page', 'Frame')
guid string Yes The unique identifier for this object in the protocol
initializer channels.InitializerTraits<T> Yes The initialization data from the server

Outputs

Name Type Description
_channel T The Proxy-based channel for sending protocol messages to the server
_wrapApiCall() Promise<R> Wraps function execution with instrumentation, logging, and error handling

Usage Examples

// ChannelOwner is used as a base class, not directly:
export class Page extends ChannelOwner<channels.PageChannel> implements api.Page {
  constructor(parent: ChannelOwner, type: string, guid: string, initializer: channels.PageInitializer) {
    super(parent, type, guid, initializer);
    // Page-specific initialization...
  }

  async goto(url: string): Promise<Response | null> {
    return await this._wrapApiCall(async () => {
      const result = await this._channel.goto({ url });
      return Response.fromNullable(result.response);
    });
  }
}

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment