Commands: read the page
goto, the ax tree, text, get, is, eval, find, console, errors, network, locate.
| command | args | result |
|---|---|---|
goto | <url> or --url; --wait load|domcontentloaded|commit; --timeout-ms | state {tab, tabs, url, title}; a URL that downloads leaves the page where it was and adds download (the file) and a note. example.com → https://, localhost:3000 → http:// |
ax (snapshot) | [<ref> | --selector <css> | --text t] scope; --limit <lines> (2000); --refs all; --format json (old flat list: {ref, role, name, value?, url?}; with --all {id, role, name, backendNodeId}); --all; --grep <words> [--limit <lines>] | text tree (below). --grep: only the lines that mention the words (letter case aside; all the words in any order when the phrase is nowhere), each under the containers it sits in, with refs to act on; the first 30 matching lines and how many there are |
eval (evaluate) | <js>, --expression <js>, --file <path.js>, or - (read the script from stdin) | the JSON value: an expression’s, an arrow function’s (it is called), or for statements the last expression’s; await works at the top level, and a body that returns gives what it returns; promises are awaited |
text | [--selector <css>] [--grep <words> [--context <lines>] [--limit <passages>]] | the element’s text as it reads (innerText: a list reads as lines), or null; an element that is not rendered gives its textContent without the <script>, <style>, <template> and <noscript> inside (one that is itself a script keeps its text); with no selector, the whole page as it reads. --grep: only the passages that mention the words, letter case aside, each with the lines around it (--context, 1) and each line’s number in the text; the first --limit (5) and how many there are; several words match in any order when the phrase is nowhere; nothing found is said, not an error. Long lines are shown around the match, and the reply stops at 12,000 characters |
get | text|value|html|outer|box|checked target; attr <name> / style <prop> target; count <css>; title; url | the value (url: the state object, as url returns it); box is {x, y, width, height} in top-level viewport pixels (inside a cross-origin frame, that frame’s) |
is | visible|hidden|enabled|disabled|checked|editable|focused target | true/false (a missing element is not visible, after 500 ms) |
console | --level error|warn|info|log|debug, --limit <n> (200), --clear, --json | [level] text (url:line) per line: console calls, uncaught exceptions ([exception]), failed loads and CSP reports; --clear prints them, then empties the list |
errors | --limit, --clear, --json | console --level error |
network | --filter <text>, --type fetch|xhr|document|…, --failed, --since <n> (only requests after #n), --limit <n> (100), --clear; --har <file> | #n METHOD STATUS type url size time per line (same-origin URLs as paths); --har writes HAR 1.2 with the response bodies the browser still holds (what route --har replays); --clear prints them, then empties the list |
network <n> | --body-file <file> | one request in full: headers, post data, response body (8 KB shown; the file gets all of it) |
locate | target (a ref, usually) | {locators: [{kind, flags}]}: the flags that find the element again, most stable first (testid, role + name, label, placeholder, text, css), each kept only when the op’s own finder picks this element on the page as it is; inside a frame each has --frame (a cross-origin frame named from the page that holds it); secret: true for a password field (type=password, autocomplete current/new-password or one-time-code) |
title / url | — | string / state |
back / forward / reload | — | state |
The ax tree
page "Cart — Acme Supply" http://127.0.0.1:8765/cart (tab 0 of 2)
- main:
- heading "Your cart" [level=1]
- table:
- row:
- cell "Brass Sprocket"
- cell "Qty 2":
- spinbutton "Qty" [ref=146] value="2"
- cell "Remove Brass Sprocket": button [ref=193]
- textbox "Coupon code" [ref=148]
- button "Apply coupon" [ref=212]
- The tree comes from one
Accessibility.getFullAXTreecall per frame, and oneDOMSnapshot.captureSnapshotfor what is clickable (Chrome only). Same-origin and in-process iframes are spliced in under theirIframenode, and open shadow roots are included. - A page of more than 3,000 DOM nodes is read from that one DOM snapshot
instead: the tree is built from it (roles, names, states and values as
Chrome computes them) and printed the same way, refs included, in about a
fifth of the time (a 2,000-row table: 325 ms for the whole tree, where
Chrome’s tree took 1.8 s). What it does not model: a modal
<dialog>’s modality, the inner fields of date and time inputs, and closed shadow roots.NAVIGERA_AX_SOURCE=chrome(ordom) picks one source for every page;bothprints Chrome’s tree, then the snapshot’s, of one page load. - Wrapper nodes (
generic, label boxes) are collapsed, and text that repeats an ancestor’s name or a neighbouring control’s label is dropped. - Adjacent text shares
- text:lines of up to 300 characters (a grid of<div>cells is a few lines, not one per cell); any other node between texts starts a new line. - A text cut at 300 characters, or a name or value cut at 150, says how much
is left out, and a cut text names the ref that reads all of it:
- text: Lorem ipsum dolor sit amet… (+1979 chars: get text 8). A snapshot that cut anything says so once, under its first line, with the totals (… 150 texts cut short here (11,553 chars left out): …). Nothing is cut when the whole snapshot, every text in full, stays under 32,000 characters: then the cuts save less than reading them back would cost.ax --full-text(MCP:full_text) prints every word;textwith no selector prints the page’s whole text as it reads (innerText). - A named node with one same-named actionable child is printed on one line,
for example
heading "X": link [ref=7]. - A ref outlives a re-render of its element: when an op finds its element
gone (a list redrawn, a button replaced after a state change), the
element is looked for again by the role and name the snapshot printed,
among those of that role and name in the snapshot’s scope, and acted on
when there are as many of them as the snapshot had and the document and
URL are the same. The result’s note says so (
ref 17 was re-rendered: this acted on button "Save", now ref 48). Otherwise the op fails as before (that ref is stale … run ax for fresh refs). [ref=N](a backend DOM node id) appears on actionable nodes: interactive roles and focusable elements, and what the page made clickable without saying so (an element with a click, mousedown or mouseup handler of its own, or the outermost element of acursor: pointerarea, where a user’s click can land: a box of some size, notpointer-events: none, not fully transparent, not in another site’s frame such as an ad): a<div>row or card prints asclickable [ref=N]: <its text>, a role it has (row) keeps it. A container that holds other actionable nodes isn’t one, and a list or table that listens for its items’ clicks gives each item or row the ref instead (one ref on the list would click its middle item). What is inside a link or button, or underaria-hiddenorinert, isn’t marked, nor is an element with nothing to tell it by; a label whose control is hidden is. An actionable node with no name or text shows its#idor.class, and what the page marks it with: a tooltip attribute (data-tooltip,title, …), its icon (an icon font’s class, an SVG sprite’s symbol,data-icon), its image’s file name, or thearia-describedbytext (clickable #send-forward [ref=19],button .icon-btn icon="fa-trash" [ref=7],link .nav img="home.png" [ref=9]). Use--refs allto get one on every node.- States are shown in brackets:
checked,disabled,expandedorcollapsed,selected,required,invalid,level=N. - Inputs show
value="…", links showurl=(shortened to the path on the same origin), and<select>lists itsoptions:inline. - Collapsed content (closed
<details>, menus that open on hover) is not in the tree until it is opened.
Made from docs/navigera.md.