test_error_reporting.html (8395B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test Error Reporting of Service Worker Failures</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script src="error_reporting_helpers.js"></script> 7 <script src="utils.js"></script> 8 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> 9 <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> 10 </head> 11 <body> 12 13 <script type="text/javascript"> 14 "use strict"; 15 16 /** 17 * Test that a bunch of service worker coding errors and failure modes that 18 * might otherwise be hard to diagnose are surfaced as console error messages. 19 * The driving use-case is minimizing cursing from a developer looking at a 20 * document in Firefox testing a page that involves service workers. 21 * 22 * This test assumes that errors will be reported via 23 * ServiceWorkerManager::ReportToAllClients and that that method is reliable and 24 * tested via some other file. 25 */ 26 27 add_task(function setupPrefs() { 28 return SpecialPowers.pushPrefEnv({"set": [ 29 ["dom.serviceWorkers.enabled", true], 30 ["dom.serviceWorkers.testing.enabled", true], 31 ["dom.caches.testing.enabled", true], 32 ]}); 33 }); 34 35 /** 36 * Ensure an error is logged during the initial registration of a SW when a 404 37 * is received. 38 */ 39 add_task(async function register_404() { 40 // Start monitoring for the error 41 let expectedMessage = expect_console_message( 42 "ServiceWorkerRegisterNetworkError", 43 [make_absolute_url("network_error/"), "404", make_absolute_url("404.js")]); 44 45 // Register, generating the 404 error. This will reject with a TypeError 46 // which we need to consume so it doesn't get thrown at our generator. 47 await navigator.serviceWorker.register("404.js", { scope: "network_error/" }) 48 .then( 49 () => { ok(false, "should have rejected"); }, 50 (e) => { ok(e.name === "TypeError", "404 failed as expected"); }); 51 52 await wait_for_expected_message(expectedMessage); 53 }); 54 55 /** 56 * Ensure an error is logged when the service worker is being served with a 57 * MIME type of text/plain rather than a JS type. 58 */ 59 add_task(async function register_bad_mime_type() { 60 let expectedMessage = expect_console_message( 61 "ServiceWorkerRegisterMimeTypeError2", 62 [make_absolute_url("bad_mime_type/"), "text/plain", 63 make_absolute_url("sw_bad_mime_type.js")]); 64 65 // consume the expected rejection so it doesn't get thrown at us. 66 await navigator.serviceWorker.register("sw_bad_mime_type.js", { scope: "bad_mime_type/" }) 67 .then( 68 () => { ok(false, "should have rejected"); }, 69 (e) => { ok(e.name === "SecurityError", "bad MIME type failed as expected"); }); 70 71 await wait_for_expected_message(expectedMessage); 72 }); 73 74 async function notAllowStorageAccess() { 75 throw new Error("Storage permissions should be used when bug 1774860 overhauls this test."); 76 } 77 78 async function allowStorageAccess() { 79 throw new Error("Storage permissions should be used when bug 1774860 overhauls this test."); 80 } 81 82 /** 83 * Ensure an error is logged when the storage is not allowed and the content 84 * script is trying to register a service worker. 85 */ 86 add_task(async function register_storage_error() { 87 let expectedMessage = expect_console_message( 88 "ServiceWorkerRegisterStorageError", 89 [make_absolute_url("storage_not_allow/")]); 90 91 await notAllowStorageAccess(); 92 93 // consume the expected rejection so it doesn't get thrown at us. 94 await navigator.serviceWorker.register("sw_storage_not_allow.js", 95 { scope: "storage_not_allow/" }) 96 .then( 97 () => { ok(false, "should have rejected"); }, 98 (e) => { ok(e.name === "SecurityError", 99 "storage access failed as expected."); }); 100 101 await wait_for_expected_message(expectedMessage); 102 103 await allowStorageAccess(); 104 }); 105 106 /** 107 * Ensure an error is logged when the storage is not allowed and the content 108 * script is trying to get the service worker registration. 109 */ 110 add_task(async function get_registration_storage_error() { 111 let expectedMessage = 112 expect_console_message("ServiceWorkerGetRegistrationStorageError", []); 113 114 await notAllowStorageAccess(); 115 116 // consume the expected rejection so it doesn't get thrown at us. 117 await navigator.serviceWorker.getRegistration() 118 .then( 119 () => { ok(false, "should have rejected"); }, 120 (e) => { ok(e.name === "SecurityError", 121 "storage access failed as expected."); }); 122 123 await wait_for_expected_message(expectedMessage); 124 125 await allowStorageAccess(); 126 }); 127 128 /** 129 * Ensure an error is logged when the storage is not allowed and the content 130 * script is trying to get the service worker registrations. 131 */ 132 add_task(async function get_registrations_storage_error() { 133 let expectedMessage = 134 expect_console_message("ServiceWorkerGetRegistrationStorageError", []); 135 136 await notAllowStorageAccess(); 137 138 // consume the expected rejection so it doesn't get thrown at us. 139 await navigator.serviceWorker.getRegistrations() 140 .then( 141 () => { ok(false, "should have rejected"); }, 142 (e) => { ok(e.name === "SecurityError", 143 "storage access failed as expected."); }); 144 145 await wait_for_expected_message(expectedMessage); 146 147 await allowStorageAccess(); 148 }); 149 150 /** 151 * Ensure an error is logged when the storage is not allowed and the content 152 * script is trying to post a message to the service worker. 153 */ 154 add_task(async function postMessage_storage_error() { 155 let expectedMessage = expect_console_message( 156 "ServiceWorkerPostMessageStorageError", 157 [make_absolute_url("storage_not_allow/")]); 158 159 let registration; 160 // consume the expected rejection so it doesn't get thrown at us. 161 await navigator.serviceWorker.register("sw_storage_not_allow.js", 162 { scope: "storage_not_allow/" }) 163 .then(reg => { registration = reg; }) 164 .then(() => notAllowStorageAccess()) 165 .then(() => registration.installing || 166 registration.waiting || 167 registration.active) 168 .then(worker => worker.postMessage('ha')) 169 .then( 170 () => { ok(false, "should have rejected"); }, 171 (e) => { ok(e.name === "SecurityError", 172 "storage access failed as expected."); }); 173 174 await wait_for_expected_message(expectedMessage); 175 176 await registration.unregister(); 177 await allowStorageAccess(); 178 }); 179 180 /** 181 * Ensure an error is logged when the storage is not allowed and the service 182 * worker is trying to get its client. 183 */ 184 add_task(async function get_client_storage_error() { 185 let expectedMessage = 186 expect_console_message("ServiceWorkerGetClientStorageError", []); 187 188 await SpecialPowers.pushPrefEnv({"set": [ 189 // Make the test pass the IsOriginPotentiallyTrustworthy. 190 ["dom.securecontext.allowlist", "mochi.test"] 191 ]}); 192 193 let registration; 194 // consume the expected rejection so it doesn't get thrown at us. 195 await navigator.serviceWorker.register("sw_storage_not_allow.js", 196 { scope: "test_error_reporting.html" }) 197 .then(reg => { 198 registration = reg; 199 return waitForState(registration.installing, "activated"); 200 }) 201 // Get the client's ID in the stage 1 202 .then(() => fetch("getClient-stage1")) 203 .then(() => notAllowStorageAccess()) 204 // Trigger the clients.get() in the stage 2 205 .then(() => fetch("getClient-stage2")) 206 .catch(e => ok(false, "fail due to:" + e)); 207 208 await wait_for_expected_message(expectedMessage); 209 210 await registration.unregister(); 211 await allowStorageAccess(); 212 }); 213 214 /** 215 * Ensure an error is logged when the storage is not allowed and the service 216 * worker is trying to get its clients. 217 */ 218 add_task(async function get_clients_storage_error() { 219 let expectedMessage = 220 expect_console_message("ServiceWorkerGetClientStorageError", []); 221 222 let registration; 223 // consume the expected rejection so it doesn't get thrown at us. 224 await navigator.serviceWorker.register("sw_storage_not_allow.js", 225 { scope: "test_error_reporting.html" }) 226 .then(reg => { 227 registration = reg; 228 return waitForState(registration.installing, "activated"); 229 }) 230 .then(() => notAllowStorageAccess()) 231 .then(() => fetch("getClients")) 232 .catch(e => ok(false, "fail due to:" + e)); 233 234 await wait_for_expected_message(expectedMessage); 235 236 await registration.unregister(); 237 await allowStorageAccess(); 238 }); 239 </script> 240 </body> 241 </html>