new file mode 100644
--- /dev/null
+++ b/dom/media/test/gUM_support.js
@@ -0,0 +1,87 @@
+// Support script for test that use getUserMedia. This allows explicit
+// configuration of prefs which affect gUM. See also
+// `testing/mochitest/runtests.py` for how the harness configures values.
+
+// Setup preconditions for tests using getUserMedia. This functions helps
+// manage different prefs that affect gUM calls in tests and makes explicit
+// the expected state before test runs.
+async function pushGetUserMediaTestPrefs({
+ fakeAudio = false,
+ fakeVideo = false,
+ loopbackAudio = false,
+ loopbackVideo = false}) {
+ // Make sure we have sensical arguments
+ if (!fakeAudio && !loopbackAudio) {
+ throw new Error("pushGetUserMediaTestPrefs: Should have fake or loopback audio!");
+ } else if (fakeAudio && loopbackAudio) {
+ throw new Error("pushGetUserMediaTestPrefs: Should not have both fake and loopback audio!");
+ }
+ if (!fakeVideo && !loopbackVideo) {
+ throw new Error("pushGetUserMediaTestPrefs: Should have fake or loopback video!");
+ } else if (fakeVideo && loopbackVideo) {
+ throw new Error("pushGetUserMediaTestPrefs: Should not have both fake and loopback video!");
+ }
+
+ let testPrefs = [];
+ if (fakeAudio) {
+ // Unset the loopback device so it doesn't take precedence
+ testPrefs.push(["media.audio_loopback_dev", ""]);
+ // Setup fake streams pref
+ testPrefs.push(["media.navigator.streams.fake", true]);
+ }
+ if (loopbackAudio) {
+ // If audio loopback is requested we expect the test harness to have set
+ // the loopback device pref, make sure it's set
+ let audioLoopDev = SpecialPowers.getCharPref("media.audio_loopback_dev", "");
+ if (!audioLoopDev) {
+ throw new Error("pushGetUserMediaTestPrefs: Loopback audio requested but " +
+ "media.audio_loopback_dev does not appear to be set!");
+ }
+ }
+ if (fakeVideo) {
+ // Unset the loopback device so it doesn't take precedence
+ testPrefs.push(["media.video_loopback_dev", ""]);
+ // Setup fake streams pref
+ testPrefs.push(["media.navigator.streams.fake", true]);
+ }
+ if (loopbackVideo) {
+ // If video loopback is requested we expect the test harness to have set
+ // the loopback device pref, make sure it's set
+ let videoLoopDev = SpecialPowers.getCharPref("media.video_loopback_dev", "");
+ if (!videoLoopDev) {
+ throw new Error("pushGetUserMediaTestPrefs: Loopback video requested but " +
+ "media.video_loopback_dev does not appear to be set!");
+ }
+ }
+ if (loopbackAudio || loopbackVideo) {
+ // Prevent gUM permission prompt. Since loopback devices are considered
+ // real devices we need to set prefs so the gUM prompt isn't presented.
+ testPrefs.push(['media.navigator.permission.disabled', true]);
+ }
+ return SpecialPowers.pushPrefEnv({set: testPrefs});
+}
+
+// Setup preconditions for tests using getUserMedia. This function will
+// configure prefs to select loopback device(s) if it can find loopback device
+// names already set in the prefs. If no loopback device name can be found then
+// prefs are setup such that a fake device is used.
+async function setupGetUserMediaTestPrefs() {
+ prefRequests = {};
+ let audioLoopDev = SpecialPowers.getCharPref("media.audio_loopback_dev", "");
+ if (audioLoopDev) {
+ prefRequests.fakeAudio = false;
+ prefRequests.loopbackAudio = true;
+ } else {
+ prefRequests.fakeAudio = true;
+ prefRequests.loopbackAudio = false;
+ }
+ let videoLoopDev = SpecialPowers.getCharPref("media.video_loopback_dev", "");
+ if (videoLoopDev) {
+ prefRequests.fakeVideo = false;
+ prefRequests.loopbackVideo = true;
+ } else {
+ prefRequests.fakeVideo = true;
+ prefRequests.loopbackVideo = false;
+ }
+ return pushGetUserMediaTestPrefs(prefRequests);
+}
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -452,16 +452,17 @@ support-files =
gizmo-noaudio.mp4
gizmo-noaudio.mp4^headers^
gizmo-short.mp4
gizmo-short.mp4^headers^
gizmo.webm
gizmo.webm^headers^
gizmo-noaudio.webm
gizmo-noaudio.webm^headers^
+ gUM_support.js
gzipped_mp4.sjs
huge-id3.mp3
huge-id3.mp3^headers^
id3tags.mp3
id3tags.mp3^headers^
invalid-cmap-s0c0.opus
invalid-cmap-s0c0.opus^headers^
invalid-cmap-s0c2.opus
--- a/dom/media/test/test_imagecapture.html
+++ b/dom/media/test/test_imagecapture.html
@@ -3,30 +3,31 @@
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1041393
-->
<head>
<meta charset="utf-8">
<title>ImageCapture tests</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="gUM_support.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1041393">ImageCapture tests</a>
<script type="application/javascript">
-var repeat = 100;
-var count;
+let repeat = 100;
+let count;
// Check if the callback returns even no JS reference on it.
function gcTest(track) {
return new Promise(function(resolve, reject) {
count = 0;
- var i;
- var imageCapture;
+ let i;
+ let imageCapture;
for(i = 0; i < repeat; i++) {
imageCapture = new ImageCapture(track);
imageCapture.onphoto = function(blob) {
count++;
if (count == repeat) {
ok(true, "pass gc testing");
resolve(track);
}
@@ -41,112 +42,103 @@ function gcTest(track) {
info("Call gc ");
SpecialPowers.gc();
});
}
// Continue calling takePhoto() in rapid succession.
function rapidTest(track) {
return new Promise(function(resolve, reject) {
- var imageCapture = new ImageCapture(track);
+ let imageCapture = new ImageCapture(track);
imageCapture.onphoto = function(blob) {
count++;
if (count == repeat) {
ok(true, "pass raipd takePhoto() testing");
resolve(track);
}
};
imageCapture.onerror = function(error) {
ok(false, "takePhoto() failure in rapid testing");
reject();
};
count = 0;
- var i;
+ let i;
for(i = 0; i < repeat; i++) {
imageCapture.takePhoto();
}
});
}
// Check if the blob is decodable.
function blobTest(track) {
return new Promise(function(resolve, reject) {
- var imageCapture = new ImageCapture(track);
+ let imageCapture = new ImageCapture(track);
imageCapture.onphoto = function(blob) {
- var img = new Image();
+ let img = new Image();
img.onerror = function() {
ok(false, "fail to decode blob");
reject();
- }
+ };
img.onload = function() {
ok(true, "decode blob success");
resolve(track);
- }
+ };
img.src = URL.createObjectURL(blob.data);
};
imageCapture.onerror = function(error) {
ok(false, "fail to capture image");
};
imageCapture.takePhoto();
});
}
// It should return an error event after disabling video track.
function trackTest(track) {
return new Promise(function(resolve, reject) {
- var imageCapture = new ImageCapture(track);
+ let imageCapture = new ImageCapture(track);
imageCapture.onphoto = function(blob) {
ok(false, "expect error when video track is disable");
reject();
};
imageCapture.onerror = function(error) {
ok(error.imageCaptureError.code == error.imageCaptureError.PHOTO_ERROR, "error code is PHOTO_ERROR")
track.enabled = true;
resolve(track);
};
track.enabled = false;
- imageCapture.takePhoto()
+ imageCapture.takePhoto();
});
}
-function init() {
- return new Promise(function(resolve, reject) {
- // use fake camera, MediaStreamGraph will be the backend of ImageCapture.
- var constraints = {video: true, fake: true}
-
- window.navigator.mozGetUserMedia(
- constraints,
- function(stream) {
- var track = stream.getVideoTracks()[0];
- resolve(track);
- },
- function(err) {
- reject(err);
- }
- );
- });
+async function init() {
+ // use loopback camera if available, otherwise fake, MediaStreamGraph will be the backend of ImageCapture.
+ await setupGetUserMediaTestPrefs();
+ let stream = await navigator.mediaDevices.getUserMedia({video: true});
+ return stream.getVideoTracks()[0];
}
-function start() {
- init().then(function(track) {
+async function start() {
+ try {
+ let track = await init();
info("ImageCapture track disable test.");
- return trackTest(track);
- }).then(function(track) {
+ track = await trackTest(track);
info("ImageCapture blob test.");
- return blobTest(track);
- }).then(function(track) {
+ track = await blobTest(track);
info("ImageCapture rapid takePhoto() test.");
- return rapidTest(track);
- }).then(function(track) {
+ track = await rapidTest(track);
info("ImageCapture multiple instances test.");
- return gcTest(track);
- }).then(SimpleTest.finish);
+ await gcTest(track);
+ } catch (e) {
+ ok(false, "Unexpected error during test: " + e);
+ } finally {
+ SimpleTest.finish();
+ }
}
SimpleTest.requestCompleteLog();
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [["dom.imagecapture.enabled", true],
["media.navigator.permission.disabled", true]
]}, start);
--- a/dom/media/test/test_mediarecorder_avoid_recursion.html
+++ b/dom/media/test/test_mediarecorder_avoid_recursion.html
@@ -1,26 +1,27 @@
<html>
<head>
<title>MediaRecorder infinite recursion with requestData() calls in "dataavailable" event</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
+ <script type="text/javascript" src="gUM_support.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=897776">Mozill
a Bug 897776</a>
<pre id="test">
<script class="testbody" type="text/javascript">
-function startTest() {
- navigator.mozGetUserMedia({audio: true, fake: true}, function(stream) {
- var mediaRecorder = new MediaRecorder(stream);
- var count = 0;
- mediaRecorder.start();
- info("mediaRecorder start");
+async function startTest() {
+ try {
+ await setupGetUserMediaTestPrefs();
+ let stream = await navigator.mediaDevices.getUserMedia({audio: true});
+ let mediaRecorder = new MediaRecorder(stream);
+ let count = 0;
mediaRecorder.onerror = function () {
ok(false, 'Unexpected onerror callback fired');
SimpleTest.finish();
};
mediaRecorder.onwarning = function () {
ok(false, 'Unexpected onwarning callback fired');
};
mediaRecorder.ondataavailable = function (e) {
@@ -30,27 +31,29 @@ function startTest() {
// the encoding thread
if (count == 30) {
info("stream.stop");
stream.stop();
} else if (count < 30 && mediaRecorder.state == 'recording') {
info("requestData again");
mediaRecorder.requestData();
}
- }
- mediaRecorder.requestData();
- info("mediaRecorder requestData");
+ };
mediaRecorder.onstop = function () {
ok(true, "requestData within ondataavailable successfully avoided infinite recursion");
SimpleTest.finish();
- }
- }, function(err) {
- ok(false, 'Unexpected error fired with: ' + err);
+ };
+ mediaRecorder.start();
+ info("mediaRecorder start");
+ mediaRecorder.requestData();
+ info("mediaRecorder requestData");
+ } catch (e) {
+ ok(false, 'Unexpected error fired with: ' + e);
SimpleTest.finish();
- });
+ }
}
SimpleTest.waitForExplicitFinish();
startTest();
</script>
</pre>
</body>
--- a/dom/media/test/test_mediarecorder_record_gum_video_timeslice.html
+++ b/dom/media/test/test_mediarecorder_record_gum_video_timeslice.html
@@ -1,25 +1,28 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test MediaRecorder Record gUM video with Timeslice</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script type="text/javascript" src="gUM_support.js"></script>
</head>
<body>
<pre id="test">
<div id="content" style="display: none">
</div>
<script class="testbody" type="text/javascript">
-function startTest() {
- navigator.mozGetUserMedia({audio: true, video: true, fake: true}, function(stream) {
- var dataAvailableCount = 0;
- var onDataAvailableFirst = false;
+async function startTest() {
+ try {
+ await setupGetUserMediaTestPrefs();
+ let stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
+ let dataAvailableCount = 0;
+ let onDataAvailableFirst = false;
mediaRecorder = new MediaRecorder(stream);
is(mediaRecorder.stream, stream,
'Media recorder stream = element stream at the start of recording');
mediaRecorder.onwarning = function() {
ok(false, 'onwarning unexpectedly fired');
};
@@ -68,20 +71,20 @@ function startTest() {
// Ensure we've received at least two ondataavailable events before
// onstop
onDataAvailableFirst = true;
}
};
mediaRecorder.start(250);
is(mediaRecorder.state, 'recording', 'Media recorder should be recording');
- }, function(err) {
+ } catch (err) {
ok(false, 'Unexpected error fired with: ' + err);
SimpleTest.finish();
- });
+ }
}
SimpleTest.waitForExplicitFinish();
startTest();
</script>
</pre>
</body>
</html>
--- a/dom/media/test/test_mediarecorder_unsupported_src.html
+++ b/dom/media/test/test_mediarecorder_unsupported_src.html
@@ -1,96 +1,96 @@
<html>
<head>
<title>Bug 957439 - Media Recording - Assertion fail at Pause if unsupported input stream.</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
+ <script type="text/javascript" src="gUM_support.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=957439">Mozilla Bug 957439</a>
<pre id="test">
<script class="testbody" type="text/javascript">
-function startTest() {
+async function startTest() {
// also do general checks on mimetype support for audio-only
ok(MediaRecorder.isTypeSupported("audio/ogg"), 'Should support audio/ogg');
ok(MediaRecorder.isTypeSupported('audio/ogg; codecs="opus"'), 'Should support audio/ogg+opus');
ok(!MediaRecorder.isTypeSupported('audio/ogg; codecs="foobar"'), 'Should not support audio/ogg + unknown_codec');
ok(!MediaRecorder.isTypeSupported("video/webm"), 'Should not support video/webm');
ok(!MediaRecorder.isTypeSupported("video/mp4"), 'Should not support video/mp4');
- navigator.mozGetUserMedia({audio: false, video: true, fake: true},
- function(stream) {
-
- // Expected callback sequence should be:
- // 1. onerror (from start)
- // 2. ondataavailable
- // 3. onstop
- var callbackStep = 0;
- var mediaRecorder = new MediaRecorder(stream);
-
- is(mediaRecorder.stream, stream, 'Stream should be provided on creation');
+ try {
+ await setupGetUserMediaTestPrefs();
+ let stream = await navigator.mediaDevices.getUserMedia({audio: false, video: true});
- mediaRecorder.onerror = function (e) {
- callbackStep++;
- info('onerror callback fired');
- if (callbackStep == 1) {
- try {
- mediaRecorder.pause();
- ok(false, 'pause should fire an exception if called on an inactive recorder');
- } catch(e) {
- ok(e instanceof DOMException, 'pause should fire an exception ' +
- 'if called on an inactive recorder');
- is(e.name, 'InvalidStateError', 'Exception name should be InvalidStateError');
- }
- }
- ok(callbackStep == 1, 'onerror callback should handle be the 1st event fired');
- is(e.error.name, 'UnknownError', 'Error name should be UnknownError.');
- ok(e.error.stack.includes('test_mediarecorder_unsupported_src.html'),
- 'Events fired from onerror should include an error with a stack trace indicating ' +
- 'an error in this test');
- is(mediaRecorder.mimeType, '', 'mimetype should be empty');
- is(mediaRecorder.state, 'inactive', 'state is inactive');
- };
+ // Expected callback sequence should be:
+ // 1. onerror (from start)
+ // 2. ondataavailable
+ // 3. onstop
+ let callbackStep = 0;
+ let mediaRecorder = new MediaRecorder(stream);
+
+ is(mediaRecorder.stream, stream, 'Stream should be provided on creation');
- mediaRecorder.onwarning = function () {
- ok(false, 'Unexpected onwarning callback fired.');
- };
+ mediaRecorder.onerror = function (e) {
+ callbackStep++;
+ info('onerror callback fired');
+ if (callbackStep == 1) {
+ try {
+ mediaRecorder.pause();
+ ok(false, 'pause should fire an exception if called on an inactive recorder');
+ } catch(e) {
+ ok(e instanceof DOMException, 'pause should fire an exception ' +
+ 'if called on an inactive recorder');
+ is(e.name, 'InvalidStateError', 'Exception name should be InvalidStateError');
+ }
+ }
+ ok(callbackStep == 1, 'onerror callback should handle be the 1st event fired');
+ is(e.error.name, 'UnknownError', 'Error name should be UnknownError.');
+ ok(e.error.stack.includes('test_mediarecorder_unsupported_src.html'),
+ 'Events fired from onerror should include an error with a stack trace indicating ' +
+ 'an error in this test');
+ is(mediaRecorder.mimeType, '', 'mimetype should be empty');
+ is(mediaRecorder.state, 'inactive', 'state is inactive');
+ };
- mediaRecorder.ondataavailable = function (evt) {
- callbackStep++;
- info('ondataavailable callback fired');
- is(callbackStep, 2, 'ondataavailable callback should handle the 2nd event fired');
- is(evt.data.size, 0, 'data size should be zero');
- ok(evt instanceof BlobEvent,
- 'Events fired from ondataavailable should be BlobEvent');
- is(evt.data.type, '', 'encoder start fail, blob miemType should be empty');
- };
+ mediaRecorder.onwarning = function () {
+ ok(false, 'Unexpected onwarning callback fired.');
+ };
- mediaRecorder.onstop = function() {
- callbackStep++;
- info('onstop callback fired');
- is(mediaRecorder.state, 'inactive', 'state should be inactive');
- is(callbackStep, 3, 'onstop callback should handle the 3rd event fired');
- SimpleTest.finish();
- };
+ mediaRecorder.ondataavailable = function (evt) {
+ callbackStep++;
+ info('ondataavailable callback fired');
+ is(callbackStep, 2, 'ondataavailable callback should handle the 2nd event fired');
+ is(evt.data.size, 0, 'data size should be zero');
+ ok(evt instanceof BlobEvent,
+ 'Events fired from ondataavailable should be BlobEvent');
+ is(evt.data.type, '', 'encoder start fail, blob miemType should be empty');
+ };
- try {
- mediaRecorder.start();
- } catch(e) {
- ok(false, 'Should not get exception in start call.');
- }
- },
- function(err) {
- ok(false, 'Unexpected error fired with: ' + err);
+ mediaRecorder.onstop = function() {
+ callbackStep++;
+ info('onstop callback fired');
+ is(mediaRecorder.state, 'inactive', 'state should be inactive');
+ is(callbackStep, 3, 'onstop callback should handle the 3rd event fired');
SimpleTest.finish();
+ };
+
+ try {
+ mediaRecorder.start();
+ } catch(e) {
+ ok(false, 'Should not get exception in start call.');
}
- );
+ } catch (err) {
+ ok(false, 'Unexpected error fired with: ' + err);
+ SimpleTest.finish();
+ }
}
SimpleTest.waitForExplicitFinish();
// In order to generate an "unsupported stream", pref off video encoding to
// make the platform support audio encoding only.
SpecialPowers.pushPrefEnv(
{
--- a/dom/media/test/test_mediatrack_consuming_mediastream.html
+++ b/dom/media/test/test_mediatrack_consuming_mediastream.html
@@ -1,149 +1,150 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test track interfaces when consuming a MediaStream from gUM</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
+ <script type="text/javascript" src="gUM_support.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
-function startTest() {
- navigator.mozGetUserMedia({audio:true, video:true, fake:true},
- function(stream) {
- var element = document.createElement("video");
-
- var audioOnchange = 0;
- var audioOnaddtrack = 0;
- var audioOnremovetrack = 0;
- var videoOnchange = 0;
- var videoOnaddtrack = 0;
- var videoOnremovetrack = 0;
- var isPlaying = false;
-
- element.audioTracks.onaddtrack = function(e) {
- audioOnaddtrack++;
- }
-
- element.audioTracks.onremovetrack = function(e) {
- audioOnremovetrack++;
- }
-
- element.audioTracks.onchange = function(e) {
- audioOnchange++;
- }
+async function startTest() {
+ let steps = 0;
+ let audioOnchange = 0;
+ let audioOnaddtrack = 0;
+ let audioOnremovetrack = 0;
+ let videoOnchange = 0;
+ let videoOnaddtrack = 0;
+ let videoOnremovetrack = 0;
+ let isPlaying = false;
+ let element = document.createElement("video");
+ let stream;
+ try {
+ await setupGetUserMediaTestPrefs();
+ stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
+ } catch (err) {
+ ok(false, 'Unexpected error fired with: ' + err);
+ SimpleTest.finish();
+ return;
+ }
- element.videoTracks.onaddtrack = function(e) {
- videoOnaddtrack++;
- }
+ element.audioTracks.onaddtrack = function(e) {
+ audioOnaddtrack++;
+ };
- element.videoTracks.onremovetrack = function(e) {
- videoOnremovetrack++;
- }
+ element.audioTracks.onremovetrack = function(e) {
+ audioOnremovetrack++;
+ };
- element.videoTracks.onchange = function(e) {
- videoOnchange++;
- }
+ element.audioTracks.onchange = function(e) {
+ audioOnchange++;
+ };
- function checkTrackRemoved() {
- if (isPlaying) {
- is(element.audioTracks.length, 0, 'The length of audioTracks should be 0.');
- is(element.videoTracks.length, 0, 'The length of videoTracks should be 0.');
- }
- }
+ element.videoTracks.onaddtrack = function(e) {
+ videoOnaddtrack++;
+ };
- function onended() {
- ok(true, 'Event ended is expected to be fired on element.');
- checkTrackRemoved();
- element.onended = null;
- element.onplaying = null;
- element.onpause = null;
- SimpleTest.finish();
- }
+ element.videoTracks.onremovetrack = function(e) {
+ videoOnremovetrack++;
+ };
+
+ element.videoTracks.onchange = function(e) {
+ videoOnchange++;
+ };
- function checkTrackAdded() {
- isPlaying = true;
- is(audioOnaddtrack, 1, 'Calls of onaddtrack on audioTracks should be 1.');
- is(element.audioTracks.length, 1, 'The length of audioTracks should be 1.');
- ok(element.audioTracks[0].enabled, 'Audio track should be enabled as default.');
- is(videoOnaddtrack, 1, 'Calls of onaddtrack on videoTracks should be 1.');
- is(element.videoTracks.length, 1, 'The length of videoTracks should be 1.');
- is(element.videoTracks.selectedIndex, 0,
- 'The first video track is set selected as default.');
- }
+ function checkTrackRemoved() {
+ if (isPlaying) {
+ is(element.audioTracks.length, 0, 'The length of audioTracks should be 0.');
+ is(element.videoTracks.length, 0, 'The length of videoTracks should be 0.');
+ }
+ }
- function setTrackEnabled(enabled) {
- element.audioTracks[0].enabled = enabled;
- element.videoTracks[0].selected = enabled;
- }
-
- function checkTrackChanged(calls, enabled) {
- is(audioOnchange, calls, 'Calls of onchange on audioTracks should be '+calls);
- is(element.audioTracks[0].enabled, enabled,
- 'Enabled value of the audio track should be ' +enabled);
- is(videoOnchange, calls, 'Calls of onchange on videoTracks should be '+calls);
- is(element.videoTracks[0].selected, enabled,
- 'Selected value of the video track should be ' +enabled);
- var index = enabled ? 0 : -1;
- is(element.videoTracks.selectedIndex, index,
- 'SelectedIndex of video tracks should be ' +index);
- }
+ element.onended = function() {
+ ok(true, 'Event ended is expected to be fired on element.');
+ checkTrackRemoved();
+ element.onended = null;
+ element.onplaying = null;
+ element.onpause = null;
+ SimpleTest.finish();
+ }
- function onpause() {
- element.onpause = null;
- if (element.ended) {
- return;
- }
- if (steps == 1) {
- setTrackEnabled(false);
- element.onplaying = onplaying;
- element.play();
- steps++;
- } else if (steps == 2) {
- setTrackEnabled(true);
- element.onplaying = onplaying;
- element.play();
- steps++;
- }
- }
+ function checkTrackAdded() {
+ isPlaying = true;
+ is(audioOnaddtrack, 1, 'Calls of onaddtrack on audioTracks should be 1.');
+ is(element.audioTracks.length, 1, 'The length of audioTracks should be 1.');
+ ok(element.audioTracks[0].enabled, 'Audio track should be enabled as default.');
+ is(videoOnaddtrack, 1, 'Calls of onaddtrack on videoTracks should be 1.');
+ is(element.videoTracks.length, 1, 'The length of videoTracks should be 1.');
+ is(element.videoTracks.selectedIndex, 0,
+ 'The first video track is set selected as default.');
+ }
+
+ function setTrackEnabled(enabled) {
+ element.audioTracks[0].enabled = enabled;
+ element.videoTracks[0].selected = enabled;
+ }
- function onplaying() {
- element.onplaying = null;
- if (element.ended) {
- return;
- }
- if (steps == 1) {
- element.onpause = onpause;
- element.pause();
- checkTrackAdded();
- } else if (steps == 2) {
- element.onpause = onpause;
- element.pause();
- checkTrackChanged(1, false);
- } else if (steps == 3) {
- checkTrackChanged(2, true);
- stream.stop();
- }
- }
+ function checkTrackChanged(calls, enabled) {
+ is(audioOnchange, calls, 'Calls of onchange on audioTracks should be '+calls);
+ is(element.audioTracks[0].enabled, enabled,
+ 'Enabled value of the audio track should be ' +enabled);
+ is(videoOnchange, calls, 'Calls of onchange on videoTracks should be '+calls);
+ is(element.videoTracks[0].selected, enabled,
+ 'Selected value of the video track should be ' +enabled);
+ var index = enabled ? 0 : -1;
+ is(element.videoTracks.selectedIndex, index,
+ 'SelectedIndex of video tracks should be ' +index);
+ }
- var steps = 0;
- element.srcObject = stream;
+ function onpause() {
+ element.onpause = null;
+ if (element.ended) {
+ return;
+ }
+ if (steps == 1) {
+ setTrackEnabled(false);
element.onplaying = onplaying;
- element.onended = onended;
element.play();
steps++;
- },
- function(err) {
- ok(false, 'Unexpected error fired with: ' + err);
- SimpleTest.finish();
+ } else if (steps == 2) {
+ setTrackEnabled(true);
+ element.onplaying = onplaying;
+ element.play();
+ steps++;
+ }
+ }
+
+ function onplaying() {
+ element.onplaying = null;
+ if (element.ended) {
+ return;
}
- );
+ if (steps == 1) {
+ element.onpause = onpause;
+ element.pause();
+ checkTrackAdded();
+ } else if (steps == 2) {
+ element.onpause = onpause;
+ element.pause();
+ checkTrackChanged(1, false);
+ } else if (steps == 3) {
+ checkTrackChanged(2, true);
+ stream.stop();
+ }
+ }
+
+ element.onplaying = onplaying;
+ element.srcObject = stream;
+
+ steps++;
+ await element.play();
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{
"set": [
["media.track.enabled", true]
]
--- a/dom/media/test/test_mediatrack_events.html
+++ b/dom/media/test/test_mediatrack_events.html
@@ -1,127 +1,129 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test events of media track interfaces</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
+ <script type="text/javascript" src="gUM_support.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
-function startTest() {
- navigator.mozGetUserMedia({audio:true, video:true, fake:true},
- function(stream) {
- var element = document.createElement("video");
-
- isnot(element.audioTracks, undefined,
- 'HTMLMediaElement::AudioTracks() property should be available.');
- isnot(element.videoTracks, undefined,
- 'HTMLMediaElement::VideoTracks() property should be available.');
-
- function verifyEvent(e, type) {
- is(e.type, type, "Event type should be " + type);
- ok(e.isTrusted, "Event should be trusted.");
- ok(!e.bubbles, "Event shouldn't bubble.");
- ok(!e.cancelable, "Event shouldn't be cancelable.");
- }
-
- element.audioTracks.onaddtrack = function(e) {
- ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
- ok(true, 'onaddtrack is expected to be called from audioTracks.');
- verifyEvent(e, "addtrack");
- }
+async function startTest() {
+ let steps = 0;
+ let element = document.createElement("video");
+ let stream;
+ try {
+ await setupGetUserMediaTestPrefs();
+ stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
+ } catch (err) {
+ ok(false, 'Unexpected error fired with: ' + err);
+ SimpleTest.finish();
+ return;
+ }
- element.audioTracks.onremovetrack = function(e) {
- ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
- ok(true, 'onremovetrack is expected to be called from audioTracks.');
- verifyEvent(e, "removetrack");
- }
-
- element.audioTracks.onchange = function(e) {
- ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
- ok(true, 'onchange is expected to be called from audioTracks.');
- verifyEvent(e, "change");
- }
+ function verifyEvent(e, type) {
+ is(e.type, type, "Event type should be " + type);
+ ok(e.isTrusted, "Event should be trusted.");
+ ok(!e.bubbles, "Event shouldn't bubble.");
+ ok(!e.cancelable, "Event shouldn't be cancelable.");
+ }
- element.videoTracks.onaddtrack = function(e) {
- ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
- ok(true, 'onaddtrack is expected to be called from videoTracks.');
- verifyEvent(e, "addtrack");
- }
+ element.audioTracks.onaddtrack = function(e) {
+ ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
+ ok(true, 'onaddtrack is expected to be called from audioTracks.');
+ verifyEvent(e, "addtrack");
+ };
- element.videoTracks.onremovetrack = function(e) {
- ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
- ok(true, 'onremovetrack is expected to be called from videoTracks.');
- verifyEvent(e, "removetrack");
- }
+ element.audioTracks.onremovetrack = function(e) {
+ ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
+ ok(true, 'onremovetrack is expected to be called from audioTracks.');
+ verifyEvent(e, "removetrack");
+ };
+
+ element.audioTracks.onchange = function(e) {
+ ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
+ ok(true, 'onchange is expected to be called from audioTracks.');
+ verifyEvent(e, "change");
+ };
- element.videoTracks.onchange = function(e) {
- ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
- ok(true, 'onchange is expected to be called from videoTracks.');
- verifyEvent(e, "change");
- }
+ element.videoTracks.onaddtrack = function(e) {
+ ok(e instanceof TrackEvent, "Event fired from onaddtrack should be a TrackEvent");
+ ok(true, 'onaddtrack is expected to be called from videoTracks.');
+ verifyEvent(e, "addtrack");
+ };
- function onended() {
- ok(true, 'Event ended is expected to be fired on element.');
- element.onended = null;
- element.onplaying = null;
- element.onpause = null;
- //This helps to prevent these events from firing after SimpleTest.finish()
- //on B2G ICS Emulator, but not sure they have been run at all, then
- element.audioTracks.onremovetrack = null;
- element.audioTracks.onaddtrack = null;
- element.audioTracks.onchange = null;
- element.videoTracks.onremovetrack = null;
- element.videoTracks.onaddtrack = null;
- element.videoTracks.onchange = null;
- SimpleTest.finish();
- }
+ element.videoTracks.onremovetrack = function(e) {
+ ok(e instanceof TrackEvent, "Event fired from onremovetrack should be a TrackEvent");
+ ok(true, 'onremovetrack is expected to be called from videoTracks.');
+ verifyEvent(e, "removetrack");
+ };
+
+ element.videoTracks.onchange = function(e) {
+ ok(e instanceof window.Event, "Event fired from onchange should be a simple event.");
+ ok(true, 'onchange is expected to be called from videoTracks.');
+ verifyEvent(e, "change");
+ };
- function onpause() {
- element.onpause = null;
- if (element.ended) {
- return;
- }
- if (steps == 1) {
- element.audioTracks[0].enabled = false;
- element.videoTracks[0].selected = false;
- element.onplaying = onplaying;
- element.play();
- steps++;
- }
- }
+ element.onended = function() {
+ ok(true, 'Event ended is expected to be fired on element.');
+ element.onended = null;
+ element.onplaying = null;
+ element.onpause = null;
+ //This helps to prevent these events from firing after SimpleTest.finish()
+ //on B2G ICS Emulator, but not sure they have been run at all, then
+ element.audioTracks.onremovetrack = null;
+ element.audioTracks.onaddtrack = null;
+ element.audioTracks.onchange = null;
+ element.videoTracks.onremovetrack = null;
+ element.videoTracks.onaddtrack = null;
+ element.videoTracks.onchange = null;
+ SimpleTest.finish();
+ }
- function onplaying() {
- element.onplaying = null;
- if (element.ended) {
- return;
- }
- if (steps == 1) {
- element.onpause = onpause;
- element.pause();
- } else if (steps == 2) {
- stream.stop();
- }
- }
-
- var steps = 0;
- element.srcObject = stream;
+ function onpause() {
+ element.onpause = null;
+ if (element.ended) {
+ return;
+ }
+ if (steps == 1) {
+ element.audioTracks[0].enabled = false;
+ element.videoTracks[0].selected = false;
element.onplaying = onplaying;
- element.onended = onended;
element.play();
steps++;
- },
- function(err) {
- ok(false, 'Unexpected error fired with: ' + err);
- SimpleTest.finish();
+ }
+ }
+
+ function onplaying() {
+ element.onplaying = null;
+ if (element.ended) {
+ return;
}
- );
+ if (steps == 1) {
+ element.onpause = onpause;
+ element.pause();
+ } else if (steps == 2) {
+ stream.stop();
+ }
+ }
+
+ element.onplaying = onplaying;
+ element.srcObject = stream;
+
+ isnot(element.audioTracks, undefined,
+ 'HTMLMediaElement::AudioTracks() property should be available.');
+ isnot(element.videoTracks, undefined,
+ 'HTMLMediaElement::VideoTracks() property should be available.');
+
+ steps++;
+ await element.play();
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{
"set": [
["media.track.enabled", true]
]
--- a/dom/media/test/test_multiple_mediastreamtracks.html
+++ b/dom/media/test/test_multiple_mediastreamtracks.html
@@ -1,40 +1,41 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test the ability of MediaStream with multiple MediaStreamTracks</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
+ <script type="text/javascript" src="gUM_support.js"></script>
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
-function startTest() {
- navigator.mediaDevices.getUserMedia({audio:true, video:true, fake:true})
- .then(function(orgStream) {
- var a = orgStream.getAudioTracks()[0];
- var v = orgStream.getVideoTracks()[0];
- var stream = new MediaStream([a, a, a, a, v, v, v].map(track => track.clone()));
- var element = document.createElement("video");
+async function startTest() {
+ try {
+ await setupGetUserMediaTestPrefs();
+ let orgStream = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
+ let a = orgStream.getAudioTracks()[0];
+ let v = orgStream.getVideoTracks()[0];
+ let stream = new MediaStream([a, a, a, a, v, v, v].map(track => track.clone()));
+ let element = document.createElement("video");
element.onloadedmetadata = function() {
is(stream.getAudioTracks().length, 4, 'Length of audio tracks should be 4.');
is(stream.getVideoTracks().length, 3, 'Length of vudio tracks should be 3.');
SimpleTest.finish();
};
element.srcObject = stream;
element.play();
- })
- .catch(function(reason) {
- ok(false, "unexpected error = " + reason.message);
+ } catch (err) {
+ ok(false, 'Unexpected error fired with: ' + err);
SimpleTest.finish();
- });
+ }
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{
"set": [
["media.track.enabled", true]
]
--- a/dom/media/test/test_streams_individual_pause.html
+++ b/dom/media/test/test_streams_individual_pause.html
@@ -1,79 +1,81 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for bug 1073406. Pausing a video element should not pause another playing the same stream.</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="manifest.js"></script>
+ <script type="text/javascript" src="gUM_support.js"></script>
</head>
<body>
<video id="video1" autoplay></video>
<video id="video2" autoplay></video>
<script class="testbody" type="text/javascript">
-SimpleTest.waitForExplicitFinish();
+async function startTest() {
+ function getVideoImagePixelData(v) {
+ let canvas = document.createElement("canvas");
+ let ctx = canvas.getContext("2d");
+ ctx.drawImage(v, 0, 0);
+ let imgData = ctx.getImageData(canvas.width/2, canvas.height/2, 1, 1).data;
+ return "r" + imgData[0] +
+ "g" + imgData[1] +
+ "b" + imgData[2] +
+ "a" + imgData[3];
+ }
+
+ try {
+ // This test expects fake devices so that the video color will change
+ // over time, explicitly request fakes.
+ await pushGetUserMediaTestPrefs({fakeAudio: true, fakeVideo: true});
+ let stream = await navigator.mediaDevices.getUserMedia({video: true});
+ let video1 = document.getElementById('video1');
+ let video2 = document.getElementById('video2');
+
+ let src = URL.createObjectURL(stream);
+ video1.src = src;
+ video2.src = src;
+
+ video1.onplaying = () => video1.pause();
+
+ let v1PausedImageData;
+ let v2PausedImageData;
-var getVideoImagePixelData = function(v) {
- var canvas = document.createElement("canvas");
- var ctx = canvas.getContext("2d");
- ctx.drawImage(v, 0, 0);
- var imgData = ctx.getImageData(canvas.width/2, canvas.height/2, 1, 1).data;
- return "r" + imgData[0] +
- "g" + imgData[1] +
- "b" + imgData[2] +
- "a" + imgData[3];
+ video1.onpause = function() {
+ v1PausedImageData = getVideoImagePixelData(video1);
+ v2PausedImageData = getVideoImagePixelData(video2);
+ v2TimesToTest = 3;
+ video2.ontimeupdate = function() {
+ if (getVideoImagePixelData(video2) === v2PausedImageData) {
+ // Wait until video2 has progressed it's video.
+ // If it doesn't, we'll time out and fail.
+ info("video2 has not progressed. Waiting.");
+ return;
+ }
+
+ if (--v2TimesToTest > 0) {
+ // Wait for a while to be sure video1 would have gotten a frame
+ // if it is playing.
+ info("video2 progressed OK");
+ return;
+ }
+
+ video2.ontimeupdate = null;
+ ok(true, "video2 is playing");
+ isnot(video1.currentTime, video2.currentTime,
+ "v1 and v2 should not be at the same currentTime");
+ is(v1PausedImageData, getVideoImagePixelData(video1),
+ "video1 video frame should not have updated since video1 paused");
+ SimpleTest.finish();
+ };
+ };
+ } catch (error) {
+ ok(false, "getUserMedia should not fail, got " + error.name);
+ SimpleTest.finish();
+ }
}
-// This test does not appear to work with the "Dummy video source" provided on
-// linux through the "media.video_loopback_dev" pref in the tree test environment.
-// We force a stream always by requesting `fake: true` here.
-
-navigator.mozGetUserMedia({video: true, fake: true },
- function(stream) {
- var stream = stream;
- var video1 = document.getElementById('video1');
- var video2 = document.getElementById('video2');
-
- var src = URL.createObjectURL(stream);
- video1.src = src;
- video2.src = src;
-
- video1.onplaying = () => video1.pause();
-
- var v1PausedImageData;
- var v2PausedImageData;
-
- video1.onpause = function() {
- v1PausedImageData = getVideoImagePixelData(video1);
- v2PausedImageData = getVideoImagePixelData(video2);
- v2TimesToTest = 3;
- video2.ontimeupdate = function() {
- if (getVideoImagePixelData(video2) === v2PausedImageData) {
- // Wait until video2 has progressed it's video.
- // If it doesn't, we'll time out and fail.
- info("video2 has not progressed. Waiting.");
- return;
- }
-
- if (--v2TimesToTest > 0) {
- // Wait for a while to be sure video1 would have gotten a frame
- // if it is playing.
- info("video2 progressed OK");
- return;
- }
-
- video2.ontimeupdate = null;
- ok(true, "video2 is playing");
- isnot(video1.currentTime, video2.currentTime,
- "v1 and v2 should not be at the same currentTime");
- is(v1PausedImageData, getVideoImagePixelData(video1),
- "video1 video frame should not have updated since video1 paused");
- SimpleTest.finish();
- };
- };
-}, function(error) {
- ok(false, "getUserMedia should not fail, got " + error.name);
- SimpleTest.finish();
-});
+SimpleTest.waitForExplicitFinish();
+startTest();
</script>
</body>
</html>