Skip to content

interact() — Control the Browser

The interact tool gives the AI control over the browser — navigate, click, type, read elements, run JavaScript, manage state, and display narration. Requires AI Web Pilot to be enabled in the extension popup.

interact({action: "navigate", url: "https://example.com"})
interact({action: "click", selector: "text=Submit"})
interact({action: "type", selector: "label=Email", text: "user@example.com"})
interact({action: "list_interactive"})
interact({action: "screenshot"}) // use observe({what: "screenshot"}) instead
interact({action: "subtitle", text: "Welcome to the demo"})
interact({action: "execute_js", script: "document.title"})
interact({action: "save_state", snapshot_name: "logged-in"})

These parameters can be added to any action:

ParameterTypeDescription
subtitlestringNarration text displayed at bottom of viewport. Empty string clears.
reasonstringWhy this action is being performed — shown in the action toast
correlation_idstringLink this action to a specific error or investigation
analyzebooleanEnable performance profiling (returns perf_diff in result)
tab_idnumberTarget a specific tab (omit for active tab)

Subtitles are persistent narration text displayed at the bottom of the viewport, like closed captions. They stay visible until replaced or cleared.

// Standalone
interact({action: "subtitle", text: "Creating a new project"})
// Composable — narration + action in one call
interact({action: "click", selector: "text=Create",
subtitle: "One click to start a new project"})
// Clear
interact({action: "subtitle", text: ""})

When enabled, action toasts show brief notifications at the top of the viewport for each action. The reason parameter customizes the toast label:

// Without reason: toast shows "Click: #submit-btn"
interact({action: "click", selector: "#submit-btn"})
// With reason: toast shows "Submit the registration form"
interact({action: "click", selector: "#submit-btn", reason: "Submit the registration form"})

Toasts can be toggled off in the extension popup — useful during demos.


All actions that accept a selector parameter support semantic selectors in addition to CSS:

SyntaxExampleHow it works
text=text=SubmitFinds element whose text content contains “Submit”
role=role=buttonFinds [role="button"]
placeholder=placeholder=EmailFinds [placeholder="Email"]
label=label=UsernameFinds label containing text, follows for attribute to target
aria-label=aria-label=CloseFinds [aria-label="Close"] with starts-with matching
CSS#submit-btnStandard document.querySelector()

Semantic selectors are resilient to UI changes — they target meaning, not structure. text=Submit still works after a CSS redesign, a framework migration, or a component library upgrade.

The aria-label= selector uses starts-with matching, so aria-label=Send matches Gmail’s "Send ‪(⌘Enter)‬".


interact({action: "navigate", url: "https://example.com"})

Navigates the active tab to the specified URL. Automatically includes perf_diff in the async result (before/after performance comparison).

ParameterTypeDescription
urlstring (required)URL to navigate to
interact({action: "refresh"})

Refreshes the current page. Includes perf_diff automatically.

interact({action: "back"})
interact({action: "forward"})

Browser history navigation.

interact({action: "new_tab", url: "https://example.com"})

Opens a new tab with the specified URL.

ParameterTypeDescription
urlstring (required)URL to open in the new tab

interact({action: "click", selector: "text=Submit"})
interact({action: "click", selector: "#confirm-btn", reason: "Confirm the order"})
ParameterTypeDescription
selectorstringCSS or semantic selector
interact({action: "type", selector: "label=Email", text: "user@example.com"})
interact({action: "type", selector: "placeholder=Search", text: "wireless headphones", clear: true})
ParameterTypeDescription
selectorstringCSS or semantic selector
textstringText to type
clearbooleanClear existing value before typing
interact({action: "select", selector: "#country", value: "US"})
ParameterTypeDescription
selectorstringCSS or semantic selector for <select> element
valuestringOption value to select
interact({action: "check", selector: "text=I agree to the Terms"})
interact({action: "check", selector: "#newsletter", checked: false})
ParameterTypeDefaultDescription
selectorstringCSS or semantic selector
checkedbooleantrueWhether to check or uncheck
interact({action: "key_press", selector: "label=Search", text: "Enter"})
interact({action: "key_press", text: "Escape"})
ParameterTypeDescription
selectorstringElement to target (optional — omit for page-level key press)
textstringKey name: Enter, Tab, Escape, Backspace, ArrowDown, ArrowUp, Space
interact({action: "focus", selector: "label=Email"})
interact({action: "scroll_to", selector: "#pricing-section"})

Wait for an element to appear on the page. Useful for async content.

interact({action: "wait_for", selector: "text=Dashboard", timeout_ms: 10000})
ParameterTypeDefaultDescription
selectorstringCSS or semantic selector
timeout_msnumber5000Maximum wait time in milliseconds

interact({action: "get_text", selector: ".order-total"})

Returns the text content of the matched element.

interact({action: "get_value", selector: "input[name='email']"})

Returns the current value of a form element.

interact({action: "get_attribute", selector: "#submit", name: "disabled"})
ParameterTypeDescription
namestringAttribute name to read
interact({action: "set_attribute", selector: "#submit", name: "disabled", value: "false"})
ParameterTypeDescription
namestringAttribute name
valuestringValue to set

Discovers all interactive elements on the page — buttons, links, inputs, selects, etc. Returns up to 100 elements with suggested selectors.

interact({action: "list_interactive"})

No parameters. Returns an array of elements, each with:

FieldDescription
tagElement tag name (button, input, a, etc.)
typeInput type (email, password, text) — only for <input>
selectorSuggested selector (semantic preferred: text=, aria-label=, placeholder=)
labelHuman-readable label (aria-label > title > placeholder > text content)
roleARIA role
visibleWhether the element is visible on screen

This is the best way to discover what’s clickable on an unfamiliar page. The AI can read the list and choose the right selector.


Run arbitrary JavaScript in the page context. See How Gasoline Executes Page Scripts for the full deep dive.

interact({action: "execute_js", script: "document.title"})
interact({action: "execute_js", script: "window.location.href"})
interact({action: "execute_js",
script: "document.querySelectorAll('li').length",
world: "main"})
ParameterTypeDefaultDescription
scriptstringJavaScript code to execute
worldstringautoauto (try main, fallback to isolated), main (page globals), isolated (CSP-proof)
timeout_msnumber5000Maximum execution time

Highlights an element on the page with a visual overlay. Useful for demos and debugging.

interact({action: "highlight", selector: "#error-message"})
interact({action: "highlight", selector: "text=Submit", duration_ms: 3000})
ParameterTypeDefaultDescription
selectorstringElement to highlight
duration_msnumber5000How long to show the highlight

Display persistent narration text at the bottom of the viewport.

interact({action: "subtitle", text: "Welcome to the product tour"})
interact({action: "subtitle", text: ""}) // Clear
ParameterTypeDescription
textstring (required)Narration text. Empty string clears.

Save the current browser state (URL, title, tab) as a named checkpoint.

interact({action: "save_state", snapshot_name: "logged-in"})

Restore a saved state checkpoint.

interact({action: "load_state", snapshot_name: "logged-in"})
interact({action: "load_state", snapshot_name: "logged-in", include_url: true})
ParameterTypeDefaultDescription
snapshot_namestringName of the saved state
include_urlbooleanfalseNavigate to the saved URL when restoring
interact({action: "list_states"})

Returns all saved states with metadata (name, URL, title, saved_at).

interact({action: "delete_state", snapshot_name: "old-checkpoint"})

Add analyze: true to any DOM action to get a perf_diff in the result — before/after timing comparison with Web Vitals ratings and a verdict.

interact({action: "click", selector: "text=Load Dashboard", analyze: true})

The navigate and refresh actions include perf_diff automatically.