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
|
<!DOCTYPE html>
<html>
<head>
<title>Test onmessageerror event handlers</title>
</head>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="utils.js"></script>
<script>
/**
* Test that ServiceWorkerGlobalScope and ServiceWorkerContainer handle
* `messageerror` events, using a test helper class `StructuredCloneTester`.
* Intances of this class can be configured to fail to serialize or
* deserialize, as it's difficult to artificially create the case where an
* object successfully serializes but fails to deserialize (which can be
* caused by out-of-memory failures or the target global not supporting a
* serialized interface).
*/
let registration = null;
let serviceWorker = null;
let serviceWorkerContainer = null;
const swScript = 'onmessageerror_worker.js';
add_task(async () => {
await SpecialPowers.pushPrefEnv({
set: [
['dom.serviceWorkers.enabled', true],
['dom.serviceWorkers.testing.enabled', true],
['dom.testing.structuredclonetester.enabled', true],
],
});
swContainer = navigator.serviceWorker;
registration = await swContainer.register(swScript);
ok(registration, 'Service Worker regsisters');
serviceWorker = registration.installing;
await waitForState(serviceWorker, 'activated');
}); // setup
add_task(async () => {
const serializable = true;
const deserializable = true;
let sct = new StructuredCloneTester(serializable, deserializable);
const p = new Promise((resolve, reject) => {
function onMessage(e) {
const expectedBehavior = 'Serializable and deserializable ' +
'StructuredCloneTester serializes and deserializes';
is(e.data.received, 'message', expectedBehavior);
swContainer.removeEventListener('message', onMessage);
resolve();
}
swContainer.addEventListener('message', onMessage);
});
serviceWorker.postMessage({ serializable, deserializable, sct });
await p;
});
add_task(async () => {
const serializable = false;
// if it's not serializable, being deserializable or not doesn't matter
const deserializable = false;
let sct = new StructuredCloneTester(serializable, deserializable);
try {
serviceWorker.postMessage({ serializable, deserializable, sct });
ok(false, 'StructuredCloneTester serialization should have thrown -- ' +
'this line should not have been reached.');
} catch (e) {
const expectedBehavior = 'Unserializable StructuredCloneTester fails ' +
`to send, with exception name: ${e.name}`;
is(e.name, 'DataCloneError', expectedBehavior);
}
});
add_task(async () => {
const serializable = true;
const deserializable = false;
let sct = new StructuredCloneTester(serializable, deserializable);
const p = new Promise((resolve, reject) => {
function onMessage(e) {
const expectedBehavior = 'ServiceWorkerGlobalScope handles ' +
'messageerror events';
is(e.data.received, 'messageerror', expectedBehavior);
swContainer.removeEventListener('message', onMessage);
resolve();
}
swContainer.addEventListener('message', onMessage);
});
serviceWorker.postMessage({ serializable, deserializable, sct });
await p;
}); // test ServiceWorkerGlobalScope onmessageerror
add_task(async () => {
const p = new Promise((resolve, reject) => {
function onMessageError(e) {
ok(true, 'ServiceWorkerContainer handles messageerror events');
swContainer.removeEventListener('messageerror', onMessageError);
resolve();
}
swContainer.addEventListener('messageerror', onMessageError);
});
serviceWorker.postMessage('send-bad-message');
await p;
}); // test ServiceWorkerContainer onmessageerror
add_task(async () => {
await SpecialPowers.popPrefEnv();
ok(await registration.unregister(), 'Service Worker unregisters');
}); // teardown
</script>
<body>
</body>
</html>
|