aria-ease 6.7.0 → 6.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 (39) hide show
  1. package/README.md +77 -10
  2. package/bin/AccordionComponentStrategy-4ZEIQ2V6.js +42 -0
  3. package/bin/ComboboxComponentStrategy-OGRVZXAF.js +64 -0
  4. package/bin/MenuComponentStrategy-JAMTCSNF.js +81 -0
  5. package/bin/TabsComponentStrategy-3SQURPMX.js +29 -0
  6. package/bin/buildContracts-GBOY7UXG.js +437 -0
  7. package/bin/{chunk-VPBHLMAS.js → chunk-LMSKLN5O.js} +21 -0
  8. package/bin/chunk-PK5L2SAF.js +17 -0
  9. package/bin/{chunk-2TOYEY5L.js → chunk-XERMSYEH.js} +12 -3
  10. package/bin/cli.cjs +991 -128
  11. package/bin/cli.js +33 -2
  12. package/bin/{configLoader-XRF6VM4J.js → configLoader-Q6A4JLKW.js} +1 -1
  13. package/{dist/contractTestRunnerPlaywright-UAOFNS7Z.js → bin/contractTestRunnerPlaywright-ZZNWDUYP.js} +270 -219
  14. package/bin/{test-WRIJHN6H.js → test-OND56UUL.js} +97 -10
  15. package/dist/AccordionComponentStrategy-4ZEIQ2V6.js +42 -0
  16. package/dist/ComboboxComponentStrategy-OGRVZXAF.js +64 -0
  17. package/dist/MenuComponentStrategy-JAMTCSNF.js +81 -0
  18. package/dist/TabsComponentStrategy-3SQURPMX.js +29 -0
  19. package/dist/chunk-PK5L2SAF.js +17 -0
  20. package/dist/{chunk-2TOYEY5L.js → chunk-XERMSYEH.js} +12 -3
  21. package/dist/{configLoader-IT4PWCJB.js → configLoader-WTGJAP4Z.js} +21 -0
  22. package/{bin/contractTestRunnerPlaywright-UAOFNS7Z.js → dist/contractTestRunnerPlaywright-XBWJZMR3.js} +270 -219
  23. package/dist/index.cjs +800 -96
  24. package/dist/index.d.cts +136 -1
  25. package/dist/index.d.ts +136 -1
  26. package/dist/index.js +421 -16
  27. package/dist/src/utils/test/AccordionComponentStrategy-WRHZOEN6.js +38 -0
  28. package/dist/src/utils/test/ComboboxComponentStrategy-5AECQSRN.js +60 -0
  29. package/dist/src/utils/test/MenuComponentStrategy-VKZQYLBE.js +77 -0
  30. package/dist/src/utils/test/TabsComponentStrategy-BKG53SEV.js +26 -0
  31. package/dist/src/utils/test/aria-contracts/accordion/accordion.contract.json +5 -11
  32. package/dist/src/utils/test/aria-contracts/combobox/combobox.listbox.contract.json +1 -1
  33. package/dist/src/utils/test/aria-contracts/menu/menu.contract.json +1 -1
  34. package/dist/src/utils/test/{chunk-2TOYEY5L.js → chunk-XERMSYEH.js} +12 -3
  35. package/dist/src/utils/test/{configLoader-LD4RV2WQ.js → configLoader-YE2CYGDG.js} +21 -0
  36. package/dist/src/utils/test/{contractTestRunnerPlaywright-IRJOAEMT.js → contractTestRunnerPlaywright-LC5OAVXB.js} +262 -200
  37. package/dist/src/utils/test/index.cjs +472 -88
  38. package/dist/src/utils/test/index.js +97 -12
  39. package/package.json +7 -2
@@ -0,0 +1,26 @@
1
+ // src/utils/test/src/component-strategies/TabsComponentStrategy.ts
2
+ var TabsComponentStrategy = class {
3
+ constructor(mainSelector, selectors) {
4
+ this.mainSelector = mainSelector;
5
+ this.selectors = selectors;
6
+ }
7
+ async resetState() {
8
+ }
9
+ async shouldSkipTest(test, page) {
10
+ if (test.isVertical !== void 0 && this.selectors.tablist) {
11
+ const tablistSelector = this.selectors.tablist;
12
+ const tablist = page.locator(tablistSelector).first();
13
+ const orientation = await tablist.getAttribute("aria-orientation");
14
+ const isVertical = orientation === "vertical";
15
+ if (test.isVertical !== isVertical) {
16
+ return true;
17
+ }
18
+ }
19
+ return false;
20
+ }
21
+ getMainSelector() {
22
+ return this.mainSelector;
23
+ }
24
+ };
25
+
26
+ export { TabsComponentStrategy };
@@ -13,16 +13,15 @@
13
13
  },
14
14
 
15
15
  "selectors": {
16
- "container": "[data-test-id=accordion-group]",
17
- "trigger": "[data-test-id=accordion-trigger]",
18
- "focusable": "[data-test-id=accordion-trigger]",
19
- "relative": "[data-test-id=accordion-trigger]",
20
- "panel": "[role=region]"
16
+ "trigger": "[data-accordion] [aria-controls][aria-expanded], [aria-controls][aria-expanded]",
17
+ "focusable": "[data-accordion] [aria-controls][aria-expanded], [aria-controls][aria-expanded]",
18
+ "relative": "[data-accordion] [aria-controls][aria-expanded], [aria-controls][aria-expanded]",
19
+ "panel": "[role='region'][aria-labelledby], [role='region'][aria-labelledby]"
21
20
  },
22
21
 
23
22
  "observables": {
24
23
  "observable": "focus | visible | attribute | role",
25
- "target": "trigger | relative | panel | container",
24
+ "target": "trigger | relative | panel | focusable",
26
25
  "relative": "first | last | next | previous"
27
26
  },
28
27
 
@@ -38,11 +37,6 @@
38
37
  "from": "panel",
39
38
  "attribute": "aria-labelledby",
40
39
  "to": "trigger"
41
- },
42
- {
43
- "type": "contains",
44
- "parent": "container",
45
- "child": "trigger"
46
40
  }
47
41
  ],
48
42
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  "selectors": {
16
16
  "input": "[role=combobox]",
17
- "button": "[data-test-id=combobox-button]",
17
+ "button": "button[tabindex='-1'], [role=button][tabindex='-1']",
18
18
  "listbox": "[role=listbox]",
19
19
  "options": "[role=option]",
20
20
  "focusable": "[role=combobox]",
@@ -13,7 +13,7 @@
13
13
  },
14
14
 
15
15
  "selectors": {
16
- "trigger": "[data-test-id=menu-trigger]",
16
+ "trigger": "[aria-controls][aria-haspopup][aria-expanded]:not([role='menuitem']):not([role='menuitemcheckbox']):not([role='menuitemradio'])",
17
17
  "container": "[role=menu]",
18
18
  "items": "[role=menuitem], [role=menuitemradio], [role=menuitemcheckbox]",
19
19
  "submenuTrigger": "[role=menu] [role=menuitem][aria-haspopup=true], [role=menu] [role=menuitemradio][aria-haspopup=true], [role=menu] [role=menuitemcheckbox][aria-haspopup=true], [role=menu] [role=menuitem][aria-haspopup=menu], [role=menu] [role=menuitemradio][aria-haspopup=menu], [role=menu] [role=menuitemcheckbox][aria-haspopup=menu]",
@@ -32,11 +32,13 @@ var ContractReporter = class {
32
32
  skipped = 0;
33
33
  warnings = 0;
34
34
  isPlaywright = false;
35
+ isCustomContract = false;
35
36
  apgUrl = "https://www.w3.org/WAI/ARIA/apg/";
36
37
  hasPrintedStaticSection = false;
37
38
  hasPrintedDynamicSection = false;
38
- constructor(isPlaywright = false) {
39
+ constructor(isPlaywright = false, isCustomContract = false) {
39
40
  this.isPlaywright = isPlaywright;
41
+ this.isCustomContract = isCustomContract;
40
42
  }
41
43
  log(message) {
42
44
  process.stderr.write(message + "\n");
@@ -197,6 +199,13 @@ ${"\u2500".repeat(60)}`);
197
199
  const totalPasses = this.staticPasses + dynamicPasses;
198
200
  const totalFailures = this.staticFailures + dynamicFailures;
199
201
  const totalRun = totalPasses + totalFailures + this.warnings;
202
+ const getComponentMessage = () => {
203
+ const componentDisplayName = `${this.componentName.charAt(0).toUpperCase()}${this.componentName.slice(1)}`;
204
+ if (this.isCustomContract) {
205
+ return `${componentDisplayName} component validates against your custom accessibility policy \u2713`;
206
+ }
207
+ return `${componentDisplayName} component meets Aria-Ease baseline WAI-ARIA expectations \u2713`;
208
+ };
200
209
  if (failures.length > 0) {
201
210
  this.reportFailures(failures);
202
211
  }
@@ -208,7 +217,7 @@ ${"\u2550".repeat(60)}`);
208
217
  `);
209
218
  if (totalFailures === 0 && this.skipped === 0 && this.warnings === 0) {
210
219
  this.log(`\u2705 All ${totalRun} tests passed!`);
211
- this.log(` ${this.componentName.charAt(0).toUpperCase()}${this.componentName.slice(1)} component meets WAI-ARIA expectations for Roles, States, Properties, and Keyboard Interactions \u2713`);
220
+ this.log(` ${getComponentMessage()}`);
212
221
  } else if (totalFailures === 0) {
213
222
  this.log(`\u2705 ${totalPasses}/${totalRun} tests passed`);
214
223
  if (this.skipped > 0) {
@@ -217,7 +226,7 @@ ${"\u2550".repeat(60)}`);
217
226
  if (this.warnings > 0) {
218
227
  this.log(`\u26A0\uFE0F ${this.warnings} warning${this.warnings > 1 ? "s" : ""}`);
219
228
  }
220
- this.log(` ${this.componentName.charAt(0).toUpperCase()}${this.componentName.slice(1)} component meets WAI-ARIA expectations for Roles, States, Properties, and Keyboard Interactions \u2713`);
229
+ this.log(` ${getComponentMessage()}`);
221
230
  } else {
222
231
  this.log(`\u274C ${totalFailures} test${totalFailures > 1 ? "s" : ""} failed`);
223
232
  this.log(`\u2705 ${totalPasses} test${totalPasses > 1 ? "s" : ""} passed`);
@@ -55,6 +55,9 @@ function validateConfig(config) {
55
55
  if (comp.path !== void 0 && typeof comp.path !== "string") {
56
56
  errors.push(`test.components[${idx}].path must be a string when provided`);
57
57
  }
58
+ if (comp.strategyPath !== void 0 && typeof comp.strategyPath !== "string") {
59
+ errors.push(`test.components[${idx}].strategyPath must be a string when provided`);
60
+ }
58
61
  if (comp.strictness !== void 0 && !["minimal", "balanced", "strict", "paranoid"].includes(comp.strictness)) {
59
62
  errors.push(`test.components[${idx}].strictness must be one of: minimal, balanced, strict, paranoid`);
60
63
  }
@@ -69,6 +72,24 @@ function validateConfig(config) {
69
72
  }
70
73
  }
71
74
  }
75
+ if (cfg.contracts !== void 0) {
76
+ if (!Array.isArray(cfg.contracts)) {
77
+ errors.push("contracts must be an array");
78
+ } else {
79
+ cfg.contracts.forEach((contract, idx) => {
80
+ if (typeof contract !== "object" || contract === null) {
81
+ errors.push(`contracts[${idx}] must be an object`);
82
+ } else {
83
+ if (typeof contract.src !== "string") {
84
+ errors.push(`contracts[${idx}].src is required and must be a string`);
85
+ }
86
+ if (contract.out !== void 0 && typeof contract.out !== "string") {
87
+ errors.push(`contracts[${idx}].out must be a string`);
88
+ }
89
+ }
90
+ });
91
+ }
92
+ }
72
93
  return { valid: errors.length === 0, errors };
73
94
  }
74
95
  async function loadConfigFile(filePath) {