test_installation_simple.html (7347B)
1 <!-- 2 Any copyright is dedicated to the Public Domain. 3 http://creativecommons.org/publicdomain/zero/1.0/ 4 --> 5 <!DOCTYPE HTML> 6 <html> 7 <head> 8 <title>Bug 930348 - test stub Navigator ServiceWorker utilities.</title> 9 <script src="/tests/SimpleTest/SimpleTest.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 11 </head> 12 <body> 13 <p id="display"></p> 14 <div id="content" style="display: none"></div> 15 <pre id="test"></pre> 16 <script class="testbody" type="text/javascript"> 17 18 function simpleRegister() { 19 var p = navigator.serviceWorker.register("worker.js", { scope: "simpleregister/" }); 20 ok(p instanceof Promise, "register() should return a Promise"); 21 return Promise.resolve(); 22 } 23 24 function sameOriginWorker() { 25 p = navigator.serviceWorker.register("http://some-other-origin/worker.js"); 26 return p.then(function(w) { 27 ok(false, "Worker from different origin should fail"); 28 }, function(e) { 29 ok(e.name === "SecurityError", "Should fail with a SecurityError"); 30 }); 31 } 32 33 function sameOriginScope() { 34 p = navigator.serviceWorker.register("worker.js", { scope: "http://www.example.com/" }); 35 return p.then(function(w) { 36 ok(false, "Worker controlling scope for different origin should fail"); 37 }, function(e) { 38 ok(e.name === "SecurityError", "Should fail with a SecurityError"); 39 }); 40 } 41 42 function httpsOnly() { 43 return SpecialPowers.pushPrefEnv({'set': [["dom.serviceWorkers.testing.enabled", false]] }) 44 .then(function() { 45 return navigator.serviceWorker.register("/worker.js"); 46 }).then(function(w) { 47 ok(false, "non-HTTPS pages cannot register ServiceWorkers"); 48 }, function(e) { 49 ok(e.name === "TypeError", "navigator.serviceWorker should be undefined"); 50 }).then(function() { 51 return SpecialPowers.popPrefEnv(); 52 }); 53 } 54 55 function realWorker() { 56 var p = navigator.serviceWorker.register("worker.js", { scope: "realworker" }); 57 return p.then(function(wr) { 58 ok(wr instanceof ServiceWorkerRegistration, "Register a ServiceWorker"); 59 60 info(wr.scope); 61 ok(wr.scope == (new URL("realworker", document.baseURI)).href, "Scope should match"); 62 // active, waiting, installing should return valid worker instances 63 // because the registration is for the realworker scope, so the workers 64 // should be obtained for that scope and not for 65 // test_installation_simple.html 66 var worker = wr.installing; 67 ok(worker && wr.scope.match(/realworker$/) && 68 worker.scriptURL.match(/worker.js$/), "Valid worker instance should be available."); 69 return wr.unregister().then(function(success) { 70 ok(success, "The worker should be unregistered successfully"); 71 }, function(e) { 72 dump("Error unregistering the worker: " + e + "\n"); 73 }); 74 }, function(e) { 75 info("Error: " + e.name); 76 ok(false, "realWorker Registration should have succeeded!"); 77 }); 78 } 79 80 function networkError404() { 81 return navigator.serviceWorker.register("404.js", { scope: "network_error/"}).then(function(w) { 82 ok(false, "404 response should fail with TypeError"); 83 }, function(e) { 84 ok(e.name === "TypeError", "404 response should fail with TypeError"); 85 }); 86 } 87 88 function redirectError() { 89 return navigator.serviceWorker.register("redirect_serviceworker.sjs", { scope: "redirect_error/" }).then(function(swr) { 90 ok(false, "redirection should fail"); 91 }, function (e) { 92 ok(e.name === "SecurityError", "redirection should fail with SecurityError"); 93 }); 94 } 95 96 function parseError() { 97 var p = navigator.serviceWorker.register("parse_error_worker.js", { scope: "parse_error/" }); 98 return p.then(function(wr) { 99 ok(false, "Registration should fail with parse error"); 100 return navigator.serviceWorker.getRegistration("parse_error/").then(function(swr) { 101 // See https://github.com/slightlyoff/ServiceWorker/issues/547 102 is(swr, undefined, "A failed registration for a scope with no prior controllers should clear itself"); 103 }); 104 }, function(e) { 105 ok(e instanceof Error, "Registration should fail with parse error"); 106 }); 107 } 108 109 // FIXME(nsm): test for parse error when Update step doesn't happen (directly from register). 110 111 function updatefound() { 112 var frame = document.createElement("iframe"); 113 frame.setAttribute("id", "simpleregister-frame"); 114 frame.setAttribute("src", new URL("simpleregister/index.html", document.baseURI).href); 115 document.body.appendChild(frame); 116 var resolve, reject; 117 var p = new Promise(function(res, rej) { 118 resolve = res; 119 reject = rej; 120 }); 121 122 var regPromise; 123 function continueTest() { 124 regPromise = navigator.serviceWorker.register( 125 "worker2.js", { scope: "simpleregister/" }); 126 } 127 128 window.onmessage = function(e) { 129 if (e.data.type == "ready") { 130 continueTest(); 131 } else if (e.data.type == "finish") { 132 window.onmessage = null; 133 // We have to make frame navigate away, otherwise it will call 134 // MaybeStopControlling() when this document is unloaded. At that point 135 // the pref has been disabled, so the ServiceWorkerManager is not available. 136 frame.setAttribute("src", new URL("about:blank").href); 137 regPromise.then(function(reg) { 138 reg.unregister().then(function(success) { 139 ok(success, "The worker should be unregistered successfully"); 140 resolve(); 141 }, function(error) { 142 dump("Error unregistering the worker: " + error + "\n"); 143 }); 144 }); 145 } else if (e.data.type == "check") { 146 ok(e.data.status, e.data.msg); 147 } 148 } 149 return p; 150 } 151 152 var readyPromiseResolved = false; 153 154 function readyPromise() { 155 var frame = document.createElement("iframe"); 156 frame.setAttribute("id", "simpleregister-frame-ready"); 157 frame.setAttribute("src", new URL("simpleregister/ready.html", document.baseURI).href); 158 document.body.appendChild(frame); 159 160 var channel = new MessageChannel(); 161 frame.addEventListener('load', function() { 162 frame.contentWindow.postMessage('your port!', '*', [channel.port2]); 163 }); 164 165 channel.port1.onmessage = function() { 166 readyPromiseResolved = true; 167 } 168 169 return Promise.resolve(); 170 } 171 172 function checkReadyPromise() { 173 ok(readyPromiseResolved, "The ready promise has been resolved!"); 174 return Promise.resolve(); 175 } 176 177 function runTest() { 178 simpleRegister() 179 .then(sameOriginWorker) 180 .then(sameOriginScope) 181 .then(httpsOnly) 182 .then(readyPromise) 183 .then(realWorker) 184 .then(networkError404) 185 .then(redirectError) 186 .then(parseError) 187 .then(updatefound) 188 .then(checkReadyPromise) 189 // put more tests here. 190 .then(function() { 191 SimpleTest.finish(); 192 }).catch(function(e) { 193 ok(false, "Some test failed with error " + e); 194 SimpleTest.finish(); 195 }); 196 } 197 198 SimpleTest.waitForExplicitFinish(); 199 SpecialPowers.pushPrefEnv({"set": [ 200 ["dom.serviceWorkers.exemptFromPerDomainMax", true], 201 ["dom.serviceWorkers.enabled", true], 202 ["dom.serviceWorkers.testing.enabled", true], 203 ["dom.caches.testing.enabled", true], 204 ]}, runTest); 205 </script> 206 </pre> 207 </body> 208 </html>