Skip to content

Commit 5edd8b4

Browse files
committed
Adds reflow scan plugin
1 parent 28ba71e commit 5edd8b4

15 files changed

Lines changed: 54 additions & 32 deletions

File tree

.github/actions/file/src/generateIssueBody.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function generateIssueBody(finding: Finding, screenshotRepo: string): str
2626
`
2727

2828
const body = `## What
29-
An accessibility scan flagged the element \`${finding.html}\` on ${finding.url} because ${finding.problemShort}. Learn more about why this was flagged by visiting ${finding.problemUrl}.
29+
An accessibility scan ${finding.html ? `flagged the element \`${finding.html}\`` : `found an issue on ${finding.url}`} because ${finding.problemShort}. Learn more about why this was flagged by visiting ${finding.problemUrl}.
3030
3131
${screenshotSection ?? ''}
3232
To fix this, ${finding.solutionShort}.

.github/actions/file/src/openIssue.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ export async function openIssue(octokit: Octokit, repoWithOwner: string, finding
2121
const owner = repoWithOwner.split('/')[0]
2222
const repo = repoWithOwner.split('/')[1]
2323

24-
const labels = [`${finding.scannerType} rule: ${finding.ruleId}`, `${finding.scannerType}-scanning-issue`]
24+
const labels = [
25+
`${finding.scannerType}${finding.ruleId ? ` rule: ${finding.ruleId}` : ''}`,
26+
`${finding.scannerType}-scanning-issue`,
27+
]
2528
const title = truncateWithEllipsis(
2629
`Accessibility issue: ${finding.problemShort[0].toUpperCase() + finding.problemShort.slice(1)} on ${new URL(finding.url).pathname}`,
2730
GITHUB_ISSUE_TITLE_MAX_LENGTH,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
export type Finding = {
22
scannerType: string
3-
ruleId: string
3+
ruleId?: string
44
url: string
5-
html: string
5+
html?: string
66
problemShort: string
77
problemUrl: string
88
solutionShort: string

.github/actions/file/src/updateFilingsWithNewFindings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ function getFilingKey(filing: ResolvedFiling | RepeatedFiling): string {
55
}
66

77
function getFindingKey(finding: Finding): string {
8-
return `${finding.url};${finding.ruleId};${finding.html}`
8+
return `${finding.url};${finding.ruleId ?? ''};${finding.html ?? ''}`
99
}
1010

1111
export function updateFilingsWithNewFindings(

.github/actions/file/tests/generateIssueBody.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ const baseFinding = {
1111
solutionShort: 'ensure the contrast between foreground and background colors meets WCAG thresholds',
1212
}
1313

14+
const findingWithEmptyOptionalFields = {
15+
scannerType: 'reflow',
16+
url: 'https://example.com/page',
17+
problemShort: 'elements must meet minimum color contrast ratio thresholds',
18+
problemUrl: 'https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=playwright',
19+
solutionShort: 'ensure the contrast between foreground and background colors meets WCAG thresholds',
20+
}
21+
1422
describe('generateIssueBody', () => {
1523
it('includes acceptance criteria and omits the Specifically section when solutionLong is missing', () => {
1624
const body = generateIssueBody(baseFinding, 'github/accessibility-scanner')
@@ -61,4 +69,11 @@ describe('generateIssueBody', () => {
6169
expect(body).not.toContain('View screenshot')
6270
expect(body).not.toContain('.screenshots')
6371
})
72+
73+
it('uses url fallback when html is not present', () => {
74+
const body = generateIssueBody(findingWithEmptyOptionalFields, 'github/accessibility-scanner')
75+
76+
expect(body).toContain(`found an issue on ${findingWithEmptyOptionalFields.url}`)
77+
expect(body).not.toContain('flagged the element')
78+
})
6479
})

.github/actions/find/src/findForUrl.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export async function findForUrl(
4848
plugin,
4949
page,
5050
addFinding,
51+
url,
5152
})
5253
} else {
5354
core.info(`Skipping plugin ${plugin.name} because it is not included in the 'scans' input`)

.github/actions/find/src/pluginManager.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const __dirname = path.dirname(__filename)
1313
type PluginDefaultParams = {
1414
page: playwright.Page
1515
addFinding: (findingData: Finding) => void
16+
url: string
1617
}
1718

1819
type Plugin = {
@@ -102,6 +103,6 @@ export async function loadPluginsFromPath({pluginsPath}: {pluginsPath: string})
102103
type InvokePluginParams = PluginDefaultParams & {
103104
plugin: Plugin
104105
}
105-
export function invokePlugin({plugin, page, addFinding}: InvokePluginParams) {
106-
return plugin.default({page, addFinding})
106+
export function invokePlugin({plugin, page, addFinding, url}: InvokePluginParams) {
107+
return plugin.default({page, addFinding, url})
107108
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export type Finding = {
22
scannerType: string
33
url: string
4-
html: string
4+
html?: string
55
problemShort: string
66
problemUrl: string
77
solutionShort: string
Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,25 @@
1-
export default async function test({ page, addFinding, url } = {}) {
2-
console.log('test plugin');
3-
// Check for horizontal scrolling at 320x256 viewport
1+
export default async function reflowScan({ page, addFinding, url } = {}) {
2+
console.log('reflow plugin');
3+
// Check for horizontal scrolling at 320x256 viewport
44
try {
55
await page.setViewportSize({ width: 320, height: 256 });
66
const scrollWidth = await page.evaluate(() => document.documentElement.scrollWidth);
77
const clientWidth = await page.evaluate(() => document.documentElement.clientWidth);
88

99
// If horizontal scroll is required (with 1px tolerance for rounding)
1010
if (scrollWidth > clientWidth + 1) {
11-
const htmlSnippet = await page.evaluate(() => {
12-
return `<html lang="${document.documentElement.lang || 'en'}">`;
13-
});
14-
15-
addFinding({
16-
scannerType: 'viewport',
17-
ruleId: 'horizontal-scroll-320x256',
11+
await addFinding({
12+
scannerType: 'reflow-scan',
1813
url,
19-
html: htmlSnippet.replace(/'/g, "&apos;"),
20-
problemShort: 'page requires horizontal scrolling at 320x256 viewport',
14+
problemShort: 'Page requires horizontal scrolling at 320x256 viewport',
2115
problemUrl: 'https://www.w3.org/WAI/WCAG21/Understanding/reflow.html',
22-
solutionShort: 'ensure content is responsive and does not require horizontal scrolling at small viewport sizes',
16+
solutionShort: 'Ensure content is responsive and does not require horizontal scrolling at small viewport sizes',
2317
solutionLong: `The page has a scroll width of ${scrollWidth}px but a client width of only ${clientWidth}px at 320x256 viewport, requiring horizontal scrolling. This violates WCAG 2.1 Level AA Success Criterion 1.4.10 (Reflow).`
2418
});
2519
}
2620
} catch (e) {
2721
console.error('Error checking horizontal scroll:', e);
2822
}
29-
3023
}
3124

32-
export const name = 'test-plugin';
25+
export const name = 'reflow-scan';
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "reflow-scan",
3+
"version": "1.0.0",
4+
"description": "Scans pages at a 320x256 viewport size to identify potential reflow issues, such as horizontal scrolling and content overflow.",
5+
"type": "module"
6+
}

0 commit comments

Comments
 (0)