@storybook/addon-a11y 9.2.0-alpha.3 → 10.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/_browser-chunks/chunk-JFJ5UJ7Q.js +11 -0
- package/dist/_browser-chunks/chunk-ULDMWS76.js +25 -0
- package/dist/_browser-chunks/chunk-XD4HDXPO.js +217 -0
- package/dist/_browser-chunks/matchers-ZRZBO4XZ.js +1987 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -26
- package/dist/manager.js +3395 -13
- package/dist/postinstall.js +7413 -62
- package/dist/preview.d.ts +3 -50
- package/dist/preview.d.tsx +50 -0
- package/dist/preview.js +12 -25
- package/package.json +24 -45
- package/preview.js +1 -1
- package/dist/chunk-CEH6MNVV.mjs +0 -3
- package/dist/index.mjs +0 -10
- package/dist/matchers-7Z3WT2CE.mjs +0 -16
- package/dist/matchers-TIWVOQAP.mjs +0 -18
- package/dist/preview.mjs +0 -8
- package/manager.js +0 -1
package/README.md
CHANGED
|
@@ -10,4 +10,6 @@ The @storybook/addon-a11y package provides accessibility testing for Storybook s
|
|
|
10
10
|
npx storybook add @storybook/addon-a11y
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
[More on getting started with the accessibility addon](https://storybook.js.org/docs/writing-tests/accessibility-testing#accessibility-checks-with-a11y-addon)
|
|
13
|
+
[More on getting started with the accessibility addon](https://storybook.js.org/docs/writing-tests/accessibility-testing#accessibility-checks-with-a11y-addon?ref=readme)
|
|
14
|
+
|
|
15
|
+
Learn more about Storybook at [storybook.js.org](https://storybook.js.org/?ref=readme).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
__name,
|
|
10
|
+
__export
|
|
11
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/constants.ts
|
|
2
|
+
var ADDON_ID = "storybook/a11y";
|
|
3
|
+
var PANEL_ID = `${ADDON_ID}/panel`;
|
|
4
|
+
var PARAM_KEY = `a11y`;
|
|
5
|
+
var RESULT = `${ADDON_ID}/result`;
|
|
6
|
+
var REQUEST = `${ADDON_ID}/request`;
|
|
7
|
+
var RUNNING = `${ADDON_ID}/running`;
|
|
8
|
+
var ERROR = `${ADDON_ID}/error`;
|
|
9
|
+
var MANUAL = `${ADDON_ID}/manual`;
|
|
10
|
+
var SELECT = `${ADDON_ID}/select`;
|
|
11
|
+
var DOCUMENTATION_LINK = "writing-tests/accessibility-testing";
|
|
12
|
+
var DOCUMENTATION_DISCREPANCY_LINK = `${DOCUMENTATION_LINK}#why-are-my-tests-failing-in-different-environments`;
|
|
13
|
+
var EVENTS = { RESULT, REQUEST, RUNNING, ERROR, MANUAL, SELECT };
|
|
14
|
+
var STATUS_TYPE_ID_COMPONENT_TEST = "storybook/component-test";
|
|
15
|
+
var STATUS_TYPE_ID_A11Y = "storybook/a11y";
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
ADDON_ID,
|
|
19
|
+
PANEL_ID,
|
|
20
|
+
PARAM_KEY,
|
|
21
|
+
DOCUMENTATION_DISCREPANCY_LINK,
|
|
22
|
+
EVENTS,
|
|
23
|
+
STATUS_TYPE_ID_COMPONENT_TEST,
|
|
24
|
+
STATUS_TYPE_ID_A11Y
|
|
25
|
+
};
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EVENTS,
|
|
3
|
+
PANEL_ID
|
|
4
|
+
} from "./chunk-ULDMWS76.js";
|
|
5
|
+
import {
|
|
6
|
+
__export,
|
|
7
|
+
__name
|
|
8
|
+
} from "./chunk-JFJ5UJ7Q.js";
|
|
9
|
+
|
|
10
|
+
// src/preview.tsx
|
|
11
|
+
var preview_exports = {};
|
|
12
|
+
__export(preview_exports, {
|
|
13
|
+
afterEach: () => afterEach,
|
|
14
|
+
initialGlobals: () => initialGlobals,
|
|
15
|
+
parameters: () => parameters
|
|
16
|
+
});
|
|
17
|
+
import { expect } from "storybook/test";
|
|
18
|
+
|
|
19
|
+
// src/a11yRunner.ts
|
|
20
|
+
import { ElementA11yParameterError } from "storybook/internal/preview-errors";
|
|
21
|
+
import { global as global2 } from "@storybook/global";
|
|
22
|
+
import { addons, waitForAnimations } from "storybook/preview-api";
|
|
23
|
+
|
|
24
|
+
// src/a11yRunnerUtils.ts
|
|
25
|
+
import { global } from "@storybook/global";
|
|
26
|
+
var { document } = global;
|
|
27
|
+
var withLinkPaths = /* @__PURE__ */ __name((results, storyId) => {
|
|
28
|
+
const pathname = document.location.pathname.replace(/iframe\.html$/, "");
|
|
29
|
+
const enhancedResults = { ...results };
|
|
30
|
+
const propertiesToAugment = ["incomplete", "passes", "violations"];
|
|
31
|
+
propertiesToAugment.forEach((key) => {
|
|
32
|
+
if (Array.isArray(results[key])) {
|
|
33
|
+
enhancedResults[key] = results[key].map((result) => ({
|
|
34
|
+
...result,
|
|
35
|
+
nodes: result.nodes.map((node, index) => {
|
|
36
|
+
const id = `${key}.${result.id}.${index + 1}`;
|
|
37
|
+
const linkPath = `${pathname}?path=/story/${storyId}&addonPanel=${PANEL_ID}&a11ySelection=${id}`;
|
|
38
|
+
return { id, ...node, linkPath };
|
|
39
|
+
})
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return enhancedResults;
|
|
44
|
+
}, "withLinkPaths");
|
|
45
|
+
|
|
46
|
+
// src/a11yRunner.ts
|
|
47
|
+
var { document: document2 } = global2;
|
|
48
|
+
var channel = addons.getChannel();
|
|
49
|
+
var DEFAULT_PARAMETERS = { config: {}, options: {} };
|
|
50
|
+
var DISABLED_RULES = [
|
|
51
|
+
// In component testing, landmarks are not always present
|
|
52
|
+
// and the rule check can cause false positives
|
|
53
|
+
"region"
|
|
54
|
+
];
|
|
55
|
+
var queue = [];
|
|
56
|
+
var isRunning = false;
|
|
57
|
+
var runNext = /* @__PURE__ */ __name(async () => {
|
|
58
|
+
if (queue.length === 0) {
|
|
59
|
+
isRunning = false;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
isRunning = true;
|
|
63
|
+
const next = queue.shift();
|
|
64
|
+
if (next) {
|
|
65
|
+
await next();
|
|
66
|
+
}
|
|
67
|
+
runNext();
|
|
68
|
+
}, "runNext");
|
|
69
|
+
var run = /* @__PURE__ */ __name(async (input = DEFAULT_PARAMETERS, storyId) => {
|
|
70
|
+
const axeCore = await import("axe-core");
|
|
71
|
+
const axe = axeCore?.default || globalThis.axe;
|
|
72
|
+
const { config = {}, options = {} } = input;
|
|
73
|
+
if (input.element) {
|
|
74
|
+
throw new ElementA11yParameterError();
|
|
75
|
+
}
|
|
76
|
+
const context = {
|
|
77
|
+
include: document2?.body,
|
|
78
|
+
exclude: [".sb-wrapper", "#storybook-docs", "#storybook-highlights-root"]
|
|
79
|
+
// Internal Storybook elements that are always in the document
|
|
80
|
+
};
|
|
81
|
+
if (input.context) {
|
|
82
|
+
const hasInclude = typeof input.context === "object" && "include" in input.context && input.context.include !== void 0;
|
|
83
|
+
const hasExclude = typeof input.context === "object" && "exclude" in input.context && input.context.exclude !== void 0;
|
|
84
|
+
if (hasInclude) {
|
|
85
|
+
context.include = input.context.include;
|
|
86
|
+
} else if (!hasInclude && !hasExclude) {
|
|
87
|
+
context.include = input.context;
|
|
88
|
+
}
|
|
89
|
+
if (hasExclude) {
|
|
90
|
+
context.exclude = context.exclude.concat(input.context.exclude);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
axe.reset();
|
|
94
|
+
const configWithDefault = {
|
|
95
|
+
...config,
|
|
96
|
+
rules: [...DISABLED_RULES.map((id) => ({ id, enabled: false })), ...config?.rules ?? []]
|
|
97
|
+
};
|
|
98
|
+
axe.configure(configWithDefault);
|
|
99
|
+
return new Promise((resolve, reject) => {
|
|
100
|
+
const highlightsRoot = document2?.getElementById("storybook-highlights-root");
|
|
101
|
+
if (highlightsRoot) {
|
|
102
|
+
highlightsRoot.style.display = "none";
|
|
103
|
+
}
|
|
104
|
+
const task = /* @__PURE__ */ __name(async () => {
|
|
105
|
+
try {
|
|
106
|
+
const result = await axe.run(context, options);
|
|
107
|
+
const resultWithLinks = withLinkPaths(result, storyId);
|
|
108
|
+
resolve(resultWithLinks);
|
|
109
|
+
} catch (error) {
|
|
110
|
+
reject(error);
|
|
111
|
+
}
|
|
112
|
+
}, "task");
|
|
113
|
+
queue.push(task);
|
|
114
|
+
if (!isRunning) {
|
|
115
|
+
runNext();
|
|
116
|
+
}
|
|
117
|
+
if (highlightsRoot) {
|
|
118
|
+
highlightsRoot.style.display = "";
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}, "run");
|
|
122
|
+
channel.on(EVENTS.MANUAL, async (storyId, input = DEFAULT_PARAMETERS) => {
|
|
123
|
+
try {
|
|
124
|
+
await waitForAnimations();
|
|
125
|
+
const result = await run(input, storyId);
|
|
126
|
+
const resultJson = JSON.parse(JSON.stringify(result));
|
|
127
|
+
channel.emit(EVENTS.RESULT, resultJson, storyId);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
channel.emit(EVENTS.ERROR, error);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// src/utils.ts
|
|
134
|
+
function getIsVitestStandaloneRun() {
|
|
135
|
+
try {
|
|
136
|
+
return import.meta.env.VITEST_STORYBOOK === "false";
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
__name(getIsVitestStandaloneRun, "getIsVitestStandaloneRun");
|
|
142
|
+
|
|
143
|
+
// src/preview.tsx
|
|
144
|
+
var vitestMatchersExtended = false;
|
|
145
|
+
var afterEach = /* @__PURE__ */ __name(async ({
|
|
146
|
+
id: storyId,
|
|
147
|
+
reporting,
|
|
148
|
+
parameters: parameters2,
|
|
149
|
+
globals,
|
|
150
|
+
viewMode
|
|
151
|
+
}) => {
|
|
152
|
+
const a11yParameter = parameters2.a11y;
|
|
153
|
+
const a11yGlobals = globals.a11y;
|
|
154
|
+
const shouldRunEnvironmentIndependent = a11yParameter?.disable !== true && a11yParameter?.test !== "off" && a11yGlobals?.manual !== true;
|
|
155
|
+
const getMode = /* @__PURE__ */ __name(() => {
|
|
156
|
+
switch (a11yParameter?.test) {
|
|
157
|
+
case "todo":
|
|
158
|
+
return "warning";
|
|
159
|
+
case "error":
|
|
160
|
+
default:
|
|
161
|
+
return "failed";
|
|
162
|
+
}
|
|
163
|
+
}, "getMode");
|
|
164
|
+
if (shouldRunEnvironmentIndependent && viewMode === "story") {
|
|
165
|
+
try {
|
|
166
|
+
const result = await run(a11yParameter, storyId);
|
|
167
|
+
if (result) {
|
|
168
|
+
const hasViolations = (result?.violations.length ?? 0) > 0;
|
|
169
|
+
reporting.addReport({
|
|
170
|
+
type: "a11y",
|
|
171
|
+
version: 1,
|
|
172
|
+
result,
|
|
173
|
+
status: hasViolations ? getMode() : "passed"
|
|
174
|
+
});
|
|
175
|
+
if (getIsVitestStandaloneRun()) {
|
|
176
|
+
if (hasViolations && getMode() === "failed") {
|
|
177
|
+
if (!vitestMatchersExtended) {
|
|
178
|
+
const { toHaveNoViolations } = await import("./matchers-ZRZBO4XZ.js");
|
|
179
|
+
expect.extend({ toHaveNoViolations });
|
|
180
|
+
vitestMatchersExtended = true;
|
|
181
|
+
}
|
|
182
|
+
expect(result).toHaveNoViolations();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
} catch (e) {
|
|
187
|
+
reporting.addReport({
|
|
188
|
+
type: "a11y",
|
|
189
|
+
version: 1,
|
|
190
|
+
result: {
|
|
191
|
+
error: e
|
|
192
|
+
},
|
|
193
|
+
status: "failed"
|
|
194
|
+
});
|
|
195
|
+
if (getIsVitestStandaloneRun()) {
|
|
196
|
+
throw e;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}, "afterEach");
|
|
201
|
+
var initialGlobals = {
|
|
202
|
+
a11y: {
|
|
203
|
+
manual: false
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
var parameters = {
|
|
207
|
+
a11y: {
|
|
208
|
+
test: "todo"
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
export {
|
|
213
|
+
afterEach,
|
|
214
|
+
initialGlobals,
|
|
215
|
+
parameters,
|
|
216
|
+
preview_exports
|
|
217
|
+
};
|