diff --git a/pkgs/test/lib/dart.js b/pkgs/test/lib/dart.js index a3cc30286..4a090ef3e 100644 --- a/pkgs/test/lib/dart.js +++ b/pkgs/test/lib/dart.js @@ -12,6 +12,7 @@ window.onload = function() { // This mimics a MultiChannel-formatted message. var sendLoadException = function(message) { window.parent.postMessage({ + // TODO: https://github.com/dart-lang/test/issues/2065 - remove href "href": window.location.href, "data": [0, {"type": "loadException", "message": message}], "exception": true, diff --git a/pkgs/test/lib/src/runner/browser/dom.dart b/pkgs/test/lib/src/runner/browser/dom.dart index 48906f693..477158baa 100644 --- a/pkgs/test/lib/src/runner/browser/dom.dart +++ b/pkgs/test/lib/src/runner/browser/dom.dart @@ -11,6 +11,7 @@ import 'package:js/js.dart'; class Window extends EventTarget {} extension WindowExtension on Window { + external Window get parent; external Location get location; CSSStyleDeclaration? getComputedStyle(Element elt, [String? pseudoElt]) => js_util.callMethod(this, 'getComputedStyle', [ @@ -135,8 +136,18 @@ extension MessageEventExtension on MessageEvent { external String get origin; List get ports => js_util.getProperty(this, 'ports').cast(); + + /// The source may be a `WindowProxy`, a `MessagePort`, or a `ServiceWorker`. + /// + /// When a message is sent from an iframe through `window.parent.postMessage` + /// the source will be a `WindowProxy` which has the same methods as [Window]. + external MessageEventSource source; } +@JS() +@staticInterop +class MessageEventSource {} + @JS() @staticInterop class Location {} diff --git a/pkgs/test/lib/src/runner/browser/post_message_channel.dart b/pkgs/test/lib/src/runner/browser/post_message_channel.dart index e24afeb1a..55a602076 100644 --- a/pkgs/test/lib/src/runner/browser/post_message_channel.dart +++ b/pkgs/test/lib/src/runner/browser/post_message_channel.dart @@ -4,15 +4,10 @@ import 'dart:js_util'; -import 'package:js/js.dart'; import 'package:stream_channel/stream_channel.dart'; import 'dom.dart' as dom; -// Avoid using this from dart:html to work around dart-lang/sdk#32113. -@JS('window.parent.postMessage') -external void _postParentMessage(Object message, String targetOrigin); - /// Constructs a [StreamChannel] wrapping [MessageChannel] communication with /// the host page. StreamChannel postMessageChannel() { @@ -50,8 +45,8 @@ StreamChannel postMessageChannel() { // Send a ready message once we're listening so the host knows it's safe to // start sending events. - // TODO(nweiz): Stop manually adding href here once issue 22554 is fixed. - _postParentMessage( + // TODO: https://github.com/dart-lang/test/issues/2065 - remove href + dom.window.parent.postMessage( jsify({'href': dom.window.location.href, 'ready': true}) as Object, dom.window.location.origin); diff --git a/pkgs/test/tool/host.dart b/pkgs/test/tool/host.dart index 3f833b6ec..ee24a1929 100644 --- a/pkgs/test/tool/host.dart +++ b/pkgs/test/tool/host.dart @@ -209,10 +209,11 @@ StreamChannel _connectToIframe(String url, int id) { // running, but it's good practice to check the origin anyway. var message = event as dom.MessageEvent; if (message.origin != dom.window.location.origin) return; - - // TODO(nweiz): Stop manually checking href here once issue 22554 is - // fixed. - if (message.data['href'] != iframe.src) return; + // Disambiguate between frames for different test suites. + // Depending on the source type, the `location.href` may be missing. + var location = js_util.getProperty(message.source, 'location') as Object?; + if (location == null) return; + if (js_util.getProperty(location, 'href') != iframe.src) return; message.stopPropagation();