aria-ease 6.14.0 → 7.0.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 (93) hide show
  1. package/dist/AccordionComponentStrategy-2SWMNUR6.js +1 -0
  2. package/dist/ComboboxComponentStrategy-YSYLR2U5.js +5 -0
  3. package/dist/MenuComponentStrategy-C22BZEBH.js +5 -0
  4. package/dist/RelativeTargetResolver-T4P25J2M.js +1 -0
  5. package/dist/TabsComponentStrategy-ADEEFJXM.js +1 -0
  6. package/dist/audit-APAPHXRO.js +9 -0
  7. package/dist/badgeHelper-IB5RTMAG.js +11 -0
  8. package/dist/badgeHelper-JSROP5ML.js +1 -0
  9. package/dist/buildContracts-T4XQZBDU.js +13 -0
  10. package/dist/chunk-52I3INNG.js +11 -0
  11. package/dist/chunk-APUMBDOT.js +1 -0
  12. package/dist/chunk-BHNO4ZI3.js +1 -0
  13. package/dist/chunk-CNU4N4AY.js +1 -0
  14. package/dist/chunk-SM6ZKEDR.js +1 -0
  15. package/dist/chunk-ZNQ5BXVJ.js +1 -0
  16. package/dist/cli.cjs +132 -3560
  17. package/dist/cli.js +19 -161
  18. package/dist/configLoader-ZEJVXLX7.js +1 -0
  19. package/dist/configLoader-ZXTSCIP6.js +1 -0
  20. package/dist/contractTestRunnerPlaywright-FOCQTM4L.js +46 -0
  21. package/dist/contractTestRunnerPlaywright-QPU6HZXG.js +46 -0
  22. package/dist/formatters-H3CPDLG5.js +87 -0
  23. package/dist/index.cjs +64 -5103
  24. package/dist/index.d.cts +4 -6
  25. package/dist/index.d.ts +4 -6
  26. package/dist/index.js +17 -2703
  27. package/dist/src/accordion/index.cjs +1 -183
  28. package/dist/src/accordion/index.js +1 -181
  29. package/dist/src/block/index.cjs +1 -124
  30. package/dist/src/block/index.js +1 -122
  31. package/dist/src/checkbox/index.cjs +1 -109
  32. package/dist/src/checkbox/index.js +1 -107
  33. package/dist/src/combobox/index.cjs +1 -265
  34. package/dist/src/combobox/index.js +1 -263
  35. package/dist/src/menu/index.cjs +1 -339
  36. package/dist/src/menu/index.js +1 -337
  37. package/dist/src/radio/index.cjs +1 -117
  38. package/dist/src/radio/index.js +1 -115
  39. package/dist/src/tabs/index.cjs +1 -265
  40. package/dist/src/tabs/index.js +1 -263
  41. package/dist/src/toggle/index.cjs +1 -119
  42. package/dist/src/toggle/index.js +1 -117
  43. package/dist/src/utils/test/AccordionComponentStrategy-X2GSQ5KT.js +1 -0
  44. package/dist/src/utils/test/ComboboxComponentStrategy-SICWLI27.js +5 -0
  45. package/dist/src/utils/test/MenuComponentStrategy-R4VPAHDE.js +5 -0
  46. package/dist/src/utils/test/RelativeTargetResolver-UQQMZHI6.js +1 -0
  47. package/dist/src/utils/test/TabsComponentStrategy-L2PYNEW6.js +1 -0
  48. package/dist/src/utils/test/badgeHelper-ER5ZOHWF.js +11 -0
  49. package/dist/src/utils/test/chunk-APUMBDOT.js +1 -0
  50. package/dist/src/utils/test/chunk-BHNO4ZI3.js +1 -0
  51. package/dist/src/utils/test/configLoader-NCYRL2O6.js +1 -0
  52. package/dist/src/utils/test/contractTestRunnerPlaywright-YZCMF64Q.js +46 -0
  53. package/dist/src/utils/test/dsl/index.cjs +1 -838
  54. package/dist/src/utils/test/dsl/index.d.cts +2 -4
  55. package/dist/src/utils/test/dsl/index.d.ts +2 -4
  56. package/dist/src/utils/test/dsl/index.js +1 -836
  57. package/dist/src/utils/test/index.cjs +64 -2672
  58. package/dist/src/utils/test/index.d.cts +2 -2
  59. package/dist/src/utils/test/index.d.ts +2 -2
  60. package/dist/src/utils/test/index.js +16 -340
  61. package/dist/test-VXSCSKV5.js +19 -0
  62. package/package.json +7 -9
  63. package/dist/AccordionComponentStrategy-4ZEIQ2V6.js +0 -42
  64. package/dist/ComboboxComponentStrategy-DU342VMB.js +0 -64
  65. package/dist/MenuComponentStrategy-VYCC2XOM.js +0 -81
  66. package/dist/RelativeTargetResolver-DJAITO6D.js +0 -7
  67. package/dist/TabsComponentStrategy-3SQURPMX.js +0 -29
  68. package/dist/audit-JYEPKLHR.js +0 -63
  69. package/dist/badgeHelper-JOWO6RQG.js +0 -15
  70. package/dist/badgeHelper-RDOMCC6E.js +0 -108
  71. package/dist/buildContracts-VIV6GM56.js +0 -437
  72. package/dist/chunk-4DU5Z5BR.js +0 -340
  73. package/dist/chunk-GJGUY643.js +0 -182
  74. package/dist/chunk-GLT43UVH.js +0 -43
  75. package/dist/chunk-I2KLQ2HA.js +0 -22
  76. package/dist/chunk-JJEPLK7L.js +0 -107
  77. package/dist/chunk-PK5L2SAF.js +0 -17
  78. package/dist/configLoader-Q7N5XV4P.js +0 -183
  79. package/dist/configLoader-REHK3S3Q.js +0 -7
  80. package/dist/contractTestRunnerPlaywright-B2HLZKKK.js +0 -1394
  81. package/dist/contractTestRunnerPlaywright-RWK52C7S.js +0 -1394
  82. package/dist/formatters-32KQIIYS.js +0 -183
  83. package/dist/src/utils/test/AccordionComponentStrategy-WRHZOEN6.js +0 -38
  84. package/dist/src/utils/test/ComboboxComponentStrategy-XKQ72RFD.js +0 -60
  85. package/dist/src/utils/test/MenuComponentStrategy-6XWU5KLW.js +0 -77
  86. package/dist/src/utils/test/RelativeTargetResolver-G2XDN2VV.js +0 -1
  87. package/dist/src/utils/test/TabsComponentStrategy-BKG53SEV.js +0 -26
  88. package/dist/src/utils/test/badgeHelper-HZKGOPB4.js +0 -102
  89. package/dist/src/utils/test/chunk-4DU5Z5BR.js +0 -332
  90. package/dist/src/utils/test/chunk-GLT43UVH.js +0 -41
  91. package/dist/src/utils/test/configLoader-NA7IBCS3.js +0 -181
  92. package/dist/src/utils/test/contractTestRunnerPlaywright-5FIGA5G4.js +0 -1372
  93. 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;