Skip to content

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

Open
crisryantan wants to merge 1 commit 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 1 commit intoDevExpress:masterfrom
crisryantan:fix/postmessage-transferable-firefox

Conversation

@crisryantan
Copy link
Copy Markdown

Closes #3077

Problem

When testing an application that uses iframe communication with MessagePort transfers, Firefox throws DataCloneError: MessagePort object could not be cloned under Hammerhead's proxy. This breaks any application that relies on MessageChannel-based communication between a parent page and iframes.

The root cause is in MessageSandbox.postMessage: the method wraps the original message in a Hammerhead envelope before calling fastApply. Firefox's structured clone algorithm cannot reconcile the wrapped envelope object with the MessagePort transferables in the transfer list — the ports reference the original message, not the new envelope.

Additionally, the modern postMessage(message, { targetOrigin, transfer }) overload is not supported. When the second argument is an object, the call is silently dropped because typeof targetUrl !== 'string' evaluates to true and the method returns null.

This does not affect Chrome because TestCafe uses native automation (CDP) for Chrome, which bypasses Hammerhead entirely.

Solution

1. Support the postMessage(message, options) overload

The postMessage method now detects when the second argument is an object (rather than a string targetOrigin) and delegates to a new _postMessageWithOptionsOverload handler that extracts targetOrigin and transfer from the options object.

2. Graceful fallback for structured clone failures

Both _postMessageWrapped and _postMessageWithOptionsOverload now wrap the fastApply call in a try/catch. When the wrapped message fails to be structured-cloned (as happens in Firefox with MessagePort transfers), the fallback sends the original unwrapped message with targetOrigin: '*'. This preserves the transfer semantics while still routing through the proxy.

3. Updated receiving side to handle unwrapped messages

  • _onWindowMessage: Messages that don't carry the Hammerhead envelope (MessageType.User or MessageType.Service) are now passed through to the original listener. Since these arrive via the browser's native postMessage, the browser has already validated the target origin.
  • MessageEvent.data getter: Only unwraps messages that explicitly carry the MessageType.User type. Raw messages from the fallback path are returned as-is.

Tests

  • Added test for postMessage(message, { targetOrigin }) options overload
  • Added test for postMessage(message, { targetOrigin, transfer }) with MessagePort
  • Updated the existing "object as targetOrigin" test to verify that messages are now correctly delivered 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.

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

2 participants