npx webqa-platform audit <url>Discovery and checks in one command, with a JSON and HTML report.
The webauditlabs CLI runs Chromium on your machine and writes structured findings with screenshots. No account, no API key. The same engine and result format power webauditlabs Cloud.
$ npx webqa-platform audit http://localhost:5173Unedited CLI output from the Nordhaus demo shop (Dutch, English, German) with five planted defects. Generated by website/scripts/capture-demo.mjs.
$ webqa run webqa.json --allow-private webqa issues found: 6 finding(s) on 6 page(s) warning http [all] /en/ 1 resource failed to load. warning clipping [all] /de/ The a "In den Warenkorb legen" does not fit; its text is cut off. warning overflow [mobile] /de/ 1 control sticks out of the viewport and is partly unreachable. error overflow [mobile] /de/ The page is 213px wider than the 390px viewport and scrolls sideways. warning links [all] /nl/contact.html 1 link on this "nl" page leads to locale "en". error lang [all] /en/products.html The page declares lang="nl" but belongs to locale "en". Evidence: .webqa/runs/2026-10-24T14-28-38-216Z
Evidence: /de/ · mobile 390pxFourteen rule-based checks (keyboard is opt-in) with stable identifiers (check/code). The same identifiers are used by the CLI, webauditlabs Cloud, the REST API and MCP.
| Area | Rules |
|---|---|
| Runtime and network | http/http_statushttp/resource_failedhttp/api_failedhttp/console_errorhttp/third_party_failed |
| Links | links/link_deadlinks/link_server_errorlinks/link_redirect_looplinks/link_redirectslinks/anchor_brokenlinks/link_emptylinks/link_wrong_locale |
| Locales and translations | lang/lang_missinglang/lang_mismatchlang/translation_missinglang/hreflang_wrong_localelang/hreflang_brokenlang/hreflang_redirectlang/hreflang_not_reciprocal |
| Layout | overflow/horizontal_overflowoverflow/control_offscreenclipping/text_clipped |
| Media | media/image_brokenmedia/image_not_loadedmedia/image_alt_missing |
| Content | content/placeholder_textcontent/template_leakcontent/heading_emptycontent/content_empty |
| Forms | forms/field_unlabeledforms/button_unnamedforms/link_button_no_hrefforms/form_insecure_actionforms/form_offsite_action |
| SEO | seo/title_missingseo/title_too_longseo/meta_description_missingseo/canonical_missingseo/canonical_offsiteseo/canonical_wrong_localeseo/heading_level_skippedseo/noindexseo/canonical_target_brokenseo/canonical_target_redirectsseo/structured_data_invalidseo/og_image_missingseo/og_image_brokenseo/robots_missingseo/robots_blocks_pageseo/robots_no_sitemapseo/soft_404seo/favicon_missingseo/sitemap_url_brokenseo/sitemap_url_redirectsseo/sitemap_url_noindexseo/sitemap_url_canonical_elsewhere |
| Accessibility | a11y/a11y_<axe rule> (serious and critical, axe-core) |
| Consistency | consistency/price_mismatchconsistency/date_expiredconsistency/duplicate_text |
| Privacy | privacy/tracker_before_consentprivacy/tracker_after_rejectprivacy/tracker_without_bannerprivacy/consent_no_reject |
| Security | security/mixed_contentsecurity/http_not_redirectedsecurity/tls_expiringsecurity/hsts_missingsecurity/security_headers_missing |
| Keyboard (off by default) | keyboard/focus_not_visiblekeyboard/focus_hidden_elementkeyboard/focus_trapkeyboard/skip_link_missing |
| Runtime and network | http/http_statushttp/resource_failedhttp/api_failedhttp/console_error |
| Links | links/link_deadlinks/link_server_errorlinks/link_redirect_looplinks/link_redirectslinks/anchor_brokenlinks/link_emptylinks/link_wrong_localelinks/contact_link_invalid |
| Locales and translations | lang/lang_missinglang/lang_mismatchlang/translation_missinglang/hreflang_wrong_localelang/hreflang_brokenlang/hreflang_redirectlang/hreflang_not_reciprocallang/untranslated_ui_text |
| Layout | overflow/horizontal_overflowoverflow/control_offscreenoverflow/element_overlapoverflow/text_too_smallclipping/text_clipped |
| Media | media/image_brokenmedia/image_not_loadedmedia/image_alt_missing |
| Content | content/placeholder_textcontent/template_leakcontent/heading_emptycontent/content_emptycontent/copyright_outdated |
| Forms | forms/field_unlabeledforms/button_unnamedforms/link_button_no_hrefforms/form_insecure_actionforms/form_offsite_actionforms/autocomplete_missingforms/input_type_mismatch |
| SEO | seo/title_missingseo/title_too_longseo/meta_description_missingseo/canonical_missingseo/canonical_offsiteseo/canonical_wrong_localeseo/heading_level_skippedseo/noindex |
| Accessibility | a11y/a11y_<axe rule> (serious and critical, axe-core) |
| Consistency | consistency/price_mismatchconsistency/date_expiredconsistency/duplicate_textconsistency/contact_mismatch |
| AI step (--ai, optional) | Untranslated text and plain-language explanations, marked for review |
npx webqa-platform audit <url>Discovery and checks in one command, with a JSON and HTML report.
webqa init <url>Detects language versions from hreflang, the language switcher or <html lang> and writes an editable webqa.json.
webqa run <spec | url>Captures pages at every configured viewport (desktop and mobile by default), runs the checks and writes result.json and screenshots to .webqa/runs/.
--jsonWrites result.json to stdout instead of the summary, for scripts and agents.
--checks a,bRuns only the checks you name, for example --checks links,seo.
--aiAdds the optional AI step: untranslated text and plain-language explanations, within a token budget.
--allow-privateAllows localhost and private network addresses, for local and staging sites.
--mode remote-cdpUses your own browser endpoint over the Chrome DevTools Protocol.
webqa mcpStarts the local MCP server for Claude Code, Cursor and other MCP clients.
webqa login · project link · --syncConnects to webauditlabs Cloud and uploads an existing local result.
local | Chromium on your machine. No account. | |
remote-cdp | Your own compatible browser endpoint. No account. | |
cloud | Managed browsers through the webauditlabs backend. Browser provider credentials never leave the backend. |
Each run writes a result file validated against the published v1 schema, a full-page screenshot per page and viewport, and an annotated copy for pages with findings. The same finding format is used by the cloud, the API and MCP.
.webqa/runs/2026-10-24T14-28-38-216Z/ ├── result.json # result.v1 ├── p03-desktop.png ├── p03-mobile.png ├── p03-mobile.annotated.png # problem elements outlined └── …
{
"id": "f4",
"check": "overflow",
"code": "horizontal_overflow",
"severity": "error",
"url": "http://127.0.0.1:8090/de/",
"locale": "de",
"viewport": "mobile",
"message": "The page is 213px wider than the 390px viewport and scrolls sideways.",
"provenance": "deterministic",
"evidence": {
"expected": "390px",
"actual": "603px",
"elements": [
{
"tag": "div",
"selector": "body > section.hero:nth-of-type(1) > div.wrap > div",
"rect": {
"x": 18,
"y": 599,
"width": 585,
"height": 415
},
"text": "HERBSTKOLLEKTION 2026 Handgemacht für jeden Tag Keramik, Leuchten und Textilien aus kleinen Werkstätten in Skandinavien "
},
{
"tag": "img",
"selector": "body > section.hero:nth-of-type(1) > div.wrap > img",
"rect": {
"x": 18,
"y": 132,
"width": 585,
"height": 439
}
}
]
}
}Agents need a deterministic way to check their work: run the audit, read structured findings, fix, and run again.
Versioned JSON with rule, severity, page, viewport, elements and screenshot path.
Exit code 0 means no findings remain; 1 means issues are still present.
webqa mcp over stdio for Claude Code, Cursor and other MCP clients. No account.
Cloud projects, runs and findings for agents and scripts, on every cloud plan.
{
"mcpServers": {
"webqa": { "command": "npx", "args": ["webqa-platform", "mcp"] }
}
}Optional. Sync uploads the result.json and screenshots of a run you already did to a linked cloud project. The run is stored with execution mode local.
webqa auditRuns locally in Chromium.
result.jsonFindings and screenshots on disk.
webqa audit --syncUploads the existing result.
webauditlabs CloudHistory, inbox and team access.
webqa init writes a webqa.json for version control: locales, pages or a sitemap with a page limit, viewports, checks and timeouts.
{
"version": 1,
"name": "www.example.nl",
"locales": [
{ "code": "nl", "url": "https://www.example.nl/nl/" },
{ "code": "de", "url": "https://www.example.nl/de/" }
],
"pages": { "sitemap": "https://www.example.nl/sitemap.xml", "maxPages": 50 },
"viewports": [{ "name": "mobile", "width": 390, "height": 844 }],
"checks": ["http", "lang", "overflow", "links", "clipping"],
"timeouts": { "pageMs": 30000, "runMs": 600000 }
}Exit codes distinguish site issues from tool and runtime errors.
| 0 | passed | No findings |
| 1 | issues_found | One or more findings |
| 2 | invalid input | Invalid configuration or arguments |
| 3 | execution_error | Tool or browser error, not a site issue |
| 4 | timed_out | Run exceeded its time limit |
Fail a build when findings appear and keep the run folder as a build artifact.
# .github/workflows/webqa.yml
- run: npx playwright install --with-deps chromium
- run: npx webqa-platform audit https://staging.example.com --json > webqa-result.json
- uses: actions/upload-artifact@v4
if: failure()
with:
name: webqa-evidence
path: .webqa/runs/