forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			123 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"use strict";
 | 
						|
 | 
						|
/* exported assert_background_serviceworker_pref_enabled,
 | 
						|
 *          getBackgroundServiceWorkerRegistration,
 | 
						|
 *          getServiceWorkerInfo, getServiceWorkerState,
 | 
						|
 *          waitForServiceWorkerRegistrationsRemoved, waitForServiceWorkerTerminated
 | 
						|
 */
 | 
						|
 | 
						|
async function assert_background_serviceworker_pref_enabled() {
 | 
						|
  is(
 | 
						|
    WebExtensionPolicy.backgroundServiceWorkerEnabled,
 | 
						|
    true,
 | 
						|
    "Expect extensions.backgroundServiceWorker.enabled to be true"
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
// Return the name of the enum corresponding to the worker's state (ex: "STATE_ACTIVATED")
 | 
						|
// because nsIServiceWorkerInfo doesn't currently provide a comparable string-returning getter.
 | 
						|
function getServiceWorkerState(workerInfo) {
 | 
						|
  const map = Object.keys(workerInfo)
 | 
						|
    .filter(k => k.startsWith("STATE_"))
 | 
						|
    .reduce((map, name) => {
 | 
						|
      map.set(workerInfo[name], name);
 | 
						|
      return map;
 | 
						|
    }, new Map());
 | 
						|
  return map.has(workerInfo.state)
 | 
						|
    ? map.get(workerInfo.state)
 | 
						|
    : "state: ${workerInfo.state}";
 | 
						|
}
 | 
						|
 | 
						|
function getServiceWorkerInfo(swRegInfo) {
 | 
						|
  const {
 | 
						|
    evaluatingWorker,
 | 
						|
    installingWorker,
 | 
						|
    waitingWorker,
 | 
						|
    activeWorker,
 | 
						|
  } = swRegInfo;
 | 
						|
  return evaluatingWorker || installingWorker || waitingWorker || activeWorker;
 | 
						|
}
 | 
						|
 | 
						|
async function waitForServiceWorkerTerminated(swRegInfo) {
 | 
						|
  info(`Wait all ${swRegInfo.scope} workers to be terminated`);
 | 
						|
 | 
						|
  try {
 | 
						|
    await BrowserTestUtils.waitForCondition(
 | 
						|
      () => !getServiceWorkerInfo(swRegInfo)
 | 
						|
    );
 | 
						|
  } catch (err) {
 | 
						|
    const workerInfo = getServiceWorkerInfo(swRegInfo);
 | 
						|
    if (workerInfo) {
 | 
						|
      ok(
 | 
						|
        false,
 | 
						|
        `Error while waiting for workers for scope ${swRegInfo.scope} to be terminated. ` +
 | 
						|
          `Found a worker in state: ${getServiceWorkerState(workerInfo)}`
 | 
						|
      );
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    throw err;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function getBackgroundServiceWorkerRegistration(extension) {
 | 
						|
  const policy = WebExtensionPolicy.getByHostname(extension.uuid);
 | 
						|
  const expectedSWScope = policy.getURL("/");
 | 
						|
  const expectedScriptURL = policy.extension.backgroundWorkerScript || "";
 | 
						|
 | 
						|
  ok(
 | 
						|
    expectedScriptURL.startsWith(expectedSWScope),
 | 
						|
    `Extension does include a valid background.service_worker: ${expectedScriptURL}`
 | 
						|
  );
 | 
						|
 | 
						|
  const swm = Cc["@mozilla.org/serviceworkers/manager;1"].getService(
 | 
						|
    Ci.nsIServiceWorkerManager
 | 
						|
  );
 | 
						|
 | 
						|
  let swReg;
 | 
						|
  let regs = swm.getAllRegistrations();
 | 
						|
 | 
						|
  for (let i = 0; i < regs.length; i++) {
 | 
						|
    let reg = regs.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
 | 
						|
    if (reg.scriptSpec === expectedScriptURL) {
 | 
						|
      swReg = reg;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  ok(swReg, `Found service worker registration for ${expectedScriptURL}`);
 | 
						|
 | 
						|
  is(
 | 
						|
    swReg.scope,
 | 
						|
    expectedSWScope,
 | 
						|
    "The extension background worker registration has the expected scope URL"
 | 
						|
  );
 | 
						|
 | 
						|
  return swReg;
 | 
						|
}
 | 
						|
 | 
						|
async function waitForServiceWorkerRegistrationsRemoved(extension) {
 | 
						|
  info(`Wait ${extension.id} service worker registration to be deleted`);
 | 
						|
  const swm = Cc["@mozilla.org/serviceworkers/manager;1"].getService(
 | 
						|
    Ci.nsIServiceWorkerManager
 | 
						|
  );
 | 
						|
  let baseURI = Services.io.newURI(`moz-extension://${extension.uuid}/`);
 | 
						|
  let principal = Services.scriptSecurityManager.createContentPrincipal(
 | 
						|
    baseURI,
 | 
						|
    {}
 | 
						|
  );
 | 
						|
 | 
						|
  await BrowserTestUtils.waitForCondition(() => {
 | 
						|
    let regs = swm.getAllRegistrations();
 | 
						|
 | 
						|
    for (let i = 0; i < regs.length; i++) {
 | 
						|
      let reg = regs.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
 | 
						|
      if (principal.equals(reg.principal)) {
 | 
						|
        return false;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    info(`All ${extension.id} service worker registrations are gone`);
 | 
						|
    return true;
 | 
						|
  }, `All ${extension.id} service worker registrations should be deleted`);
 | 
						|
}
 |