blob: d92c2b88386ec8d07e576b031b35b19a10307e2d [file] [log] [blame]
<!DOCTYPE html>
<title>DedicatedWorker: ServiceWorker interception</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.js"></script>
<script>
// These tests should not be upstreamed to WPT because these check Chrome's
// spec-incompatible behavior (https://crbug.com/731599). These should be
// superseded by tests in WPT after the issue is fixed. See also
// external/wpt/service-workers/service-worker/dedicated-worker-service-worker-interception.https.html
const kServiceWorkerScriptURL =
'resources/service-worker-interception-service-worker.js';
const kWindowURL = 'resources/new-worker-window.html';
function openWindow(url) {
return new Promise(resolve => {
let win = window.open(url, '_blank');
add_result_callback(() => win.close());
window.onmessage = e => {
assert_equals(e.data, 'LOADED');
resolve(win);
};
});
}
// Tests that a dedicated worker should be served by the owner document's
// service worker.
//
// [Current document] registers a service worker for Window's URL.
// --(open)--> [Window] should be controlled by the service worker.
// --(new Worker)--> [Worker] should be served by the service worker.
promise_test(async t => {
const registration = await service_worker_unregister_and_register(
t, kServiceWorkerScriptURL + '?controlled', kWindowURL);
add_result_callback(() => registration.unregister());
await wait_for_state(t, registration.installing, 'activated');
const win = await openWindow(kWindowURL);
assert_not_equals(win.navigator.serviceWorker.controller, null,
'The document should be controlled.');
// |win| is controlled by the service worker, so a new dedicated worker
// created from |win| should also be controlled by the service worker.
const kWorkerScriptURL = 'service-worker-interception-network-worker.js';
win.postMessage(kWorkerScriptURL, '*');
const msg_event = await new Promise(resolve => window.onmessage = resolve);
assert_equals(msg_event.data, 'LOADED_FROM_SERVICE_WORKER');
}, 'Module loading for new Worker() on a controlled document should be ' +
'intercepted by a service worker.');
// Tests that a dedicated worker should not be served by a service worker other
// than the owner document's service worker.
//
// [Current document] registers a service worker for Worker's URL.
// --(open)--> [Window] should not be controlled by the service worker.
// --(new Worker)--> [Worker] should not be served by the service worker.
promise_test(async t => {
const kWorkerScriptURL = 'service-worker-interception-network-worker.js';
const kScope = 'resources/' + kWorkerScriptURL;
const registration = await service_worker_unregister_and_register(
t, kServiceWorkerScriptURL + '?non-controlled', kScope);
add_result_callback(() => registration.unregister());
await wait_for_state(t, registration.installing, 'activated');
const win = await openWindow(kWindowURL);
assert_equals(win.navigator.serviceWorker.controller, null,
'The document should not be controlled.');
// |win| is not controlled by the service worker, so a new dedicated worker
// created from |win| should not be controlled by the service worker even if
// the script URL of the dedicated worker is under the scope of the service
// worker.
win.postMessage(kWorkerScriptURL, '*');
const msg_event = await new Promise(resolve => window.onmessage = resolve);
assert_equals(msg_event.data, 'LOADED_FROM_NETWORK');
}, 'Module loading for new Worker() on a non-controlled document should not ' +
'be intercepted by a service worker even if the script URL is under the ' +
'scope.');
// Tests that static import should be served by the owner document's service
// worker.
//
// [Current document] registers a service worker for Window's URL.
// --(open)--> [Window] should be controlled by the service worker.
// --(new Worker)--> [Worker] should be controlled by the service worker.
// --(static import)--> [Script] should be served by the service worker.
promise_test(async t => {
const registration = await service_worker_unregister_and_register(
t, kServiceWorkerScriptURL + '?static', kWindowURL);
add_result_callback(() => registration.unregister());
await wait_for_state(t, registration.installing, 'activated');
const win = await openWindow(kWindowURL);
assert_not_equals(win.navigator.serviceWorker.controller, null,
'The document should be controlled.');
// |win| is controlled by the service worker, so a new dedicated worker
// created from |win| and static import from the dedicated worker should
// also be controlled by the service worker.
const kWorkerScriptURL =
'service-worker-interception-static-import-worker.js';
win.postMessage(kWorkerScriptURL, '*');
const msg_event = await new Promise(resolve => window.onmessage = resolve);
assert_equals(msg_event.data, 'LOADED_FROM_SERVICE_WORKER');
}, 'Static import on a controlled dedicated worker should be intercepted by ' +
'a service worker.');
// Tests that dynamic import should be served by the owner document's service
// worker.
//
// [Current document] registers a service worker for Window's URL.
// --(open)--> [Window] should be controlled by the service worker.
// --(new Worker)--> [Worker] should be controlled by the service worker.
// --(dynamic import)--> [Script] should be served by the service worker.
promise_test(async t => {
const registration = await service_worker_unregister_and_register(
t, kServiceWorkerScriptURL + '?dynamic', kWindowURL);
add_result_callback(() => registration.unregister());
await wait_for_state(t, registration.installing, 'activated');
const win = await openWindow(kWindowURL);
assert_not_equals(win.navigator.serviceWorker.controller, null,
'The document should be controlled.');
// |win| is controlled by the service worker, so a new dedicated worker
// created from |win| and dynamic import from the dedicated worker should
// also be controlled by the service worker.
const kWorkerScriptURL =
'service-worker-interception-dynamic-import-worker.js';
win.postMessage(kWorkerScriptURL, '*');
const msg_event = await new Promise(resolve => window.onmessage = resolve);
assert_equals(msg_event.data, 'LOADED_FROM_SERVICE_WORKER');
}, 'Dynamic import on a controlled dedicated worker should be intercepted by ' +
'a service worker.');
</script>