Automated accessibility testing for the Stellar Trust Escrow frontend using Playwright and @axe-core/playwright.
The accessibility scanner automatically checks all major pages of the application for WCAG Level AA violations. It runs as part of the CI/CD pipeline and can also be run locally during development.
-
Install dependencies:
npm ci cd frontend && npm ci
-
Build and start the frontend:
cd frontend npm run build npm run start:test
In a separate terminal:
cd frontend
npm run test:a11y:scanOr from the root directory:
node scripts/accessibility-scan.jsBASE_URL- Base URL of the application (default:http://localhost:3000)CI- Set totrueto enable stricter CI thresholds
Example:
BASE_URL=http://localhost:3000 npm run test:a11y:scanThe scanner checks the following pages:
- Landing Page (
/) - Dashboard (
/dashboard) - Explorer (
/explorer) - Create Escrow (
/escrow/create) - Profile (
/profile)
The scanner uses different thresholds for local development vs CI:
| Impact Level | Local Threshold | CI Threshold |
|---|---|---|
| Critical | 0 | 0 |
| Serious | 5 | 0 |
| Moderate | 10 | 5 |
| Minor | 20 | 10 |
CI mode is stricter to prevent accessibility regressions from being merged.
After each scan, an HTML report is generated in frontend/accessibility-reports/. The report includes:
- Summary of violations by severity
- Detailed information for each violation
- Affected HTML elements
- Links to remediation guidance
- WCAG criteria references
- Critical: Must be fixed immediately. Blocks basic functionality for users with disabilities.
- Serious: Significant barriers that should be fixed soon.
- Moderate: Noticeable issues that should be addressed.
- Minor: Small improvements that enhance accessibility.
The accessibility scanner runs automatically in the CI pipeline:
- Triggered on pushes and PRs to
developbranch - Only runs when frontend files change
- Fails the build if thresholds are exceeded
- Uploads HTML reports as artifacts
- Go to the GitHub Actions run
- Navigate to the "Accessibility (a11y)" job
- Download the
accessibility-reports-*artifact - Open the HTML file in a browser
Issue: Text doesn't have sufficient contrast with background.
Fix: Use colors that meet WCAG AA contrast ratios:
- Normal text: 4.5:1
- Large text (18pt+): 3:1
Issue: Images missing alt attributes.
Fix: Add descriptive alt text to all images:
<img src="logo.png" alt="Stellar Trust Escrow Logo" />Issue: Form inputs missing associated labels.
Fix: Use proper label associations:
<label htmlFor="email">Email</label>
<input id="email" type="email" />Issue: Interactive elements not keyboard accessible.
Fix: Ensure all interactive elements can be focused and activated via keyboard:
<button onClick={handleClick}>Click Me</button>
// Not: <div onClick={handleClick}>Click Me</div>Issue: Incorrect or missing ARIA attributes.
Fix: Use semantic HTML first, ARIA as enhancement:
// Good
<button>Submit</button>
// If custom component needed
<div role="button" tabIndex={0} aria-label="Submit">Submit</div>- Run locally before committing - Catch issues early
- Fix critical and serious violations immediately
- Use semantic HTML - Reduces need for ARIA
- Test with screen readers - Automated tools catch ~30-40% of issues
- Review HTML reports - Understand the context of violations
If the scanner times out waiting for pages to load:
-
Increase timeout in
accessibility-scan.js:timeout: 60000; // Increase from 30000
-
Check that the frontend server is running on the correct port
If you encounter false positives:
- Review the violation in the HTML report
- Verify it's actually a false positive (consult WCAG guidelines)
- If confirmed, consider adding an exception with documentation
Ensure the frontend builds successfully:
cd frontend
npm run build
npm run start:testCheck that port 3000 is not already in use:
lsof -i :3000When adding new pages:
- Add the page to
PAGES_TO_SCANinaccessibility-scan.js - Run the scanner locally to establish baseline
- Fix any violations before committing
- Update this README if needed
For questions or issues with the accessibility scanner:
- Check this README first
- Review the HTML report for specific guidance
- Consult the Axe documentation
- Open an issue with the
accessibilitylabel