// 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:5000}); // 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.getUserMedia({ video: true, audio: true }, okCallback, failedCallback(test)); } function createInvisibleVideoTag() { var video = document.createElement('video'); video.autoplay = true; video.style.display = 'none'; document.body.appendChild(video); return video; } // 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 () { assert_inherits(stream, 'clone'); assert_true(typeof stream.clone === 'function'); }, '[MediaStream] clone function'); test(function () { assert_own_property(stream, 'active'); assert_true(typeof stream.active === 'boolean'); assert_readonly(stream, 'active'); }, '[MediaStream] active attribute'); test(function () { assert_own_property(stream, 'onactive'); assert_true(stream.onactive === null); }, '[MediaStream] onactive EventHandler'); test(function () { assert_own_property(stream, 'oninactive'); assert_true(stream.oninactive === null); }, '[MediaStream] oninactive 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); mediaStreamTest.done(); }); invokeGetUserMedia(mediaStreamTest, okCallback); }); var mediaStreamCallbacksTest = async_test('4.2.2 MediaStream callbacks'); mediaStreamCallbacksTest.step(function() { var addCallbackCalled = false; var onAddTrackCallback = mediaStreamCallbacksTest.step_func(function (event) { assert_true(event.track instanceof MediaStreamTrack); addCallbackCalled = true; }); var onRemoveTrackCallback = mediaStreamCallbacksTest.step_func(function (event) { assert_true(event.track instanceof MediaStreamTrack); assert_true(addCallbackCalled, 'Add should have been called after remove.'); mediaStreamCallbacksTest.done(); }); var okCallback = mediaStreamCallbacksTest.step_func(function (stream) { var videoTracks = stream.getVideoTracks(); // Verify event handlers are working. stream.onaddtrack = onAddTrackCallback; stream.onremovetrack = onRemoveTrackCallback; stream.removeTrack(videoTracks[0]); stream.addTrack(videoTracks[0]); }); invokeGetUserMedia(mediaStreamCallbacksTest, okCallback); }); // TODO(phoglund): add test for onactive/oninactive. // 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 () { 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 () { assert_own_property(track, '_readonly'); assert_readonly(track, '_readonly'); assert_true(typeof track._readonly === 'boolean'); }, '[MediaStreamTrack (' + type + ')] _readonly attribute'); test(function () { 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 () { 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 () { assert_inherits(track, 'getNativeSettings'); assert_true(typeof track.capabilities === 'function'); }, '[MediaStreamTrack (' + type + ')]: getNativeSettings function'); test(function () { assert_inherits(track, 'clone'); assert_true(typeof track.clone === 'function'); }, '[MediaStreamTrack (' + type + ')] clone function'); test(function () { assert_inherits(track, 'stop'); assert_true(typeof track.stop === 'function'); }, '[MediaStreamTrack (' + type + ')] stop function'); test(function () { assert_inherits(track, 'getCapabilities'); assert_true(typeof track.capabilities === 'function'); }, '[MediaStreamTrack (' + type + ')]: getCapabilities function'); test(function () { assert_inherits(track, 'getConstraints'); assert_true(typeof track.constraints === 'function'); }, '[MediaStreamTrack (' + type + ')]: getConstraints function'); test(function () { assert_inherits(track, 'getSettings'); assert_true(typeof track.constraints === 'function'); }, '[MediaStreamTrack (' + type + ')]: getSettings function'); test(function () { assert_inherits(track, 'applyConstraints'); assert_true(typeof track.applyConstraints === 'function'); }, '[MediaStreamTrack (' + type + ')]: applyConstraints 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); }); // 6. Media streams as media elements. var playingInMediaElementTest = async_test( '6.2 Loading and Playing a MediaStream in a Media Element'); playingInMediaElementTest.step(function() { var video = createInvisibleVideoTag(); var okCallback = playingInMediaElementTest.step_func(function (stream) { video.onplay = playingInMediaElementTest.step_func(function() { // This depends on what webcam we're actually running with, but the // resolution should at least be greater than or equal to QVGA. assert_greater_than_equal(video.videoWidth, 320); assert_greater_than_equal(video.videoHeight, 240); playingInMediaElementTest.done(); }); video.srcObject = stream; }); invokeGetUserMedia(playingInMediaElementTest, okCallback); }); // Verifies a media element track (for instance belonging to a video tag) // after it has been assigned a media stream. function verifyOneMediaElementTrack(track, correspondingMediaStreamTrack) { assert_equals(track.id, correspondingMediaStreamTrack.id); assert_equals(track.kind, 'main'); assert_equals(track.label, correspondingMediaStreamTrack.label); assert_equals(track.language, ''); } var setsUpMediaTracksRightTest = async_test( '6.2 Sets up