Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Commands

The navigera command line: sessions, flags and output, with the command list by topic.

The commands by topic: sessions, tabs and the browser, read the page, act on the page, state, emulation and audit.

navigera [GLOBAL FLAGS] <command> [ARGS] [GLOBAL FLAGS]
global flagmeaning
-s, --session <name|path>named session. A bare name lives in a directory only you can enter: $XDG_RUNTIME_DIR/navigera/<name>.sock, else $TMPDIR/navigera-<uid>/<name>.sock (mode 0700; navigera refuses one that is a symlink, someone else’s or open to others), %TEMP%\navigera\ on Windows; a value with a path separator is used as the path. $NAVIGERA_SESSION sets a default for client calls
--output compact|raw|jsonwhat a command prints. compact, the default: an action that moved the page prints only its own fields and what changed ({"title":"Saved"}); one that left it on the same document, after an ax of it, prints the lines of that tree that changed (+ new, - gone, ~ the same element reading differently; at most 40, then a count), read again the way that ax read it, waiting as ax does for data the action fetches, and ok when no line changed (after a fill, the field’s own new value is not a change). On a large page (past 2,500 DOM nodes) a text entry (fill, type, insert-text) that changed nothing else is not read again: a journal kept in the page since the last read (its DOM, frames, shadow roots, form values, and the style rules that follow :focus, :hover, :invalid, :has() and the like) shows it, and the report is the same ok; a check, uncheck or select that moved only checkboxes, radios or single selects reports their lines rewritten as a read prints them; anything it can’t watch (a style sheet of another origin) means a read, as before. $NAVIGERA_CHANGE_JOURNAL=0 reads after every entry; a read prints its value (strings unquoted, the ax tree as text). raw: the result only, as it is. json: one JSON line per command, {"ok":true,"result":…} or {"ok":false,"error":…}, for programs. Outside json, errors go to stderr as error: … (exit code 1) and notes as note: …. $NAVIGERA_OUTPUT sets the mode for every command of a shell; a flag wins. The session remembers the state it last reported. --compact: --output compact; --raw: --output raw
--prettypretty-print the JSON
--timeout-ms <ms>before the command: navigation/command timeout (default 35000). After an element command: that op’s element wait (default 5000)
--wait-ms <ms>element ops’ wait when they name no timeout, and on one wait for a condition, its timeout (default 5000; $NAVIGERA_WAIT_MS). On start/serve/mcp it holds for the whole session
--download-dir <dir>where downloaded files go ($NAVIGERA_DOWNLOAD_DIR; default a directory of the session’s own in navigera-<uid> under the system temp directory, which only you can enter)
--chromium <path>browser binary (also $NAVIGERA_CHROMIUM, $CHROME_BIN)
--engine chrome|lightpanda ($NAVIGERA_ENGINE), --headedengine; visible window
--idle-timeout-s <s>a session server shuts down after this idle time (default 600, 0 = never; also start --idle <s>). status and sessions don’t count as use
--own-browserwith start (or mcp): a browser of the session’s own instead of a context on the shared browser ($NAVIGERA_SHARED_BROWSER=0)
--parent <pid>with start: the session quits when that process exits (checked twice a second; $NAVIGERA_PARENT_PID)
--allow-domains <list>with start/serve/mcp: hostnames this session may navigate to or request from (comma-separated; *.example.com covers its subdomains, not itself; $NAVIGERA_ALLOW_DOMAINS, a flag wins). Everything else is refused at the Fetch request stage, before any route rule, on every redirect hop; a refused navigation’s error names the denied host and the flag, and status lists refused hosts. An entry is a hostname only (no scheme, port, path or userinfo); malformed or empty lists are refused at startup, never silently disabled. --allow-domains-docs-only checks top-level navigation only: a navigation restriction, not exfiltration protection (subresources, iframes included, still go out). Requests are paused at the browser too, so a popup (window.open, target=_blank) is refused before its first request goes out, and on a browser of the session’s own (serve, start --own-browser) a service worker’s fetches are checked in strict mode. Limits, measured: this is a hostname policy, not an origin policy (scheme and port are ignored); WebSocket handshakes are NOT intercepted by Fetch in Chrome, so neither mode stops exfiltration over them, nor over a service worker of a shared browser; file:, about:, blob: and data: URLs carry no host to check and pass through. A session that cannot install the interception fails to start rather than running unenforced; reset keeps the policy, reset --all drops it, a fork starts without one
-V, --version, -h, --help, help <command>info

Every command prints one JSON object: {"id":…, "ok":true, "result":…, "elapsed_ms":…} or {"ok":false, "error":"…"}. Two optional fields report side effects: dialogs (dialogs the page opened and how they were answered) and new_tabs (tabs the page opened, now in the tab list). The exit code is 0 on success, 1 on a failed op and 2 on bad arguments.

Targets. Element commands take exactly one target:

  • a ref from ax as the first argument (click 12; @12, e12, ref12 and ref=12 also work) or --ref 12;

  • --selector <css>: the first match a user could reach (when the first one is parked off the page and another isn’t, the other). host >>> inner crosses shadow roots: inner inside the open shadow root of an element host matches (or a shadow root under it), as in "#app >>> x-card:nth-of-type(2) >>> button"; locate writes one for an element in a shadow root;

  • --text "<visible text>": the best match by accessible label, text or value. An exact match beats a partial one, actionable elements beat plain ones, and a <label> stands for its control.

  • --role <role> [--name <accessible name>], --label <form label>, --placeholder <text>, --testid <data-testid>: semantic locators (case-insensitive, exact before contains, visible first, open shadow roots included); --nth <i> picks among their matches or --selector’s (0-based, -1 = the last).

  • --near <text> with any of them: the match whose own part of the page (its card, row or section: the largest ancestor holding no other match) shows the text: click --role button --name "Add to cart" --near "Brass Widget". It holds when items reorder, where --nth doesn’t; locate writes it when a role and name match more than one element.

  • --frame <css> with any of them: look only inside that iframe or frame ("#outer >> #inner" for one inside another), of this origin or another, when two frames hold the same element (two address forms, two payment frames). wait --selector/--text/--gone --frame … too. When the CSS matches several frames, the first in document order is the one; when it matches none, the error says so.

Selector, text and locator targets auto-wait (default 5 s, --wait-ms) for the element to appear. They search the top document first, then its open shadow roots and the documents of same-origin frames (iframes, framesets, srcdoc), so a form inside an iframe or a button inside a web component is reached the same way. When the element isn’t there, frames of another origin (a card form from a payment provider, a sign-in frame) are searched too, from an isolated world navigera makes in each, which the page can’t see. A single wait --text or wait --selector looks there as well. In a browser navigera launched, cross-site frames share the page’s process, so all of them are reachable; with --attach to your own browser, frames in another process are reachable by ref only.


Made from docs/navigera.md.