@storybook/addon-a11y 9.2.0-alpha.3 → 10.0.0-beta.0

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 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
+ };