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’sno_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.63The list covers frames too: a step with
--framekeeps it, andfixchanges 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 plainbitti fixlists 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 anoptional clickthatfixputs before the step. A.featurestep is left alone: change itsstepblock 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 workthen writes what that session did as a scenario: each action once, and the waits between (reads andevalleft 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’slocate, each checked on the page; inside a web component’s shadow root, CSS through its hosts:--selector "#tip >>> button"),basefrom the firstgoto, anexpect urlwhere an action moved the page, anexpect textfor 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’slocatesays) 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 plainnavigeraworks too when that navigera hashistory. -
bitti record <url> --out t.btopens 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 samelocateasfrom-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), anexpect urlwhere 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 eachleft 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.--headlessand--for <s>work as forrecord. A.featureis refused (its steps live in itsstepblocks). -
bitti mcpis 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) besidebitti_from_session(what those tools did, as a scenario;outwrites it),bitti_run,bitti_list,bitti_lint,bitti_failure(the last run’s failures with the nearest elements) andbitti_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 filesargsnames) stays inside the working directory, as navigera’s own tools’ files do, andargscan’t name a--chromiumto start;NAVIGERA_MCP_ALLOW_FILES=1lifts both. A project’s own.btfiles still do what they say (exec,[server]). -
--pause-on-failurestops 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/…, thennavigera -s bt ax); Enter goes on with the run. It runs one worker. With no terminal to press Enter in, it waitsBITTI_PAUSE_Sseconds (default 600, for an agent looking from elsewhere), and under CI (CIset) 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.