| name | aside-visual-browse |
| description | Read this when you need a coordinate fallback for visible browser UI that snapshots, refs, or locators cannot target reliably. |
| metadata | {"version":"0.1.0"} |
Visual Browse
cua global is available in REPL.
Visual browsing is a coordinate fallback for visible browser UI that cannot be targeted reliably with snapshot(page), refs, or page locators. Use it only while the task genuinely depends on visible pixels.
When to use
- Canvas rendered apps: slide/document/image editors, maps, games, charts, whiteboards and simulations
- Custom visual controls: drag handles, sliders, drawing surfaces, crop boxes, map pins, timeline controls
- Unstable or missing refs: visible controls whose snapshot refs are stale, absent, obscured, or repeatedly hit the wrong target
- Visual verification: when DOM state is insufficient and the next action depends on what is visibly rendered
When not to use
Do not use visual browsing for:
- reading ordinary page text
- navigation-only work
- simple buttons, links, inputs, menus, or forms with usable refs
- repeated coordinate guesses without checking the visual result
Prefer snapshot(page), refs, and locators when they can target the UI reliably.
Operating rules
cua always acts on the current active page. Open or focus the right tab first.
- When coordinates are not already known, call
display(await cua.getVisibleScreenshot()) before acting.
- After any CUA action that changes the page, verify before the next action.
- Use
snapshot(page) when DOM/ref state matters.
- Use
display(await cua.getVisibleScreenshot()) when visual state matters.
- Return to
snapshot(page), refs, or locators as soon as the visual task is done (e.g. CAPTCHA solved, canvas interaction complete, dropdown finally submitted).
- Only keep using
visual-browse mode while the page genuinely requires pixel-level visual interaction.
- Use coordinates for pixel-only manipulation. Use refs or locators for UI controls whenever they exist.
Recovery
- If a popup, modal, or cookie banner blocks interaction, handle that first.
- If an action does not visibly work, take a fresh screenshot before retrying.
- If the same coordinate approach fails 2-3 times, switch strategy instead of repeating.
- For layered canvas/editor surfaces, prefer coarse sidebar/tool controls over precise clicks on stacked objects.
API
interface CUAAPI {
click(options: {
x: number;
y: number;
button?: 'left' | 'middle' | 'right';
keypress?: string[];
}): Promise<void>;
doubleClick(options: {
x: number;
y: number;
keypress?: string[];
}): Promise<void>;
drag(options: {
path: Array<{ x: number; y: number }>;
keys?: string[];
}): Promise<void>;
getVisibleScreenshot(): Promise<>;
(: {
: [];
}): <>;
(: {
?: [];
: ;
: ;
}): <>;
(: {
?: [];
: ;
: ;
: ;
: ;
}): <>;
(: { : }): <>;
}
Modifier keys
Use these values in keypress / keys: Alt, Control, ControlOrMeta, Meta, Shift.
ControlOrMeta means Meta on macOS and Control elsewhere. Aliases also work: Cmd, Command, Ctrl, Option.
Examples
display(await cua.getVisibleScreenshot());
await cua.click({ x: 420, y: 315 });
console.log((await snapshot(page)).tree);
await cua.drag({
path: [
{ x: 240, y: 540 },
{ x: 320, y: 540 },
{ x: 410, y: 540 },
],
});