# What Is the Playwright-Style Facade Surface in ego-browser?

> Discover the Playwright-style facade surface in ego-browser. This familiar API simplifies browser automation by wrapping CDP calls, letting you write Playwright-like scripts effortlessly.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: deep-dive
- Published: 2026-08-29

---

**The Playwright-style facade surface in ego-browser is a high-level, familiar API that wraps Chrome DevTools Protocol (CDP) calls, letting agent scripts write automation code that looks and behaves like standard Playwright without directly managing low-level browser internals.**

The `ego-browser` package—part of the closed-source ego-lite runtime—exposes this facade to bridge the gap between developer ergonomics and protocol-level control. Built in `helperContext()` within [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), the facade translates Playwright-style method signatures into CDP messages, handles auto-retry logic, and returns strongly-typed promises.

## How the Facade Is Constructed

The facade surface is instantiated through **`helperContext()`** in [[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts#L810-L819). This function assembles multiple facade objects that each mirror a Playwright counterpart, providing a cohesive automation environment for agent scripts.

Each facade is a thin, typed wrapper around the internal CDP driver found in [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts) and the `driver/*` modules. They abstract away connection management, message serialization, and response handling.

## Core Facade Objects

The Playwright-style facade surface comprises six primary objects:

### `page` — Page Automation

Mirrors **Playwright's `Page`** with auto-waiting, asynchronous methods for navigation and interaction:

- `url()`, `goto()`
- `locator()`, `getByText()`, `getByLabel()`
- `setDefaultTimeout()`
- `waitForEvent()`, `waitForLoadState()`, `waitForURL()`, `waitForRequest()`, `waitForResponse()`
- `evaluate()`
- `screenshot()`, `screencast.start()` / `screencast.stop()`
- `keyboard.press()`, `keyboard.type()`
- `mouse.click()`

### `locator` — Element Targeting

Mirrors **Playwright's `Locator`** for strict, retry-enabled element selection:

- `locator()`, `getByRole()`
- `first()`, `nth()` — chaining for multiple matches
- `click()`, `hover()`, `dragTo()`, `scrollIntoViewIfNeeded()`
- `fill()`, `clear()`, `press()`
- `check()`, `selectOption()`
- `textContent()`, `innerText()`, `isVisible()`, `getAttribute()`
- `screenshot()`, `evaluate()`, `evaluateAll()`, `waitFor()`

Implementation resides in [[`src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/locator.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/locator.ts).

### `browser` — Tab Management

Mirrors **Playwright's `Browser`** for multi-tab orchestration:

- `listTabs()`, `currentTab()`, `switchTab()`
- `openOrReuseTab()`, `closeTab()`

### `taskSpaces` — Task-Space Handling

Provides Playwright-style APIs for managing agent task lifecycles:

- `useOrCreate()`, `claim()`, `switch()`
- `complete()`, hand-off utilities, and agent control wait conditions

### `site` — Site-Skill Integration

Exposes learned site skills and context:

- Access site-specific automation patterns
- Run site-trained tools
- Fetch learning context for adaptive behavior

### `fetch` — Network Requests

Dual-environment network facade:

- `fetch.server()` — Node-side HTTP requests
- `fetch.browser()` — in-page `fetch` execution via `page.evaluate()` style injection

## Practical Code Examples

### Basic Navigation and Element Interaction

```typescript
await page.goto('https://example.com');
const loginBtn = page.locator('button[data-test="login"]');
await loginBtn.click();
await page.waitForURL(/dashboard/);

```

### Keyboard and Mouse Input

```typescript
await page.keyboard.type('hello world');
await page.mouse.click(400, 300);   // coordinates are (x, y)

```

### Event-Driven Download Handling

```typescript
const [download] = await Promise.all([
  page.waitForEvent('download'),
  loginBtn.click(),
]);
await download.saveAs('login-report.pdf');

```

### Task Space Lifecycle

```typescript
const ts = await taskSpaces.useOrCreate('my-task');
await ts.claim('my-task');
await ts.switch('my-task');
// …automation actions execute here…
await ts.complete('my-task', { keep: true });

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) | Defines `helperContext()` and facade metadata (`FACADE_HELP`) |
| [`src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/locator.ts) | Implements `Locator`-equivalent selection and interaction |
| [`src/driver/waits.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/waits.ts) | Provides `waitFor*` utilities for requests, responses, and events |
| [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts) | Core CDP transport layer that facades delegate to |
| [`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts) | Executes `page.evaluate()`-style JavaScript in page context |

## Summary

- The **Playwright-style facade surface** in ego-browser wraps CDP complexity in a familiar, high-level API
- Six facade objects (`page`, `locator`, `browser`, `taskSpaces`, `site`, `fetch`) provide comprehensive automation coverage
- All methods are **asynchronous and auto-waiting**, matching Playwright's behavioral contract
- Implementation spans [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), [`src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/locator.ts), [`src/driver/waits.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/waits.ts), and supporting runtime files
- Agents write standard-looking Playwright code while the runtime handles CDP translation, retry logic, and type safety

## Frequently Asked Questions

### What problem does the Playwright-style facade solve in ego-browser?

The facade eliminates the need for agent scripts to manage raw Chrome DevTools Protocol messages. According to the citrolabs/ego-lite source code, it provides ergonomic, retry-enabled, typed wrappers that let developers use well-documented Playwright patterns instead of learning CDP internals.

### How does `locator()` differ from standard Playwright usage?

The `ego-browser` locator facade in [`src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/locator.ts) implements the same strictness and auto-waiting semantics as Playwright's `Locator`, but delegates to CDP-based element resolution. Methods like `dragTo()`, `scrollIntoViewIfNeeded()`, and `evaluateAll()` are available with identical signatures.

### Can I use standard Playwright documentation with ego-browser?

Yes—method names, parameter patterns, and behavioral semantics intentionally mirror Playwright. However, the underlying implementation in [`browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/browser-runtime.ts) and [`cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/cdp-eval.ts) uses CDP, so some Playwright-specific configuration options may not translate directly.

### Where are wait conditions implemented in the facade?

Playwright-style wait utilities including `waitForURL()`, `waitForRequest()`, `waitForResponse()`, and `waitForEvent()` are defined in [`src/driver/waits.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/waits.ts). These wrap CDP event listeners and polling logic to match Playwright's timeout and retry behavior.