From 08a9325182c40992527efd9955b4945fb56b85d6 Mon Sep 17 00:00:00 2001 From: Jony J <1844749591@qq.com> Date: Fri, 1 Nov 2024 11:30:11 +0800 Subject: [PATCH] feat: add a11y test for components demo (#51414) * test: add accessibility test utilities * refactor(tests): replace polling with Promise chain for axe test queue management * test: add a11y test for components demo * feat: add a11y test utils * test: add a11y test for components demo * test: add a11y test for components demo * chore: remove unnecessary code * feat: add polyfill for test environment * test: add a11y test for components demo * test: add a11y test for components demo * chore: adjust code style --- components/affix/__tests__/Affix.test.tsx | 2 +- components/affix/__tests__/a11y.test.ts | 5 + components/alert/__tests__/a11y.test.ts | 5 + components/alert/__tests__/index.test.tsx | 2 +- components/anchor/__tests__/a11y.test.ts | 5 + components/app/__tests__/a11y.test.ts | 5 + components/avatar/__tests__/a11y.test.ts | 5 + components/back-top/__tests__/a11y.test.ts | 5 + components/badge/__tests__/a11y.test.ts | 5 + .../breadcrumb/__tests__/Breadcrumb.test.tsx | 2 +- components/breadcrumb/__tests__/a11y.test.ts | 5 + components/button/__tests__/a11y.test.ts | 5 + .../color-picker/__tests__/a11y.test.ts | 4 + .../descriptions/__tests__/a11y.test.ts | 3 + components/divider/__tests__/a11y.test.ts | 3 + components/drawer/__tests__/a11y.test.ts | 3 + components/dropdown/__tests__/a11y.test.ts | 3 + components/empty/__tests__/a11y.test.ts | 3 + .../float-button/__tests__/a11y.test.ts | 3 + components/icon/__tests__/a11y.test.ts | 3 + components/image/__tests__/a11y.test.ts | 3 + .../input-number/__tests__/a11y.test.ts | 3 + components/input/__tests__/a11y.test.ts | 3 + components/mentions/__tests__/a11y.test.ts | 3 + components/menu/__tests__/a11y.test.ts | 3 + components/message/__tests__/a11y.test.ts | 3 + components/modal/__tests__/a11y.test.ts | 4 + .../notification/__tests__/a11y.test.ts | 3 + components/popconfirm/__tests__/a11y.test.ts | 3 + components/radio/__tests__/a11y.test.ts | 3 + components/result/__tests__/a11y.test.ts | 3 + components/select/__tests__/a11y.test.ts | 3 + components/space/__tests__/a11y.test.ts | 3 + components/spin/__tests__/a11y.test.ts | 3 + components/splitter/__tests__/a11y.test.ts | 3 + components/switch/__tests__/a11y.test.ts | 3 + components/tag/__tests__/a11y.test.ts | 3 + components/timeline/__tests__/a11y.test.ts | 3 + tests/shared/accessibilityTest.tsx | 134 +++++++++++++++++- 39 files changed, 260 insertions(+), 5 deletions(-) create mode 100644 components/affix/__tests__/a11y.test.ts create mode 100644 components/alert/__tests__/a11y.test.ts create mode 100644 components/anchor/__tests__/a11y.test.ts create mode 100644 components/app/__tests__/a11y.test.ts create mode 100644 components/avatar/__tests__/a11y.test.ts create mode 100644 components/back-top/__tests__/a11y.test.ts create mode 100644 components/badge/__tests__/a11y.test.ts create mode 100644 components/breadcrumb/__tests__/a11y.test.ts create mode 100644 components/button/__tests__/a11y.test.ts create mode 100644 components/color-picker/__tests__/a11y.test.ts create mode 100644 components/descriptions/__tests__/a11y.test.ts create mode 100644 components/divider/__tests__/a11y.test.ts create mode 100644 components/drawer/__tests__/a11y.test.ts create mode 100644 components/dropdown/__tests__/a11y.test.ts create mode 100644 components/empty/__tests__/a11y.test.ts create mode 100644 components/float-button/__tests__/a11y.test.ts create mode 100644 components/icon/__tests__/a11y.test.ts create mode 100644 components/image/__tests__/a11y.test.ts create mode 100644 components/input-number/__tests__/a11y.test.ts create mode 100644 components/input/__tests__/a11y.test.ts create mode 100644 components/mentions/__tests__/a11y.test.ts create mode 100644 components/menu/__tests__/a11y.test.ts create mode 100644 components/message/__tests__/a11y.test.ts create mode 100644 components/modal/__tests__/a11y.test.ts create mode 100644 components/notification/__tests__/a11y.test.ts create mode 100644 components/popconfirm/__tests__/a11y.test.ts create mode 100644 components/radio/__tests__/a11y.test.ts create mode 100644 components/result/__tests__/a11y.test.ts create mode 100644 components/select/__tests__/a11y.test.ts create mode 100644 components/space/__tests__/a11y.test.ts create mode 100644 components/spin/__tests__/a11y.test.ts create mode 100644 components/splitter/__tests__/a11y.test.ts create mode 100644 components/switch/__tests__/a11y.test.ts create mode 100644 components/tag/__tests__/a11y.test.ts create mode 100644 components/timeline/__tests__/a11y.test.ts diff --git a/components/affix/__tests__/Affix.test.tsx b/components/affix/__tests__/Affix.test.tsx index 2bf977c87b..7a1b0cbd17 100644 --- a/components/affix/__tests__/Affix.test.tsx +++ b/components/affix/__tests__/Affix.test.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useRef } from 'react'; import Affix from '..'; -import accessibilityTest from '../../../tests/shared/accessibilityTest'; +import { accessibilityTest } from '../../../tests/shared/accessibilityTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { render, triggerResize, waitFakeTimer } from '../../../tests/utils'; import Button from '../../button'; diff --git a/components/affix/__tests__/a11y.test.ts b/components/affix/__tests__/a11y.test.ts new file mode 100644 index 0000000000..f8bd0be946 --- /dev/null +++ b/components/affix/__tests__/a11y.test.ts @@ -0,0 +1,5 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +describe('affix demo a11y', () => { + accessibilityDemoTest('affix'); +}); diff --git a/components/alert/__tests__/a11y.test.ts b/components/alert/__tests__/a11y.test.ts new file mode 100644 index 0000000000..563f233ed3 --- /dev/null +++ b/components/alert/__tests__/a11y.test.ts @@ -0,0 +1,5 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +describe('alert demo a11y', () => { + accessibilityDemoTest('alert', { disabledRules: ['button-name'] }); +}); diff --git a/components/alert/__tests__/index.test.tsx b/components/alert/__tests__/index.test.tsx index 68e554c711..8e55d6f612 100644 --- a/components/alert/__tests__/index.test.tsx +++ b/components/alert/__tests__/index.test.tsx @@ -3,7 +3,7 @@ import userEvent from '@testing-library/user-event'; import { resetWarned } from 'rc-util/lib/warning'; import Alert from '..'; -import accessibilityTest from '../../../tests/shared/accessibilityTest'; +import { accessibilityTest } from '../../../tests/shared/accessibilityTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { act, render, screen, waitFakeTimer } from '../../../tests/utils'; import Button from '../../button'; diff --git a/components/anchor/__tests__/a11y.test.ts b/components/anchor/__tests__/a11y.test.ts new file mode 100644 index 0000000000..279baa3edd --- /dev/null +++ b/components/anchor/__tests__/a11y.test.ts @@ -0,0 +1,5 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +describe('anchor demo a11y', () => { + accessibilityDemoTest('anchor'); +}); diff --git a/components/app/__tests__/a11y.test.ts b/components/app/__tests__/a11y.test.ts new file mode 100644 index 0000000000..a7563c3867 --- /dev/null +++ b/components/app/__tests__/a11y.test.ts @@ -0,0 +1,5 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +describe('app demo a11y', () => { + accessibilityDemoTest('app'); +}); diff --git a/components/avatar/__tests__/a11y.test.ts b/components/avatar/__tests__/a11y.test.ts new file mode 100644 index 0000000000..a1bf8f95e7 --- /dev/null +++ b/components/avatar/__tests__/a11y.test.ts @@ -0,0 +1,5 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +describe('avatar demo a11y', () => { + accessibilityDemoTest('avatar', { disabledRules: ['image-alt'] }); +}); diff --git a/components/back-top/__tests__/a11y.test.ts b/components/back-top/__tests__/a11y.test.ts new file mode 100644 index 0000000000..a8da556386 --- /dev/null +++ b/components/back-top/__tests__/a11y.test.ts @@ -0,0 +1,5 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +describe('back-top demo a11y', () => { + accessibilityDemoTest('back-top'); +}); diff --git a/components/badge/__tests__/a11y.test.ts b/components/badge/__tests__/a11y.test.ts new file mode 100644 index 0000000000..dfe673081e --- /dev/null +++ b/components/badge/__tests__/a11y.test.ts @@ -0,0 +1,5 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +describe('badge demo a11y', () => { + accessibilityDemoTest('badge', { disabledRules: ['button-name'] }); +}); diff --git a/components/breadcrumb/__tests__/Breadcrumb.test.tsx b/components/breadcrumb/__tests__/Breadcrumb.test.tsx index 22f8bd1259..f49a75158b 100644 --- a/components/breadcrumb/__tests__/Breadcrumb.test.tsx +++ b/components/breadcrumb/__tests__/Breadcrumb.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { resetWarned } from '../../_util/warning'; -import accessibilityTest from '../../../tests/shared/accessibilityTest'; +import { accessibilityTest } from '../../../tests/shared/accessibilityTest'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; import { render } from '../../../tests/utils'; diff --git a/components/breadcrumb/__tests__/a11y.test.ts b/components/breadcrumb/__tests__/a11y.test.ts new file mode 100644 index 0000000000..cb786d3644 --- /dev/null +++ b/components/breadcrumb/__tests__/a11y.test.ts @@ -0,0 +1,5 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +describe('breadcrumb demo a11y', () => { + accessibilityDemoTest('breadcrumb'); +}); diff --git a/components/button/__tests__/a11y.test.ts b/components/button/__tests__/a11y.test.ts new file mode 100644 index 0000000000..22dbb03871 --- /dev/null +++ b/components/button/__tests__/a11y.test.ts @@ -0,0 +1,5 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +describe('button demo a11y', () => { + accessibilityDemoTest('button'); +}); diff --git a/components/color-picker/__tests__/a11y.test.ts b/components/color-picker/__tests__/a11y.test.ts new file mode 100644 index 0000000000..c758f3d0c8 --- /dev/null +++ b/components/color-picker/__tests__/a11y.test.ts @@ -0,0 +1,4 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +// skip _InternalPanelDoNotUseOrYouWillBeFired +accessibilityDemoTest('color-picker', { skip: ['pure-panel.tsx'] }); diff --git a/components/descriptions/__tests__/a11y.test.ts b/components/descriptions/__tests__/a11y.test.ts new file mode 100644 index 0000000000..d7870c921b --- /dev/null +++ b/components/descriptions/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('descriptions'); diff --git a/components/divider/__tests__/a11y.test.ts b/components/divider/__tests__/a11y.test.ts new file mode 100644 index 0000000000..3896c48b33 --- /dev/null +++ b/components/divider/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('divider'); diff --git a/components/drawer/__tests__/a11y.test.ts b/components/drawer/__tests__/a11y.test.ts new file mode 100644 index 0000000000..28ce13161d --- /dev/null +++ b/components/drawer/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('drawer', { disabledRules: ['image-alt'] }); diff --git a/components/dropdown/__tests__/a11y.test.ts b/components/dropdown/__tests__/a11y.test.ts new file mode 100644 index 0000000000..855dd7779f --- /dev/null +++ b/components/dropdown/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('dropdown'); diff --git a/components/empty/__tests__/a11y.test.ts b/components/empty/__tests__/a11y.test.ts new file mode 100644 index 0000000000..21872c8a22 --- /dev/null +++ b/components/empty/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('empty', { disabledRules: ['label'] }); diff --git a/components/float-button/__tests__/a11y.test.ts b/components/float-button/__tests__/a11y.test.ts new file mode 100644 index 0000000000..36e296a027 --- /dev/null +++ b/components/float-button/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('float-button', { disabledRules: ['button-name'] }); diff --git a/components/icon/__tests__/a11y.test.ts b/components/icon/__tests__/a11y.test.ts new file mode 100644 index 0000000000..0f5a5e61f7 --- /dev/null +++ b/components/icon/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('icon', { disabledRules: ['role-img-alt'] }); diff --git a/components/image/__tests__/a11y.test.ts b/components/image/__tests__/a11y.test.ts new file mode 100644 index 0000000000..1dee4bff6a --- /dev/null +++ b/components/image/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('image', { disabledRules: ['image-alt', 'label'] }); diff --git a/components/input-number/__tests__/a11y.test.ts b/components/input-number/__tests__/a11y.test.ts new file mode 100644 index 0000000000..be139b7879 --- /dev/null +++ b/components/input-number/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('input-number', { disabledRules: ['label'] }); diff --git a/components/input/__tests__/a11y.test.ts b/components/input/__tests__/a11y.test.ts new file mode 100644 index 0000000000..4102e41aec --- /dev/null +++ b/components/input/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('input', { disabledRules: ['label'] }); diff --git a/components/mentions/__tests__/a11y.test.ts b/components/mentions/__tests__/a11y.test.ts new file mode 100644 index 0000000000..5854f70c62 --- /dev/null +++ b/components/mentions/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('mentions', { disabledRules: ['label'] }); diff --git a/components/menu/__tests__/a11y.test.ts b/components/menu/__tests__/a11y.test.ts new file mode 100644 index 0000000000..20a1547598 --- /dev/null +++ b/components/menu/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('menu', { disabledRules: ['button-name'] }); diff --git a/components/message/__tests__/a11y.test.ts b/components/message/__tests__/a11y.test.ts new file mode 100644 index 0000000000..156821dc1f --- /dev/null +++ b/components/message/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('message'); diff --git a/components/modal/__tests__/a11y.test.ts b/components/modal/__tests__/a11y.test.ts new file mode 100644 index 0000000000..c44d2784dd --- /dev/null +++ b/components/modal/__tests__/a11y.test.ts @@ -0,0 +1,4 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +// skip debug components +accessibilityDemoTest('modal', { skip: ['wireframe.tsx', 'render-panel.tsx'] }); diff --git a/components/notification/__tests__/a11y.test.ts b/components/notification/__tests__/a11y.test.ts new file mode 100644 index 0000000000..19f8d68b23 --- /dev/null +++ b/components/notification/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('notification', { disabledRules: ['button-name', 'label'] }); diff --git a/components/popconfirm/__tests__/a11y.test.ts b/components/popconfirm/__tests__/a11y.test.ts new file mode 100644 index 0000000000..6faab2fbb6 --- /dev/null +++ b/components/popconfirm/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('popconfirm', { disabledRules: ['button-name'] }); diff --git a/components/radio/__tests__/a11y.test.ts b/components/radio/__tests__/a11y.test.ts new file mode 100644 index 0000000000..cfac8f6a60 --- /dev/null +++ b/components/radio/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('radio'); diff --git a/components/result/__tests__/a11y.test.ts b/components/result/__tests__/a11y.test.ts new file mode 100644 index 0000000000..57e50fbc42 --- /dev/null +++ b/components/result/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('result'); diff --git a/components/select/__tests__/a11y.test.ts b/components/select/__tests__/a11y.test.ts new file mode 100644 index 0000000000..74e52ad162 --- /dev/null +++ b/components/select/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('select', { disabledRules: ['label', 'button-name'] }); diff --git a/components/space/__tests__/a11y.test.ts b/components/space/__tests__/a11y.test.ts new file mode 100644 index 0000000000..77f33a1fc0 --- /dev/null +++ b/components/space/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('space', { disabledRules: ['label', 'button-name'] }); diff --git a/components/spin/__tests__/a11y.test.ts b/components/spin/__tests__/a11y.test.ts new file mode 100644 index 0000000000..0a7872e043 --- /dev/null +++ b/components/spin/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('spin', { disabledRules: ['button-name'] }); diff --git a/components/splitter/__tests__/a11y.test.ts b/components/splitter/__tests__/a11y.test.ts new file mode 100644 index 0000000000..308ca9bb2d --- /dev/null +++ b/components/splitter/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('splitter'); diff --git a/components/switch/__tests__/a11y.test.ts b/components/switch/__tests__/a11y.test.ts new file mode 100644 index 0000000000..a8e9bcb835 --- /dev/null +++ b/components/switch/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('switch', { disabledRules: ['button-name'] }); diff --git a/components/tag/__tests__/a11y.test.ts b/components/tag/__tests__/a11y.test.ts new file mode 100644 index 0000000000..0cefd61ce0 --- /dev/null +++ b/components/tag/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('tag'); diff --git a/components/timeline/__tests__/a11y.test.ts b/components/timeline/__tests__/a11y.test.ts new file mode 100644 index 0000000000..45bd9edfaa --- /dev/null +++ b/components/timeline/__tests__/a11y.test.ts @@ -0,0 +1,3 @@ +import accessibilityDemoTest from '../../../tests/shared/accessibilityTest'; + +accessibilityDemoTest('timeline'); diff --git a/tests/shared/accessibilityTest.tsx b/tests/shared/accessibilityTest.tsx index b1c6e34219..4df29d5045 100644 --- a/tests/shared/accessibilityTest.tsx +++ b/tests/shared/accessibilityTest.tsx @@ -1,15 +1,145 @@ import React from 'react'; import { render } from '@testing-library/react'; +import { globSync } from 'glob'; import { axe } from 'jest-axe'; +class AxeQueueManager { + private queue: Promise = Promise.resolve(); + private isProcessing = false; + + async enqueue(task: () => Promise): Promise { + const currentQueue = this.queue; + + const newTask = async () => { + try { + await currentQueue; + this.isProcessing = true; + return await task(); + } finally { + this.isProcessing = false; + } + }; + + this.queue = this.queue.then(newTask, newTask); + + return this.queue; + } + + isRunning(): boolean { + return this.isProcessing; + } +} + +const axeQueueManager = new AxeQueueManager(); + +const runAxe = async (...args: Parameters): Promise> => { + return axeQueueManager.enqueue(async () => { + try { + return await axe(...args); + } catch (error) { + console.error('Axe test failed:', error); + throw error; + } + }); +}; + +type Rules = { + [key: string]: { + enabled: boolean; + }; +}; + +const convertRulesToAxeFormat = (rules: string[]): Rules => { + return rules.reduce( + (acc, rule) => ({ + ...acc, + [rule]: { enabled: false }, + }), + {}, + ); +}; + // eslint-disable-next-line jest/no-export -export default function accessibilityTest(Component: React.ComponentType) { +export function accessibilityTest(Component: React.ComponentType, disabledRules?: string[]) { + beforeAll(() => { + // Fake ResizeObserver + global.ResizeObserver = jest.fn(() => { + return { + observe() {}, + unobserve() {}, + disconnect() {}, + }; + }) as jest.Mock; + + // fake fetch + global.fetch = jest.fn(() => { + return { + then() { + return this; + }, + catch() { + return this; + }, + finally() { + return this; + }, + }; + }) as jest.Mock; + }); + + beforeEach(() => { + // Reset all mocks + if (global.fetch) { + (global.fetch as jest.Mock).mockClear(); + } + }); + + afterEach(() => { + // Clear all mocks + jest.clearAllMocks(); + }); describe(`accessibility`, () => { it(`component does not have any violations`, async () => { jest.useRealTimers(); const { container } = render(); - const results = await axe(container); + + const rules = convertRulesToAxeFormat(disabledRules || []); + + const results = await runAxe(container, { rules }); expect(results).toHaveNoViolations(); + }, 30000); + }); +} + +type Options = { + skip?: boolean | string[]; + disabledRules?: string[]; +}; + +// eslint-disable-next-line jest/no-export +export default function accessibilityDemoTest(component: string, options: Options = {}) { + // If skip is true, return immediately without executing any tests + if (options.skip === true) { + describe.skip(`${component} demo a11y`, () => { + it('skipped', () => {}); + }); + return; + } + + describe(`${component} demo a11y`, () => { + const files = globSync(`./components/${component}/demo/*.tsx`).filter( + (file) => + !file.includes('_semantic') && !file.includes('debug') && !file.includes('component-token'), + ); + + files.forEach((file) => { + const shouldSkip = Array.isArray(options.skip) && options.skip.some((c) => file.endsWith(c)); + const testMethod = shouldSkip ? describe.skip : describe; + + testMethod(`Test ${file} accessibility`, () => { + const Demo = require(`../../${file}`).default; + accessibilityTest(Demo, options.disabledRules); + }); }); }); }