aria-ease 6.2.1 → 6.2.2

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 (37) hide show
  1. package/README.md +5 -17
  2. package/bin/cli.cjs +227 -115
  3. package/bin/cli.js +1 -1
  4. package/bin/{contractTestRunnerPlaywright-HL2VPEEV.js → contractTestRunnerPlaywright-ACAWN34W.js} +227 -115
  5. package/bin/{test-HH2EW2NM.js → test-A3ESFXOR.js} +1 -1
  6. package/dist/{contractTestRunnerPlaywright-EXEBWWPC.js → contractTestRunnerPlaywright-O7FF7GV4.js} +227 -115
  7. package/dist/index.cjs +229 -116
  8. package/dist/index.d.cts +10 -0
  9. package/dist/index.d.ts +10 -0
  10. package/dist/index.js +3 -2
  11. package/dist/src/{Types.d-CxWrr421.d.ts → Types.d-CRjhbrcw.d.cts} +10 -0
  12. package/dist/src/{Types.d-CxWrr421.d.cts → Types.d-CRjhbrcw.d.ts} +10 -0
  13. package/dist/src/accordion/index.d.cts +1 -1
  14. package/dist/src/accordion/index.d.ts +1 -1
  15. package/dist/src/block/index.d.cts +1 -1
  16. package/dist/src/block/index.d.ts +1 -1
  17. package/dist/src/checkbox/index.d.cts +1 -1
  18. package/dist/src/checkbox/index.d.ts +1 -1
  19. package/dist/src/combobox/index.cjs +1 -1
  20. package/dist/src/combobox/index.d.cts +1 -1
  21. package/dist/src/combobox/index.d.ts +1 -1
  22. package/dist/src/combobox/index.js +1 -1
  23. package/dist/src/menu/index.d.cts +1 -1
  24. package/dist/src/menu/index.d.ts +1 -1
  25. package/dist/src/radio/index.cjs +1 -0
  26. package/dist/src/radio/index.d.cts +1 -1
  27. package/dist/src/radio/index.d.ts +1 -1
  28. package/dist/src/radio/index.js +1 -0
  29. package/dist/src/toggle/index.d.cts +1 -1
  30. package/dist/src/toggle/index.d.ts +1 -1
  31. package/dist/src/utils/test/{contractTestRunnerPlaywright-LJHY3AB4.js → contractTestRunnerPlaywright-7BPRTIN4.js} +227 -115
  32. package/dist/src/utils/test/contracts/AccordionContract.json +1 -0
  33. package/dist/src/utils/test/contracts/ComboboxContract.json +1 -0
  34. package/dist/src/utils/test/contracts/MenuContract.json +1 -0
  35. package/dist/src/utils/test/index.cjs +227 -115
  36. package/dist/src/utils/test/index.js +1 -1
  37. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -350,6 +350,11 @@ __export(contractTestRunnerPlaywright_exports, {
350
350
  });
351
351
  async function runContractTestsPlaywright(componentName, url) {
352
352
  const reporter = new ContractReporter(true);
353
+ const actionTimeoutMs = 400;
354
+ const assertionTimeoutMs = 400;
355
+ function isBrowserClosedError(error) {
356
+ return error instanceof Error && error.message.includes("Target page, context or browser has been closed");
357
+ }
353
358
  const contractTyped = contract_default;
354
359
  const contractPath = contractTyped[componentName]?.path;
355
360
  if (!contractPath) {
@@ -368,17 +373,29 @@ async function runContractTestsPlaywright(componentName, url) {
368
373
  try {
369
374
  page = await createTestPage();
370
375
  if (url) {
371
- await page.goto(url, {
372
- waitUntil: "domcontentloaded",
373
- timeout: 3e4
374
- });
376
+ try {
377
+ await page.goto(url, {
378
+ waitUntil: "domcontentloaded",
379
+ timeout: 3e4
380
+ });
381
+ } catch (error) {
382
+ throw new Error(
383
+ `Failed to navigate to ${url}. Ensure dev server is running and accessible. Original error: ${error instanceof Error ? error.message : String(error)}`
384
+ );
385
+ }
375
386
  await page.addStyleTag({ content: `* { transition: none !important; animation: none !important; }` });
376
387
  }
377
388
  const mainSelector = componentContract.selectors.trigger || componentContract.selectors.input || componentContract.selectors.container;
378
389
  if (!mainSelector) {
379
- throw new Error(`No main selector (trigger, input, or container) found in contract for ${componentName}`);
390
+ throw new Error(`CRITICAL: No main selector (trigger, input, or container) found in contract for ${componentName}`);
391
+ }
392
+ try {
393
+ await page.locator(mainSelector).first().waitFor({ state: "attached", timeout: 3e4 });
394
+ } catch (error) {
395
+ throw new Error(
396
+ `CRITICAL: Component element '${mainSelector}' not found on page within 30s. This usually means the component didn't render or the contract selector is incorrect. Original error: ${error instanceof Error ? error.message : String(error)}`
397
+ );
380
398
  }
381
- await page.locator(mainSelector).first().waitFor({ state: "attached", timeout: 3e4 });
382
399
  if (componentName === "menu" && componentContract.selectors.trigger) {
383
400
  await page.locator(componentContract.selectors.trigger).first().waitFor({
384
401
  state: "visible",
@@ -458,6 +475,13 @@ async function runContractTestsPlaywright(componentName, url) {
458
475
  }
459
476
  }
460
477
  for (const dynamicTest of componentContract.dynamic || []) {
478
+ if (!page || page.isClosed()) {
479
+ console.warn(`
480
+ \u26A0\uFE0F Browser closed - skipping remaining ${componentContract.dynamic.length - componentContract.dynamic.indexOf(dynamicTest)} tests
481
+ `);
482
+ failures.push(`CRITICAL: Browser/page closed before completing all tests. ${componentContract.dynamic.length - componentContract.dynamic.indexOf(dynamicTest)} tests skipped.`);
483
+ break;
484
+ }
461
485
  const { action, assertions } = dynamicTest;
462
486
  const failuresBeforeTest = failures.length;
463
487
  if (componentContract.selectors.popup) {
@@ -477,16 +501,16 @@ async function runContractTestsPlaywright(componentName, url) {
477
501
  const closeElement = page.locator(closeSelector).first();
478
502
  await closeElement.focus();
479
503
  await page.keyboard.press("Escape");
480
- menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: 2e3 }).then(() => true).catch(() => false);
504
+ menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: assertionTimeoutMs }).then(() => true).catch(() => false);
481
505
  }
482
506
  if (!menuClosed && componentContract.selectors.trigger) {
483
507
  const triggerElement = page.locator(componentContract.selectors.trigger).first();
484
- await triggerElement.click();
485
- menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: 2e3 }).then(() => true).catch(() => false);
508
+ await triggerElement.click({ timeout: actionTimeoutMs });
509
+ menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: assertionTimeoutMs }).then(() => true).catch(() => false);
486
510
  }
487
511
  if (!menuClosed) {
488
512
  await page.mouse.click(10, 10);
489
- menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: 2e3 }).then(() => true).catch(() => false);
513
+ menuClosed = await (0, test_exports.expect)(popupElement).toBeHidden({ timeout: assertionTimeoutMs }).then(() => true).catch(() => false);
490
514
  }
491
515
  if (!menuClosed) {
492
516
  throw new Error(
@@ -515,9 +539,9 @@ This indicates a problem with the menu component's close functionality.`
515
539
  const isExpanded = await trigger.getAttribute("aria-expanded") === "true";
516
540
  const triggerPanel = await trigger.getAttribute("aria-controls");
517
541
  if (isExpanded && triggerPanel) {
518
- await trigger.click();
542
+ await trigger.click({ timeout: actionTimeoutMs });
519
543
  const panel = page.locator(`#${triggerPanel}`);
520
- await (0, test_exports.expect)(panel).toBeHidden({ timeout: 1e3 }).catch(() => {
544
+ await (0, test_exports.expect)(panel).toBeHidden({ timeout: assertionTimeoutMs }).catch(() => {
521
545
  });
522
546
  }
523
547
  }
@@ -556,134 +580,192 @@ This indicates a problem with the menu component's close functionality.`
556
580
  continue;
557
581
  }
558
582
  for (const act of action) {
583
+ if (!page || page.isClosed()) {
584
+ failures.push(`CRITICAL: Browser/page closed during test execution. Remaining actions skipped.`);
585
+ break;
586
+ }
559
587
  if (act.type === "focus") {
560
- const focusSelector = componentContract.selectors[act.target];
561
- if (!focusSelector) {
562
- failures.push(`Selector for focus target ${act.target} not found.`);
588
+ try {
589
+ const focusSelector = componentContract.selectors[act.target];
590
+ if (!focusSelector) {
591
+ failures.push(`Selector for focus target ${act.target} not found.`);
592
+ continue;
593
+ }
594
+ await page.locator(focusSelector).first().focus({ timeout: actionTimeoutMs });
595
+ } catch (error) {
596
+ if (isBrowserClosedError(error)) {
597
+ failures.push(`CRITICAL: Browser/page closed during test execution. Remaining actions skipped.`);
598
+ break;
599
+ }
600
+ failures.push(`Failed to focus ${act.target}: ${error instanceof Error ? error.message : String(error)}`);
563
601
  continue;
564
602
  }
565
- await page.locator(focusSelector).first().focus();
566
603
  }
567
604
  if (act.type === "type" && act.value) {
568
- const typeSelector = componentContract.selectors[act.target];
569
- if (!typeSelector) {
570
- failures.push(`Selector for type target ${act.target} not found.`);
605
+ try {
606
+ const typeSelector = componentContract.selectors[act.target];
607
+ if (!typeSelector) {
608
+ failures.push(`Selector for type target ${act.target} not found.`);
609
+ continue;
610
+ }
611
+ await page.locator(typeSelector).first().fill(act.value, { timeout: actionTimeoutMs });
612
+ } catch (error) {
613
+ if (isBrowserClosedError(error)) {
614
+ failures.push(`CRITICAL: Browser/page closed during test execution. Remaining actions skipped.`);
615
+ break;
616
+ }
617
+ failures.push(`Failed to type into ${act.target}: ${error instanceof Error ? error.message : String(error)}`);
571
618
  continue;
572
619
  }
573
- await page.locator(typeSelector).first().fill(act.value);
574
620
  }
575
621
  if (act.type === "click") {
576
- if (act.target === "document") {
577
- await page.mouse.click(10, 10);
578
- } else if (act.target === "relative" && act.relativeTarget) {
579
- const relativeSelector = componentContract.selectors.relative;
580
- if (!relativeSelector) {
581
- failures.push(`Relative selector not defined for click action.`);
582
- continue;
583
- }
584
- const relativeElement = await resolveRelativeTarget(relativeSelector, act.relativeTarget);
585
- if (!relativeElement) {
586
- failures.push(`Could not resolve relative target ${act.relativeTarget} for click.`);
587
- continue;
622
+ try {
623
+ if (act.target === "document") {
624
+ await page.mouse.click(10, 10);
625
+ } else if (act.target === "relative" && act.relativeTarget) {
626
+ const relativeSelector = componentContract.selectors.relative;
627
+ if (!relativeSelector) {
628
+ failures.push(`Relative selector not defined for click action.`);
629
+ continue;
630
+ }
631
+ const relativeElement = await resolveRelativeTarget(relativeSelector, act.relativeTarget);
632
+ if (!relativeElement) {
633
+ failures.push(`Could not resolve relative target ${act.relativeTarget} for click.`);
634
+ continue;
635
+ }
636
+ await relativeElement.click({ timeout: actionTimeoutMs });
637
+ } else {
638
+ const actionSelector = componentContract.selectors[act.target];
639
+ if (!actionSelector) {
640
+ failures.push(`Selector for action target ${act.target} not found.`);
641
+ continue;
642
+ }
643
+ await page.locator(actionSelector).first().click({ timeout: actionTimeoutMs });
588
644
  }
589
- await relativeElement.click();
590
- } else {
591
- const actionSelector = componentContract.selectors[act.target];
592
- if (!actionSelector) {
593
- failures.push(`Selector for action target ${act.target} not found.`);
594
- continue;
645
+ } catch (error) {
646
+ if (isBrowserClosedError(error)) {
647
+ failures.push(`CRITICAL: Browser/page closed during test execution. Remaining actions skipped.`);
648
+ break;
595
649
  }
596
- await page.locator(actionSelector).first().click();
650
+ failures.push(`Failed to click ${act.target}: ${error instanceof Error ? error.message : String(error)}`);
651
+ continue;
597
652
  }
598
653
  }
599
654
  if (act.type === "keypress" && act.key) {
600
- const keyMap = {
601
- "Space": "Space",
602
- "Enter": "Enter",
603
- "Escape": "Escape",
604
- "Arrow Up": "ArrowUp",
605
- "Arrow Down": "ArrowDown",
606
- "Arrow Left": "ArrowLeft",
607
- "Arrow Right": "ArrowRight",
608
- "Home": "Home",
609
- "End": "End",
610
- "Tab": "Tab"
611
- };
612
- let keyValue = keyMap[act.key] || act.key;
613
- if (keyValue === "Space") {
614
- keyValue = " ";
615
- } else if (keyValue.includes(" ")) {
616
- keyValue = keyValue.replace(/ /g, "");
617
- }
618
- if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
619
- await page.keyboard.press(keyValue);
620
- } else {
621
- const keypressSelector = componentContract.selectors[act.target];
622
- if (!keypressSelector) {
623
- failures.push(`Selector for keypress target ${act.target} not found.`);
624
- continue;
655
+ try {
656
+ const keyMap = {
657
+ "Space": "Space",
658
+ "Enter": "Enter",
659
+ "Escape": "Escape",
660
+ "Arrow Up": "ArrowUp",
661
+ "Arrow Down": "ArrowDown",
662
+ "Arrow Left": "ArrowLeft",
663
+ "Arrow Right": "ArrowRight",
664
+ "Home": "Home",
665
+ "End": "End",
666
+ "Tab": "Tab"
667
+ };
668
+ let keyValue = keyMap[act.key] || act.key;
669
+ if (keyValue === "Space") {
670
+ keyValue = " ";
671
+ } else if (keyValue.includes(" ")) {
672
+ keyValue = keyValue.replace(/ /g, "");
625
673
  }
626
- const target = page.locator(keypressSelector).first();
627
- const elementCount = await target.count();
628
- if (elementCount === 0) {
629
- reporter.reportTest(dynamicTest, "skip", `Skipping test - ${act.target} element not found (optional submenu test)`);
674
+ if (act.target === "focusable" && ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Escape"].includes(keyValue)) {
675
+ await page.keyboard.press(keyValue);
676
+ } else {
677
+ const keypressSelector = componentContract.selectors[act.target];
678
+ if (!keypressSelector) {
679
+ failures.push(`Selector for keypress target ${act.target} not found.`);
680
+ continue;
681
+ }
682
+ const target = page.locator(keypressSelector).first();
683
+ const elementCount = await target.count();
684
+ if (elementCount === 0) {
685
+ reporter.reportTest(dynamicTest, "skip", `Skipping test - ${act.target} element not found (optional submenu test)`);
686
+ break;
687
+ }
688
+ await target.press(keyValue, { timeout: actionTimeoutMs });
689
+ }
690
+ } catch (error) {
691
+ if (isBrowserClosedError(error)) {
692
+ failures.push(`CRITICAL: Browser/page closed during test execution. Remaining actions skipped.`);
630
693
  break;
631
694
  }
632
- await target.press(keyValue);
695
+ failures.push(`Failed to press ${act.key} on ${act.target}: ${error instanceof Error ? error.message : String(error)}`);
696
+ continue;
633
697
  }
634
698
  }
635
699
  if (act.type === "hover") {
636
- if (act.target === "relative" && act.relativeTarget) {
700
+ try {
701
+ if (act.target === "relative" && act.relativeTarget) {
702
+ const relativeSelector = componentContract.selectors.relative;
703
+ if (!relativeSelector) {
704
+ failures.push(`Relative selector not defined for hover action.`);
705
+ continue;
706
+ }
707
+ const relativeElement = await resolveRelativeTarget(relativeSelector, act.relativeTarget);
708
+ if (!relativeElement) {
709
+ failures.push(`Could not resolve relative target ${act.relativeTarget} for hover.`);
710
+ continue;
711
+ }
712
+ await relativeElement.hover({ timeout: actionTimeoutMs });
713
+ } else {
714
+ const hoverSelector = componentContract.selectors[act.target];
715
+ if (!hoverSelector) {
716
+ failures.push(`Selector for hover target ${act.target} not found.`);
717
+ continue;
718
+ }
719
+ await page.locator(hoverSelector).first().hover({ timeout: actionTimeoutMs });
720
+ }
721
+ } catch (error) {
722
+ if (isBrowserClosedError(error)) {
723
+ failures.push(`CRITICAL: Browser/page closed during test execution. Remaining actions skipped.`);
724
+ break;
725
+ }
726
+ failures.push(`Failed to hover ${act.target}: ${error instanceof Error ? error.message : String(error)}`);
727
+ continue;
728
+ }
729
+ }
730
+ }
731
+ for (const assertion of assertions) {
732
+ if (!page || page.isClosed()) {
733
+ failures.push(`CRITICAL: Browser/page closed before completing all tests. Increase test timeout or reduce test complexity.`);
734
+ break;
735
+ }
736
+ let target;
737
+ try {
738
+ if (assertion.target === "relative") {
637
739
  const relativeSelector = componentContract.selectors.relative;
638
740
  if (!relativeSelector) {
639
- failures.push(`Relative selector not defined for hover action.`);
741
+ failures.push("Relative selector is not defined in the contract.");
640
742
  continue;
641
743
  }
642
- const relativeElement = await resolveRelativeTarget(relativeSelector, act.relativeTarget);
643
- if (!relativeElement) {
644
- failures.push(`Could not resolve relative target ${act.relativeTarget} for hover.`);
744
+ const relativeTargetValue = assertion.relativeTarget || assertion.expectedValue;
745
+ if (!relativeTargetValue) {
746
+ failures.push("Relative target or expected value is not defined.");
645
747
  continue;
646
748
  }
647
- await relativeElement.hover();
749
+ target = await resolveRelativeTarget(relativeSelector, relativeTargetValue);
648
750
  } else {
649
- const hoverSelector = componentContract.selectors[act.target];
650
- if (!hoverSelector) {
651
- failures.push(`Selector for hover target ${act.target} not found.`);
751
+ const assertionSelector = componentContract.selectors[assertion.target];
752
+ if (!assertionSelector) {
753
+ failures.push(`Selector for assertion target ${assertion.target} not found.`);
652
754
  continue;
653
755
  }
654
- await page.locator(hoverSelector).first().hover();
756
+ target = page.locator(assertionSelector).first();
655
757
  }
656
- }
657
- }
658
- for (const assertion of assertions) {
659
- let target;
660
- if (assertion.target === "relative") {
661
- const relativeSelector = componentContract.selectors.relative;
662
- if (!relativeSelector) {
663
- failures.push("Relative selector is not defined in the contract.");
664
- continue;
665
- }
666
- const relativeTargetValue = assertion.relativeTarget || assertion.expectedValue;
667
- if (!relativeTargetValue) {
668
- failures.push("Relative target or expected value is not defined.");
758
+ if (!target) {
759
+ failures.push(`Target ${assertion.target} not found.`);
669
760
  continue;
670
761
  }
671
- target = await resolveRelativeTarget(relativeSelector, relativeTargetValue);
672
- } else {
673
- const assertionSelector = componentContract.selectors[assertion.target];
674
- if (!assertionSelector) {
675
- failures.push(`Selector for assertion target ${assertion.target} not found.`);
676
- continue;
677
- }
678
- target = page.locator(assertionSelector).first();
679
- }
680
- if (!target) {
681
- failures.push(`Target ${assertion.target} not found.`);
762
+ } catch (error) {
763
+ failures.push(`Failed to resolve target ${assertion.target}: ${error instanceof Error ? error.message : String(error)}`);
682
764
  continue;
683
765
  }
684
766
  if (assertion.assertion === "toBeVisible") {
685
767
  try {
686
- await (0, test_exports.expect)(target).toBeVisible({ timeout: 2e3 });
768
+ await (0, test_exports.expect)(target).toBeVisible({ timeout: assertionTimeoutMs });
687
769
  passes.push(`${assertion.target} is visible as expected. Test: "${dynamicTest.description}".`);
688
770
  } catch {
689
771
  const debugState = await page.evaluate((sel) => {
@@ -697,7 +779,7 @@ This indicates a problem with the menu component's close functionality.`
697
779
  }
698
780
  if (assertion.assertion === "notToBeVisible") {
699
781
  try {
700
- await (0, test_exports.expect)(target).toBeHidden({ timeout: 2e3 });
782
+ await (0, test_exports.expect)(target).toBeHidden({ timeout: assertionTimeoutMs });
701
783
  passes.push(`${assertion.target} is not visible as expected. Test: "${dynamicTest.description}".`);
702
784
  } catch {
703
785
  const debugState = await page.evaluate((sel) => {
@@ -719,7 +801,7 @@ This indicates a problem with the menu component's close functionality.`
719
801
  failures.push(assertion.failureMessage + ` ${assertion.target} "${assertion.attribute}" should not be empty, found "${attributeValue}".`);
720
802
  }
721
803
  } else {
722
- await (0, test_exports.expect)(target).toHaveAttribute(assertion.attribute, assertion.expectedValue, { timeout: 3e3 });
804
+ await (0, test_exports.expect)(target).toHaveAttribute(assertion.attribute, assertion.expectedValue, { timeout: assertionTimeoutMs });
723
805
  passes.push(`${assertion.target} has expected "${assertion.attribute}". Test: "${dynamicTest.description}".`);
724
806
  }
725
807
  } catch {
@@ -749,7 +831,7 @@ This indicates a problem with the menu component's close functionality.`
749
831
  }
750
832
  if (assertion.assertion === "toHaveFocus") {
751
833
  try {
752
- await (0, test_exports.expect)(target).toBeFocused({ timeout: 5e3 });
834
+ await (0, test_exports.expect)(target).toBeFocused({ timeout: assertionTimeoutMs });
753
835
  passes.push(`${assertion.target} has focus as expected. Test: "${dynamicTest.description}".`);
754
836
  } catch {
755
837
  const actualFocus = await page.evaluate(() => {
@@ -784,18 +866,48 @@ This indicates a problem with the menu component's close functionality.`
784
866
  reporter.summary(failures);
785
867
  } catch (error) {
786
868
  if (error instanceof Error) {
787
- if (error.message.includes("Executable doesn't exist")) {
788
- console.error("\n\u274C Playwright browsers not found!\n");
869
+ if (error.message.includes("Executable doesn't exist") || error.message.includes("browserType.launch")) {
870
+ console.error("\n\u274C CRITICAL: Playwright browsers not found!\n");
789
871
  console.log("\u{1F4E6} Run: npx playwright install chromium\n");
790
- failures.push("Playwright browser not installed. Run: npx playwright install chromium");
791
- } else if (error.message.includes("net::ERR_CONNECTION_REFUSED")) {
792
- console.error("\n\u274C Cannot connect to dev server!\n");
872
+ failures.push("CRITICAL: Playwright browser not installed. Run: npx playwright install chromium");
873
+ } else if (error.message.includes("net::ERR_CONNECTION_REFUSED") || error.message.includes("NS_ERROR_CONNECTION_REFUSED")) {
874
+ console.error("\n\u274C CRITICAL: Cannot connect to dev server!\n");
793
875
  console.log(` Make sure your dev server is running at ${url}
794
876
  `);
795
- failures.push(`Dev server not running at ${url}`);
877
+ failures.push(`CRITICAL: Dev server not running at ${url}`);
878
+ } else if (error.message.includes("Timeout") && error.message.includes("waitFor")) {
879
+ console.error("\n\u274C CRITICAL: Component not found on page!\n");
880
+ console.log(` The component selector could not be found within 30 seconds.
881
+ `);
882
+ console.log(` This usually means:
883
+ `);
884
+ console.log(` - The component didn't render
885
+ `);
886
+ console.log(` - The URL is incorrect
887
+ `);
888
+ console.log(` - The component selector in the contract is wrong
889
+ `);
890
+ failures.push(`CRITICAL: Component element not found on page - ${error.message}`);
891
+ } else if (error.message.includes("Target page, context or browser has been closed")) {
892
+ console.error("\n\u274C CRITICAL: Browser/page was closed unexpectedly!\n");
893
+ console.log(` This usually means:
894
+ `);
895
+ console.log(` - The test timeout was too short
896
+ `);
897
+ console.log(` - The browser crashed
898
+ `);
899
+ console.log(` - An external process killed the browser
900
+ `);
901
+ failures.push(`CRITICAL: Browser/page closed unexpectedly - ${error.message}`);
902
+ } else if (error.message.includes("FATAL")) {
903
+ console.error(`
904
+ ${error.message}
905
+ `);
906
+ failures.push(error.message);
796
907
  } else {
797
- console.error("\u274C Playwright test error:", error.message);
798
- failures.push(`Test error: ${error.message}`);
908
+ console.error("\n\u274C UNEXPECTED ERROR:", error.message);
909
+ console.error("Stack:", error.stack);
910
+ failures.push(`UNEXPECTED ERROR: ${error.message}`);
799
911
  }
800
912
  }
801
913
  } finally {
@@ -1614,6 +1726,7 @@ function makeRadioAccessible({ radioGroupId, radiosClass, defaultSelectedIndex =
1614
1726
  selectRadio(nextIndex);
1615
1727
  break;
1616
1728
  case " ":
1729
+ case "Enter":
1617
1730
  event.preventDefault();
1618
1731
  selectRadio(index);
1619
1732
  break;
@@ -2052,7 +2165,7 @@ function makeComboboxAccessible({ comboboxInputId, comboboxButtonId, listBoxId,
2052
2165
  activeIndex = -1;
2053
2166
  setActiveDescendant(-1);
2054
2167
  }
2055
- return { cleanup, refresh };
2168
+ return { cleanup, refresh, openListbox, closeListbox };
2056
2169
  }
2057
2170
 
2058
2171
  // src/utils/test/src/test.ts
package/dist/index.d.cts CHANGED
@@ -7,25 +7,35 @@ interface JestAxeResult {
7
7
  interface AccessibilityInstance {
8
8
  cleanup: () => void;
9
9
  refresh?: () => void;
10
+
11
+ //Menu methods
10
12
  openMenu?: () => void;
11
13
  closeMenu?: () => void;
14
+
12
15
  // Accordion methods
13
16
  expandItem?: (index: number) => void;
14
17
  collapseItem?: (index: number) => void;
15
18
  toggleItem?: (index: number) => void;
19
+
16
20
  // Radio methods
17
21
  selectRadio?: (index: number) => void;
18
22
  getSelectedIndex?: () => number;
23
+
19
24
  // Checkbox methods
20
25
  toggleCheckbox?: (index: number) => void;
21
26
  setCheckboxState?: (index: number, checked: boolean) => void;
22
27
  getCheckedStates?: () => boolean[];
23
28
  getCheckedIndices?: () => number[];
29
+
24
30
  // Toggle methods
25
31
  toggleButton?: (index: number) => void;
26
32
  setPressed?: (index: number, pressed: boolean) => void;
27
33
  getPressedStates?: () => boolean[];
28
34
  getPressedIndices?: () => number[];
35
+
36
+ //Combobox methods
37
+ openListbox?: () => void;
38
+ closeListbox?: () => void;
29
39
  }
30
40
 
31
41
  interface AccordionConfig {
package/dist/index.d.ts CHANGED
@@ -7,25 +7,35 @@ interface JestAxeResult {
7
7
  interface AccessibilityInstance {
8
8
  cleanup: () => void;
9
9
  refresh?: () => void;
10
+
11
+ //Menu methods
10
12
  openMenu?: () => void;
11
13
  closeMenu?: () => void;
14
+
12
15
  // Accordion methods
13
16
  expandItem?: (index: number) => void;
14
17
  collapseItem?: (index: number) => void;
15
18
  toggleItem?: (index: number) => void;
19
+
16
20
  // Radio methods
17
21
  selectRadio?: (index: number) => void;
18
22
  getSelectedIndex?: () => number;
23
+
19
24
  // Checkbox methods
20
25
  toggleCheckbox?: (index: number) => void;
21
26
  setCheckboxState?: (index: number, checked: boolean) => void;
22
27
  getCheckedStates?: () => boolean[];
23
28
  getCheckedIndices?: () => number[];
29
+
24
30
  // Toggle methods
25
31
  toggleButton?: (index: number) => void;
26
32
  setPressed?: (index: number, pressed: boolean) => void;
27
33
  getPressedStates?: () => boolean[];
28
34
  getPressedIndices?: () => number[];
35
+
36
+ //Combobox methods
37
+ openListbox?: () => void;
38
+ closeListbox?: () => void;
29
39
  }
30
40
 
31
41
  interface AccordionConfig {
package/dist/index.js CHANGED
@@ -787,6 +787,7 @@ function makeRadioAccessible({ radioGroupId, radiosClass, defaultSelectedIndex =
787
787
  selectRadio(nextIndex);
788
788
  break;
789
789
  case " ":
790
+ case "Enter":
790
791
  event.preventDefault();
791
792
  selectRadio(index);
792
793
  break;
@@ -1225,7 +1226,7 @@ function makeComboboxAccessible({ comboboxInputId, comboboxButtonId, listBoxId,
1225
1226
  activeIndex = -1;
1226
1227
  setActiveDescendant(-1);
1227
1228
  }
1228
- return { cleanup, refresh };
1229
+ return { cleanup, refresh, openListbox, closeListbox };
1229
1230
  }
1230
1231
 
1231
1232
  // src/utils/test/src/test.ts
@@ -1337,7 +1338,7 @@ Error: ${error instanceof Error ? error.message : String(error)}`
1337
1338
  const devServerUrl = await checkDevServer(url);
1338
1339
  if (devServerUrl) {
1339
1340
  console.log(`\u{1F3AD} Running Playwright tests on ${devServerUrl}`);
1340
- const { runContractTestsPlaywright } = await import("./contractTestRunnerPlaywright-EXEBWWPC.js");
1341
+ const { runContractTestsPlaywright } = await import("./contractTestRunnerPlaywright-O7FF7GV4.js");
1341
1342
  contract = await runContractTestsPlaywright(componentName, devServerUrl);
1342
1343
  } else {
1343
1344
  throw new Error(
@@ -1,25 +1,35 @@
1
1
  interface AccessibilityInstance {
2
2
  cleanup: () => void;
3
3
  refresh?: () => void;
4
+
5
+ //Menu methods
4
6
  openMenu?: () => void;
5
7
  closeMenu?: () => void;
8
+
6
9
  // Accordion methods
7
10
  expandItem?: (index: number) => void;
8
11
  collapseItem?: (index: number) => void;
9
12
  toggleItem?: (index: number) => void;
13
+
10
14
  // Radio methods
11
15
  selectRadio?: (index: number) => void;
12
16
  getSelectedIndex?: () => number;
17
+
13
18
  // Checkbox methods
14
19
  toggleCheckbox?: (index: number) => void;
15
20
  setCheckboxState?: (index: number, checked: boolean) => void;
16
21
  getCheckedStates?: () => boolean[];
17
22
  getCheckedIndices?: () => number[];
23
+
18
24
  // Toggle methods
19
25
  toggleButton?: (index: number) => void;
20
26
  setPressed?: (index: number, pressed: boolean) => void;
21
27
  getPressedStates?: () => boolean[];
22
28
  getPressedIndices?: () => number[];
29
+
30
+ //Combobox methods
31
+ openListbox?: () => void;
32
+ closeListbox?: () => void;
23
33
  }
24
34
 
25
35
  interface AccordionConfig {
@@ -1,25 +1,35 @@
1
1
  interface AccessibilityInstance {
2
2
  cleanup: () => void;
3
3
  refresh?: () => void;
4
+
5
+ //Menu methods
4
6
  openMenu?: () => void;
5
7
  closeMenu?: () => void;
8
+
6
9
  // Accordion methods
7
10
  expandItem?: (index: number) => void;
8
11
  collapseItem?: (index: number) => void;
9
12
  toggleItem?: (index: number) => void;
13
+
10
14
  // Radio methods
11
15
  selectRadio?: (index: number) => void;
12
16
  getSelectedIndex?: () => number;
17
+
13
18
  // Checkbox methods
14
19
  toggleCheckbox?: (index: number) => void;
15
20
  setCheckboxState?: (index: number, checked: boolean) => void;
16
21
  getCheckedStates?: () => boolean[];
17
22
  getCheckedIndices?: () => number[];
23
+
18
24
  // Toggle methods
19
25
  toggleButton?: (index: number) => void;
20
26
  setPressed?: (index: number, pressed: boolean) => void;
21
27
  getPressedStates?: () => boolean[];
22
28
  getPressedIndices?: () => number[];
29
+
30
+ //Combobox methods
31
+ openListbox?: () => void;
32
+ closeListbox?: () => void;
23
33
  }
24
34
 
25
35
  interface AccordionConfig {
@@ -1,4 +1,4 @@
1
- import { A as AccordionConfig, a as AccessibilityInstance } from '../Types.d-CxWrr421.cjs';
1
+ import { A as AccordionConfig, a as AccessibilityInstance } from '../Types.d-CRjhbrcw.cjs';
2
2
 
3
3
  /**
4
4
  * Makes an accordion accessible by managing ARIA attributes, keyboard navigation, and state.