non-fully-active.https.html (3844B)
1 <!DOCTYPE html> 2 <meta charset="utf-8" /> 3 <title>Geolocation Test: non-fully active document</title> 4 <link rel="help" href="https://github.com/w3c/permissions/pull/365" /> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script src="/resources/testdriver.js"></script> 8 <script src="/resources/testdriver-vendor.js"></script> 9 <body></body> 10 <script> 11 // Creates the iframe, wait for it to load... 12 async function attachIframe() { 13 const iframe = document.createElement("iframe"); 14 await new Promise((resolve) => { 15 iframe.src = "resources/empty.html"; 16 iframe.addEventListener("load", resolve, { once: true }); 17 document.body.appendChild(iframe); 18 }); 19 return iframe; 20 } 21 22 promise_test(async (t) => { 23 const iframe = await attachIframe(); 24 25 // Steal the needed references 26 const { permissions } = iframe.contentWindow.navigator; 27 const TypeErrorCtor = iframe.contentWindow.TypeError; 28 const DOMExceptionCtor = iframe.contentWindow.DOMException; 29 30 // Let's check that ordering is correct. 31 await promise_rejects_js( 32 t, 33 TypeErrorCtor, 34 permissions.query({ name: "xxxxx-not-supported" }), 35 "query() should reject if the feature is not supported" 36 ); 37 38 // no longer fully active, let's try that again... 39 iframe.remove(); 40 41 // Now, let's try with Geolocation as it's supported by all browsers. 42 await promise_rejects_dom( 43 t, 44 "InvalidStateError", 45 DOMExceptionCtor, 46 permissions.query({ name: "whatever" }), 47 "must reject in the right global when the document is not fully active" 48 ); 49 50 // Re-attach, and go back to fully active. 51 document.body.appendChild(iframe); 52 await new Promise((resolve) => 53 iframe.addEventListener("load", resolve, { once: true }) 54 ); 55 56 // And we are back to fully active, so this should not reject. 57 const status = await iframe.contentWindow.navigator.permissions.query({ 58 name: "geolocation", 59 }); 60 assert_equals(status.name, "geolocation"); 61 iframe.remove(); 62 }, "Trying to query() a non-fully active document rejects with a InvalidStateError"); 63 64 promise_test(async (t) => { 65 // Create the iframe, wait for it to load... 66 const iframe = await attachIframe(); 67 68 // Get the status 69 const initialStatus = 70 await iframe.contentWindow.navigator.permissions.query({ 71 name: "geolocation", 72 }); 73 74 assert_true("onchange" in initialStatus, "onchange is supported"); 75 76 // Let's check events are firing... 77 await new Promise(async (resolve) => { 78 const newState = initialStatus.state === "prompt" ? "denied" : "granted"; 79 initialStatus.addEventListener("change", resolve, { once: true }); 80 await test_driver.set_permission({ name: "geolocation" }, newState); 81 }); 82 83 // No longer fully active... 84 iframe.remove(); 85 86 await new Promise(async (resolve, reject) => { 87 // Gets dropped on the floor. 88 initialStatus.addEventListener("change", reject, { once: true }); 89 await test_driver.set_permission({ name: "geolocation" }, "prompt"); 90 // Try to force it synthetically. This would trigger the event synchronously. 91 initialStatus.dispatchEvent(new Event("change")); 92 resolve(); 93 }); 94 95 // Re-attach, and go back to fully active. 96 document.body.appendChild(iframe); 97 await new Promise((resolve) => 98 iframe.addEventListener("load", resolve, { once: true }) 99 ); 100 101 // Finally, let's recheck that permission state. 102 const finalStatus = await iframe.contentWindow.navigator.permissions.query({ 103 name: "geolocation", 104 }); 105 assert_equals(finalStatus.state, "prompt", "expected prompt state"); 106 iframe.remove(); 107 }, "Permission change events shouldn't fire on non-fully active document"); 108 </script>