summaryrefslogtreecommitdiffstats
path: root/toolkit/components/extensions/test/browser/head_serviceworker.js
blob: b2f9512e5a75220454ecb7a2a5dfb9645c4367dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"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`);
}