Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions packages/plugin-e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,19 @@
"engines": {
"node": ">=20 <=24"
},
"peerDependenciesMeta": {
"@axe-core/playwright": {
"optional": true
}
},
"peerDependencies": {
"@axe-core/playwright": "^4.11.1",
"@playwright/test": "^1.52.0",
"axe-core": "^4.11.1"
"@playwright/test": "^1.52.0"
},
"devDependencies": {
"@axe-core/playwright": "^4.11.1",
"@playwright/test": "^1.58.1",
"@types/uuid": "^11.0.0",
"axe-core": "^4.11.1",
"dotenv": "^17.2.4"
},
"dependencies": {
Expand Down
14 changes: 12 additions & 2 deletions packages/plugin-e2e/src/fixtures/scanForA11yViolations.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import AxeBuilder from '@axe-core/playwright';
import { TestFixture } from '@playwright/test';
import { AxeResults } from 'axe-core';
import type { AxeResults } from 'axe-core';
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's an issue but plugin-e2e ships types which rely on axe-core. I think they'll be considered any if the package is missing but want to surface it in the PR all the same.

Image

Copy link
Copy Markdown
Contributor Author

@fastfrwrd fastfrwrd Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah :/ ultimately I think this is still probably the cleanest way to make this work, since the user probably doesn't actually interact with the report but just passes it from the fixture to the custom matcher.

import type { AxeBuilder as AxeBuilderType } from '@axe-core/playwright';

import { PlaywrightArgs, AxeScanContext } from '../types';

export const DEFAULT_A11Y_TAGS = ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa' /* 'best-practice' */];

let AxeBuilder: typeof AxeBuilderType;

/**
* @alpha - the API for accessibility scanning is still being finalized and may change in future releases. Feedback is welcome!
*/
Expand All @@ -15,6 +17,14 @@ export const scanForA11yViolations: TestFixture<
> = async ({ page }, use, testInfo) => {
let inc = 1;
await use(async (context?: AxeScanContext) => {
if (!AxeBuilder) {
try {
const { AxeBuilder: _AxeBuilder } = await import('@axe-core/playwright');
AxeBuilder = _AxeBuilder;
Comment on lines +21 to +23
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dynamic import is pulling a named export ({ AxeBuilder }), but this module was previously imported as the default export (import AxeBuilder from '@axe-core/playwright'). If @axe-core/playwright only provides a default export, _AxeBuilder will be undefined and new AxeBuilder({ page }) will crash. Align the dynamic import (and the AxeBuilderType typing) with the package’s actual export shape (likely default).

Copilot uses AI. Check for mistakes.
} catch (error) {
throw new Error('@axe-core/playwright must be installed as a peer dependency to use a11y scanning.');
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thrown message says only @axe-core/playwright must be installed, but axe-core is also declared as an (optional) peer and may be the actual missing module that makes this import fail. Update the error to mention both packages (or make it generic like “axe a11y peer deps”) so users know what to install.

Suggested change
throw new Error('@axe-core/playwright must be installed as a peer dependency to use a11y scanning.');
throw new Error('@axe-core/playwright and axe-core must be installed (as peer dependencies) to use a11y scanning.');

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that optional dependency only impacts TypeScript types, which seem to not be an issue unless we forget to import type, so we don't care I think.

}
}
const builder = new AxeBuilder({ page }).withTags(DEFAULT_A11Y_TAGS);
if (context?.options) {
builder.options(context!.options);
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-e2e/src/matchers/toHaveNoA11yViolations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MatcherReturnType } from '@playwright/test';
import { AxeResults } from 'axe-core';
import type { MatcherReturnType } from '@playwright/test';
import type { AxeResults } from 'axe-core';

import { A11yViolationsOptions } from '../types';

Expand Down
Loading