From 1063ac3365406f5ba812ef6cb64246f5aaf993db Mon Sep 17 00:00:00 2001 From: asakusuma Date: Wed, 18 Sep 2019 17:17:29 +0900 Subject: [PATCH] Clear-Site-Data: clients uncontrolled by service workers after storage directive Adds a failing test, asserting that pages actively controlled by a service worker become uncontrolled after the Clear-Site-Data storage directive. We agreed on this behavior in a spec issue and confirmed the need for this test at the TPAC Service Workers F2F. https://github.com/w3c/ServiceWorker/issues/614 F2F notes: https://docs.google.com/document/d/1_Qfw5m3BJEaL1xIzTJd41HXjgJ9gq7mroBDXqSJIzic/edit --- clear-site-data/storage.https.html | 31 ++++++++++++++++ .../support/page_using_service_worker.html | 35 +++++++++++++++++++ clear-site-data/support/service_worker.js | 16 ++++++++- clear-site-data/support/test_utils.sub.js | 19 +++++++++- 4 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 clear-site-data/support/page_using_service_worker.html diff --git a/clear-site-data/storage.https.html b/clear-site-data/storage.https.html index 35c9fd1a03bc2c..e1e763e9292ddf 100644 --- a/clear-site-data/storage.https.html +++ b/clear-site-data/storage.https.html @@ -13,6 +13,8 @@ return datatype.name == "storage"; })[0]; + var serviceWorkerTestPageIFrame; + // The tests are set up asynchronously. setup({"explicit_done": true}); @@ -22,6 +24,23 @@ test(function() {}, "Populate backends."); TestUtils.populateStorage() + .then(() => { + const serviceWorkerResponseOk = TestUtils.getServiceWorkerResponseOk(); + + // Create iFrame in the service worker's scope. This page will make a request + // for another page that is only served by the service worker + serviceWorkerTestPageIFrame = document.createElement("iframe"); + serviceWorkerTestPageIFrame.src = "support/page_using_service_worker.html"; + document.body.appendChild(serviceWorkerTestPageIFrame); + + promise_test(function() { + return serviceWorkerResponseOk.then(function(responseIsOk) { + assert_true(responseIsOk, "Response should be 200"); + }); + }, "Baseline: Service worker responds to request"); + + return serviceWorkerResponseOk; + }) .then(function() { // Navigate to a resource with a Clear-Site-Data header in // an iframe, then verify that all backends of the "storage" @@ -45,6 +64,18 @@ }, test_name); }); + promise_test(function() { + const serviceWorkerResponseOk = TestUtils.getServiceWorkerResponseOk(); + + // Tell the iframe to make a request for the URL that the service worker + // responds to + serviceWorkerTestPageIFrame.contentWindow.postMessage(null, "*"); + + return serviceWorkerResponseOk.then(function(responseIsOk) { + assert_false(responseIsOk, "Response should not be 200"); + }); + }, "Service worker no longer responds to requests"); + done(); }); }); diff --git a/clear-site-data/support/page_using_service_worker.html b/clear-site-data/support/page_using_service_worker.html new file mode 100644 index 00000000000000..83443a7c058077 --- /dev/null +++ b/clear-site-data/support/page_using_service_worker.html @@ -0,0 +1,35 @@ + + + + Clear-Site-Data + Service Workers Test Page + + + + + + \ No newline at end of file diff --git a/clear-site-data/support/service_worker.js b/clear-site-data/support/service_worker.js index 8504a030ddfc4d..01fbbb782b0400 100644 --- a/clear-site-data/support/service_worker.js +++ b/clear-site-data/support/service_worker.js @@ -1 +1,15 @@ -/* This file is intentionally left blank. */ + +self.addEventListener('install', () => { + return self.skipWaiting(); +}); + +self.addEventListener('activate', (e) => { + e.waitUntil(self.clients.claim()); +}); + +self.addEventListener('fetch', (e) => { + const url = new URL(e.request.url); + if (url.pathname.match('sw-page')) { + e.respondWith(new Response('from-service-worker')); + } +}); \ No newline at end of file diff --git a/clear-site-data/support/test_utils.sub.js b/clear-site-data/support/test_utils.sub.js index 235273bd5ba4cb..13c3a92e13202f 100644 --- a/clear-site-data/support/test_utils.sub.js +++ b/clear-site-data/support/test_utils.sub.js @@ -121,7 +121,7 @@ var TestUtils = (function() { "add": function() { return navigator.serviceWorker.register( "support/service_worker.js", - { scope: "support/scope-that-does-not-contain-this-test/"}); + { scope: "support/"}); }, "isEmpty": function() { return new Promise(function(resolve, reject) { @@ -245,6 +245,23 @@ var TestUtils = (function() { */ TestUtils.populateStorage = populate.bind(this, TestUtils.STORAGE); + /** + * Wait for a postMessage from an iFrame. This message communicates the result + * of a request that can only be served by the service worker + * @private + */ + TestUtils.getServiceWorkerResponseOk = function() { + return new Promise(function(resolve) { + const cb = (m) => { + if (m.data && m.data.subject === "service-worker-page-request") { + window.removeEventListener("message", cb); + resolve(m.data.ok); + } + }; + window.addEventListener("message", cb); + }); + } + /** * Get the support server URL that returns a Clear-Site-Data header * to clear |datatypes|.