MediaDevices-getUserMedia.https.html (7172B)
1 <!doctype html> 2 <html> 3 <head> 4 <title>getUserMedia: test that mediaDevices.getUserMedia is present</title> 5 <link rel="author" title="Dr Alex Gouaillard" href="mailto:agouaillard@gmail.com"/> 6 <link rel="help" href="https://w3c.github.io/mediacapture-main/#mediadevices-interface-extensions"> 7 <meta name='assert' content='Check that the mediaDevices.getUserMedia() method is present.'/> 8 </head> 9 <body> 10 <h1 class="instructions">Description</h1> 11 <p class="instructions">This test checks for the presence of the 12 <code>navigator.mediaDevices.getUserMedia</code> method.</p> 13 <div id='log'></div> 14 <script src=/resources/testharness.js></script> 15 <script src=/resources/testharnessreport.js></script> 16 <script src=/resources/testdriver.js></script> 17 <script src=/resources/testdriver-vendor.js></script> 18 <script src=permission-helper.js></script> 19 <script> 20 test(function () { 21 assert_not_equals(navigator.mediaDevices.getUserMedia, undefined, "navigator.mediaDevices.getUserMedia exists."); 22 // TODO: do some stuff with it 23 assert_not_equals(navigator.mediaDevices.getSupportedConstraints, undefined, "navigator.mediaDevices.getSupportedConstraints exists."); 24 var list = navigator.mediaDevices.getSupportedConstraints(); 25 // TODO: we are supposed to check that all values returned can be used in a constraint .... 26 // NOTE: the current list of attributes that may or may not be here 27 // ... FF for example has many no tin that list, should we fail if an attribute is present but not listed in the specs? 28 // list.width 29 // list.height 30 // list.aspectRatio 31 // list.frameRate 32 // list.facingMode 33 // list.volume 34 // list.sampleRate 35 // list.sampleSize 36 // list.echoCancellation 37 // list.latency 38 // list.channelCount 39 // list.deviceId 40 // list.groupId 41 }, "mediaDevices.getUserMedia() is present on navigator"); 42 43 promise_test(async t => { 44 // Both permissions are needed at some point, asking both at once 45 await setMediaPermission(); 46 // A successful camera gUM call is needed to expose camera information 47 const afterGum = await navigator.mediaDevices.getUserMedia({video: true}); 48 afterGum.getTracks()[0].stop(); 49 50 assert_true(navigator.mediaDevices.getSupportedConstraints()["groupId"], 51 "groupId should be supported"); 52 const devices = await navigator.mediaDevices.enumerateDevices(); 53 for (const device of devices) { 54 await navigator.mediaDevices.getUserMedia( 55 {video: {groupId: {exact: device.groupId}}}).then(stream => { 56 const found_device = devices.find(({deviceId}) => 57 deviceId == stream.getTracks()[0].getSettings().deviceId); 58 assert_not_equals(found_device, undefined); 59 assert_equals(found_device.kind, "videoinput"); 60 assert_equals(found_device.groupId, device.groupId); 61 stream.getTracks().forEach(t => t.stop()); 62 }, error => { 63 assert_equals(error.name, "OverconstrainedError"); 64 assert_equals(error.constraint, "groupId"); 65 const found_device = devices.find(element => 66 element.kind == "videoinput" && element.groupId == device.groupId); 67 assert_equals(found_device, undefined); 68 }); 69 } 70 }, 'groupId is correctly supported by getUserMedia() for video devices'); 71 72 promise_test(async t => { 73 // A successful microphone gUM call is needed to expose microphone information 74 const afterGum = await navigator.mediaDevices.getUserMedia({audio: true}); 75 afterGum.getTracks()[0].stop(); 76 77 assert_true(navigator.mediaDevices.getSupportedConstraints()["groupId"], 78 "groupId should be supported"); 79 const devices = await navigator.mediaDevices.enumerateDevices(); 80 for (const device of devices) { 81 await navigator.mediaDevices.getUserMedia( 82 {audio: {groupId: {exact: device.groupId}}}).then(stream => { 83 const found_device = devices.find(({deviceId}) => 84 deviceId == stream.getTracks()[0].getSettings().deviceId); 85 assert_not_equals(found_device, undefined); 86 assert_equals(found_device.kind, "audioinput"); 87 assert_equals(found_device.groupId, device.groupId); 88 stream.getTracks().forEach(t => t.stop()); 89 }, error => { 90 assert_equals(error.name, "OverconstrainedError"); 91 assert_equals(error.constraint, "groupId"); 92 const found_device = devices.find(element => 93 element.kind == "audioinput" && element.groupId == device.groupId); 94 assert_equals(found_device, undefined); 95 }); 96 } 97 }, 'groupId is correctly supported by getUserMedia() for audio devices'); 98 99 promise_test(async t => { 100 assert_true(navigator.mediaDevices.getSupportedConstraints()["resizeMode"], 101 "resizeMode should be supported"); 102 const stream = await navigator.mediaDevices.getUserMedia( 103 { video: {resizeMode: {exact: 'none'}}}); 104 const [track] = stream.getVideoTracks(); 105 t.add_cleanup(() => track.stop()); 106 assert_equals(track.getSettings().resizeMode, 'none'); 107 }, 'getUserMedia() supports setting none as resizeMode.'); 108 109 promise_test(async t => { 110 assert_true(navigator.mediaDevices.getSupportedConstraints()["resizeMode"], 111 "resizeMode should be supported"); 112 const stream = await navigator.mediaDevices.getUserMedia( 113 { video: {resizeMode: {exact: 'crop-and-scale'}}}); 114 const [track] = stream.getVideoTracks(); 115 t.add_cleanup(() => track.stop()); 116 assert_equals(track.getSettings().resizeMode, 'crop-and-scale'); 117 }, 'getUserMedia() supports setting crop-and-scale as resizeMode without downscaling.'); 118 119 promise_test(async t => { 120 assert_true(navigator.mediaDevices.getSupportedConstraints()["resizeMode"], 121 "resizeMode should be supported"); 122 const stream = await navigator.mediaDevices.getUserMedia( 123 { video: {resizeMode: {exact: 'crop-and-scale'}, width: {max: 30}}}); 124 const [track] = stream.getVideoTracks(); 125 t.add_cleanup(() => track.stop()); 126 assert_equals(track.getSettings().resizeMode, 'crop-and-scale'); 127 assert_less_than_equal(track.getSettings().width, 30); 128 }, 'getUserMedia() supports setting crop-and-scale as resizeMode with downscaling.'); 129 130 promise_test(async t => { 131 assert_true(navigator.mediaDevices.getSupportedConstraints()["resizeMode"], 132 "resizeMode should be supported"); 133 const stream = await navigator.mediaDevices.getUserMedia( 134 { video: {resizeMode: {exact: 'crop-and-scale'}, frameRate: {max: 5}}}); 135 const [track] = stream.getVideoTracks(); 136 t.add_cleanup(() => track.stop()); 137 assert_equals(track.getSettings().resizeMode, 'crop-and-scale'); 138 assert_less_than_equal(track.getSettings().frameRate, 5); 139 }, 'getUserMedia() supports setting crop-and-scale as resizeMode with decimation.'); 140 141 promise_test(async t => { 142 assert_true(navigator.mediaDevices.getSupportedConstraints()["resizeMode"], 143 "resizeMode should be supported"); 144 try { 145 const stream = await navigator.mediaDevices.getUserMedia( 146 { video: {resizeMode: {exact: 'INVALID'}}}); 147 t.add_cleanup(() => stream.getVideoTracks()[0].stop()); 148 t.unreached_func('getUserMedia() should fail with invalid resizeMode')(); 149 } catch (e) { 150 assert_equals(e.name, 'OverconstrainedError'); 151 assert_equals(e.constraint, 'resizeMode'); 152 } 153 }, 'getUserMedia() fails with exact invalid resizeMode.'); 154 </script> 155 </body> 156 </html>