Skip to main content

Documentation Index

Fetch the complete documentation index at: https://libretto.sh/docs/llms.txt

Use this file to discover all available pages before exploring further.

Execute Playwright TypeScript in a persistent REPL for an open browser page.
The exec command runs TypeScript Playwright code against a live browser session. Use it to validate selectors, inspect page data, prototype individual steps, and experiment with interactions before encoding them in a workflow file. exec evaluates code in a persistent REPL scoped to the browser session. Values come from expressions, top-level await is supported, and declarations remain available to later exec calls in the same session.
npx libretto exec --session debug-example "await page.url()"

Usage

Pass the code as a quoted string argument:
npx libretto exec --session debug-example "await page.url()"
npx libretto exec --session debug-example "await page.locator('button').count()"
npx libretto exec --session debug-example "await page.locator('button:has-text(\"Continue\")').click()"

Available globals

Inside the code you pass to exec, these variables are available without any imports:
GlobalTypeDescription
pagePageThe active Playwright page
frameFrameThe active page’s main frame
contextBrowserContextThe browser context for the session
browserBrowserThe browser instance
fetchtypeof fetchThe global fetch function
Buffertypeof BufferNode.js Buffer
consoleConsoleStandard console (log, warn, error)
setTimeoutfunctionSchedule a callback after a delay
setIntervalfunctionSchedule a repeating callback
clearTimeoutfunctionCancel a scheduled setTimeout
clearIntervalfunctionCancel a scheduled setInterval
URLtypeof URLThe WHATWG URL constructor

Persistent REPL

Each browser session has a persistent exec REPL. Define helper functions once, then reuse them in later calls:
cat <<'EOF' | npx libretto exec - --session debug-example
async function textOf(selector: string) {
  return await page.locator(selector).textContent();
}
EOF

npx libretto exec --session debug-example "await textOf('h1')"
The page and frame globals are refreshed for each call, including calls that use --page <page-id>.

Flags

code
string
required
The Playwright TypeScript code to execute, passed as the first positional argument. Pass - to read from stdin.
--session
string
required
The session to execute against.
--page
string
Target a specific page ID within the session. Use npx libretto pages --session <name> to list page IDs when a popup or new tab is open.
--visualize
boolean
Enable ghost cursor and highlight visualization. Shows a visible cursor trace and element highlights as Playwright interacts with the page.

Return values

If the code evaluates to a value, exec prints it to stdout:
  • Strings are printed as-is.
  • All other values are printed as pretty-printed JSON.
  • If the code evaluates to undefined, exec prints Executed successfully.
npx libretto exec --session debug-example "await page.title()"
# My Page Title

npx libretto exec --session debug-example "await page.locator('li').count()"
# 12

Rules

Let failures throw. Do not hide exec failures with try/catch or .catch(). Swallowed errors make debugging harder. Surface them so you can see exactly what failed.
Do not run multiple exec commands in parallel. Each exec call drives the same browser page. Running them concurrently causes race conditions.
  • Use exec for focused inspection and short-lived interaction experiments.
  • Use exec - (stdin) for complex multi-line scripts.
  • Validate a selector with exec before encoding it in a workflow file.
  • Use exec to prototype a single step, then move the working code into your .ts workflow file.
  • Do not use top-level return; write the expression you want to inspect.

Examples

# Print the current URL
npx libretto exec --session debug-example "await page.url()"

# Count how many buttons are on the page
npx libretto exec --session debug-example "await page.locator('button').count()"

# Click a button
npx libretto exec --session debug-example "await page.locator('button:has-text(\"Continue\")').click()"

# Read a value from an input field
npx libretto exec --session debug-example "await page.locator('input[name=\"email\"]').inputValue()"

# Run against a specific page in a session
npx libretto exec --session debug-example --page <page-id> "await page.url()"

# Pipe from stdin (multi-line, named session)
echo "await page.url()" | npx libretto exec - --session debug-example

snapshot

Use snapshot to identify selectors before running exec.

run & resume

Move validated exec code into a workflow file and run it end to end.