From fb9316ae7607db80a0b3401c64d2a75cce77cc1a Mon Sep 17 00:00:00 2001 From: sheeeuWu Date: Mon, 8 Jun 2026 01:16:18 +0530 Subject: [PATCH] test(SuccessGuide-accessibility): verify Accessibility Standards & Screen Reader Aria Compliance (Variation 4) --- .../SuccessGuide.accessibility.test.tsx | 87 +++++++++++++++++++ app/components/SuccessGuide.tsx | 28 ++++-- 2 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 app/components/SuccessGuide.accessibility.test.tsx diff --git a/app/components/SuccessGuide.accessibility.test.tsx b/app/components/SuccessGuide.accessibility.test.tsx new file mode 100644 index 000000000..371b757b4 --- /dev/null +++ b/app/components/SuccessGuide.accessibility.test.tsx @@ -0,0 +1,87 @@ +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom/vitest'; +import { describe, it, expect, vi } from 'vitest'; +import { SuccessGuide } from './SuccessGuide'; + +type MockMotionProps = { + children?: React.ReactNode; + className?: string; + [key: string]: unknown; +}; + +vi.mock('framer-motion', () => ({ + motion: { + div: ({ children, ...props }: MockMotionProps) =>
{children}
, + }, + AnimatePresence: ({ children }: { children?: React.ReactNode }) => <>{children}, +})); + +vi.mock('./Icons', () => ({ + CloseIcon: () => , +})); + +vi.mock('@/context/TranslationContext', () => ({ + useTranslation: () => ({ + t: (key: string) => key, + }), +})); + +const defaultProps = { + markdown: '![CommitPulse](https://commitpulse.vercel.app/api/streak?user=testuser)', + onDismiss: vi.fn(), +}; + +describe('SuccessGuide — Accessibility & Screen Reader Compliance', () => { + it('renders as a named region landmark linked to h2 via aria-labelledby', () => { + const { container } = render(); + + const region = container.querySelector('[role="region"]'); + expect(region).toBeInTheDocument(); + expect(region).toHaveAttribute('aria-labelledby', 'success-guide-heading'); + + const heading = screen.getByRole('heading', { level: 2 }); + expect(heading).toHaveAttribute('id', 'success-guide-heading'); + expect(heading).toHaveTextContent('success_guide.title'); + }); + + it('renders dismiss button with aria-label and correct button role', () => { + render(); + + const dismissButton = screen.getByRole('button', { name: 'Dismiss guide' }); + expect(dismissButton).toBeInTheDocument(); + expect(dismissButton.tagName).toBe('BUTTON'); + }); + + it('renders steps grid with aria-label and all 4 step titles visible', () => { + const { container } = render(); + + const stepsGrid = container.querySelector('[aria-label="Steps to embed your badge"]'); + expect(stepsGrid).toBeInTheDocument(); + + expect(screen.getByText('success_guide.step_1_title')).toBeInTheDocument(); + expect(screen.getByText('success_guide.step_2_title')).toBeInTheDocument(); + expect(screen.getByText('success_guide.step_3_title')).toBeInTheDocument(); + expect(screen.getByText('success_guide.step_4_title')).toBeInTheDocument(); + }); + + it('renders step numbers as visible text for screen reader sequence announcement', () => { + render(); + + expect(screen.getByText('01')).toBeInTheDocument(); + expect(screen.getByText('02')).toBeInTheDocument(); + expect(screen.getByText('03')).toBeInTheDocument(); + expect(screen.getByText('04')).toBeInTheDocument(); + }); + + it('renders markdown snippet in code element with aria-label and hides $ symbol', () => { + const { container } = render(); + + const codeEl = container.querySelector('code[aria-label="Your badge markdown snippet"]'); + expect(codeEl).toBeInTheDocument(); + expect(codeEl).toHaveTextContent(defaultProps.markdown); + + const dollar = container.querySelector('[aria-hidden="true"].select-none'); + expect(dollar).toBeInTheDocument(); + expect(dollar).toHaveTextContent('$'); + }); +}); diff --git a/app/components/SuccessGuide.tsx b/app/components/SuccessGuide.tsx index e4c46d013..4af234080 100644 --- a/app/components/SuccessGuide.tsx +++ b/app/components/SuccessGuide.tsx @@ -45,16 +45,21 @@ export function SuccessGuide({ markdown, onDismiss }: SuccessGuideProps) { className="max-w-4xl mx-auto mb-12" >
-
+