aria-ease 2.8.3 → 2.9.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.
Files changed (43) hide show
  1. package/bin/audit-XZJXMUPL.js +46 -0
  2. package/bin/chunk-5Z7PR3VC.js +182 -0
  3. package/bin/chunk-JSBRDJBE.js +30 -0
  4. package/bin/cli.cjs +13967 -0
  5. package/bin/cli.d.cts +1 -0
  6. package/bin/cli.d.ts +1 -0
  7. package/bin/cli.js +4 -4
  8. package/{dist/contractTestRunnerPlaywright-7O2T4JES.js → bin/contractTestRunnerPlaywright-62LXHK7K.js} +117 -12
  9. package/bin/formatters-U4E5EVPL.js +183 -0
  10. package/bin/test-PK5MBHIN.js +12842 -0
  11. package/dist/{chunk-SSBW5VAA.js → chunk-57O4KFP4.js} +4 -0
  12. package/dist/{contractTestRunnerPlaywright-AJ2DOOJT.js → contractTestRunnerPlaywright-LGXSV2ZS.js} +111 -12
  13. package/dist/index.cjs +409 -26
  14. package/dist/index.d.cts +27 -1
  15. package/dist/index.d.ts +27 -1
  16. package/dist/index.js +296 -17
  17. package/dist/src/Types.d-uG0Hm1yK.d.cts +39 -0
  18. package/dist/src/Types.d-uG0Hm1yK.d.ts +39 -0
  19. package/dist/src/accordion/index.d.cts +1 -1
  20. package/dist/src/accordion/index.d.ts +1 -1
  21. package/dist/src/block/index.d.cts +1 -1
  22. package/dist/src/block/index.d.ts +1 -1
  23. package/dist/src/checkbox/index.d.cts +1 -1
  24. package/dist/src/checkbox/index.d.ts +1 -1
  25. package/dist/src/combobox/index.cjs +243 -0
  26. package/dist/src/combobox/index.d.cts +14 -0
  27. package/dist/src/combobox/index.d.ts +14 -0
  28. package/dist/src/combobox/index.js +241 -0
  29. package/dist/src/menu/index.d.cts +1 -1
  30. package/dist/src/menu/index.d.ts +1 -1
  31. package/dist/src/radio/index.d.cts +1 -1
  32. package/dist/src/radio/index.d.ts +1 -1
  33. package/dist/src/toggle/index.d.cts +1 -1
  34. package/dist/src/toggle/index.d.ts +1 -1
  35. package/dist/src/utils/test/{chunk-SSBW5VAA.js → chunk-57O4KFP4.js} +4 -0
  36. package/dist/src/utils/test/{contractTestRunnerPlaywright-AJ2DOOJT.js → contractTestRunnerPlaywright-LGXSV2ZS.js} +111 -12
  37. package/dist/src/utils/test/contracts/ComboboxContract.json +474 -0
  38. package/dist/src/utils/test/index.cjs +167 -26
  39. package/dist/src/utils/test/index.js +55 -17
  40. package/package.json +10 -3
  41. package/dist/src/Types.d-w1KLKLcA.d.cts +0 -24
  42. package/dist/src/Types.d-w1KLKLcA.d.ts +0 -24
  43. package/dist/src/utils/test/contractTestRunnerPlaywright-7O2T4JES.js +0 -252
@@ -0,0 +1,46 @@
1
+ import "./chunk-JSBRDJBE.js";
2
+
3
+ // src/utils/audit/src/audit/audit.ts
4
+ import AxeBuilder from "@axe-core/playwright";
5
+ import { chromium } from "playwright";
6
+ async function runAudit(url, options) {
7
+ let browser;
8
+ const timeout = options?.timeout || 6e4;
9
+ const waitUntil = options?.waitUntil || "domcontentloaded";
10
+ try {
11
+ browser = await chromium.launch({ headless: true });
12
+ const context = await browser.newContext();
13
+ const page = await context.newPage();
14
+ await page.goto(url, { waitUntil, timeout });
15
+ const axe = new AxeBuilder({ page });
16
+ const axeResults = await axe.analyze();
17
+ return axeResults;
18
+ } catch (error) {
19
+ if (error instanceof Error) {
20
+ if (error.message.includes("Executable doesn't exist")) {
21
+ console.error("\n\u274C Playwright browsers not found!\n");
22
+ console.log("\u{1F4E6} First-time setup required:");
23
+ console.log(" Run: npx playwright install chromium\n");
24
+ console.log("\u{1F4A1} This downloads the browser needed for auditing (~200MB)");
25
+ console.log(" You only need to do this once.\n");
26
+ } else if (error.message.includes("page.goto: net::ERR_CONNECTION_REFUSED")) {
27
+ console.error("\n\u274C Server Not Running!\n");
28
+ console.log(" Make sure your server is running before auditing URL");
29
+ console.log(" Run: npm run dev # or your start command");
30
+ } else if (error.message.includes("page.goto: Protocol error (Page.navigate): Cannot navigate to invalid URL")) {
31
+ console.error("\n\u274C Cannot audit invalid URL\n");
32
+ } else {
33
+ console.error("\u274C Audit error:", error.message);
34
+ console.log(" Make sure you provide a valid URL");
35
+ }
36
+ } else {
37
+ console.error("\u274C Audit error (non-Error):", String(error));
38
+ }
39
+ throw error;
40
+ } finally {
41
+ if (browser) await browser.close();
42
+ }
43
+ }
44
+ export {
45
+ runAudit
46
+ };
@@ -0,0 +1,182 @@
1
+ // src/utils/test/contract/contract.json
2
+ var contract_default = {
3
+ menu: {
4
+ path: "./contracts/MenuContract.json",
5
+ component: "menu"
6
+ },
7
+ combobox: {
8
+ path: "./contracts/ComboboxContract.json",
9
+ component: "combobox"
10
+ }
11
+ };
12
+
13
+ // src/utils/test/contract/ContractReporter.ts
14
+ var ContractReporter = class {
15
+ startTime = 0;
16
+ componentName = "";
17
+ staticPasses = 0;
18
+ staticFailures = 0;
19
+ dynamicResults = [];
20
+ totalTests = 0;
21
+ skipped = 0;
22
+ isPlaywright = false;
23
+ constructor(isPlaywright = false) {
24
+ this.isPlaywright = isPlaywright;
25
+ }
26
+ log(message) {
27
+ process.stderr.write(message + "\n");
28
+ }
29
+ start(componentName, totalTests) {
30
+ this.startTime = Date.now();
31
+ this.componentName = componentName;
32
+ this.totalTests = totalTests;
33
+ const mode = this.isPlaywright ? "Playwright (Real Browser)" : "jsdom (Fast)";
34
+ this.log(`
35
+ ${"\u2550".repeat(60)}`);
36
+ this.log(`\u{1F50D} Testing ${componentName} Component - ${mode}`);
37
+ this.log(`${"\u2550".repeat(60)}
38
+ `);
39
+ }
40
+ reportStatic(passes, failures) {
41
+ this.staticPasses = passes;
42
+ this.staticFailures = failures;
43
+ const icon = failures === 0 ? "\u2705" : "\u274C";
44
+ const status = failures === 0 ? "PASS" : "FAIL";
45
+ this.log(`${icon} Static ARIA Tests: ${status}`);
46
+ this.log(` ${passes}/${passes + failures} required attributes present
47
+ `);
48
+ }
49
+ /**
50
+ * Report individual dynamic test result
51
+ */
52
+ reportTest(test, status, failureMessage) {
53
+ const result = {
54
+ description: test.description,
55
+ status,
56
+ failureMessage
57
+ };
58
+ if (status === "skip" && test.requiresBrowser) {
59
+ result.skipReason = "Requires real browser (addEventListener events)";
60
+ }
61
+ this.dynamicResults.push(result);
62
+ const icons = { pass: "\u2713", fail: "\u2717", skip: "\u25CB" };
63
+ this.log(` ${icons[status]} ${test.description}`);
64
+ if (status === "skip" && !this.isPlaywright) {
65
+ this.log(` \u21B3 Skipped in jsdom (runs in Playwright)`);
66
+ }
67
+ if (status === "fail" && failureMessage) {
68
+ this.log(` \u21B3 ${failureMessage}`);
69
+ }
70
+ }
71
+ /**
72
+ * Report all failures with actionable context
73
+ */
74
+ reportFailures(failures) {
75
+ if (failures.length === 0) return;
76
+ this.log(`
77
+ ${"\u2500".repeat(60)}`);
78
+ this.log(`\u274C Failures (${failures.length}):
79
+ `);
80
+ failures.forEach((failure, index) => {
81
+ this.log(`${index + 1}. ${failure}`);
82
+ if (failure.includes("aria-")) {
83
+ this.log(` \u{1F4A1} Add the missing ARIA attribute to improve screen reader support`);
84
+ } else if (failure.includes("focus")) {
85
+ this.log(` \u{1F4A1} Check keyboard event handlers and focus management`);
86
+ } else if (failure.includes("visible")) {
87
+ this.log(` \u{1F4A1} Verify display/visibility styles and state management`);
88
+ }
89
+ this.log("");
90
+ });
91
+ }
92
+ /**
93
+ * Report skipped tests with helpful context
94
+ */
95
+ reportSkipped() {
96
+ if (this.skipped === 0 || this.isPlaywright) return;
97
+ const skippedTests = this.dynamicResults.filter((r) => r.status === "skip");
98
+ this.log(`
99
+ ${"\u2500".repeat(60)}`);
100
+ this.log(`\u2139\uFE0F Skipped Tests (${this.skipped}):
101
+ `);
102
+ this.log(`These tests use native keyboard events via addEventListener,`);
103
+ this.log(`which jsdom cannot simulate. They run successfully in Playwright.
104
+ `);
105
+ skippedTests.forEach((test, index) => {
106
+ this.log(`${index + 1}. ${test.description}`);
107
+ });
108
+ this.log(`
109
+ \u{1F4A1} Run with Playwright for full validation:`);
110
+ this.log(` testUiComponent('${this.componentName}', component, 'http://localhost:5173/')
111
+ `);
112
+ }
113
+ /**
114
+ * Generate final summary with statistics
115
+ */
116
+ summary(failures) {
117
+ const duration = Date.now() - this.startTime;
118
+ const dynamicPasses = this.dynamicResults.filter((r) => r.status === "pass").length;
119
+ const dynamicFailures = this.dynamicResults.filter((r) => r.status === "fail").length;
120
+ this.skipped = this.dynamicResults.filter((r) => r.status === "skip").length;
121
+ const totalPasses = this.staticPasses + dynamicPasses;
122
+ const totalFailures = this.staticFailures + dynamicFailures;
123
+ const totalRun = totalPasses + totalFailures;
124
+ if (failures.length > 0) {
125
+ this.reportFailures(failures);
126
+ }
127
+ this.reportSkipped();
128
+ this.log(`
129
+ ${"\u2550".repeat(60)}`);
130
+ this.log(`\u{1F4CA} Summary
131
+ `);
132
+ if (totalFailures === 0 && this.skipped === 0) {
133
+ this.log(`\u2705 All ${totalRun} tests passed!`);
134
+ this.log(` ${this.componentName} component meets APG and WCAG guidelines \u2713`);
135
+ } else if (totalFailures === 0) {
136
+ this.log(`\u2705 ${totalPasses}/${totalRun} tests passed`);
137
+ this.log(`\u25CB ${this.skipped} tests skipped (jsdom limitation)`);
138
+ this.log(` ${this.componentName} component works correctly`);
139
+ } else {
140
+ this.log(`\u274C ${totalFailures} test${totalFailures > 1 ? "s" : ""} failed`);
141
+ this.log(`\u2705 ${totalPasses} test${totalPasses > 1 ? "s" : ""} passed`);
142
+ if (this.skipped > 0) {
143
+ this.log(`\u25CB ${this.skipped} test${this.skipped > 1 ? "s" : ""} skipped`);
144
+ }
145
+ }
146
+ this.log(`\u23F1\uFE0F Duration: ${duration}ms`);
147
+ this.log(`${"\u2550".repeat(60)}
148
+ `);
149
+ if (totalFailures > 0) {
150
+ this.log(`\u{1F527} Next Steps:`);
151
+ this.log(` 1. Review the failures above`);
152
+ this.log(` 2. Fix ARIA attributes and keyboard handlers`);
153
+ this.log(` 3. Re-run tests to verify fixes
154
+ `);
155
+ } else if (!this.isPlaywright && this.skipped > 0) {
156
+ this.log(`\u2728 Optional: Run Playwright tests for complete validation
157
+ `);
158
+ }
159
+ return {
160
+ passes: totalPasses,
161
+ failures: totalFailures,
162
+ skipped: this.skipped,
163
+ duration
164
+ };
165
+ }
166
+ /**
167
+ * Report an error during test execution
168
+ */
169
+ error(message, context) {
170
+ this.log(`
171
+ \u274C Error: ${message}`);
172
+ if (context) {
173
+ this.log(` Context: ${context}`);
174
+ }
175
+ this.log("");
176
+ }
177
+ };
178
+
179
+ export {
180
+ contract_default,
181
+ ContractReporter
182
+ };
@@ -0,0 +1,30 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __commonJS = (cb, mod) => function __require() {
8
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
+ // If the importer is in node compatibility mode or this is not an ESM
20
+ // file that has been converted to a CommonJS file using a Babel-
21
+ // compatible transform (i.e. "__esModule" has not been set), then set
22
+ // "default" to the CommonJS "module.exports" for node compatibility.
23
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
+ mod
25
+ ));
26
+
27
+ export {
28
+ __commonJS,
29
+ __toESM
30
+ };