Skip to content

Commit c90ab9d

Browse files
WilliamBerryiiiBill Berry
andauthored
test(docs): add jest-axe accessibility testing to Docusaurus components (#845)
# Pull Request ## Description Added **jest-axe** accessibility testing to all five Docusaurus component test suites. Each test file gained an async assertion that renders the component, runs axe-core analysis, and verifies zero accessibility violations. This establishes automated a11y coverage for the documentation site's custom React components. ## Related Issue(s) Related to #821 ## Type of Change Select all that apply: **Code & Documentation:** * [ ] Bug fix (non-breaking change fixing an issue) * [x] New feature (non-breaking change adding functionality) * [ ] Breaking change (fix or feature causing existing functionality to change) * [ ] Documentation update **Infrastructure & Configuration:** * [ ] GitHub Actions workflow * [ ] Linting configuration (markdown, PowerShell, etc.) * [ ] Security configuration * [ ] DevContainer configuration * [x] Dependency update **AI Artifacts:** * [ ] Reviewed contribution with `prompt-builder` agent and addressed all feedback * [ ] Copilot instructions (`.github/instructions/*.instructions.md`) * [ ] Copilot prompt (`.github/prompts/*.prompt.md`) * [ ] Copilot agent (`.github/agents/*.agent.md`) * [ ] Copilot skill (`.github/skills/*/SKILL.md`) **Other:** * [ ] Script/automation (`.ps1`, `.sh`, `.py`) * [ ] Other (please describe): ## Testing - All 34 Docusaurus component tests pass (`npm test` in `docs/docusaurus/`) - Each new a11y test renders the component, calls `axe(container)`, and asserts `toHaveNoViolations()` - The `region` rule is disabled inline since components render as fragments outside a full page landmark structure - `Icons.test.tsx` tests `GettingStartedIcon` as a representative sample rather than all six icon variants ## Checklist ### Required Checks * [x] Documentation is updated (if applicable) * [x] Files follow existing naming conventions * [x] Changes are backwards compatible (if applicable) * [x] Tests added for new functionality (if applicable) ### Required Automated Checks The following validation commands must pass before merging: * [x] Markdown linting: `npm run lint:md` * [x] Spell checking: `npm run spell-check` * [x] Frontmatter validation: `npm run lint:frontmatter` * [x] Skill structure validation: `npm run validate:skills` * [x] Link validation: `npm run lint:md-links` * [x] PowerShell analysis: `npm run lint:ps` Co-authored-by: Bill Berry <wbery@microsoft.com>
1 parent 79362b1 commit c90ab9d

File tree

7 files changed

+200
-0
lines changed

7 files changed

+200
-0
lines changed

docs/docusaurus/package-lock.json

Lines changed: 143 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/docusaurus/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@
3131
"@testing-library/jest-dom": "^6.9.1",
3232
"@testing-library/react": "^16.3.2",
3333
"@types/jest": "^30.0.0",
34+
"@types/jest-axe": "^3.5.9",
3435
"@types/react": "^19.2.14",
3536
"identity-obj-proxy": "^3.0.0",
3637
"jest": "^30.2.0",
38+
"jest-axe": "^10.0.0",
3739
"jest-environment-jsdom": "^30.2.0",
3840
"ts-jest": "^29.4.6"
3941
},

docs/docusaurus/src/components/Cards/__tests__/BoxCard.test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import React from 'react';
22
import { render, screen } from '@testing-library/react';
33
import '@testing-library/jest-dom';
4+
import { axe, toHaveNoViolations } from 'jest-axe';
45
import BoxCard from '../BoxCard';
56

7+
expect.extend(toHaveNoViolations);
8+
69
describe('BoxCard', () => {
710
const defaultProps = {
811
title: 'Box Title',
@@ -44,4 +47,12 @@ describe('BoxCard', () => {
4447
const { container } = render(<BoxCard {...defaultProps} />);
4548
expect(container.querySelector('img')).toBeNull();
4649
});
50+
51+
it('has no accessibility violations', async () => {
52+
const { container } = render(<BoxCard {...defaultProps} />);
53+
const results = await axe(container, {
54+
rules: { region: { enabled: false } },
55+
});
56+
expect(results).toHaveNoViolations();
57+
});
4758
});

docs/docusaurus/src/components/Cards/__tests__/CardGrid.test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import React from 'react';
22
import { render, screen } from '@testing-library/react';
33
import '@testing-library/jest-dom';
4+
import { axe, toHaveNoViolations } from 'jest-axe';
45
import CardGrid from '../CardGrid';
56

7+
expect.extend(toHaveNoViolations);
8+
69
describe('CardGrid', () => {
710
it('renders children', () => {
811
render(<CardGrid><div>child content</div></CardGrid>);
@@ -23,4 +26,12 @@ describe('CardGrid', () => {
2326
const { container } = render(<CardGrid columns={4}><div>child</div></CardGrid>);
2427
expect(container.firstChild).toHaveClass('cardGridFour');
2528
});
29+
30+
it('has no accessibility violations', async () => {
31+
const { container } = render(<CardGrid><div>child</div></CardGrid>);
32+
const results = await axe(container, {
33+
rules: { region: { enabled: false } },
34+
});
35+
expect(results).toHaveNoViolations();
36+
});
2637
});

docs/docusaurus/src/components/Cards/__tests__/IconCard.test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import React from 'react';
22
import { render, screen } from '@testing-library/react';
33
import '@testing-library/jest-dom';
4+
import { axe, toHaveNoViolations } from 'jest-axe';
45
import IconCard from '../IconCard';
56

7+
expect.extend(toHaveNoViolations);
8+
69
describe('IconCard', () => {
710
const defaultProps = {
811
icon: <span data-testid="test-icon">🚀</span>,
@@ -37,4 +40,12 @@ describe('IconCard', () => {
3740
const { container } = render(<IconCard {...defaultProps} />);
3841
expect(container.querySelector('.cardDescription')).toBeNull();
3942
});
43+
44+
it('has no accessibility violations', async () => {
45+
const { container } = render(<IconCard {...defaultProps} />);
46+
const results = await axe(container, {
47+
rules: { region: { enabled: false } },
48+
});
49+
expect(results).toHaveNoViolations();
50+
});
4051
});

docs/docusaurus/src/components/HeroSection/__tests__/HeroSection.test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import React from 'react';
22
import { render, screen } from '@testing-library/react';
33
import '@testing-library/jest-dom';
4+
import { axe, toHaveNoViolations } from 'jest-axe';
45
import HeroSection from '..';
56

7+
expect.extend(toHaveNoViolations);
8+
69
describe('HeroSection', () => {
710
it('renders title and subtitle', () => {
811
render(<HeroSection title="Hello World" subtitle="A subtitle" />);
@@ -14,4 +17,12 @@ describe('HeroSection', () => {
1417
render(<HeroSection title="Heading" subtitle="Sub" />);
1518
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('Heading');
1619
});
20+
21+
it('has no accessibility violations', async () => {
22+
const { container } = render(<HeroSection title="Hello World" subtitle="A subtitle" />);
23+
const results = await axe(container, {
24+
rules: { region: { enabled: false } },
25+
});
26+
expect(results).toHaveNoViolations();
27+
});
1728
});

docs/docusaurus/src/components/Icons/__tests__/Icons.test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import { render } from '@testing-library/react';
33
import '@testing-library/jest-dom';
4+
import { axe, toHaveNoViolations } from 'jest-axe';
45
import {
56
GettingStartedIcon,
67
AgentsPromptsIcon,
@@ -10,6 +11,8 @@ import {
1011
TemplatesExamplesIcon,
1112
} from '..';
1213

14+
expect.extend(toHaveNoViolations);
15+
1316
const icons = [
1417
{ name: 'GettingStartedIcon', Component: GettingStartedIcon },
1518
{ name: 'AgentsPromptsIcon', Component: AgentsPromptsIcon },
@@ -32,4 +35,12 @@ describe('Icons', () => {
3235
const svg = container.querySelector('svg');
3336
expect(svg).toHaveClass('custom-class');
3437
});
38+
39+
it('has no accessibility violations', async () => {
40+
const { container } = render(<GettingStartedIcon />);
41+
const results = await axe(container, {
42+
rules: { region: { enabled: false } },
43+
});
44+
expect(results).toHaveNoViolations();
45+
});
3546
});

0 commit comments

Comments
 (0)