Skip to content

Commit

Permalink
Add tests for cross-origin window and location
Browse files Browse the repository at this point in the history
Tests that we can use JSAny? as the type without
violating cross-origin policy. This will then be
used in package:web to implement a wrapper.

Change-Id: Ic30557138b61e27e421747ead81ea2fb7f6db240
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/381886
Commit-Queue: Srujan Gaddam <[email protected]>
Reviewed-by: Sigmund Cherem <[email protected]>
  • Loading branch information
srujzs authored and Commit Queue committed Sep 12, 2024
1 parent b141611 commit 591b774
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
105 changes: 105 additions & 0 deletions tests/lib/js/static_interop_test/cross_origin_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Test that `JSAny?` can be used in some guaranteed ways to interact with
// cross-origin objects.

import 'dart:js_interop';

import 'package:expect/expect.dart';

@JS('Object.is')
external bool _is(CrossOriginWindow a, CrossOriginWindow b);

@JS()
external Window get window;

@JS('document.body.append')
external void append(HTMLIFrameElement iframe);

@JS('document.createElement')
external JSObject _createElement(String tag);

HTMLIFrameElement createIFrame() => HTMLIFrameElement(_createElement('iframe'));

// Should be aligned with the members used in `cross_origin.dart` from
// `package:web`.
extension type CrossOriginWindow(JSAny? _) {
external bool get closed;
external int get length;
external CrossOriginLocation get location;
external set locationString(String value);
external CrossOriginWindow get opener;
external CrossOriginWindow get parent;
external CrossOriginWindow get top;
external CrossOriginWindow get frames;
external CrossOriginWindow get self;
external CrossOriginWindow get window;
external void blur();
external void close();
external void focus();
external void postMessage(
JSAny? message, [
JSAny optionsOrTargetOrigin,
JSArray<JSObject> transfer,
]);
}

extension type Window(CrossOriginWindow _) implements CrossOriginWindow {
external CrossOriginWindow open(String url);
}

// Should be aligned with the members used in `cross_origin.dart` from
// `package:web`.
extension type CrossOriginLocation(JSAny? _) {
external void replace(String url);
external set href(String value);
}

extension type HTMLIFrameElement(JSObject _) implements JSObject {
external CrossOriginWindow get contentWindow;
external set src(String value);
}

void main() {
const url = 'https://www.google.com';
const url2 = 'https://www.example.org';

void testCommon(CrossOriginWindow crossOriginWindow) {
Expect.equals(crossOriginWindow.length, 0);
Expect.isFalse(crossOriginWindow.closed);
crossOriginWindow.location.replace(url2);
crossOriginWindow.location.href = url;
crossOriginWindow.locationString = url2;
crossOriginWindow.postMessage('hello world'.toJS);
crossOriginWindow.postMessage('hello world'.toJS, url2.toJS);
crossOriginWindow.postMessage('hello world'.toJS, url2.toJS, JSArray());
crossOriginWindow.blur();
crossOriginWindow.focus();
crossOriginWindow.close();
}

final openedWindow = window.open(url);
Expect.isTrue(_is(openedWindow.opener, window));
Expect.isTrue(_is(openedWindow.parent, openedWindow));
Expect.isTrue(_is(openedWindow.top, openedWindow));
Expect.isTrue(_is(openedWindow.frames, openedWindow));
Expect.isTrue(_is(openedWindow.self, openedWindow));
Expect.isTrue(_is(openedWindow.window, openedWindow));
testCommon(openedWindow);
Expect.isTrue(openedWindow.closed);

final iframe = createIFrame();
iframe.src = url;
append(iframe);
final contentWindow = iframe.contentWindow;
Expect.isTrue(_is(contentWindow.opener, CrossOriginWindow(null)));
Expect.isTrue(_is(contentWindow.parent, window));
Expect.isTrue(_is(contentWindow.top, window.top));
Expect.isTrue(_is(contentWindow.frames, contentWindow));
Expect.isTrue(_is(contentWindow.self, contentWindow));
Expect.isTrue(_is(contentWindow.window, contentWindow));
testCommon(contentWindow);
Expect.isFalse(contentWindow.closed);
}
1 change: 1 addition & 0 deletions tests/lib/lib.status
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ js/type_parameter_lowering_test: SkipByDesign # Issue 42085. CSP policy disallow
[ $jscl ]
js/export/static_interop_mock/proto_test: SkipByDesign # Uses dart:html.
js/static_interop_test/constants_test: SkipByDesign # Uses dart:html.
js/static_interop_test/cross_origin_test: SkipByDesign # Uses the DOM.
js/static_interop_test/futurevaluetype_test: SkipByDesign # Uses dart:html.
js/static_interop_test/import/import_test: SkipByDesign # TODO(srujzs): This test uses the file system to load a module. Since the test runner doesn't start an HTTP server for commandline JS shells, I don't think this is supported.
js/static_interop_test/supertype_transform_test: SkipByDesign # Uses dart:html.
Expand Down

0 comments on commit 591b774

Please sign in to comment.