diff --git a/docusaurus/docs/e2e-test-a-plugin/index.md b/docusaurus/docs/e2e-test-a-plugin/index.md index 8b48ededbc..dc3397ac46 100644 --- a/docusaurus/docs/e2e-test-a-plugin/index.md +++ b/docusaurus/docs/e2e-test-a-plugin/index.md @@ -22,6 +22,7 @@ The `@grafana/plugin-e2e` tool offers a consistent way to interact with the Graf - **Predefined fixtures:** Offers a set of predefined fixtures that are tailored for Grafana plugin testing. - **Custom models:** Provides custom models that represent pages and components in Grafana, simplifying maintenance and creating reusable code to avoid repetition. - **Expect matchers:** Includes a range of expect matchers that are specialized for Grafana plugin assertions, helping you validate plugin behavior more effectively. +- **Accessibility testing:** Integrates with [Axe](https://www.deque.com/axe/) to run configurable accessibility scans inside your tests, with default rules aligned with Grafana's [WCAG 2.1 AA](https://www.w3.org/TR/WCAG21/) target. - **Integration with Playwright:** Seamlessly integrates with the Playwright testing framework, leveraging its powerful browser automation capabilities. ## End-to-end testing guides diff --git a/docusaurus/docs/e2e-test-a-plugin/test-a-panel-plugin.md b/docusaurus/docs/e2e-test-a-plugin/test-a-panel-plugin.md index 38a1e3d9de..0c75ff7683 100644 --- a/docusaurus/docs/e2e-test-a-plugin/test-a-panel-plugin.md +++ b/docusaurus/docs/e2e-test-a-plugin/test-a-panel-plugin.md @@ -186,3 +186,66 @@ test('should display dropdown with two values when two frames are passed to the await expect(panelEditPage.getByTestIdOrAriaLabel(selectors.components.Select.option)).toHaveText(['a', 'b']); }); ``` + +## Test for accessibility violations + +`@grafana/plugin-e2e` ships with an [Axe](https://www.deque.com/axe/)-powered `scanForA11yViolations` fixture and a `toHaveNoA11yViolations` matcher so you can catch accessibility regressions in your panel as part of your end-to-end suite. By default the scan runs the WCAG 2.0 and 2.1 A and AA rule sets, which match Grafana's [WCAG 2.1 AA](https://www.w3.org/TR/WCAG21/) target. + +`@axe-core/playwright` is an optional peer dependency, so install it alongside `@grafana/plugin-e2e` to use these APIs: + +```bash +npm install --save-dev @axe-core/playwright +``` + +:::note +The accessibility scanning APIs are `@alpha`. The surface may change before it becomes stable. Feedback is welcome on [GitHub](https://github.com/grafana/plugin-tools/issues). +::: + +The following test renders a panel from a provisioned dashboard and asserts that there are no accessibility violations on the page: + +```ts +test('panel has no accessibility violations', async ({ + gotoDashboardPage, + readProvisionedDashboard, + scanForA11yViolations, +}) => { + const dashboard = await readProvisionedDashboard({ fileName: 'my-panel-dashboard.json' }); + const dashboardPage = await gotoDashboardPage({ ...dashboard }); + await expect(dashboardPage.getPanelByTitle('My panel').locator).toBeVisible(); + + const report = await scanForA11yViolations(); + expect(report).toHaveNoA11yViolations(); +}); +``` + +When violations are found, `toHaveNoA11yViolations` prints each rule, its impact, and the affected DOM nodes, and the full Axe report is attached to the Playwright test result as a JSON artifact. + +### Scope a scan to your panel + +Pass `include` or `exclude` to limit the scan to a CSS selector (or array of selectors). This is useful when you only want to assert on the markup your plugin owns rather than the surrounding Grafana chrome. Add a `data-testid` to your panel's root element and target it from the test: + +```ts +const report = await scanForA11yViolations({ + include: '[data-testid="my-panel-root"]', +}); +expect(report).toHaveNoA11yViolations(); +``` + +You can also pass through any [axe-core run options](https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#options-parameter) — for example, to run a single rule: + +```ts +const report = await scanForA11yViolations({ + options: { runOnly: ['color-contrast'] }, +}); +``` + +### Tune the assertion + +`toHaveNoA11yViolations` accepts a `threshold` (the maximum number of violations to allow) and `ignoredRules` (axe rule IDs to skip when counting violations). This is helpful when adopting accessibility testing on an existing plugin and you want to track new regressions without fixing every pre-existing issue up front: + +```ts +expect(report).toHaveNoA11yViolations({ + threshold: 2, + ignoredRules: ['color-contrast'], +}); +```