Skip to main content

Snapshot Functions

The snapshot module provides functions for generating accessibility tree snapshots with embedded element refs for deterministic element selection.

Core Functions

getEnhancedSnapshot()

Generate an enhanced accessibility snapshot with element refs.
import { getEnhancedSnapshot } from '@agentic-labs/browser';
import { chromium } from 'playwright-core';

const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');

const snapshot = await getEnhancedSnapshot(page, {
  interactive: true,
  cursor: true,
  maxDepth: 5,
  compact: true,
  selector: '#main-content'
});

console.log(snapshot.tree);
console.log(snapshot.refs);
page
Page
Playwright Page instance
options
SnapshotOptions
Snapshot configuration options
interactive
boolean
Only include interactive elements (buttons, links, inputs, etc.)
cursor
boolean
Include cursor-interactive elements (cursor:pointer, onclick, tabindex)
maxDepth
number
Maximum depth of tree to include (0 = root only)
compact
boolean
Remove structural elements without meaningful content
selector
string
CSS selector to scope the snapshot to a specific element
return
EnhancedSnapshot
tree
string
Accessibility tree as formatted text with refs
refs
RefMap
Map of element refs (e1, e2, etc.) to locator data
Example Output:
- heading "Example Domain" [ref=e1] [level=1]
- paragraph: This domain is for use in illustrative examples
- link "More information..." [ref=e2]
- button "Submit" [ref=e3]
- textbox "Email" [ref=e4]
# Cursor-interactive elements:
- clickable "Login" [ref=e5] [cursor:pointer]

parseRef()

Parse a ref from a command argument. Supports multiple ref formats.
import { parseRef } from '@agentic-labs/browser';

const ref1 = parseRef('@e1');      // 'e1'
const ref2 = parseRef('ref=e2');   // 'e2'
const ref3 = parseRef('e3');       // 'e3'
const ref4 = parseRef('#button');  // null (not a ref)
arg
string
Ref argument string (e.g., ‘@e1’, ‘ref=e1’, or ‘e1’)
return
string | null
Parsed ref ID (e.g., ‘e1’) or null if not a valid ref format
Supported Formats:
  • @e1 - At-prefixed ref
  • ref=e1 - Ref with equals
  • e1 - Direct ref (pattern: /^e\d+$/)

getSnapshotStats()

Get statistics about a snapshot.
import { getSnapshotStats } from '@agentic-labs/browser';

const snapshot = await getEnhancedSnapshot(page);
const stats = getSnapshotStats(snapshot.tree, snapshot.refs);

console.log(stats);
// {
//   lines: 42,
//   chars: 1234,
//   tokens: 309,
//   refs: 15,
//   interactive: 12
// }
tree
string
Snapshot tree text
refs
RefMap
Snapshot refs map
return
object
lines
number
Number of lines in tree
chars
number
Number of characters
tokens
number
Estimated token count (chars / 4)
refs
number
Total number of refs
interactive
number
Number of interactive element refs

resetRefs()

Reset the ref counter. Called automatically at the start of each snapshot.
import { resetRefs } from '@agentic-labs/browser';

resetRefs(); // Reset counter to 0

Types & Interfaces

EnhancedSnapshot

The result of getEnhancedSnapshot().
interface EnhancedSnapshot {
  tree: string;      // Accessibility tree as formatted text
  refs: RefMap;      // Map of refs to element data
}

RefMap

Map of element refs to their locator data.
interface RefMap {
  [ref: string]: {
    selector: string;  // Playwright selector (e.g., "getByRole('button', { name: 'Submit', exact: true })")
    role: string;      // ARIA role (e.g., 'button', 'link', 'textbox')
    name: string;      // Accessible name
    nth?: number;      // Index for disambiguation when multiple elements have same role+name
  };
}
Example:
{
  'e1': {
    selector: "getByRole('heading', { name: 'Example Domain', exact: true })",
    role: 'heading',
    name: 'Example Domain'
  },
  'e2': {
    selector: "getByRole('link', { name: 'More information...', exact: true })",
    role: 'link',
    name: 'More information...'
  },
  'e3': {
    selector: "getByRole('button', { name: 'Submit', exact: true })",
    role: 'button',
    name: 'Submit',
    nth: 0  // First of multiple 'Submit' buttons
  }
}

SnapshotOptions

Configuration options for getEnhancedSnapshot().
interface SnapshotOptions {
  /** Only include interactive elements (buttons, links, inputs, etc.) */
  interactive?: boolean;
  
  /** Include cursor-interactive elements (cursor:pointer, onclick, tabindex) */
  cursor?: boolean;
  
  /** Maximum depth of tree to include (0 = root only) */
  maxDepth?: number;
  
  /** Remove structural elements without meaningful content */
  compact?: boolean;
  
  /** CSS selector to scope the snapshot */
  selector?: string;
}

Interactive Roles

Elements with these ARIA roles are considered interactive and receive refs:
  • button
  • link
  • textbox
  • checkbox
  • radio
  • combobox
  • listbox
  • menuitem, menuitemcheckbox, menuitemradio
  • option
  • searchbox
  • slider
  • spinbutton
  • switch
  • tab
  • treeitem

Content Roles

Elements with these roles get refs for text extraction:
  • heading
  • cell, gridcell, columnheader, rowheader
  • listitem
  • article
  • region
  • main
  • navigation

Cursor-Interactive Elements

When cursor: true is enabled, the snapshot includes elements with:
  • cursor: pointer CSS property
  • onclick attribute or handler
  • tabindex attribute (except -1)
These elements get pseudo-roles:
  • clickable - Has cursor:pointer or onclick
  • focusable - Has tabindex
The selector for cursor-interactive elements is a CSS selector, not a role-based selector.

Usage with BrowserManager

The BrowserManager class provides a convenient wrapper:
import { BrowserManager } from '@agentic-labs/browser';

const manager = new BrowserManager();
await manager.launch();

const page = manager.getPage();
await page.goto('https://example.com');

// Get snapshot via manager (caches refs internally)
const snapshot = await manager.getSnapshot({ interactive: true });

// Click element by ref
const locator = manager.getLocatorFromRef('@e3');
if (locator) {
  await locator.click();
}

// Or use getLocator which supports both refs and selectors
await manager.getLocator('@e3').click();

Build docs developers (and LLMs) love