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
|
<!DOCTYPE html>
<title>Service Worker: getRegistrations()</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script>
// Purge the existing registrations for the origin.
// getRegistrations() is used in order to avoid adding additional complexity
// e.g. adding an internal function.
promise_test(async () => {
const registrations = await navigator.serviceWorker.getRegistrations();
await Promise.all(registrations.map(r => r.unregister()));
const value = await navigator.serviceWorker.getRegistrations();
assert_array_equals(
value, [],
'getRegistrations should resolve with an empty array.');
}, 'registrations are not returned following unregister');
promise_test(async t => {
const scope = 'resources/scope/getregistrations/normal';
const script = 'resources/empty-worker.js';
const registrations = [
await service_worker_unregister_and_register(t, script, scope)];
t.add_cleanup(() => registrations[0].unregister());
const value = await navigator.serviceWorker.getRegistrations();
assert_array_equals(value, registrations,
'getRegistrations should resolve with an array of registrations');
}, 'Register then getRegistrations');
promise_test(async t => {
const scope1 = 'resources/scope/getregistrations/scope1';
const scope2 = 'resources/scope/getregistrations/scope2';
const scope3 = 'resources/scope/getregistrations/scope12';
const script = 'resources/empty-worker.js';
t.add_cleanup(() => service_worker_unregister(t, scope1));
t.add_cleanup(() => service_worker_unregister(t, scope2));
t.add_cleanup(() => service_worker_unregister(t, scope3));
const registrations = [
await service_worker_unregister_and_register(t, script, scope1),
await service_worker_unregister_and_register(t, script, scope2),
await service_worker_unregister_and_register(t, script, scope3),
];
const value = await navigator.serviceWorker.getRegistrations();
assert_array_equals(value, registrations);
}, 'Register multiple times then getRegistrations');
promise_test(async t => {
const scope = 'resources/scope/getregistrations/register-unregister';
const script = 'resources/empty-worker.js';
const registration = await service_worker_unregister_and_register(t, script, scope);
await registration.unregister();
const value = await navigator.serviceWorker.getRegistrations();
assert_array_equals(
value, [], 'getRegistrations should resolve with an empty array.');
}, 'Register then Unregister then getRegistrations');
promise_test(async t => {
const scope = 'resources/scope/getregistrations/register-unregister-controlled';
const script = 'resources/empty-worker.js';
const registration = await service_worker_unregister_and_register(t, script, scope);
await wait_for_state(t, registration.installing, 'activated');
// Create a frame controlled by the service worker and unregister the
// worker.
const frame = await with_iframe(scope);
t.add_cleanup(() => frame.remove());
await registration.unregister();
const value = await navigator.serviceWorker.getRegistrations();
assert_array_equals(
value, [],
'getRegistrations should resolve with an empty array.');
assert_equals(registration.installing, null);
assert_equals(registration.waiting, null);
assert_equals(registration.active.state, 'activated');
}, 'Register then Unregister with controlled frame then getRegistrations');
promise_test(async t => {
const host_info = get_host_info();
// Rewrite the url to point to remote origin.
const frame_same_origin_url = new URL("resources/frame-for-getregistrations.html", window.location);
const frame_url = host_info['HTTPS_REMOTE_ORIGIN'] + frame_same_origin_url.pathname;
const scope = 'resources/scope-for-getregistrations';
const script = 'resources/empty-worker.js';
// Loads an iframe and waits for 'ready' message from it to resolve promise.
// Caller is responsible for removing frame.
function with_iframe_ready(url) {
return new Promise(resolve => {
const frame = document.createElement('iframe');
frame.src = url;
window.addEventListener('message', function onMessage(e) {
window.removeEventListener('message', onMessage);
if (e.data == 'ready') {
resolve(frame);
}
});
document.body.appendChild(frame);
});
}
// We need this special frame loading function because the frame is going
// to register it's own service worker and there is the possibility that that
// register() finishes after the register() for the same domain later in the
// test. So we have to wait until the cross origin register() is done, and not
// just until the frame loads.
const frame = await with_iframe_ready(frame_url);
t.add_cleanup(async () => {
// Wait until the cross-origin worker is unregistered.
let resolve;
const channel = new MessageChannel();
channel.port1.onmessage = e => {
if (e.data == 'unregistered')
resolve();
};
frame.contentWindow.postMessage('unregister', '*', [channel.port2]);
await new Promise(r => { resolve = r; });
frame.remove();
});
const registrations = [
await service_worker_unregister_and_register(t, script, scope)];
t.add_cleanup(() => registrations[0].unregister());
const value = await navigator.serviceWorker.getRegistrations();
assert_array_equals(
value, registrations,
'getRegistrations should only return same origin registrations.');
}, 'getRegistrations promise resolves only with same origin registrations.');
</script>
|