-
Notifications
You must be signed in to change notification settings - Fork 54
/
Copy pathbrowser_multie10s_update.js
133 lines (114 loc) · 4.49 KB
/
browser_multie10s_update.js
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
"use strict";
// Testing if 2 child processes are correctly managed when they both try to do
// an SW update.
const BASE_URI =
"http://mochi.test:8888/browser/dom/serviceworkers/test/isolated/multi-e10s-update/";
add_task(async function test_update() {
info("Setting the prefs to having multi-e10s enabled");
await SpecialPowers.pushPrefEnv({"set": [
["dom.ipc.processCount", 4],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
]});
let url = BASE_URI + "file_multie10s_update.html";
info("Creating the first tab...");
let tab1 = BrowserTestUtils.addTab(gBrowser, url);
let browser1 = gBrowser.getBrowserForTab(tab1);
await BrowserTestUtils.browserLoaded(browser1);
info("Creating the second tab...");
let tab2 = BrowserTestUtils.addTab(gBrowser, url);
let browser2 = gBrowser.getBrowserForTab(tab2);
await BrowserTestUtils.browserLoaded(browser2);
let sw = BASE_URI + "server_multie10s_update.sjs";
info("Let's make sure there are no existing registrations...");
let existingCount = await ContentTask.spawn(browser1, null, async function() {
const regs = await content.navigator.serviceWorker.getRegistrations();
return regs.length;
});
is(existingCount, 0, "Previous tests should have cleaned up!");
info("Let's start the test...");
let status = await ContentTask.spawn(browser1, sw, function(url) {
// Let the SW be served immediately once by triggering a relase immediately.
// We don't need to await this. We do this from a frame script because
// it has fetch.
content.fetch(url + "?release");
// Registration of the SW
return content.navigator.serviceWorker.register(url)
// Activation
.then(function(r) {
content.registration = r;
return new content.window.Promise(resolve => {
let worker = r.installing;
worker.addEventListener('statechange', () => {
if (worker.state === 'installed') {
resolve(true);
}
});
});
})
// Waiting for the result.
.then(() => {
return new content.window.Promise(resolveResults => {
// Once both updates have been issued and a single update has failed, we
// can tell the .sjs to release a single copy of the SW script.
let updateCount = 0;
const uc = new content.window.BroadcastChannel('update');
// This promise tracks the updates tally.
const updatesIssued = new Promise(resolveUpdatesIssued => {
uc.onmessage = function(e) {
updateCount++;
console.log("got update() number", updateCount);
if (updateCount === 2) {
resolveUpdatesIssued();
}
};
});
let results = [];
const rc = new content.window.BroadcastChannel('result');
// This promise resolves when an update has failed.
const oneFailed = new Promise(resolveOneFailed => {
rc.onmessage = function(e) {
console.log("got result", e.data);
results.push(e.data);
if (e.data === 1) {
resolveOneFailed();
}
if (results.length != 2) {
return;
}
resolveResults(results[0] + results[1]);
}
});
Promise.all([updatesIssued, oneFailed]).then(() => {
console.log("releasing update");
content.fetch(url + "?release").catch((ex) => {
console.error("problem releasing:", ex);
});
});
// Let's inform the tabs.
const sc = new content.window.BroadcastChannel('start');
sc.postMessage('go');
});
});
});
if (status == 0) {
ok(false, "both succeeded. This is wrong.");
} else if (status == 1) {
ok(true, "one succeded, one failed. This is good.");
} else {
ok(false, "both failed. This is definitely wrong.");
}
// let's clean up the registration and get the fetch count. The count
// should be 1 for the initial fetch and 1 for the update.
const count = await ContentTask.spawn(browser1, sw, async function(url) {
// We stored the registration on the frame script's wrapper, hence directly
// accesss content without using wrappedJSObject.
await content.registration.unregister();
const { count } =
await content.fetch(url + "?get-and-clear-count").then(r => r.json());
return count;
});
is(count, 2, "SW should have been fetched only twice");
BrowserTestUtils.removeTab(tab1);
BrowserTestUtils.removeTab(tab2);
});