<!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>