This guide provides comprehensive testing procedures for accessibility compliance across YieldVault-RWA core flows. All testing should be performed against WCAG 2.1 AA standards.
cd frontend
npm run test -- --run src/tests/accessibility.test.tsxExpected Results: All tests pass with zero violations reported by axe-core.
- ✅ Skip-link presence and functionality
- ✅ Button accessible names
- ✅ Form label associations
- ✅ Modal ARIA attributes (role, modal, labelledby, describedby)
- ✅ Tabs keyboard navigation and ARIA roles
- ✅ Data table captions and header scopes
- ✅ Pagination accessible labels
- ✅ Alert roles on banners
- ✅ Progress bar ARIA attributes
- ✅ Color contrast ratios (dark/light themes, tertiary text)
- ✅ Keyboard focus styles
- ✅ Accordion aria-expanded and aria-controls
- ✅ Disabled button states with sufficient contrast
- ✅ Badge color variants contrast
- ✅ Tabs inactive tab contrast
- ✅ Health status indicator tooltip readability
- ✅ Breadcrumbs font size and contrast
- ✅ Small text + tertiary color combinations
- ✅ Focus visibility on interactive elements
- ✅ Error state text contrast
Test Path: Home → Vault Selection → Tabs (Deposit/Withdraw)
Keyboard Sequence:
- Open
/(home page) - Press
Tabto move through all interactive elements in order:- Skip link should be first (but off-screen)
- Navigation bar (logo, nav links, connect wallet)
- Vault selection cards
- Deposit/Withdraw tabs
- Action buttons
- Press
Shift+Tabto navigate backwards - Press
Enter/Spaceon buttons to activate - Press
Escapeto close any opened modals
Expected Results:
- ✅ Tab order is logical and left-to-right
- ✅ No keyboard traps
- ✅ All interactive elements receive focus
- ✅ Focus outline is clearly visible (cyan 2px)
- ✅ Skip link is accessible when first focused
- ✅ Modals can be closed with Escape key
Test Path: Portfolio → Charts → Holdings Table
Keyboard Sequence:
- Navigate to
/portfolio - Tab through:
- Chart controls (if interactive)
- Holdings data table
- Pagination controls
- Sorting header buttons
- Use
Arrowkeys within table for cell navigation (if implemented)
Expected Results:
- ✅ Table headers are keyboard accessible
- ✅ Sorting buttons respond to Enter/Space
- ✅ Pagination controls are keyboard accessible
- ✅ Chart interactions (if any) are keyboard accessible
Test Path: Transaction History → Filters → Pagination → Detail View
Keyboard Sequence:
- Navigate to transaction history page
- Tab through:
- Filter panel buttons/selects
- Sort buttons on table headers
- Table rows (if selectable)
- Pagination buttons
- Open transaction detail drawer with Enter/Space
- Close drawer with Escape
Expected Results:
- ✅ All filter controls are accessible
- ✅ Sort buttons work with keyboard
- ✅ Pagination works without mouse
- ✅ Detail drawer can be opened/closed with keyboard
Test Path: Settings → Language & Theme Toggles
Keyboard Sequence:
- Navigate to
/settings - Tab to language switcher, activate with Space/Enter
- Tab to theme toggle, activate with Space/Enter
- Verify settings persist
Expected Results:
- ✅ All toggles are keyboard accessible
- ✅ State changes are announced to screen readers
- ✅ Settings persist after keyboard interaction
Test Path: Any modal (Session Expiration, Confirmations, etc.)
Keyboard Sequence:
- Trigger a modal (e.g., attempt transaction that needs confirmation)
- Tab within modal - should stay within modal (focus trap)
- Tab to close button, press Enter
- Verify focus returns to triggering element
- Open modal again, press Escape
- Verify modal closes and focus is restored
Expected Results:
- ✅ Focus cannot escape modal
- ✅ Escape key closes modal
- ✅ Close button works with Enter/Space
- ✅ Focus is properly restored after modal closes
- Open any YieldVault page
- Right-click on text element → Inspect
- In DevTools, use the color picker to check contrast
- Look for contrast ratio indicator (usually shown when hovering over colors)
Tool: WebAIM Contrast Checker
Test Cases:
-
Primary Text on Main Background
- Dark:
#ffffffon#0a0b10 - Expected: ≥ 4.5:1 ✅
- Dark:
-
Secondary Text on Main Background
- Dark:
#a8b8ccon#0a0b10 - Expected: ≥ 4.5:1 ✅
- Dark:
-
Tertiary Text on Main Background
- Dark:
#8494a7on#0a0b10 - Expected: ≥ 4.5:1 ✅
- Dark:
-
Disabled Button Text
- Dark:
rgba(255, 255, 255, 0.7)onrgba(100, 116, 139, 0.6) - Expected: ≥ 4.5:1 ✅
- Dark:
-
Badge Colors (new)
- Cyan:
var(--accent-cyan)onrgba(2, 132, 199, 0.15) - Purple:
#d8b4feon light background - Success:
#86efacon background - Warning:
#fcd34don background - Error:
#fca5a5on background - All expected: ≥ 4.5:1 ✅
- Cyan:
-
Breadcrumb Text
var(--text-secondary)on page background- Expected: ≥ 4.5:1 ✅
-
Health Status Indicator Tooltip
- Text:
var(--text-primary)/var(--text-secondary)on surface - Expected: ≥ 4.5:1 ✅
- Text:
-
Tabs - Active vs Inactive
- Active:
var(--text-primary)on active background - Inactive:
var(--text-secondary)on transparent/muted - Expected: ≥ 4.5:1 ✅
- Active:
-
Light Theme Equivalents (test on
[data-theme="light"])- Primary:
#0f172aon#f8fafc - Secondary:
#40505fon#f8fafc - Tertiary:
#5a6a7don#f8fafc - All expected: ≥ 4.5:1 ✅
- Primary:
Tool: axe DevTools
Steps:
- Install axe DevTools extension
- Open any YieldVault page
- Run axe scan
- Filter for "Contrast" issues
- Expected: 0 issues found ✅
Enable VoiceOver:
- Go to System Preferences → Accessibility → VoiceOver
- Enable VoiceOver
- Use
Caps Lockas modifier key (orCtrl+Option)
Test Cases:
- Press
Caps Lock + Uto open rotor - Navigate to headings:
- Expected: "Portfolio Heading Level 1"
- Expected: "Select a Vault Heading Level 2"
- Navigate to buttons:
- Verify button names are announced (e.g., "Deposit Tab selected", "Withdraw Tab")
- Press
Caps Lock + Right Arrowto read page content in order- Verify skip link is first interactive element
- Navigate to table with rotor (Caps Lock + U)
- VoiceOver should announce:
- "Table with caption: Holdings"
- Table column headers with
scope="col" - Row data with proper cell associations
- Tab through and verify:
- Column sort buttons announce sortability
- Pagination buttons announce current page and navigation
- Navigate to data table
- Expected announcements:
- Table caption: "Transaction history"
- Column headers with proper scope
- Row numbers for each transaction
- Test pagination:
- "Page 1 of 5, Previous page button disabled"
- "Next page button"
- Navigate language selector
- Expected: "Language Switcher Popup Button" or similar
- Verify options are announced when opened
- Navigate theme toggle
- Expected: "Toggle switch" or "Dark mode toggle"
- Verify state is announced (e.g., "checked" / "unchecked")
- Trigger a modal
- Expected VoiceOver will:
- Announce modal title (if present with ID matching aria-labelledby)
- Announce modal description (if present with ID matching aria-describedby)
- Read role="dialog" and aria-modal="true"
- Tab through modal content
- Press Escape to close
- Expected: Focus should return to triggering element
- Open Command Palette:
Ctrl+K(Windows/Linux) orCmd+K(Mac) - With VoiceOver enabled, verify:
- Search box is announced
- Results are read as they appear
- Arrow keys navigate results
- Enter selects result
Similar tests to VoiceOver:
- Enable NVDA screen reader
- Use Insert key + keyboard shortcuts to navigate
- Run same tests as above
Chrome/Edge/Firefox: Settings → Zoom
-
Set zoom to 125%
- Verify layout doesn't break
- All text remains readable
- No horizontal scrolling (ideally)
- Buttons remain 44×44px or larger
-
Set zoom to 150%
- Same verification as 125%
- Columns may stack on wider screens (acceptable)
-
Set zoom to 200%
- Verify usability is maintained
- Focus indicators remain visible
- Interactive elements are still clickable
- System Preferences → Accessibility → Display
- Increase text size to maximum
- Test YieldVault application
- Verify:
- Custom fonts scale appropriately
- Layout adjusts gracefully
- No text cutoff
- Open on iOS/Android device
- Pinch to zoom in/out
- Verify:
- Content remains readable
- Interactive elements remain accessible
- No horizontal scrolling at normal zoom levels
- Settings → Ease of Access → Display
- Enable "High Contrast" mode
- Test YieldVault:
- Verify all UI elements remain visible
- Focus indicators should be extra prominent
- Cyan accent should maintain contrast
Chrome DevTools:
- Right-click → Inspect
- Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows) → "Emulate CSS media feature prefers-contrast"
- Verify:
- All text remains readable
- Interactive elements are clearly visible
- No content is hidden
Tool: Microsoft Accessibility Insights browser extension
- Install extension
- Click extension icon → "View issues"
- Look for color-only dependency issues
- Navigate page and verify:
- Color is NOT the only way to convey information
- Status indicators use icons + color + text
- Charts have legends and labels
Simulate: Protanopia (Red-Blind), Deuteranopia (Green-Blind), Tritanopia (Blue-Yellow-Blind)
Tool: Coblis Color Blindness Simulator
Test Cases:
- Status indicators (Healthy, Degraded, Unhealthy)
- Expected: Visible differences beyond color alone
- Alert banners (Warning, Error, Success)
- Expected: Icon + text + color used for distinction
- Badge colors
- Expected: Text labels make status clear regardless of color
- System Preferences → Accessibility → Display
- Enable "Reduce motion"
- Test YieldVault:
- Animations should be minimal or non-existent
- Transitions should be instant or very quick
- All functionality remains intact
- Settings → Ease of Access → Display
- Enable "Show animations"
- Turn OFF animations (same effect)
- Test application
Chrome DevTools:
- Cmd+Shift+P (Mac) → "Emulate CSS media feature prefers-reduced-motion"
- Verify animations are disabled
Use a ruler or browser DevTools to verify:
- All buttons: minimum 44×44px ✅
- Link text within paragraphs: sufficient spacing
- Form inputs: minimum 44px height ✅
- Enable VoiceOver: Settings → Accessibility → VoiceOver
- Swipe right to move forward, swipe left to move backward
- Double-tap to activate
- Test same flows as desktop (Home, Portfolio, etc.)
- Enable TalkBack: Settings → Accessibility → TalkBack
- Swipe down then right for next item
- Double-tap to activate
- Test core flows
Test at breakpoints:
- Mobile: 375px width (iPhone SE)
- Tablet: 768px width (iPad)
- Desktop: 1200px+ width
Expected: All accessibility features work at each breakpoint
- Inspect form inputs with DevTools
- Verify each input has:
- Associated
<label>element - Label has
forattribute matching inputid - Screen reader announces label when input is focused
- Associated
- Submit form with errors
- Verify:
- Error message is associated with input (
aria-describedby) - Error text has sufficient contrast (≥ 4.5:1)
- Error is announced to screen reader
- Error icon is not the only visual indicator
- Error message is associated with input (
- Check form inputs
- Verify:
- Required fields have
requiredattribute oraria-required="true" - Label indicates required (text + asterisk or icon)
- Screen reader announces requirement
- Required fields have
For charts (APY Trend, Yield Breakdown, Vault Performance):
- Inspect chart components
- Verify:
- Chart has accessible title/caption
- Chart data is available in table format
- Tooltip data is keyboard accessible
- Color is not the only way to distinguish data
- Look for alternative text representation
- Check if data table is provided
- Verify legend is keyboard accessible
Verify documentation exists for:
-
aria-labelusage patterns -
aria-labelledbypatterns -
aria-describedbypatterns -
role=attribute guidelines - Focus management strategies
Verify documentation for:
- Required ARIA attributes per component
- Expected keyboard interactions
- Color contrast requirements
- Font size requirements
- Browser is up-to-date
- Screen reader is enabled (if testing with screen reader)
- Browser extensions don't interfere
- Test environment is clean (clear cache if needed)
- Primary text contrast ✅ (4.5:1+)
- Secondary text contrast ✅ (4.5:1+)
- Interactive elements visible ✅
- Focus indicators visible ✅
- Disabled states visible ✅
- Primary text contrast ✅ (4.5:1+)
- Secondary text contrast ✅ (4.5:1+)
- Interactive elements visible ✅
- Focus indicators visible ✅
- Disabled states visible ✅
- Tab order is logical ✅
- No keyboard traps ✅
- All interactive elements focused ✅
- Focus visible on all elements ✅
- Escape closes modals ✅
- Enter/Space activates buttons ✅
- Page structure announced correctly ✅
- Headings hierarchy is proper ✅
- Links have descriptive text ✅
- Buttons have accessible names ✅
- Form labels associated ✅
- Tables have captions ✅
- Alerts/live regions announced ✅
When reporting accessibility issues, use this template:
**Title**: [Component] Accessibility Issue - [Specific Problem]
**Environment**:
- Browser: [e.g., Chrome 120]
- Screen Reader: [e.g., Safari VoiceOver / NVDA]
- Theme: [Dark/Light]
- Page: [e.g., /portfolio]
**Issue**:
[Describe what fails WCAG 2.1 AA requirement]
**Steps to Reproduce**:
1. [Step 1]
2. [Step 2]
3. [Step 3]
**Expected**:
[What should happen per WCAG 2.1 AA]
**Actual**:
[What currently happens]
**Severity**: [Critical/High/Medium/Low]
**WCAG Criteria**: [e.g., 1.4.3 Contrast (Minimum)]
Run before every commit:
npm run test -- src/tests/accessibility.test.tsx --run- Full keyboard navigation test (all flows)
- Screen reader verification (Safari VoiceOver + NVDA)
- Color contrast verification (all components)
- Responsive design testing (mobile/tablet/desktop)
- High contrast mode testing
- Reduced motion testing
- Full WCAG 2.1 AA audit
- External accessibility audit (optional)
- Update guidelines if needed
- Review and close accessibility issues
- axe-core - Integrated in tests
- axe DevTools - Browser extension
- WebAIM - Accessibility resources
- WCAG 2.1 Guideline
- WAVE Browser Extension - Visual feedback
- WCAG Color Contrast Checker
- Accessibility Insights - Microsoft tool
- Color Blindness Simulator
- macOS: Safari VoiceOver (built-in)
- Windows: NVDA (free), JAWS (commercial)
- Linux: Orca (free)
- Mobile: iOS VoiceOver, Android TalkBack
| Issue | WCAG | Fix |
|---|---|---|
| Low contrast text | 1.4.3 | Increase luminance difference |
| Missing alt text | 1.1.1 | Add descriptive alt attribute |
| Form label missing | 1.3.1 | Associate label with input |
| No focus indicator | 2.4.7 | Add :focus-visible style |
| Keyboard trap | 2.1.2 | Ensure Tab can exit |
| Unclear button text | 2.4.3 | Use descriptive button labels |
| Color only | 1.4.1 | Add text/icon/pattern in addition |
| Not resizable | 1.4.4 | Allow text resizing/zoom |
| Animation autoplays | 2.2.2 | Add pause/stop controls |
| Unclear link purpose | 2.4.4 | Make link text descriptive |
- All automated tests passing (0 violations)
- Keyboard navigation verified on all flows
- Screen reader testing completed (macOS + at least one other)
- Color contrast verified (all components, both themes)
- Mobile accessibility tested
- Reduced motion respected
- High contrast mode tested
- Text scaling tested (125%, 150%, 200%)
- Documentation updated
- Issues resolved and documented