Claude Agent Skill · by Wshobson

Screen Reader Testing

You know how accessibility testing often stops at automated tools and basic keyboard navigation? This skill gets you actually testing with real screen readers l

Install
Terminal · npx
$npx skills add https://github.com/wshobson/agents --skill screen-reader-testing
Works with Paperclip

How Screen Reader Testing fits into a Paperclip company.

Screen Reader Testing drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.

S
SaaS FactoryPaired

Pre-configured AI company — 18 agents, 18 skills, one-time purchase.

$27$59
Explore pack
Source file
SKILL.md538 lines
Expand
---name: screen-reader-testingdescription: Test web applications with screen readers including VoiceOver, NVDA, and JAWS. Use when validating screen reader compatibility, debugging accessibility issues, or ensuring assistive technology support.--- # Screen Reader Testing Practical guide to testing web applications with screen readers for comprehensive accessibility validation. ## When to Use This Skill - Validating screen reader compatibility- Testing ARIA implementations- Debugging assistive technology issues- Verifying form accessibility- Testing dynamic content announcements- Ensuring navigation accessibility ## Core Concepts ### 1. Major Screen Readers | Screen Reader | Platform  | Browser        | Usage || ------------- | --------- | -------------- | ----- || **VoiceOver** | macOS/iOS | Safari         | ~15%  || **NVDA**      | Windows   | Firefox/Chrome | ~31%  || **JAWS**      | Windows   | Chrome/IE      | ~40%  || **TalkBack**  | Android   | Chrome         | ~10%  || **Narrator**  | Windows   | Edge           | ~4%   | ### 2. Testing Priority ```Minimum Coverage:1. NVDA + Firefox (Windows)2. VoiceOver + Safari (macOS)3. VoiceOver + Safari (iOS) Comprehensive Coverage:+ JAWS + Chrome (Windows)+ TalkBack + Chrome (Android)+ Narrator + Edge (Windows)``` ### 3. Screen Reader Modes | Mode               | Purpose                | When Used         || ------------------ | ---------------------- | ----------------- || **Browse/Virtual** | Read content           | Default reading   || **Focus/Forms**    | Interact with controls | Filling forms     || **Application**    | Custom widgets         | ARIA applications | ## VoiceOver (macOS) ### Setup ```Enable: System Preferences → Accessibility → VoiceOverToggle: Cmd + F5Quick Toggle: Triple-press Touch ID``` ### Essential Commands ```Navigation:VO = Ctrl + Option (VoiceOver modifier) VO + Right Arrow   Next elementVO + Left Arrow    Previous elementVO + Shift + Down  Enter groupVO + Shift + Up    Exit group Reading:VO + A             Read all from cursorCtrl               Stop speakingVO + B             Read current paragraph Interaction:VO + Space         Activate elementVO + Shift + M     Open menuTab                Next focusable elementShift + Tab        Previous focusable element Rotor (VO + U):Navigate by: Headings, Links, Forms, LandmarksLeft/Right Arrow   Change rotor categoryUp/Down Arrow      Navigate within categoryEnter              Go to item Web Specific:VO + Cmd + H       Next headingVO + Cmd + J       Next form controlVO + Cmd + L       Next linkVO + Cmd + T       Next table``` ### Testing Checklist ```markdown## VoiceOver Testing Checklist ### Page Load - [ ] Page title announced- [ ] Main landmark found- [ ] Skip link works ### Navigation - [ ] All headings discoverable via rotor- [ ] Heading levels logical (H1 → H2 → H3)- [ ] Landmarks properly labeled- [ ] Skip links functional ### Links & Buttons - [ ] Link purpose clear- [ ] Button actions described- [ ] New window/tab announced ### Forms - [ ] All labels read with inputs- [ ] Required fields announced- [ ] Error messages read- [ ] Instructions available- [ ] Focus moves to errors ### Dynamic Content - [ ] Alerts announced immediately- [ ] Loading states communicated- [ ] Content updates announced- [ ] Modals trap focus correctly ### Tables - [ ] Headers associated with cells- [ ] Table navigation works- [ ] Complex tables have captions``` ### Common Issues & Fixes ```html<!-- Issue: Button not announcing purpose --><button><svg>...</svg></button> <!-- Fix --><button aria-label="Close dialog"><svg aria-hidden="true">...</svg></button> <!-- Issue: Dynamic content not announced --><div id="results">New results loaded</div> <!-- Fix --><div id="results" role="status" aria-live="polite">New results loaded</div> <!-- Issue: Form error not read --><input type="email" /><span class="error">Invalid email</span> <!-- Fix --><input type="email" aria-invalid="true" aria-describedby="email-error" /><span id="email-error" role="alert">Invalid email</span>``` ## NVDA (Windows) ### Setup ```Download: nvaccess.orgStart: Ctrl + Alt + NStop: Insert + Q``` ### Essential Commands ```Navigation:Insert = NVDA modifier Down Arrow         Next lineUp Arrow           Previous lineTab                Next focusableShift + Tab        Previous focusable Reading:NVDA + Down Arrow  Say allCtrl               Stop speechNVDA + Up Arrow    Current line Headings:H                  Next headingShift + H          Previous heading1-6                Heading level 1-6 Forms:F                  Next form fieldB                  Next buttonE                  Next edit fieldX                  Next checkboxC                  Next combo box Links:K                  Next linkU                  Next unvisited linkV                  Next visited link Landmarks:D                  Next landmarkShift + D          Previous landmark Tables:T                  Next tableCtrl + Alt + Arrows Navigate cells Elements List (NVDA + F7):Shows all links, headings, form fields, landmarks``` ### Browse vs Focus Mode ```NVDA automatically switches modes:- Browse Mode: Arrow keys navigate content- Focus Mode: Arrow keys control interactive elements Manual switch: NVDA + Space Watch for:- "Browse mode" announcement when navigating- "Focus mode" when entering form fields- Application role forces forms mode``` ### Testing Script ```markdown## NVDA Test Script ### Initial Load 1. Navigate to page2. Let page finish loading3. Press Insert + Down to read all4. Note: Page title, main content identified? ### Landmark Navigation 1. Press D repeatedly2. Check: All main areas reachable?3. Check: Landmarks properly labeled? ### Heading Navigation 1. Press Insert + F7 → Headings2. Check: Logical heading structure?3. Press H to navigate headings4. Check: All sections discoverable? ### Form Testing 1. Press F to find first form field2. Check: Label read?3. Fill in invalid data4. Submit form5. Check: Errors announced?6. Check: Focus moved to error? ### Interactive Elements 1. Tab through all interactive elements2. Check: Each announces role and state3. Activate buttons with Enter/Space4. Check: Result announced? ### Dynamic Content 1. Trigger content update2. Check: Change announced?3. Open modal4. Check: Focus trapped?5. Close modal6. Check: Focus returns?``` ## JAWS (Windows) ### Essential Commands ```Start: Desktop shortcut or Ctrl + Alt + JVirtual Cursor: Auto-enabled in browsers Navigation:Arrow keys         Navigate contentTab                Next focusableInsert + Down      Read allCtrl               Stop speech Quick Keys:H                  Next headingT                  Next tableF                  Next form fieldB                  Next buttonG                  Next graphicL                  Next list;                  Next landmark Forms Mode:Enter              Enter forms modeNumpad +           Exit forms modeF5                 List form fields Lists:Insert + F7        Link listInsert + F6        Heading listInsert + F5        Form field list Tables:Ctrl + Alt + Arrows Table navigation``` ## TalkBack (Android) ### Setup ```Enable: Settings → Accessibility → TalkBackToggle: Hold both volume buttons 3 seconds``` ### Gestures ```Explore: Drag finger across screenNext: Swipe rightPrevious: Swipe leftActivate: Double tapScroll: Two finger swipe Reading Controls (swipe up then right):- Headings- Links- Controls- Characters- Words- Lines- Paragraphs``` ## Common Test Scenarios ### 1. Modal Dialog ```html<!-- Accessible modal structure --><div  role="dialog"  aria-modal="true"  aria-labelledby="dialog-title"  aria-describedby="dialog-desc">  <h2 id="dialog-title">Confirm Delete</h2>  <p id="dialog-desc">This action cannot be undone.</p>  <button>Cancel</button>  <button>Delete</button></div>``` ```javascript// Focus managementfunction openModal(modal) {  // Store last focused element  lastFocus = document.activeElement;   // Move focus to modal  modal.querySelector("h2").focus();   // Trap focus  modal.addEventListener("keydown", trapFocus);} function closeModal(modal) {  // Return focus  lastFocus.focus();} function trapFocus(e) {  if (e.key === "Tab") {    const focusable = modal.querySelectorAll(      'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',    );    const first = focusable[0];    const last = focusable[focusable.length - 1];     if (e.shiftKey && document.activeElement === first) {      last.focus();      e.preventDefault();    } else if (!e.shiftKey && document.activeElement === last) {      first.focus();      e.preventDefault();    }  }   if (e.key === "Escape") {    closeModal(modal);  }}``` ### 2. Live Regions ```html<!-- Status messages (polite) --><div role="status" aria-live="polite" aria-atomic="true">  <!-- Content updates will be announced after current speech --></div> <!-- Alerts (assertive) --><div role="alert" aria-live="assertive">  <!-- Content updates interrupt current speech --></div> <!-- Progress updates --><div  role="progressbar"  aria-valuenow="75"  aria-valuemin="0"  aria-valuemax="100"  aria-label="Upload progress"></div> <!-- Log (additions only) --><div role="log" aria-live="polite" aria-relevant="additions">  <!-- New messages announced, removals not --></div>``` ### 3. Tab Interface ```html<div role="tablist" aria-label="Product information">  <button role="tab" id="tab-1" aria-selected="true" aria-controls="panel-1">    Description  </button>  <button    role="tab"    id="tab-2"    aria-selected="false"    aria-controls="panel-2"    tabindex="-1"  >    Reviews  </button></div> <div role="tabpanel" id="panel-1" aria-labelledby="tab-1">  Product description content...</div> <div role="tabpanel" id="panel-2" aria-labelledby="tab-2" hidden>  Reviews content...</div>``` ```javascript// Tab keyboard navigationtablist.addEventListener("keydown", (e) => {  const tabs = [...tablist.querySelectorAll('[role="tab"]')];  const index = tabs.indexOf(document.activeElement);   let newIndex;  switch (e.key) {    case "ArrowRight":      newIndex = (index + 1) % tabs.length;      break;    case "ArrowLeft":      newIndex = (index - 1 + tabs.length) % tabs.length;      break;    case "Home":      newIndex = 0;      break;    case "End":      newIndex = tabs.length - 1;      break;    default:      return;  }   tabs[newIndex].focus();  activateTab(tabs[newIndex]);  e.preventDefault();});``` ## Debugging Tips ```javascript// Log what screen reader seesfunction logAccessibleName(element) {  const computed = window.getComputedStyle(element);  console.log({    role: element.getAttribute("role") || element.tagName,    name:      element.getAttribute("aria-label") ||      element.getAttribute("aria-labelledby") ||      element.textContent,    state: {      expanded: element.getAttribute("aria-expanded"),      selected: element.getAttribute("aria-selected"),      checked: element.getAttribute("aria-checked"),      disabled: element.disabled,    },    visible: computed.display !== "none" && computed.visibility !== "hidden",  });}``` ## Best Practices ### Do's - **Test with actual screen readers** - Not just simulators- **Use semantic HTML first** - ARIA is supplemental- **Test in browse and focus modes** - Different experiences- **Verify focus management** - Especially for SPAs- **Test keyboard only first** - Foundation for SR testing ### Don'ts - **Don't assume one SR is enough** - Test multiple- **Don't ignore mobile** - Growing user base- **Don't test only happy path** - Test error states- **Don't skip dynamic content** - Most common issues- **Don't rely on visual testing** - Different experience