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: state, emulation and audit

cookies, storage, set, route, clock, init-script, WebMCP, passkey, a11y, vitals and totp.

commandargsresult
http[GET|POST|PUT|PATCH|DELETE|HEAD] <url> [--json <body> | --body <text> | --form <name=value>]... [--header 'Name: value']... [--max <bytes>] [--insecure] [--as-json]one request outside the page, for an API the page can’t call (another origin without CORS, or a POST a link can’t make): it carries the cookies the browser holds for that URL (HttpOnly too, never printed), and the cookies the answers set go into the browser, so a sign-in through an API carries to the pages. Redirects are followed one hop at a time, each checked against --allow-domains and sent its own cookies. Prints HTTP <status> · <ms> · <type> and the body (16 KB, --max); --as-json: {status, ms, url, content_type, body, more_bytes, cookies_sent, cookies_stored}. Proxies and certificates as --attach wss:// reads them
cookies[--all] [--url <u>] [--values] [--json]; set <name> <value> [--url <u> | --domain <d>] [--path] [--expires <unix s>] [--http-only] [--secure] [--same-site Lax|Strict|None]; delete <name>; clearone cookie per line (--all: every cookie in the browser), an HttpOnly cookie’s value hidden unless --values or --json: it is usually a session’s key, which an agent never needs to read and which, once printed, is in its context; set → {set}, delete → {deleted}, clear → {cleared: true}
storage[local|session] [get [<key>] | set <key> <value> | remove <key> | clear]the value, or the whole store as an object
statesave|load <file.json>every cookie (HttpOnly too), the open tabs’ localStorage and the passkeys of a passkey on authenticator to a file, or back: {saved|loaded, cookies, origins} (+ passkeys). The file is the common storage-state JSON, so one saved by another browser tool loads here, and back. load sets the cookies at once and gives each origin’s keys to documents of that origin that lack them
totp<ENV_NAME>no session needed: the current code of a sign-in’s authenticator app (RFC 6238, what Google Authenticator or 1Password shows), from the secret in that environment variable: its base32 key or the otpauth://totp/... URI of the site’s QR code (digits, period read from it; SHA1, which nearly every site uses). The secret is never an argument, which would land in the shell history. A code with under 3 s left waits for the next one, so it can’t run out before the site checks it. fill --label "Authentication code" "$(navigera totp SHOP_TOTP)"
setviewport <w> <h> [--scale <dpr>] [--mobile], device <name> (55 devices: iPhone SE to 17 Pro Max, Pixel 5 to 10 Pro XL, Galaxy S, A, Z Flip, Z Fold and Tab models, iPads, Laptop, Desktop, Desktop HD, Desktop HD HiDPI), media dark|light|print|reduced-motion|forced-colors, geo <lat> <lon> [--accuracy <m>], offline on|off, network slow-3g|fast-3g|4g or network <latency ms> <down kbit/s> [<up kbit/s>] (Chrome DevTools’ presets; one setting with offline: the later wins), cpu <slowdown> (4: four times slower; mid-tier is 4, low-end 6, DevTools’ presets for phones), permissions grant|deny|reset <name>… (geolocation, notifications, camera, microphone, clipboard, midi, sensors, background-sync), headers 'Name: value'… (or a JSON object), ua <string>, locale <tag>, timezone <zone>, credentials <user> <password>; off resets onewhat was set. Applies to every tab and to tabs opened later
route<url glob> (*, ? over the whole URL), then --abort (default), --status <n> [--body <text> | --body-file <f>] [--content-type <t>] [--header 'Name: value']…, or --modify [--set-header 'Name: value']… [--replace <from> <to>]… (the request reaches the server and its response is changed: headers set, 'Name:' removes one; text replaced in the body); or [<url glob>] --har <file> [--not-found abort|continue]: answer from a HAR (one network --har wrote, or a browser’s): the first unused entry with the request’s method and URL, then the last one again; requests it has no entry for fail (abort, the default) or go to the network (continue); no glob = every request. No argument lists the rules with their hit counts{route, action}. Only matching URLs are intercepted
unroute[<url glob>]{removed} (all rules without a glob)
clockinstall [--time <t>] [--paused], set <t>, run-for <length>, fast-forward <length>, pause-at <t>, resume, uninstall; no action shows it. <t>: a date (2024-02-02T08:00:00, local unless it says Z or an offset) or epoch ms; <length>: 500ms, 30s, 5m, 1h, 2d, mm:ss, hh:mm:ss{now, time, paused, timers} (+ fired for the ones that run timers). From install on, Date, performance.now, setTimeout/setInterval and Intl.DateTimeFormat without a date read a clock of navigera’s in every document of every tab: it starts at --time (default now) and flows with real time, or stands still (--paused, pause-at). set moves the date only (timers keep their delays); run-for advances, firing each timer due on the way at its own time (an interval as often as it comes); fast-forward jumps, firing each that came due once; pause-at runs to a time and stops there. A new document (a reload, a link, a new tab) goes on from where the clock is. Animation frames keep real time, and so do navigera’s own scripts in the page (its waits): code eval runs is the page’s. reset takes the clock away
init-script<js>, --file <path.js>, --clear; no argument lists themruns before the page’s own scripts in every document of every tab; adding returns {init_scripts: n}, --clear {removed}
webmcp-list—the tools the page registered with WebMCP (document.modelContext.registerTool): {tools: [{name, description, read_only, input_schema?, consequential?, untrusted_content?}], untrusted} sorted by name. See WebMCP
webmcp-call<name> [--params '{json}'] [--confirm] [--timeout-ms <n>]runs the tool in the frame that registered it and waits for its answer: state + {tool, output, untrusted}; a tool the page doesn’t mark read-only is refused without --confirm
passkey (webauthn)on [--authenticator internal|usb|nfc|ble|hybrid] [--no-user-verification] [--no-resident-key], off, list (the default), load <file.json>, remove <id>, clear, verify on|offon: a virtual WebAuthn authenticator (Chrome’s) in every tab and in tabs opened later, so the page’s navigator.credentials.create() and .get() (passkey sign-up and sign-in) are answered with no person, phone or security key: by default the device’s own (internal), making discoverable passkeys with user verification, as a password manager does; --authenticator makes it a security key or a phone. Turn it on before the page asks: without it, headless Chrome leaves the request pending. A tab opened later starts with the passkeys the others hold. list: {passkeys: [{id, rp_id, user, sign_count}]}, never a private key. state save keeps them under credentials (private keys included, in the shape Playwright’s credentials.get() gives: id, rpId, userHandle, privateKey, publicKey, signCount, base64url) and state load puts them back, turning the authenticator on; load takes one such passkey, a list, or a state file. verify off: the next ceremonies fail as a fingerprint that doesn’t match would (NotAllowedError). reset keeps the authenticator and drops its passkeys (they belonged to the old context, as cookies do); reset --all drops both. Chrome only
a11y (accessibility, audit)[--selector <css>] [--tags <list>] [--ignore <rule>,…]an accessibility audit with axe-core 4.14 (built in), run in an isolated world of the page, which never sees a window.axe: {violations, by_impact, rules: [{rule, impact, help, count, nodes: [{ref, selector, html}], more}], tags, axe}, the worst rules first, up to 5 elements each with its ref (act on it, or ax <ref> around it). WCAG 2.0, 2.1 and 2.2 A and AA by default (wcag2a,wcag2aa,wcag21a,wcag21aa,wcag22aa); --tags best-practice adds axe’s own advice; --ignore color-contrast,region leaves rules out; --selector form audits one part. The top document and frames of its origin; a cross-origin frame is not audited. Not on Lightpanda
vitals (web-vitals)—the current document’s web vitals as the browser measured them, read from its own performance entries (nothing injected before): {ttfb, fcp, lcp, load} in ms from the navigation’s start, cls (the largest session window of layout shifts no input caused), inp (ms: the slowest interaction, one in 50 left out as Google counts it) and interactions; lcp_element, cls_elements (up to 3) and inp_element with inp_event name what to fix, as CSS selectors; rating says good, needs-improvement or poor for each by Google’s thresholds (LCP 2.5/4 s, FCP 1.8/3 s, TTFB 0.8/1.8 s, CLS 0.1/0.25, INP 200/500 ms). The browser keeps only interactions of 104 ms or more, so when all of them were quicker inp is null with inp_under_ms: 104 (rated good). LCP stops at the first input, as in Chrome. Measure as a phone would with set cpu 4 and set network fast-3g first. Not on Lightpanda

Made from docs/navigera.md.