Bug 1267733 P4 Add a wpt test that verifies a service worker update can recover from a broken navigation interception. r=jdm

--HG--
rename : testing/web-platform/tests/service-workers/service-worker/resources/update-worker.py => testing/web-platform/tests/service-workers/service-worker/resources/update-recovery-worker.py
rename : testing/web-platform/tests/service-workers/service-worker/update.https.html => testing/web-platform/tests/service-workers/service-worker/update-recovery.https.html
This commit is contained in:
Ben Kelly 2016-04-27 02:24:04 -07:00
Родитель c9b282c4c6
Коммит fe9b3f361f
3 изменённых файлов: 102 добавлений и 0 удалений

Просмотреть файл

@ -35378,6 +35378,12 @@
"url": "/service-workers/service-worker/navigate-window.https.html"
}
],
"service-workers/service-worker/update-recovery.https.html": [
{
"path": "service-workers/service-worker/update-recovery.https.html",
"url": "/service-workers/service-worker/update-recovery.https.html"
}
],
"web-animations/animation/startTime.html": [
{
"path": "web-animations/animation/startTime.html",

Просмотреть файл

@ -0,0 +1,25 @@
def main(request, response):
# Set mode to 'init' for initial fetch.
mode = 'init'
if 'update-recovery-mode' in request.cookies:
mode = request.cookies['update-recovery-mode'].value
# no-cache itself to ensure the user agent finds a new version for each update.
headers = [('Cache-Control', 'no-cache, must-revalidate'),
('Pragma', 'no-cache')]
extra_body = ''
if mode == 'init':
# Install a bad service worker that will break the controlled
# document navigation.
response.set_cookie('update-recovery-mode', 'bad')
extra_body = "addEventListener('fetch', function(e) { e.respondWith(Promise.reject()); });"
elif mode == 'bad':
# When the update tries to pull the script again, update to
# a worker service worker that does not break document
# navigation. Serve the same script from then on.
response.delete_cookie('update-recovery-mode')
headers.append(('Content-Type', 'application/javascript'))
return headers, '%s' % (extra_body)

Просмотреть файл

@ -0,0 +1,71 @@
<!DOCTYPE html>
<title>Service Worker: recovery by navigation update</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
async_test(function(t) {
var scope = 'resources/simple.txt';
var worker_url = 'resources/update-recovery-worker.py';
var expected_url = normalizeURL(worker_url);
var registration;
function with_bad_iframe(url) {
return new Promise(function(resolve, reject) {
var frame = document.createElement('iframe');
// There is no cross-browser event to listen for to detect an
// iframe that fails to load due to a bad interception. Unfortunately
// we have to use a timeout.
var timeout = setTimeout(function() {
frame.remove();
resolve();
}, 5000);
// If we do get a load event, though, we know something went wrong.
frame.addEventListener('load', function() {
clearTimeout(timeout);
frame.remove();
reject('expected bad iframe should not fire a load event!');
});
frame.src = url;
document.body.appendChild(frame);
});
}
function with_update(t) {
return new Promise(function(resolve, reject) {
registration.addEventListener('updatefound', function onUpdate() {
registration.removeEventListener('updatefound', onUpdate);
wait_for_state(t, registration.installing, 'activated').then(function() {
resolve();
});
});
});
}
service_worker_unregister_and_register(t, worker_url, scope)
.then(function(r) {
registration = r;
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() {
return Promise.all([
with_update(t),
with_bad_iframe(scope)
]);
})
.then(function() {
return with_iframe(scope);
})
.then(function(frame) {
assert_equals(frame.contentWindow.navigator.serviceWorker.controller.scriptURL,
expected_url);
frame.remove();
return service_worker_unregister_and_done(t, scope);
})
.catch(unreached_rejection(t));
}, 'Recover from a bad service worker by updating after a failed navigation.');
</script>