-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
pa11y.js
151 lines (131 loc) · 4.04 KB
/
pa11y.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* eslint-disable no-console */
const puppeteer = require('puppeteer');
const pa11y = require('pa11y');
const NUMBER_OF_BROWSERS = 5;
async function runPa11y() {
const browsers = [
{
browser: await puppeteer.launch(),
taken: new Promise((resolve) => {
resolve();
}),
},
{
browser: await puppeteer.launch(),
taken: new Promise((resolve) => {
resolve();
}),
},
{
browser: await puppeteer.launch(),
taken: new Promise((resolve) => {
resolve();
}),
},
{
browser: await puppeteer.launch(),
taken: new Promise((resolve) => {
resolve();
}),
},
{
browser: await puppeteer.launch(),
taken: new Promise((resolve) => {
resolve();
}),
},
];
await browsers.forEach(async (instance) => {
// eslint-disable-next-line require-atomic-updates
instance.page = await instance.browser.newPage();
});
let browserIndex = 0;
const results = [];
const setupBrowser = browsers[0].browser;
const page = await setupBrowser.newPage();
// eslint-disable-next-line node/no-path-concat
const iframePath = `file://${__dirname}/../build/storybook/static/iframe.html`;
const stories = await page
.goto(iframePath)
.then(() => page.evaluate(() => window.__STORYBOOK_CLIENT_API__.raw()));
const storyQueryStrings = stories.reduce((memo, story) => {
// There is no need to test the Playground, or the "All Examples" stories
const isSkippedStory =
story.kind === 'Playground|Playground' || story.name === 'All Examples';
if (!isSkippedStory) {
const idParam = `id=${encodeURIComponent(story.id)}`;
memo.push(
idParam,
`${idParam}&contexts=Global%20Theming=Enabled%20-%20Light%20Mode`,
// Dark mode has lots of errors. It is still very WIP so ignore for now
// `${idParam}&contexts=Global%20Theming=Enabled%20-%20Dark%20Mode`,
);
}
return memo;
}, []);
storyQueryStrings.forEach((queryString) => {
const currentBrowser = browsers[browserIndex % NUMBER_OF_BROWSERS];
browserIndex++;
currentBrowser.taken = currentBrowser.taken.then(async () => {
console.log('Testing ', queryString);
const result = await pa11y(`${iframePath}?${queryString}`, {
browser: currentBrowser.browser,
ignore: [
// Missing lang attribute on <html> tag
// Storybook does not include this property so ignore it
'WCAG2AA.Principle3.Guideline3_1.3_1_1.H57.2',
],
});
result.exampleID = queryString;
delete result.pageUrl;
results.push(result);
});
});
await Promise.all(browsers.map((instance) => instance.taken));
await Promise.all(browsers.map((instance) => instance.browser.close()));
return results;
}
(async () => {
let rawResults;
try {
rawResults = await runPa11y();
if (rawResults.length === 0) {
throw new Error('Component URLs could not be crawled');
}
} catch (error) {
console.log(error);
process.exit(1);
}
const results = rawResults.filter((result) => result.issues.length);
if (results.length) {
console.log(
`
========================================================================
The following issues were discovered and need to be fixed before this code can be merged
========================================================================
`,
);
results.forEach((result) => {
console.log(
'------------------------------------------------------------------------',
);
console.log(result.exampleID);
console.log(
'------------------------------------------------------------------------',
);
console.log(JSON.stringify(result.issues, null, 2));
});
} else {
console.log(
`
========================================================================
No issues were discovered!
========================================================================
`,
);
}
if (results.length) {
process.exit(1);
}
process.exit(0);
})();