Setting Up Lighthouse CI Thresholds for WCAG 2.2 AA
Pipeline failures frequently occur when Lighthouse CI score thresholds conflict with actual WCAG 2.2 AA compliance. Misconfigured assertions trigger false negatives on valid pages, stalling deployments and wasting engineering cycles. This guide provides exact lhci.json assertion mapping, DOM-state validation steps, and false-positive mitigation strategies. For foundational context on audit selection and tool alignment, review Web Accessibility Testing Fundamentals & Tool Selection before adjusting pipeline gates.
Root Cause: Threshold Misalignment & Audit ID Mapping
Lighthouse evaluates accessibility through heuristic scoring, not direct WCAG conformance checks. This architectural gap causes CI pipelines to fail even when manual audits confirm compliance.
- WCAG 2.2 AA introduces updated success criteria, including Focus Not Obscured (2.4.11) and Target Size (Minimum) (2.5.8). Lighthouse audits approximate these via DOM inspection.
- Default
lhciconfigurations often enforce>=0.90across all categories. This blanket threshold triggers false negatives on heuristic-heavy audits. - Audits returning
scoreDisplayMode: "manual"default to a score of0. Without explicit pipeline handling, they immediately block builds.
Diagnose failures by inspecting the raw Lighthouse JSON output. Cross-reference failing audit IDs against your actual DOM state before adjusting thresholds.
Exact Configuration Adjustment: lhci.json Assertions
Enforce WCAG 2.2 AA compliance by defining granular thresholds in the assertions object. Avoid global category gates that penalize heuristic variance.
{
"ci": {
"collect": {
"settings": {
"preset": "desktop",
"onlyCategories": ["accessibility"]
}
},
"assert": {
"assertions": {
"categories:accessibility": ["error", { "minScore": 0.95 }],
"target-size": ["warn", { "minScore": 0.80 }],
"focus-order": ["error", { "minScore": 1.0 }],
"color-contrast": ["error", { "minScore": 1.0 }]
}
}
}
}
This configuration sets strict error gating for deterministic criteria like focus order and color contrast. It downgrades heuristic-heavy audits like target-size to warn, preventing pipeline paralysis on edge cases. To prevent threshold drift across sprints, align your persistent baseline storage with Lighthouse CI Baseline Configuration.
Validation & False-Positive Resolution
Validate threshold accuracy against staging environments before merging to main. Run targeted collections to isolate scanner artifacts.
- Execute
lhci autorun --collect.urlagainst your staging environment to capture live DOM states. - Inspect the generated report. Differentiate between
score: 0(actual failure) andscoreDisplayMode: "manual"(requires human review). - Filter out
manualaudits from CI gating. Route them to issue trackers for manual validation. - Enforce
--preset=desktopin collection settings. Mobile viewport scaling artificially inflatestarget-sizefailures due to touch-area calculations.
If audits consistently fail despite valid markup, verify that ARIA attributes are injected before the load event fires.
Pipeline Impact & Gating Strategy
Integrate thresholds into your CI workflow without causing build paralysis. Implement tiered gating to balance velocity and compliance.
- Apply
warnthresholds on feature branches. Reserveerrorgating formainand release branches. - Cache baseline reports in your CI runner. This prevents flaky failures caused by transient network latency or third-party script injection.
- Configure the
uploadstep with--githubTokento surface PR annotations directly in the diff. - Monitor
target-sizeandfocus-orderfor dynamic DOM injection delays. Increase load timeouts if SPAs hydrate after initial paint.
- name: Run Lighthouse CI
run: |
npx lhci autorun \
--collect.url=https://staging.your-domain.com \
--collect.settings.maxWaitForLoad=15000 \
--collect.settings.emulatedFormFactor=desktop
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
The extended maxWaitForLoad parameter ensures dynamically injected ARIA attributes and focus traps are captured before scoring begins.
Common Pitfalls
- Setting global
>=1.0thresholds causes unavoidable failures on heuristic audits. - Ignoring
scoreDisplayMode: "manual"audits, which default to0and trigger immediate false negatives. - Failing to account for dynamic content injection delays, causing
focus-orderscanner misses. - Overriding
target-sizethresholds without verifying actual touch target bounding boxes in the computed DOM.
FAQ
How do I map Lighthouse audit IDs to specific WCAG 2.2 AA success criteria?
Cross-reference Lighthouse’s audits directory with the WCAG 2.2 AA mapping matrix. Use categories:accessibility for broad gating, then override specific IDs like color-contrast (SC 1.4.3) or target-size (SC 2.5.8) with granular minScore values.
Why does Lighthouse CI fail on target-size despite passing manual WCAG checks?
Lighthouse calculates target size from the computed CSSOM, excluding pseudo-elements or dynamically injected touch areas. Set the assertion to warn or off and validate manually, or adjust --collect.settings.throttlingMethod to provided.
How do I prevent threshold flakiness from dynamic DOM updates?
Increase maxWaitForLoad in lhci.json, implement --collect.settings.extraHeaders for auth bypass, and use --collect.settings.onlyAudits to isolate stable DOM states. Cache baselines to ignore transient layout shifts.