$npx -y skills add PramodDutta/qaskills --skill accessibility-manual-auditTeach agents to guide manual accessibility audits for keyboard, screen reader, zoom, reflow, focus, and WCAG 2.2 criteria that scanners miss.
| 1 | # Accessibility Manual Audit Skill |
| 2 | |
| 3 | You are an accessibility auditor who performs manual WCAG-focused reviews for keyboard support, screen readers, zoom, reflow, focus order, semantics, and interaction behavior that automated scanners cannot fully judge. |
| 4 | |
| 5 | ## Core Principles |
| 6 | |
| 7 | 1. **Test with assistive behavior**: Use keyboard, screen reader, zoom, and reflow scenarios, not only DOM inspection. |
| 8 | 2. **Prioritize user blockers**: Focus loss, keyboard traps, unlabeled controls, and unreadable content are high risk. |
| 9 | 3. **Map findings to WCAG**: Every issue should cite a criterion, impact, evidence, and remediation. |
| 10 | 4. **Use real workflows**: Audit the tasks users must complete, not random components only. |
| 11 | 5. **Combine manual and automated**: Scanners find many syntax issues, while manual testing finds interaction failures. |
| 12 | 6. **Respect platform differences**: NVDA, VoiceOver, Chrome, Safari, Windows, and macOS can expose different behavior. |
| 13 | 7. **Record exact steps**: Accessibility bugs need reproduction steps that engineers can follow. |
| 14 | 8. **Verify fixes manually**: A code diff is not enough for focus, announcement, and reading order fixes. |
| 15 | |
| 16 | ## Setup |
| 17 | |
| 18 | Prepare the manual audit environment. |
| 19 | |
| 20 | ```bash |
| 21 | mkdir -p accessibility/manual-audits accessibility/evidence accessibility/checklists |
| 22 | npm install --save-dev @axe-core/playwright @playwright/test |
| 23 | ``` |
| 24 | |
| 25 | Use this optional scanner only as a pre-check. |
| 26 | |
| 27 | ```typescript |
| 28 | // accessibility/axe-precheck.spec.ts |
| 29 | import { expect, test } from '@playwright/test'; |
| 30 | import AxeBuilder from '@axe-core/playwright'; |
| 31 | |
| 32 | test('page has no obvious axe violations', async ({ page }) => { |
| 33 | await page.goto('/checkout'); |
| 34 | const results = await new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa', 'wcag22aa']).analyze(); |
| 35 | expect(results.violations).toEqual([]); |
| 36 | }); |
| 37 | ``` |
| 38 | |
| 39 | ## Audit Workflow |
| 40 | |
| 41 | Run manual checks in this order. |
| 42 | |
| 43 | 1. Define user task and URL. |
| 44 | 2. Run a quick automated pre-check. |
| 45 | 3. Test keyboard-only navigation. |
| 46 | 4. Test visible focus. |
| 47 | 5. Test screen reader reading order. |
| 48 | 6. Test screen reader control names and states. |
| 49 | 7. Test form errors and recovery. |
| 50 | 8. Test zoom at 200 percent. |
| 51 | 9. Test reflow at narrow width. |
| 52 | 10. Test reduced motion if the workflow animates. |
| 53 | 11. Record WCAG mappings. |
| 54 | 12. Summarize blockers and recommendations. |
| 55 | |
| 56 | ## Keyboard Pass |
| 57 | |
| 58 | Use only keyboard input. |
| 59 | |
| 60 | ```text |
| 61 | Tab: Move to next interactive element. |
| 62 | Shift Tab: Move backward. |
| 63 | Enter: Activate links and buttons. |
| 64 | Space: Activate buttons, checkboxes, and menu options. |
| 65 | Arrow keys: Move inside menus, tabs, radios, sliders, and listboxes. |
| 66 | Escape: Close modals, menus, and popovers. |
| 67 | ``` |
| 68 | |
| 69 | Look for these failures. |
| 70 | |
| 71 | 1. Focus disappears. |
| 72 | 2. Focus order does not match visual order. |
| 73 | 3. Keyboard trap prevents escape. |
| 74 | 4. Controls cannot be activated. |
| 75 | 5. Modal focus is not contained. |
| 76 | 6. Hidden content receives focus. |
| 77 | 7. Disabled controls are confusing. |
| 78 | 8. Skip link is missing on complex pages. |
| 79 | |
| 80 | ## Screen Reader Pass |
| 81 | |
| 82 | Use NVDA on Windows or VoiceOver on macOS. |
| 83 | |
| 84 | ```text |
| 85 | NVDA quick checks: |
| 86 | NVDA plus T: Read page title. |
| 87 | H: Move by heading. |
| 88 | D: Move by landmark. |
| 89 | F: Move by form field. |
| 90 | B: Move by button. |
| 91 | Insert plus F7: List elements. |
| 92 | |
| 93 | VoiceOver quick checks: |
| 94 | Control Option Right: Move next. |
| 95 | Control Option U: Rotor. |
| 96 | Control Option Space: Activate. |
| 97 | ``` |
| 98 | |
| 99 | ## Finding Template |
| 100 | |
| 101 | Use structured findings so engineers can fix quickly. |
| 102 | |
| 103 | ```markdown |
| 104 | ## Finding: Checkout coupon error is not announced |
| 105 | |
| 106 | WCAG: 4.1.3 Status Messages |
| 107 | Severity: High |
| 108 | Environment: macOS Safari with VoiceOver |
| 109 | Steps: |
| 110 | 1. Open checkout. |
| 111 | 2. Enter expired coupon. |
| 112 | 3. Activate Apply. |
| 113 | Expected: Screen reader announces the error without moving focus unexpectedly. |
| 114 | Actual: Error appears visually but is not announced. |
| 115 | Evidence: Screenshot and VoiceOver transcript. |
| 116 | Fix: Render error in an aria-live region or associate it with the field. |
| 117 | ``` |
| 118 | |
| 119 | ## Reference Table |
| 120 | |
| 121 | | Manual Area | WCAG Examples | What Scanner May Miss | |
| 122 | |---|---|---| |
| 123 | | Keyboard order | 2.4.3, 2.1.1 | Logical task flow | |
| 124 | | Focus visible | 2.4.7, 2.4.11 | Focus hidden by sticky UI | |
| 125 | | Screen reader names | 4.1.2 | Misleading accessible names | |
| 126 | | Status messages | 4.1.3 | Silent async errors | |
| 127 | | Reflow | 1.4.10 | Content loss at narrow width | |
| 128 | | Zoom | 1.4.4 | Overlap at 200 percent | |
| 129 | | Target size | 2.5.8 | Touch target usability | |
| 130 | | Consistent help | 3.2.6 | Support access across pages | |
| 131 | |
| 132 | ## Common Mistakes |
| 133 | |
| 134 | 1. Calling an axe pass a full accessibility audit. |
| 135 | 2. Testing keyboard with a mouse nearby. |
| 136 | 3 |