diff options
Diffstat (limited to 'dom/media/tests/mochitest/test_enumerateDevices.html')
-rw-r--r-- | dom/media/tests/mochitest/test_enumerateDevices.html | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/dom/media/tests/mochitest/test_enumerateDevices.html b/dom/media/tests/mochitest/test_enumerateDevices.html new file mode 100644 index 000000000..dd4db59d7 --- /dev/null +++ b/dom/media/tests/mochitest/test_enumerateDevices.html @@ -0,0 +1,134 @@ +<!DOCTYPE HTML> +<html> +<head> + <script src="mediaStreamPlayback.js"></script> +</head> +<body> +<pre id="test"> +<script type="application/javascript"> +createHTML({ title: "Run enumerateDevices code", bug: "1046245" }); +/** + Tests covering enumerateDevices API and deviceId constraint. Exercise code. +*/ + +async function mustSucceed(msg, f) { + try { + await f(); + ok(true, msg + " must succeed"); + } catch (e) { + is(e.name, null, msg + " must succeed: " + e.message); + } +} + +async function mustFailWith(msg, reason, constraint, f) { + try { + await f(); + ok(false, msg + " must fail"); + } catch(e) { + is(e.name, reason, msg + " must fail: " + e.message); + if (constraint) { + is(e.constraint, constraint, msg + " must fail w/correct constraint."); + } + } +} + +var pushPrefs = (...p) => SpecialPowers.pushPrefEnv({set: p}); +var gUM = c => navigator.mediaDevices.getUserMedia(c); + +var validateDevice = ({kind, label, deviceId, groupId}) => { + ok(kind == "videoinput" || kind == "audioinput", "Known device kind"); + is(deviceId.length, 44, "deviceId length id as expected for Firefox"); + ok(label.length !== undefined, "Device label: " + label); + + // TODO: s/todo_// once Bug 1213453 is fixed. + todo_isnot(groupId, "", "groupId must be present."); +} + +runTest(async () => { + await pushPrefs(["media.navigator.streams.fake", true]); + + // Validate enumerated devices. + + let devices = await navigator.mediaDevices.enumerateDevices(); + ok(devices.length > 0, "At least one device found"); + let jsoned = JSON.parse(JSON.stringify(devices)); + is(jsoned[0].kind, devices[0].kind, "kind survived serializer"); + is(jsoned[0].deviceId, devices[0].deviceId, "deviceId survived serializer"); + for (let device of devices) { + validateDevice(device); + // Test deviceId constraint + let deviceId = device.deviceId; + let constraints = (device.kind == "videoinput") ? { video: { deviceId } } + : { audio: { deviceId } }; + for (let track of (await gUM(constraints)).getTracks()) { + is(typeof(track.label), "string", "Track label is a string"); + is(track.label, device.label, "Track label is the device label"); + track.stop(); + } + } + + const unknownId = "unknown9qHr8B0JIbcHlbl9xR+jMbZZ8WyoPfpCXPfc="; + + // Check deviceId failure paths for video. + + await mustSucceed("unknown plain deviceId on video", + () => gUM({ video: { deviceId: unknownId } })); + await mustSucceed("unknown plain deviceId on audio", + () => gUM({ audio: { deviceId: unknownId } })); + await mustFailWith("unknown exact deviceId on video", + "OverconstrainedError", "deviceId", + () => gUM({ video: { deviceId: { exact: unknownId } } })); + await mustFailWith("unknown exact deviceId on audio", + "OverconstrainedError", "deviceId", + () => gUM({ audio: { deviceId: { exact: unknownId } } })); + + // Check that deviceIds are stable for same origin and differ across origins. + + const path = "/tests/dom/media/tests/mochitest/test_enumerateDevices_iframe.html"; + const origins = ["http://mochi.test:8888", "http://test1.mochi.test:8888"]; + info(window.location); + + let haveDevicesMap = new Promise(resolve => { + let map = new Map(); + window.addEventListener("message", ({origin, data}) => { + ok(origins.includes(origin), "Got message from expected origin"); + map.set(origin, JSON.parse(data)); + if (map.size < origins.length) return; + resolve(map); + }); + }); + + await Promise.all(origins.map(origin => { + let iframe = document.createElement("iframe"); + iframe.src = origin + path; + info(iframe.src); + document.documentElement.appendChild(iframe); + return new Promise(resolve => iframe.onload = resolve); + })); + let devicesMap = await haveDevicesMap; + let [sameOriginDevices, differentOriginDevices] = origins.map(o => devicesMap.get(o)); + + is(sameOriginDevices.length, devices.length); + is(differentOriginDevices.length, devices.length); + [...sameOriginDevices, ...differentOriginDevices].forEach(d => validateDevice(d)); + + for (let device of sameOriginDevices) { + ok(devices.find(d => d.deviceId == device.deviceId), + "Same origin deviceId for " + device.label + " must match"); + } + for (let device of differentOriginDevices) { + ok(!devices.find(d => d.deviceId == device.deviceId), + "Different origin deviceId for " + device.label + " must be different"); + } + + // Check the special case of no devices found. + await pushPrefs(["media.navigator.streams.fake", false], + ["media.audio_loopback_dev", "none"], + ["media.video_loopback_dev", "none"]); + devices = await navigator.mediaDevices.enumerateDevices(); + ok(devices.length === 0, "No devices found"); +}); +</script> +</pre> +</body> +</html> |