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

Running

bitti run and its flags: which scenarios run, and in which browsers and apps.

bitti run [<file.bt|file.feature|dir>...] [--base-url <url>] [--var k=v] [--grep <text>] [--grep-invert <text>]
              [--tag <tag|expression>] [--last-failed] [--max-failures <n>|-x] [--forbid-only|--allow-only]
              [--workers <n|auto>|-j <n>] [--isolation context|browser] [--retries <n>] [--fail-on-flaky] [--shard <i/n>]
              [--repeat <n>] [--shuffle [<seed>]] [--slowmo <ms>]
              [--reporter console|jsonl|github] [--junit <file>] [--cucumber <file>] [--allure <dir>] [--html <file>] [--json]
              [--timeout-ms <ms>] [--wait-ms <ms>] [--headed] [--chromium <path>] [--engine chrome|lightpanda]
              [--electron <app> [--electron-arg <arg>]...] [--attach <port|ws://…>]
              [--secrets <file>] [--evidence <dir>] [--pause-on-failure] [--trace on-failure|all] [--video on-failure|all] [--update-snapshots]
              [--compare-report html,json,rows|none] [--config <file>] [--env <name>]
bitti lint [<file.bt|file.feature|dir>...]
bitti list [<file.bt|file.feature|dir>...]
bitti trace <dir> [<line>]
bitti fix [<file>:<line>] [--use <n>] [--all [--min <p>]]
bitti navigera <command…>
bitti from-session <name> [--scenario <name>] [--out <file.bt>]
bitti record <url> [--out <file.bt>] [--scenario <name>] [--headless] [--for <seconds>]
bitti record --extend <file.bt> [--scenario <name>] [--base-url <url>] [--secrets <file>]
bitti mcp [--headed] [--chromium <path>]
bitti skill          # the agent skill (what an agent reads to write tests)
bitti <command> --help   # that command's usage and options
bitti --version

--base-url falls back to base in the file, then BITTI_BASE_URL. --workers is auto unless given: half the CPUs, at most 8, and never more than there are scenarios. --workers 1 runs them one at a time.

Picking what runs

  • --tag smoke runs the scenarios tagged @smoke; a tag expression picks by several, as Cucumber writes them: --tag "smoke and not slow", --tag "(checkout or cart) and not wip". Repeated, any of them. --grep-invert <text> leaves out the names that contain it.
  • Some tags say how a scenario runs: @skip and @fixme aren’t run and are reported as skipped (SKIP, JUnit <skipped/>, Allure skipped); @slow gives each check three times its time; @serial (or @exclusive) runs the scenario while no other one runs, for one that changes what the others read (an app setting, a shared account): the others run in parallel first, then each @serial one alone; @only runs only the scenarios that have it, a focus while working on one. It is an error with --forbid-only, which is on by itself under CI (CI set), so a focus left in by mistake doesn’t pass a build on a few scenarios (--allow-only runs just those anyway).
  • --max-failures <n> starts no scenario once n have failed (-x: at the first), and says how many were not run; the run fails.
  • --last-failed (--lf) runs only the scenarios that failed in the last run in this directory (.bitti/last-run.json). With none, it says so and exits 0.
  • --scenario-timeout-ms <ms> (scenario_timeout_ms in bitti.toml) is the most one scenario’s steps may take: no step starts once it is up, and a step’s wait (an expect, a retry, an http or exec, its own --timeout-ms too) stops there, the failure saying so. @slow triples it. Off by default. --global-timeout-ms <ms> (global_timeout_ms) does the same for the whole run: no scenario starts after it, those running stop there, and the run fails with the count of scenarios it never ran.
  • --slowmo <ms> waits that long before each step that acts on the page (goto, click, fill …), to follow a --headed run by eye; checks and http steps aren’t slowed.

Browsers and apps

  • A click that opens a tab or a popup (target=_blank, window.open) moves the scenario to it, as navigera does: the next steps read and act there. tab-select 0 goes back to the first tab; tab-close closes the one you’re on.
  • Every scenario starts in a fresh browser context (navigera reset --all: no cookies, storage, tabs, routes, init scripts, set emulation or dialog answer from the scenario before), in about 40 ms instead of a new browser’s few hundred. --workers n runs n at once, each in a browser context of one shared browser (about 40% less memory at 4 workers than a browser each; --isolation browser gives each its own). The longest start first (by .bitti/timings.json, which each run updates; the first run goes in file order).
  • --engine lightpanda (or engine = "lightpanda" in a profile, or NAVIGERA_ENGINE=lightpanda) runs on Lightpanda ($LIGHTPANDA_BIN or lightpanda on the PATH), a new Lightpanda for each scenario (it has one context per process): less memory, no layout. It is a smoke tier, not a replacement: hover-revealed elements, new tabs, screenshots and ax pixels need Chrome. On the 40-scenario suite’s 25 site scenarios it passes 22, and is not faster: 22 s against Chrome’s 11 s at one worker (half of it the three failures’ waits).
  • --electron <app> (or electron = "./app" and electron_args = [...] in bitti.toml) tests an Electron desktop app instead of a web page: the scenarios drive its windows as tabs, through navigera’s start --electron. <app> is the app’s directory or main script (the Electron in its node_modules runs it), a packaged app’s executable or a macOS .app bundle. Each scenario gets a fresh app, so none sees what the one before left in its storage, and they run one at a time (two copies of an app would share its user data): --workers becomes 1. A window the app opens itself (Settings, a second document) becomes the scenario’s tab, and one that closes itself hands back to the one before. expect js --main "<code>" checks the app’s main process (a function gets the electron module: ({ app }) => app.getName()), and eval --main runs code there as a step. On a Linux CI machine, run under xvfb-run. The example: tests/fixtures/electron, run in CI on Linux, macOS and Windows against navigera’s fixture app.
  • --attach <port|ws://…> (or attach = "9222" in bitti.toml) runs against a browser or an Electron app that is already running with a DevTools port: the build a developer has open (npm start -- --remote-debugging-port=9222), or a Chrome they started. In an app, the scenarios run one after the other in the one app, each going on where the one before left it, and the app keeps running after the run. In a browser, each scenario gets a clean context of its own. One worker. The example: tests/fixtures/electron-attached.

Made from docs/running.md.