getdisplaymedia-capture-controller.https.window.js (7992B)
1 // META: script=/resources/testdriver.js 2 // META: script=/resources/testdriver-vendor.js 3 // META: timeout=long 4 5 'use strict'; 6 7 const validFocusBehaviors = [ 8 'focus-capturing-application', 'focus-captured-surface', 'no-focus-change' 9 ]; 10 const validDisplaySurfaces = ['window', 'browser']; 11 12 test(() => { 13 assert_own_property(window, 'CaptureController'); 14 }, 'CaptureController in window'); 15 16 const stopTracks = stream => stream.getTracks().forEach(track => track.stop()); 17 18 validFocusBehaviors.forEach( 19 (focusBehavior) => test( 20 (t) => { 21 const controller = new CaptureController(); 22 controller.setFocusBehavior(focusBehavior); 23 }, 24 `setFocusBehavior("${ 25 focusBehavior}") must succeed before capture starts`)); 26 27 ['invalid', null, undefined, {}, true].forEach( 28 (focusBehavior) => test( 29 () => { 30 const controller = new CaptureController(); 31 assert_throws_js( 32 TypeError, () => controller.setFocusBehavior(focusBehavior)); 33 }, 34 `setFocusBehavior("${ 35 focusBehavior}") must throw TypeError if focusBehavior is invalid`)); 36 37 promise_test(async (t) => { 38 const controller = new CaptureController(); 39 await test_driver.bless('getDisplayMedia()'); 40 const stream = await navigator.mediaDevices.getDisplayMedia({controller}); 41 t.add_cleanup(() => stopTracks(stream)); 42 assert_equals(stream.getTracks().length, 1); 43 assert_equals(stream.getVideoTracks().length, 1); 44 assert_equals(stream.getAudioTracks().length, 0); 45 }, 'getDisplayMedia({controller}) must succeed'); 46 47 ['invalid', null, {}, true].forEach( 48 (controller) => promise_test( 49 async (t) => { 50 await test_driver.bless('getDisplayMedia()'); 51 await promise_rejects_js( 52 t, TypeError, 53 navigator.mediaDevices.getDisplayMedia({controller})); 54 }, 55 `getDisplayMedia({controller: ${ 56 controller}}) must fail with TypeError`)); 57 58 promise_test(async (t) => { 59 const controller = new CaptureController(); 60 61 await test_driver.bless('getDisplayMedia()'); 62 const stream = await navigator.mediaDevices.getDisplayMedia({controller}); 63 t.add_cleanup(() => stopTracks(stream)); 64 65 await test_driver.bless('getDisplayMedia()'); 66 const p = navigator.mediaDevices.getDisplayMedia({controller}); 67 t.add_cleanup(async () => { 68 try { 69 stopTracks(await p); 70 } catch { 71 } 72 }); 73 await promise_rejects_dom( 74 t, 'InvalidStateError', Promise.race([p, Promise.resolve()]), 75 'getDisplayMedia should have returned an already-rejected promise.'); 76 }, 'getDisplayMedia({controller}) must fail with InvalidStateError if controller is bound'); 77 78 validDisplaySurfaces.forEach((displaySurface) => { 79 validFocusBehaviors.forEach( 80 (focusBehavior) => promise_test( 81 async (t) => { 82 const controller = new CaptureController(); 83 await test_driver.bless('getDisplayMedia()'); 84 const stream = await navigator.mediaDevices.getDisplayMedia( 85 {controller, video: {displaySurface}}); 86 t.add_cleanup(() => stopTracks(stream)); 87 controller.setFocusBehavior(focusBehavior); 88 }, 89 `setFocusBehavior("${ 90 focusBehavior}") must succeed when window of opportunity is opened if capturing a ${ 91 displaySurface}`)); 92 }); 93 94 validDisplaySurfaces.forEach((displaySurface) => { 95 validFocusBehaviors.forEach( 96 (focusBehavior) => promise_test( 97 async (t) => { 98 const controller = new CaptureController(); 99 await test_driver.bless('getDisplayMedia()'); 100 const p = navigator.mediaDevices.getDisplayMedia( 101 {controller, video: {displaySurface}}); 102 controller.setFocusBehavior(focusBehavior); 103 const stream = await p; 104 t.add_cleanup(() => stopTracks(stream)); 105 }, 106 `setFocusBehavior("${ 107 focusBehavior}") must succeed when getDisplayMedia promise is pending if capturing a ${ 108 displaySurface}`)); 109 }); 110 111 validDisplaySurfaces.forEach((displaySurface) => { 112 validFocusBehaviors.forEach( 113 (focusBehavior) => promise_test( 114 async (t) => { 115 const controller = new CaptureController(); 116 await test_driver.bless('getDisplayMedia()'); 117 const stream = await navigator.mediaDevices.getDisplayMedia( 118 {controller, video: {displaySurface}}); 119 stopTracks(stream); 120 assert_throws_dom( 121 'InvalidStateError', 122 () => controller.setFocusBehavior(focusBehavior)); 123 }, 124 `setFocusBehavior("${ 125 focusBehavior}") must throw InvalidStateError when track is stopped if capturing a ${ 126 displaySurface}`)); 127 }); 128 129 validFocusBehaviors.forEach( 130 (focusBehavior) => promise_test( 131 async (t) => { 132 const controller = new CaptureController(); 133 await test_driver.bless('getDisplayMedia()'); 134 const stream = await navigator.mediaDevices.getDisplayMedia( 135 {controller, video: {displaySurface: 'monitor'}}); 136 t.add_cleanup(() => stopTracks(stream)); 137 assert_throws_dom( 138 'InvalidStateError', 139 () => controller.setFocusBehavior(focusBehavior)); 140 }, 141 `setFocusBehavior("${ 142 focusBehavior}") must throw InvalidStateError if capturing a monitor`)); 143 144 validDisplaySurfaces.forEach((displaySurface) => { 145 validFocusBehaviors.forEach( 146 (focusBehavior) => promise_test( 147 async (t) => { 148 const controller = new CaptureController(); 149 await test_driver.bless('getDisplayMedia()'); 150 const stream = await navigator.mediaDevices.getDisplayMedia( 151 {controller, video: {displaySurface}}); 152 t.add_cleanup(() => stopTracks(stream)); 153 await new Promise((resolve) => step_timeout(resolve, 0)); 154 assert_throws_dom( 155 'InvalidStateError', 156 () => controller.setFocusBehavior(focusBehavior)); 157 }, 158 `setFocusBehavior("${ 159 focusBehavior}") must throw InvalidStateError when window of opportunity is closed if capturing a ${ 160 displaySurface}`)); 161 }); 162 163 validDisplaySurfaces.forEach((displaySurface) => { 164 validFocusBehaviors.forEach( 165 (focusBehavior) => promise_test( 166 async (t) => { 167 const controller = new CaptureController(); 168 await test_driver.bless('getDisplayMedia()'); 169 const stream = await navigator.mediaDevices.getDisplayMedia( 170 {controller, video: {displaySurface}}); 171 t.add_cleanup(() => stopTracks(stream)); 172 controller.setFocusBehavior(focusBehavior) 173 assert_throws_dom( 174 'InvalidStateError', 175 () => controller.setFocusBehavior(focusBehavior)); 176 }, 177 `setFocusBehavior("${ 178 focusBehavior}") must throw InvalidStateError the second time if capturing a ${ 179 displaySurface}`)); 180 }); 181 182 validFocusBehaviors.forEach( 183 (focusBehavior) => promise_test( 184 async (t) => { 185 const controller = new CaptureController(); 186 const options = { 187 controller: controller, 188 video: {width: {max: 0}}, 189 } 190 try { 191 await test_driver.bless('getDisplayMedia()'); 192 stopTracks(await navigator.mediaDevices.getDisplayMedia(options)); 193 } catch (err) { 194 assert_equals(err.name, 'OverconstrainedError', err.message); 195 assert_throws_dom( 196 'InvalidStateError', 197 () => controller.setFocusBehavior(focusBehavior)); 198 return; 199 } 200 assert_unreached('getDisplayMedia should have failed'); 201 }, 202 `setFocusBehavior("${ 203 focusBehavior}") must throw InvalidStateError if getDisplayMedia fails`));