How to Use the Page Facade API in ego-lite: A Playwright-Style Interface for Browser Automation
The Page Facade API in ego-lite provides a Playwright-style interface that wraps Chrome DevTools Protocol (CDP) commands, exposing high-level methods like page.goto(), page.evaluate(), and page.screenshot() through the ego helper context with automatic Promise-based async handling.
The Page Facade API in ego-lite offers agent developers a concise, high-level abstraction for browser automation without directly managing CDP message construction. Built on top of the Chrome DevTools Protocol transport, this facade is constructed in src/helpers.ts and injected into scripts via helperContext(), making the page object automatically available under the top-level ego helpers when running inside the ego-lite harness.
Architecture and Initialization
The facade is created by the createPageFacade() function defined in src/helpers.ts. When a script executes within the ego-lite harness, this object is registered in the helper context, enabling immediate access to browser control methods. Unlike raw CDP implementations, the facade handles reference management and message serialization internally, presenting a clean surface that mirrors Playwright's API design.
Under the hood, the implementation spans several key modules:
src/driver/nav.ts– Backs navigation primitives includingpage.goto()and URL-related wait conditions.src/driver/locator.ts– Implements selector resolution forpage.locator()and convenience methods likegetByText().src/cdp-eval.ts– Powerspage.evaluate()throughcdp()andjs()helper functions.src/browser-runtime.ts– Manages the CDP transport layer and event buffering required by all facade operations.
Core API Methods
Navigation and URL Management
Use page.goto(url) to load destinations and await page.url() to retrieve the current address. Because the facade operates over the CDP transport provided by src/browser-runtime.ts, the URL method returns a Promise and must be awaited.
await page.goto('https://example.com')
const current = await page.url()
For redirect synchronization, page.waitForURL(pattern) supports glob patterns to match against the final navigation target:
await page.waitForURL('**/dashboard', { timeout: 15000 })
Element Locators and Interaction
The facade provides page.locator(selector) for raw CSS selectors and semantic helpers: getByText(), getByLabel(), getByPlaceholder(), and getByTestId(). These return locators supporting click and type operations, implemented atop the resolution logic in src/driver/locator.ts.
Input simulation is available through page.keyboard and page.mouse:
await page.getByText('Accept Terms').click()
await page.getByLabel('Email').type('user@example.com')
await page.keyboard.press('Enter')
await page.mouse.click(100, 200)
Page Evaluation
Execute JavaScript in the browser context using page.evaluate(). The expression runs in the page's execution context with full access to the DOM, backed by the evaluation infrastructure in src/cdp-eval.ts.
const title = await page.evaluate(() => document.title)
const data = await page.evaluate(() => window.myAppState)
Visual Capture and Recording
Capture static PNGs with page.screenshot() or record dynamic sessions via the screencast sub-object:
await page.screenshot({ path: 'state.png' })
await page.screencast.start({
path: 'session.webm',
size: { width: 1280, height: 720 },
quality: 80
})
await page.waitForLoadState('networkidle')
await page.screencast.stop()
Synchronization and Timeouts
Control default waiting behavior with page.setDefaultTimeout(ms). Fine-grained synchronization methods include waitForLoadState(), waitForRequest(), waitForResponse(), and waitForEvent() for download monitoring.
page.setDefaultTimeout(10_000)
await page.waitForLoadState('networkidle')
const download = await page.waitForEvent('download')
Complete Usage Example
This example demonstrates navigation, form interaction, and visual capture using the Page Facade API:
// Navigate and extract metadata
await page.goto('https://example.com')
const title = await page.evaluate(() => document.title)
console.log('Page title:', title)
// Fill and submit a form using semantic locators
await page.getByLabel('Email').type('user@example.com')
await page.getByLabel('Password').type('secret')
await page.keyboard.press('Enter')
// Wait for post-login navigation and capture result
await page.waitForURL('**/dashboard', { timeout: 15000 })
await page.screenshot({ path: 'final.png' })
// Record a short screencast of the session
await page.screencast.start({ path: 'session.webm', size: { width: 1280, height: 720 }, quality: 80 })
await page.waitForLoadState('networkidle')
await page.screencast.stop()
Summary
- The Page Facade API in ego-lite wraps CDP complexity in a Playwright-compatible interface defined in
src/helpers.tsviacreatePageFacade(). - Access the
pageobject through theegohelper context automatically provided to scripts running in the ego-lite harness. - All methods are asynchronous and return Promises, requiring
awaitfor result retrieval due to the underlying CDP transport insrc/browser-runtime.ts. - The architecture delegates to specialized modules:
src/driver/nav.tsfor navigation,src/driver/locator.tsfor element selection, andsrc/cdp-eval.tsfor script execution. - Built-in support for screenshots, screencasts, downloads, and network synchronization eliminates boilerplate CDP message handling.
Frequently Asked Questions
How do I access the page object in an ego-lite script?
The page object is automatically available through the top-level ego helpers when your script runs inside the ego-lite harness. It is constructed by createPageFacade() in src/helpers.ts and injected via helperContext(), requiring no manual initialization or import statements.
Does the Page Facade API support parallel browser contexts?
While the facade itself manages a single page instance per script execution, the underlying src/browser-runtime.ts handles CDP transport multiplexing. For parallel operations, spawn separate script executions, as each receives its own isolated page facade instance bound to its CDP session.
Why must I await page.url() when other properties might be synchronous?
All facade methods abstract asynchronous CDP operations. The page.url() method queries the browser's current state through the protocol transport, making it inherently asynchronous and Promise-based for consistency with the rest of the API surface and to ensure accurate state retrieval from the remote browser.
How does page.evaluate() differ from direct CDP evaluate calls?
page.evaluate() wraps the low-level CDP evaluation mechanisms found in src/cdp-eval.ts, handling script context isolation, exception serialization, and return value marshaling automatically. This provides safer execution compared to raw Runtime.evaluate CDP commands while maintaining full access to the page's JavaScript context.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →