activation.https.html (6131B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <meta name="timeout" content="long"> 4 <title>service worker: activation</title> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="resources/test-helpers.sub.js"></script> 8 <body> 9 <script> 10 // Returns {registration, iframe}, where |registration| has an active and 11 // waiting worker. The active worker controls |iframe| and has an inflight 12 // message event that can be finished by calling 13 // |registration.active.postMessage('go')|. 14 function setup_activation_test(t, scope, worker_url) { 15 var registration; 16 var iframe; 17 return navigator.serviceWorker.getRegistration(scope) 18 .then(r => { 19 if (r) 20 return r.unregister(); 21 }) 22 .then(() => { 23 // Create an in-scope iframe. Do this prior to registration to avoid 24 // racing between an update triggered by navigation and the update() 25 // call below. 26 return with_iframe(scope); 27 }) 28 .then(f => { 29 iframe = f; 30 // Create an active worker. 31 return navigator.serviceWorker.register(worker_url, { scope: scope }); 32 }) 33 .then(r => { 34 registration = r; 35 add_result_callback(() => registration.unregister()); 36 return wait_for_state(t, r.installing, 'activated'); 37 }) 38 .then(() => { 39 // Check that the frame was claimed. 40 assert_not_equals( 41 iframe.contentWindow.navigator.serviceWorker.controller, null); 42 // Create an in-flight request. 43 registration.active.postMessage('wait'); 44 // Now there is both a controllee and an in-flight request. 45 // Initiate an update. 46 return registration.update(); 47 }) 48 .then(() => { 49 // Wait for a waiting worker. 50 return wait_for_state(t, registration.installing, 'installed'); 51 }) 52 .then(() => { 53 return wait_for_activation_on_sample_scope(t, self); 54 }) 55 .then(() => { 56 assert_not_equals(registration.waiting, null); 57 assert_not_equals(registration.active, null); 58 return Promise.resolve({registration: registration, iframe: iframe}); 59 }); 60 } 61 promise_test(t => { 62 var scope = 'resources/no-controllee'; 63 var worker_url = 'resources/mint-new-worker.py'; 64 var registration; 65 var iframe; 66 var new_worker; 67 return setup_activation_test(t, scope, worker_url) 68 .then(result => { 69 registration = result.registration; 70 iframe = result.iframe; 71 // Finish the in-flight request. 72 registration.active.postMessage('go'); 73 return wait_for_activation_on_sample_scope(t, self); 74 }) 75 .then(() => { 76 // The new worker is still waiting. Remove the frame and it should 77 // activate. 78 new_worker = registration.waiting; 79 assert_equals(new_worker.state, 'installed'); 80 var reached_active = wait_for_state(t, new_worker, 'activating'); 81 iframe.remove(); 82 return reached_active; 83 }) 84 .then(() => { 85 assert_equals(new_worker, registration.active); 86 }); 87 }, 'loss of controllees triggers activation'); 88 promise_test(t => { 89 var scope = 'resources/no-request'; 90 var worker_url = 'resources/mint-new-worker.py'; 91 var registration; 92 var iframe; 93 var new_worker; 94 return setup_activation_test(t, scope, worker_url) 95 .then(result => { 96 registration = result.registration; 97 iframe = result.iframe; 98 // Remove the iframe. 99 iframe.remove(); 100 return new Promise(resolve => setTimeout(resolve, 0)); 101 }) 102 .then(() => { 103 // Finish the request. 104 new_worker = registration.waiting; 105 var reached_active = wait_for_state(t, new_worker, 'activating'); 106 registration.active.postMessage('go'); 107 return reached_active; 108 }) 109 .then(() => { 110 assert_equals(registration.active, new_worker); 111 }); 112 }, 'finishing a request triggers activation'); 113 promise_test(t => { 114 var scope = 'resources/skip-waiting'; 115 var worker_url = 'resources/mint-new-worker.py?skip-waiting'; 116 var registration; 117 var iframe; 118 var new_worker; 119 return setup_activation_test(t, scope, worker_url) 120 .then(result => { 121 registration = result.registration; 122 iframe = result.iframe; 123 // Finish the request. The iframe does not need to be removed because 124 // skipWaiting() was called. 125 new_worker = registration.waiting; 126 var reached_active = wait_for_state(t, new_worker, 'activating'); 127 registration.active.postMessage('go'); 128 return reached_active; 129 }) 130 .then(() => { 131 assert_equals(registration.active, new_worker); 132 // Remove the iframe. 133 iframe.remove(); 134 }); 135 }, 'skipWaiting bypasses no controllee requirement'); 136 137 // This test is not really about activation, but otherwise is very 138 // similar to the other tests here. 139 promise_test(t => { 140 var scope = 'resources/unregister'; 141 var worker_url = 'resources/mint-new-worker.py'; 142 var registration; 143 var iframe; 144 var new_worker; 145 return setup_activation_test(t, scope, worker_url) 146 .then(result => { 147 registration = result.registration; 148 iframe = result.iframe; 149 // Remove the iframe. 150 iframe.remove(); 151 return registration.unregister(); 152 }) 153 .then(() => { 154 // The unregister operation should wait for the active worker to 155 // finish processing its events before clearing the registration. 156 new_worker = registration.waiting; 157 var reached_redundant = wait_for_state(t, new_worker, 'redundant'); 158 registration.active.postMessage('go'); 159 return reached_redundant; 160 }) 161 .then(() => { 162 assert_equals(registration.installing, null); 163 assert_equals(registration.waiting, null); 164 assert_equals(registration.active, null); 165 }); 166 }, 'finishing a request triggers unregister'); 167 </script> 168 </body>