service-worker-interception-tests.js (5212B)
1 function openWindow(t, url) { 2 return new Promise(resolve => { 3 const win = window.open(url, '_blank'); 4 t.add_cleanup(() => win.close()); 5 window.onmessage = e => { 6 assert_equals(e.data, 'LOADED'); 7 resolve(win); 8 }; 9 }); 10 } 11 12 // Runs a series of tests related to service worker interception for a worklet. 13 // 14 // Usage: 15 // runServiceWorkerInterceptionTests("paint"); 16 function runServiceWorkerInterceptionTests(worklet_type) { 17 const worklet = get_worklet(worklet_type); 18 19 // Tests that a worklet should be served by the owner document's service 20 // worker. 21 // 22 // [Current document] registers a service worker for Window's URL. 23 // --(open)--> [Window] should be controlled by the service worker. 24 // --(addModule)--> [Worklet] should be served by the service worker. 25 promise_test(async t => { 26 const kWindowURL = 'resources/addmodule-window.html'; 27 const kServiceWorkerScriptURL = 'resources/service-worker.js'; 28 // This doesn't contain the 'resources/' prefix because this will be 29 // imported from a html file under resources/. 30 const kWorkletScriptURL = 'non-existent-worklet-script.js'; 31 32 const registration = await service_worker_unregister_and_register( 33 t, kServiceWorkerScriptURL, kWindowURL); 34 t.add_cleanup(() => registration.unregister()); 35 await wait_for_state(t, registration.installing, 'activated'); 36 37 const win = await openWindow(t, kWindowURL); 38 assert_not_equals(win.navigator.serviceWorker.controller, null, 39 'The document should be controlled.'); 40 41 // The worklet script on kWorkletScriptURL doesn't exist but the service 42 // worker serves it, so the addModule() should succeed. 43 win.postMessage({ type: worklet_type, script_url: kWorkletScriptURL }, '*'); 44 const msgEvent = await new Promise(resolve => window.onmessage = resolve); 45 assert_equals(msgEvent.data, 'RESOLVED'); 46 }, 'addModule() on a controlled document should be intercepted by a ' + 47 'service worker.'); 48 49 // Tests that a worklet should not be served by a service worker other than 50 // the owner document's service worker. 51 // 52 // [Current document] registers a service worker for Worklet's URL. 53 // --(open)--> [Window] should not be controlled by the service worker. 54 // --(addModule)--> [Worklet] should not be served by the service worker. 55 promise_test(async t => { 56 const kWindowURL = 'resources/addmodule-window.html'; 57 const kServiceWorkerScriptURL = 'resources/service-worker.js'; 58 // This doesn't contain the 'resources/' prefix because this will be 59 // imported from a html file under resources/. 60 const kWorkletScriptURL = 'non-existent-worklet-script.js'; 61 62 const registration = await service_worker_unregister_and_register( 63 t, kServiceWorkerScriptURL, 'resources/' + kWorkletScriptURL); 64 t.add_cleanup(() => registration.unregister()); 65 await wait_for_state(t, registration.installing, 'activated'); 66 67 const win = await openWindow(t, kWindowURL); 68 assert_equals(win.navigator.serviceWorker.controller, null, 69 'The document should not be controlled.'); 70 71 // The worklet script on kWorkletScriptURL doesn't exist and the service 72 // worker doesn't serve it, so the addModule() should fail. 73 win.postMessage({ type: worklet_type, script_url: kWorkletScriptURL }, '*'); 74 const msgEvent = await new Promise(resolve => window.onmessage = resolve); 75 assert_equals(msgEvent.data, 'REJECTED'); 76 }, 'addModule() on a non-controlled document should not be intercepted by ' + 77 'a service worker even if the script is under the service worker scope.'); 78 79 // Tests that static import should be served by the owner document's service 80 // worker. 81 // 82 // [Current document] registers a service worker for Window's URL. 83 // --(open)--> [Window] should be controlled by the service worker. 84 // --(addModule)--> [Worklet] should be served by the service worker. 85 // --(static import)--> [Script] should be served by the service worker. 86 promise_test(async t => { 87 const kWindowURL = 'resources/addmodule-window.html'; 88 const kServiceWorkerScriptURL = 'resources/service-worker.js'; 89 // This doesn't contain the 'resources/' prefix because this will be 90 // imported from a html file under resources/. 91 const kWorkletScriptURL = 'import-non-existent-worklet-script.js'; 92 93 const registration = await service_worker_unregister_and_register( 94 t, kServiceWorkerScriptURL, kWindowURL); 95 t.add_cleanup(() => registration.unregister()); 96 await wait_for_state(t, registration.installing, 'activated'); 97 98 const win = await openWindow(t, kWindowURL); 99 assert_not_equals(win.navigator.serviceWorker.controller, null, 100 'The document should be controlled.'); 101 102 // A script statically imported by the worklet doesn't exist but the service 103 // worker serves it, so the addModule() should succeed. 104 win.postMessage({ type: worklet_type, script_url: kWorkletScriptURL }, '*'); 105 const msgEvent = await new Promise(resolve => window.onmessage = resolve); 106 assert_equals(msgEvent.data, 'RESOLVED'); 107 }, 'Static import should be intercepted by a service worker.'); 108 }