Barazo default frontend barazo.forum
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(a11y): add accessibility statement page (M14) (#15)

WCAG 2.2 AA conformance statement with testing methods,
accessibility features, known limitations, and contact info.
Includes 6 tests with axe accessibility audit.

authored by

Guido X Jansen and committed by
GitHub
4ea7ea56 41d380dd

+187
+58
src/app/accessibility/page.test.tsx
··· 1 + /** 2 + * Tests for accessibility statement page. 3 + * @see specs/prd-web.md Section M14 4 + */ 5 + 6 + import { describe, it, expect, vi } from 'vitest' 7 + import { render, screen } from '@testing-library/react' 8 + import { axe } from 'vitest-axe' 9 + import AccessibilityPage from './page' 10 + 11 + // Mock next/navigation 12 + vi.mock('next/navigation', () => ({ 13 + usePathname: () => '/accessibility', 14 + useRouter: () => ({ push: vi.fn() }), 15 + })) 16 + 17 + // Mock next-themes 18 + vi.mock('next-themes', () => ({ 19 + useTheme: () => ({ theme: 'dark', setTheme: vi.fn() }), 20 + ThemeProvider: ({ children }: { children: React.ReactNode }) => children, 21 + })) 22 + 23 + describe('AccessibilityPage', () => { 24 + it('renders page heading', () => { 25 + render(<AccessibilityPage />) 26 + expect(screen.getByRole('heading', { name: /accessibility/i, level: 1 })).toBeInTheDocument() 27 + }) 28 + 29 + it('states WCAG 2.2 AA conformance target', () => { 30 + render(<AccessibilityPage />) 31 + expect(screen.getByText(/wcag.*2\.2/i)).toBeInTheDocument() 32 + expect(screen.getByText(/level aa/i)).toBeInTheDocument() 33 + }) 34 + 35 + it('lists testing methods', () => { 36 + render(<AccessibilityPage />) 37 + expect(screen.getByText(/automated testing/i)).toBeInTheDocument() 38 + expect(screen.getByText(/keyboard navigation/i)).toBeInTheDocument() 39 + expect(screen.getByText(/screen reader/i)).toBeInTheDocument() 40 + }) 41 + 42 + it('includes contact information', () => { 43 + render(<AccessibilityPage />) 44 + expect(screen.getByRole('heading', { name: /contact/i })).toBeInTheDocument() 45 + expect(screen.getByRole('link', { name: /github issue tracker/i })).toBeInTheDocument() 46 + }) 47 + 48 + it('renders breadcrumbs', () => { 49 + render(<AccessibilityPage />) 50 + expect(screen.getByText('Home')).toBeInTheDocument() 51 + }) 52 + 53 + it('passes axe accessibility check', async () => { 54 + const { container } = render(<AccessibilityPage />) 55 + const results = await axe(container) 56 + expect(results).toHaveNoViolations() 57 + }) 58 + })
+129
src/app/accessibility/page.tsx
··· 1 + /** 2 + * Accessibility statement page. 3 + * URL: /accessibility 4 + * Describes WCAG 2.2 AA conformance, testing methods, and contact info. 5 + * @see specs/prd-web.md Section M14 6 + */ 7 + 8 + import type { Metadata } from 'next' 9 + import { ForumLayout } from '@/components/layout/forum-layout' 10 + import { Breadcrumbs } from '@/components/breadcrumbs' 11 + 12 + export const metadata: Metadata = { 13 + title: 'Accessibility Statement', 14 + description: 15 + 'Barazo is committed to WCAG 2.2 Level AA accessibility. Learn about our testing, standards, and how to report issues.', 16 + alternates: { 17 + canonical: '/accessibility', 18 + }, 19 + } 20 + 21 + export default function AccessibilityPage() { 22 + return ( 23 + <ForumLayout> 24 + <div className="mx-auto max-w-2xl space-y-8"> 25 + <Breadcrumbs items={[{ label: 'Home', href: '/' }, { label: 'Accessibility' }]} /> 26 + 27 + <h1 className="text-2xl font-bold text-foreground">Accessibility Statement</h1> 28 + 29 + <section className="space-y-3"> 30 + <h2 className="text-lg font-semibold text-foreground">Our Commitment</h2> 31 + <p className="text-sm leading-relaxed text-muted-foreground"> 32 + Barazo is committed to ensuring digital accessibility for people with disabilities. We 33 + continually improve the user experience for everyone and apply the relevant 34 + accessibility standards. 35 + </p> 36 + </section> 37 + 38 + <section className="space-y-3"> 39 + <h2 className="text-lg font-semibold text-foreground">Conformance Status</h2> 40 + <p className="text-sm leading-relaxed text-muted-foreground"> 41 + We aim to conform to the{' '} 42 + <strong>Web Content Accessibility Guidelines (WCAG) 2.2 Level AA</strong>. These 43 + guidelines explain how to make web content more accessible to people with a wide range 44 + of disabilities. 45 + </p> 46 + </section> 47 + 48 + <section className="space-y-3"> 49 + <h2 className="text-lg font-semibold text-foreground">Testing Methods</h2> 50 + <p className="text-sm leading-relaxed text-muted-foreground"> 51 + We test accessibility through a combination of methods: 52 + </p> 53 + <ul className="list-inside list-disc space-y-2 text-sm text-muted-foreground"> 54 + <li> 55 + <strong>Automated testing</strong> using axe-core and ESLint accessibility rules in 56 + our continuous integration pipeline. 57 + </li> 58 + <li> 59 + <strong>Keyboard navigation</strong> testing to ensure all interactive elements are 60 + reachable and operable without a mouse. 61 + </li> 62 + <li> 63 + <strong>Screen reader</strong> testing with VoiceOver to verify content is properly 64 + announced and navigable. 65 + </li> 66 + <li> 67 + <strong>Lighthouse audits</strong> targeting an accessibility score of 95 or higher on 68 + all page types. 69 + </li> 70 + </ul> 71 + </section> 72 + 73 + <section className="space-y-3"> 74 + <h2 className="text-lg font-semibold text-foreground">Accessibility Features</h2> 75 + <ul className="list-inside list-disc space-y-2 text-sm text-muted-foreground"> 76 + <li>Semantic HTML with proper heading hierarchy and landmark regions.</li> 77 + <li>Skip links for jumping to main content and the reply editor.</li> 78 + <li>Keyboard-accessible controls with visible focus indicators.</li> 79 + <li>ARIA attributes for dynamic content, dialogs, and tab patterns.</li> 80 + <li>Color contrast meeting WCAG AA requirements in both light and dark themes.</li> 81 + <li>Pagination as the default for content lists (no infinite scroll).</li> 82 + <li>Respects reduced motion preferences via prefers-reduced-motion.</li> 83 + </ul> 84 + </section> 85 + 86 + <section className="space-y-3"> 87 + <h2 className="text-lg font-semibold text-foreground">Known Limitations</h2> 88 + <p className="text-sm leading-relaxed text-muted-foreground"> 89 + While we strive for full accessibility, some areas may have limitations: 90 + </p> 91 + <ul className="list-inside list-disc space-y-2 text-sm text-muted-foreground"> 92 + <li> 93 + User-generated content may not always meet accessibility standards (e.g., images 94 + without alt text in posts). 95 + </li> 96 + <li>Third-party embeds and plugins may have their own accessibility limitations.</li> 97 + </ul> 98 + </section> 99 + 100 + <section className="space-y-3"> 101 + <h2 className="text-lg font-semibold text-foreground">Contact Us</h2> 102 + <p className="text-sm leading-relaxed text-muted-foreground"> 103 + If you encounter accessibility barriers on Barazo, please contact us. We take 104 + accessibility feedback seriously and will work to address issues promptly. 105 + </p> 106 + <p className="text-sm leading-relaxed text-muted-foreground"> 107 + You can report accessibility issues through our{' '} 108 + <a 109 + href="https://github.com/barazo-forum/barazo-web/issues" 110 + className="text-primary underline hover:text-primary/80" 111 + target="_blank" 112 + rel="noopener noreferrer" 113 + > 114 + GitHub issue tracker 115 + </a> 116 + . Please include the page URL, a description of the issue, and the assistive technology 117 + you are using. 118 + </p> 119 + </section> 120 + 121 + <section className="space-y-3"> 122 + <p className="text-xs text-muted-foreground"> 123 + This statement was last updated on February 2026. 124 + </p> 125 + </section> 126 + </div> 127 + </ForumLayout> 128 + ) 129 + }