Skip to content

fix: support postMessage options overload and handle transferable clone failures in Firefox#3078

Open
crisryantan wants to merge 3 commits intoDevExpress:masterfrom
crisryantan:fix/postmessage-transferable-firefox
Open

fix: support postMessage options overload and handle transferable clone failures in Firefox#3078
crisryantan wants to merge 3 commits intoDevExpress:masterfrom
crisryantan:fix/postmessage-transferable-firefox

Conversation

@crisryantan
Copy link
Copy Markdown

@crisryantan crisryantan commented Mar 27, 2026

Closes #3077

Problem

MessageSandbox.postMessage did not support the modern postMessage(message, { targetOrigin, transfer }) overload.
When the second argument was an object, the call was treated as invalid and returned early, so messages were not delivered.

This also caused issues for MessageChannel-based communication in Firefox, because the options object (which may include transfer) was being handled as targetUrl instead of a proper overload shape.

Solution

1. Support the postMessage(message, options) overload

postMessage now detects when the second argument is an object and delegates to _postMessageWithOptionsOverload.

2. Handle options and transferables using native semantics

_postMessageWithOptionsOverload:

  • extracts targetOrigin from options (falls back to current origin when missing),
  • wraps only the user message with Hammerhead metadata,
  • forwards options with targetOrigin: '*' so transferable handling remains native.

3. Keep legacy signature behavior intact

The existing wrapped flow for postMessage(message, targetOrigin, transfer?) remains in place.

Per maintainer feedback, the additional clone-error fallback path and related receive-side handling were removed.

Tests

  • Added test for postMessage(message, { targetOrigin }) options overload.
  • Added test for postMessage(message, { targetOrigin, transfer }) with MessagePort.
  • Updated the existing object-second-argument test to verify message delivery via the options-overload path.

Made with Cursor

…ne failures

MessageSandbox.postMessage previously did not support the modern
postMessage(message, { targetOrigin, transfer }) overload, silently
dropping such calls. This broke iframe communication for applications
using the options-based API.

Additionally, in Firefox the Hammerhead message envelope can cause
DataCloneError ("MessagePort object could not be cloned") when
transferable objects are present in the transfer list. The structured
clone algorithm in Firefox fails to reconcile the wrapped message
with the original transfer list.

This commit:

- Adds support for the postMessage(message, options) overload by
  detecting an object second argument and extracting targetOrigin
  and transfer from it.

- Wraps the fastApply call in a try/catch so that when structured
  clone fails (e.g. Firefox with MessagePort transfers), the
  original unwrapped message is sent as a fallback.

- Updates the receiving side (MessageEvent.data getter and
  _onWindowMessage) to pass through messages that do not carry the
  Hammerhead user-message envelope, since they may arrive from the
  fallback path.

- Updates tests to cover the options overload and adjusts the
  existing "object as targetOrigin" test to reflect the new
  behavior.

Made-with: Cursor
@github-actions
Copy link
Copy Markdown

Thank you for your contribution to TestCafe. When a member of the TestCafe team becomes available, they will review this PR.

@Aleksey28
Copy link
Copy Markdown
Collaborator

Hi @crisryantan,

We appreciate your contribution. I checked your changes and came to the conclusion that it's not necessary to make an additional handling for MessagePort. In the postMessage method, it tries to wrap the entire args[1] with MessageSandbox._wrapMessage and that causes the issue. However, I see that you already fixed it. You extracted targetOrigin from this object and only wrapped this targetOrigin. So, please remove the code that handles the MessagePort object could not be cloned exception. Also, you can remove comments without handling that exception. Everything is clear, so no comments are required.

Align with maintainer feedback by keeping the postMessage options overload support while removing the extra MessagePort clone-error fallback path and related fallback handling.

Made-with: Cursor
Keep upstream diagnostic behavior and inline note context while preserving the maintainer-requested removal of clone-error fallback handling.

Made-with: Cursor
@crisryantan crisryantan deployed to authentication April 28, 2026 20:47 — with GitHub Actions Active
@crisryantan
Copy link
Copy Markdown
Author

Hi @crisryantan,

We appreciate your contribution. I checked your changes and came to the conclusion that it's not necessary to make an additional handling for MessagePort. In the postMessage method, it tries to wrap the entire args[1] with MessageSandbox._wrapMessage and that causes the issue. However, I see that you already fixed it. You extracted targetOrigin from this object and only wrapped this targetOrigin. So, please remove the code that handles the MessagePort object could not be cloned exception. Also, you can remove comments without handling that exception. Everything is clear, so no comments are required.

Thanks! Can you please take a look again 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

postMessage with MessagePort transfer fails in Firefox with DataCloneError

4 participants