# Ego-Browser Page Facade API: A Playwright-Compatible Interface for Browser Automation

> Explore the ego-browser page facade API, a Playwright-compatible interface. It simplifies browser automation by wrapping CDP commands with unique ego-lite features for efficient task management and site interaction.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: api-reference
- Published: 2026-08-16

---

**The ego-browser page facade API provides a Playwright-compatible scripting interface that wraps Chrome DevTools Protocol (CDP) commands in familiar methods like `goto`, `locator`, and `screenshot`, while integrating unique ego-lite runtime features such as task-space management and learned site tools.**

The **ego-browser** package within the [citrolabs/ego-lite](https://github.com/citrolabs/ego-lite) repository delivers a high-level browser automation API designed to mirror Playwright's ergonomics. This facade abstracts the underlying CDP transport layer implemented in [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts), exposing a global `page` object that supports standard navigation, element interaction, and screenshot capabilities. Unlike standard Playwright, the facade incorporates ego-lite-specific concepts including task-space ownership and extensible site-specific tooling.

## Core Architecture and Implementation

The page facade is constructed by the `createPageFacade()` function defined in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (lines 684-824). This factory aggregates helper methods and binds them to the global `page` object exposed to automation scripts.

### Factory Method and State Binding

In [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), `createPageFacade()` initializes the API surface by wrapping CDP commands routed through [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts). The factory creates a proxy object that implements Playwright-style method signatures while maintaining connection to the ego-lite binary's runtime state stored in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts).

```typescript
// The facade is created internally and exposed as the global 'page' object
await page.goto('https://example.com', { timeout: 15000 });
console.log(await page.title());  // Returns the document title
console.log(await page.url());    // Returns the current href

```

### Runtime State Management

The facade relies on a singleton state manager defined in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts). This module stores the current CDP session, task-space ownership flags, and default timeout values. When scripts invoke `page.setDefaultTimeout()`, the facade updates this shared state, affecting subsequent operations across the session.

## API Surface and Playwright Parity

The ego-browser page facade API implements a comprehensive subset of Playwright's `Page` class, documented in [`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts) (lines 17-250). This includes navigation, element location, waiting strategies, and input simulation.

### Navigation and Page Information

The facade provides standard navigation methods that accept Playwright-compatible options objects:

- **`goto(url, options)`**: Navigates to URL with timeout and wait-until settings
- **`reload(options)`**: Refreshes the current page
- **`url()`**: Returns the current location href
- **`title()`**: Returns the document title
- **`info()`**: Returns viewport dimensions, scroll position, and page metrics

```javascript
await page.goto('https://example.com', { timeout: 15000 });
console.log(await page.url());   // Current URL string
console.log(await page.info());  // Viewport, scroll, size metadata

```

### Strict Locator API

The `locator()` method in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) returns strict, auto-waiting locator objects that mirror Playwright's Locator API. These locators support method chaining for filtering and traversal:

- **Filtering**: `locator.filter()`, `locator.first`, `locator.nth(index)`, `locator.last`
- **Actions**: `click()`, `fill()`, `press()`, `hover()`, `waitFor()`
- **Semantic selectors**: `getByRole()`, `getByText()`, `getByLabel()`, `getByPlaceholder()`, `getByAltText()`, `getByTitle()`, `getByTestId()`

```javascript
// Strict locator with auto-waiting behavior
await page.locator('button[type=submit]').click();

// Semantic selectors
await page.getByRole('button', { name: 'Cancel' }).click();
await page.getByText('Welcome', { exact: true }).waitFor({ state: 'visible' });

```

### Input and Screenshot Methods

The facade exposes Playwright-compatible input devices and media capture:

- **Keyboard**: `page.keyboard.type()`, `page.keyboard.press()`
- **Mouse**: `page.mouse.click()` with coordinate support
- **Screenshots**: `page.screenshot({ path: 'capture.png' })`
- **Screencasting**: `page.screencast.start()`, `page.screencast.stop()`

```javascript
await page.keyboard.type('Hello world');
await page.keyboard.press('Enter');
await page.mouse.click(200, 150);  // Direct coordinates fallback

await page.screenshot({ path: 'screenshot.png' });
await page.screencast.start({ path: 'record.webm', size: { width: 1280, height: 720 } });
await page.screencast.stop();

```

## Key Differences from Playwright

While the API surfaces are compatible, the ego-browser page facade diverges from Playwright in runtime architecture, error handling, and extensibility.

### Task-Space Integration

Unlike Playwright, the ego-browser facade is aware of **task spaces** (agent-owned versus user-owned contexts) defined in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) and [`src/env.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/env.ts). Methods like `completeTaskSpace()` utilize the facade to manage browser tab lifecycle, enabling programmatic handoff between automation agents and user control.

```javascript
// Close the task space and associated browser tab
await completeTaskSpace('my-space', { keep: false });

```

### Error Handling and Retry Semantics

The facade wraps resolution failures in `ElementResolutionError` instances that carry `transient` or `permanent` flags. This classification, implemented in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts), enables intelligent retry logic at the driver layer ([`src/driver/element-ops.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/element-ops.ts)), distinguishing between network timeouts (retryable) and DOM structural failures (permanent).

### Extensible Site Tools

The facade supports learned, site-specific automation via `runSiteTool()` and `loadSiteContext()` (referenced in [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) lines 494-514). These methods allow the runtime to execute pre-trained automation sequences on the current page, extending beyond Playwright's standard scripting capabilities.

```javascript
// Invoke a learned site-specific automation routine
await page.runSiteTool('checkout-flow', { items: ['item-123'] });

```

## Summary

The ego-browser page facade API bridges Playwright's developer experience with the ego-lite runtime's specialized browser automation infrastructure:

- **Factory-based instantiation** via `createPageFacade()` in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) creates the global `page` object
- **Playwright method parity** including `goto`, `locator`, `getByRole`, and `screenshot` with matching signatures
- **CDP-backed transport** managed through [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts) rather than Playwright's internal drivers
- **Task-space awareness** enabling agent/user context switching not present in standard Playwright
- **Strict locator model** with auto-waiting implemented in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts)
- **Extended error taxonomy** using `ElementResolutionError` with transient/permanent classifications
- **Site-specific extensibility** through `runSiteTool()` for learned automation patterns

## Frequently Asked Questions

### How does the ego-browser page facade API differ from Playwright's Page class?

The **ego-browser page facade API** mirrors Playwright's method signatures but operates on a custom CDP transport layer specific to the ego-lite runtime. While Playwright manages browser contexts internally through its own driver architecture, the facade relies on [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts) for CDP communication and integrates with ego-lite's task-space management system. The facade also extends Playwright's capabilities with site-specific tool execution (`runSiteTool`) and specialized error handling through `ElementResolutionError` classifications.

### Where is the page facade created in the ego-browser source code?

The facade is instantiated by the `createPageFacade()` function located in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (lines 684-824). This factory method aggregates navigation, locator, and input helper methods, binding them to the global `page` object exposed to automation scripts. The function interfaces with the singleton state manager in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) to maintain session context and timeout configurations.

### Does the ego-browser locator API support the same chaining methods as Playwright?

Yes, the locator implementation in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) supports Playwright-compatible chaining including `first`, `last`, `nth(index)`, and `filter()` methods. Locators returned by `page.locator()` or semantic selectors like `getByText()` are strict and auto-waiting, automatically polling for element stability before executing actions such as `click()` or `fill()`. This behavior matches Playwright's Locator API while adding ego-specific error classification for retry logic.

### Can I use standard Playwright scripts with the ego-browser page facade?

Most standard Playwright patterns translate directly to the ego-browser page facade due to intentional API compatibility. Scripts using `page.goto()`, `page.locator()`, keyboard simulation, and screenshot methods require minimal or no modification. However, Playwright-specific features like browser context management, route interception, and custom fixture patterns are handled differently in ego-lite, requiring migration to the task-space model and CDP-based runtime architecture documented in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) and [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts).