Index: third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.html |
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..15a2e95bd39d411a2579dd4e0661791cde6d175f |
--- /dev/null |
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-within-sw-manual.html |
@@ -0,0 +1,122 @@ |
+<!DOCTYPE html> |
+<script src="/resources/testharness.js"></script> |
+<script src="/resources/testharnessreport.js"></script> |
+<script src="/common/get-host-info.sub.js"></script> |
+<script src="resources/test-helpers.sub.js"></script> |
+<body> |
+<script> |
+const worker = 'resources/fetch-event-within-sw-worker.js'; |
+ |
+function wait(ms) { |
+ return new Promise(r => setTimeout(r, ms)); |
+} |
+ |
+function reset() { |
+ for (const iframe of [...document.querySelectorAll('.test-iframe')]) { |
+ iframe.remove(); |
+ } |
+ return navigator.serviceWorker.getRegistrations().then(registrations => { |
+ return Promise.all(registrations.map(r => r.unregister())); |
+ }).then(() => caches.keys()).then(cacheKeys => { |
+ return Promise.all(cacheKeys.map(c => caches.delete(c))); |
+ }); |
+} |
+ |
+add_completion_callback(reset); |
+ |
+function regReady(reg) { |
+ return new Promise((resolve, reject) => { |
+ if (reg.active) { |
+ resolve(); |
+ return; |
+ } |
+ const nextWorker = reg.waiting || reg.installing; |
+ |
+ nextWorker.addEventListener('statechange', () => { |
+ if (nextWorker.state == 'redundant') { |
+ reject(Error(`Service worker failed to install`)); |
+ return; |
+ } |
+ if (nextWorker.state == 'activated') { |
+ resolve(); |
+ } |
+ }); |
+ }); |
+} |
+ |
+function getCookies() { |
+ return new Map( |
+ document.cookie |
+ .split(/;/g) |
+ .map(c => c.trim().split('=').map(s => s.trim())) |
+ ); |
+} |
+ |
+function registerSwAndOpenFrame() { |
+ return reset().then(() => navigator.serviceWorker.register(worker, {scope: 'resources/'})) |
+ .then(reg => regReady(reg)) |
+ .then(() => with_iframe('resources/simple.html')); |
+} |
+ |
+function raceBroadcastAndCookie(channel, cookie) { |
+ const initialCookie = getCookies().get(cookie); |
+ let done = false; |
+ |
+ return Promise.race([ |
+ new Promise(resolve => { |
+ const bc = new BroadcastChannel(channel); |
+ bc.onmessage = () => { |
+ bc.close(); |
+ resolve('broadcast'); |
+ }; |
+ }), |
+ (function checkCookie() { |
+ // Stop polling if the broadcast channel won |
+ if (done == true) return; |
+ if (getCookies().get(cookie) != initialCookie) return 'cookie'; |
+ |
+ return wait(200).then(checkCookie); |
+ }()) |
+ ]).then(val => { |
+ done = true; |
+ return val; |
+ }); |
+} |
+ |
+promise_test(() => { |
+ return Notification.requestPermission().then(permission => { |
+ if (permission != "granted") { |
+ throw Error('You must allow notifications for this origin before running this test.'); |
+ } |
+ return registerSwAndOpenFrame(); |
+ }).then(iframe => { |
+ return Promise.resolve().then(() => { |
+ // In this test, the service worker will ping the 'icon-request' channel |
+ // if it intercepts a request for 'notification_icon.py'. If the request |
+ // reaches the server it sets the 'notification' cookie to the value given |
+ // in the URL. "raceBroadcastAndCookie" monitors both and returns which |
+ // happens first. |
+ const race = raceBroadcastAndCookie('icon-request', 'notification'); |
+ const notification = new iframe.contentWindow.Notification('test', { |
+ icon: `notification_icon.py?set-cookie-notification=${Math.random()}` |
+ }); |
+ notification.close(); |
+ |
+ return race.then(winner => { |
+ assert_equals(winner, 'broadcast', 'The service worker intercepted the from-window notification icon request'); |
+ }); |
+ }).then(() => { |
+ // Similar race to above, but this time the service worker requests the |
+ // notification. |
+ const race = raceBroadcastAndCookie('icon-request', 'notification'); |
+ iframe.contentWindow.fetch(`show-notification?set-cookie-notification=${Math.random()}`); |
+ |
+ return race.then(winner => { |
+ assert_equals(winner, 'broadcast', 'The service worker intercepted the from-service-worker notification icon request'); |
+ }); |
+ }) |
+ }); |
+}, `Notification requests intercepted both from window and SW`); |
+ |
+</script> |
+</body> |