Skip to content

Commit 88d20c3

Browse files
feat: replace exclude input with urlConfig for per-URL selector exclusion
Agent-Logs-Url: https://github.com/github/accessibility-scanner/sessions/3565f54a-5878-479d-8bcd-ef2b85413be6 Co-authored-by: abdulahmad307 <204748719+abdulahmad307@users.noreply.github.com>
1 parent 9155530 commit 88d20c3

5 files changed

Lines changed: 51 additions & 26 deletions

File tree

.github/actions/find/action.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ description: 'Finds potential accessibility gaps.'
44
inputs:
55
urls:
66
description: 'Newline-delimited list of URLs to check for accessibility issues'
7-
required: true
7+
required: false
88
multiline: true
9+
url_config:
10+
description: "Stringified JSON array of URL config objects, each with a 'url' field and an optional 'excludeSelectors' field (array of CSS selectors to exclude from the Axe scan for that URL). When provided, takes precedence over the 'urls' input."
11+
required: false
912
auth_context:
1013
description: "Stringified JSON object containing 'username', 'password', 'cookies', and/or 'localStorage' from an authenticated session"
1114
required: false
@@ -22,9 +25,6 @@ inputs:
2225
color_scheme:
2326
description: 'Playwright colorScheme setting: https://playwright.dev/docs/api/class-browser#browser-new-context-option-color-scheme'
2427
required: false
25-
exclude:
26-
description: 'Stringified JSON array of CSS selectors to exclude from the Axe scan'
27-
required: false
2828

2929
outputs:
3030
findings_file:

.github/actions/find/src/index.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type {AuthContextInput, ColorSchemePreference, ReducedMotionPreference} from './types.js'
1+
import type {AuthContextInput, ColorSchemePreference, ReducedMotionPreference, UrlConfig} from './types.js'
22
import fs from 'node:fs'
33
import path from 'node:path'
44
import * as core from '@actions/core'
@@ -7,8 +7,37 @@ import {findForUrl} from './findForUrl.js'
77

88
export default async function () {
99
core.info("Starting 'find' action")
10-
const urls = core.getMultilineInput('urls', {required: true})
11-
core.debug(`Input: 'urls: ${JSON.stringify(urls)}'`)
10+
const urlConfigInput = core.getInput('url_config', {required: false})
11+
let urlConfigs: UrlConfig[] | undefined
12+
if (urlConfigInput) {
13+
try {
14+
const parsed = JSON.parse(urlConfigInput)
15+
if (!Array.isArray(parsed)) {
16+
throw new Error("Input 'url_config' must be a JSON array.")
17+
}
18+
for (const item of parsed) {
19+
if (typeof item !== 'object' || item === null || typeof item.url !== 'string') {
20+
throw new Error("Each entry in 'url_config' must be an object with a 'url' string field.")
21+
}
22+
}
23+
urlConfigs = parsed as UrlConfig[]
24+
} catch (e) {
25+
throw new Error(`Invalid 'url_config' input: ${(e as Error).message}`)
26+
}
27+
}
28+
29+
let urls: string[]
30+
if (urlConfigs) {
31+
core.debug(`Input: 'url_config: ${JSON.stringify(urlConfigs)}'`)
32+
urls = urlConfigs.map(c => c.url)
33+
} else {
34+
urls = core.getMultilineInput('urls', {required: false})
35+
core.debug(`Input: 'urls: ${JSON.stringify(urls)}'`)
36+
if (urls.length === 0) {
37+
throw new Error("Either 'urls' or 'url_config' input must be provided.")
38+
}
39+
}
40+
1241
const authContextInput: AuthContextInput = JSON.parse(core.getInput('auth_context', {required: false}) || '{}')
1342
const authContext = new AuthContext(authContextInput)
1443

@@ -34,20 +63,11 @@ export default async function () {
3463
colorScheme = colorSchemeInput as ColorSchemePreference
3564
}
3665

37-
const excludeInput = core.getInput('exclude', {required: false})
38-
let exclude: string[] | undefined
39-
if (excludeInput) {
40-
try {
41-
exclude = JSON.parse(excludeInput) as string[]
42-
} catch {
43-
throw new Error(`Input 'exclude' must be a valid JSON array of CSS selectors. Received: ${excludeInput}`)
44-
}
45-
}
46-
4766
const findings = []
4867
for (const url of urls) {
4968
core.info(`Preparing to scan ${url}`)
50-
const findingsForUrl = await findForUrl(url, authContext, includeScreenshots, reducedMotion, colorScheme, exclude)
69+
const excludeSelectors = urlConfigs?.find(c => c.url === url)?.excludeSelectors
70+
const findingsForUrl = await findForUrl(url, authContext, includeScreenshots, reducedMotion, colorScheme, excludeSelectors)
5171
if (findingsForUrl.length === 0) {
5272
core.info(`No accessibility gaps were found on ${url}`)
5373
continue

.github/actions/find/src/types.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,8 @@ export type AuthContextInput = {
3737
export type ReducedMotionPreference = 'reduce' | 'no-preference' | null
3838

3939
export type ColorSchemePreference = 'light' | 'dark' | 'no-preference' | null
40+
41+
export type UrlConfig = {
42+
url: string
43+
excludeSelectors?: string[]
44+
}

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
# reduced_motion: no-preference # Optional: Playwright reduced motion configuration option
5959
# color_scheme: light # Optional: Playwright color scheme configuration option
6060
# scans: '["axe","reflow-scan"]' # Optional: An array of scans (or plugins) to be performed. If not provided, only Axe will be performed.
61-
# exclude: '["iframe","#third-party-widget"]' # Optional: A JSON array of CSS selectors to exclude from the Axe scan.
61+
# url_config: '[{"url":"https://example.com","excludeSelectors":["iframe","#widget"]}]' # Optional: Per-URL config with CSS selectors to exclude from the Axe scan. When provided, takes precedence over 'urls'.
6262
```
6363

6464
> 👉 Update all `REPLACE_THIS` placeholders with your actual values. See [Action Inputs](#action-inputs) for details.
@@ -116,7 +116,7 @@ Trigger the workflow manually or automatically based on your configuration. The
116116

117117
| Input | Required | Description | Example |
118118
| ------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
119-
| `urls` | Yes | Newline-delimited list of URLs to scan | `https://primer.style`<br>`https://primer.style/octicons` |
119+
| `urls` | No* | Newline-delimited list of URLs to scan. Required unless `url_config` is provided. | `https://primer.style`<br>`https://primer.style/octicons` |
120120
| `repository` | Yes | Repository (with owner) for issues and PRs | `primer/primer-docs` |
121121
| `token` | Yes | PAT with write permissions (see above) | `${{ secrets.GH_TOKEN }}` |
122122
| `cache_key` | Yes | Key for caching results across runs<br>Allowed: `A-Za-z0-9._/-` | `cached_results-primer.style-main.json` |
@@ -131,7 +131,7 @@ Trigger the workflow manually or automatically based on your configuration. The
131131
| `reduced_motion` | No | Playwright `reducedMotion` setting for scan contexts. Allowed values: `reduce`, `no-preference` | `reduce` |
132132
| `color_scheme` | No | Playwright `colorScheme` setting for scan contexts. Allowed values: `light`, `dark`, `no-preference` | `dark` |
133133
| `scans` | No | An array of scans (or plugins) to be performed. If not provided, only Axe will be performed. | `'["axe", "reflow-scan", ...other plugins]'` |
134-
| `exclude` | No | A stringified JSON array of CSS selectors to exclude from the Axe scan. Useful for iframes, third-party widgets, or user-generated content. | `'["iframe","#third-party-widget"]'` |
134+
| `url_config` | No | A stringified JSON array of URL config objects. Each object must have a `url` field and may have an optional `excludeSelectors` field (array of CSS selectors to exclude from the Axe scan for that URL). When provided, takes precedence over the `urls` input. | `'[{"url":"https://example.com","excludeSelectors":["iframe","#widget"]}]'` |
135135

136136
---
137137

action.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ description: 'Finds potential accessibility gaps, files GitHub issues to track t
44
inputs:
55
urls:
66
description: 'Newline-delimited list of URLs to check for accessibility issues'
7-
required: true
7+
required: false
88
multiline: true
9+
url_config:
10+
description: "Stringified JSON array of URL config objects, each with a 'url' field and an optional 'excludeSelectors' field (array of CSS selectors to exclude from the Axe scan for that URL). When provided, takes precedence over the 'urls' input."
11+
required: false
912
repository:
1013
description: 'Repository (with owner) to file issues in'
1114
required: true
@@ -51,9 +54,6 @@ inputs:
5154
scans:
5255
description: 'Stringified JSON array of scans to perform. If not provided, only Axe will be performed'
5356
required: false
54-
exclude:
55-
description: 'Stringified JSON array of CSS selectors to exclude from the Axe scan'
56-
required: false
5757

5858
outputs:
5959
results:
@@ -112,12 +112,12 @@ runs:
112112
uses: ./../../_actions/github/accessibility-scanner/current/.github/actions/find
113113
with:
114114
urls: ${{ inputs.urls }}
115+
url_config: ${{ inputs.url_config }}
115116
auth_context: ${{ inputs.auth_context || steps.auth.outputs.auth_context }}
116117
include_screenshots: ${{ inputs.include_screenshots }}
117118
reduced_motion: ${{ inputs.reduced_motion }}
118119
color_scheme: ${{ inputs.color_scheme }}
119120
scans: ${{ inputs.scans }}
120-
exclude: ${{ inputs.exclude }}
121121
- name: File
122122
id: file
123123
uses: ./../../_actions/github/accessibility-scanner/current/.github/actions/file

0 commit comments

Comments
 (0)