/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; /* import-globals-from head.js */ /** * Temporarily flip all the preferences necessary for service worker testing. */ async function enableServiceWorkerDebugging() { // Enable service workers. await pushPref("dom.serviceWorkers.enabled", true); // Accept workers from mochitest's http (normally only available in https). await pushPref("dom.serviceWorkers.testing.enabled", true); // Force single content process. Necessary until sw e10s refactor is done (Bug 1231208). await pushPref("dom.ipc.processCount", 1); Services.ppmm.releaseCachedProcesses(); } /* exported enableServiceWorkerDebugging */ /** * Helper to listen once on a message sent using postMessage from the provided tab. * * @param {Tab} tab * The tab on which the message will be received. * @param {String} message * The name of the expected message. */ function onServiceWorkerMessage(tab, message) { info("Make the test page notify us when the service worker sends a message."); return SpecialPowers.spawn( tab.linkedBrowser, [message], function (messageChild) { return new Promise(resolve => { const win = content.wrappedJSObject; win.navigator.serviceWorker.addEventListener( "message", function (event) { if (event.data == messageChild) { resolve(); } } ); }); } ); } /* exported onServiceWorkerMessage */ async function _waitForServiceWorkerStatus(workerText, status, document) { await waitUntil(() => { const target = findDebugTargetByText(workerText, document); const statusElement = target && target.querySelector(".qa-worker-status"); return statusElement && statusElement.textContent === status; }); return findDebugTargetByText(workerText, document); } /* exported waitForServiceWorkerRunning */ async function waitForServiceWorkerStopped(workerText, document) { return _waitForServiceWorkerStatus(workerText, "Stopped", document); } /* exported waitForServiceWorkerStopped */ async function waitForServiceWorkerRunning(workerText, document) { return _waitForServiceWorkerStatus(workerText, "Running", document); } /* exported waitForServiceWorkerRunning */ async function waitForServiceWorkerRegistering(workerText, document) { return _waitForServiceWorkerStatus(workerText, "Registering", document); } /* exported waitForServiceWorkerRegistering */ async function waitForRegistration(tab) { info("Wait until the registration appears on the window"); const swBrowser = tab.linkedBrowser; await asyncWaitUntil(async () => SpecialPowers.spawn(swBrowser, [], async function () { return !!(await content.wrappedJSObject.getRegistration()); }) ); } /* exported waitForRegistration */ /** * Unregister the service worker from the content page. The content page should define * `getRegistration` to allow this helper to retrieve the service worker registration that * should be unregistered. * * @param {Tab} tab * The tab on which the service worker should be removed. */ async function unregisterServiceWorker(tab) { return SpecialPowers.spawn(tab.linkedBrowser, [], function () { const win = content.wrappedJSObject; // Check that the content page defines getRegistration. is( typeof win.getRegistration, "function", "getRegistration is a valid function" ); win.getRegistration().unregister(); }); } /* exported unregisterServiceWorker */