Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add axe accessibility testing #32977

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
504522d
use axe for automated a11y testing
marchbox Oct 3, 2024
8469078
Merge branch 'microsoft:master' into users/machi/axe
marchbox Oct 3, 2024
cd1252a
update change file
marchbox Oct 3, 2024
3327ef4
add a11y tests to all components
marchbox Oct 4, 2024
33052b5
fix formatting
marchbox Oct 4, 2024
df9d70c
allow aria attributes to be set as boolean false
marchbox Oct 4, 2024
23cbc9b
also set aria props on element internals
marchbox Oct 4, 2024
f27e8cc
fix exiting accessibility issues in components and stories
marchbox Oct 4, 2024
e2e70d9
Merge branch 'microsoft:master' into users/machi/axe
marchbox Oct 4, 2024
69154dc
Merge branch 'users/machi/axe' of github.com:marchbox/fluentui into u…
marchbox Oct 4, 2024
d910db2
fix drawer accessibility issues
marchbox Oct 4, 2024
002b0d5
temporarily disable menu and menulist axe tests
marchbox Oct 4, 2024
d2e17bf
fix exiting accessibility issues in components and stories batch 2
marchbox Oct 4, 2024
dd714d5
fix accessibility issue in tablist
marchbox Oct 7, 2024
45ff924
fix accessibility issue in textarea stories
marchbox Oct 7, 2024
f1dfc67
fix accessibility issue in text-input stories
marchbox Oct 7, 2024
6d0a398
fix accessibility issue in rating-display
marchbox Oct 7, 2024
87dae73
fix axe testing helper
marchbox Oct 7, 2024
4160aa7
Merge branch 'microsoft:master' into users/machi/axe
marchbox Oct 7, 2024
c3efbc5
Merge branch 'master' into users/machi/axe
marchbox Oct 7, 2024
e9ea0c7
fix dup deps issue
marchbox Oct 7, 2024
1ffb9c8
fix formatting
marchbox Oct 7, 2024
81156d6
fix tests
marchbox Oct 7, 2024
494f74b
fix formatting
marchbox Oct 8, 2024
7cd0180
Merge branch 'master' into users/machi/axe
marchbox Oct 8, 2024
9ff8008
fix formatting
marchbox Oct 8, 2024
97286f6
Merge branch 'microsoft:master' into users/machi/axe
marchbox Oct 8, 2024
2799769
Merge branch 'master' into users/machi/axe
marchbox Oct 8, 2024
eeba6f1
Merge branch 'master' into users/machi/axe
marchbox Oct 9, 2024
10f3385
move dependency to root
marchbox Oct 9, 2024
a720785
Merge branch 'master' into users/machi/axe
marchbox Oct 10, 2024
6ac933d
Merge branch 'master' into users/machi/axe
marchbox Oct 11, 2024
e1d6803
Merge branch 'master' into users/machi/axe
marchbox Oct 15, 2024
5c0226d
Merge branch 'microsoft:master' into users/machi/axe
marchbox Oct 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "add axe automated a11y testing",
"packageName": "@fluentui/web-components",
"email": "[email protected]",
"dependentChangeType": "patch"
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"devDependencies": {
"@actions/core": "1.9.1",
"@actions/github": "5.0.3",
"@axe-core/playwright": "^4.10.0",
"@babel/core": "7.24.6",
"@babel/generator": "7.24.6",
"@babel/parser": "7.24.6",
Expand Down
23 changes: 21 additions & 2 deletions packages/web-components/src/accordion/accordion.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { Locator } from '@playwright/test';
import { test } from '@playwright/test';
import { expect, fixtureURL } from '../helpers.tests.js';
import { analyzePageWithAxe, createElementInternalsTrapsForAxe, expect, fixtureURL } from '../helpers.tests.js';

const storybookDocId = 'components-accordion--docs';

test.describe('Accordion', () => {
test.beforeEach(async ({ page }) => {
await page.goto(fixtureURL('components-accordion--accordion'));
await page.goto(fixtureURL(storybookDocId));

await page.waitForFunction(() =>
Promise.all([
Expand Down Expand Up @@ -435,3 +437,20 @@ test.describe('Accordion', () => {
await expect(item).toHaveAttribute('expanded');
});
});

test('should not have auto detectable accessibility issues', async ({ page }) => {
await createElementInternalsTrapsForAxe(page);

await page.goto(fixtureURL(storybookDocId));
await page.waitForFunction(() =>
Promise.all([
customElements.whenDefined('fluent-accordion'),
customElements.whenDefined('fluent-accordion-item'),
customElements.whenDefined('fluent-checkbox'),
]),
);

const results = await analyzePageWithAxe(page);

expect(results.violations).toEqual([]);
});
17 changes: 15 additions & 2 deletions packages/web-components/src/anchor-button/anchor-button.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { spinalCase } from '@microsoft/fast-web-utilities';
import { test } from '@playwright/test';
import { expect, fixtureURL } from '../helpers.tests.js';
import { analyzePageWithAxe, createElementInternalsTrapsForAxe, expect, fixtureURL } from '../helpers.tests.js';

const storybookDocId = 'components-button-anchor--docs';

const proxyAttributes = {
href: 'href',
Expand All @@ -27,7 +29,7 @@ const booleanAttributes = {

test.describe('Anchor Button', () => {
test.beforeEach(async ({ page }) => {
await page.goto(fixtureURL('components-button-anchor--anchor-button'));
await page.goto(fixtureURL(storybookDocId));

await page.waitForFunction(() => customElements.whenDefined('fluent-anchor-button'));
});
Expand Down Expand Up @@ -143,3 +145,14 @@ test.describe('Anchor Button', () => {
expect(newPage.url()).toContain(expectedUrl);
});
});

test('should not have auto detectable accessibility issues', async ({ page }) => {
await createElementInternalsTrapsForAxe(page);

await page.goto(fixtureURL(storybookDocId));
await page.waitForFunction(() => customElements.whenDefined('fluent-anchor-button'));

const results = await analyzePageWithAxe(page);

expect(results.violations).toEqual([]);
});
47 changes: 44 additions & 3 deletions packages/web-components/src/avatar/avatar.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { test } from '@playwright/test';
import { expect, fixtureURL } from '../helpers.tests.js';
import { analyzePageWithAxe, createElementInternalsTrapsForAxe, expect, fixtureURL } from '../helpers.tests.js';
import type { Avatar } from './avatar.js';
import { AvatarAppearance, AvatarColor, AvatarSize } from './avatar.options.js';
import type { AvatarAppearance, AvatarColor, AvatarSize } from './avatar.options.js';

const storybookDocId = 'components-avatar--docs';

test.describe('Avatar Component', () => {
test.beforeEach(async ({ page }) => {
await page.goto(fixtureURL('components-avatar--image'));
await page.goto(fixtureURL(storybookDocId));

await page.waitForFunction(() => customElements.whenDefined('fluent-avatar'));
});
Expand Down Expand Up @@ -81,6 +83,10 @@ test.describe('Avatar Component', () => {
test('should have a role of img', async ({ page }) => {
const element = page.locator('fluent-avatar');

await page.setContent(/* html */ `
<fluent-avatar></fluent-avatar>
`);

await expect(element).toHaveJSProperty('elementInternals.role', 'img');
});

Expand Down Expand Up @@ -119,6 +125,10 @@ test.describe('Avatar Component', () => {
test('should render correctly in active state', async ({ page }) => {
const element = page.locator('fluent-avatar');

await page.setContent(/* html */ `
<fluent-avatar></fluent-avatar>
`);

await element.evaluate((node: Avatar) => {
node.active = 'active';
});
Expand All @@ -129,6 +139,10 @@ test.describe('Avatar Component', () => {
test('should render correctly in inactive state', async ({ page }) => {
const element = page.locator('fluent-avatar');

await page.setContent(/* html */ `
<fluent-avatar></fluent-avatar>
`);

await element.evaluate((node: Avatar) => {
node.active = 'inactive';
});
Expand All @@ -139,6 +153,10 @@ test.describe('Avatar Component', () => {
test('default color should be neutral', async ({ page }) => {
const element = page.locator('fluent-avatar');

await page.setContent(/* html */ `
<fluent-avatar></fluent-avatar>
`);

await expect(element).toHaveCustomState('neutral');
});

Expand All @@ -165,6 +183,10 @@ test.describe('Avatar Component', () => {
test(`should set the color attribute on the internal control`, async ({ page }) => {
const element = page.locator('fluent-avatar');

await page.setContent(/* html */ `
<fluent-avatar></fluent-avatar>
`);

for (const [, value] of Object.entries(colorAttributes)) {
await test.step(value, async () => {
await element.evaluate((node: Avatar, colorValue: string) => {
Expand All @@ -181,6 +203,10 @@ test.describe('Avatar Component', () => {
test(`should set the size attribute on the internal control`, async ({ page }) => {
const element = page.locator('fluent-avatar');

await page.setContent(/* html */ `
<fluent-avatar></fluent-avatar>
`);

for (const [, value] of Object.entries(sizeAttributes)) {
await test.step(`${value}`, async () => {
await element.evaluate((node: Avatar, sizeValue: number) => {
Expand All @@ -197,6 +223,10 @@ test.describe('Avatar Component', () => {
test(`should set and reflect the appearance attribute on the internal control`, async ({ page }) => {
const element = page.locator('fluent-avatar');

await page.setContent(/* html */ `
<fluent-avatar></fluent-avatar>
`);

for (const [, value] of Object.entries(appearanceAttributes)) {
await test.step(value, async () => {
await element.evaluate((node: Avatar, appearanceValue: string) => {
Expand All @@ -209,3 +239,14 @@ test.describe('Avatar Component', () => {
}
});
});

test('should not have auto detectable accessibility issues', async ({ page }) => {
await createElementInternalsTrapsForAxe(page);

await page.goto(fixtureURL(storybookDocId));
await page.waitForFunction(() => customElements.whenDefined('fluent-avatar'));

const results = await analyzePageWithAxe(page);

expect(results.violations).toEqual([]);
});
Loading
Loading