Developer docs
The Ariawalk CLI
Run your Ariawalk tests with the browser on your own machine. An AI agent tries each task the way a blind person would, with the NVDA or JAWS screen reader, and you get the same report as in the app. Because the browser runs where you are, it can test localhost, a staging site behind your VPN, a preview deployment or the build inside a CI job. The agent's decisions, the review and the report stay in Ariawalk.
On this page
Get started
You need Node.js 20.3 or later and an Ariawalk account with at least one test. Create an account if you don't have one yet, and add a test in the app.
npx ariawalk install # once: downloads the Chromium the CLI drives
npx ariawalk login # confirm a code in your browser
npx ariawalk tests # your tests and their ids
npx ariawalk run <testId> --base-url http://localhost:3000The run prints every step as it goes: the key the agent pressed and what the screen reader said. At the end you get the outcome, the score and a link to the full report. The run also shows live on its page in the app.
Prefer installing it? npm install --global ariawalk gives you an ariawalk command; every example on this page works with or without npx.
Log in
ariawalk login shows a short code and opens ariawalk.com/device. Check that the code matches, click Allow, and the CLI is logged in. Over SSH or in a container, add --no-browser and open the printed link on any device.
The CLI gets an API key named after your computer (CLI · your-laptop) for one organization. If you're in several, it asks which one, or pass --org "Team name". The key appears under API and MCP in the app, where you can revoke it.
npx ariawalk whoami # who you're logged in as, and where
npx ariawalk logout # revokes this computer's key and forgets itIn CI, don't log in: create a key with Read and run access under API and MCP and set it as ARIAWALK_API_KEY. The login is saved in ~/.config/ariawalk/config.json, readable only by you.
Run tests
Pick what to run
npx ariawalk run # a checklist of your tests to pick from
npx ariawalk run <testId> # one test
npx ariawalk run <testId> <testId> # several, one after another
npx ariawalk run --app "My shop" # every test of an applicationIn the checklist, type numbers to tick tests (2 4-6), a for all, Enter to run, or q to quit. It's plain lines rather than a menu that redraws itself, so it works with screen readers and over SSH. ariawalk tests lists your tests with their ids and latest results (--json for scripts).
Point it at your site
--base-url runs the test on another origin and keeps the test's path: a test starting at https://shop.example.com/checkout with --base-url http://localhost:3000 starts at http://localhost:3000/checkout. Without it, the test uses its own start URL.
Local runs can test any address your machine reaches: localhost and private hosts (127.0.0.1, 192.168.x.x, 10.x.x.x, *.local, *.internal and single-word intranet names) as well as public sites, like a preview deployment.
Test data and secrets
Ariawalk never sends secret test data (passwords, card numbers) to the CLI. Give their values on your machine, as an option or an environment variable named after the key:
npx ariawalk run <testId> --data password=hunter2
ARIAWALK_DATA_PASSWORD=hunter2 npx ariawalk run <testId>If a secret is missing, the CLI says which before it starts, so no run is used up. The agent itself only ever sees {{password}}, and secret values are masked in everything uploaded.
Watch, stop and read
--headedshows the browser,--slow-mo 250slows every action down and--verboseprints every key press, finding and reason.- Ctrl+C stops after the current step (twice quits at once). Stop run on the run's page in the app stops the CLI too.
npx ariawalk report <runId or report URL>prints a run's full report as Markdown: findings with WCAG criteria and fixes, and what the screen reader said.
Environments and baselines
Every run belongs to an environment, and comparisons stay within it. Runs from your machine go to your own local environment, runs in CI to ci:<branch>, and runs started in the app or by a schedule to production. So a half-finished change on your laptop never becomes the baseline for production, and two developers testing localhost never mix up each other's results.
A run is compared with the last finished run of the same test in its environment (its baseline). A new CI branch starts from the default branch's latest CI run. A test's page in the app has an environment filter for its history.
CI
The CLI runs on the CI runner, so it can test whatever the runner can reach: a preview deployment, the build you start inside the job, or staging through a VPN. It reads branch, commit and pull request from GitHub Actions, GitLab CI and Buildkite automatically.
Pass or fail
| Option | What it does |
|---|---|
| --fail-on blocked | The default: fail when the agent couldn't finish the task (blocked or inconclusive). |
| --fail-on regression | Fail when a test got worse than its baseline. |
| --fail-on new-serious | Fail on serious or blocker issues that are new since the baseline (a first run has nothing to compare with, so it doesn't fail on this). |
| --fail-on none | Don't fail on outcomes; use with --min-score. |
| --min-score 80 | Fail when a test's overall score is lower. |
Combine checks with commas: --fail-on blocked,regression. Exit codes: 0 everything passed, 1 an accessibility check failed, 2 a run couldn't finish (setup, quota, network, stopped). A broken run never counts as an accessibility failure, and the other way around.
Results
--junit ariawalk.xml for test reporters, --markdown summary.md and --json-file results.json. On GitHub Actions a summary with every test, its score and why failing ones failed is added to the job's page automatically (--no-summary turns that off). --concurrency 3 runs three tests at once.
GitHub Actions
The Ariawalk action installs the CLI, caches Chromium, runs your tests and keeps one comment with the results on the pull request:
permissions:
contents: read
pull-requests: write # for the results comment
steps:
- uses: AndreHogberg/ariawalk-action@v1
with:
api-key: ${{ secrets.ARIAWALK_API_KEY }}
app: My shop
base-url: ${{ steps.deploy.outputs.url }}
fail-on: blocked,regression
data: |
password=${{ secrets.STAGING_PASSWORD }}It takes the same choices as the CLI (tests, app, base-url, fail-on, min-score, concurrency, junit) and sets the exit-code output. Without the action, run the CLI yourself:
- run: npx ariawalk install --with-deps
- run: npx ariawalk run --app "My shop" --base-url ${{ steps.deploy.outputs.url }} --fail-on blocked,regression
env:
ARIAWALK_API_KEY: ${{ secrets.ARIAWALK_API_KEY }}
ARIAWALK_DATA_PASSWORD: ${{ secrets.STAGING_PASSWORD }}GitLab CI and other containers
The image ghcr.io/andrehogberg/ariawalk has the CLI with Chromium and its system libraries preinstalled, for CI systems that run jobs in containers (GitLab, Jenkins, Buildkite, self-hosted runners). Tags follow the CLI's versions, plus latest.
accessibility:
image: ghcr.io/andrehogberg/ariawalk:latest
script:
- ariawalk run --app "My shop" --base-url "$PREVIEW_URL" --junit ariawalk.xml
artifacts:
reports:
junit: ariawalk.xmldocker run --rm -e ARIAWALK_API_KEY ghcr.io/andrehogberg/ariawalk \
ariawalk run --app "My shop" --base-url https://preview.example.comOther setups
- The build inside the job: start it first (
npm run build && npm start &), then use--base-url http://localhost:3000. - Behind a VPN: use a self-hosted runner inside the network, or a VPN step (WireGuard, Tailscale) before the run.
- Fresh Linux machines need Chromium's system libraries:
ariawalk install --with-depsinstalls both.
Coding agents (MCP)
ariawalk mcp is a local MCP server for coding agents like Claude Code and Cursor. Its browser runs on your machine, so an agent can change your code, run the test against the dev server, read what blocked a screen reader user and fix it. (Ariawalk's hosted MCP server at ariawalk.com/mcp can't reach localhost.)
npx ariawalk login # once
claude mcp add ariawalk -- npx -y ariawalk mcpFor other clients, add it to their MCP configuration:
{
"mcpServers": {
"ariawalk": {
"command": "npx",
"args": ["-y", "ariawalk", "mcp"],
"env": { "ARIAWALK_DATA_PASSWORD": "…" }
}
}
}Its tools: list_tests, run_locally (tests or a whole application against a base URL; returns pass or fail and each full report), get_report, compare_runs and whoami. Secret test data goes in the server's environment, never through the agent.
Agents that run shell commands can use the CLI directly instead: npx ariawalk skills install adds a skill (.claude/skills/ariawalk/SKILL.md, or in your home folder with --global) that teaches them how.
Command reference
| Option | What it does |
|---|---|
| ariawalk install | Downloads the Chromium the CLI drives. --with-deps also installs its system libraries (Linux, CI); --only-shell skips the full browser (no --headed). |
| ariawalk login | Logs in with your browser. --org, --no-browser, or --key aw_… to use an existing key. |
| ariawalk whoami | Who you're logged in as, and in which organization. |
| ariawalk logout | Revokes this computer's key and forgets it. |
| ariawalk tests | Your tests with ids and latest results. --app to filter, --json for scripts. Also ariawalk run list. |
| ariawalk run | Runs tests: ids, --app, or a checklist without either. Options below. |
| ariawalk report | A run's full report as Markdown, by run id or report URL. |
| ariawalk mcp | The local MCP server for coding agents (stdio). |
| ariawalk skills install | Adds the agent skill to this project (--global: for every project). |
| Option | What it does |
|---|---|
| --base-url <url> | Run on this origin, keeping the test's path. |
| --app <name|id> | Every test of an application. |
| --data <key=value> | A test data value, e.g. a secret (repeatable). Or ARIAWALK_DATA_<KEY>. |
| --concurrency <n> | Tests at once, each in its own browser (1-10, default 1). |
| --fail-on <check> | blocked (default), regression, new-serious or none; comma-separated or repeated. |
| --min-score <0-100> | Fail tests scoring lower. |
| --junit <file> | JUnit XML results. |
| --markdown <file> | A Markdown summary. |
| --json-file <file> | Results as JSON. |
| --no-summary | No summary in $GITHUB_STEP_SUMMARY. |
| --no-screenshots | Keep screenshots on this machine. |
| --no-ci | Don't read CI metadata: the run counts as a local run. |
| --headed | Show the browser. |
| --slow-mo <ms> | Slow down every browser action. |
| --verbose | Every key press, finding and reason. |
| --api-url <url> | Another Ariawalk instance (or ARIAWALK_API_URL). |
What leaves your machine
The browser runs locally, but the agent's decisions and your report live in Ariawalk, so some of each run is uploaded:
- What the screen reader said at each step, and the decision taken: the agent decides from this alone.
- Findings, scores and the text of each page (its accessibility tree), for the report and the AI review.
- A screenshot per page view, unless you pass
--no-screenshots.
Secret test data never leaves your machine unmasked. Every run counts toward your organization's monthly runs, like runs started in the app.
Troubleshooting
- “Chromium is not installed yet”: run
npx ariawalk install(on Linux CI,--with-deps). - “This test needs secret values Ariawalk never sends”: pass them with
--dataorARIAWALK_DATA_<KEY>. - “The CLI stopped checking in”: the run was interrupted because the CLI was closed or lost its connection for two minutes. Its steps so far are kept; run it again.
- Usage used up: the run exits with code 2: nothing starts, or a run in progress stops with its steps kept. Buy credits or turn on paid usage on the billing page, upgrade your plan, or wait for next month.
- Logging in over SSH: use
ariawalk login --no-browserand open the link on any device.
Something else? The API docs describe the endpoints the CLI uses.