blob: 8267e6506d20cc4c1d8e8a55d9234124a6027510 [file] [log] [blame]
<!DOCTYPE html>
<title>Service Worker: navigator.serviceWorker.ready</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<body>
<script>
test(function() {
var promise = navigator.serviceWorker.ready;
assert_equals(promise, navigator.serviceWorker.ready,
'repeated access to ready without intervening ' +
'registrations should return the same Promise object');
}, 'ready returns the same Promise object');
promise_test(function(t) {
return with_iframe('resources/blank.html?uncontrolled')
.then(t.step_func(function(frame) {
var promise = frame.contentWindow.navigator.serviceWorker.ready;
t.add_cleanup(function() {
frame.remove();
});
assert_equals(Object.getPrototypeOf(promise),
frame.contentWindow.Promise.prototype,
'the Promise should be in the context of the ' +
'related document');
}));
}, 'ready returns a Promise object in the context of the related document');
promise_test(function(t) {
var url = 'resources/empty-worker.js';
var scope = 'resources/blank.html?ready-controlled';
var expected_url = normalizeURL(url);
var frame;
return service_worker_unregister_and_register(t, url, scope)
.then(function(registration) {
add_completion_callback(function() {
registration.unregister();
});
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() { return with_iframe(scope); })
.then(function(f) {
t.add_cleanup(function() {
f.remove();
});
frame = f;
return frame.contentWindow.navigator.serviceWorker.ready;
})
.then(function(registration) {
assert_equals(registration.installing, null,
'installing should be null');
assert_equals(registration.waiting, null,
'waiting should be null');
assert_equals(registration.active.scriptURL, expected_url,
'active after ready should not be null');
assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
registration.active,
'the controller should be the active worker');
assert_in_array(registration.active.state,
['activating', 'activated'],
'.ready should be resolved when the registration ' +
'has an active worker');
});
}, 'ready on a controlled document');
promise_test(function(t) {
var url = 'resources/empty-worker.js';
var scope = 'resources/blank.html?ready-potential-controlled';
var expected_url = normalizeURL(url);
var frame;
return with_iframe(scope)
.then(function(f) {
t.add_cleanup(function() {
f.remove();
});
frame = f;
return navigator.serviceWorker.register(url, {scope:scope});
})
.then(function(r) {
add_completion_callback(function() {
r.unregister();
});
return frame.contentWindow.navigator.serviceWorker.ready;
})
.then(function(registration) {
assert_equals(registration.installing, null,
'installing should be null');
assert_equals(registration.waiting, null,
'waiting should be null.')
assert_equals(registration.active.scriptURL, expected_url,
'active after ready should not be null');
assert_in_array(registration.active.state,
['activating', 'activated'],
'.ready should be resolved when the registration ' +
'has an active worker');
assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
null,
'uncontrolled document should not have a controller');
});
}, 'ready on a potential controlled document');
promise_test(function(t) {
var url = 'resources/empty-worker.js';
var scope = 'resources/blank.html?ready-installing';
return service_worker_unregister(t, scope)
.then(function() {
return with_iframe(scope);
})
.then(function(f) {
var promise = f.contentWindow.navigator.serviceWorker.ready;
t.add_cleanup(function() {
f.remove();
});
navigator.serviceWorker.register(url, {scope: scope});
return promise;
})
.then(function(registration) {
add_completion_callback(function() {
registration.unregister();
});
assert_equals(registration.installing, null,
'installing should be null');
assert_equals(registration.waiting, null, 'waiting should be null');
assert_not_equals(registration.active, null,
'active after ready should not be null');
assert_in_array(registration.active.state,
['activating', 'activated'],
'.ready should be resolved when the registration ' +
'has an active worker');
});
}, 'ready on an iframe whose parent registers a new service worker');
promise_test(function(t) {
var url = 'resources/empty-worker.js';
var scope = 'resources/register-iframe.html';
var expected_url = normalizeURL(url);
return with_iframe(scope)
.then(function(f) {
t.add_cleanup(function() {
f.remove();
});
return f.contentWindow.navigator.serviceWorker.ready;
})
.then(function(registration) {
add_completion_callback(function() {
registration.unregister();
});
assert_equals(registration.installing, null,
'installing should be null');
assert_equals(registration.waiting, null, 'waiting should be null');
assert_not_equals(registration.active, null,
'active after ready should not be null');
assert_in_array(registration.active.state,
['activating', 'activated'],
'.ready should be resolved with "active worker"');
});
}, 'ready on an iframe that installs a new service worker');
promise_test(function(t) {
var url = 'resources/empty-worker.js';
var matched_scope = 'resources/blank.html?ready-after-match';
var longer_matched_scope = 'resources/blank.html?ready-after-match-longer';
var frame, registration;
return Promise.all([service_worker_unregister(t, matched_scope),
service_worker_unregister(t, longer_matched_scope)])
.then(function() {
return with_iframe(longer_matched_scope);
})
.then(function(f) {
t.add_cleanup(function() {
f.remove();
});
frame = f;
return navigator.serviceWorker.register(url, {scope: matched_scope});
})
.then(function(r) {
add_completion_callback(function() {
r.unregister();
});
registration = r;
return wait_for_state(t, r.installing, 'activated');
})
.then(function() {
return navigator.serviceWorker.register(
url, {scope: longer_matched_scope});
})
.then(function(r) {
add_completion_callback(function() {
r.unregister();
});
return frame.contentWindow.navigator.serviceWorker.ready;
})
.then(function(r) {
assert_equals(r.scope, normalizeURL(longer_matched_scope),
'longer matched registration should be returned');
assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
null, 'controller should be null');
});
}, 'ready after a longer matched registration registered');
promise_test(function(t) {
var url = 'resources/empty-worker.js';
var matched_scope = 'resources/blank.html?ready-after-resolve';
var longer_matched_scope =
'resources/blank.html?ready-after-resolve-longer';
var frame, registration;
return service_worker_unregister_and_register(t, url, matched_scope)
.then(function(r) {
add_completion_callback(function() {
r.unregister();
});
registration = r;
return wait_for_state(t, r.installing, 'activated');
})
.then(function() {
return with_iframe(longer_matched_scope);
})
.then(function(f) {
t.add_cleanup(function() {
f.remove();
});
frame = f;
return f.contentWindow.navigator.serviceWorker.ready;
})
.then(function(r) {
assert_equals(r.scope, normalizeURL(matched_scope),
'matched registration should be returned');
return navigator.serviceWorker.register(
url, {scope: longer_matched_scope});
})
.then(function(r) {
add_completion_callback(function() {
r.unregister();
});
return frame.contentWindow.navigator.serviceWorker.ready;
})
.then(function(r) {
assert_equals(r.scope, normalizeURL(matched_scope),
'ready should only be resolved once');
});
}, 'access ready after it has been resolved');
</script>