test_unresolved_fetch_interception.html (3814B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 Test that an unresolved respondWith promise will reset the channel when 5 the service worker is terminated due to idling, and that appropriate error 6 messages are logged for both the termination of the serice worker and the 7 resetting of the channel. 8 --> 9 <head> 10 <title>Test for Bug 1188545</title> 11 <script src="/tests/SimpleTest/SimpleTest.js"></script> 12 <script src="error_reporting_helpers.js"></script> 13 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 14 <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> 15 </head> 16 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1188545">Mozilla Bug 118845</a> 17 <p id="display"></p> 18 <div id="content" style="display: none"> 19 20 </div> 21 <pre id="test"> 22 </pre> 23 24 <script src="utils.js"></script> 25 <script class="testbody" type="text/javascript"> 26 // (This doesn't really need to be its own task, but it allows the actual test 27 // case to be self-contained.) 28 add_task(function setupPrefs() { 29 return SpecialPowers.pushPrefEnv({"set": [ 30 ["dom.serviceWorkers.enabled", true], 31 ["dom.serviceWorkers.testing.enabled", true], 32 ]}); 33 }); 34 35 add_task(async function grace_timeout_termination_with_interrupted_intercept() { 36 // Setup timeouts so that the service worker will go into grace timeout after 37 // a zero-length idle timeout. 38 await SpecialPowers.pushPrefEnv({"set": [ 39 ["dom.serviceWorkers.idle_timeout", 0], 40 ["dom.serviceWorkers.idle_extended_timeout", 299999]]}); 41 42 let registration = await navigator.serviceWorker.register( 43 "unresolved_fetch_worker.js", { scope: "./"} ); 44 await waitForState(registration.installing, "activated"); 45 ok(navigator.serviceWorker.controller, "Controlled"); // double check! 46 47 // We want to make sure the SW is active and processing the fetch before we 48 // try and kill it. It sends us a message when it has done so. 49 let waitForFetchActive = new Promise((resolve) => { 50 navigator.serviceWorker.onmessage = resolve; 51 }); 52 53 // Issue a fetch which the SW will respondWith() a never resolved promise. 54 // The fetch, however, will terminate when the SW is killed, so check that. 55 let hangingFetch = fetch("does_not_exist.html") 56 .then(() => { ok(false, "should have rejected "); }, 57 () => { ok(true, "hung fetch terminates when worker dies"); }); 58 59 await waitForFetchActive; 60 61 let expectedMessage = expect_console_message( 62 // Termination error 63 "ServiceWorkerGraceTimeoutTermination", 64 [make_absolute_url("./")], 65 // The interception failure error generated by the RespondWithHandler 66 // destructor when it notices it didn't get a response before being 67 // destroyed. It logs via the intercepted channel nsIConsoleReportCollector 68 // that is eventually flushed to our document and its console. 69 "InterceptionFailedWithURL", 70 [make_absolute_url("does_not_exist.html")] 71 ); 72 73 // Zero out the grace timeout too so the worker will get terminated after two 74 // zero-length timer firings. Note that we need to do something to get the 75 // SW to renew its keepalive for this to actually cause the timers to be 76 // rescheduled... 77 await SpecialPowers.pushPrefEnv({"set": [ 78 ["dom.serviceWorkers.idle_extended_timeout", 0]]}); 79 // ...which we do by postMessaging it. 80 navigator.serviceWorker.controller.postMessage("doomity doom doom"); 81 82 // Now wait for signs that the worker was terminated by the fetch failing. 83 await hangingFetch; 84 85 // The worker should now be dead and the error logged, wait/assert. 86 await wait_for_expected_message(expectedMessage); 87 88 // roll back all of our test case specific preferences and otherwise cleanup 89 await SpecialPowers.popPrefEnv(); 90 await SpecialPowers.popPrefEnv(); 91 await registration.unregister(); 92 }); 93 </script> 94 </body> 95 </html>