-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug 1868068 [wpt PR 43491] - Reland "Dispatch close event when Messag…
…ePort is disentangled", a=testonly Automatic update from web-platform-tests Reland "Dispatch close event when MessagePort is disentangled" This is a reland of commit 6a74d3d8049e1744b862757a73f90f3d7a5e08b0 The tests newly added by the original CL were failing on chrome_wpt_tests on the Linux Tests bot: https://ci.chromium.org/ui/p/chromium/builders/ci/Linux%20Tests/138259/overview This is because the builder added in https://crrev.com/c/5005230 might be broken. Specifically, chrome-wpt builder cannot run GC(Bug: 1509657) and BFCache doesn't work on chrome-wpt builder(Bug: 1509303). I changed two tests expectations described below. ・third_party/blink/web_tests/external/wpt/webmessaging/message-channels/close-event/garbage-collected.tentative.any.js ・third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/message-port-entangled-after-restore.https.tentative.window.js Original change's description: > Dispatch close event when MessagePort is disentangled > > We want to dispatch a close event when an entangled MessagePort is disconnected. > Given a pair of entangled ports, port1 and port2, if port2 is closed at any point, > a port1’s error handler is run. > So we can change an error handler to dispatch a close event. > > The tests of close event are as follows: > 1) port was explicitly closed. > 2) owning document was destroyed. > 3) owning document crashed. > 4) port was garbage collected. > > Design Doc:https://docs.google.com/document/d/1lXZU2Pk2ycitqj8aL9kxT2aauwXqpA0vJDUalkXA29Y > Explainer:https://github.com/fergald/explainer-messageport-close > HTML spec PR:whatwg/html#9933 > > Bug: 1495616 > Change-Id: I99f9f5a0d7cc63f0916da316ec666ba793215019 > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5003089 > Reviewed-by: Jeremy Roman <[email protected]> > Commit-Queue: Nonoka Muraki <[email protected]> > Reviewed-by: Ming-Ying Chung <[email protected]> > Cr-Commit-Position: refs/heads/main@{#1231743} Change-Id: I0a8f31245d7b5abe9ddfc262dff8063316e953df Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5083156 Reviewed-by: Jeremy Roman <[email protected]> Commit-Queue: Nonoka Muraki <[email protected]> Reviewed-by: Ming-Ying Chung <[email protected]> Cr-Commit-Position: refs/heads/main@{#1234854} -- wpt-commits: 05aab53917a8309fe7f1ab5c50d094ac488ce942 wpt-pr: 43491
- Loading branch information
1 parent
bc64b16
commit 87400a9
Showing
7 changed files
with
241 additions
and
8 deletions.
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
...the-web/back-forward-cache/message-port-entangled-after-restore.https.tentative.window.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// META: timeout=long | ||
// META: title=Confirm close event is not fired when the page enters BFCache and MessagePort still works after the page is restored. | ||
// META: script=/common/dispatcher/dispatcher.js | ||
// META: script=/common/get-host-info.sub.js | ||
// META: script=/common/utils.js | ||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js | ||
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js | ||
// META: script=resources/rc-helper.js | ||
|
||
promise_test(async t => { | ||
// Register a service worker. | ||
const scope = | ||
'/html/browsers/browsing-the-web/remote-context-helper/resources' | ||
const workerUrl = | ||
`resources/service-worker.js?pipe=header(Service-Worker-Allowed,${ | ||
scope})`; | ||
const registration = | ||
await service_worker_unregister_and_register(t, workerUrl, scope); | ||
t.add_cleanup(_ => registration.unregister()); | ||
await wait_for_state(t, registration.installing, 'activated'); | ||
|
||
// Open a window with noopener so that BFCache will work. | ||
const rcHelper = new RemoteContextHelper(); | ||
const rc1 = await rcHelper.addWindow( | ||
/*extraConfig=*/ null, /*options=*/ {features: 'noopener'}); | ||
|
||
// Confirm the page is controlled. | ||
assert_true( | ||
await rc1.executeScript( | ||
() => (navigator.serviceWorker.controller !== null)), | ||
'The page should be controlled before navigation'); | ||
|
||
// Send MessagePort to the service worker. | ||
await rc1.executeScript(() => { | ||
const {port1, port2} = new MessageChannel(); | ||
port1.start(); | ||
const ctrl = navigator.serviceWorker.controller; | ||
ctrl.postMessage({type: 'storeMessagePort'}, [port2]); | ||
self.waitForMessage = (sentMessage) => { | ||
return new Promise(resolve => { | ||
port1.addEventListener('message', (event) => { | ||
resolve(event.data); | ||
}); | ||
port1.postMessage(sentMessage); | ||
}); | ||
}; | ||
}); | ||
|
||
// Verify that the page was BFCached. | ||
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); | ||
|
||
// Confirm MessagePort can still work after the page is restored from | ||
// BFCache. | ||
assert_equals( | ||
await rc1.executeScript( | ||
async () => | ||
await self.waitForMessage('Confirm the ports can communicate')), | ||
'Receive message'); | ||
|
||
// Confirm the close event was not fired. | ||
assert_false(await rc1.executeScript( | ||
async () => | ||
await self.waitForMessage('Ask if the close event was fired'))); | ||
}, 'MessagePort still works after the page is restored from BFCache'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 0 additions & 8 deletions
8
...web-platform/tests/webmessaging/message-channels/close-event/close-event.tentative.any.js
This file was deleted.
Oops, something went wrong.
43 changes: 43 additions & 0 deletions
43
...rm/tests/webmessaging/message-channels/close-event/document-destroyed.tentative.window.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// META: title=Close event test when the document is destroyed. | ||
// META: script=/common/dispatcher/dispatcher.js | ||
// META: script=/common/get-host-info.sub.js | ||
// META: script=/common/utils.js | ||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js | ||
// META: script=resources/helper.js | ||
|
||
promise_test(async t => { | ||
const rc = await addWindow(); | ||
const waitForPort = expectMessagePortFromWindow(window); | ||
await createMessageChannelAndSendPort(rc); | ||
const closeEventPromise = createCloseEventPromise(await waitForPort); | ||
rc.navigateToNew(); | ||
await closeEventPromise; | ||
}, 'The context is navigated to a new document and a close event is fired.') | ||
|
||
promise_test(async t => { | ||
const rc = await addWindow(); | ||
const waitForPort = expectMessagePortFromWindow(window); | ||
await createMessageChannelAndSendPort(rc); | ||
const closeEventPromise = createCloseEventPromise(await waitForPort); | ||
rc.executeScript(() => window.close()); | ||
await closeEventPromise; | ||
}, 'The window is closed and a close event is fired.') | ||
|
||
promise_test(async t => { | ||
let iframe; | ||
const waitForLoad = new Promise(resolve => { | ||
iframe = document.createElement('iframe'); | ||
iframe.onload = resolve; | ||
document.documentElement.appendChild(iframe); | ||
}); | ||
await waitForLoad; | ||
|
||
const waitForPort = expectMessagePortFromWindow(iframe.contentWindow); | ||
const {port1, port2} = new MessageChannel(); | ||
port1.start(); | ||
iframe.contentWindow.postMessage('', '*', [port2]); | ||
await waitForPort; | ||
const closeEventPromise = createCloseEventPromise(port1); | ||
iframe.remove(); | ||
await closeEventPromise; | ||
}, 'The iframe is deleted and a close event is fired.') |
35 changes: 35 additions & 0 deletions
35
...orm/tests/webmessaging/message-channels/close-event/explicitly-closed.tentative.window.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// META: title=Close event test when an entangled port is explicitly closed. | ||
// META: script=/common/dispatcher/dispatcher.js | ||
// META: script=/common/get-host-info.sub.js | ||
// META: script=/common/utils.js | ||
// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js | ||
// META: script=resources/helper.js | ||
|
||
async_test(t => { | ||
const channel = new MessageChannel(); | ||
channel.port1.start(); | ||
channel.port2.start(); | ||
channel.port2.onclose = t.step_func_done(); | ||
channel.port1.close(); | ||
}, 'Close event on port2 is fired when port1 is explicitly closed'); | ||
|
||
async_test(t => { | ||
const channel = new MessageChannel(); | ||
channel.port1.start(); | ||
channel.port2.start(); | ||
channel.port1.onclose = | ||
t.unreached_func('Should not fire a close event on port1'); | ||
channel.port1.close(); | ||
t.step_timeout(t.step_func_done(), 1000); | ||
}, 'Close event on port1 is not fired when port1 is explicitly closed'); | ||
|
||
promise_test(async t => { | ||
const rc = await addWindow(); | ||
const waitForPort = expectMessagePortFromWindow(window); | ||
await createMessageChannelAndSendPort(rc); | ||
const closeEventPromise = createCloseEventPromise(await waitForPort); | ||
rc.executeScript(() => { | ||
window.closePort(); | ||
}); | ||
await closeEventPromise; | ||
}, 'Close event on port2 is fired when port1, which is in a different window, is explicitly closed.') |
23 changes: 23 additions & 0 deletions
23
...atform/tests/webmessaging/message-channels/close-event/garbage-collected.tentative.any.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// META: title=Close event test when an entangled port is GCed. | ||
// META: script=/common/gc.js | ||
|
||
/** | ||
* Create a new MessageChannel and return port1 and a weak reference to port2. | ||
* It is expected that port2 will be garbage collected and a close event | ||
* will be fired on port1. | ||
* | ||
* @returns {Array.<[MessagePort, WeakRef<MessagePort>]>} | ||
*/ | ||
function createMessageChannelAndWeakReferToPort() { | ||
const {port1, port2} = new MessageChannel(); | ||
port1.start(); | ||
return [port1, new WeakRef(port2)]; | ||
} | ||
|
||
promise_test(async t => { | ||
const [port1, weakport2] = createMessageChannelAndWeakReferToPort(); | ||
const closeEventPromise = new Promise(resolve => port1.onclose = resolve); | ||
garbageCollect(); | ||
await closeEventPromise; | ||
assert_equals(weakport2.deref(), undefined, 'port2 should be GCed'); | ||
}, 'Entangled port is garbage collected, and the close event is fired.') |
62 changes: 62 additions & 0 deletions
62
testing/web-platform/tests/webmessaging/message-channels/close-event/resources/helper.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** | ||
* Create a new promise that resolves when the window receives | ||
* the MessagePort and starts 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 expectMessagePortFromWindow(window) { | ||
return new Promise(resolve => { | ||
window.onmessage = e => { | ||
try { | ||
assert_true(e.ports[0] instanceof window.MessagePort); | ||
e.ports[0].start(); | ||
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. | ||
* | ||
* @param {RemoteContextWrapper} remoteContextWrapper | ||
*/ | ||
async function createMessageChannelAndSendPort(remoteContextWrapper) { | ||
await remoteContextWrapper.executeScript(() => { | ||
const {port1, port2} = new MessageChannel(); | ||
port1.start(); | ||
window.opener.postMessage({}, '*', [port2]); | ||
window.closePort = () => { | ||
port1.close(); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Creates a window with a remote context. | ||
* | ||
* @returns {Promise<RemoteContextWrapper>} | ||
*/ | ||
async function addWindow() { | ||
const helper = new RemoteContextHelper(); | ||
return helper.addWindow(); | ||
} | ||
|
||
/** | ||
* Creates a new promise that resolves when the close event is fired. | ||
* | ||
* @param {MessagePort} port - MessagePort on which the close event will | ||
* be fired. | ||
* @returns {Promise} A promise you should await to ensure the close event | ||
* is dispatched. | ||
*/ | ||
function createCloseEventPromise(port) { | ||
return new Promise(resolve => port.onclose = resolve); | ||
} |