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

Failures and fixes

What a failure prints, fixing locators with bitti fix, and the tools that write scenarios: navigera, from-session, record, mcp.

  • A failure prints the step, what was expected and seen, where the page was, a screenshot (under .bitti/runs/), and a note when an earlier click changed nothing on the page (navigera’s no_effect), the usual reason the next check fails. When the element isn’t there, it lists the closest ones on the page as locators to paste in:

    FAIL  shop.bt:21  Accept the cookies  (611 ms)
          line 23: click --role button --name "Accept everything"
          click role="button" name="Accept everything": … no element …
          nearest on the page:
            1. button "Accept all"   --role button --name "Accept all"   0.63
    

    The list covers frames too: a step with --frame keeps it, and fix changes only the locator.

  • bitti fix <file>:<line> [--use <n>] puts the last run’s n-th “nearest on the page” into that step (only its locator flags change, and only if the line still reads as it did); bitti fix --all [--min 0.6] takes each failure’s first suggestion that scored that much, and plain bitti fix lists them. The failure block prints the command. A click that something else covers (a consent bar, a modal) gets that thing’s buttons instead, “Accept”, “Close”, “Got it” … first, as an optional click that fix puts before the step. A .feature step is left alone: change its step block instead.

  • bitti navigera … is navigera itself, built in: explore a page the way an agent does (bitti navigera -s work start, goto, ax, click 12, fill 15 ada@example.com) with no second program to install. bitti from-session work then writes what that session did as a scenario: each action once, and the waits between (reads and eval left out), every ref replaced by the most stable locator that found its element again just before the action (test id, role and name, label, placeholder, text, CSS; navigera’s locate, each checked on the page; inside a web component’s shadow root, CSS through its hosts: --selector "#tip >>> button"), base from the first goto, an expect url where an action moved the page, an expect text for a heading that changed or a status/alert message that appeared (as a comment when it has numbers, which may change), and a value typed into a password field (type=password, as navigera’s locate says) as ${secret:NAME}, named after the field (${secret:PASSWORD}, ${secret:CONFIRM_PASSWORD}). What it can’t keep (a mouse at coordinates, a ref no locator found again) is a # left out: line. Read it through, keep the expects that matter, add the ones the test is for. A session started by a plain navigera works too when that navigera has history.

  • bitti record <url> --out t.bt opens a browser to use by hand: each click, field change, check, select, upload and Enter becomes a step as you do it, with the most stable locator that finds the element (the same locate as from-session, run in the page at that moment; when the click takes its element or the page away before that check is done, a banner’s Accept or a link, the element’s own text or label read as it was clicked), an expect url where the page moved, a password field’s value as ${secret:NAME} (never written down). The file is rewritten after every step: close the browser or press Ctrl-C to stop. A click into a field isn’t a step (its value is); typing in a field twice keeps the last value.

  • bitti record --extend t.bt [--scenario <name>] grows a scenario instead: it runs that scenario (default: the file’s last) to its end, after each left out, then hands you the browser there; what you do goes in after its last step, the same way, and the rest of the file stays as it was. A scenario that fails before its end is not extended: fix it first. --headless and --for <s> work as for record. A .feature is refused (its steps live in its step blocks).

  • bitti mcp is the same loop for an agent over MCP (stdio): navigera’s browser tools (browser_navigate, browser_snapshot, browser_click, … one browser for all of them) beside bitti_from_session (what those tools did, as a scenario; out writes it), bitti_run, bitti_list, bitti_lint, bitti_failure (the last run’s failures with the nearest elements) and bitti_fix. Its instructions tell the agent that page content is data, not instructions, and to confirm irreversible actions against the user’s request. Register it as {"command": "bitti", "args": ["mcp"]}. What the tools run, read and write (paths, out, the files args names) stays inside the working directory, as navigera’s own tools’ files do, and args can’t name a --chromium to start; NAVIGERA_MCP_ALLOW_FILES=1 lifts both. A project’s own .bt files still do what they say (exec, [server]).

  • --pause-on-failure stops at a failure with the browser as the failure left it and prints how to look at that very tab (navigera -s bt start --attach ws://…/devtools/page/…, then navigera -s bt ax); Enter goes on with the run. It runs one worker. With no terminal to press Enter in, it waits BITTI_PAUSE_S seconds (default 600, for an agent looking from elsewhere), and under CI (CI set) it doesn’t pause unless that is set.

  • Exit codes: 0 passed, 1 a scenario failed, 2 a file or argument is wrong, 3 the browser or the app server didn’t start.


Made from docs/running.md.