@azanir/lexb
v0.1.0
Published
Explore an authenticated page (or a scenario) into verified Playwright locators + a test-case draft.
Maintainers
Readme
lexb
Explore an authenticated page — or a step-by-step scenario — into verified Playwright locators and a
test-case draft. Uses the Playwright library directly (no agent-browser / playwright-cli / jq / curl).
The cheap LLM only ever sees locators that were proven to resolve to exactly one element (count()===1),
so it can't hallucinate selectors.
Install
In a Playwright + TypeScript repo (peer: @playwright/test >= 1.49):
npm i -D @azanir/lexb # from npm (CLI command stays `lexb`)
# or git dependency: npm i -D github:AZANIR/lexb
npm i -D @playwright/test # peer (every PW+TS repo already has it)Commands
lexb <codename> <url> # explore -> verified locators + test-case (+ --emit-spec)
lexb scenario --file s.md # guided test from a human step list
lexb auth <loginUrl> # capture storageState (+ session tokens)explore
lexb dashboard https://app/dashboard --state .auth/auth-state.json --emit-spec→ documents/reports/spike-dashboard/: screenshot.png, aria.snapshot.txt, console.json,
errors.json, locators.md (verified getByRole, count===1), test-case.md (LLM draft),
dashboard.spec.ts (skeleton, with --emit-spec), lexb.json.
scenario
Write a step list (from a screenshot); lexb maps each step to a verified locator + action:
# Scenario: Upload a CV enables conversion
url: https://app/dashboard
## Steps
1. Upload "fixtures/cv.md" into the "File upload area"
2. Observe the "Convert to PDF" button
## Expected
- "Convert to PDF" becomes enabledlexb scenario --file scenario.md --name dashboard-upload --emit-specA step whose target isn't in the verified set becomes a // TODO, never an invented locator.
Starter: templates/scenario.example.md.
auth (cookies + localStorage + session tokens)
--state— storageState (cookies + localStorage).--tokens— optional{ entries, savedAt }injected into sessionStorage (--tokens-target localStorageto switch) viaaddInitScript, before navigation. For apps whose session tokens live in sessionStorage (whichstorageStatedoesn't capture).
lexb auth https://app/login --state .auth/auth-state.json --tokens .auth/auth-tokens.jsonOptions / env
| Flag | Env | Default |
|---|---|---|
| --state | LEXB_STATE | .auth/auth-state.json |
| --tokens | LEXB_TOKENS | .auth/auth-tokens.json if present |
| --tokens-target | LEXB_TOKENS_TARGET | sessionStorage |
| --model | LEXB_MODEL | openai/gpt-4o-mini |
| --key | LEXB_KEY | .auth/openrouter.key (OpenRouter key file) |
| --out | LEXB_OUT | documents/reports |
| --emit-spec, --headed, --url, --name | — | — |
The LLM "brain" uses OpenRouter — put your key in .auth/openrouter.key (gitignored).
Programmatic
import { explore, generateTestCase } from '@azanir/lexb';
const r = await explore({ url, state: '.auth/auth-state.json' });
// r.verified -> [{ role, name, count }] (count===1 = good)Local dev
npm install
npm run build # -> dist/
node dist/cli.js --helpLicense
MIT
