aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/wpt/meta/MANIFEST.json4
-rw-r--r--tests/wpt/meta/focus/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back.html.ini3
-rw-r--r--tests/wpt/meta/focus/activeelement-after-focusing-different-site-iframe.html.ini3
-rw-r--r--tests/wpt/meta/focus/activeelement-after-focusing-same-site-iframe-contentwindow.html.ini3
-rw-r--r--tests/wpt/meta/focus/activeelement-after-focusing-same-site-iframe.html.ini3
-rw-r--r--tests/wpt/meta/focus/activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html.ini3
-rw-r--r--tests/wpt/meta/focus/activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html.ini3
-rw-r--r--tests/wpt/meta/focus/focus-restoration-in-different-site-iframes-window.html.ini3
-rw-r--r--tests/wpt/meta/focus/focus-restoration-in-same-site-iframes-window.html.ini3
-rw-r--r--tests/wpt/meta/focus/iframe-focuses-parent-same-site.html.ini2
-rw-r--r--tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects-function-caching.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/the-window-object/focus.window.js.ini3
-rw-r--r--tests/wpt/meta/html/browsers/the-window-object/security-window/window-security.https.html.ini6
-rw-r--r--tests/wpt/meta/html/browsers/the-window-object/window-properties.https.html.ini5
-rw-r--r--tests/wpt/meta/html/dom/idlharness.any.js.ini3
-rw-r--r--tests/wpt/meta/html/dom/idlharness.https.html.ini18
-rw-r--r--tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/event-listeners.window.js.ini6
-rw-r--r--tests/wpt/meta/webidl/ecmascript-binding/global-object-implicit-this-value-cross-realm.html.ini3
-rw-r--r--tests/wpt/meta/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js.ini7
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json9
-rw-r--r--tests/wpt/mozilla/tests/mozilla/FocusEvent.html7
-rw-r--r--tests/wpt/mozilla/tests/mozilla/focus_inter_documents.html207
-rw-r--r--tests/wpt/tests/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js10
-rw-r--r--tests/wpt/tests/webmessaging/message-channels/close-event/resources/helper.js38
24 files changed, 275 insertions, 80 deletions
diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json
index 750266dc59c..72c930afccf 100644
--- a/tests/wpt/meta/MANIFEST.json
+++ b/tests/wpt/meta/MANIFEST.json
@@ -518802,7 +518802,7 @@
"close-event": {
"resources": {
"helper.js": [
- "cb9ea9fe981e95374b836255c752a42de788fc7b",
+ "48744ac1c5b530ef8d46c3d9a0378c698353a5bc",
[]
]
}
@@ -848537,7 +848537,7 @@
]
],
"explicitly-closed.tentative.window.js": [
- "612003d58eaea908ad93294a7bbf777184356a28",
+ "12bfa0bd73e9278e39b825d4fa81437f943cbd02",
[
"webmessaging/message-channels/close-event/explicitly-closed.tentative.window.html",
{
diff --git a/tests/wpt/meta/focus/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back.html.ini b/tests/wpt/meta/focus/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back.html.ini
deleted file mode 100644
index 8f3aec5177f..00000000000
--- a/tests/wpt/meta/focus/activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[activeelement-after-focusing-different-site-iframe-then-immediately-focusing-back.html]
- [Check focus event and active element after focusing different site iframe then immediately focusing back]
- expected: FAIL
diff --git a/tests/wpt/meta/focus/activeelement-after-focusing-different-site-iframe.html.ini b/tests/wpt/meta/focus/activeelement-after-focusing-different-site-iframe.html.ini
deleted file mode 100644
index b489ab52a39..00000000000
--- a/tests/wpt/meta/focus/activeelement-after-focusing-different-site-iframe.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[activeelement-after-focusing-different-site-iframe.html]
- [Check trailing events]
- expected: FAIL
diff --git a/tests/wpt/meta/focus/activeelement-after-focusing-same-site-iframe-contentwindow.html.ini b/tests/wpt/meta/focus/activeelement-after-focusing-same-site-iframe-contentwindow.html.ini
index 5864035c9e1..612b845c7e9 100644
--- a/tests/wpt/meta/focus/activeelement-after-focusing-same-site-iframe-contentwindow.html.ini
+++ b/tests/wpt/meta/focus/activeelement-after-focusing-same-site-iframe-contentwindow.html.ini
@@ -1,2 +1,3 @@
[activeelement-after-focusing-same-site-iframe-contentwindow.html]
- expected: TIMEOUT
+ [Check result]
+ expected: FAIL
diff --git a/tests/wpt/meta/focus/activeelement-after-focusing-same-site-iframe.html.ini b/tests/wpt/meta/focus/activeelement-after-focusing-same-site-iframe.html.ini
deleted file mode 100644
index 406e6a58324..00000000000
--- a/tests/wpt/meta/focus/activeelement-after-focusing-same-site-iframe.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[activeelement-after-focusing-same-site-iframe.html]
- [Check trailing events]
- expected: FAIL
diff --git a/tests/wpt/meta/focus/activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html.ini b/tests/wpt/meta/focus/activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html.ini
index 532cbcbabfe..a58db5d3146 100644
--- a/tests/wpt/meta/focus/activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html.ini
+++ b/tests/wpt/meta/focus/activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html.ini
@@ -1,2 +1,3 @@
[activeelement-after-immediately-focusing-different-site-iframe-contentwindow.html]
- expected: TIMEOUT
+ [Check result]
+ expected: FAIL
diff --git a/tests/wpt/meta/focus/activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html.ini b/tests/wpt/meta/focus/activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html.ini
index 8483775c0c1..d8b0d3212c9 100644
--- a/tests/wpt/meta/focus/activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html.ini
+++ b/tests/wpt/meta/focus/activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html.ini
@@ -1,2 +1,3 @@
[activeelement-after-immediately-focusing-same-site-iframe-contentwindow.html]
- expected: TIMEOUT
+ [Check result]
+ expected: FAIL
diff --git a/tests/wpt/meta/focus/focus-restoration-in-different-site-iframes-window.html.ini b/tests/wpt/meta/focus/focus-restoration-in-different-site-iframes-window.html.ini
index 8bdcea27053..1e3e377f307 100644
--- a/tests/wpt/meta/focus/focus-restoration-in-different-site-iframes-window.html.ini
+++ b/tests/wpt/meta/focus/focus-restoration-in-different-site-iframes-window.html.ini
@@ -1,2 +1,3 @@
[focus-restoration-in-different-site-iframes-window.html]
- expected: TIMEOUT
+ [Check result]
+ expected: FAIL
diff --git a/tests/wpt/meta/focus/focus-restoration-in-same-site-iframes-window.html.ini b/tests/wpt/meta/focus/focus-restoration-in-same-site-iframes-window.html.ini
index 53f4db35f7e..f19949138fa 100644
--- a/tests/wpt/meta/focus/focus-restoration-in-same-site-iframes-window.html.ini
+++ b/tests/wpt/meta/focus/focus-restoration-in-same-site-iframes-window.html.ini
@@ -1,2 +1,3 @@
[focus-restoration-in-same-site-iframes-window.html]
- expected: TIMEOUT
+ [Check result]
+ expected: FAIL
diff --git a/tests/wpt/meta/focus/iframe-focuses-parent-same-site.html.ini b/tests/wpt/meta/focus/iframe-focuses-parent-same-site.html.ini
deleted file mode 100644
index 8877baa8ac6..00000000000
--- a/tests/wpt/meta/focus/iframe-focuses-parent-same-site.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[iframe-focuses-parent-same-site.html]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects-function-caching.html.ini b/tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects-function-caching.html.ini
index 6720c0f77da..3e682215a0e 100644
--- a/tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects-function-caching.html.ini
+++ b/tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects-function-caching.html.ini
@@ -1,7 +1,4 @@
[cross-origin-objects-function-caching.html]
- [Cross-origin Window methods are cached]
- expected: FAIL
-
[Cross-origin Location `replace` method is cached]
expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/the-window-object/focus.window.js.ini b/tests/wpt/meta/html/browsers/the-window-object/focus.window.js.ini
deleted file mode 100644
index 27a9640a02c..00000000000
--- a/tests/wpt/meta/html/browsers/the-window-object/focus.window.js.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[focus.window.html]
- [focus]
- expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/the-window-object/security-window/window-security.https.html.ini b/tests/wpt/meta/html/browsers/the-window-object/security-window/window-security.https.html.ini
index 8afe0888e4e..32cd3f302d4 100644
--- a/tests/wpt/meta/html/browsers/the-window-object/security-window/window-security.https.html.ini
+++ b/tests/wpt/meta/html/browsers/the-window-object/security-window/window-security.https.html.ini
@@ -328,9 +328,3 @@
[A SecurityError exception must be thrown when window.stop is accessed from a different origin.]
expected: FAIL
-
- [A SecurityError exception should not be thrown when window.blur is accessed from a different origin.]
- expected: FAIL
-
- [A SecurityError exception should not be thrown when window.focus is accessed from a different origin.]
- expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/the-window-object/window-properties.https.html.ini b/tests/wpt/meta/html/browsers/the-window-object/window-properties.https.html.ini
index e9061d31d26..94ad9ce191c 100644
--- a/tests/wpt/meta/html/browsers/the-window-object/window-properties.https.html.ini
+++ b/tests/wpt/meta/html/browsers/the-window-object/window-properties.https.html.ini
@@ -1,9 +1,4 @@
[window-properties.https.html]
- [Window method: focus]
- expected: FAIL
-
- [Window method: blur]
- expected: FAIL
[Window method: print]
expected: FAIL
diff --git a/tests/wpt/meta/html/dom/idlharness.any.js.ini b/tests/wpt/meta/html/dom/idlharness.any.js.ini
index f17466adc7f..ad5e57e0759 100644
--- a/tests/wpt/meta/html/dom/idlharness.any.js.ini
+++ b/tests/wpt/meta/html/dom/idlharness.any.js.ini
@@ -95,9 +95,6 @@
[History interface: existence and properties of interface object]
expected: FAIL
- [MessagePort interface: attribute onclose]
- expected: FAIL
-
[WorkerGlobalScope interface: attribute onlanguagechange]
expected: FAIL
diff --git a/tests/wpt/meta/html/dom/idlharness.https.html.ini b/tests/wpt/meta/html/dom/idlharness.https.html.ini
index 23b8e353fb0..ac7504347d7 100644
--- a/tests/wpt/meta/html/dom/idlharness.https.html.ini
+++ b/tests/wpt/meta/html/dom/idlharness.https.html.ini
@@ -1517,9 +1517,6 @@
[SVGSVGElement interface: attribute onpagereveal]
expected: FAIL
- [MessagePort interface: attribute onclose]
- expected: FAIL
-
[NotRestoredReasonDetails interface: existence and properties of interface object]
expected: FAIL
@@ -1738,9 +1735,6 @@
[Document interface: attribute all]
expected: FAIL
- [Window interface: operation focus()]
- expected: FAIL
-
[Window interface: attribute scrollbars]
expected: FAIL
@@ -1870,9 +1864,6 @@
[Document interface: new Document() must inherit property "dir" with the proper type]
expected: FAIL
- [Window interface: window must inherit property "blur()" with the proper type]
- expected: FAIL
-
[Document interface: operation execCommand(DOMString, optional boolean, optional DOMString)]
expected: FAIL
@@ -1897,9 +1888,6 @@
[Document interface: iframe.contentDocument must inherit property "queryCommandEnabled(DOMString)" with the proper type]
expected: FAIL
- [Window interface: operation blur()]
- expected: FAIL
-
[Document interface: iframe.contentDocument must inherit property "onslotchange" with the proper type]
expected: FAIL
@@ -1924,9 +1912,6 @@
[Document interface: documentWithHandlers must inherit property "onauxclick" with the proper type]
expected: FAIL
- [Window interface: window must inherit property "focus()" with the proper type]
- expected: FAIL
-
[Document interface: documentWithHandlers must inherit property "onwebkitanimationend" with the proper type]
expected: FAIL
@@ -5375,9 +5360,6 @@
[Navigator interface: window.navigator must inherit property "pdfViewerEnabled" with the proper type]
expected: FAIL
- [MessagePort interface: attribute onclose]
- expected: FAIL
-
[SharedWorker interface: existence and properties of interface object]
expected: FAIL
diff --git a/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/event-listeners.window.js.ini b/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/event-listeners.window.js.ini
index c00e2949bf5..b229be268ec 100644
--- a/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/event-listeners.window.js.ini
+++ b/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/event-listeners.window.js.ini
@@ -1,12 +1,6 @@
[event-listeners.window.html]
- [Standard event listeners are to be removed from Window]
- expected: FAIL
-
[Standard event listeners are to be removed from Window for an active but not fully active document]
expected: FAIL
- [Standard event listeners are to be removed from Window for a non-active document that is the associated Document of a Window (frame is removed)]
- expected: FAIL
-
[Custom event listeners are to be removed from Window for an active but not fully active document]
expected: FAIL
diff --git a/tests/wpt/meta/webidl/ecmascript-binding/global-object-implicit-this-value-cross-realm.html.ini b/tests/wpt/meta/webidl/ecmascript-binding/global-object-implicit-this-value-cross-realm.html.ini
index 492ba730948..b63c174f353 100644
--- a/tests/wpt/meta/webidl/ecmascript-binding/global-object-implicit-this-value-cross-realm.html.ini
+++ b/tests/wpt/meta/webidl/ecmascript-binding/global-object-implicit-this-value-cross-realm.html.ini
@@ -1,6 +1,3 @@
[global-object-implicit-this-value-cross-realm.html]
- [Cross-realm global object's operation throws when called on incompatible object]
- expected: FAIL
-
[Cross-realm global object's operation called on null / undefined]
expected: FAIL
diff --git a/tests/wpt/meta/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js.ini b/tests/wpt/meta/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js.ini
deleted file mode 100644
index c625c16f713..00000000000
--- a/tests/wpt/meta/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[explicitly-closed.tentative.window.html]
- expected: TIMEOUT
- [Close event on port2 is fired when port1 is explicitly closed]
- expected: TIMEOUT
-
- [Close event on port2 is fired when port1, which is in a different window, is explicitly closed.]
- expected: TIMEOUT
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 4262fa5aca3..a3f77769a9d 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -12744,7 +12744,7 @@
]
},
"FocusEvent.html": [
- "9e002c1088de060b5e7f94c4152bf9fb779c04cc",
+ "7fb7aebf2afbac7f68a16308b9cc5d4588b7022f",
[
null,
{}
@@ -13278,6 +13278,13 @@
{}
]
],
+ "focus_inter_documents.html": [
+ "5c759772367e844066d1df0081917c9e129d09ec",
+ [
+ null,
+ {}
+ ]
+ ],
"follow-hyperlink.html": [
"6ac9eaeb5814a663988ed8c664c113072e329dc5",
[
diff --git a/tests/wpt/mozilla/tests/mozilla/FocusEvent.html b/tests/wpt/mozilla/tests/mozilla/FocusEvent.html
index 9e002c1088d..7fb7aebf2af 100644
--- a/tests/wpt/mozilla/tests/mozilla/FocusEvent.html
+++ b/tests/wpt/mozilla/tests/mozilla/FocusEvent.html
@@ -48,13 +48,6 @@
]
},
- {
- element: document.body,
- expected_events: [
- {element: input3, event_name: "blur"},
- ]
- }
-
];
var idx = 0;
diff --git a/tests/wpt/mozilla/tests/mozilla/focus_inter_documents.html b/tests/wpt/mozilla/tests/mozilla/focus_inter_documents.html
new file mode 100644
index 00000000000..5c759772367
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/focus_inter_documents.html
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <iframe id="f1"></iframe>
+ <iframe id="f2"></iframe>
+ <input id="d0">
+ <script>
+
+ /** Wait for an `event` event to be fired on `element`. Resolves to a boolean
+ * value indicating whether the event was fired within a predetermined period. */
+ async function waitForEvent(element, event) {
+ let listener;
+ try {
+ return await new Promise(resolve => {
+ setTimeout(() => resolve(false), 1000);
+ listener = () => resolve(true);
+ element.addEventListener(event, listener);
+ });
+ } finally {
+ if (listener) {
+ element.removeEventListener(event, listener);
+ }
+ }
+ }
+
+ promise_test(async t => {
+ await new Promise(r => window.onload = r);
+
+ const d0 = document.getElementById("d0");
+
+ // This test requires the document to have focus as a starting condition.
+ if (!document.hasFocus() || document.activeElement !== d0) {
+ const p = new Promise(r => d0.onfocus = r);
+ d0.focus();
+ await p;
+ }
+
+ assert_true(document.hasFocus(), "Document has focus as starting condition.");
+ assert_equals(document.activeElement, d0, "`d0` has focus as starting condition.");
+ }, "Starting condition");
+
+ promise_test(async t => {
+ const d0 = document.getElementById("d0");
+ const f1 = document.getElementById("f1");
+ f1.contentDocument.body.innerHTML = '<input id=d1>';
+ const d1 = f1.contentDocument.getElementById("d1");
+
+ const p0 = waitForEvent(d1, 'focus');
+ const p1 = waitForEvent(f1, 'focus');
+ const p2 = waitForEvent(f1.contentWindow, 'focus');
+ const p3 = waitForEvent(d0, 'blur');
+
+ d1.focus();
+
+ assert_true(await p0, "`d1.focus` fires in time");
+ await p1; // FIXME: doesn't fire on Firefox, Blink, Edge, and WebKit
+ assert_true(await p2, "`f1.contentWindow.focus` fires in time");
+ assert_true(await p3, "`d0.blur` fires in time");
+
+ assert_equals(document.activeElement, f1, "The top-level document's activeElement is `f1`");
+ assert_true(f1.contentDocument.hasFocus(), "f1's contentDocument has focus");
+ assert_equals(f1.contentDocument.activeElement, d1, "f1's contentDocument's activeElement is `d1`");
+ }, "Focusing an element in a nested browsing context also focuses the container");
+
+ promise_test(async t => {
+ const f1 = document.getElementById("f1");
+ const d1 = f1.contentDocument.getElementById("d1");
+
+ const f2 = document.getElementById("f2");
+ f2.contentDocument.body.innerHTML = '<input id=d2>';
+ const d2 = f2.contentDocument.getElementById("d2");
+
+ const p0 = waitForEvent(d1, 'blur');
+ const p1 = waitForEvent(f1, 'blur');
+ const p2 = waitForEvent(f1.contentWindow, 'blur');
+
+ d2.focus();
+
+ assert_true(await p0, "`d1.blur` fires in time");
+ await p1; // FIXME: doesn't fire on Firefox, Blink, Edge, and WebKit
+ assert_true(await p2, "`f1.contentWindow.blur` fires in time");
+
+ // Wait for any ongoing execution of the focus update steps to complete
+ await new Promise(r => window.setTimeout(r, 0));
+
+ assert_equals(document.activeElement, f2, "The top-level document's activeElement is `f2`");
+ assert_true(f2.contentDocument.hasFocus(), "f2's contentDocument has focus");
+ assert_equals(f2.contentDocument.activeElement, d2, "f2's contentDocument's activeElement is `d2`");
+ assert_false(f1.contentDocument.hasFocus(), "f1's contentDocument does not have focus");
+ assert_equals(f1.contentDocument.activeElement, f1.contentDocument.body, "f1's contentDocument's activeElement is its body");
+ }, "Focusing an element in a different container also unfocuses the previously focused element and its container");
+
+ promise_test(async t => {
+ const d0 = document.getElementById("d0");
+
+ const f2 = document.getElementById("f2");
+ const d2 = f2.contentDocument.getElementById("d2");
+
+ const p0 = waitForEvent(d2, 'blur');
+ const p1 = waitForEvent(f2, 'blur');
+ const p2 = waitForEvent(f2.contentWindow, 'blur');
+ const p3 = waitForEvent(d0, 'focus');
+
+ d0.focus();
+
+ assert_true(await p0, "`d2.blur` fires in time");
+ await p1; // FIXME: doesn't fire on Firefox, Blink, Edge, and WebKit
+ assert_true(await p2, "`f2.contentWindow.blur` fires in time");
+ assert_true(await p3, "`d0.focus` fires in time");
+
+ // Wait for any ongoing execution of the focus update steps to complete
+ await new Promise(r => window.setTimeout(r, 0));
+
+ assert_equals(document.activeElement, d0, "The top-level document's activeElement is `d0`");
+ assert_false(f2.contentDocument.hasFocus(), "f2's contentDocument does not have focus");
+ assert_equals(f2.contentDocument.activeElement, f2.contentDocument.body, "f2's contentDocument's activeElement is its body");
+ }, "Unfocusing a container also unfocuses any focused elements within");
+
+ promise_test(async t => {
+ const f1 = document.getElementById("f1");
+
+ const p0 = waitForEvent(f1, 'focus');
+ const p1 = waitForEvent(f1.contentWindow, 'focus');
+
+ f1.focus();
+
+ await p0; // FIXME: doesn't fire on Firefox, Blink, Edge, and WebKit
+ assert_true(await p1, "`f1.contentWindow.focus` fires in time");
+
+ assert_equals(document.activeElement, f1, "The top-level document's activeElement is `f1`");
+ assert_true(f1.contentDocument.hasFocus(), "f1's contentDocument has focus");
+ }, "Focusing a container changes the contained document's 'has focus steps' result");
+
+ promise_test(async t => {
+ const f1 = document.getElementById("f1");
+
+ // `f1` should be focused because of the previous step
+ assert_equals(document.activeElement, f1, "The top-level document's activeElement is `f1`");
+
+ // Navigate the focused container
+ const pLoad = new Promise(resolve => window.subframeIsReady = resolve);
+ f1.srcdoc = "<script>window.parent.subframeIsReady();</" + "script>";
+ await pLoad;
+
+ // Allow some delay before the document finally receives focus
+ if (!f1.contentDocument.hasFocus()) {
+ await waitForEvent(f1.contentWindow, 'focus');
+ }
+
+ assert_true(f1.contentDocument.hasFocus(), "f1's contentDocument has focus");
+ }, "When a focused container navigates, the new document should receive focus");
+
+ promise_test(async t => {
+ const f2 = document.getElementById("f2");
+
+ const p0 = waitForEvent(f2, 'focus');
+ const p1 = waitForEvent(f2.contentWindow, 'focus');
+
+ f2.contentWindow.focus();
+
+ await p0; // FIXME: doesn't fire on Firefox, Blink, Edge, and WebKit
+ assert_true(await p1, "`f2.contentWindow.focus` fires in time");
+
+ assert_equals(document.activeElement, f2, "The top-level document's activeElement is `f2`");
+ assert_true(f2.contentDocument.hasFocus(), "f2's contentDocument has focus");
+ }, "Focusing the window of a nested browsing context also focuses the container");
+
+ promise_test(async t => {
+ const f2 = document.getElementById("f2");
+ const d2 = f2.contentDocument.getElementById("d2");
+
+ {
+ const p = waitForEvent(d2, 'focus');
+ f2.focus();
+ d2.focus();
+ await p;
+ }
+
+ const p0 = waitForEvent(d2, 'blur');
+ d2.blur();
+ assert_true(await p0, "`d2.blur` fires in time");
+
+ // FIXME: This passes on Firefox, Blink, and WebKit but is not spec-
+ // compliant. Per spec, the top-level document's viewport should be
+ // focused instead.
+ //
+ // <https://html.spec.whatwg.org/multipage/#get-the-focusable-area>
+ //
+ // > The unfocusing steps for an object `old focus target`` that is either a
+ // > focusable area or an element that is not a focusable area are as
+ // > follows: [...]
+ // >
+ // > 7. If `topDocument`'s browsing context has system focus, then run the
+ // > focusing steps for topDocument's viewport.
+
+ assert_equals(document.activeElement, f2, "The top-level document's activeElement is `f2`");
+ assert_equals(f2.contentDocument.activeElement, f2.contentDocument.body, "f2's contentDocument's activeElement is its body");
+ assert_true(f2.contentDocument.hasFocus(), "f2's contentDocument has focus");
+ }, "Blurring an element in a nested browsing context focuses its node document");
+ </script>
+</body>
+</html>
diff --git a/tests/wpt/tests/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js b/tests/wpt/tests/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js
index 612003d58ea..12bfa0bd73e 100644
--- a/tests/wpt/tests/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js
+++ b/tests/wpt/tests/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js
@@ -33,3 +33,13 @@ promise_test(async t => {
});
await closeEventPromise;
}, 'Close event on port2 is fired when port1, which is in a different window, is explicitly closed.')
+
+promise_test(async t => {
+ const rc = await addWindow();
+ const waitForPort = expectMessagePortFromWindowWithoutStartingIt(window);
+ await createMessageChannelAndSendPortFollowedByClose(rc);
+ const port = await waitForPort;
+ const closeEventPromise = createCloseEventPromise(port);
+ port.start();
+ await closeEventPromise;
+}, 'Close event on port2 is fired when port1, in a different window, is closed during the transfer of port2.')
diff --git a/tests/wpt/tests/webmessaging/message-channels/close-event/resources/helper.js b/tests/wpt/tests/webmessaging/message-channels/close-event/resources/helper.js
index cb9ea9fe981..48744ac1c5b 100644
--- a/tests/wpt/tests/webmessaging/message-channels/close-event/resources/helper.js
+++ b/tests/wpt/tests/webmessaging/message-channels/close-event/resources/helper.js
@@ -22,6 +22,44 @@ function expectMessagePortFromWindow(window) {
}
/**
+ * Create a new promise that resolves when the window receives
+ * the MessagePort and does not start it.
+ *
+ * @param {Window} window - The window to wait for the MessagePort.
+ * @returns {Promise<MessagePort>} A promise you should await to ensure the
+ * window
+ * receives the MessagePort.
+ */
+function expectMessagePortFromWindowWithoutStartingIt(window) {
+ return new Promise(resolve => {
+ window.onmessage = e => {
+ try {
+ assert_true(e.ports[0] instanceof window.MessagePort);
+ resolve(e.ports[0]);
+ } catch (e) {
+ reject(e);
+ }
+ };
+ });
+}
+
+/**
+ * Create a new MessageChannel and transfers one of the ports to
+ * the window which opened the window with a remote context provided
+ * as an argument, and immediately closes the entangled port.
+ *
+ * @param {RemoteContextWrapper} remoteContextWrapper
+ */
+async function createMessageChannelAndSendPortFollowedByClose(remoteContextWrapper) {
+ await remoteContextWrapper.executeScript(() => {
+ const {port1, port2} = new MessageChannel();
+ port1.start();
+ window.opener.postMessage({}, '*', [port2]);
+ port1.close();
+ });
+}
+
+/**
* Create a new MessageChannel and transfers one of the ports to
* the window which opened the window with a remote context provided
* as an argument.