OLD | NEW |
(Empty) | |
| 1 <!DOCTYPE html> |
| 2 <script src="/resources/testharness.js"></script> |
| 3 <script src="/resources/testharnessreport.js"></script> |
| 4 <script src="/common/get-host-info.sub.js"></script> |
| 5 <script src="resources/test-helpers.sub.js"></script> |
| 6 <body> |
| 7 <script> |
| 8 const worker = 'resources/fetch-event-within-sw-worker.js'; |
| 9 |
| 10 function wait(ms) { |
| 11 return new Promise(r => setTimeout(r, ms)); |
| 12 } |
| 13 |
| 14 function reset() { |
| 15 for (const iframe of [...document.querySelectorAll('.test-iframe')]) { |
| 16 iframe.remove(); |
| 17 } |
| 18 return navigator.serviceWorker.getRegistrations().then(registrations => { |
| 19 return Promise.all(registrations.map(r => r.unregister())); |
| 20 }).then(() => caches.keys()).then(cacheKeys => { |
| 21 return Promise.all(cacheKeys.map(c => caches.delete(c))); |
| 22 }); |
| 23 } |
| 24 |
| 25 add_completion_callback(reset); |
| 26 |
| 27 function regReady(reg) { |
| 28 return new Promise((resolve, reject) => { |
| 29 if (reg.active) { |
| 30 resolve(); |
| 31 return; |
| 32 } |
| 33 const nextWorker = reg.waiting || reg.installing; |
| 34 |
| 35 nextWorker.addEventListener('statechange', () => { |
| 36 if (nextWorker.state == 'redundant') { |
| 37 reject(Error(`Service worker failed to install`)); |
| 38 return; |
| 39 } |
| 40 if (nextWorker.state == 'activated') { |
| 41 resolve(); |
| 42 } |
| 43 }); |
| 44 }); |
| 45 } |
| 46 |
| 47 function getCookies() { |
| 48 return new Map( |
| 49 document.cookie |
| 50 .split(/;/g) |
| 51 .map(c => c.trim().split('=').map(s => s.trim())) |
| 52 ); |
| 53 } |
| 54 |
| 55 function registerSwAndOpenFrame() { |
| 56 return reset().then(() => navigator.serviceWorker.register(worker, {scope: 're
sources/'})) |
| 57 .then(reg => regReady(reg)) |
| 58 .then(() => with_iframe('resources/simple.html')); |
| 59 } |
| 60 |
| 61 function raceBroadcastAndCookie(channel, cookie) { |
| 62 const initialCookie = getCookies().get(cookie); |
| 63 let done = false; |
| 64 |
| 65 return Promise.race([ |
| 66 new Promise(resolve => { |
| 67 const bc = new BroadcastChannel(channel); |
| 68 bc.onmessage = () => { |
| 69 bc.close(); |
| 70 resolve('broadcast'); |
| 71 }; |
| 72 }), |
| 73 (function checkCookie() { |
| 74 // Stop polling if the broadcast channel won |
| 75 if (done == true) return; |
| 76 if (getCookies().get(cookie) != initialCookie) return 'cookie'; |
| 77 |
| 78 return wait(200).then(checkCookie); |
| 79 }()) |
| 80 ]).then(val => { |
| 81 done = true; |
| 82 return val; |
| 83 }); |
| 84 } |
| 85 |
| 86 promise_test(() => { |
| 87 return Notification.requestPermission().then(permission => { |
| 88 if (permission != "granted") { |
| 89 throw Error('You must allow notifications for this origin before running t
his test.'); |
| 90 } |
| 91 return registerSwAndOpenFrame(); |
| 92 }).then(iframe => { |
| 93 return Promise.resolve().then(() => { |
| 94 // In this test, the service worker will ping the 'icon-request' channel |
| 95 // if it intercepts a request for 'notification_icon.py'. If the request |
| 96 // reaches the server it sets the 'notification' cookie to the value given |
| 97 // in the URL. "raceBroadcastAndCookie" monitors both and returns which |
| 98 // happens first. |
| 99 const race = raceBroadcastAndCookie('icon-request', 'notification'); |
| 100 const notification = new iframe.contentWindow.Notification('test', { |
| 101 icon: `notification_icon.py?set-cookie-notification=${Math.random()}` |
| 102 }); |
| 103 notification.close(); |
| 104 |
| 105 return race.then(winner => { |
| 106 assert_equals(winner, 'broadcast', 'The service worker intercepted the f
rom-window notification icon request'); |
| 107 }); |
| 108 }).then(() => { |
| 109 // Similar race to above, but this time the service worker requests the |
| 110 // notification. |
| 111 const race = raceBroadcastAndCookie('icon-request', 'notification'); |
| 112 iframe.contentWindow.fetch(`show-notification?set-cookie-notification=${Ma
th.random()}`); |
| 113 |
| 114 return race.then(winner => { |
| 115 assert_equals(winner, 'broadcast', 'The service worker intercepted the f
rom-service-worker notification icon request'); |
| 116 }); |
| 117 }) |
| 118 }); |
| 119 }, `Notification requests intercepted both from window and SW`); |
| 120 |
| 121 </script> |
| 122 </body> |
OLD | NEW |