-
Notifications
You must be signed in to change notification settings - Fork 31
Adds reflow scan plugin #173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
5edd8b4
6ac9324
1a50d81
b80cbb9
d250560
79d3cfa
c050d25
3cf1970
daed7e9
738ba9c
9e6acc4
953a7b5
381f66f
4eab30a
effdb30
8985ccc
d397134
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,8 @@ const __dirname = path.dirname(__filename) | |
|
|
||
| type PluginDefaultParams = { | ||
| page: playwright.Page | ||
| addFinding: (findingData: Finding) => void | ||
| addFinding: (findingData: Finding) => Promise<void> | ||
| url: string | ||
| } | ||
|
|
||
| type Plugin = { | ||
|
|
@@ -65,7 +66,7 @@ export async function loadCustomPlugins() { | |
|
|
||
| // - currently, the plugin manager will abort loading | ||
| // all plugins if there's an error | ||
| // - the problem with this is that if a scanner user doesnt | ||
| // - the problem with this is that if a scanner user doesn't | ||
| // have custom plugins, they won't have a 'scanner-plugins' folder | ||
| // which will cause an error and abort loading all plugins, including built-in ones | ||
| // - so for custom plugins, if the path doesn't exist, we can return early | ||
|
|
@@ -87,7 +88,13 @@ export async function loadPluginsFromPath({pluginsPath}: {pluginsPath: string}) | |
|
|
||
| if (fs.existsSync(pluginFolderPath) && fs.lstatSync(pluginFolderPath).isDirectory()) { | ||
| core.info(`Found plugin: ${pluginFolder}`) | ||
| plugins.push(await dynamicImport(path.join(pluginsPath, pluginFolder, 'index.js'))) | ||
| const plugin = await dynamicImport(path.join(pluginsPath, pluginFolder, 'index.js')) | ||
| // Prevents a plugin from running twice | ||
| if (plugins.some(p => p.name === plugin.name)) { | ||
| core.info(`Skipping duplicate plugin: ${plugin.name}`) | ||
| continue | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change was needed because when testing within this repo, the
A slim edge case, but we needed to handle it for the tests in this repo.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we should namespace our plugins. so it would be something like One of the things we discussed was that it's on the plugin authors to ensure that names are unique - does that apply in this case? or are we saying that it only applies when the name clash happens between two custom plugins (so it doesnt apply if the name clash happens between 1 built-in and 1 custom plugin)? I don't know if I'm leaning one way or another 🤔
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think one disadvantage of programmatically removing (skipping) a plugin is we can't control which one gets skipped. With the current change, only the first one in the file-system will load, but what if we want the second one to load? would we not then revert to having to change the name anyway? I guess I'm realizing that ensuring names are unique is still going to be the end result in many cases, so we should just use that as a criteria for loading plugins
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could namespace our plugins, but in the case of any we add to the accessibility-scanner repo we would still run into it loading twice only in our tests -- specifically with the So we'd run into this issue if someone else created a custom plugin called "reflow-scan" in their own The alternative to the issue we're running into in our tests is to either:
I'm not really in love with either of these options, though... I guess a third alternative is if someone does create a naming clash and we are to skip the plugin, it could
Are you talking about ensuring for unique names? |
||
| plugins.push(plugin) | ||
| } | ||
| } | ||
| } catch (e) { | ||
|
|
@@ -102,6 +109,6 @@ export async function loadPluginsFromPath({pluginsPath}: {pluginsPath: string}) | |
| type InvokePluginParams = PluginDefaultParams & { | ||
| plugin: Plugin | ||
| } | ||
| export function invokePlugin({plugin, page, addFinding}: InvokePluginParams) { | ||
| return plugin.default({page, addFinding}) | ||
| export function invokePlugin({plugin, page, addFinding, url}: InvokePluginParams) { | ||
| return plugin.default({page, addFinding, url}) | ||
|
lindseywild marked this conversation as resolved.
Outdated
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,32 +1,31 @@ | ||
| export default async function test({ page, addFinding, url } = {}) { | ||
| console.log('test plugin'); | ||
| // Check for horizontal scrolling at 320x256 viewport | ||
| export default async function reflowScan({ page, addFinding, url } = {}) { | ||
| console.log('reflow plugin'); | ||
| const originalViewport = page.viewportSize() | ||
| // Check for horizontal scrolling at 320x256 viewport | ||
| try { | ||
| await page.setViewportSize({ width: 320, height: 256 }); | ||
| const scrollWidth = await page.evaluate(() => document.documentElement.scrollWidth); | ||
| const clientWidth = await page.evaluate(() => document.documentElement.clientWidth); | ||
| await page.setViewportSize({width: 320, height: 256}) | ||
| const scrollWidth = await page.evaluate(() => document.documentElement.scrollWidth) | ||
| const clientWidth = await page.evaluate(() => document.documentElement.clientWidth) | ||
|
|
||
| // If horizontal scroll is required (with 1px tolerance for rounding) | ||
| if (scrollWidth > clientWidth + 1) { | ||
| const htmlSnippet = await page.evaluate(() => { | ||
| return `<html lang="${document.documentElement.lang || 'en'}">`; | ||
| }); | ||
|
|
||
| addFinding({ | ||
| scannerType: 'viewport', | ||
| ruleId: 'horizontal-scroll-320x256', | ||
| await addFinding({ | ||
| scannerType: 'reflow-scan', | ||
| url, | ||
| html: htmlSnippet.replace(/'/g, "'"), | ||
| problemShort: 'page requires horizontal scrolling at 320x256 viewport', | ||
| problemUrl: 'https://www.w3.org/WAI/WCAG21/Understanding/reflow.html', | ||
| solutionShort: 'ensure content is responsive and does not require horizontal scrolling at small viewport sizes', | ||
| 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).` | ||
| }); | ||
| 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).`, | ||
| }) | ||
| } | ||
| } catch (e) { | ||
| console.error('Error checking horizontal scroll:', e); | ||
| console.error('Error checking horizontal scroll:', e) | ||
| } finally { | ||
| // Restore original viewport so subsequent scans (e.g. Axe) aren't affected | ||
| if (originalViewport) { | ||
| await page.setViewportSize(originalViewport) | ||
| } | ||
| } | ||
|
|
||
| } | ||
|
|
||
| export const name = 'test-plugin'; | ||
| export const name = 'reflow-scan'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| { | ||
| "name": "reflow-scan", | ||
| "version": "1.0.0", | ||
| "description": "Scans pages at a 320x256 viewport size to identify potential reflow issues, such as horizontal scrolling and content overflow.", | ||
| "type": "module" | ||
| } |
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.