Supported browsers
Which browsers and engines navigera drives, CI coverage, and how one is found or installed.
More: Lightpanda and your own browser, Electron and natural mode.
Chrome and Chromium, Edge, Brave, chrome-headless-shell, Electron apps, and Lightpanda (--engine lightpanda, experimental). CI runs the end-to-end suite on the current Chrome Stable and the three milestones before it, chrome-headless-shell, Chrome Beta, the runner’s Chrome on Linux and Windows, and Lightpanda; every CDP call navigera makes is checked against the protocol each browser serves.
CI runs the full end-to-end suite on:
- the current Chrome Stable and the three milestones before it (about four months of releases, covering Extended Stable), all from Chrome for Testing;
- chrome-headless-shell;
- Chrome Beta, as a non-blocking early warning;
- the runner’s own Chrome, on Linux, macOS and Windows.
The suite is weekly as well as on every push, so a new Chrome release is
caught before agents hit it. In its first runs the matrix caught two real
bugs that the runner’s Chrome alone missed: Chrome 151 segfaulted with one of
the automation flags (--disable-features=OptimizationHints, bisected with
chrome-bisect.yml), and on Chrome 153 an Enter-submitted form returned
before its redirect landed. Both are fixed.
Each run also checks CDP protocol correctness. navigera records
every command it sends (NAVIGERA_CDP_TRACE), and
tools/cdp_check.py validates every method, parameter
and enum value against the /json/protocol that that browser serves.
Deprecated or unknown usage fails the build. Edge and Brave are covered by
the benchmark.
Lightpanda 1.0 (--engine lightpanda) runs the same end-to-end suite in
CI, on 1.0.1 and the nightly. It is a different engine (one tab, no layout),
so navigera fills in what its CDP leaves out: shadow roots and password
fields in ax, confirm()/prompt() answers, navigations a click starts.
The differences that remain are listed in
docs/navigera.md.
Browsers and engines
-
Chrome-family (default). navigera looks for a browser in this order:
--chromium;$NAVIGERA_CHROMIUM,$CHROME_BIN;- for a headless run, the chrome-headless-shell
navigera install-browserinstalled; - system Chrome, Chromium or Edge;
- the Chrome
navigera install-browser chromeinstalled.
Brave and Edge work via
--chromium. chrome-headless-shell starts faster than full Chrome: it has no browser UI to bring up. -
Installing a browser.
navigera install-browser [chrome-headless-shell | chrome] [--channel stable|beta|dev|canary]downloads the latest of that channel from Google’s Chrome for Testing, the builds Google publishes for automation, throughcurl, checks every file of the archive against its checksum, and unpacks it into$NAVIGERA_BROWSERS, else~/.cache/navigera/browsers(~/Library/Caches/navigera/browserson macOS,%LOCALAPPDATA%\navigera\browserson Windows);--whereprints the directory. Run it again for a newer version; the newest installed one is used. Chrome for Testing has no Linux ARM build: there, install Chromium from the distribution.--naturalalways takes the full Chrome. -
Browser flags. Chrome runs without its sandbox as root, or when a first launch shows this machine can’t give it one (the warning says so once);
NAVIGERA_NO_SANDBOX=1turns it off up front and silences the warning.NAVIGERA_EXTRA_FLAGS(space-separated) adds Chrome flags;NAVIGERA_DROP_FLAGS(comma-separated prefixes) removes navigera’s own.NAVIGERA_EXTRA_FLAGSreaches--profilebrowsers too.NAVIGERA_PROFILE_DIR=<dir>is where throwaway profiles go (default/dev/shmwhen it is tmpfs with room, else the system temp directory). -
CDP transport.
--remote-debugging-pipeby default on Linux/macOS: no TCP port, and the browser exits when navigera dies.--transport ws(or$NAVIGERA_CDP_TRANSPORT=ws) opens a DevTools WebSocket port instead, for attaching other tools. Windows always usesws; Chrome runs in a kill-on-close job object there, so it still exits with navigera. -
Windows sessions. The session file holds
127.0.0.1:<port> <token>; the server listens on that loopback port and drops any client whose first line isn’t the token (a web page posting to localhost can’t drive it).startdetaches the server from the console, the caller’s job and its stdio handles, so the shell that ranstartreturns at once. It returns once the browser is up (no need to sleep after it); the first Chrome launch on a fresh Windows machine takes 4–6 s, later ones under 1 s. -
A session that stopped. A client call to a session that isn’t running quotes the end of its server’s log (
<socket>.log, kept after the server exits), which says why it stopped:idle for 600s,process <pid> (--parent) exited, a browser crash, orquit. -
One session name, one browser. A session name is shared by every process that uses it: two agents on one name drive one browser (wrong pages, missing refs, one’s
quitends the other’s session). A command that came in while another client’s command was running on the session gets anotesaying so. So does a command from a different process than the session’s last one (within 10 minutes), and that last one’s next command is told whether its tab was moved and from where to where. The process is the first one up the tree that isn’t a shell, a wrapper or navigera’s npm/Python launcher (Linux), so an agent that runs each command in a fresh shell counts as one;NAVIGERA_CALLER=<name>names it explicitly (and turns it on elsewhere). Give each agent its own-s <name>. -
Shared browser. Named sessions (and
navigera mcp) share one browser, each in a browser context of its own: tabs, popups, cookies, local storage, cache, downloads (each session’s own directory), permissions, routes, credentials, init scripts, emulation and dialog answers are the session’s. N parallel agents cost one browser plus a renderer each instead of N browsers. A small host process (navigera … browser-host, started by the first session) launches the browser as a session would and keeps it; sessions reach it through a socket in the session directory (browser-<key>.sock; on Windows the loopback port and token file sessions use), never a DevTools port: on Linux/macOS the browser still runs on the private pipe. Each session gets a browser-level CDP session of its own; the host renumbers commands and routes answers and events, and a session can address only what it opened and cannot close the browser. A session’s contexts close when its connection does, a killed session server’s included. The browser closes 30 s after its last session leaves ($NAVIGERA_SHARED_GRACE_S), so the next agent’sstartis warm. Sessions share a browser when everything that shapes it matches (navigera’s version, the executable, headless or not,--natural,NAVIGERA_EXTRA_FLAGS/NAVIGERA_DROP_FLAGS/NAVIGERA_NO_SANDBOX);show/hidemove a session to the visible or headless one. If the shared browser dies, each session’s next command relaunches it (or joins the relaunch another session made), reopens the session’s tabs at their last URLs, restores its cookies and localStorage from an in-memory snapshot (at most 500 ms old, taken when the session is idle), and says what was lost in a note and arecoveredfield (history, scroll, typed text, sessionStorage, refs, logs; a tab last loaded by a form POST reopens with GET). A command running at the crash fails and is not retried; a second crash within 10 s of a recovery ends the session. A browser of its own instead:start --own-browser(orNAVIGERA_SHARED_BROWSER=0);--attach,--profile,--electron, Lightpanda and--transport wson Linux/macOS always get one.
Made from README.md, docs/browsers.md, docs/navigera.md.