2026 OpenClaw Frontend Practice:
Parse axe-core Accessibility JSON on a Remote Mac → PR-Readable Summaries (HowTo)
Accessibility regressions are easier to prevent than to explain in chat threads. This HowTo chains axe-core JSON from your CI job on a rented remote Mac, a tiny normalization step, and OpenClaw so reviewers see a compact markdown block inside the pull request—without pasting vendor dashboards or other URLs that only work when someone is already logged in. Pair it with the broader pre-deploy quality narrative in Lighthouse, links, and baseline a11y on remote Mac and the same PR-comment discipline as visual regression diff → PR summary when you unify automation commentary.
01 How to run axe-core and capture JSON output
axe-core is an engine, not a single CLI. In 2026 the durable pattern is to run it where your UI already boots: Playwright or Cypress test steps that call injectAxe() and checkA11y(), or a headless script that loads each preview URL and writes results with @axe-core/cli. On a shared remote Mac, pin Chromium or WebKit versions next to Node so yesterday’s run matches today’s CI container.
Always persist machine-readable JSON, not screenshots of DevTools. Configure your runner to emit either the default axe results object or a merged array of results per URL. Store files under a deterministic path such as .openclaw/reports/$GIT_SHA/a11y/ with names like raw_home.json, raw_checkout.json, plus a small manifest.json listing base URL, commit, browser build string, and axe-core version. gzip the raw payload if your reports grow large; keep the uncompressed normalized file beside it for agents.
CI should treat accessibility like any other gate: exit non-zero when policy is breached, but still upload artifacts so OpenClaw can summarize failures for humans. If you run axe only after deploy, trigger the same job from a preview deployment step so the JSON always references a stable HTTPS origin.
- Parallel routes: Shard by path prefix on busy sites; merge JSON in a final step with deterministic sort keys.
- Timeouts: Set per-page budgets so a hung third-party iframe does not stall the entire Mac worker.
02 OpenClaw parsing rules template
OpenClaw should never scrape your Git host’s HTML. Give it read access to the repo and the report directory, then describe a rigid template in plain language: “Read a11y_normalized.json; output pr_a11y_summary.md with the sections below.” The template should force separation between facts copied from JSON (rule ids, counts, selectors) and suggested fixes labeled as hypotheses.
A practical section order is: Executive counts (serious, moderate, minor), Top rules sorted by impact then frequency, Representative nodes (at most three examples per rule with truncated HTML), WCAG mapping when present in the payload, Retest commands (the exact npm script or Playwright tag), and Waivers (empty unless your policy adds ticket ids). Check in the template beside other OpenClaw tasks so reviewers can diff prompt changes like code.
For consistency with other gates, mirror the threshold language you already use for performance or bundle size. The bundle analyzer threshold PR summary playbook shows how to keep numeric policy next to the markdown generator so teams do not argue about numbers in the comment thread.
03 Summary fields and thresholds
Your normalized JSON should expose fields OpenClaw (and shell scripts) can aggregate without re-parsing axe internals: ruleId, impact, wcagRefs, helpUrl (public documentation only), failureSummary, targetSelectors, url, and fingerprint (hash of rule plus selector array). Drop full page HTML; keep snippets under four kilobytes each to avoid leaking PII into PR comments.
| Policy tier | Example threshold | CI behavior |
|---|---|---|
| Serious | Count = 0 | Fail job; include full rule list in OpenClaw markdown. |
| Moderate | Count ≤ team budget (e.g. 3) | Warn or fail depending on release phase; require ticket references for waivers. |
| Minor / review | Report only | Do not block merge; still list top five in the PR summary for visibility. |
| Inapplicable / passes | N/A | Omit from PR body unless auditing coverage; mention scanned URL count instead. |
Version the threshold table in Git next to your workflow YAML. When product policy changes, bump a schemaVersion field inside a11y_normalized.json so old comments are obviously stale.
04 Posting summaries back through your Git provider
Describe the handoff to security reviewers as REST APIs plus repository-scoped credentials, not “open this browser tab.” For GitHub, create a fine-grained personal access token or a GitHub App installation token limited to one repository and the pull requests: write permission. For GitLab, use a project access token with api on that project only. Document the sequence: authenticate with Authorization: Bearer or PRIVATE-TOKEN, locate the merge request or pull request id from environment variables your CI already exports, then create or update a single comment that contains the markdown OpenClaw wrote.
Avoid embedding links that assume an interactive session. If you must reference documentation, use stable public helpUrl values from axe or WCAG quick reference pages. Never paste links to internal analytics or review UIs that redirect through SSO. When your policy forbids direct API access from the Mac worker, POST the same markdown to an internal automation webhook that already holds credentials; the webhook becomes the only component that talks to Git.
Idempotency: Prefix the comment body with an HTML marker such as <!-- openclaw-a11y:$SHA -->. On reruns, search existing PR comments for that marker, then update in place instead of spamming duplicates. Retries: Apply exponential backoff with jitter for HTTP 429, 500, and 502 responses, capped at five attempts, and log only token fingerprints—not secrets.
05 Troubleshooting FAQ
Empty violations but the page is clearly broken. axe only sees the DOM your test loads. Confirm you are not checking a skeleton shell before data fetch completes, and that shadow roots are open if your components rely on them. Increase waits or assert on network idle before running axe.
Flaky counts between runs. Ads, consent banners, and session timers change the DOM. Freeze clock and locale in Playwright, block third-party hosts where policy allows, or snapshot cookies that dismiss banners before the scan.
OpenClaw invents selectors that do not exist. Tighten the template: “Selectors must be copied verbatim from targetSelectors; do not invent new paths.” Provide a JSON schema for the normalized file and validate it in CI before the agent runs.
403 or 401 from the Git API. Token scopes are wrong, or the bot account cannot see the fork workflow. For GitHub Actions from forks, use pull_request_target carefully or post from a trusted internal service instead of untrusted code.
Comment body too large. Truncate examples per rule, link to the archived JSON artifact path inside your CI system, and keep the PR text under the provider’s limit by summarizing top rules only.
Run axe-core where your app already executes, write JSON and a manifest under .openclaw/reports/$SHA/a11y/, normalize violations once, apply a strict OpenClaw markdown template, enforce serious and moderate thresholds in CI, and post back through least-privilege Git APIs with idempotent markers and retries. Rent Apple Silicon through MacWww when you need the same WebKit-adjacent environment for both scans and manual verification.
Run axe-core, OpenClaw, and PR summaries on a remote Mac
Open the homepage, compare pricing, or use Buy / Rent without a forced login. Questions live in the Help Center. For more frontend automation runbooks, see Playwright E2E auto-fix, E2E log triage, and the blog index.