Understanding Ego‑Lite Snapshot Output Format and Using loc= Values

Ego‑Lite’s page.snapshot() returns an HTML string with stable @N reference markers, while page.snapshotRaw() produces a structured object containing content and refs properties, and loc= values provide resilient locators using prefixes like css:, xpath:, text:, role:, and href: that survive DOM changes and page navigations.

Ego‑Lite is a browser automation framework designed for AI agents requiring stable interaction primitives. Understanding the snapshot output format and how to leverage loc= values is essential for building scripts that withstand page reloads and DOM mutations. These mechanisms are implemented across the core driver files and provide the foundation for reliable element resolution.

Snapshot Output Format in Ego‑Lite

Ego‑Lite provides two primary methods for capturing the current state of a webpage, each serving different use cases within the automation lifecycle.

Human‑Readable HTML with @N References

The page.snapshot() method returns a string containing the page’s HTML snapshot with embedded @N reference markers. These markers provide stable numeric identifiers for DOM elements that can be referenced during the current session. According to the library’s format registry in src/format.ts (lines 402‑423), this method is optimized for debugging and visual inspection rather than programmatic parsing.

Structured Raw Output via snapshotRaw()

For programmatic access, page.snapshotRaw() returns an object with two top‑level properties:

  • content – A string containing the full HTML snapshot with embedded @N markers.
  • refs – An array of reference objects describing DOM elements addressable via their numeric IDs.

This structured format is generated in src/driver/observe.ts and declared in src/format.ts. The refs array enables precise element targeting without re‑querying the DOM, though these references are short‑lived compared to loc= locators.

Understanding loc= Values and Locator Syntax

loc= values represent the preferred mechanism for creating stable, reusable locators that survive DOM changes and page navigations. Unlike raw @N references that expire after navigation, loc= strings are resolved dynamically against the current DOM each time they are used.

When a loc= string is passed to helpers like page.click(), page.elementCenter(), or page.waitForSelector(), the element resolver (implemented in src/element-resolver.ts) parses the string, evaluates it against the DOM, and returns the corresponding element or its reference ID. This mechanism provides transient‑safe resolution: if an element is temporarily unavailable, the resolver throws an ElementResolutionError with a transient flag, enabling retry logic.

Supported Locator Prefixes

The element resolver supports five distinct locator prefixes, each targeting different DOM attributes:

  • css: (default) – Standard CSS selector syntax. Example: loc=div.article or loc=css:.nav-button
  • xpath: – XPath expressions for complex traversal. Example: loc=xpath=//button[text()="Submit"]
  • text: – Case‑sensitive visible text search. Example: loc=text=Login
  • role: – ARIA role selectors for accessibility. Example: loc=role=button
  • href: – URL‑based selection for anchor tags. Example: loc=href=/contact

If no prefix is specified, the resolver defaults to CSS selector mode.

Practical Examples of Using loc= Locators

The following examples demonstrate how to capture snapshots and use loc= values with methods exposed in src/helpers.ts:

// Capture raw snapshot for debugging structured data
const snap = await page.snapshotRaw();
console.log(snap.content);   // HTML string with @N refs
console.log(snap.refs);      // [{ id: 12, locator: 'loc=css:.button', ... }]

// Click a link using URL-based locator
await page.click('loc=href=/pricing');

// Wait for element containing specific text
await page.waitForSelector('loc=text=Welcome back');

// Get center coordinates using explicit CSS prefix
const center = await page.elementCenter('loc=css=.hero-image');
console.log(center); // { x: 345, y: 210 }

Summary

  • page.snapshot() returns human‑readable HTML with @N markers defined in src/format.ts.
  • page.snapshotRaw() provides a structured object with content (HTML string) and refs (element array) properties.
  • loc= values use prefixes (css:, xpath:, text:, role:, href:) to create stable locators that survive navigation.
  • The element resolver in src/element-resolver.ts handles dynamic resolution and throws ElementResolutionError with a transient flag for retryable failures.
  • These mechanisms are exposed to agent scripts through src/helpers.ts.

Frequently Asked Questions

What is the difference between @N references and loc= locators?

@N references are numeric IDs embedded in HTML snapshots that point to specific DOM elements at the time of capture, but they become invalid after page navigation. loc= locators are string queries that resolve dynamically each time they are used, making them resilient across multiple rounds and page changes.

How do I handle transient errors when resolving loc= values?

When an element is temporarily unavailable, the resolver in src/element-resolver.ts throws an ElementResolutionError with a transient property set to true. You should wrap your calls in retry logic that catches this specific error and re‑attempts the resolution after a brief delay.

Which source files define the snapshot helpers and locator resolution?

The method signatures are declared in src/format.ts (lines 402‑423), the raw snapshot implementation resides in src/driver/observe.ts, and the locator parsing logic is contained in src/element-resolver.ts. Public exposure to scripts occurs through src/helpers.ts.

Can I use loc= values with XPath expressions?

Yes, prefix your locator with xpath: to use XPath syntax. For example: await page.click('loc=xpath=//div[@class="modal"]//button'). This is evaluated by the element resolver alongside other locator types.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →