import AxeBuilder from "@axe-core/playwright"; import type { Page } from "@playwright/test"; import { expect, test } from "../helpers/serve-dist"; type AccessibilityState = | "default" | "audio-running" | "static" | "reduced-motion" | "media-failure" | "missing-social"; const states: readonly AccessibilityState[] = [ "default", "audio-running", "static", "reduced-motion", "media-failure", "missing-social", ]; async function enterState( page: Page, distUrl: string, state: AccessibilityState, ): Promise { if (state === "reduced-motion") { await page.emulateMedia({ reducedMotion: "reduce" }); } if (state === "media-failure") { await page.addInitScript(() => { const nativeGetContext = HTMLCanvasElement.prototype.getContext; Object.defineProperty(HTMLCanvasElement.prototype, "getContext", { configurable: true, value( this: HTMLCanvasElement, contextId: string, options?: unknown, ): RenderingContext | null { if ( contextId === "webgl" || contextId === "webgl2" || contextId === "experimental-webgl" ) { return null; } return Reflect.apply(nativeGetContext, this, [ contextId, options, ]) as RenderingContext | null; }, }); }); } await page.goto(distUrl, { waitUntil: "domcontentloaded" }); if (state === "audio-running") { await page.getByRole("button", { name: "START THE DRIVE" }).click(); await expect( page.getByRole("button", { name: "Mute sound" }), ).toBeVisible(); } else if (state === "static") { await page.getByRole("button", { name: "Drive settings" }).click(); await page.getByLabel("Quality control").selectOption("static"); await expect(page.getByRole("status")).toContainText("Motion: static"); } else if (state === "reduced-motion") { await page.getByRole("button", { name: "Drive settings" }).click(); await expect(page.getByRole("status")).toContainText( "reduced motion requested", ); } else if (state === "media-failure") { await expect(page.locator(".journey-world")).toHaveAttribute( "data-scene-state", "failed", ); } else if (state === "missing-social") { await page.locator('#contact a[target="_blank"]').evaluateAll((links) => { for (const link of links) link.closest("li")?.remove(); }); await expect(page.locator('#contact a[target="_blank"]')).toHaveCount(0); await expect(page.locator('#contact a[href^="mailto:"]')).toBeVisible(); } } for (const state of states) { test(`${state} has no WCAG 2.2 A or AA axe violations`, async ({ page, distUrl, }) => { await enterState(page, distUrl, state); const result = await new AxeBuilder({ page }) .withTags(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22aa"]) .analyze(); expect(result.violations).toEqual([]); }); }