<!doctype html>
<meta charset=utf-8>
<title>Service Worker: claim() should affect other registration</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
promise_test(function(t) {
var frame;
var init_scope = 'resources/blank.html?affect-other';
var init_worker_url = 'resources/empty.js';
var init_registration;
var init_workers = [undefined, undefined];
var claim_scope = 'resources/blank.html?affect-other-registration';
var claim_worker_url = 'resources/claim-worker.js';
var claim_registration;
var claim_worker;
return Promise.resolve()
// Register the first service worker to init_scope.
.then(() => navigator.serviceWorker.register(init_worker_url + '?v1',
{scope: init_scope}))
.then(r => {
init_registration = r;
init_workers[0] = r.installing;
return Promise.resolve()
.then(() => wait_for_state(t, init_workers[0], 'activated'))
.then(() => assert_array_equals([init_registration.active,
init_registration.waiting,
init_registration.installing],
[init_workers[0],
null,
null],
'Wrong workers.'));
})
// Create an iframe as the client of the first service worker of init_scope.
.then(() => with_iframe(claim_scope))
.then(f => frame = f)
// Check the controller.
.then(() => frame.contentWindow.navigator.serviceWorker.getRegistration(
normalizeURL(init_scope)))
.then(r => assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
r.active,
'.controller should belong to init_scope.'))
// Register the second service worker to init_scope.
.then(() => navigator.serviceWorker.register(init_worker_url + '?v2',
{scope: init_scope}))
.then(r => {
assert_equals(r, init_registration, 'Should be the same registration');
init_workers[1] = r.installing;
return Promise.resolve()
.then(() => wait_for_state(t, init_workers[1], 'installed'))
.then(() => assert_array_equals([init_registration.active,
init_registration.waiting,
init_registration.installing],
[init_workers[0],
init_workers[1],
null],
'Wrong workers.'));
})
// Register a service worker to claim_scope.
.then(() => navigator.serviceWorker.register(claim_worker_url,
{scope: claim_scope}))
.then(r => {
claim_registration = r;
claim_worker = r.installing;
return wait_for_state(t, claim_worker, 'activated')
})
// Let claim_worker claim the created iframe.
.then(function() {
var channel = new MessageChannel();
var saw_message = new Promise(function(resolve) {
channel.port1.onmessage = t.step_func(function(e) {
assert_equals(e.data, 'PASS',
'Worker call to claim() should fulfill.');
resolve();
});
});
claim_worker.postMessage({port: channel.port2}, [channel.port2]);
return saw_message;
})
// Check the controller.
.then(() => frame.contentWindow.navigator.serviceWorker.getRegistration(
normalizeURL(claim_scope)))
.then(r => assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
r.active,
'.controller should belong to claim_scope.'))
// Check the status of created registrations and service workers.
.then(() => wait_for_state(t, init_workers[1], 'activated'))
.then(() => {
assert_array_equals([claim_registration.active,
claim_registration.waiting,
claim_registration.installing],
[claim_worker,
null,
null],
'claim_worker should be the only worker.')
assert_array_equals([init_registration.active,
init_registration.waiting,
init_registration.installing],
[init_workers[1],
null,
null],
'The waiting sw should become the active worker.')
assert_array_equals([init_workers[0].state,
init_workers[1].state,
claim_worker.state],
['redundant',
'activated',
'activated'],
'Wrong worker states.');
})
// Cleanup and finish testing.
.then(() => frame.remove())
.then(() => Promise.all([
init_registration.unregister(),
claim_registration.unregister()
]))
.then(() => t.done());
}, 'claim() should affect the originally controlling registration.');
</script>