Skip to content

Commit

Permalink
Clear-Site-Data: clients uncontrolled by service workers after storag…
Browse files Browse the repository at this point in the history
…e 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.

w3c/ServiceWorker#614
F2F notes: https://docs.google.com/document/d/1_Qfw5m3BJEaL1xIzTJd41HXjgJ9gq7mroBDXqSJIzic/edit
  • Loading branch information
asakusuma committed Sep 18, 2019
1 parent 4534f63 commit 53b7aff
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 2 deletions.
36 changes: 36 additions & 0 deletions clear-site-data/storage.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
return datatype.name == "storage";
})[0];

var serviceWorkerTestPageIFrame;

// The tests are set up asynchronously.
setup({"explicit_done": true});

Expand All @@ -22,6 +24,28 @@
test(function() {}, "Populate backends.");

TestUtils.populateStorage()
.then(() => {
return navigator.serviceWorker.getRegistration("support/").then(function(reg) {
return TestUtils.waitForServiceWorkerActive(reg);
});
})
.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"
Expand All @@ -45,6 +69,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();
});
});
Expand Down
22 changes: 22 additions & 0 deletions clear-site-data/support/page_using_service_worker.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<title>Clear-Site-Data + Service Workers Test Page</title>
</head>
<body>
<script>
function requestServiceWorkerPage() {
// Make a request to a URL that is only served by the service worker
fetch("sw-page").then(function(result) {
window.top.postMessage({
subject: "service-worker-page-request",
ok: result.ok
}, "*");
});
}
window.addEventListener("message", requestServiceWorkerPage);

requestServiceWorkerPage();
</script>
</body>
</html>
16 changes: 15 additions & 1 deletion clear-site-data/support/service_worker.js
Original file line number Diff line number Diff line change
@@ -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'));
}
});
39 changes: 38 additions & 1 deletion clear-site-data/support/test_utils.sub.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -245,6 +245,43 @@ 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);
});
}

/**
* Returns a promise that resolves when the registration has an active worker
* @param reg The service worker registration object
* @return a promise that resolves when the worker becomes active
* @private
*/
TestUtils.waitForServiceWorkerActive = function(reg) {
return new Promise((resolve) => {
(function pollForControllingWorker() {
if (reg.active && reg.active.state === 'activated') {
resolve();
} else {
step_timeout(() => {
pollForControllingWorker();
}, 100);
}
})();
});
}

/**
* Get the support server URL that returns a Clear-Site-Data header
* to clear |datatypes|.
Expand Down

0 comments on commit 53b7aff

Please sign in to comment.