forked from adevinta/spark
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck-a11y.js
104 lines (84 loc) · 3.14 KB
/
check-a11y.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env node
import { readFileSync } from 'fs'
import chalk from 'chalk'
import AxeBuilder from '@axe-core/webdriverjs'
import { Builder, By, until } from 'selenium-webdriver'
import { Options } from 'selenium-webdriver/firefox.js'
const impactColor = {
minor: chalk.hex('#ffff00'),
moderate: chalk.hex('#ffa500'),
serious: chalk.hex('#ff0000'),
critical: chalk.red,
}
const { stories } = JSON.parse(readFileSync('dist/stories.json', 'utf8'))
const pkgFilter = process.argv.slice(2).map((pkgPath) => `./${pkgPath.split('/src')[0]}`) ?? []
const storiesList = Object.keys(stories).reduce((acc, cur) => {
const isComponentStory = (story) => (story.importPath).startsWith('./packages/components/') && !(story.id).endsWith('--docs')
const belongsToFilter = (story, filter) => filter.includes(stories[cur].importPath.split('/src')[0])
if (isComponentStory(stories[cur])) {
if (pkgFilter.length && !belongsToFilter(stories[cur], pkgFilter)) {
return acc
}
acc.push(stories[cur].id)
}
return acc
}, [])
let issues = {
minor: 0,
moderate: 0,
serious: 0,
critical: 0,
}
const checkA11y = async () => {
const driver = new Builder()
.forBrowser('firefox')
.setFirefoxOptions(new Options().headless())
.build()
for (const storyId of storiesList) {
console.log(`Checking accessibility for ${stories[storyId].title}...`)
try {
await driver.get(`http://localhost:6006/iframe.html?viewMode=story&id=${storyId}`)
const results = await new AxeBuilder(driver)
.options({
resultTypes: ['violations', 'incomplete'],
rules: {
'page-has-heading-one': { enabled: false },
'landmark-one-main': { enabled: false },
'region': { enabled: false },
'color-contrast': { enabled: false },
},
runOnly: ['best-practice', 'wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'],
reporter: 'no-passes',
})
.exclude('.docblock-argstable')
.analyze()
if (results.violations.length) {
issues = results.violations.reduce((acc, cur) => {
acc[cur.impact] += cur.nodes.length
return acc
},
{
minor: 0,
moderate: 0,
serious: 0,
critical: 0,
})
console.log(chalk.bold(`${stories[storyId].title} issues (${Object.values(issues).reduce((a, b) => a + b, 0)}): ${impactColor.minor(issues.minor)} minor, ${impactColor.moderate(issues.moderate)} moderate, ${impactColor.serious(issues.serious)} serious, ${impactColor.critical(issues.critical)} critical`))
results.violations.forEach((issue) => {
console.log(`- ${issue.help} (${impactColor[issue.impact](`${issue.nodes.length}`)})`)
})
console.log()
}
} catch (e) {
console.error(chalk.bold.red(e.message))
}
}
const totalIssues = Object.values(issues).reduce((a, b) => a + b, 0)
if (totalIssues === 0) {
console.log()
console.log(chalk.bold.green('🎉 Congratulations, no accessibility issue has been found!'))
}
if (issues.critical) process.exit(1)
await driver.quit()
}
checkA11y()