aria-ease 6.14.0 → 7.0.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.
Files changed (94) hide show
  1. package/README.md +1 -1
  2. package/dist/AccordionComponentStrategy-2SWMNUR6.js +1 -0
  3. package/dist/ComboboxComponentStrategy-YSYLR2U5.js +5 -0
  4. package/dist/MenuComponentStrategy-C22BZEBH.js +5 -0
  5. package/dist/RelativeTargetResolver-T4P25J2M.js +1 -0
  6. package/dist/TabsComponentStrategy-ADEEFJXM.js +1 -0
  7. package/dist/audit-WBKVW7H6.js +9 -0
  8. package/dist/badgeHelper-IB5RTMAG.js +11 -0
  9. package/dist/badgeHelper-JSROP5ML.js +1 -0
  10. package/dist/buildContracts-T4XQZBDU.js +13 -0
  11. package/dist/chunk-52I3INNG.js +11 -0
  12. package/dist/chunk-APUMBDOT.js +1 -0
  13. package/dist/chunk-BHNO4ZI3.js +1 -0
  14. package/dist/chunk-CNU4N4AY.js +1 -0
  15. package/dist/chunk-SM6ZKEDR.js +1 -0
  16. package/dist/chunk-ZNQ5BXVJ.js +1 -0
  17. package/dist/cli.cjs +132 -3560
  18. package/dist/cli.js +19 -161
  19. package/dist/configLoader-ZEJVXLX7.js +1 -0
  20. package/dist/configLoader-ZXTSCIP6.js +1 -0
  21. package/dist/contractTestRunnerPlaywright-FOCQTM4L.js +46 -0
  22. package/dist/contractTestRunnerPlaywright-QPU6HZXG.js +46 -0
  23. package/dist/formatters-H3CPDLG5.js +87 -0
  24. package/dist/index.cjs +64 -5103
  25. package/dist/index.d.cts +4 -6
  26. package/dist/index.d.ts +4 -6
  27. package/dist/index.js +17 -2703
  28. package/dist/src/accordion/index.cjs +1 -183
  29. package/dist/src/accordion/index.js +1 -181
  30. package/dist/src/block/index.cjs +1 -124
  31. package/dist/src/block/index.js +1 -122
  32. package/dist/src/checkbox/index.cjs +1 -109
  33. package/dist/src/checkbox/index.js +1 -107
  34. package/dist/src/combobox/index.cjs +1 -265
  35. package/dist/src/combobox/index.js +1 -263
  36. package/dist/src/menu/index.cjs +1 -339
  37. package/dist/src/menu/index.js +1 -337
  38. package/dist/src/radio/index.cjs +1 -117
  39. package/dist/src/radio/index.js +1 -115
  40. package/dist/src/tabs/index.cjs +1 -265
  41. package/dist/src/tabs/index.js +1 -263
  42. package/dist/src/toggle/index.cjs +1 -119
  43. package/dist/src/toggle/index.js +1 -117
  44. package/dist/src/utils/test/AccordionComponentStrategy-X2GSQ5KT.js +1 -0
  45. package/dist/src/utils/test/ComboboxComponentStrategy-SICWLI27.js +5 -0
  46. package/dist/src/utils/test/MenuComponentStrategy-R4VPAHDE.js +5 -0
  47. package/dist/src/utils/test/RelativeTargetResolver-UQQMZHI6.js +1 -0
  48. package/dist/src/utils/test/TabsComponentStrategy-L2PYNEW6.js +1 -0
  49. package/dist/src/utils/test/badgeHelper-ER5ZOHWF.js +11 -0
  50. package/dist/src/utils/test/chunk-APUMBDOT.js +1 -0
  51. package/dist/src/utils/test/chunk-BHNO4ZI3.js +1 -0
  52. package/dist/src/utils/test/configLoader-NCYRL2O6.js +1 -0
  53. package/dist/src/utils/test/contractTestRunnerPlaywright-YZCMF64Q.js +46 -0
  54. package/dist/src/utils/test/dsl/index.cjs +1 -838
  55. package/dist/src/utils/test/dsl/index.d.cts +2 -4
  56. package/dist/src/utils/test/dsl/index.d.ts +2 -4
  57. package/dist/src/utils/test/dsl/index.js +1 -836
  58. package/dist/src/utils/test/index.cjs +64 -2672
  59. package/dist/src/utils/test/index.d.cts +2 -2
  60. package/dist/src/utils/test/index.d.ts +2 -2
  61. package/dist/src/utils/test/index.js +16 -340
  62. package/dist/test-VXSCSKV5.js +19 -0
  63. package/package.json +8 -10
  64. package/dist/AccordionComponentStrategy-4ZEIQ2V6.js +0 -42
  65. package/dist/ComboboxComponentStrategy-DU342VMB.js +0 -64
  66. package/dist/MenuComponentStrategy-VYCC2XOM.js +0 -81
  67. package/dist/RelativeTargetResolver-DJAITO6D.js +0 -7
  68. package/dist/TabsComponentStrategy-3SQURPMX.js +0 -29
  69. package/dist/audit-JYEPKLHR.js +0 -63
  70. package/dist/badgeHelper-JOWO6RQG.js +0 -15
  71. package/dist/badgeHelper-RDOMCC6E.js +0 -108
  72. package/dist/buildContracts-VIV6GM56.js +0 -437
  73. package/dist/chunk-4DU5Z5BR.js +0 -340
  74. package/dist/chunk-GJGUY643.js +0 -182
  75. package/dist/chunk-GLT43UVH.js +0 -43
  76. package/dist/chunk-I2KLQ2HA.js +0 -22
  77. package/dist/chunk-JJEPLK7L.js +0 -107
  78. package/dist/chunk-PK5L2SAF.js +0 -17
  79. package/dist/configLoader-Q7N5XV4P.js +0 -183
  80. package/dist/configLoader-REHK3S3Q.js +0 -7
  81. package/dist/contractTestRunnerPlaywright-B2HLZKKK.js +0 -1394
  82. package/dist/contractTestRunnerPlaywright-RWK52C7S.js +0 -1394
  83. package/dist/formatters-32KQIIYS.js +0 -183
  84. package/dist/src/utils/test/AccordionComponentStrategy-WRHZOEN6.js +0 -38
  85. package/dist/src/utils/test/ComboboxComponentStrategy-XKQ72RFD.js +0 -60
  86. package/dist/src/utils/test/MenuComponentStrategy-6XWU5KLW.js +0 -77
  87. package/dist/src/utils/test/RelativeTargetResolver-G2XDN2VV.js +0 -1
  88. package/dist/src/utils/test/TabsComponentStrategy-BKG53SEV.js +0 -26
  89. package/dist/src/utils/test/badgeHelper-HZKGOPB4.js +0 -102
  90. package/dist/src/utils/test/chunk-4DU5Z5BR.js +0 -332
  91. package/dist/src/utils/test/chunk-GLT43UVH.js +0 -41
  92. package/dist/src/utils/test/configLoader-NA7IBCS3.js +0 -181
  93. package/dist/src/utils/test/contractTestRunnerPlaywright-5FIGA5G4.js +0 -1372
  94. package/dist/test-WDBS5JWO.js +0 -358
@@ -1,838 +1 @@
1
- 'use strict';
2
-
3
- // src/utils/test/dsl/src/state-packs/combobox/comboboxStatePack.ts
4
- var COMBOBOX_STATES = {
5
- "popup.open": {
6
- setup: [
7
- {
8
- when: ["keyboard", "textInput"],
9
- steps: () => [
10
- { type: "keypress", target: "input", key: "ArrowDown" }
11
- ]
12
- },
13
- {
14
- when: ["pointer"],
15
- steps: () => [
16
- { type: "click", target: "button" }
17
- ]
18
- }
19
- ],
20
- assertion: isComboboxOpen
21
- },
22
- "popup.closed": {
23
- setup: [
24
- {
25
- when: ["keyboard"],
26
- steps: () => [
27
- /* { type: "keypress", target: "input", key: "Escape" } */
28
- ]
29
- },
30
- {
31
- when: ["pointer"],
32
- steps: () => [
33
- /* { type: "click", target: "button" } */
34
- ]
35
- }
36
- ],
37
- assertion: [...isComboboxClosed(), ...isActiveDescendantEmpty()]
38
- },
39
- "main.focused": {
40
- setup: [
41
- {
42
- when: ["keyboard"],
43
- steps: () => [
44
- { type: "focus", target: "main" }
45
- ]
46
- }
47
- ],
48
- assertion: isMainFocused
49
- },
50
- "main.notFocused": {
51
- setup: [
52
- {
53
- when: ["keyboard"],
54
- steps: () => [
55
- //what to do here?
56
- ]
57
- }
58
- ],
59
- assertion: isMainNotFocused
60
- },
61
- "input.filled": {
62
- setup: [
63
- {
64
- when: ["keyboard", "textInput"],
65
- steps: () => [
66
- { type: "type", target: "input", value: "test" }
67
- ]
68
- }
69
- ],
70
- assertion: isInputFilled
71
- },
72
- "input.notFilled": {
73
- setup: [
74
- {
75
- when: ["keyboard", "textInput"],
76
- steps: () => [
77
- { type: "type", target: "input", value: "" }
78
- ]
79
- }
80
- ],
81
- assertion: isInputNotFilled
82
- },
83
- "activeOption.first": {
84
- requires: ["popup.open"],
85
- setup: [
86
- {
87
- when: ["keyboard"],
88
- steps: () => [
89
- { type: "keypress", target: "input", key: "ArrowDown" }
90
- ]
91
- }
92
- ],
93
- assertion: isActiveDescendantFirst
94
- },
95
- "activeOption.last": {
96
- requires: ["activeOption.first"],
97
- setup: [
98
- {
99
- when: ["keyboard"],
100
- steps: () => [
101
- { type: "keypress", target: "input", key: "ArrowUp" }
102
- ]
103
- }
104
- ],
105
- assertion: isActiveDescendantLast
106
- },
107
- "activeDescendant.notEmpty": {
108
- requires: [],
109
- setup: [
110
- {
111
- when: ["keyboard"],
112
- steps: () => []
113
- }
114
- ],
115
- assertion: isActiveDescendantNotEmpty
116
- },
117
- "activeDescendant.Empty": {
118
- requires: [],
119
- setup: [
120
- {
121
- when: ["keyboard"],
122
- steps: () => []
123
- }
124
- ],
125
- assertion: isActiveDescendantEmpty
126
- },
127
- "selectedOption.first": {
128
- requires: ["popup.open"],
129
- setup: [
130
- {
131
- when: ["pointer"],
132
- steps: () => [
133
- { type: "click", target: "relative", relativeTarget: "first" }
134
- ]
135
- }
136
- ],
137
- assertion: () => isAriaSelected("first")
138
- },
139
- "selectedOption.last": {
140
- requires: ["popup.open"],
141
- setup: [
142
- {
143
- when: ["pointer"],
144
- steps: () => [
145
- { type: "click", target: "relative", relativeTarget: "last" }
146
- ]
147
- }
148
- ],
149
- assertion: () => isAriaSelected("last")
150
- }
151
- };
152
- function isComboboxOpen() {
153
- return [
154
- {
155
- target: "popup",
156
- assertion: "toBeVisible",
157
- failureMessage: "Expected popup to be visible"
158
- },
159
- {
160
- target: "main",
161
- assertion: "toHaveAttribute",
162
- attribute: "aria-expanded",
163
- expectedValue: "true",
164
- failureMessage: "Expect combobox main to have aria-expanded='true'."
165
- }
166
- ];
167
- }
168
- function isComboboxClosed() {
169
- return [
170
- {
171
- target: "popup",
172
- assertion: "notToBeVisible",
173
- failureMessage: "Expected popup to be closed"
174
- },
175
- {
176
- target: "main",
177
- assertion: "toHaveAttribute",
178
- attribute: "aria-expanded",
179
- expectedValue: "false",
180
- failureMessage: "Expect combobox main to have aria-expanded='false'."
181
- }
182
- ];
183
- }
184
- function isActiveDescendantFirst() {
185
- return [
186
- {
187
- target: "main",
188
- assertion: "toHaveAttribute",
189
- attribute: "aria-activedescendant",
190
- expectedValue: { ref: "relative", relativeTarget: "first", property: "id" },
191
- failureMessage: "Expected aria-activedescendant on main to match the id of the first option."
192
- }
193
- ];
194
- }
195
- function isActiveDescendantLast() {
196
- return [
197
- {
198
- target: "main",
199
- assertion: "toHaveAttribute",
200
- attribute: "aria-activedescendant",
201
- expectedValue: { ref: "relative", relativeTarget: "last", property: "id" },
202
- failureMessage: "Expected aria-activedescendant on main to match the id of the last option."
203
- }
204
- ];
205
- }
206
- function isActiveDescendantNotEmpty() {
207
- return [
208
- {
209
- target: "main",
210
- assertion: "toHaveAttribute",
211
- attribute: "aria-activedescendant",
212
- expectedValue: "!empty",
213
- failureMessage: "Expected aria-activedescendant on main to not be empty."
214
- }
215
- ];
216
- }
217
- function isActiveDescendantEmpty() {
218
- return [
219
- {
220
- target: "main",
221
- assertion: "toHaveAttribute",
222
- attribute: "aria-activedescendant",
223
- expectedValue: "",
224
- failureMessage: "Expected aria-activedescendant on main to be empty."
225
- }
226
- ];
227
- }
228
- function isAriaSelected(index) {
229
- return [
230
- {
231
- target: "relative",
232
- relativeTarget: index,
233
- assertion: "toHaveAttribute",
234
- attribute: "aria-selected",
235
- expectedValue: "true",
236
- failureMessage: `Expected ${index} option to have aria-selected='true'.`
237
- }
238
- ];
239
- }
240
- function isMainFocused() {
241
- return [
242
- {
243
- target: "main",
244
- assertion: "toHaveFocus",
245
- failureMessage: "Expected main to be focused."
246
- }
247
- ];
248
- }
249
- function isMainNotFocused() {
250
- return [
251
- {
252
- target: "main",
253
- assertion: "notToHaveFocus",
254
- failureMessage: "Expected main to not have focused."
255
- }
256
- ];
257
- }
258
- function isInputFilled() {
259
- return [
260
- {
261
- target: "input",
262
- assertion: "toHaveValue",
263
- expectedValue: "test",
264
- failureMessage: "Expected input to have the value 'test'."
265
- }
266
- ];
267
- }
268
- function isInputNotFilled() {
269
- return [
270
- {
271
- target: "input",
272
- assertion: "toHaveValue",
273
- expectedValue: "",
274
- failureMessage: "Expected input to have the value ''."
275
- }
276
- ];
277
- }
278
-
279
- // src/utils/test/dsl/src/state-packs/menu/menuStatePack.ts
280
- var MENU_STATES = {
281
- "popup.open": {
282
- setup: [
283
- {
284
- when: ["keyboard"],
285
- steps: () => [
286
- { type: "keypress", target: "main", key: "Enter" }
287
- ]
288
- },
289
- {
290
- when: ["pointer"],
291
- steps: () => [
292
- { type: "click", target: "main" }
293
- ]
294
- }
295
- ],
296
- assertion: isMenuPopupOpen
297
- },
298
- "popup.closed": {
299
- setup: [
300
- {
301
- when: ["keyboard"],
302
- steps: () => [
303
- // component resets after each test so popup is closed
304
- ]
305
- },
306
- {
307
- when: ["pointer"],
308
- steps: () => []
309
- }
310
- ],
311
- assertion: isMenuPopupClosed
312
- },
313
- "main.focused": {
314
- setup: [
315
- {
316
- when: ["keyboard"],
317
- steps: () => [
318
- { type: "focus", target: "main" }
319
- ]
320
- }
321
- ],
322
- assertion: isMainFocused2
323
- },
324
- "main.notFocused": {
325
- setup: [
326
- {
327
- when: ["keyboard"],
328
- steps: () => [
329
- //what to do here?
330
- ]
331
- }
332
- ],
333
- assertion: isMainNotFocused2
334
- },
335
- "activeItem.first": {
336
- requires: ["popup.open"],
337
- setup: [
338
- {
339
- when: ["keyboard"],
340
- steps: () => [
341
- // By default, the first item should be active when the menu opens, so no action is needed to set this state
342
- ]
343
- }
344
- ],
345
- assertion: isActiveItemFirst
346
- },
347
- "activeItem.last": {
348
- requires: ["popup.open"],
349
- setup: [
350
- {
351
- when: ["keyboard"],
352
- steps: () => [
353
- { type: "keypress", target: "main", key: "ArrowUp" }
354
- ]
355
- }
356
- ],
357
- assertion: isActiveItemLast
358
- },
359
- "submenu.open": {
360
- requires: ["popup.open"],
361
- setup: [
362
- {
363
- when: ["keyboard"],
364
- steps: () => [
365
- { type: "keypress", target: "submenuTrigger", key: "ArrowRight" }
366
- ]
367
- },
368
- {
369
- when: ["pointer"],
370
- steps: () => [
371
- { type: "click", target: "submenuTrigger" }
372
- ]
373
- }
374
- ],
375
- assertion: isSubmenuPopupOpen
376
- },
377
- "submenu.closed": {
378
- requires: ["submenu.open"],
379
- setup: [
380
- {
381
- when: ["keyboard"],
382
- steps: () => [
383
- { type: "keypress", target: "submenuTrigger", key: "ArrowLeft" }
384
- ]
385
- },
386
- {
387
- when: ["pointer"],
388
- steps: () => [
389
- { type: "click", target: "submenuTrigger" }
390
- ]
391
- }
392
- ],
393
- assertion: isSubmenuPopupClosed
394
- },
395
- "submenuTrigger.focused": {
396
- setup: [
397
- {
398
- when: ["keyboard"],
399
- steps: () => [
400
- { type: "focus", target: "submenuTrigger" }
401
- ]
402
- }
403
- ],
404
- assertion: isSubmenuTriggerFocused
405
- },
406
- "submenuTrigger.notFocused": {
407
- setup: [
408
- {
409
- when: ["keyboard"],
410
- steps: () => [
411
- //what to do here?
412
- ]
413
- }
414
- ],
415
- assertion: isSubmenuTriggerNotFocused
416
- },
417
- "submenuActiveItem.first": {
418
- requires: ["submenu.open"],
419
- setup: [
420
- {
421
- when: ["keyboard"],
422
- steps: () => [
423
- // By default, the first item should be active when the submenu opens, so no action is needed to set this state
424
- ]
425
- },
426
- {
427
- when: ["pointer"],
428
- steps: () => []
429
- }
430
- ],
431
- assertion: isSubmenuActiveItemFirst
432
- }
433
- };
434
- function isMenuPopupOpen() {
435
- return [
436
- {
437
- target: "popup",
438
- assertion: "toBeVisible",
439
- failureMessage: "Expected popup to be visible"
440
- },
441
- {
442
- target: "main",
443
- assertion: "toHaveAttribute",
444
- attribute: "aria-expanded",
445
- expectedValue: "true",
446
- failureMessage: "Expect menu main to have aria-expanded='true'."
447
- }
448
- ];
449
- }
450
- function isMenuPopupClosed() {
451
- return [
452
- {
453
- target: "popup",
454
- assertion: "notToBeVisible",
455
- failureMessage: "Expected popup to be closed"
456
- },
457
- {
458
- target: "main",
459
- assertion: "toHaveAttribute",
460
- attribute: "aria-expanded",
461
- expectedValue: "false",
462
- failureMessage: "Expect menu main to have aria-expanded='false'."
463
- }
464
- ];
465
- }
466
- function isMainFocused2() {
467
- return [
468
- {
469
- target: "main",
470
- assertion: "toHaveFocus",
471
- failureMessage: "Expected menu main to be focused."
472
- }
473
- ];
474
- }
475
- function isMainNotFocused2() {
476
- return [
477
- {
478
- target: "main",
479
- assertion: "notToHaveFocus",
480
- failureMessage: "Expected menu main to not have focused."
481
- }
482
- ];
483
- }
484
- function isActiveItemFirst() {
485
- return [
486
- {
487
- target: "relative",
488
- assertion: "toHaveFocus",
489
- expectedValue: "first",
490
- failureMessage: "First menu item should have focus."
491
- }
492
- ];
493
- }
494
- function isActiveItemLast() {
495
- return [
496
- {
497
- target: "relative",
498
- assertion: "toHaveFocus",
499
- expectedValue: "last",
500
- failureMessage: "Last menu item should have focus."
501
- }
502
- ];
503
- }
504
- function isSubmenuPopupOpen() {
505
- return [
506
- {
507
- target: "submenu",
508
- assertion: "toBeVisible",
509
- failureMessage: "Expected submenu to be visible"
510
- },
511
- {
512
- target: "submenuTrigger",
513
- assertion: "toHaveAttribute",
514
- attribute: "aria-expanded",
515
- expectedValue: "true",
516
- failureMessage: "Expect submenu trigger to have aria-expanded='true'."
517
- }
518
- ];
519
- }
520
- function isSubmenuPopupClosed() {
521
- return [
522
- {
523
- target: "submenu",
524
- assertion: "notToBeVisible",
525
- failureMessage: "Expected submenu to be closed"
526
- },
527
- {
528
- target: "submenuTrigger",
529
- assertion: "toHaveAttribute",
530
- attribute: "aria-expanded",
531
- expectedValue: "false",
532
- failureMessage: "Expect submenu trigger to have aria-expanded='false'."
533
- }
534
- ];
535
- }
536
- function isSubmenuTriggerFocused() {
537
- return [
538
- {
539
- target: "submenuTrigger",
540
- assertion: "toHaveFocus",
541
- failureMessage: "Expected submenu trigger to be focused."
542
- }
543
- ];
544
- }
545
- function isSubmenuTriggerNotFocused() {
546
- return [
547
- {
548
- target: "submenuTrigger",
549
- assertion: "notToHaveFocus",
550
- failureMessage: "Expected submenu trigger to not have focused."
551
- }
552
- ];
553
- }
554
- function isSubmenuActiveItemFirst() {
555
- return [
556
- {
557
- target: "submenuItems",
558
- assertion: "toHaveFocus",
559
- failureMessage: "First interactive item in the submenu should have focus after Right Arrow open the submenu."
560
- }
561
- ];
562
- }
563
-
564
- // src/utils/test/dsl/src/state-packs/Capability.ts
565
- function hasCapabilities(ctx, requiredCaps) {
566
- return requiredCaps.some((cap) => ctx.capabilities.includes(cap));
567
- }
568
- function resolveSetup(setup, ctx) {
569
- if (Array.isArray(setup) && setup.length && !setup[0].when) {
570
- setup = [{ when: ["keyboard"], steps: () => setup }];
571
- }
572
- for (const strat of setup) {
573
- if (hasCapabilities(ctx, strat.when)) {
574
- return strat.steps(ctx);
575
- }
576
- }
577
- throw new Error(
578
- `No setup strategy matches capabilities: ${ctx.capabilities.join(", ")}`
579
- );
580
- }
581
-
582
- // src/utils/test/dsl/src/contractBuilder.ts
583
- var STATE_PACKS = {
584
- "combobox": COMBOBOX_STATES,
585
- "menu": MENU_STATES
586
- // Add more mappings as needed
587
- };
588
- var FluentContract = class {
589
- constructor(jsonContract) {
590
- this.jsonContract = jsonContract;
591
- }
592
- toJSON() {
593
- return this.jsonContract;
594
- }
595
- };
596
- var ContractBuilder = class {
597
- constructor(componentName) {
598
- this.componentName = componentName;
599
- this.statePack = STATE_PACKS[componentName] || {};
600
- }
601
- metaValue = {};
602
- selectorsValue = {};
603
- relationshipInvariants = [];
604
- staticAssertions = [];
605
- dynamicTests = [];
606
- statePack;
607
- meta(meta) {
608
- this.metaValue = meta;
609
- return this;
610
- }
611
- selectors(selectors) {
612
- this.selectorsValue = selectors;
613
- return this;
614
- }
615
- relationships(fn) {
616
- const statePack = this.statePack;
617
- const ctx = { capabilities: ["keyboard"] };
618
- const resolveAllSetups = (stateName, visited = /* @__PURE__ */ new Set()) => {
619
- if (visited.has(stateName)) return [];
620
- visited.add(stateName);
621
- const s = statePack[stateName];
622
- if (!s) return [];
623
- let actions = [];
624
- if (Array.isArray(s.requires)) {
625
- for (const req of s.requires) {
626
- actions = actions.concat(resolveAllSetups(req, visited));
627
- }
628
- }
629
- if (s.setup) actions = actions.concat(resolveSetup(s.setup, ctx));
630
- return actions;
631
- };
632
- const api = {
633
- ariaReference: (from, attribute, to) => {
634
- return {
635
- requires: (state) => {
636
- const setupActions = resolveAllSetups(state, /* @__PURE__ */ new Set());
637
- return {
638
- required: () => this.relationshipInvariants.push({ type: "aria-reference", from, attribute, to, level: "required", setup: setupActions }),
639
- optional: () => this.relationshipInvariants.push({ type: "aria-reference", from, attribute, to, level: "optional", setup: setupActions }),
640
- recommended: () => this.relationshipInvariants.push({ type: "aria-reference", from, attribute, to, level: "recommended", setup: setupActions })
641
- };
642
- },
643
- required: () => this.relationshipInvariants.push({ type: "aria-reference", from, attribute, to, level: "required" }),
644
- optional: () => this.relationshipInvariants.push({ type: "aria-reference", from, attribute, to, level: "optional" }),
645
- recommended: () => this.relationshipInvariants.push({ type: "aria-reference", from, attribute, to, level: "recommended" })
646
- };
647
- },
648
- contains: (parent, child) => {
649
- return {
650
- requires: (state) => {
651
- const setupActions = resolveAllSetups(state, /* @__PURE__ */ new Set());
652
- return {
653
- required: () => this.relationshipInvariants.push({ type: "contains", parent, child, level: "required", setup: setupActions }),
654
- optional: () => this.relationshipInvariants.push({ type: "contains", parent, child, level: "optional", setup: setupActions }),
655
- recommended: () => this.relationshipInvariants.push({ type: "contains", parent, child, level: "recommended", setup: setupActions })
656
- };
657
- },
658
- required: () => this.relationshipInvariants.push({ type: "contains", parent, child, level: "required" }),
659
- optional: () => this.relationshipInvariants.push({ type: "contains", parent, child, level: "optional" }),
660
- recommended: () => this.relationshipInvariants.push({ type: "contains", parent, child, level: "recommended" })
661
- };
662
- }
663
- };
664
- fn(api);
665
- return this;
666
- }
667
- static(fn) {
668
- const api = {
669
- target: (target) => {
670
- return {
671
- requires: (state) => {
672
- const statePack = this.statePack;
673
- const ctx = { capabilities: ["keyboard"] };
674
- const resolveAllSetups = (stateName, visited = /* @__PURE__ */ new Set()) => {
675
- if (visited.has(stateName)) return [];
676
- visited.add(stateName);
677
- const s = statePack[stateName];
678
- if (!s) return [];
679
- let actions = [];
680
- if (Array.isArray(s.requires)) {
681
- for (const req of s.requires) {
682
- actions = actions.concat(resolveAllSetups(req, visited));
683
- }
684
- }
685
- if (s.setup) actions = actions.concat(resolveSetup(s.setup, ctx));
686
- return actions;
687
- };
688
- const setupActions = resolveAllSetups(state, /* @__PURE__ */ new Set());
689
- return {
690
- has: (attribute, expectedValue) => ({
691
- required: () => this.staticAssertions.push({ target, attribute, expectedValue, failureMessage: "", level: "required", setup: setupActions }),
692
- optional: () => this.staticAssertions.push({ target, attribute, expectedValue, failureMessage: "", level: "optional", setup: setupActions }),
693
- recommended: () => this.staticAssertions.push({ target, attribute, expectedValue, failureMessage: "", level: "recommended", setup: setupActions })
694
- })
695
- };
696
- },
697
- has: (attribute, expectedValue) => ({
698
- required: () => this.staticAssertions.push({ target, attribute, expectedValue, failureMessage: "", level: "required" }),
699
- optional: () => this.staticAssertions.push({ target, attribute, expectedValue, failureMessage: "", level: "optional" }),
700
- recommended: () => this.staticAssertions.push({ target, attribute, expectedValue, failureMessage: "", level: "recommended" })
701
- })
702
- };
703
- }
704
- };
705
- fn(api);
706
- return this;
707
- }
708
- when(event) {
709
- return new DynamicTestBuilder(this, this.statePack, event);
710
- }
711
- addDynamicTest(test) {
712
- this.dynamicTests.push(test);
713
- }
714
- build() {
715
- return {
716
- meta: this.metaValue,
717
- selectors: this.selectorsValue,
718
- relationships: this.relationshipInvariants.length ? this.relationshipInvariants : void 0,
719
- static: this.staticAssertions.length ? [{ assertions: this.staticAssertions }] : [],
720
- dynamic: this.dynamicTests
721
- };
722
- }
723
- };
724
- var DynamicTestBuilder = class {
725
- constructor(parent, statePack, event) {
726
- this.parent = parent;
727
- this.statePack = statePack;
728
- this.event = event;
729
- }
730
- _as;
731
- _on;
732
- _given = [];
733
- _then = [];
734
- _desc = "";
735
- _level = "required";
736
- as(actionType) {
737
- this._as = actionType;
738
- return this;
739
- }
740
- on(target) {
741
- this._on = target;
742
- return this;
743
- }
744
- given(states) {
745
- this._given = Array.isArray(states) ? states : [states];
746
- return this;
747
- }
748
- then(states) {
749
- this._then = Array.isArray(states) ? states : [states];
750
- return this;
751
- }
752
- describe(desc) {
753
- this._desc = desc;
754
- return this;
755
- }
756
- required() {
757
- this._level = "required";
758
- this._finalize();
759
- return this.parent;
760
- }
761
- optional() {
762
- this._level = "optional";
763
- this._finalize();
764
- return this.parent;
765
- }
766
- recommended() {
767
- this._level = "recommended";
768
- this._finalize();
769
- return this.parent;
770
- }
771
- _finalize() {
772
- const capabilityMap = {
773
- keypress: "keyboard",
774
- click: "pointer",
775
- type: "textInput",
776
- focus: "keyboard",
777
- hover: "pointer"
778
- // add more mappings as needed
779
- };
780
- const capability = capabilityMap[this._as || "keyboard"] || (this._as || "keyboard");
781
- const ctx = { capabilities: [capability] };
782
- const resolveAllSetups = (stateName, visited = /* @__PURE__ */ new Set()) => {
783
- if (visited.has(stateName)) return [];
784
- visited.add(stateName);
785
- const s = this.statePack[stateName];
786
- if (!s) return [];
787
- let actions = [];
788
- if (Array.isArray(s.requires)) {
789
- for (const req of s.requires) {
790
- actions = actions.concat(resolveAllSetups(req, visited));
791
- }
792
- }
793
- if (s.setup) actions = actions.concat(resolveSetup(s.setup, ctx));
794
- return actions;
795
- };
796
- const setup = [];
797
- for (const state of this._given) {
798
- setup.push(...resolveAllSetups(state));
799
- }
800
- const assertions = [];
801
- for (const state of this._then) {
802
- const s = this.statePack[state];
803
- if (s && s.assertion !== void 0) {
804
- let value = s.assertion;
805
- if (typeof value === "function") {
806
- try {
807
- value = value();
808
- } catch (e) {
809
- throw new Error(`Error calling assertion function for state '${state}': ${e.message}`);
810
- }
811
- }
812
- if (Array.isArray(value)) assertions.push(...value);
813
- else assertions.push(value);
814
- }
815
- }
816
- const action = [
817
- {
818
- type: this._as,
819
- target: this._on,
820
- key: this._as === "keypress" ? this.event : void 0
821
- }
822
- ];
823
- this.parent.addDynamicTest({
824
- description: this._desc || "",
825
- level: this._level,
826
- action,
827
- assertions,
828
- ...setup.length ? { setup } : {}
829
- });
830
- }
831
- };
832
- function createContract(componentName, define) {
833
- const builder = new ContractBuilder(componentName);
834
- define(builder);
835
- return new FluentContract(builder.build());
836
- }
837
-
838
- exports.createContract = createContract;
1
+ 'use strict';var A={"popup.open":{setup:[{when:["keyboard","textInput"],steps:()=>[{type:"keypress",target:"input",key:"ArrowDown"}]},{when:["pointer"],steps:()=>[{type:"click",target:"button"}]}],assertion:w},"popup.closed":{setup:[{when:["keyboard"],steps:()=>[]},{when:["pointer"],steps:()=>[]}],assertion:[...M(),...f()]},"main.focused":{setup:[{when:["keyboard"],steps:()=>[{type:"focus",target:"main"}]}],assertion:E},"main.notFocused":{setup:[{when:["keyboard"],steps:()=>[]}],assertion:D},"input.filled":{setup:[{when:["keyboard","textInput"],steps:()=>[{type:"type",target:"input",value:"test"}]}],assertion:C},"input.notFilled":{setup:[{when:["keyboard","textInput"],steps:()=>[{type:"type",target:"input",value:""}]}],assertion:I},"activeOption.first":{requires:["popup.open"],setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"input",key:"ArrowDown"}]}],assertion:q},"activeOption.last":{requires:["activeOption.first"],setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"input",key:"ArrowUp"}]}],assertion:S},"activeDescendant.notEmpty":{requires:[],setup:[{when:["keyboard"],steps:()=>[]}],assertion:T},"activeDescendant.Empty":{requires:[],setup:[{when:["keyboard"],steps:()=>[]}],assertion:f},"selectedOption.first":{requires:["popup.open"],setup:[{when:["pointer"],steps:()=>[{type:"click",target:"relative",relativeTarget:"first"}]}],assertion:()=>b("first")},"selectedOption.last":{requires:["popup.open"],setup:[{when:["pointer"],steps:()=>[{type:"click",target:"relative",relativeTarget:"last"}]}],assertion:()=>b("last")}};function w(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expect combobox main to have aria-expanded='true'."}]}function M(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expect combobox main to have aria-expanded='false'."}]}function q(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:{ref:"relative",relativeTarget:"first",property:"id"},failureMessage:"Expected aria-activedescendant on main to match the id of the first option."}]}function S(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:{ref:"relative",relativeTarget:"last",property:"id"},failureMessage:"Expected aria-activedescendant on main to match the id of the last option."}]}function T(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"!empty",failureMessage:"Expected aria-activedescendant on main to not be empty."}]}function f(){return [{target:"main",assertion:"toHaveAttribute",attribute:"aria-activedescendant",expectedValue:"",failureMessage:"Expected aria-activedescendant on main to be empty."}]}function b(a){return [{target:"relative",relativeTarget:a,assertion:"toHaveAttribute",attribute:"aria-selected",expectedValue:"true",failureMessage:`Expected ${a} option to have aria-selected='true'.`}]}function E(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected main to be focused."}]}function D(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected main to not have focused."}]}function C(){return [{target:"input",assertion:"toHaveValue",expectedValue:"test",failureMessage:"Expected input to have the value 'test'."}]}function I(){return [{target:"input",assertion:"toHaveValue",expectedValue:"",failureMessage:"Expected input to have the value ''."}]}var x={"popup.open":{setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"main",key:"Enter"}]},{when:["pointer"],steps:()=>[{type:"click",target:"main"}]}],assertion:V},"popup.closed":{setup:[{when:["keyboard"],steps:()=>[]},{when:["pointer"],steps:()=>[]}],assertion:_},"main.focused":{setup:[{when:["keyboard"],steps:()=>[{type:"focus",target:"main"}]}],assertion:F},"main.notFocused":{setup:[{when:["keyboard"],steps:()=>[]}],assertion:H},"activeItem.first":{requires:["popup.open"],setup:[{when:["keyboard"],steps:()=>[]}],assertion:P},"activeItem.last":{requires:["popup.open"],setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"main",key:"ArrowUp"}]}],assertion:O},"submenu.open":{requires:["popup.open"],setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"submenuTrigger",key:"ArrowRight"}]},{when:["pointer"],steps:()=>[{type:"click",target:"submenuTrigger"}]}],assertion:B},"submenu.closed":{requires:["submenu.open"],setup:[{when:["keyboard"],steps:()=>[{type:"keypress",target:"submenuTrigger",key:"ArrowLeft"}]},{when:["pointer"],steps:()=>[{type:"click",target:"submenuTrigger"}]}],assertion:R},"submenuTrigger.focused":{setup:[{when:["keyboard"],steps:()=>[{type:"focus",target:"submenuTrigger"}]}],assertion:L},"submenuTrigger.notFocused":{setup:[{when:["keyboard"],steps:()=>[]}],assertion:z},"submenuActiveItem.first":{requires:["submenu.open"],setup:[{when:["keyboard"],steps:()=>[]},{when:["pointer"],steps:()=>[]}],assertion:J}};function V(){return [{target:"popup",assertion:"toBeVisible",failureMessage:"Expected popup to be visible"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expect menu main to have aria-expanded='true'."}]}function _(){return [{target:"popup",assertion:"notToBeVisible",failureMessage:"Expected popup to be closed"},{target:"main",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expect menu main to have aria-expanded='false'."}]}function F(){return [{target:"main",assertion:"toHaveFocus",failureMessage:"Expected menu main to be focused."}]}function H(){return [{target:"main",assertion:"notToHaveFocus",failureMessage:"Expected menu main to not have focused."}]}function P(){return [{target:"relative",assertion:"toHaveFocus",expectedValue:"first",failureMessage:"First menu item should have focus."}]}function O(){return [{target:"relative",assertion:"toHaveFocus",expectedValue:"last",failureMessage:"Last menu item should have focus."}]}function B(){return [{target:"submenu",assertion:"toBeVisible",failureMessage:"Expected submenu to be visible"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"true",failureMessage:"Expect submenu trigger to have aria-expanded='true'."}]}function R(){return [{target:"submenu",assertion:"notToBeVisible",failureMessage:"Expected submenu to be closed"},{target:"submenuTrigger",assertion:"toHaveAttribute",attribute:"aria-expanded",expectedValue:"false",failureMessage:"Expect submenu trigger to have aria-expanded='false'."}]}function L(){return [{target:"submenuTrigger",assertion:"toHaveFocus",failureMessage:"Expected submenu trigger to be focused."}]}function z(){return [{target:"submenuTrigger",assertion:"notToHaveFocus",failureMessage:"Expected submenu trigger to not have focused."}]}function J(){return [{target:"submenuItems",assertion:"toHaveFocus",failureMessage:"First interactive item in the submenu should have focus after Right Arrow open the submenu."}]}function N(a,e){return e.some(o=>a.capabilities.includes(o))}function v(a,e){Array.isArray(a)&&a.length&&!a[0].when&&(a=[{when:["keyboard"],steps:()=>a}]);for(let o of a)if(N(e,o.when))return o.steps(e);throw new Error(`No setup strategy matches capabilities: ${e.capabilities.join(", ")}`)}var U={combobox:A,menu:x},h=class{constructor(e){this.jsonContract=e;}toJSON(){return this.jsonContract}},y=class{constructor(e){this.componentName=e;this.statePack=U[e]||{};}metaValue={};selectorsValue={};relationshipInvariants=[];staticAssertions=[];dynamicTests=[];statePack;meta(e){return this.metaValue=e,this}selectors(e){return this.selectorsValue=e,this}relationships(e){let o=this.statePack,p={capabilities:["keyboard"]},c=(t,i=new Set)=>{if(i.has(t))return [];i.add(t);let s=o[t];if(!s)return [];let r=[];if(Array.isArray(s.requires))for(let n of s.requires)r=r.concat(c(n,i));return s.setup&&(r=r.concat(v(s.setup,p))),r};return e({ariaReference:(t,i,s)=>({requires:r=>{let n=c(r,new Set);return {required:()=>this.relationshipInvariants.push({type:"aria-reference",from:t,attribute:i,to:s,level:"required",setup:n}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:t,attribute:i,to:s,level:"optional",setup:n}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:t,attribute:i,to:s,level:"recommended",setup:n})}},required:()=>this.relationshipInvariants.push({type:"aria-reference",from:t,attribute:i,to:s,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"aria-reference",from:t,attribute:i,to:s,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"aria-reference",from:t,attribute:i,to:s,level:"recommended"})}),contains:(t,i)=>({requires:s=>{let r=c(s,new Set);return {required:()=>this.relationshipInvariants.push({type:"contains",parent:t,child:i,level:"required",setup:r}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:t,child:i,level:"optional",setup:r}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:t,child:i,level:"recommended",setup:r})}},required:()=>this.relationshipInvariants.push({type:"contains",parent:t,child:i,level:"required"}),optional:()=>this.relationshipInvariants.push({type:"contains",parent:t,child:i,level:"optional"}),recommended:()=>this.relationshipInvariants.push({type:"contains",parent:t,child:i,level:"recommended"})})}),this}static(e){return e({target:p=>{let c=t=>{let i=this.statePack,s={capabilities:["keyboard"]},r=(n,u=new Set)=>{if(u.has(n))return [];u.add(n);let d=i[n];if(!d)return [];let g=[];if(Array.isArray(d.requires))for(let k of d.requires)g=g.concat(r(k,u));return d.setup&&(g=g.concat(v(d.setup,s))),g};return r(t,new Set)},l=(t,i,s)=>({required:()=>this.staticAssertions.push({target:p,attribute:t,expectedValue:i,failureMessage:"",level:"required",setup:s}),optional:()=>this.staticAssertions.push({target:p,attribute:t,expectedValue:i,failureMessage:"",level:"optional",setup:s}),recommended:()=>this.staticAssertions.push({target:p,attribute:t,expectedValue:i,failureMessage:"",level:"recommended",setup:s})});return {has:(t,i)=>({...l(t,i),requires:r=>{let n=c(r);return l(t,i,n)}})}}}),this}when(e){return new m(this,this.statePack,e)}addDynamicTest(e){this.dynamicTests.push(e);}build(){return {meta:this.metaValue,selectors:this.selectorsValue,relationships:this.relationshipInvariants.length?this.relationshipInvariants:void 0,static:this.staticAssertions.length?[{assertions:this.staticAssertions}]:[],dynamic:this.dynamicTests}}},m=class{constructor(e,o,p){this.parent=e;this.statePack=o;this.event=p;}_as;_on;_given=[];_then=[];_desc="";_level="required";as(e){return this._as=e,this}on(e){return this._on=e,this}given(e){return this._given=Array.isArray(e)?e:[e],this}then(e){return this._then=Array.isArray(e)?e:[e],this}describe(e){return this._desc=e,this}required(){return this._level="required",this._finalize(),this.parent}optional(){return this._level="optional",this._finalize(),this.parent}recommended(){return this._level="recommended",this._finalize(),this.parent}_finalize(){let p={capabilities:[{keypress:"keyboard",click:"pointer",type:"textInput",focus:"keyboard",hover:"pointer"}[this._as||"keyboard"]||this._as||"keyboard"]},c=(s,r=new Set)=>{if(r.has(s))return [];r.add(s);let n=this.statePack[s];if(!n)return [];let u=[];if(Array.isArray(n.requires))for(let d of n.requires)u=u.concat(c(d,r));return n.setup&&(u=u.concat(v(n.setup,p))),u},l=[];for(let s of this._given)l.push(...c(s));let t=[];for(let s of this._then){let r=this.statePack[s];if(r&&r.assertion!==void 0){let n=r.assertion;if(typeof n=="function")try{n=n();}catch(u){throw new Error(`Error calling assertion function for state '${s}': ${u.message}`)}Array.isArray(n)?t.push(...n):t.push(n);}}let i=[{type:this._as,target:this._on,key:this._as==="keypress"?this.event:void 0}];this.parent.addDynamicTest({description:this._desc||"",level:this._level,action:i,assertions:t,...l.length?{setup:l}:{}});}};function Y(a,e){let o=new y(a);return e(o),new h(o.build())}exports.createContract=Y;