helper-serviceworker.js (3615B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /* import-globals-from head.js */ 7 8 /** 9 * Temporarily flip all the preferences necessary for service worker testing. 10 */ 11 async function enableServiceWorkerDebugging() { 12 // Enable service workers. 13 await pushPref("dom.serviceWorkers.enabled", true); 14 15 // Accept workers from mochitest's http (normally only available in https). 16 await pushPref("dom.serviceWorkers.testing.enabled", true); 17 18 // Force single content process. Necessary until sw e10s refactor is done (Bug 1231208). 19 await pushPref("dom.ipc.processCount", 1); 20 Services.ppmm.releaseCachedProcesses(); 21 } 22 /* exported enableServiceWorkerDebugging */ 23 24 /** 25 * Helper to listen once on a message sent using postMessage from the provided tab. 26 * 27 * @param {Tab} tab 28 * The tab on which the message will be received. 29 * @param {string} message 30 * The name of the expected message. 31 */ 32 function onServiceWorkerMessage(tab, message) { 33 info("Make the test page notify us when the service worker sends a message."); 34 return SpecialPowers.spawn( 35 tab.linkedBrowser, 36 [message], 37 function (messageChild) { 38 return new Promise(resolve => { 39 const win = content.wrappedJSObject; 40 win.navigator.serviceWorker.addEventListener( 41 "message", 42 function (event) { 43 if (event.data == messageChild) { 44 resolve(); 45 } 46 } 47 ); 48 }); 49 } 50 ); 51 } 52 /* exported onServiceWorkerMessage */ 53 54 async function _waitForServiceWorkerStatus(workerText, status, document) { 55 await waitUntil(() => { 56 const target = findDebugTargetByText(workerText, document); 57 const statusElement = target && target.querySelector(".qa-worker-status"); 58 return statusElement && statusElement.textContent === status; 59 }); 60 61 return findDebugTargetByText(workerText, document); 62 } 63 /* exported waitForServiceWorkerRunning */ 64 65 async function waitForServiceWorkerStopped(workerText, document) { 66 return _waitForServiceWorkerStatus(workerText, "Stopped", document); 67 } 68 /* exported waitForServiceWorkerStopped */ 69 70 async function waitForServiceWorkerRunning(workerText, document) { 71 return _waitForServiceWorkerStatus(workerText, "Running", document); 72 } 73 /* exported waitForServiceWorkerRunning */ 74 75 async function waitForServiceWorkerRegistering(workerText, document) { 76 return _waitForServiceWorkerStatus(workerText, "Registering", document); 77 } 78 /* exported waitForServiceWorkerRegistering */ 79 80 async function waitForRegistration(tab) { 81 info("Wait until the registration appears on the window"); 82 const swBrowser = tab.linkedBrowser; 83 await asyncWaitUntil(async () => 84 SpecialPowers.spawn(swBrowser, [], async function () { 85 return !!(await content.wrappedJSObject.getRegistration()); 86 }) 87 ); 88 } 89 /* exported waitForRegistration */ 90 91 /** 92 * Unregister the service worker from the content page. The content page should define 93 * `getRegistration` to allow this helper to retrieve the service worker registration that 94 * should be unregistered. 95 * 96 * @param {Tab} tab 97 * The tab on which the service worker should be removed. 98 */ 99 async function unregisterServiceWorker(tab) { 100 return SpecialPowers.spawn(tab.linkedBrowser, [], function () { 101 const win = content.wrappedJSObject; 102 // Check that the content page defines getRegistration. 103 is( 104 typeof win.getRegistration, 105 "function", 106 "getRegistration is a valid function" 107 ); 108 win.getRegistration().unregister(); 109 }); 110 } 111 /* exported unregisterServiceWorker */