blob: b6335fae3134b6e3d3aba492d5ba4b25942d8d0f [file] [log] [blame]
<!DOCTYPE HTML>
<html>
<head>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
// Formatting of promises is done according to
// https://www.chromium.org/blink/serviceworker/testing#TOC-Layout-Tests-Style
promise_test(function() {
return navigator.mediaDevices.getUserMedia({})
.then(function(s) {
assert_unreached('getUserMedia should have failed');
})
.catch(function(e) {
assert_equals(e.name, 'TypeError');
});
}, 'getUserMedia() without any media types should fail');
promise_test(function() {
return navigator.mediaDevices.getUserMedia({'audio': true})
.then(function(s) {
// do nothing
})
.catch(function(e) {
assert_unreached('getUserMedia should have succeeded');
});
}, 'getUserMedia() with audio=true should succeed');
promise_test(function() {
return navigator.mediaDevices.getUserMedia(
{audio: {'mandatory': { 'valid_but_unsupported_1': 0}}})
.then(function(s) {
assert_unreached('getUserMedia should have failed');
})
.catch(function(e) {
assert_equals(e.name, 'OverconstrainedError');
assert_equals(e.constraint, 'valid_but_unsupported_1');
});
}, 'getUserMedia() with unsupported mandatory constraint should fail');
// The next tests document existing behavior. They seem non-conformant
// with the specs.
promise_test(function() {
return navigator.mediaDevices.getUserMedia({video: {}})
.then(function(s) {
assert_unreached('getUserMedia should have failed');
})
.catch(function(e) {
assert_equals(e.name, 'Error');
});
}, 'getUserMedia() with empty constraints (neither mandatory nor optional) should fail with Error');
// The following set of tests verify behavior when trying to use the
// dictionary form of constraints. The behaviors currently expected are:
// - Unknown names in dictionary: ignored - which means pass
// - Known names and legal syntax for value: pass
// All constraints allow a primitive value (boolean, string or number),
// and Javascript is capable of coercing just about anything into those values,
// so we never get TypeError thrown here.
//
// Tests that the values are parsed and returned correctly are in
// MediaStreamTrack-getConstraints.html.
function check_constraints_fail(name, constraints, expected_error) {
promise_test(function() {
return navigator.mediaDevices.getUserMedia({'video': constraints})
.then(() => assert_unreached('getUserMedia should have failed'),
e => assert_equals(e.name, expected_error));
}, name);
}
function check_constraints_pass(name, constraints) {
promise_test(function() {
return navigator.mediaDevices.getUserMedia({'video': constraints});
}, name);
}
check_constraints_pass(
'Constraint with unsupported name gets ignored',
{'unsupported_name': 47});
check_constraints_pass(
'Constraint with exact Long value should be parsed',
{'height': {exact: 47}});
check_constraints_pass(
'Constraint with Long naked value should be parsed',
{height: 47});
check_constraints_pass(
'echoCancellation constraint with boolean value should be parsed',
{'echoCancellation': {exact: true}});
check_constraints_pass(
'echoCancellation constraint with boolean naked value should be parsed',
{'echoCancellation': true});
check_constraints_pass(
'autoGainControl constraint with boolean value should be parsed',
{'autoGainControl': {exact: true}});
check_constraints_pass(
'autoGainControl constraint with boolean naked value should be parsed',
{'autoGainControl': true});
check_constraints_pass(
'noiseSuppression constraint with boolean value should be parsed',
{'noiseSuppression': {exact: true}});
check_constraints_pass(
'noiseSuppression constraint with boolean naked value should be parsed',
{'noiseSuppression': true});
check_constraints_pass(
'Constraint with string value should work on exact with array',
{'facingMode': {ideal: ['user']}});
check_constraints_pass(
'Constraint with exact string value should work',
{'facingMode': {ideal: 'user'}});
check_constraints_pass(
'Constraint with naked string value should be parsed',
{'facingMode': 'user'});
check_constraints_fail(
'Using both mandatory and height should give TypeError',
{'mandatory': {'height': '270'}, 'height': '270'}, 'TypeError');
promise_test(async t => {
let stream = await navigator.mediaDevices.getUserMedia(
{video: {width: 639, height: 479}});
let track = stream.getVideoTracks()[0];
let settings = track.getSettings();
assert_equals(settings.width, 639);
assert_equals(settings.height, 479);
assert_equals(settings.resizeMode, "crop-and-scale");
track.stop();
stream = await navigator.mediaDevices.getUserMedia(
{video: {width: 639, height: 479, resizeMode: {exact: "none"}}});
track = stream.getVideoTracks()[0];
settings = track.getSettings();
// With rescaling disabled, a native resolution is used.
assert_equals(settings.width, 640);
assert_equals(settings.height, 480);
assert_equals(settings.resizeMode, "none");
track.stop();
try {
stream = await navigator.mediaDevices.getUserMedia(
{video: {width: {exact: 639}, resizeMode: {exact: "none"}}});
t.add_cleanup(()=>stream.getVideoTracks()[0].stop());
t.step(() => assert_unreached('applyConstraints should have failed'));
} catch(e) {
assert_equals(e.name, 'OverconstrainedError');
assert_equals(e.constraint, 'width');
}
}, 'getUserMedia() resizeMode constraint');
</script>
</body>
</html>