MediaDevices-after-discard.https.html (2914B)
1 <!doctype html> 2 <title>Test promises from MediaDevices methods in a discarded browsing 3 context</title> 4 <script src=/resources/testharness.js></script> 5 <script src=/resources/testharnessreport.js></script> 6 <script src=/resources/testdriver.js></script> 7 <script src=/resources/testdriver-vendor.js></script> 8 <script src=permission-helper.js></script> 9 <body></body> 10 <script> 11 let devices; 12 let child_DOMException; 13 setup(() => { 14 const frame = document.createElement('iframe'); 15 document.body.appendChild(frame); 16 devices = frame.contentWindow.navigator.mediaDevices; 17 child_DOMException = frame.contentWindow.DOMException; 18 frame.remove(); 19 }); 20 21 // https://w3c.github.io/mediacapture-main/#dom-mediadevices-getusermedia 22 // If the current settings object's responsible document is NOT fully active, 23 // return a promise rejected with a DOMException object whose name attribute 24 // has the value "InvalidStateError". 25 promise_test(async () => { 26 await setMediaPermission("granted", ["microphone"]); 27 // `catch()` is used rather than static Promise methods because microtasks 28 // for `PromiseResolve()` do not run when Promises in inactive Documents are 29 // involved. Whether microtasks for `catch()` run depends on the realm of 30 // the handler rather than the realm of the Promise. 31 // See https://github.com/whatwg/html/issues/5319. 32 let promise_already_rejected = false; 33 let rejected_reason; 34 devices.getUserMedia({audio:true}).catch(reason => { 35 promise_already_rejected = true; 36 rejected_reason = reason; 37 }); 38 // Race a settled promise to check that the returned promise is already 39 // rejected. 40 await Promise.reject().catch(() => { 41 assert_true(promise_already_rejected, 42 'should have returned an already-rejected promise.'); 43 assert_throws_dom('InvalidStateError', child_DOMException, 44 () => { throw rejected_reason }); 45 }); 46 }, 'getUserMedia() in a discarded browsing context'); 47 48 // https://w3c.github.io/mediacapture-main/#dom-mediadevices-enumeratedevices 49 // https://w3c.github.io/mediacapture-main/#device-enumeration-can-proceed 50 // Device enumeration can proceed steps return false when device enumeration 51 // can be exposed is true and the document is not fully active. 52 promise_test(async () => { 53 let promise_state = 'pending'; 54 // `then()` is used to avoid methods that apply `PromiseResolve()` to 55 // Promises from inactive realms, which would lead to microtasks that don't 56 // run. 57 devices.enumerateDevices().then(() => promise_state = 'resolved', 58 () => promise_state = 'rejected'); 59 // Enumerate in the parent document to provide enough time to check that the 60 // Promise from the inactive document does not settle. 61 await navigator.mediaDevices.enumerateDevices(); 62 assert_equals(promise_state, 'pending', 'Promise state'); 63 }, 'enumerateDevices() in a discarded browsing context'); 64 </script>