summaryrefslogtreecommitdiffstats
path: root/dom/media/tests/mochitest/test_enumerateDevices.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/tests/mochitest/test_enumerateDevices.html')
-rw-r--r--dom/media/tests/mochitest/test_enumerateDevices.html134
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>