summaryrefslogtreecommitdiffstats
path: root/dom/cache/test/mochitest/driver.js
blob: db0231c16808456a299ab67f8a1f9b85856a854e (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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
//
// This helper script exposes a runTests function that takes the name of a
// test script as its input argument and runs the test in three different
// contexts:
// 1. Regular Worker context
// 2. Service Worker context
// 3. Window context
// The function returns a promise which will get resolved once all tests
// finish.  The testFile argument is the name of the test file to be run
// in the different contexts, and the optional order argument can be set
// to either "parallel" or "sequential" depending on how the caller wants
// the tests to be run.  If this argument is not provided, the default is
// "both", which runs the tests in both modes.
// The caller of this function is responsible to call SimpleTest.finish
// when the returned promise is resolved.

function runTests(testFile, order) {
  async function setupPrefs() {
    // Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5)
    // Acquire storage access permission here so that the Cache API is avaialable
    return SpecialPowers.pushPrefEnv({
      set: [
        ["dom.caches.testing.enabled", true],
        ["dom.serviceWorkers.enabled", true],
        ["dom.serviceWorkers.testing.enabled", true],
        ["dom.serviceWorkers.exemptFromPerDomainMax", true],
      ],
    });
  }

  // adapted from dom/indexedDB/test/helpers.js
  function clearStorage() {
    var clearUnpartitionedStorage = new Promise(function (resolve, reject) {
      var qms = SpecialPowers.Services.qms;
      var principal = SpecialPowers.wrap(document).nodePrincipal;
      var request = qms.clearStoragesForPrincipal(principal);
      var cb = SpecialPowers.wrapCallback(resolve);
      request.callback = cb;
    });
    var clearPartitionedStorage = new Promise(function (resolve, reject) {
      var qms = SpecialPowers.Services.qms;
      var principal = SpecialPowers.wrap(document).partitionedPrincipal;
      var request = qms.clearStoragesForPrincipal(principal);
      var cb = SpecialPowers.wrapCallback(resolve);
      request.callback = cb;
    });
    return Promise.all([clearUnpartitionedStorage, clearPartitionedStorage]);
  }

  function loadScript(script) {
    return new Promise(function (resolve, reject) {
      var s = document.createElement("script");
      s.src = script;
      s.onerror = reject;
      s.onload = resolve;
      document.body.appendChild(s);
    });
  }

  function importDrivers() {
    /* import-globals-from worker_driver.js */
    /* import-globals-from serviceworker_driver.js */
    return Promise.all([
      loadScript("worker_driver.js"),
      loadScript("serviceworker_driver.js"),
    ]);
  }

  function runWorkerTest() {
    return workerTestExec(testFile);
  }

  function runServiceWorkerTest() {
    if (
      navigator.serviceWorker == null &&
      SpecialPowers.getBoolPref("dom.cache.privateBrowsing.enabled")
    ) {
      return new Promise(function (resolve, reject) {
        resolve(true);
      });
    }

    return serviceWorkerTestExec(testFile);
  }

  function runFrameTest() {
    return new Promise(function (resolve, reject) {
      var iframe = document.createElement("iframe");
      iframe.src = "frame.html";
      iframe.onload = function () {
        var doc = iframe.contentDocument;
        var s = doc.createElement("script");
        s.src = testFile;
        window.addEventListener("message", function onMessage(event) {
          if (event.data.context != "Window") {
            return;
          }
          if (event.data.type == "finish") {
            window.removeEventListener("message", onMessage);
            resolve();
          } else if (event.data.type == "status") {
            ok(event.data.status, event.data.context + ": " + event.data.msg);
          }
        });
        doc.body.appendChild(s);
      };
      document.body.appendChild(iframe);
    });
  }

  SimpleTest.waitForExplicitFinish();

  if (typeof order == "undefined") {
    order = "sequential"; // sequential by default, see bug 1143222.
    // TODO: Make this "both" again.
  }

  ok(
    order == "parallel" || order == "sequential" || order == "both",
    "order argument should be valid"
  );

  if (order == "both") {
    info("Running tests in both modes; first: sequential");
    return runTests(testFile, "sequential").then(function () {
      info("Running tests in parallel mode");
      return runTests(testFile, "parallel");
    });
  }
  if (order == "sequential") {
    return setupPrefs()
      .then(importDrivers)
      .then(runWorkerTest)
      .then(clearStorage)
      .then(runServiceWorkerTest)
      .then(clearStorage)
      .then(runFrameTest)
      .then(clearStorage)
      .catch(function (e) {
        ok(false, "A promise was rejected during test execution: " + e);
      });
  }
  return setupPrefs()
    .then(importDrivers)
    .then(() =>
      Promise.all([runWorkerTest(), runServiceWorkerTest(), runFrameTest()])
    )
    .then(clearStorage)
    .catch(function (e) {
      ok(false, "A promise was rejected during test execution: " + e);
    });
}