browser_unregister_with_containers.js (5067B)
1 "use strict"; 2 3 const BASE_URI = "http://mochi.test:8888/browser/dom/serviceworkers/test/"; 4 const PAGE_URI = BASE_URI + "empty.html"; 5 const SCOPE = PAGE_URI + "?unregister_with_containers"; 6 const SW_SCRIPT = BASE_URI + "empty.js"; 7 8 function doRegister(browser) { 9 return SpecialPowers.spawn( 10 browser, 11 [{ script: SW_SCRIPT, scope: SCOPE }], 12 async function (opts) { 13 let reg = await content.navigator.serviceWorker.register(opts.script, { 14 scope: opts.scope, 15 }); 16 let worker = reg.installing || reg.waiting || reg.active; 17 await new Promise(resolve => { 18 if (worker.state === "activated") { 19 resolve(); 20 return; 21 } 22 worker.addEventListener("statechange", function onStateChange() { 23 if (worker.state === "activated") { 24 worker.removeEventListener("statechange", onStateChange); 25 resolve(); 26 } 27 }); 28 }); 29 } 30 ); 31 } 32 33 function doUnregister(browser) { 34 return SpecialPowers.spawn(browser, [SCOPE], async function (uri) { 35 let reg = await content.navigator.serviceWorker.getRegistration(uri); 36 let worker = reg.active; 37 await reg.unregister(); 38 await new Promise(resolve => { 39 if (worker.state === "redundant") { 40 resolve(); 41 return; 42 } 43 worker.addEventListener("statechange", function onStateChange() { 44 if (worker.state === "redundant") { 45 worker.removeEventListener("statechange", onStateChange); 46 resolve(); 47 } 48 }); 49 }); 50 }); 51 } 52 53 function isControlled(browser) { 54 return SpecialPowers.spawn(browser, [], function () { 55 return !!content.navigator.serviceWorker.controller; 56 }); 57 } 58 59 async function checkControlled(browser) { 60 let controlled = await isControlled(browser); 61 ok(controlled, "window should be controlled"); 62 } 63 64 async function checkUncontrolled(browser) { 65 let controlled = await isControlled(browser); 66 ok(!controlled, "window should not be controlled"); 67 } 68 69 add_task(async function test() { 70 await SpecialPowers.pushPrefEnv({ 71 set: [ 72 // Avoid service worker propagation races by disabling multi-e10s for now. 73 // This can be removed after the e10s refactor is complete. 74 ["dom.ipc.processCount", 1], 75 ["dom.serviceWorkers.enabled", true], 76 ["dom.serviceWorkers.testing.enabled", true], 77 ], 78 }); 79 80 // Setup service workers in two different contexts with the same scope. 81 let containerTab1 = BrowserTestUtils.addTab(gBrowser, PAGE_URI, { 82 userContextId: 1, 83 }); 84 let containerBrowser1 = gBrowser.getBrowserForTab(containerTab1); 85 await BrowserTestUtils.browserLoaded(containerBrowser1); 86 87 let containerTab2 = BrowserTestUtils.addTab(gBrowser, PAGE_URI, { 88 userContextId: 2, 89 }); 90 let containerBrowser2 = gBrowser.getBrowserForTab(containerTab2); 91 await BrowserTestUtils.browserLoaded(containerBrowser2); 92 93 await doRegister(containerBrowser1); 94 await doRegister(containerBrowser2); 95 96 await checkUncontrolled(containerBrowser1); 97 await checkUncontrolled(containerBrowser2); 98 99 // Close the tabs we used to register the service workers. These are not 100 // controlled. 101 BrowserTestUtils.removeTab(containerTab1); 102 BrowserTestUtils.removeTab(containerTab2); 103 104 // Open a controlled tab in each container. 105 containerTab1 = BrowserTestUtils.addTab(gBrowser, SCOPE, { 106 userContextId: 1, 107 }); 108 containerBrowser1 = gBrowser.getBrowserForTab(containerTab1); 109 await BrowserTestUtils.browserLoaded(containerBrowser1); 110 111 containerTab2 = BrowserTestUtils.addTab(gBrowser, SCOPE, { 112 userContextId: 2, 113 }); 114 containerBrowser2 = gBrowser.getBrowserForTab(containerTab2); 115 await BrowserTestUtils.browserLoaded(containerBrowser2); 116 117 await checkControlled(containerBrowser1); 118 await checkControlled(containerBrowser2); 119 120 // Remove the first container's controlled tab 121 BrowserTestUtils.removeTab(containerTab1); 122 123 // Create a new uncontrolled tab for the first container and use it to 124 // unregister the service worker. 125 containerTab1 = BrowserTestUtils.addTab(gBrowser, PAGE_URI, { 126 userContextId: 1, 127 }); 128 containerBrowser1 = gBrowser.getBrowserForTab(containerTab1); 129 await BrowserTestUtils.browserLoaded(containerBrowser1); 130 await doUnregister(containerBrowser1); 131 132 await checkUncontrolled(containerBrowser1); 133 await checkControlled(containerBrowser2); 134 135 // Remove the second container's controlled tab 136 BrowserTestUtils.removeTab(containerTab2); 137 138 // Create a new uncontrolled tab for the second container and use it to 139 // unregister the service worker. 140 containerTab2 = BrowserTestUtils.addTab(gBrowser, PAGE_URI, { 141 userContextId: 2, 142 }); 143 containerBrowser2 = gBrowser.getBrowserForTab(containerTab2); 144 await BrowserTestUtils.browserLoaded(containerBrowser2); 145 await doUnregister(containerBrowser2); 146 147 await checkUncontrolled(containerBrowser1); 148 await checkUncontrolled(containerBrowser2); 149 150 // Close the two tabs we used to unregister the service worker. 151 BrowserTestUtils.removeTab(containerTab1); 152 BrowserTestUtils.removeTab(containerTab2); 153 });