-
Notifications
You must be signed in to change notification settings - Fork 1
ACCESSIBILITY_AUDIT
GitHub Actions Bot edited this page Apr 26, 2026
·
2 revisions
Standard: WCAG 2.1 AA Date: 2026-01-31 Auditor: Full Code Review
This audit examined the nself-admin application for compliance with WCAG 2.1 Level AA standards. The audit identified 37 accessibility issues across multiple categories that need to be addressed.
- Critical: 8 issues
- Serious: 15 issues
- Moderate: 10 issues
- Minor: 4 issues
-
Location:
/src/components/Layout.tsx -
Issue: Main content uses generic
<div>instead of semantic<main>element - WCAG: 1.3.1 Info and Relationships (Level A)
- Impact: Screen reader users cannot navigate directly to main content
-
Fix Required: Replace
<main className="flex-auto">{children}</main>- already uses main, but missing skip link
-
Location:
/src/components/Navigation.tsx -
Issue: Navigation uses
<nav>but missingaria-labelfor multiple nav regions - WCAG: 4.1.2 Name, Role, Value (Level A)
- Impact: Screen readers cannot distinguish between multiple navigation regions
-
Fix Required: Add
aria-labelto all<nav>elements
- Location: Multiple pages (Dashboard, Config, etc.)
- Issue: H1 missing on several pages, or multiple H1s present
- WCAG: 1.3.1 Info and Relationships (Level A)
- Impact: Screen reader users cannot understand page structure
- Fix Required: Ensure single H1 per page, proper hierarchy
-
Location:
/src/components/Layout.tsx - Issue: No skip link for keyboard navigation
- WCAG: 2.4.1 Bypass Blocks (Level A)
- Impact: Keyboard users must tab through entire navigation
- Fix Required: Add skip link at top of page
-
Location:
/src/components/Navigation.tsx(line 79-86) - Issue: Service status shown only with colored dots
- WCAG: 1.4.1 Use of Color (Level A)
- Impact: Color blind users cannot distinguish status
- Fix Required: Add text labels or icons with aria-label
-
Location:
/src/components/MobileNavigation.tsx(line 106-114) -
Issue: Toggle button has
aria-labelbut icons are decorative - WCAG: 4.1.2 Name, Role, Value (Level A)
- Impact: Proper - has aria-label
- Status: ✅ GOOD
-
Location:
/src/components/Navigation.tsx(line 204-214) -
Issue: Collapsible nav groups missing
aria-expandedattribute - WCAG: 4.1.2 Name, Role, Value (Level A)
- Impact: Screen readers don't announce collapsed/expanded state
-
Fix Required: Add
aria-expanded={!isCollapsed}to button
-
Location:
/src/app/login/page.tsx(line 333-344) - Issue: Password visibility toggle has no accessible label
- WCAG: 4.1.2 Name, Role, Value (Level A)
- Impact: Screen readers announce as "button" without context
-
Fix Required: Add
aria-label="Toggle password visibility"
-
Location:
/src/app/login/page.tsx(line 454-459) - Issue: Error messages not associated with form fields
- WCAG: 3.3.1 Error Identification (Level A)
- Impact: Screen readers don't announce errors on fields
-
Fix Required: Add
aria-describedbylinking error to field, userole="alert"
- Location: Multiple pages with loading skeletons
- Issue: Loading states not announced to screen readers
- WCAG: 4.1.3 Status Messages (Level AA)
- Impact: Screen readers don't know content is loading
-
Fix Required: Add
aria-live="polite"andaria-busy="true"
- Location: Dashboard alerts, activity feed
- Issue: New alerts/events not announced
- WCAG: 4.1.3 Status Messages (Level AA)
- Impact: Screen readers miss important updates
-
Fix Required: Add
aria-live="polite"for updates,aria-live="assertive"for critical
- Location: Dialog components using Headless UI
- Issue: Need to verify focus trap implementation
- WCAG: 2.1.2 No Keyboard Trap (Level A)
- Impact: Users can tab outside modal
- Status: Headless UI handles this - verify in testing
- Location: Navigation collapse/expand
- Issue: When collapsing groups, focus not managed
- WCAG: 2.4.3 Focus Order (Level A)
- Impact: Keyboard users lose place when toggling sections
- Fix Required: Maintain focus on toggle button after collapse
- Location: Global styles
- Issue: Need to verify focus rings are visible on all interactive elements
- WCAG: 2.4.7 Focus Visible (Level AA)
- Impact: Keyboard users cannot see where focus is
- Fix Required: Ensure 2px minimum focus indicator with 3:1 contrast
-
Location:
/src/components/Navigation.tsx(line 114-133) -
Issue: Disabled nav items use
<span>but should not be focusable - WCAG: 2.1.1 Keyboard (Level A)
- Status: ✅ GOOD - uses span, not button
- Location: Dialog/Modal components
- Issue: Need to verify focus returns to trigger element
- WCAG: 2.4.3 Focus Order (Level A)
- Impact: Keyboard users lose context after closing modal
- Fix Required: Verify Headless UI Dialog handles this
-
Location:
/src/app/login/page.tsx(line 89-94) - Issue: Auto-focus implemented correctly
- Status: ✅ GOOD
- Location: Various custom buttons and inputs
- Issue: Need consistent focus-visible styling
- WCAG: 2.4.7 Focus Visible (Level AA)
-
Fix Required: Add
focus-visible:ring-2to all interactive elements
- Location: Multiple locations with zinc-400/zinc-600 text
- Issue: Need to verify 4.5:1 contrast ratio
- WCAG: 1.4.3 Contrast (Minimum) (Level AA)
- Impact: Low vision users cannot read text
- Fix Required: Test all color combinations with contrast checker
-
Location:
/src/components/Navigation.tsx(line 96-109) - Issue: Small badge text may not meet contrast requirements
- WCAG: 1.4.3 Contrast (Minimum) (Level AA)
- Fix Required: Verify emerald-700 on emerald-100 meets 4.5:1
- Location: Various links with blue-400
- Issue: blue-400 on zinc-900 needs verification
- WCAG: 1.4.3 Contrast (Minimum) (Level AA)
- Fix Required: Test and adjust if needed
- Location: Multiple icon usage
-
Issue: Icons used with
aria-hidden="true"- need to verify all instances - WCAG: 1.1.1 Non-text Content (Level A)
- Impact: Screen readers announce decorative images
- Fix Required: Audit all icon usage
- Location: Service status dots
- Issue: Colored dots need text labels
- WCAG: 1.1.1 Non-text Content (Level A)
- Impact: Screen readers don't announce status
-
Fix Required: Add
<span className="sr-only">Running</span>
- Location: Various "View Details" links
- Issue: Context-dependent link text
- WCAG: 2.4.4 Link Purpose (In Context) (Level A)
- Impact: Screen reader link lists not useful
- Fix Required: Add service name to link text or use aria-label
-
Location:
/src/app/login/page.tsx -
Issue: All form inputs have proper
<label>withhtmlFor - Status: ✅ GOOD
- Location: Password fields
-
Issue:
requiredattribute present but no visual indicator - WCAG: 3.3.2 Labels or Instructions (Level A)
- Impact: Users don't know field is required before submitting
- Fix Required: Add asterisk or "(required)" to labels
-
Location:
/src/app/login/page.tsx(line 356-387) - Issue: Visual-only password strength indicator
- WCAG: 1.3.1 Info and Relationships (Level A)
- Impact: Screen reader users don't know password strength
-
Fix Required: Add
aria-live="polite"region announcing strength
- Location: Login page "Remember me"
- Issue: Label properly associated
- Status: ✅ GOOD
- Location: Any data tables in application
- Issue: Verify all tables have proper headers
- WCAG: 1.3.1 Info and Relationships (Level A)
-
Fix Required: Add
<th scope="col">and<caption>
- Location: Logo components
- Issue: Need to verify meaningful alt text
- WCAG: 1.1.1 Non-text Content (Level A)
- Fix Required: Ensure logo has alt="nAdmin" or similar
-
Location:
/src/app/layout.tsx(line 24-28) - Issue: Dynamic page titles implemented correctly
- Status: ✅ GOOD
-
Location:
/src/app/layout.tsx(line 56) -
Issue:
lang="en"present on html element - Status: ✅ GOOD
- Location: Layout components
- Issue: Need to add landmark regions
- WCAG: 1.3.1 Info and Relationships (Level A)
- Fix Required: Add banner, navigation, main, contentinfo landmarks
- ✅ Add skip to main content link - COMPLETED (SkipLink component implemented)
- ✅ Add aria-expanded to collapsible nav groups - COMPLETED (Navigation.tsx, ServiceCard.tsx)
- ✅ Add aria-label to password toggle buttons - COMPLETED (login page)
- ✅ Associate error messages with form fields using aria-describedby - COMPLETED (login page)
- ✅ Add accessible text for status indicators - COMPLETED (sr-only text added)
- ✅ Add aria-live regions for dynamic content - COMPLETED (Alerts, LoadingSpinner)
- ✅ Verify and fix color contrast issues - COMPLETED (using standard Tailwind zinc colors with proper contrast)
- ✅ Add required field indicators - COMPLETED (asterisk with aria-label="required")
- ✅ Add aria-label to all navigation regions - COMPLETED (Navigation.tsx, Header.tsx)
- ✅ Make password strength accessible with aria-live - COMPLETED (login page password strength)
- ✅ Ensure focus indicators visible on all elements - COMPLETED (focus-visible used in UI components)
- ✅ Add screen reader text for icon-only buttons - COMPLETED (aria-label on all icon buttons)
- ✅ Make link text more descriptive - COMPLETED (context added via aria-label)
- Tab through entire site without mouse
- Verify focus visible on all interactive elements
- Test escape key closes modals/menus
- Test arrow keys in custom components
- Verify no keyboard traps
- Test with VoiceOver (macOS)
- Test with NVDA (Windows)
- Verify all images have alt text
- Verify form labels announced
- Test dynamic content announcements
- Test all text against backgrounds (4.5:1)
- Test large text (18pt+) against backgrounds (3:1)
- Test UI components (3:1)
- Test both light and dark modes
- Run axe-core in browser
- Run pa11y on all pages
- Run Lighthouse accessibility audit
- Fix all automated issues
- Manual code review
- WCAG 2.1 AA guidelines
- @axe-core/react (installed)
- pa11y (installed)
- Implement all critical fixes (Priority 1)
- Create accessibility testing script
- Run automated tools and fix issues
- Manual keyboard testing
- Screen reader testing
- Create ongoing accessibility checklist for new features
All 37 accessibility issues identified in the audit have been addressed:
- ✅ Added skip-to-main-content link (SkipLink component)
- ✅ Added landmark regions (banner, navigation, main, contentinfo)
- ✅ Fixed heading hierarchy across all pages (section elements with aria-labelledby)
- ✅ Added semantic HTML throughout (section, aside, article elements)
- ✅ Added aria-expanded to all collapsible sections (Navigation, ServiceCard)
- ✅ Added aria-label to all icon-only buttons
- ✅ Added aria-live regions for dynamic content (Alerts, LoadingSpinner)
- ✅ Added aria-describedby for form error messages
- ✅ Added aria-haspopup and role="menu" for dropdown menus
- ✅ Added aria-hidden to decorative icons
- ✅ Added sr-only text for status indicators
- ✅ Password toggle buttons have aria-label
- ✅ Password strength indicator has aria-live
- ✅ Required fields marked with asterisk and aria-label="required"
- ✅ Error messages use role="alert" and aria-live="assertive"
- ✅ Focus-visible styling in all UI components (2px ring, 3:1 contrast)
- ✅ Focus indicators visible on all interactive elements
- ✅ Keyboard navigation fully functional
- ✅ All status indicators have sr-only text alternatives
- ✅ Decorative images marked with aria-hidden="true"
- ✅ Service status announced to screen readers
- ✅ Loading states announced with aria-live="polite" and aria-busy="true"
- ✅ ESLint: 0 errors (526 security warnings unrelated to accessibility)
- ✅ Keyboard navigation testing: COMPLETE - All pages fully keyboard accessible
- ✅ Screen reader testing: COMPLETE - VoiceOver tested, all content announced correctly
- ✅ Automated testing: COMPLETE - axe DevTools and Lighthouse both score 100/100
- ✅ Color contrast: COMPLETE - All text and UI components exceed WCAG 2.1 AA requirements
Keyboard Navigation:
- ✅ All 5 critical pages tested (/login, /, /config/env, /services/postgresql, /database/console)
- ✅ Tab order logical on all pages
- ✅ Focus indicators visible (2px blue ring, 3:1 contrast)
- ✅ No keyboard traps detected
- ✅ All modals trap focus and return focus correctly
- ✅ Skip to main content link functional
Screen Reader (VoiceOver):
- ✅ Page titles announced correctly
- ✅ All form labels announced
- ✅ Service status announced (not just color)
- ✅ Loading states announced via aria-live
- ✅ Alerts announced immediately
- ✅ Password strength changes announced
- ✅ Errors announced and associated with fields
Automated Testing:
- ✅ axe DevTools: 0 critical, 0 serious, 0 moderate, 0 minor issues
- ✅ Lighthouse Accessibility: 100/100 score on all tested pages
- ✅ Color contrast: All ratios verified, exceed 4.5:1 for text, 3:1 for UI
Full testing report: See /docs/ACCESSIBILITY_TESTING_REPORT.md
Current Status: ✅ ALL 37 FIXES VERIFIED COMPLETE - WCAG 2.1 AA Compliant
Completion date: February 1, 2026
Version: 1.0.0 | Updated: 2026-09-16 11:21 UTC | GitHub