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
|
<!DOCTYPE html>
<title>Service Worker: Clients.get</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
function wait_for_clientId() {
return new Promise(function(resolve, reject) {
window.onmessage = e => {
resolve(e.data.clientId);
};
});
}
promise_test(async t => {
// Register service worker.
const scope = 'resources/clients-get-frame.html';
const client_ids = [];
const registration = await service_worker_unregister_and_register(
t, 'resources/clients-get-worker.js', scope);
t.add_cleanup(() => registration.unregister());
await wait_for_state(t, registration.installing, 'activated');
// Prepare for test cases.
// Case 1: frame1 which is focused.
const frame1 = await with_iframe(scope + '#1');
t.add_cleanup(() => frame1.remove());
frame1.focus();
client_ids.push(await wait_for_clientId());
// Case 2: frame2 which is not focused.
const frame2 = await with_iframe(scope + '#2');
t.add_cleanup(() => frame2.remove());
client_ids.push(await wait_for_clientId());
// Case 3: invalid id.
client_ids.push('invalid-id');
// Call clients.get() for each id on the service worker.
const message_event = await new Promise(resolve => {
navigator.serviceWorker.onmessage = resolve;
registration.active.postMessage({clientIds: client_ids});
});
const expected = [
// visibilityState, focused, url, type, frameType
['visible', true, normalizeURL(scope) + '#1', 'window', 'nested'],
['visible', false, normalizeURL(scope) + '#2', 'window', 'nested'],
undefined
];
assert_equals(message_event.data.length, 3);
assert_array_equals(message_event.data[0], expected[0]);
assert_array_equals(message_event.data[1], expected[1]);
assert_equals(message_event.data[2], expected[2]);
}, 'Test Clients.get()');
promise_test(async t => {
// Register service worker.
const scope = 'resources/simple.html';
const registration = await service_worker_unregister_and_register(
t, 'resources/clients-get-resultingClientId-worker.js', scope)
t.add_cleanup(() => registration.unregister());
await wait_for_state(t, registration.installing, 'activated');
const worker = registration.active;
// Load frame within the scope.
const frame = await with_iframe(scope);
t.add_cleanup(() => frame.remove());
frame.focus();
// Get resulting client id.
const resultingClientId = await new Promise(resolve => {
navigator.serviceWorker.onmessage = e => {
if (e.data.msg == 'getResultingClientId') {
resolve(e.data.resultingClientId);
}
};
worker.postMessage({msg: 'getResultingClientId'});
});
// Query service worker for clients.get(resultingClientId).
const isResultingClientUndefined = await new Promise(resolve => {
navigator.serviceWorker.onmessage = e => {
if (e.data.msg == 'getIsResultingClientUndefined') {
resolve(e.data.isResultingClientUndefined);
}
};
worker.postMessage({msg: 'getIsResultingClientUndefined',
resultingClientId});
});
assert_false(
isResultingClientUndefined,
'Clients.get(FetchEvent.resultingClientId) resolved with a Client');
}, 'Test successful Clients.get(FetchEvent.resultingClientId)');
promise_test(async t => {
// Register service worker.
const scope = 'resources/simple.html?fail';
const registration = await service_worker_unregister_and_register(
t, 'resources/clients-get-resultingClientId-worker.js', scope);
t.add_cleanup(() => registration.unregister());
await wait_for_state(t, registration.installing, 'activated');
// Load frame, and destroy it while loading.
const worker = registration.active;
let frame = document.createElement('iframe');
frame.src = scope;
t.add_cleanup(() => {
if (frame) {
frame.remove();
}
});
await new Promise(resolve => {
navigator.serviceWorker.onmessage = e => {
// The service worker posts a message to remove the iframe during fetch
// event.
if (e.data.msg == 'destroyResultingClient') {
frame.remove();
frame = null;
worker.postMessage({msg: 'resultingClientDestroyed'});
resolve();
}
};
document.body.appendChild(frame);
});
resultingDestroyedClientId = await new Promise(resolve => {
navigator.serviceWorker.onmessage = e => {
// The worker sends a message back when it receives the message
// 'resultingClientDestroyed' with the resultingClientId.
if (e.data.msg == 'resultingClientDestroyedAck') {
assert_equals(frame, null, 'Frame should be destroyed at this point.');
resolve(e.data.resultingDestroyedClientId);
}
};
});
// Query service worker for clients.get(resultingDestroyedClientId).
const isResultingClientUndefined = await new Promise(resolve => {
navigator.serviceWorker.onmessage = e => {
if (e.data.msg == 'getIsResultingClientUndefined') {
resolve(e.data.isResultingClientUndefined);
}
};
worker.postMessage({msg: 'getIsResultingClientUndefined',
resultingClientId: resultingDestroyedClientId });
});
assert_true(
isResultingClientUndefined,
'Clients.get(FetchEvent.resultingClientId) resolved with `undefined`');
}, 'Test unsuccessful Clients.get(FetchEvent.resultingClientId)');
</script>
|