summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/tests/mochitests/test_getUserMedia_constraints.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/webrtc/tests/mochitests/test_getUserMedia_constraints.html')
-rw-r--r--dom/media/webrtc/tests/mochitests/test_getUserMedia_constraints.html166
1 files changed, 166 insertions, 0 deletions
diff --git a/dom/media/webrtc/tests/mochitests/test_getUserMedia_constraints.html b/dom/media/webrtc/tests/mochitests/test_getUserMedia_constraints.html
new file mode 100644
index 0000000000..d6439ce9d6
--- /dev/null
+++ b/dom/media/webrtc/tests/mochitests/test_getUserMedia_constraints.html
@@ -0,0 +1,166 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script src="mediaStreamPlayback.js"></script>
+ <script src="constraints.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+createHTML({ title: "Test getUserMedia constraints", bug: "882145" });
+/**
+ Tests covering gUM constraints API for audio, video and fake video. Exercise
+ successful parsing code and ensure that unknown required constraints and
+ overconstraining cases produce appropriate errors.
+*/
+var tests = [
+ // Each test here tests a different constraint or codepath.
+ { message: "unknown required constraint on video ignored",
+ constraints: { video: { somethingUnknown: { exact: 0 } } },
+ error: null },
+ { message: "unknown required constraint on audio ignored",
+ constraints: { audio: { somethingUnknown: { exact: 0 } } },
+ error: null },
+ { message: "audio overconstrained by facingMode ignored",
+ constraints: { audio: { facingMode: { exact: 'left' } } },
+ error: null },
+ { message: "full screensharing requires permission",
+ constraints: { video: { mediaSource: 'screen' } },
+ error: "NotAllowedError" },
+ { message: "application screensharing no longer exists",
+ constraints: { video: { mediaSource: 'application' } },
+ error: "OverconstrainedError" },
+ { message: "window screensharing requires permission",
+ constraints: { video: { mediaSource: 'window' } },
+ error: "NotAllowedError" },
+ { message: "browser screensharing requires permission",
+ constraints: { video: { mediaSource: 'browser' } },
+ error: "NotAllowedError" },
+ { message: "unknown mediaSource in video fails",
+ constraints: { video: { mediaSource: 'uncle' } },
+ error: "OverconstrainedError",
+ constraint: "mediaSource" },
+ { message: "unknown mediaSource in audio fails",
+ constraints: { audio: { mediaSource: 'uncle' } },
+ error: "OverconstrainedError",
+ constraint: "mediaSource" },
+ { message: "emtpy constraint fails",
+ constraints: { },
+ error: "TypeError" },
+ { message: "Triggering mock failure in default video device fails",
+ constraints: { video: { deviceId: 'bad device' } },
+ error: "NotReadableError" },
+ { message: "Triggering mock failure in default audio device fails",
+ constraints: { audio: { deviceId: 'bad device' } },
+ error: "NotReadableError" },
+ { message: "Success-path: optional video facingMode + audio ignoring facingMode",
+ constraints: { audio: { mediaSource: 'microphone',
+ facingMode: 'left',
+ foo: 0,
+ advanced: [{ facingMode: 'environment' },
+ { facingMode: 'user' },
+ { bar: 0 }] },
+ video: { mediaSource: 'camera',
+ foo: 0,
+ advanced: [{ facingMode: 'environment' },
+ { facingMode: ['user'] },
+ { facingMode: ['left', 'right', 'user'] },
+ { bar: 0 }] } },
+ error: null },
+ { message: "legacy facingMode ignored",
+ constraints: { video: { mandatory: { facingMode: 'left' } } },
+ error: null },
+];
+
+var mustSupport = [
+ 'width', 'height', 'frameRate', 'facingMode', 'deviceId', 'groupId',
+ 'echoCancellation', 'noiseSuppression', 'autoGainControl', 'channelCount',
+
+ // Yet to add:
+ // 'aspectRatio', 'volume', 'sampleRate', 'sampleSize', 'latency'
+
+ // http://fluffy.github.io/w3c-screen-share/#screen-based-video-constraints
+ // OBE by http://w3c.github.io/mediacapture-screen-share
+ 'mediaSource',
+
+ // Experimental https://bugzilla.mozilla.org/show_bug.cgi?id=1131568#c3
+ 'browserWindow', 'scrollWithPage',
+ 'viewportOffsetX', 'viewportOffsetY', 'viewportWidth', 'viewportHeight',
+];
+
+var mustFailWith = (msg, reason, constraint, f) =>
+ f().then(() => ok(false, msg + " must fail"), e => {
+ is(e.name, reason, msg + " must fail: " + e.message);
+ if (constraint !== undefined) {
+ is(e.constraint, constraint, msg + " must fail w/correct constraint.");
+ }
+ });
+
+/**
+ * Starts the test run by running through each constraint
+ * test by verifying that the right resolution and rejection is fired.
+ */
+
+runTest(() => pushPrefs(
+ // This test expects fake devices, particularly for the 'triggering mock
+ // failure *' steps. So explicitly disable loopback and setup fakes
+ ['media.audio_loopback_dev', ''],
+ ['media.video_loopback_dev', ''],
+ ['media.navigator.streams.fake', true]
+ )
+ .then(() => {
+ // Check supported constraints first.
+ var dict = navigator.mediaDevices.getSupportedConstraints();
+ var supported = Object.keys(dict);
+
+ mustSupport.forEach(key => ok(supported.includes(key) && dict[key],
+ "Supports " + key));
+
+ var unexpected = supported.filter(key => !mustSupport.includes(key));
+ is(unexpected.length, 0,
+ "Unanticipated support (please update test): " + unexpected);
+ })
+ .then(() => pushPrefs(["media.getusermedia.browser.enabled", false],
+ ["media.getusermedia.screensharing.enabled", false]))
+ .then(() => tests.reduce((p, test) => p.then(
+ () => {
+ SpecialPowers.wrap(document).notifyUserGestureActivation();
+ return getUserMedia(test.constraints);
+ })
+ .then(stream => {
+ is(null, test.error, test.message);
+ stream.getTracks().forEach(t => t.stop());
+ }, e => {
+ is(e.name, test.error, test.message + ": " + e.message);
+ if (test.constraint) {
+ is(e.constraint, test.constraint,
+ test.message + " w/correct constraint.");
+ }
+ }), Promise.resolve()))
+ .then(() => getUserMedia({video: true, audio: true}))
+ .then(stream => stream.getVideoTracks()[0].applyConstraints({ width: 320 })
+ .then(() => stream.getAudioTracks()[0].applyConstraints({ }))
+ .then(() => {
+ stream.getTracks().forEach(track => track.stop());
+ ok(true, "applyConstraints code exercised");
+ }))
+ // TODO: Test outcome once fake devices support constraints (Bug 1088621)
+ .then(() => mustFailWith("applyConstraints fails on non-Gum tracks",
+ "OverconstrainedError", "",
+ () => (new AudioContext())
+ .createMediaStreamDestination().stream
+ .getAudioTracks()[0].applyConstraints()))
+ .then(() => mustFailWith(
+ "getUserMedia with unsatisfied required constraint",
+ "OverconstrainedError", "deviceId",
+ () => getUserMedia({ audio: true,
+ video: { deviceId: { exact: "unheardof" } } })))
+ .then(() => mustFailWith(
+ "getUserMedia with unsatisfied required constraint array",
+ "OverconstrainedError", "deviceId",
+ () => getUserMedia({ audio: true,
+ video: { deviceId: { exact: ["a", "b"] } } }))));
+</script>
+</pre>
+</body>
+</html>