diff --git a/.github/actions/find/README.md b/.github/actions/find/README.md index f674e23..be4323c 100644 --- a/.github/actions/find/README.md +++ b/.github/actions/find/README.md @@ -19,6 +19,18 @@ 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) +configuration option. + +#### `color_scheme` + +**Optional** Playwright +[`colorScheme`](https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme) +configuration option. + ### Outputs #### `findings` diff --git a/.github/actions/find/action.yml b/.github/actions/find/action.yml index 2ab8dcb..f4add9b 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: https://playwright.dev/docs/api/class-browser#browser-new-page-option-reduced-motion" + required: false + color_scheme: + description: "Playwright colorScheme setting: https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme" + required: false outputs: findings: diff --git a/.github/actions/find/package-lock.json b/.github/actions/find/package-lock.json index eb0f134..6208a9a 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 f24057c..bff83b2 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,12 +8,18 @@ export async function findForUrl( url: string, authContext?: AuthContext, includeScreenshots: boolean = false, + reducedMotion?: ReducedMotionPreference, + colorScheme?: ColorSchemePreference, ): 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 4688606..60de50e 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' @@ -11,11 +11,31 @@ 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: ReducedMotionPreference | undefined + if (reducedMotionInput) { + 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 ReducedMotionPreference + } + const colorSchemeInput = core.getInput('color_scheme', {required: false}) + let colorScheme: ColorSchemePreference | undefined + if (colorSchemeInput) { + 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 ColorSchemePreference + } 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/.github/actions/find/src/types.d.ts b/.github/actions/find/src/types.d.ts index 72582c4..ce226ea 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 diff --git a/README.md b/README.md index 3c9cebc..06e2a35 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 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. @@ -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` | --- @@ -148,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 932bc27..063206d 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: https://playwright.dev/docs/api/class-browser#browser-new-page-option-reduced-motion" + required: false + color_scheme: + description: "Playwright colorScheme setting: https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme" + 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