From 7911d389e8ed85ab2f0bb4a9c028e9a51258a742 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 01:25:22 +0000 Subject: [PATCH 1/5] Initial plan From 4f418b1f5d257d97a1c257f88f24fbdf10b108e5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 01:27:35 +0000 Subject: [PATCH 2/5] Add reduced motion and color scheme action inputs Co-authored-by: JoyceZhu <6251669+JoyceZhu@users.noreply.github.com> --- .github/actions/find/README.md | 8 ++++++++ .github/actions/find/action.yml | 6 ++++++ .github/actions/find/src/findForUrl.ts | 8 +++++++- .github/actions/find/src/index.ts | 18 +++++++++++++++++- README.md | 4 ++++ action.yml | 8 ++++++++ 6 files changed, 50 insertions(+), 2 deletions(-) diff --git a/.github/actions/find/README.md b/.github/actions/find/README.md index f674e23d..ae34bdc0 100644 --- a/.github/actions/find/README.md +++ b/.github/actions/find/README.md @@ -19,6 +19,14 @@ https://primer.style/octicons/ **Optional** Stringified JSON object containing `username`, `password`, `cookies`, and/or `localStorage` from an authenticated session. For example: `{"username":"some-user","password":"correct-horse-battery-staple","cookies":[{"name":"theme-preference","value":"light","domain":"primer.style","path":"/"}],"localStorage":{"https://primer.style":{"theme-preference":"light"}}}` +#### `reduced_motion` + +**Optional** Playwright [`reducedMotion`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-reduced-motion) setting to emulate user preference. Allowed values: `reduce`, `no-preference`. + +#### `color_scheme` + +**Optional** Playwright [`colorScheme`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme) setting to emulate user preference. Allowed values: `light`, `dark`, `no-preference`. + ### Outputs #### `findings` diff --git a/.github/actions/find/action.yml b/.github/actions/find/action.yml index 2ab8dcba..e7873455 100644 --- a/.github/actions/find/action.yml +++ b/.github/actions/find/action.yml @@ -13,6 +13,12 @@ inputs: description: "Whether to capture screenshots of scanned pages and include links to them in the issue" required: false default: "false" + reduced_motion: + description: "Playwright reducedMotion setting. Allowed values: 'reduce', 'no-preference'" + required: false + color_scheme: + description: "Playwright colorScheme setting. Allowed values: 'light', 'dark', 'no-preference'" + required: false outputs: findings: diff --git a/.github/actions/find/src/findForUrl.ts b/.github/actions/find/src/findForUrl.ts index f24057ca..33a1bf9b 100644 --- a/.github/actions/find/src/findForUrl.ts +++ b/.github/actions/find/src/findForUrl.ts @@ -8,12 +8,18 @@ export async function findForUrl( url: string, authContext?: AuthContext, includeScreenshots: boolean = false, + reducedMotion?: 'reduce' | 'no-preference', + colorScheme?: 'light' | 'dark' | 'no-preference', ): Promise { const browser = await playwright.chromium.launch({ headless: true, executablePath: process.env.CI ? '/usr/bin/google-chrome' : undefined, }) - const contextOptions = authContext?.toPlaywrightBrowserContextOptions() ?? {} + const contextOptions = { + ...(authContext?.toPlaywrightBrowserContextOptions() ?? {}), + ...(reducedMotion ? {reducedMotion} : {}), + ...(colorScheme ? {colorScheme} : {}), + } const context = await browser.newContext(contextOptions) const page = await context.newPage() await page.goto(url) diff --git a/.github/actions/find/src/index.ts b/.github/actions/find/src/index.ts index 4688606b..7333851d 100644 --- a/.github/actions/find/src/index.ts +++ b/.github/actions/find/src/index.ts @@ -11,11 +11,27 @@ export default async function () { const authContext = new AuthContext(authContextInput) const includeScreenshots = core.getInput('include_screenshots', {required: false}) !== 'false' + const reducedMotionInput = core.getInput('reduced_motion', {required: false}) + let reducedMotion: 'reduce' | 'no-preference' | undefined + if (reducedMotionInput) { + if (!['reduce', 'no-preference'].includes(reducedMotionInput)) { + throw new Error("Input 'reduced_motion' must be one of: 'reduce', 'no-preference'") + } + reducedMotion = reducedMotionInput + } + const colorSchemeInput = core.getInput('color_scheme', {required: false}) + let colorScheme: 'light' | 'dark' | 'no-preference' | undefined + if (colorSchemeInput) { + if (!['light', 'dark', 'no-preference'].includes(colorSchemeInput)) { + throw new Error("Input 'color_scheme' must be one of: 'light', 'dark', 'no-preference'") + } + colorScheme = colorSchemeInput + } const findings = [] for (const url of urls) { core.info(`Preparing to scan ${url}`) - const findingsForUrl = await findForUrl(url, authContext, includeScreenshots) + const findingsForUrl = await findForUrl(url, authContext, includeScreenshots, reducedMotion, colorScheme) if (findingsForUrl.length === 0) { core.info(`No accessibility gaps were found on ${url}`) continue diff --git a/README.md b/README.md index 3c9cebca..78e30c4b 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ jobs: # auth_context: # Optional: Stringified JSON object for complex authentication # skip_copilot_assignment: false # Optional: Set to true to skip assigning issues to GitHub Copilot (or if you don't have GitHub Copilot) # include_screenshots: false # Optional: Set to true to capture screenshots and include links to them in filed issues + # reduced_motion: no-preference # Optional: Playwright reduced motion emulation (`reduce` or `no-preference`) + # color_scheme: dark # Optional: Playwright color scheme emulation (`light`, `dark`, or `no-preference`) ``` > 👉 Update all `REPLACE_THIS` placeholders with your actual values. See [Action Inputs](#action-inputs) for details. @@ -115,6 +117,8 @@ Trigger the workflow manually or automatically based on your configuration. The | `auth_context` | No | If scanned pages require authentication, a stringified JSON object containing username, password, cookies, and/or localStorage from an authenticated session | `{"username":"some-user","password":"***","cookies":[...]}` | | `skip_copilot_assignment` | No | Whether to skip assigning filed issues to GitHub Copilot. Set to `true` if you don't have GitHub Copilot or prefer to handle issues manually | `true` | | `include_screenshots` | No | Whether to capture screenshots of scanned pages and include links to them in filed issues. Screenshots are stored on the `gh-cache` branch of the repository running the workflow. Default: `false` | `true` | +| `reduced_motion` | No | Playwright `reducedMotion` setting for scan contexts. Allowed values: `reduce`, `no-preference` | `reduce` | +| `color_scheme` | No | Playwright `colorScheme` setting for scan contexts. Allowed values: `light`, `dark`, `no-preference` | `dark` | --- diff --git a/action.yml b/action.yml index 932bc27f..8859b6e6 100644 --- a/action.yml +++ b/action.yml @@ -35,6 +35,12 @@ inputs: description: "Whether to capture screenshots and include links to them in the issue" required: false default: "false" + reduced_motion: + description: "Playwright reducedMotion setting for scans. Allowed values: 'reduce', 'no-preference'" + required: false + color_scheme: + description: "Playwright colorScheme setting for scans. Allowed values: 'light', 'dark', 'no-preference'" + required: false outputs: results: @@ -85,6 +91,8 @@ runs: urls: ${{ inputs.urls }} auth_context: ${{ inputs.auth_context || steps.auth.outputs.auth_context }} include_screenshots: ${{ inputs.include_screenshots }} + reduced_motion: ${{ inputs.reduced_motion }} + color_scheme: ${{ inputs.color_scheme }} - name: File id: file uses: ./../../_actions/github/accessibility-scanner/current/.github/actions/file From ac972a3c7466277e3cb0f419c5c3a74d2acd068c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 01:28:05 +0000 Subject: [PATCH 3/5] Fix TypeScript narrowing for new scanner inputs Co-authored-by: JoyceZhu <6251669+JoyceZhu@users.noreply.github.com> --- .github/actions/find/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/find/src/index.ts b/.github/actions/find/src/index.ts index 7333851d..3df7614b 100644 --- a/.github/actions/find/src/index.ts +++ b/.github/actions/find/src/index.ts @@ -17,7 +17,7 @@ export default async function () { if (!['reduce', 'no-preference'].includes(reducedMotionInput)) { throw new Error("Input 'reduced_motion' must be one of: 'reduce', 'no-preference'") } - reducedMotion = reducedMotionInput + reducedMotion = reducedMotionInput as 'reduce' | 'no-preference' } const colorSchemeInput = core.getInput('color_scheme', {required: false}) let colorScheme: 'light' | 'dark' | 'no-preference' | undefined @@ -25,7 +25,7 @@ export default async function () { if (!['light', 'dark', 'no-preference'].includes(colorSchemeInput)) { throw new Error("Input 'color_scheme' must be one of: 'light', 'dark', 'no-preference'") } - colorScheme = colorSchemeInput + colorScheme = colorSchemeInput as 'light' | 'dark' | 'no-preference' } const findings = [] From 88c9363e572e82844ac876fe962b0f9b0f77a764 Mon Sep 17 00:00:00 2001 From: Joyce Zhu Date: Thu, 26 Feb 2026 22:53:26 +0000 Subject: [PATCH 4/5] Name some types for readability --- .github/actions/find/package-lock.json | 1 + .github/actions/find/src/findForUrl.ts | 6 +++--- .github/actions/find/src/index.ts | 22 +++++++++++++--------- .github/actions/find/src/types.d.ts | 4 ++++ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/.github/actions/find/package-lock.json b/.github/actions/find/package-lock.json index eb0f1342..6208a9ac 100644 --- a/.github/actions/find/package-lock.json +++ b/.github/actions/find/package-lock.json @@ -121,6 +121,7 @@ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", "license": "Apache-2.0", + "peer": true, "bin": { "playwright-core": "cli.js" }, diff --git a/.github/actions/find/src/findForUrl.ts b/.github/actions/find/src/findForUrl.ts index 33a1bf9b..bff83b29 100644 --- a/.github/actions/find/src/findForUrl.ts +++ b/.github/actions/find/src/findForUrl.ts @@ -1,4 +1,4 @@ -import type {Finding} from './types.d.js' +import type {ColorSchemePreference, Finding, ReducedMotionPreference} from './types.d.js' import {AxeBuilder} from '@axe-core/playwright' import playwright from 'playwright' import {AuthContext} from './AuthContext.js' @@ -8,8 +8,8 @@ export async function findForUrl( url: string, authContext?: AuthContext, includeScreenshots: boolean = false, - reducedMotion?: 'reduce' | 'no-preference', - colorScheme?: 'light' | 'dark' | 'no-preference', + reducedMotion?: ReducedMotionPreference, + colorScheme?: ColorSchemePreference, ): Promise { const browser = await playwright.chromium.launch({ headless: true, diff --git a/.github/actions/find/src/index.ts b/.github/actions/find/src/index.ts index 3df7614b..60de50ec 100644 --- a/.github/actions/find/src/index.ts +++ b/.github/actions/find/src/index.ts @@ -1,4 +1,4 @@ -import type {AuthContextInput} from './types.js' +import type {AuthContextInput, ColorSchemePreference, ReducedMotionPreference} from './types.js' import * as core from '@actions/core' import {AuthContext} from './AuthContext.js' import {findForUrl} from './findForUrl.js' @@ -12,20 +12,24 @@ export default async function () { const includeScreenshots = core.getInput('include_screenshots', {required: false}) !== 'false' const reducedMotionInput = core.getInput('reduced_motion', {required: false}) - let reducedMotion: 'reduce' | 'no-preference' | undefined + let reducedMotion: ReducedMotionPreference | undefined if (reducedMotionInput) { - if (!['reduce', 'no-preference'].includes(reducedMotionInput)) { - throw new Error("Input 'reduced_motion' must be one of: 'reduce', 'no-preference'") + if (!['reduce', 'no-preference', null].includes(reducedMotionInput)) { + throw new Error( + "Input 'reduced_motion' must be one of: 'reduce', 'no-preference', or null per Playwright documentation.", + ) } - reducedMotion = reducedMotionInput as 'reduce' | 'no-preference' + reducedMotion = reducedMotionInput as ReducedMotionPreference } const colorSchemeInput = core.getInput('color_scheme', {required: false}) - let colorScheme: 'light' | 'dark' | 'no-preference' | undefined + let colorScheme: ColorSchemePreference | undefined if (colorSchemeInput) { - if (!['light', 'dark', 'no-preference'].includes(colorSchemeInput)) { - throw new Error("Input 'color_scheme' must be one of: 'light', 'dark', 'no-preference'") + if (!['light', 'dark', 'no-preference', null].includes(colorSchemeInput)) { + throw new Error( + "Input 'color_scheme' must be one of: 'light', 'dark', 'no-preference', or null per Playwright documentation.", + ) } - colorScheme = colorSchemeInput as 'light' | 'dark' | 'no-preference' + colorScheme = colorSchemeInput as ColorSchemePreference } const findings = [] diff --git a/.github/actions/find/src/types.d.ts b/.github/actions/find/src/types.d.ts index 72582c46..ce226ea1 100644 --- a/.github/actions/find/src/types.d.ts +++ b/.github/actions/find/src/types.d.ts @@ -31,3 +31,7 @@ export type AuthContextInput = { cookies?: Cookie[] localStorage?: LocalStorage } + +export type ReducedMotionPreference = 'reduce' | 'no-preference' | null + +export type ColorSchemePreference = 'light' | 'dark' | 'no-preference' | null From 8d104a27458e04eda683ddf7efbd195251ad2a21 Mon Sep 17 00:00:00 2001 From: Joyce Zhu Date: Thu, 26 Feb 2026 22:59:23 +0000 Subject: [PATCH 5/5] Clarify error messages/documentation --- .github/actions/find/README.md | 8 ++++++-- .github/actions/find/action.yml | 4 ++-- README.md | 8 ++++---- action.yml | 4 ++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/actions/find/README.md b/.github/actions/find/README.md index ae34bdc0..be4323c7 100644 --- a/.github/actions/find/README.md +++ b/.github/actions/find/README.md @@ -21,11 +21,15 @@ https://primer.style/octicons/ #### `reduced_motion` -**Optional** Playwright [`reducedMotion`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-reduced-motion) setting to emulate user preference. Allowed values: `reduce`, `no-preference`. +**Optional** Playwright +[`reducedMotion`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-reduced-motion) +configuration option. #### `color_scheme` -**Optional** Playwright [`colorScheme`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme) setting to emulate user preference. Allowed values: `light`, `dark`, `no-preference`. +**Optional** Playwright +[`colorScheme`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme) +configuration option. ### Outputs diff --git a/.github/actions/find/action.yml b/.github/actions/find/action.yml index e7873455..f4add9b4 100644 --- a/.github/actions/find/action.yml +++ b/.github/actions/find/action.yml @@ -14,10 +14,10 @@ inputs: required: false default: "false" reduced_motion: - description: "Playwright reducedMotion setting. Allowed values: 'reduce', 'no-preference'" + description: "Playwright reducedMotion setting: https://playwright.dev/docs/api/class-browser#browser-new-page-option-reduced-motion" required: false color_scheme: - description: "Playwright colorScheme setting. Allowed values: 'light', 'dark', 'no-preference'" + description: "Playwright colorScheme setting: https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme" required: false outputs: diff --git a/README.md b/README.md index 78e30c4b..06e2a358 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ jobs: # auth_context: # Optional: Stringified JSON object for complex authentication # skip_copilot_assignment: false # Optional: Set to true to skip assigning issues to GitHub Copilot (or if you don't have GitHub Copilot) # include_screenshots: false # Optional: Set to true to capture screenshots and include links to them in filed issues - # reduced_motion: no-preference # Optional: Playwright reduced motion emulation (`reduce` or `no-preference`) - # color_scheme: dark # Optional: Playwright color scheme emulation (`light`, `dark`, or `no-preference`) + # reduced_motion: no-preference # Optional: Playwright reduced motion configuration option + # color_scheme: light # Optional: Playwright color scheme configuration option ``` > 👉 Update all `REPLACE_THIS` placeholders with your actual values. See [Action Inputs](#action-inputs) for details. @@ -152,11 +152,11 @@ The a11y scanner leverages GitHub Copilot coding agent, which can be configured 💬 We welcome your feedback! To submit feedback or report issues, please create an issue in this repository. For more information on contributing, please refer to the [CONTRIBUTING](./CONTRIBUTING.md) file. -## License +## License 📄 This project is licensed under the terms of the MIT open source license. Please refer to the [LICENSE](./LICENSE) file for the full terms. -## Maintainers +## Maintainers 🔧 Please refer to the [CODEOWNERS](./.github/CODEOWNERS) file for more information. diff --git a/action.yml b/action.yml index 8859b6e6..063206dd 100644 --- a/action.yml +++ b/action.yml @@ -36,10 +36,10 @@ inputs: required: false default: "false" reduced_motion: - description: "Playwright reducedMotion setting for scans. Allowed values: 'reduce', 'no-preference'" + description: "Playwright reducedMotion setting: https://playwright.dev/docs/api/class-browser#browser-new-page-option-reduced-motion" required: false color_scheme: - description: "Playwright colorScheme setting for scans. Allowed values: 'light', 'dark', 'no-preference'" + description: "Playwright colorScheme setting: https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme" required: false outputs: