Update getUserMedia W3C conformance tests.

This CL updates these tests to the spec as of
http://dev.w3.org/2011/webrtc/editor/archives/20130824/getusermedia.html

There are still a lot of functionality that lacks testing. I've put a bunch of TODOs in there but I'm unlikely to get time to implement them all any time soon...

TEST=local testing with Chrome Canary.
BUG=
R=phoglund@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/2639004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5090 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
kjellander@webrtc.org 2013-11-06 13:26:34 +00:00
parent 8bad50e845
commit c4225b63bb
2 changed files with 487 additions and 318 deletions

View File

@ -1,7 +1,16 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<!--
Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
Use of this source code is governed by a BSD-style license
that can be found in the LICENSE file in the root of the source
tree. An additional intellectual property rights grant can be found
in the file PATENTS. All contributing project authors may
be found in the AUTHORS file in the root of the source tree.
-->
<html>
<head>
<title>GetUserMedia Browser Conformance Test</title>
<title>getUserMedia Browser Conformance Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
</head>
@ -18,328 +27,37 @@ Notice that this requires the site you're browsing to use HTTPS.
<p>This page contains a foundation of conformance tests that can be expanded
to cover most things in the W3C specification of the Media Capture and Streams
API.</p>
<p>VERSION: These tests are based on the W3C Editor's Draft of 25 September
2012.
<p>VERSION: These tests are based on the W3C Editor's Draft of August 24th,
2013
(<a href="http://dev.w3.org/2011/webrtc/editor/archives/20130824/getusermedia.html">http://dev.w3.org/2011/webrtc/editor/archives/20130824/getusermedia.html</a>)
<p>STATUS: In its current state, it only performs simple checks on the various
attributes and methods of the objects exposed by the API. There's not much
functionality tested so far.</p>
<p>PREREQUISITES: You must have a webcam available on the machine that the
test is executed at.</p>
<p>PREFIX: These tests currently utilizes the <pre>webkit</pre> prefix, so
that will have to changed in order to to test conformance with the actual
standard!</p>
<p>SPEC: <a href="http://dev.w3.org/2011/webrtc/editor/getusermedia.html">
http://dev.w3.org/2011/webrtc/editor/getusermedia.html</a></p>
functionality tested so far. The spec doesn't define if an attribute shall be
owned by the object itself (<code>assert_own_propety</code>) or if it shall be
inherited (<code>assert_inherits</code>). Since testharness.js doesn't offer
any generic function that covers both, the method for verification is
currently chosen according to the current Chrome implementation.</p>
<p>PREFIXES: These tests currently utilizes the <code>adapter.js</code>
script, which handle the prefixes used by different browsers.</p>
<p>HOW TO RUN: The easiest way is to tell your browser to:
<ul>
<li>Provide a fake webcam (<code>--use-fake-ui-for-media-stream</code> in
Chrome)</li>
<li>Automatically allow access to the webcam
(<code>--use-fake-device-for-media-stream</code> in Chrome)</li>
<li>Allow loading HTML files from disk
(<code>--allow-file-access-from-files</code> in Chrome)</li>
</ul>
Then just load this HTML file to execute the tests.</p>
<div id="log"></div>
<video width="320" height="240" id="local-view" autoplay="autoplay"
muted="true"></video>
<script src="https://w3c-test.org/resources/testharness.js"></script>
<!-- Load the polyfill to switch-hit between Chrome and Firefox -->
<script src="https://webrtc.googlecode.com/svn/stable/webrtc/test/manual/adapter.js"></script>
<script type="text/javascript">
setup({timeout:10000});
// Helper functions to minimize code duplication.
function failedCallback(test) {
return test.step_func(function (error) {
assert_unreached('Should not get an error callback');
});
}
function invokeGetUserMedia(test, okCallback) {
navigator.webkitGetUserMedia({ video: true, audio: true }, okCallback,
failedCallback(test));
}
// MediaStream.
var mediaStreamTest = async_test('4.2 MediaStream');
function verifyMediaStream(stream) {
test(function () {
assert_own_property(stream, 'label');
assert_true(typeof stream.label === 'string');
assert_readonly(stream, 'label');
}, "MediaStream label attribute");
test(function () {
assert_own_property(stream, 'audioTracks');
assert_true(typeof stream.audioTracks === 'object',
'audioTracks is a MediaStreamTrackList');
assert_readonly(stream, 'audioTracks');
}, "MediaStream audioTracks attribute");
test(function () {
assert_own_property(stream, 'videoTracks');
assert_true(typeof stream.videoTracks === 'object',
'videoTracks is a MediaStreamTrackList');
assert_readonly(stream, 'videoTracks');
}, "MediaStream videoTracks attribute");
test(function () {
assert_own_property(stream, 'ended');
assert_true(typeof stream.ended === 'boolean');
assert_false(stream.ended);
}, "MediaStream ended attribute");
test(function () {
assert_own_property(stream, 'onended');
assert_true(stream.onended === null);
}, "MediaStream onended EventHandler");
}
mediaStreamTest.step(function() {
var okCallback = mediaStreamTest.step_func(function (localStream) {
verifyMediaStream(localStream);
// Verify event handlers are working.
localStream.onended = onendedCallback
assert_false(localStream.ended);
localStream.stop();
});
var onendedCallback = mediaStreamTest.step_func(function () {
assert_true(localStream.ended);
mediaStreamTest.done();
});
invokeGetUserMedia(mediaStreamTest, okCallback);;
});
// LocalMediaStream.
var localMediaStreamTest = async_test('4.3 LocalMediaStream');
localMediaStreamTest.step(function() {
var okCallback = localMediaStreamTest.step_func(function (localStream) {
assert_own_property(localStream, 'stop');
assert_true(typeof localStream.stop === 'function');
localMediaStreamTest.done();
});
invokeGetUserMedia(localMediaStreamTest, okCallback);
});
// MediaStreamTrack.
var mediaStreamTrackTest = async_test('4.4 MediaStreamTrack');
function verifyTrack(type, track) {
test(function () {
assert_own_property(track, 'kind');
assert_readonly(track, 'kind');
}, 'MediaStreamTrack (' + type + ') kind attribute');
test(function () {
assert_own_property(track, 'label');
assert_true(typeof track.label === 'string',
'label is an object (DOMString)');
assert_readonly(track, 'label');
}, 'MediaStreamTrack (' + type + ') label attribute');
test(function () {
assert_own_property(track, 'enabled');
assert_true(typeof track.enabled === 'boolean',
'enabled is an object (DOMString)');
assert_true(track.enabled, 'enabled property must be true initially');
}, 'MediaStreamTrack (' + type + ') enabled attribute');
test(function () {
assert_own_property(track, 'readyState');
assert_true(typeof track.readyState === 'number');
assert_readonly(track, 'readyState');
assert_equals(track.readyState, track.LIVE,
'readyState must be LIVE initially');
}, 'MediaStreamTrack (' + type + ') readyState attribute');
test(function () {
assert_own_property(track, 'onmute');
assert_true(track.onmute === null);
}, 'MediaStreamTrack (' + type + ') onmute EventHandler');
test(function () {
assert_own_property(track, 'onunmute');
assert_true(track.onunmute === null);
}, 'MediaStreamTrack (' + type + ') onunmute EventHandler');
test(function () {
assert_own_property(track, 'onended');
assert_true(track.onended === null);
}, 'MediaStreamTrack (' + type + ') onended EventHandler');
}
mediaStreamTrackTest.step(function() {
var okCallback = mediaStreamTrackTest.step_func(function (localStream) {
verifyTrack('audio', localStream.audioTracks[0]);
verifyTrack('video', localStream.videoTracks[0]);
mediaStreamTrackTest.done();
});
invokeGetUserMedia(mediaStreamTrackTest, okCallback);
});
// URL tests.
var createObjectURLTest = async_test('4.5 URL createObjectURL method');
createObjectURLTest.step(function() {
var okCallback = createObjectURLTest.step_func(function (localStream) {
var url = webkitURL.createObjectURL(localStream);
assert_true(typeof url === 'string');
createObjectURLTest.done();
});
invokeGetUserMedia(createObjectURLTest, okCallback);
});
// MediaStreamTrackList tests.
var mediaStreamTrackListTest = async_test('4.6 MediaStreamTrackList');
function verifyTrackList(type, trackList) {
test(function () {
assert_own_property(trackList, 'length');
assert_true(typeof trackList.length === 'number');
assert_true(trackList.length === 1);
}, 'MediaStreamTrackList (' + type + ') length attribute');
test(function () {
assert_own_property(trackList, 'item');
assert_true(typeof trackList.item === 'function');
assert_true(trackList.item(0) !== null);
}, 'MediaStreamTrackList (' + type + ') item() method');
test(function () {
assert_own_property(trackList, 'add');
assert_true(typeof trackList.add === 'function');
}, 'MediaStreamTrackList (' + type + ') add() method');
test(function () {
assert_own_property(trackList, 'remove');
assert_true(typeof trackList.remove === 'function');
}, 'MediaStreamTrackList (' + type + ') remove() method');
test(function () {
assert_own_property(trackList, 'onaddtrack');
assert_true(trackList.onaddtrack === null);
}, 'MediaStreamTrackList (' + type + ') onaddtrack EventHandler');
test(function () {
assert_own_property(trackList, 'onremovetrack');
assert_true(trackList.onremovetrack === null);
}, 'MediaStreamTrackList (' + type + ') onremovetrack EventHandler');
}
mediaStreamTrackListTest.step(function() {
var okCallback = mediaStreamTrackListTest.step_func(function (localStream) {
verifyTrackList('audioTracks', localStream.audioTracks);
verifyTrackList('videoTracks', localStream.videoTracks);
mediaStreamTrackListTest.done();
});
invokeGetUserMedia(mediaStreamTrackListTest, okCallback);
});
// MediaStreams as Media Elements.
var mediaElementsTest = async_test('4.7 MediaStreams as Media Elements');
mediaElementsTest.step(function() {
var okCallback = mediaElementsTest.step_func(function (localStream) {
var url = webkitURL.createObjectURL(localStream);
var videoTag = document.getElementById('local-view');
videoTag.src = url;
assert_equals(videoTag.currentSrc, url);
assert_false(videoTag.preload);
assert_equals(videoTag.buffered.length, 1);
assert_equals(videoTag.buffered.start(0), 0);
assert_equals(videoTag.buffered.end(0), 0);
// Attempts to alter currentTime shall be ignored.
assert_true(videoTag.currentTime >= 0);
var time = videoTag.currentTime;
videoTag.currentTime = time - 100;
assert_true(videoTag.currentTime >= time);
assert_equals(videoTag.duration, infinity);
assert_false(videoTag.seeking);
assert_equals(videoTag.defaultPlaybackRate, 1.0);
// Attempts to alter defaultPlaybackRate shall fail.
assert_throws(videoTag.defaultPlaybackRate = 2.0);
assert_equals(videoTag.playbackRate, 1.0);
// Attempts to alter playbackRate shall fail.
assert_throws(videoTag.playbackRate = 2.0);
assert_equals(videoTag.played.length, 1);
assert_equals(videoTag.played.start(0), 0);
assert_true(videoTag.played.end(0) >= videoTag.currentTime);
assert_equals(videoTag.seekable.length, 0);
assert_equals(videoTag.seekable.start(), videoTag.currentTime);
assert_equals(videoTag.seekable.end(), videoTag.currentTime);
assert_equals(videoTag.startOffsetTime, NaN);
assert_false(videoTag.loop);
mediaElementsTest.done();
});
invokeGetUserMedia(mediaElementsTest, okCallback);
});
// NavigatorUserMedia.
var getUserMediaTest = async_test('5.1 NavigatorUserMedia');
getUserMediaTest.step(function() {
var okCallback = getUserMediaTest.step_func(function (localStream) {
assert_true(localStream !== null);
getUserMediaTest.done();
});
// boolean parameters, without failure callback:
navigator.webkitGetUserMedia({ video: true, audio: true }, okCallback);
navigator.webkitGetUserMedia({ video: true, audio: false }, okCallback);
navigator.webkitGetUserMedia({ video: false, audio: true }, okCallback);
// boolean parameters, with failure callback:
navigator.webkitGetUserMedia({ video: true, audio: true }, okCallback,
failedCallback(getUserMediaTest));
navigator.webkitGetUserMedia({ video: true, audio: false }, okCallback,
failedCallback(getUserMediaTest));
navigator.webkitGetUserMedia({ video: false, audio: true }, okCallback,
failedCallback(getUserMediaTest));
});
// MediaStreamConstraints.
var constraintsTest =
async_test('5.2 MediaStreamConstraints');
constraintsTest.step(function() {
var okCallback = constraintsTest.step_func(function (localStream) {
assert_true(localStream !== null);
constraintsTest.done();
});
// Constraints on video.
// See http://code.google.com/p/webrtc-samples/source/browse/trunk/demos/html/constraints-and-stats.html
// for more examples of constraints.
var constraints = {};
constraints.audio = true;
constraints.video = { mandatory: {}, optional: [] };
constraints.video.mandatory.minWidth = 640;
constraints.video.mandatory.minHeight = 480;
constraints.video.mandatory.minFrameRate = 15;
navigator.webkitGetUserMedia(constraints, okCallback,
failedCallback(constraintsTest));
});
// NavigatorUserMediaSuccessCallback.
var successCallbackTest =
async_test('5.3 NavigatorUserMediaSuccessCallback');
successCallbackTest.step(function() {
var okCallback = successCallbackTest.step_func(function (localStream) {
assert_true(localStream !== null);
assert_own_property(localStream, 'stop');
successCallbackTest.done();
});
invokeGetUserMedia(successCallbackTest, okCallback);
});
// NavigatorUserMediaError and NavigatorUserMediaErrorCallback.
var errorCallbackTest =
async_test('5.4 NavigatorUserMediaError and ' +
'NavigatorUserMediaErrorCallback');
errorCallbackTest.step(function() {
var okCallback = errorCallbackTest.step_func(function (localStream) {
assert_unreached('Should not get a success callback');
});
var errorCallback = errorCallbackTest.step_func(function (error) {
assert_own_property(error, 'PERMISSION_DENIED');
assert_readonly(error.PERMISSION_DENIED);
assert_true(typeof error.PERMISSION_DENIED === 'number');
assert_own_property(error, 'code');
assert_readonly(error.code);
assert_true(typeof error.code === 'number');
});
// Setting both audio and video to false triggers an error callback.
// TODO(kjellander): Figure out if there's a way in the spec to trigger an
// error callback.
navigator.webkitGetUserMedia({ video: false, audio: false }, okCallback,
errorCallback);
});
</script>
<video width="640" height="480" id="local-view" autoplay="autoplay"></video>
<script src="getusermedia_conformance_test.js"></script>
</body>
</html>

View File

@ -0,0 +1,451 @@
// Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
setup({timeout:10000});
// Helper functions to minimize code duplication.
function failedCallback(test) {
return test.step_func(function (error) {
assert_unreached('Should not get an error callback');
});
}
function invokeGetUserMedia(test, okCallback) {
getUserMedia({ video: true, audio: true }, okCallback,
failedCallback(test));
}
// 4.2 MediaStream.
var mediaStreamTest = async_test('4.2 MediaStream');
function verifyMediaStream(stream) {
// TODO(kjellander): Add checks for default values where applicable.
test(function () {
assert_own_property(stream, 'id');
assert_true(typeof stream.id === 'string');
assert_readonly(stream, 'id');
}, '[MediaStream] id attribute');
test(function () {
assert_inherits(stream, 'getAudioTracks');
assert_true(typeof stream.getAudioTracks === 'function');
}, '[MediaStream] getAudioTracks function');
test(function () {
assert_inherits(stream, 'getVideoTracks');
assert_true(typeof stream.getVideoTracks === 'function');
}, '[MediaStream] getVideoTracks function');
test(function () {
assert_inherits(stream, 'getTrackById');
assert_true(typeof stream.getTrackById === 'function');
}, '[MediaStream] getTrackById function');
test(function () {
assert_inherits(stream, 'addTrack');
assert_true(typeof stream.addTrack === 'function');
}, '[MediaStream] addTrack function');
test(function () {
assert_inherits(stream, 'removeTrack');
assert_true(typeof stream.removeTrack === 'function');
}, '[MediaStream] removeTrack function');
test(function () {
// Missing in Chrome.
assert_inherits(stream, 'clone');
assert_true(typeof stream.clone === 'function');
}, '[MediaStream] clone function');
test(function () {
assert_own_property(stream, 'ended');
assert_true(typeof stream.ended === 'boolean');
assert_readonly(stream, 'ended');
}, '[MediaStream] ended attribute');
test(function () {
assert_own_property(stream, 'onended');
assert_true(stream.onended === null);
}, '[MediaStream] onended EventHandler');
test(function () {
assert_own_property(stream, 'onaddtrack');
assert_true(stream.onaddtrack === null);
}, '[MediaStream] onaddtrack EventHandler');
test(function () {
assert_own_property(stream, 'onremovetrack');
assert_true(stream.onremovetrack === null);
}, '[MediaStream] onremovetrack EventHandler');
}
mediaStreamTest.step(function() {
var okCallback = mediaStreamTest.step_func(function (stream) {
verifyMediaStream(stream);
var videoTracks = stream.getVideoTracks();
assert_true(videoTracks.length > 0);
// Verify event handlers are working.
stream.onaddtrack = onAddTrackCallback
stream.onremovetrack = onRemoveTrackCallback
stream.removeTrack(videoTracks[0]);
stream.addTrack(videoTracks[0]);
mediaStreamTest.done();
});
var onAddTrackCallback = mediaStreamTest.step_func(function () {
// TODO(kjellander): verify number of tracks.
mediaStreamTest.done();
});
var onRemoveTrackCallback = mediaStreamTest.step_func(function () {
// TODO(kjellander): verify number of tracks.
mediaStreamTest.done();
});
invokeGetUserMedia(mediaStreamTest, okCallback);;
});
// 4.3 MediaStreamTrack.
var mediaStreamTrackTest = async_test('4.3 MediaStreamTrack');
function verifyTrack(type, track) {
test(function () {
assert_own_property(track, 'kind');
assert_readonly(track, 'kind');
assert_true(typeof track.kind === 'string',
'kind is an object (DOMString)');
}, '[MediaStreamTrack (' + type + ')] kind attribute');
test(function () {
assert_own_property(track, 'id');
assert_readonly(track, 'id');
assert_true(typeof track.id === 'string',
'id is an object (DOMString)');
}, '[MediaStreamTrack (' + type + ')] id attribute');
test(function () {
assert_own_property(track, 'label');
assert_readonly(track, 'label');
assert_true(typeof track.label === 'string',
'label is an object (DOMString)');
}, '[MediaStreamTrack (' + type + ')] label attribute');
test(function () {
assert_own_property(track, 'enabled');
assert_true(typeof track.enabled === 'boolean');
assert_true(track.enabled, 'enabled property must be true initially');
}, '[MediaStreamTrack (' + type + ')] enabled attribute');
test(function () {
// Missing in Chrome.
assert_own_property(track, 'muted');
assert_readonly(track, 'muted');
assert_true(typeof track.muted === 'boolean');
assert_false(track.muted, 'muted property must be false initially');
}, '[MediaStreamTrack (' + type + ')] muted attribute');
test(function () {
assert_own_property(track, 'onmute');
assert_true(track.onmute === null);
}, '[MediaStreamTrack (' + type + ')] onmute EventHandler');
test(function () {
assert_own_property(track, 'onunmute');
assert_true(track.onunmute === null);
}, '[MediaStreamTrack (' + type + ')] onunmute EventHandler');
test(function () {
// Missing in Chrome.
assert_own_property(track, '_readonly');
assert_readonly(track, '_readonly');
assert_true(typeof track._readonly === 'boolean');
}, '[MediaStreamTrack (' + type + ')] _readonly attribute');
test(function () {
// Missing in Chrome.
assert_own_property(track, 'remote');
assert_readonly(track, 'remote');
assert_true(typeof track.remote === 'boolean');
}, '[MediaStreamTrack (' + type + ')] remote attribute');
test(function () {
assert_own_property(track, 'readyState');
assert_readonly(track, 'readyState');
assert_true(typeof track.readyState === 'string');
// TODO(kjellander): verify the initial state.
}, '[MediaStreamTrack (' + type + ')] readyState attribute');
test(function () {
// Missing in Chrome.
assert_own_property(track, 'onstarted');
assert_true(track.onstarted === null);
}, '[MediaStreamTrack (' + type + ')] onstarted EventHandler');
test(function () {
assert_own_property(track, 'onended');
assert_true(track.onended === null);
}, '[MediaStreamTrack (' + type + ')] onended EventHandler');
test(function () {
// Missing in Chrome.
assert_inherits(track, 'getSourceInfos');
assert_true(typeof track.getSourceInfos === 'function');
}, '[MediaStreamTrack (' + type + ')]: getSourceInfos function');
test(function () {
// Missing in Chrome.
assert_inherits(track, 'constraints');
assert_true(typeof track.constraints === 'function');
}, '[MediaStreamTrack (' + type + ')]: constraints function');
test(function () {
// Missing in Chrome.
assert_inherits(track, 'states');
assert_true(typeof track.states === 'function');
}, '[MediaStreamTrack (' + type + ')]: states function');
test(function () {
// Missing in Chrome.
assert_inherits(track, 'capabilities');
assert_true(typeof track.capabilities === 'function');
}, '[MediaStreamTrack (' + type + ')]: capabilities function');
test(function () {
// Missing in Chrome.
assert_inherits(track, 'applyConstraints');
assert_true(typeof track.applyConstraints === 'function');
}, '[MediaStreamTrack (' + type + ')]: applyConstraints function');
test(function () {
// Missing in Chrome.
assert_own_property(track, 'onoverconstrained');
assert_true(track.onoverconstrained === null);
}, '[MediaStreamTrack (' + type + ')] onoverconstrained EventHandler');
test(function () {
// Missing in Chrome.
assert_inherits(track, 'clone');
assert_true(typeof track.clone === 'function');
}, '[MediaStreamTrack (' + type + ')] clone function');
test(function () {
// Missing in Chrome.
assert_inherits(track, 'stop');
assert_true(typeof track.stop === 'function');
}, '[MediaStreamTrack (' + type + ')] stop function');
};
mediaStreamTrackTest.step(function() {
var okCallback = mediaStreamTrackTest.step_func(function (stream) {
verifyTrack('audio', stream.getAudioTracks()[0]);
verifyTrack('video', stream.getVideoTracks()[0]);
mediaStreamTrackTest.done();
});
invokeGetUserMedia(mediaStreamTrackTest, okCallback);
});
mediaStreamTrackTest.step(function() {
var okCallback = mediaStreamTrackTest.step_func(function (stream) {
// Verify event handlers are working.
var track = stream.getVideoTracks()[0];
track.onended = onendedCallback
track.stop();
mediaStreamTrackTest.done();
});
var onendedCallback = mediaStreamTrackTest.step_func(function () {
assert_true(track.ended);
mediaStreamTrackTest.done();
});
invokeGetUserMedia(mediaStreamTrackTest, okCallback);
});
// 4.4 MediaStreamTrackEvent tests.
var mediaStreamTrackEventTest = async_test('4.4 MediaStreamTrackEvent');
mediaStreamTrackEventTest.step(function() {
var okCallback = mediaStreamTrackEventTest.step_func(function (stream) {
// TODO(kjellander): verify attributes
mediaStreamTrackEventTest.done();
});
invokeGetUserMedia(mediaStreamTrackEventTest, okCallback);
});
// 4.5 Video and Audio Tracks tests.
var avTracksTest = async_test('4.5 Video and Audio Tracks');
avTracksTest.step(function() {
var okCallback = avTracksTest.step_func(function (stream) {
// TODO(kjellander): verify attributes
avTracksTest.done();
});
invokeGetUserMedia(avTracksTest, okCallback);
});
// 5. The model: sources, sinks, constraints, and states
// 6. Source states
// 6.1 Dictionary MediaSourceStates Members
// 7. Source capabilities
// 7.1 Dictionary CapabilityRange Members
// 7.2 CapabilityList array
// 7.3 Dictionary AllVideoCapabilities Members
// 7.4 Dictionary AllAudioCapabilities Members
// 8. URL tests.
var createObjectURLTest = async_test('8.1 URL createObjectURL method');
createObjectURLTest.step(function() {
var okCallback = createObjectURLTest.step_func(function (stream) {
var url = webkitURL.createObjectURL(stream);
assert_true(typeof url === 'string');
createObjectURLTest.done();
});
invokeGetUserMedia(createObjectURLTest, okCallback);
});
// 9. MediaStreams as Media Elements.
var mediaElementsTest = async_test('9. MediaStreams as Media Elements');
function verifyVideoTagWithStream(videoTag) {
test(function () {
assert_equals(videoTag.buffered.length, 0);
}, '[Video tag] buffered attribute');
test(function () {
// Attempts to alter currentTime shall be ignored.
assert_true(videoTag.currentTime >= 0);
assert_throws('InvalidStateError',
function () { videoTag.currentTime = 1234; },
'Attempts to modify currentTime shall throw ' +
'InvalidStateError');
}, '[Video tag] currentTime attribute');
test(function () {
assert_equals(videoTag.duration, Infinity, 'videoTag.duration');
}, '[Video tag] duration attribute');
test(function () {
assert_false(videoTag.seeking, 'videoTag.seeking');
}, '[Video tag] seeking attribute');
test(function () {
assert_equals(videoTag.defaultPlaybackRate, 1.0);
assert_throws('DOMException',
function () { videoTag.defaultPlaybackRate = 2.0; },
'Attempts to alter videoTag.defaultPlaybackRate MUST fail');
}, '[Video tag] defaultPlaybackRate attribute');
test(function () {
assert_equals(videoTag.playbackRate, 1.0);
assert_throws('DOMException',
function () { videoTag.playbackRate = 2.0; },
'Attempts to alter videoTag.playbackRate MUST fail');
}, '[Video tag] playbackRate attribute');
test(function () {
assert_equals(videoTag.played.length, 1, 'videoTag.played.length');
assert_equals(videoTag.played.start(0), 0);
assert_true(videoTag.played.end(0) >= videoTag.currentTime);
}, '[Video tag] played attribute');
test(function () {
assert_equals(videoTag.seekable.length, 0);
assert_equals(videoTag.seekable.start(), videoTag.currentTime);
assert_equals(videoTag.seekable.end(), videoTag.currentTime);
assert_equals(videoTag.startDate, NaN, 'videoTag.startDate');
}, '[Video tag] seekable attribute');
test(function () {
assert_false(videoTag.loop);
}, '[Video tag] loop attribute');
};
mediaElementsTest.step(function() {
var okCallback = mediaElementsTest.step_func(function (stream) {
var videoTag = document.getElementById('local-view');
// Call the polyfill wrapper to attach the media stream to this element.
attachMediaStream(videoTag, stream);
verifyVideoTagWithStream(videoTag);
mediaElementsTest.done();
});
invokeGetUserMedia(mediaElementsTest, okCallback);
});
// 11. Obtaining local multimedia content.
// 11.1 NavigatorUserMedia.
var getUserMediaTest = async_test('11.1 NavigatorUserMedia');
getUserMediaTest.step(function() {
var okCallback = getUserMediaTest.step_func(function (stream) {
assert_true(stream !== null);
getUserMediaTest.done();
});
// boolean parameters, without failure callback:
getUserMedia({ video: true, audio: true }, okCallback);
getUserMedia({ video: true, audio: false }, okCallback);
getUserMedia({ video: false, audio: true }, okCallback);
// boolean parameters, with failure callback:
getUserMedia({ video: true, audio: true }, okCallback,
failedCallback(getUserMediaTest));
getUserMedia({ video: true, audio: false }, okCallback,
failedCallback(getUserMediaTest));
getUserMedia({ video: false, audio: true }, okCallback,
failedCallback(getUserMediaTest));
});
// 11.2 MediaStreamConstraints.
var constraintsTest = async_test('11.2 MediaStreamConstraints');
constraintsTest.step(function() {
var okCallback = constraintsTest.step_func(function (stream) {
assert_true(stream !== null);
constraintsTest.done();
});
// Constraints on video.
// See http://webrtc.googlecode.com/svn/trunk/samples/js/demos/html/constraints-and-stats.html
// for more examples of constraints.
var constraints = {};
constraints.audio = true;
constraints.video = { mandatory: {}, optional: [] };
constraints.video.mandatory.minWidth = 640;
constraints.video.mandatory.minHeight = 480;
constraints.video.mandatory.minFrameRate = 15;
getUserMedia(constraints, okCallback, failedCallback(constraintsTest));
});
// 11.3 NavigatorUserMediaSuccessCallback.
var successCallbackTest =
async_test('11.3 NavigatorUserMediaSuccessCallback');
successCallbackTest.step(function() {
var okCallback = successCallbackTest.step_func(function (stream) {
assert_true(stream !== null);
successCallbackTest.done();
});
invokeGetUserMedia(successCallbackTest, okCallback);
});
// 11.4 NavigatorUserMediaError and NavigatorUserMediaErrorCallback.
var errorCallbackTest = async_test('11.4 NavigatorUserMediaError and ' +
'NavigatorUserMediaErrorCallback');
errorCallbackTest.step(function() {
var okCallback = errorCallbackTest.step_func(function (stream) {
assert_unreached('Should not get a success callback');
});
var errorCallback = errorCallbackTest.step_func(function (error) {
assert_own_property(error, 'name');
assert_readonly(error.name);
assert_true(typeof error.name === 'string');
assert_equals(error.name, 'ConstraintNotSatisfiedError', 'error.name');
errorCallbackTest.done();
});
// Setting both audio and video to false triggers an error callback.
// TODO(kjellander): Figure out if there's a way in the spec to trigger an
// error callback.
// TODO(kjellander): Investigate why the error callback is not called when
// false/false is provided in Chrome.
getUserMedia({ video: false, audio: false }, okCallback, errorCallback);
});