initial wcag-ada
This commit is contained in:
parent
042b8cb83a
commit
d52cfe7de2
112 changed files with 9069 additions and 0 deletions
162
apps/wcag-ada/scanner/README.md
Normal file
162
apps/wcag-ada/scanner/README.md
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
# WCAG-ADA Accessibility Scanner
|
||||
|
||||
A high-performance accessibility scanner built with Playwright and axe-core for WCAG compliance testing.
|
||||
|
||||
## Features
|
||||
|
||||
- 🚀 Fast scanning with Playwright
|
||||
- ♿ WCAG 2.0, 2.1, and 2.2 compliance testing
|
||||
- 📊 Detailed violation reports with fix suggestions
|
||||
- 📸 Screenshot capture for violations
|
||||
- 🔐 Authentication support (basic, form-based, custom)
|
||||
- 📱 Mobile and desktop viewport testing
|
||||
- 🎯 Custom rule support
|
||||
- 🚫 Resource blocking for faster scans
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Example
|
||||
|
||||
```typescript
|
||||
import { AccessibilityScanner } from '@wcag-ada/scanner';
|
||||
|
||||
const scanner = new AccessibilityScanner();
|
||||
await scanner.initialize();
|
||||
|
||||
const result = await scanner.scan({
|
||||
url: 'https://example.com',
|
||||
wcagLevel: {
|
||||
level: 'AA',
|
||||
version: '2.1'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Compliance Score: ${result.summary.score}%`);
|
||||
console.log(`Violations Found: ${result.summary.violationCount}`);
|
||||
|
||||
await scanner.close();
|
||||
```
|
||||
|
||||
### Advanced Options
|
||||
|
||||
```typescript
|
||||
const result = await scanner.scan({
|
||||
url: 'https://example.com',
|
||||
wcagLevel: {
|
||||
level: 'AA',
|
||||
version: '2.1'
|
||||
},
|
||||
includeScreenshots: true,
|
||||
viewport: {
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
isMobile: false
|
||||
},
|
||||
authenticate: {
|
||||
type: 'form',
|
||||
loginUrl: 'https://example.com/login',
|
||||
credentials: {
|
||||
username: 'user@example.com',
|
||||
password: 'password'
|
||||
},
|
||||
selectors: {
|
||||
username: '#email',
|
||||
password: '#password',
|
||||
submit: 'button[type="submit"]'
|
||||
}
|
||||
},
|
||||
excludeSelectors: [
|
||||
'.cookie-banner',
|
||||
'[aria-hidden="true"]'
|
||||
],
|
||||
waitForSelector: '#main-content',
|
||||
timeout: 60000
|
||||
});
|
||||
```
|
||||
|
||||
### Scan Multiple Pages
|
||||
|
||||
```typescript
|
||||
const urls = [
|
||||
'https://example.com',
|
||||
'https://example.com/about',
|
||||
'https://example.com/contact'
|
||||
];
|
||||
|
||||
const results = await scanner.scanMultiplePages(urls, {
|
||||
wcagLevel: { level: 'AA', version: '2.1' }
|
||||
});
|
||||
```
|
||||
|
||||
## Scan Results
|
||||
|
||||
The scanner returns a comprehensive `AccessibilityScanResult` object containing:
|
||||
|
||||
- **Summary**: Overall compliance score, violation counts by severity
|
||||
- **Violations**: Detailed list of accessibility issues with:
|
||||
- Impact level (critical, serious, moderate, minor)
|
||||
- Affected elements with HTML snippets
|
||||
- Fix suggestions
|
||||
- WCAG criteria mapping
|
||||
- Screenshots (if enabled)
|
||||
- **Passes**: Rules that passed
|
||||
- **Incomplete**: Rules that need manual review
|
||||
- **Page Metadata**: Title, language, element counts, landmark presence
|
||||
- **WCAG Compliance**: Level-specific compliance status
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
The scanner is optimized for speed:
|
||||
- Blocks unnecessary resources (images, fonts, analytics)
|
||||
- Parallel page scanning support
|
||||
- Configurable timeouts
|
||||
- Headless browser mode
|
||||
|
||||
## Custom Rules
|
||||
|
||||
Add custom accessibility rules:
|
||||
|
||||
```typescript
|
||||
const customRules = [{
|
||||
id: 'custom-button-size',
|
||||
selector: 'button',
|
||||
tags: ['custom', 'wcag21aa'],
|
||||
description: 'Buttons must have minimum touch target size',
|
||||
help: 'Ensure buttons are at least 44x44 pixels',
|
||||
severity: 'serious',
|
||||
validator: (element) => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
return rect.width >= 44 && rect.height >= 44;
|
||||
}
|
||||
}];
|
||||
|
||||
const result = await scanner.scan({
|
||||
url: 'https://example.com',
|
||||
customRules
|
||||
});
|
||||
```
|
||||
|
||||
## Running the Example
|
||||
|
||||
```bash
|
||||
bun run src/example.ts
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Build
|
||||
bun run build
|
||||
|
||||
# Watch mode
|
||||
bun run dev
|
||||
|
||||
# Type checking
|
||||
bun run typecheck
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue