Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!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>