@trackunit/react-vite-test-setup 0.0.7 → 0.0.8

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.
package/index.cjs.js CHANGED
@@ -661,6 +661,78 @@ const setupTranslations = () => {
661
661
  }));
662
662
  };
663
663
 
664
+ const TARGET_ORIGIN_WILDCARD = "*";
665
+ let postMessagePolyfillInstalled = false;
666
+ const patchedPostMessageWindows = new WeakSet();
667
+ /**
668
+ * Wrap a window's `postMessage` so it accepts both the legacy
669
+ * `postMessage(message, targetOrigin)` and the modern
670
+ * `postMessage(message, { targetOrigin, transfer })` signatures, forwarding
671
+ * either to the legacy two-arg form that jsdom understands. Idempotent per
672
+ * window instance.
673
+ */
674
+ const patchWindowPostMessage = (target) => {
675
+ if (patchedPostMessageWindows.has(target)) {
676
+ return;
677
+ }
678
+ const originalPostMessage = target.postMessage.bind(target);
679
+ const wrapped = (message, optionsOrTargetOrigin) => {
680
+ let targetOrigin = TARGET_ORIGIN_WILDCARD;
681
+ if (typeof optionsOrTargetOrigin === "string") {
682
+ targetOrigin = optionsOrTargetOrigin;
683
+ }
684
+ else if (typeof optionsOrTargetOrigin === "object" &&
685
+ optionsOrTargetOrigin !== null &&
686
+ "targetOrigin" in optionsOrTargetOrigin &&
687
+ typeof optionsOrTargetOrigin.targetOrigin === "string") {
688
+ targetOrigin = optionsOrTargetOrigin.targetOrigin;
689
+ }
690
+ originalPostMessage(message, targetOrigin);
691
+ };
692
+ Object.defineProperty(target, "postMessage", { value: wrapped, writable: true, configurable: true });
693
+ patchedPostMessageWindows.add(target);
694
+ };
695
+ /**
696
+ * Polyfill jsdom's `Window.postMessage` so it accepts the modern
697
+ * `postMessage(message, { targetOrigin, transfer })` options-object form in
698
+ * addition to the legacy `postMessage(message, targetOrigin)` form.
699
+ *
700
+ * Penpal v7's `WindowMessenger.sendMessage` uses the options-object form
701
+ * (part of the WHATWG HTML spec, supported by real browsers and happy-dom),
702
+ * but jsdom 26 still only implements the legacy two-arg form and stringifies
703
+ * the options object into the target-origin slot. Any component test that
704
+ * either initialises the iris-app-runtime `HostConnector` singleton (via
705
+ * `ThemeCssProviderIrisApp` → `getThemeCssProperties`) or mounts a
706
+ * `WidgetExtensionFrame` / `IrisAppIframe` (via `usePenpalIframe`'s
707
+ * `WindowMessenger({ remoteWindow: iframe.contentWindow })`) then blows up
708
+ * with `Invalid target origin '[object Object]'`.
709
+ *
710
+ * jsdom installs `postMessage` as an own property on every window (including
711
+ * iframe `contentWindow`s), so a plain `Window.prototype` patch doesn't
712
+ * cover iframes. Hook the prototype's `contentWindow` getter to lazy-patch
713
+ * iframe windows on first access. Idempotent.
714
+ */
715
+ const installPostMessagePolyfill = () => {
716
+ if (postMessagePolyfillInstalled) {
717
+ return;
718
+ }
719
+ patchWindowPostMessage(window);
720
+ const iframeDescriptor = Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, "contentWindow");
721
+ if (iframeDescriptor?.get && iframeDescriptor.configurable) {
722
+ const originalGetter = iframeDescriptor.get;
723
+ Object.defineProperty(HTMLIFrameElement.prototype, "contentWindow", {
724
+ configurable: true,
725
+ get: function getContentWindow() {
726
+ const contentWindow = originalGetter.call(this);
727
+ if (contentWindow !== null) {
728
+ patchWindowPostMessage(contentWindow);
729
+ }
730
+ return contentWindow;
731
+ },
732
+ });
733
+ }
734
+ postMessagePolyfillInstalled = true;
735
+ };
664
736
  /**
665
737
  * Flushes all promises in the queue.
666
738
  * This is useful when testing async code.
@@ -900,6 +972,7 @@ const setupReactTestingLibrary = () => {
900
972
  setupMatchMediaMock();
901
973
  setupResizeObserver();
902
974
  setupIntersectionObserver();
975
+ installPostMessagePolyfill();
903
976
  };
904
977
 
905
978
  /**
package/index.esm.js CHANGED
@@ -640,6 +640,78 @@ const setupTranslations = () => {
640
640
  }));
641
641
  };
642
642
 
643
+ const TARGET_ORIGIN_WILDCARD = "*";
644
+ let postMessagePolyfillInstalled = false;
645
+ const patchedPostMessageWindows = new WeakSet();
646
+ /**
647
+ * Wrap a window's `postMessage` so it accepts both the legacy
648
+ * `postMessage(message, targetOrigin)` and the modern
649
+ * `postMessage(message, { targetOrigin, transfer })` signatures, forwarding
650
+ * either to the legacy two-arg form that jsdom understands. Idempotent per
651
+ * window instance.
652
+ */
653
+ const patchWindowPostMessage = (target) => {
654
+ if (patchedPostMessageWindows.has(target)) {
655
+ return;
656
+ }
657
+ const originalPostMessage = target.postMessage.bind(target);
658
+ const wrapped = (message, optionsOrTargetOrigin) => {
659
+ let targetOrigin = TARGET_ORIGIN_WILDCARD;
660
+ if (typeof optionsOrTargetOrigin === "string") {
661
+ targetOrigin = optionsOrTargetOrigin;
662
+ }
663
+ else if (typeof optionsOrTargetOrigin === "object" &&
664
+ optionsOrTargetOrigin !== null &&
665
+ "targetOrigin" in optionsOrTargetOrigin &&
666
+ typeof optionsOrTargetOrigin.targetOrigin === "string") {
667
+ targetOrigin = optionsOrTargetOrigin.targetOrigin;
668
+ }
669
+ originalPostMessage(message, targetOrigin);
670
+ };
671
+ Object.defineProperty(target, "postMessage", { value: wrapped, writable: true, configurable: true });
672
+ patchedPostMessageWindows.add(target);
673
+ };
674
+ /**
675
+ * Polyfill jsdom's `Window.postMessage` so it accepts the modern
676
+ * `postMessage(message, { targetOrigin, transfer })` options-object form in
677
+ * addition to the legacy `postMessage(message, targetOrigin)` form.
678
+ *
679
+ * Penpal v7's `WindowMessenger.sendMessage` uses the options-object form
680
+ * (part of the WHATWG HTML spec, supported by real browsers and happy-dom),
681
+ * but jsdom 26 still only implements the legacy two-arg form and stringifies
682
+ * the options object into the target-origin slot. Any component test that
683
+ * either initialises the iris-app-runtime `HostConnector` singleton (via
684
+ * `ThemeCssProviderIrisApp` → `getThemeCssProperties`) or mounts a
685
+ * `WidgetExtensionFrame` / `IrisAppIframe` (via `usePenpalIframe`'s
686
+ * `WindowMessenger({ remoteWindow: iframe.contentWindow })`) then blows up
687
+ * with `Invalid target origin '[object Object]'`.
688
+ *
689
+ * jsdom installs `postMessage` as an own property on every window (including
690
+ * iframe `contentWindow`s), so a plain `Window.prototype` patch doesn't
691
+ * cover iframes. Hook the prototype's `contentWindow` getter to lazy-patch
692
+ * iframe windows on first access. Idempotent.
693
+ */
694
+ const installPostMessagePolyfill = () => {
695
+ if (postMessagePolyfillInstalled) {
696
+ return;
697
+ }
698
+ patchWindowPostMessage(window);
699
+ const iframeDescriptor = Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, "contentWindow");
700
+ if (iframeDescriptor?.get && iframeDescriptor.configurable) {
701
+ const originalGetter = iframeDescriptor.get;
702
+ Object.defineProperty(HTMLIFrameElement.prototype, "contentWindow", {
703
+ configurable: true,
704
+ get: function getContentWindow() {
705
+ const contentWindow = originalGetter.call(this);
706
+ if (contentWindow !== null) {
707
+ patchWindowPostMessage(contentWindow);
708
+ }
709
+ return contentWindow;
710
+ },
711
+ });
712
+ }
713
+ postMessagePolyfillInstalled = true;
714
+ };
643
715
  /**
644
716
  * Flushes all promises in the queue.
645
717
  * This is useful when testing async code.
@@ -879,6 +951,7 @@ const setupReactTestingLibrary = () => {
879
951
  setupMatchMediaMock();
880
952
  setupResizeObserver();
881
953
  setupIntersectionObserver();
954
+ installPostMessagePolyfill();
882
955
  };
883
956
 
884
957
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@trackunit/react-vite-test-setup",
3
3
  "description": "Test setup utilities for React applications",
4
- "version": "0.0.7",
4
+ "version": "0.0.8",
5
5
  "repository": "https://github.com/Trackunit/manager",
6
6
  "license": "SEE LICENSE IN LICENSE.txt",
7
7
  "engines": {