--- a/dom/media/tests/mochitest/constraints.js
+++ b/dom/media/tests/mochitest/constraints.js
@@ -65,23 +65,30 @@ var common_tests = [
/**
* Starts the test run by running through each constraint
* test by verifying that the right resolution and rejection is fired.
*/
function testConstraints(tests) {
- function testgum(prev, test) {
- return prev.then(() => navigator.mediaDevices.getUserMedia(test.constraints))
- .then(() => is(null, test.error, test.message),
- reason => is(reason.name, test.error, test.message + ": " + reason.message));
+ function testgum(p, test) {
+ return p.then(function() {
+ return navigator.mediaDevices.getUserMedia(test.constraints);
+ })
+ .then(function() {
+ is(null, test.error, test.message);
+ }, function(reason) {
+ is(reason.name, test.error, test.message + ": " + reason.message);
+ });
}
- var p = new Promise(resolve => SpecialPowers.pushPrefEnv({
- set : [ ['media.getusermedia.browser.enabled', false],
- ['media.getusermedia.screensharing.enabled', false] ]
- }, resolve));
+ var p = new Promise(r => SpecialPowers.pushPrefEnv({
+ set : [ ['media.getusermedia.browser.enabled', false],
+ ['media.getusermedia.screensharing.enabled', false] ]
+ }, r));
- tests.reduce(testgum, p)
- .catch(reason => ok(false, "Unexpected failure: " + reason.message))
- .then(SimpleTest.finish);
+ tests.forEach(function(test) {
+ p = testgum(p, test);
+ });
+ p.catch(reason => ok(false, "Unexpected failure: " + reason.message))
+ .then(SimpleTest.finish);
}
--- a/dom/media/tests/mochitest/dataChannel.js
+++ b/dom/media/tests/mochitest/dataChannel.js
@@ -1,170 +1,230 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/**
- * Returns the contents of a blob as text
- *
- * @param {Blob} blob
- The blob to retrieve the contents from
- */
-function getBlobContent(blob) {
- return new Promise(resolve => {
- var reader = new FileReader();
- // Listen for 'onloadend' which will always be called after a success or failure
- reader.onloadend = event => resolve(event.target.result);
- reader.readAsText(blob);
- });
-}
-
function addInitialDataChannel(chain) {
chain.insertBefore('PC_LOCAL_CREATE_OFFER', [
- function PC_REMOTE_EXPECT_DATA_CHANNEL(test) {
- test.pcRemote.expectDataChannel();
- },
+ ['PC_LOCAL_CREATE_DATA_CHANNEL',
+ function (test) {
+ var channel = test.pcLocal.createDataChannel({});
- function PC_LOCAL_CREATE_DATA_CHANNEL(test) {
- var channel = test.pcLocal.createDataChannel({});
- is(channel.binaryType, "blob", channel + " is of binary type 'blob'");
- is(channel.readyState, "connecting", channel + " is in state: 'connecting'");
+ is(channel.binaryType, "blob", channel + " is of binary type 'blob'");
+ is(channel.readyState, "connecting", channel + " is in state: 'connecting'");
+
+ is(test.pcLocal.signalingState, STABLE,
+ "Create datachannel does not change signaling state");
- is(test.pcLocal.signalingState, STABLE,
- "Create datachannel does not change signaling state");
- }
+ test.next();
+ }
+ ]
]);
-
+ chain.insertAfter('PC_REMOTE_CREATE_ANSWER', [
+ [
+ 'PC_LOCAL_SETUP_DATA_CHANNEL_CALLBACK',
+ function (test) {
+ test.waitForInitialDataChannel(test.pcLocal, function () {
+ ok(true, test.pcLocal + " dataChannels[0] switched to 'open'");
+ },
+ // At this point a timeout failure will be of no value
+ null);
+ test.next();
+ }
+ ],
+ [
+ 'PC_REMOTE_SETUP_DATA_CHANNEL_CALLBACK',
+ function (test) {
+ test.waitForInitialDataChannel(test.pcRemote, function () {
+ ok(true, test.pcRemote + " dataChannels[0] switched to 'open'");
+ },
+ // At this point a timeout failure will be of no value
+ null);
+ test.next();
+ }
+ ]
+ ]);
chain.insertBefore('PC_LOCAL_CHECK_MEDIA_TRACKS', [
- function PC_LOCAL_VERIFY_DATA_CHANNEL_STATE(test) {
- return test.pcLocal.dataChannels[0].opened;
- },
-
- function PC_REMOTE_VERIFY_DATA_CHANNEL_STATE(test) {
- return test.pcRemote.nextDataChannel.then(channel => channel.opened);
- }
+ [
+ 'PC_LOCAL_VERIFY_DATA_CHANNEL_STATE',
+ function (test) {
+ test.waitForInitialDataChannel(test.pcLocal, function() {
+ test.next();
+ }, function() {
+ ok(false, test.pcLocal + " initial dataChannels[0] failed to switch to 'open'");
+ //TODO: use stopAndExit() once bug 1019323 has landed
+ unexpectedEventAndFinish(this, 'timeout')
+ // to prevent test framework timeouts
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_REMOTE_VERIFY_DATA_CHANNEL_STATE',
+ function (test) {
+ test.waitForInitialDataChannel(test.pcRemote, function() {
+ test.next();
+ }, function() {
+ ok(false, test.pcRemote + " initial dataChannels[0] failed to switch to 'open'");
+ //TODO: use stopAndExit() once bug 1019323 has landed
+ unexpectedEventAndFinish(this, 'timeout');
+ // to prevent test framework timeouts
+ test.next();
+ });
+ }
+ ]
]);
chain.removeAfter('PC_REMOTE_CHECK_ICE_CONNECTIONS');
chain.append([
- function SEND_MESSAGE(test) {
- var message = "Lorem ipsum dolor sit amet";
+ [
+ 'SEND_MESSAGE',
+ function (test) {
+ var message = "Lorem ipsum dolor sit amet";
- return test.send(message).then(result => {
- is(result.data, message, "Message correctly transmitted from pcLocal to pcRemote.");
- });
- },
+ test.send(message, function (channel, data) {
+ is(data, message, "Message correctly transmitted from pcLocal to pcRemote.");
- function SEND_BLOB(test) {
- var contents = ["At vero eos et accusam et justo duo dolores et ea rebum."];
- var blob = new Blob(contents, { "type" : "text/plain" });
+ test.next();
+ });
+ }
+ ],
+ [
+ 'SEND_BLOB',
+ function (test) {
+ var contents = ["At vero eos et accusam et justo duo dolores et ea rebum."];
+ var blob = new Blob(contents, { "type" : "text/plain" });
- return test.send(blob).then(result => {
- ok(result.data instanceof Blob, "Received data is of instance Blob");
- is(result.data.size, blob.size, "Received data has the correct size.");
+ test.send(blob, function (channel, data) {
+ ok(data instanceof Blob, "Received data is of instance Blob");
+ is(data.size, blob.size, "Received data has the correct size.");
- return getBlobContent(result.data);
- }).then(recv_contents =>
- is(recv_contents, contents, "Received data has the correct content."));
- },
+ getBlobContent(data, function (recv_contents) {
+ is(recv_contents, contents, "Received data has the correct content.");
- function CREATE_SECOND_DATA_CHANNEL(test) {
- return test.createDataChannel({ }).then(result => {
- var sourceChannel = result.local;
- var targetChannel = result.remote;
- is(sourceChannel.readyState, "open", sourceChannel + " is in state: 'open'");
- is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
-
- is(targetChannel.binaryType, "blob", targetChannel + " is of binary type 'blob'");
- });
- },
+ test.next();
+ });
+ });
+ }
+ ],
+ [
+ 'CREATE_SECOND_DATA_CHANNEL',
+ function (test) {
+ test.createDataChannel({ }, function (sourceChannel, targetChannel) {
+ is(sourceChannel.readyState, "open", sourceChannel + " is in state: 'open'");
+ is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
- function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL(test) {
- var channels = test.pcRemote.dataChannels;
- var message = "I am the Omega";
+ is(targetChannel.binaryType, "blob", targetChannel + " is of binary type 'blob'");
+ is(targetChannel.readyState, "open", targetChannel + " is in state: 'open'");
- return test.send(message).then(result => {
- is(channels.indexOf(result.channel), channels.length - 1, "Last channel used");
- is(result.data, message, "Received message has the correct content.");
- });
- },
+ test.next();
+ });
+ }
+ ],
+ [
+ 'SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL',
+ function (test) {
+ var channels = test.pcRemote.dataChannels;
+ var message = "Lorem ipsum dolor sit amet";
+ test.send(message, function (channel, data) {
+ is(channels.indexOf(channel), channels.length - 1, "Last channel used");
+ is(data, message, "Received message has the correct content.");
- function SEND_MESSAGE_THROUGH_FIRST_CHANNEL(test) {
- var message = "Message through 1st channel";
- var options = {
- sourceChannel: test.pcLocal.dataChannels[0],
- targetChannel: test.pcRemote.dataChannels[0]
- };
+ test.next();
+ });
+ }
+ ],
+ [
+ 'SEND_MESSAGE_THROUGH_FIRST_CHANNEL',
+ function (test) {
+ var message = "Message through 1st channel";
+ var options = {
+ sourceChannel: test.pcLocal.dataChannels[0],
+ targetChannel: test.pcRemote.dataChannels[0]
+ };
- return test.send(message, options).then(result => {
- is(test.pcRemote.dataChannels.indexOf(result.channel), 0, "1st channel used");
- is(result.data, message, "Received message has the correct content.");
- });
- },
-
+ test.send(message, function (channel, data) {
+ is(test.pcRemote.dataChannels.indexOf(channel), 0, "1st channel used");
+ is(data, message, "Received message has the correct content.");
- function SEND_MESSAGE_BACK_THROUGH_FIRST_CHANNEL(test) {
- var message = "Return a message also through 1st channel";
- var options = {
- sourceChannel: test.pcRemote.dataChannels[0],
- targetChannel: test.pcLocal.dataChannels[0]
- };
+ test.next();
+ }, options);
+ }
+ ],
+ [
+ 'SEND_MESSAGE_BACK_THROUGH_FIRST_CHANNEL',
+ function (test) {
+ var message = "Return a message also through 1st channel";
+ var options = {
+ sourceChannel: test.pcRemote.dataChannels[0],
+ targetChannel: test.pcLocal.dataChannels[0]
+ };
- return test.send(message, options).then(result => {
- is(test.pcLocal.dataChannels.indexOf(result.channel), 0, "1st channel used");
- is(result.data, message, "Return message has the correct content.");
- });
- },
+ test.send(message, function (channel, data) {
+ is(test.pcLocal.dataChannels.indexOf(channel), 0, "1st channel used");
+ is(data, message, "Return message has the correct content.");
- function CREATE_NEGOTIATED_DATA_CHANNEL(test) {
- var options = {
- negotiated:true,
- id: 5,
- protocol: "foo/bar",
- ordered: false,
- maxRetransmits: 500
- };
- return test.createDataChannel(options).then(result => {
- var sourceChannel2 = result.local;
- var targetChannel2 = result.remote;
- is(sourceChannel2.readyState, "open", sourceChannel2 + " is in state: 'open'");
- is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
+ test.next();
+ }, options);
+ }
+ ],
+ [
+ 'CREATE_NEGOTIATED_DATA_CHANNEL',
+ function (test) {
+ var options = {negotiated:true, id: 5, protocol:"foo/bar", ordered:false,
+ maxRetransmits:500};
+ test.createDataChannel(options, function (sourceChannel2, targetChannel2) {
+ is(sourceChannel2.readyState, "open", sourceChannel2 + " is in state: 'open'");
+ is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
- is(targetChannel2.binaryType, "blob", targetChannel2 + " is of binary type 'blob'");
+ is(targetChannel2.binaryType, "blob", targetChannel2 + " is of binary type 'blob'");
+ is(targetChannel2.readyState, "open", targetChannel2 + " is in state: 'open'");
- is(sourceChannel2.id, options.id, sourceChannel2 + " id is:" + sourceChannel2.id);
- var reliable = !options.ordered ? false : (options.maxRetransmits || options.maxRetransmitTime);
- is(sourceChannel2.protocol, options.protocol, sourceChannel2 + " protocol is:" + sourceChannel2.protocol);
- is(sourceChannel2.reliable, reliable, sourceChannel2 + " reliable is:" + sourceChannel2.reliable);
- /*
- These aren't exposed by IDL yet
+ if (options.id != undefined) {
+ is(sourceChannel2.id, options.id, sourceChannel2 + " id is:" + sourceChannel2.id);
+ }
+ else {
+ options.id = sourceChannel2.id;
+ }
+ var reliable = !options.ordered ? false : (options.maxRetransmits || options.maxRetransmitTime);
+ is(sourceChannel2.protocol, options.protocol, sourceChannel2 + " protocol is:" + sourceChannel2.protocol);
+ is(sourceChannel2.reliable, reliable, sourceChannel2 + " reliable is:" + sourceChannel2.reliable);
+ /*
+ These aren't exposed by IDL yet
is(sourceChannel2.ordered, options.ordered, sourceChannel2 + " ordered is:" + sourceChannel2.ordered);
is(sourceChannel2.maxRetransmits, options.maxRetransmits, sourceChannel2 + " maxRetransmits is:" +
- sourceChannel2.maxRetransmits);
+ sourceChannel2.maxRetransmits);
is(sourceChannel2.maxRetransmitTime, options.maxRetransmitTime, sourceChannel2 + " maxRetransmitTime is:" +
- sourceChannel2.maxRetransmitTime);
- */
+ sourceChannel2.maxRetransmitTime);
+ */
- is(targetChannel2.id, options.id, targetChannel2 + " id is:" + targetChannel2.id);
- is(targetChannel2.protocol, options.protocol, targetChannel2 + " protocol is:" + targetChannel2.protocol);
- is(targetChannel2.reliable, reliable, targetChannel2 + " reliable is:" + targetChannel2.reliable);
- /*
- These aren't exposed by IDL yet
- is(targetChannel2.ordered, options.ordered, targetChannel2 + " ordered is:" + targetChannel2.ordered);
+ is(targetChannel2.id, options.id, targetChannel2 + " id is:" + targetChannel2.id);
+ is(targetChannel2.protocol, options.protocol, targetChannel2 + " protocol is:" + targetChannel2.protocol);
+ is(targetChannel2.reliable, reliable, targetChannel2 + " reliable is:" + targetChannel2.reliable);
+ /*
+ These aren't exposed by IDL yet
+ is(targetChannel2.ordered, options.ordered, targetChannel2 + " ordered is:" + targetChannel2.ordered);
is(targetChannel2.maxRetransmits, options.maxRetransmits, targetChannel2 + " maxRetransmits is:" +
- targetChannel2.maxRetransmits);
+ targetChannel2.maxRetransmits);
is(targetChannel2.maxRetransmitTime, options.maxRetransmitTime, targetChannel2 + " maxRetransmitTime is:" +
- targetChannel2.maxRetransmitTime);
- */
- });
- },
+ targetChannel2.maxRetransmitTime);
+ */
- function SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL2(test) {
- var channels = test.pcRemote.dataChannels;
- var message = "I am the walrus; Goo goo g'joob";
+ test.next();
+ });
+ }
+ ],
+ [
+ 'SEND_MESSAGE_THROUGH_LAST_OPENED_CHANNEL2',
+ function (test) {
+ var channels = test.pcRemote.dataChannels;
+ var message = "Lorem ipsum dolor sit amet";
- return test.send(message).then(result => {
- is(channels.indexOf(result.channel), channels.length - 1, "Last channel used");
- is(result.data, message, "Received message has the correct content.");
- });
- }
+ test.send(message, function (channel, data) {
+ is(channels.indexOf(channel), channels.length - 1, "Last channel used");
+ is(data, message, "Received message has the correct content.");
+
+ test.next();
+ });
+ }
+ ]
]);
}
--- a/dom/media/tests/mochitest/head.js
+++ b/dom/media/tests/mochitest/head.js
@@ -1,16 +1,15 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict";
-
var Cc = SpecialPowers.Cc;
var Ci = SpecialPowers.Ci;
+var Cr = SpecialPowers.Cr;
// Specifies whether we are using fake streams to run this automation
var FAKE_ENABLED = true;
try {
var audioDevice = SpecialPowers.getCharPref('media.audio_loopback_dev');
var videoDevice = SpecialPowers.getCharPref('media.video_loopback_dev');
dump('TEST DEVICES: Using media devices:\n');
dump('audio: ' + audioDevice + '\nvideo: ' + videoDevice + '\n');
@@ -28,37 +27,37 @@ try {
* Meta information of the test
* @param {string} meta.title
* Description of the test
* @param {string} [meta.bug]
* Bug the test was created for
* @param {boolean} [meta.visible=false]
* Visibility of the media elements
*/
-function realCreateHTML(meta) {
+function createHTML(meta) {
var test = document.getElementById('test');
// Create the head content
var elem = document.createElement('meta');
elem.setAttribute('charset', 'utf-8');
document.head.appendChild(elem);
var title = document.createElement('title');
title.textContent = meta.title;
document.head.appendChild(title);
// Create the body content
var anchor = document.createElement('a');
- anchor.textContent = meta.title;
+ anchor.setAttribute('target', '_blank');
+
if (meta.bug) {
anchor.setAttribute('href', 'https://bugzilla.mozilla.org/show_bug.cgi?id=' + meta.bug);
- } else {
- anchor.setAttribute('target', '_blank');
}
+ anchor.textContent = meta.title;
document.body.insertBefore(anchor, test);
var display = document.createElement('p');
display.setAttribute('id', 'display');
document.body.insertBefore(display, test);
var content = document.createElement('div');
content.setAttribute('id', 'content');
@@ -77,119 +76,110 @@ function realCreateHTML(meta) {
* Description to use for the element
* @return {HTMLMediaElement} The created HTML media element
*/
function createMediaElement(type, label) {
var id = label + '_' + type;
var element = document.getElementById(id);
// Sanity check that we haven't created the element already
- if (element) {
+ if (element)
return element;
- }
element = document.createElement(type === 'audio' ? 'audio' : 'video');
element.setAttribute('id', id);
element.setAttribute('height', 100);
element.setAttribute('width', 150);
element.setAttribute('controls', 'controls');
- element.setAttribute('autoplay', 'autoplay');
document.getElementById('content').appendChild(element);
return element;
}
/**
* Wrapper function for mozGetUserMedia to allow a singular area of control
* for determining whether we run this with fake devices or not.
*
* @param {Dictionary} constraints
* The constraints for this mozGetUserMedia callback
+ * @param {Function} onSuccess
+ * The success callback if the stream is successfully retrieved
+ * @param {Function} onError
+ * The error callback if the stream fails to be retrieved
*/
-function getUserMedia(constraints) {
+function getUserMedia(constraints, onSuccess, onError) {
if (!("fake" in constraints) && FAKE_ENABLED) {
constraints["fake"] = FAKE_ENABLED;
}
info("Call getUserMedia for " + JSON.stringify(constraints));
- return navigator.mediaDevices.getUserMedia(constraints);
+ navigator.mozGetUserMedia(constraints, onSuccess, onError);
}
-// These are the promises we use to track that the prerequisites for the test
-// are in place before running it. Users of this file need to ensure that they
-// also provide a promise called `scriptsReady` as well.
-var setTestOptions;
-var testConfigured = new Promise(r => setTestOptions = r);
-function setupEnvironment() {
- if (!window.SimpleTest) {
- return Promise.resolve();
- }
-
- // Running as a Mochitest.
- SimpleTest.requestFlakyTimeout("WebRTC inherently depends on timeouts");
- window.finish = () => SimpleTest.finish();
- SpecialPowers.pushPrefEnv({
- 'set': [
+/**
+ * Setup any Mochitest for WebRTC by enabling the preference for
+ * peer connections. As by bug 797979 it will also enable mozGetUserMedia()
+ * and disable the mozGetUserMedia() permission checking.
+ *
+ * @param {Function} aCallback
+ * Test method to execute after initialization
+ */
+function runTest(aCallback) {
+ if (window.SimpleTest) {
+ // Running as a Mochitest.
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.requestFlakyTimeout("WebRTC inherently depends on timeouts");
+ SpecialPowers.pushPrefEnv({'set': [
['dom.messageChannel.enabled', true],
['media.peerconnection.enabled', true],
['media.peerconnection.identity.enabled', true],
['media.peerconnection.identity.timeout', 12000],
['media.peerconnection.default_iceservers', '[]'],
['media.navigator.permission.disabled', true],
['media.getusermedia.screensharing.enabled', true],
- ['media.getusermedia.screensharing.allowed_domains', "mochi.test"]
- ]
- }, setTestOptions);
+ ['media.getusermedia.screensharing.allowed_domains', "mochi.test"]]
+ }, function () {
+ try {
+ aCallback();
+ }
+ catch (err) {
+ generateErrorCallback()(err);
+ }
+ });
+ } else {
+ // Steeplechase, let it call the callback.
+ window.run_test = function(is_initiator) {
+ var options = {is_local: is_initiator,
+ is_remote: !is_initiator};
+ aCallback(options);
+ };
+ // Also load the steeplechase test code.
+ var s = document.createElement("script");
+ s.src = "/test.js";
+ document.head.appendChild(s);
+ }
}
-// This is called by steeplechase; which provides the test configuration options
-// directly to the test through this function. If we're not on steeplechase,
-// the test is configured directly and immediately.
-function run_test(is_initiator) {
- var options = { is_local: is_initiator,
- is_remote: !is_initiator };
-
- // Also load the steeplechase test code.
- var s = document.createElement("script");
- s.src = "/test.js";
- s.onload = () => setTestOptions(options);
- document.head.appendChild(s);
-}
-
-function runTestWhenReady(testFunc) {
- setupEnvironment();
- return Promise.all([scriptsReady, testConfigured]).then(() => {
- try {
- return testConfigured.then(options => testFunc(options));
- } catch (e) {
- ok(false, 'Error executing test: ' + e +
- ((typeof e.stack === 'string') ?
- (' ' + e.stack.split('\n').join(' ... ')) : ''));
- }
- });
-}
-
-
/**
* Checks that the media stream tracks have the expected amount of tracks
* with the correct kind and id based on the type and constraints given.
*
* @param {Object} constraints specifies whether the stream should have
* audio, video, or both
* @param {String} type the type of media stream tracks being checked
* @param {sequence<MediaStreamTrack>} mediaStreamTracks the media stream
* tracks being checked
*/
function checkMediaStreamTracksByType(constraints, type, mediaStreamTracks) {
- if (constraints[type]) {
+ if(constraints[type]) {
is(mediaStreamTracks.length, 1, 'One ' + type + ' track shall be present');
- if (mediaStreamTracks.length) {
+ if(mediaStreamTracks.length) {
is(mediaStreamTracks[0].kind, type, 'Track kind should be ' + type);
ok(mediaStreamTracks[0].id, 'Track id should be defined');
}
} else {
is(mediaStreamTracks.length, 0, 'No ' + type + ' tracks shall be present');
}
}
@@ -203,37 +193,39 @@ function checkMediaStreamTracksByType(co
*/
function checkMediaStreamTracks(constraints, mediaStream) {
checkMediaStreamTracksByType(constraints, 'audio',
mediaStream.getAudioTracks());
checkMediaStreamTracksByType(constraints, 'video',
mediaStream.getVideoTracks());
}
-/*** Utility methods */
-
-/** The dreadful setTimeout, use sparingly */
-function wait(time) {
- return new Promise(r => setTimeout(r, time));
-}
+/**
+ * Utility methods
+ */
-/** The even more dreadful setInterval, use even more sparingly */
-function waitUntil(func, time) {
- return new Promise(resolve => {
- var interval = setInterval(() => {
- if (func()) {
- clearInterval(interval);
- resolve();
- }
- }, time || 200);
- });
+/**
+ * Returns the contents of a blob as text
+ *
+ * @param {Blob} blob
+ The blob to retrieve the contents from
+ * @param {Function} onSuccess
+ Callback with the blobs content as parameter
+ */
+function getBlobContent(blob, onSuccess) {
+ var reader = new FileReader();
+
+ // Listen for 'onloadend' which will always be called after a success or failure
+ reader.onloadend = function (event) {
+ onSuccess(event.target.result);
+ };
+
+ reader.readAsText(blob);
}
-/*** Test control flow methods */
-
/**
* Generates a callback function fired only under unexpected circumstances
* while running the tests. The generated function kills off the test as well
* gracefully.
*
* @param {String} [message]
* An optional message to show if no object gets passed into the
* generated callback method.
@@ -241,247 +233,60 @@ function waitUntil(func, time) {
function generateErrorCallback(message) {
var stack = new Error().stack.split("\n");
stack.shift(); // Don't include this instantiation frame
/**
* @param {object} aObj
* The object fired back from the callback
*/
- return aObj => {
+ return function (aObj) {
if (aObj) {
if (aObj.name && aObj.message) {
ok(false, "Unexpected callback for '" + aObj.name +
"' with message = '" + aObj.message + "' at " +
JSON.stringify(stack));
} else {
ok(false, "Unexpected callback with = '" + aObj +
"' at: " + JSON.stringify(stack));
}
} else {
ok(false, "Unexpected callback with message = '" + message +
"' at: " + JSON.stringify(stack));
}
- throw new Error("Unexpected callback");
+ SimpleTest.finish();
}
}
-var unexpectedEventArrived;
-var rejectOnUnexpectedEvent = new Promise((x, reject) => {
- unexpectedEventArrived = reject;
-});
-
/**
* Generates a callback function fired only for unexpected events happening.
*
* @param {String} description
Description of the object for which the event has been fired
* @param {String} eventName
Name of the unexpected event
*/
-function unexpectedEvent(message, eventName) {
+function unexpectedEventAndFinish(message, eventName) {
var stack = new Error().stack.split("\n");
stack.shift(); // Don't include this instantiation frame
- return e => {
- var details = "Unexpected event '" + eventName + "' fired with message = '" +
- message + "' at: " + JSON.stringify(stack);
- ok(false, details);
- unexpectedEventArrived(new Error(details));
+ return function () {
+ ok(false, "Unexpected event '" + eventName + "' fired with message = '" +
+ message + "' at: " + JSON.stringify(stack));
+ SimpleTest.finish();
}
}
-/**
- * Implements the one-shot event pattern used throughout. Each of the 'onxxx'
- * attributes on the wrappers can be set with a custom handler. Prior to the
- * handler being set, if the event fires, it causes the test execution to halt.
- * That handler is used exactly once, after which the original, error-generating
- * handler is re-installed. Thus, each event handler is used at most once.
- *
- * @param {object} wrapper
- * The wrapper on which the psuedo-handler is installed
- * @param {object} obj
- * The real source of events
- * @param {string} event
- * The name of the event
- */
-function createOneShotEventWrapper(wrapper, obj, event) {
- var onx = 'on' + event;
- var unexpected = unexpectedEvent(wrapper, event);
- wrapper[onx] = unexpected;
- obj[onx] = e => {
- info(wrapper + ': "on' + event + '" event fired');
- e.wrapper = wrapper;
- wrapper[onx](e);
- wrapper[onx] = unexpected;
- };
-}
+function IsMacOSX10_6orOlder() {
+ var is106orOlder = false;
-
-/**
- * This class executes a series of functions in a continuous sequence.
- * Promise-bearing functions are executed after the previous promise completes.
- *
- * @constructor
- * @param {object} framework
- * A back reference to the framework which makes use of the class. It is
- * passed to each command callback.
- * @param {function[]} commandList
- * Commands to set during initialization
- */
-function CommandChain(framework, commandList) {
- this._framework = framework;
- this.commands = commandList || [ ];
+ if (navigator.platform.indexOf("Mac") == 0) {
+ var version = Cc["@mozilla.org/system-info;1"]
+ .getService(SpecialPowers.Ci.nsIPropertyBag2)
+ .getProperty("version");
+ // the next line is correct: Mac OS 10.6 corresponds to Darwin version 10.x !
+ // Mac OS 10.7 is Darwin version 11.x. the |version| string we've got here
+ // is the Darwin version.
+ is106orOlder = (parseFloat(version) < 11.0);
+ }
+ return is106orOlder;
}
-CommandChain.prototype = {
- /**
- * Start the command chain. This returns a promise that always resolves
- * cleanly (this catches errors and fails the test case).
- */
- execute: function () {
- return this.commands.reduce((prev, next, i) => {
- if (typeof next !== 'function' || !next.name) {
- throw new Error('registered non-function' + next);
- }
-
- return prev.then(() => {
- info('Run step ' + (i + 1) + ': ' + next.name);
- return Promise.race([ next(this._framework), rejectOnUnexpectedEvent ]);
- });
- }, Promise.resolve())
- .catch(e =>
- ok(false, 'Error in test execution: ' + e +
- ((typeof e.stack === 'string') ?
- (' ' + e.stack.split('\n').join(' ... ')) : '')));
- },
-
- /**
- * Add new commands to the end of the chain
- */
- append: function(commands) {
- this.commands = this.commands.concat(commands);
- },
-
- /**
- * Returns the index of the specified command in the chain.
- */
- indexOf: function(functionOrName) {
- if (typeof functionOrName === 'string') {
- return this.commands.findIndex(f => f.name === functionOrName);
- }
- return this.commands.indexOf(functionOrName);
- },
-
- /**
- * Inserts the new commands after the specified command.
- */
- insertAfter: function(functionOrName, commands) {
- this._insertHelper(functionOrName, commands, 1);
- },
-
- /**
- * Inserts the new commands before the specified command.
- */
- insertBefore: function(functionOrName, commands) {
- this._insertHelper(functionOrName, commands, 0);
- },
-
- _insertHelper: function(functionOrName, commands, delta) {
- var index = this.indexOf(functionOrName);
-
- if (index >= 0) {
- this.commands = [].concat(
- this.commands.slice(0, index + delta),
- commands,
- this.commands.slice(index + delta));
- }
- },
-
- /**
- * Removes the specified command, returns what was removed.
- */
- remove: function(functionOrName) {
- var index = this.indexOf(functionOrName);
- if (index >= 0) {
- return this.commands.splice(index, 1);
- }
- return [];
- },
-
- /**
- * Removes all commands after the specified one, returns what was removed.
- */
- removeAfter: function(functionOrName) {
- var index = this.indexOf(functionOrName);
- if (index >= 0) {
- return this.commands.splice(index + 1);
- }
- return [];
- },
-
- /**
- * Removes all commands before the specified one, returns what was removed.
- */
- removeBefore: function(functionOrName) {
- var index = this.indexOf(functionOrName);
- if (index >= 0) {
- return this.commands.splice(0, index);
- }
- return [];
- },
-
- /**
- * Replaces a single command, returns what was removed.
- */
- replace: function(functionOrName, commands) {
- this.insertBefore(functionOrName, commands);
- return this.remove(functionOrName);
- },
-
- /**
- * Replaces all commands after the specified one, returns what was removed.
- */
- replaceAfter: function(functionOrName, commands) {
- var oldCommands = this.removeAfter(functionOrName);
- this.append(commands);
- return oldCommands;
- },
-
- /**
- * Replaces all commands before the specified one, returns what was removed.
- */
- replaceBefore: function(functionOrName, commands) {
- var oldCommands = this.removeBefore(functionOrName);
- this.insertBefore(functionOrName, commands);
- return oldCommands;
- },
-
- /**
- * Remove all commands whose name match the specified regex.
- */
- filterOut: function (id_match) {
- this.commands = this.commands.filter(c => !id_match.test(c.name));
- }
-};
-
-
-function IsMacOSX10_6orOlder() {
- if (navigator.platform.indexOf("Mac") !== 0) {
- return false;
- }
-
- var version = Cc["@mozilla.org/system-info;1"]
- .getService(Ci.nsIPropertyBag2)
- .getProperty("version");
- // the next line is correct: Mac OS 10.6 corresponds to Darwin version 10.x !
- // Mac OS 10.7 is Darwin version 11.x. the |version| string we've got here
- // is the Darwin version.
- return (parseFloat(version) < 11.0);
-}
-
-(function(){
- var el = document.createElement("link");
- el.rel = "stylesheet";
- el.type = "text/css";
- el.href= "/tests/SimpleTest/test.css";
- document.head.appendChild(el);
-}());
--- a/dom/media/tests/mochitest/identity/identityevent.js
+++ b/dom/media/tests/mochitest/identity/identityevent.js
@@ -1,12 +1,12 @@
(function(g) {
'use strict';
- g.trapIdentityEvents = target => {
+ g.trapIdentityEvents = function(target) {
var state = {};
var identityEvents = ['idpassertionerror', 'idpvalidationerror',
'identityresult', 'peeridentity'];
identityEvents.forEach(function(name) {
target.addEventListener(name, function(e) {
state[name] = e;
}, false);
});
--- a/dom/media/tests/mochitest/identity/test_getIdentityAssertion.html
+++ b/dom/media/tests/mochitest/identity/test_getIdentityAssertion.html
@@ -1,110 +1,117 @@
<!DOCTYPE HTML>
<html>
<head>
- <script type="application/javascript">var scriptRelativePath = "../";</script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="../head.js"></script>
<script type="application/javascript" src="../pc.js"></script>
+ <script type="application/javascript" src="../templates.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
- title: "getIdentityAssertion Tests",
- bug: "942367"
+ title: "getIdentityAssertion Tests"
});
function checkIdentity(assertion, identity) {
// here we dig into the payload, which means we need to know something
// about how the IdP actually works (not good in general, but OK here)
var assertion = JSON.parse(atob(assertion)).assertion;
var user = JSON.parse(assertion).username;
is(user, identity, "id should be '" + identity + "' is '" + user + "'");
}
var test;
function theTest() {
test = new PeerConnectionTest();
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.chain.removeAfter('PC_REMOTE_CHECK_INITIAL_SIGNALINGSTATE');
test.chain.append([
- function GET_IDENTITY_ASSERTION_FAILS_WITHOUT_PROVIDER(test) {
- return new Promise(resolve => {
- test.pcLocal._pc.onidpassertionerror = function(e) {
- ok(e, "getIdentityAssertion must fail without provider");
- resolve();
- };
- test.pcLocal._pc.getIdentityAssertion();
- });
- },
- function GET_IDENTITY_ASSERTION_FIRES_EVENTUALLY_AND_SUBSEQUENTLY(test) {
- return new Promise(resolve => {
- var fired = 0;
- test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html');
- test.pcLocal._pc.onidentityresult = function(e) {
- fired++;
- if (fired == 1) {
- ok(true, "identityresult fired");
- checkIdentity(e.assertion, 'someone@example.com');
- } else if (fired == 2) {
- ok(true, "identityresult fired 2x");
- checkIdentity(e.assertion, 'someone@example.com');
- resolve();
- }
- };
- test.pcLocal._pc.onidpassertionerror = function(e) {
- ok(false, "error event fired");
- resolve();
- };
- test.pcLocal._pc.getIdentityAssertion();
- test.pcLocal._pc.getIdentityAssertion();
- });
+ [
+ "GET_IDENTITY_ASSERTION_FAILS_WITHOUT_PROVIDER",
+ function(test) {
+ test.pcLocal._pc.onidpassertionerror = function(e) {
+ ok(e, "getIdentityAssertion must fail without provider");
+ test.next();
+ };
+ test.pcLocal._pc.getIdentityAssertion();
},
- function GET_IDENTITY_ASSERTION_FAILS(test) {
- return new Promise(resolve => {
- test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html#error');
- test.pcLocal._pc.onidentityresult = function(e) {
- ok(false, "Should not get an identity result");
- resolve();
- };
- test.pcLocal._pc.onidpassertionerror = function(err) {
- ok(err, "Got error event from getIdentityAssertion");
- resolve();
- };
- test.pcLocal._pc.getIdentityAssertion();
- });
- },
- function GET_IDENTITY_ASSERTION_IDP_NOT_READY(test) {
- return new Promise(resolve => {
- test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html#error:ready');
- test.pcLocal._pc.onidentityresult = function(e) {
- ok(false, "Should not get an identity result");
- resolve();
- };
- test.pcLocal._pc.onidpassertionerror = function(e) {
- ok(e, "Got error callback from getIdentityAssertion");
- resolve();
- };
- test.pcLocal._pc.getIdentityAssertion();
- });
- },
- function GET_IDENTITY_ASSERTION_WITH_SPECIFIC_NAME(test) {
- return new Promise(resolve => {
- test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html', 'user@example.com');
- test.pcLocal._pc.onidentityresult = function(e) {
- checkIdentity(e.assertion, 'user@example.com');
- resolve();
- };
- test.pcLocal._pc.onidpassertionerror = function(e) {
- ok(false, "Got error callback from getIdentityAssertion");
- resolve();
- };
- test.pcLocal._pc.getIdentityAssertion();
- });
+ ],
+ [
+ "GET_IDENTITY_ASSERTION_FIRES_EVENTUALLY_AND_SUBSEQUENTLY",
+ function(test) {
+ var fired = 0;
+ test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html');
+ test.pcLocal._pc.onidentityresult = function(e) {
+ fired++;
+ if (fired == 1) {
+ ok(true, "identityresult fired");
+ checkIdentity(e.assertion, 'someone@example.com');
+ } else if (fired == 2) {
+ ok(true, "identityresult fired 2x");
+ checkIdentity(e.assertion, 'someone@example.com');
+ test.next();
+ }
+ };
+ test.pcLocal._pc.onidpassertionerror = function(e) {
+ ok(false, "error event fired");
+ test.next();
+ };
+ test.pcLocal._pc.getIdentityAssertion();
+ test.pcLocal._pc.getIdentityAssertion();
}
+ ],
+ [
+ "GET_IDENTITY_ASSERTION_FAILS",
+ function(test) {
+ test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html#error');
+ test.pcLocal._pc.onidentityresult = function(e) {
+ ok(false, "Should not get an identity result");
+ test.next();
+ };
+ test.pcLocal._pc.onidpassertionerror = function(err) {
+ ok(err, "Got error event from getIdentityAssertion");
+ test.next();
+ };
+ test.pcLocal._pc.getIdentityAssertion();
+ }
+ ],
+ [
+ "GET_IDENTITY_ASSERTION_IDP_NOT_READY",
+ function(test) {
+ test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html#error:ready');
+ test.pcLocal._pc.onidentityresult = function(e) {
+ ok(false, "Should not get an identity result");
+ test.next();
+ };
+ test.pcLocal._pc.onidpassertionerror = function(e) {
+ ok(e, "Got error callback from getIdentityAssertion");
+ test.next();
+ };
+ test.pcLocal._pc.getIdentityAssertion();
+ }
+ ],
+ [
+ "GET_IDENTITY_ASSERTION_WITH_SPECIFIC_NAME",
+ function(test) {
+ test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html', 'user@example.com');
+ test.pcLocal._pc.onidentityresult = function(e) {
+ checkIdentity(e.assertion, 'user@example.com');
+ test.next();
+ };
+ test.pcLocal._pc.onidpassertionerror = function(e) {
+ ok(false, "Got error callback from getIdentityAssertion");
+ test.next();
+ };
+ test.pcLocal._pc.getIdentityAssertion();
+ }
+ ]
]);
test.run();
}
runNetworkTest(theTest);
</script>
</pre>
</body>
--- a/dom/media/tests/mochitest/identity/test_peerConnection_peerIdentity.html
+++ b/dom/media/tests/mochitest/identity/test_peerConnection_peerIdentity.html
@@ -1,21 +1,26 @@
<!DOCTYPE HTML>
<html>
<head>
- <script type="application/javascript">var scriptRelativePath = "../";</script>
+ <meta charset="utf-8"/>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="../head.js"></script>
<script type="application/javascript" src="../pc.js"></script>
+ <script type="application/javascript" src="../templates.js"></script>
<script type="application/javascript" src="../blacksilence.js"></script>
+ <script type="application/javascript" src="../turnConfig.js"></script>
</head>
<body>
+<div id="display"></div>
<pre id="test">
<script type="application/javascript">
createHTML({
- title: "setIdentityProvider leads to peerIdentity and assertions in SDP",
- bug: "942367"
+ title: "setIdentityProvider leads to peerIdentity and assertions in SDP"
});
var test;
function theTest() {
var id1 = 'someone@test1.example.com';
var id2 = 'someone@test2.example.com';
test = new PeerConnectionTest({
config_local: {
@@ -38,36 +43,48 @@ function theTest() {
}, {
video: true,
fake: true,
peerIdentity: id1
}]);
test.setIdentityProvider(test.pcLocal, 'test1.example.com', 'idp.html');
test.setIdentityProvider(test.pcRemote, 'test2.example.com', 'idp.html');
test.chain.append([
-
- function PEER_IDENTITY_IS_SET_CORRECTLY(test) {
+ [
+ "PEER_IDENTITY_IS_SET_CORRECTLY",
+ function(test) {
// no need to wait to check identity in this case,
// setRemoteDescription should wait for the IdP to complete
function checkIdentity(pc, pfx, idp, name) {
is(pc.peerIdentity.idp, idp, pfx + "IdP is correct");
is(pc.peerIdentity.name, name + "@" + idp, pfx + "identity is correct");
}
checkIdentity(test.pcLocal._pc, "local: ", "test2.example.com", "someone");
checkIdentity(test.pcRemote._pc, "remote: ", "test1.example.com", "someone");
- },
-
- function REMOTE_STREAMS_ARE_RESTRICTED(test) {
+ test.next();
+ }
+ ],
+ [
+ "REMOTE_STREAMS_ARE_RESTRICTED",
+ function(test) {
var remoteStream = test.pcLocal._pc.getRemoteStreams()[0];
- return Promise.all([
- new Promise(done => audioIsSilence(true, remoteStream, done)),
- new Promise(done => videoIsBlack(true, remoteStream, done))
- ]);
+ var oneDone = false;
+ function done() {
+ if (!oneDone) {
+ oneDone = true;
+ return;
+ }
+ test.next();
+ }
+
+ audioIsSilence(true, remoteStream, done);
+ videoIsBlack(true, remoteStream, done);
}
+ ],
]);
test.run();
}
runNetworkTest(theTest);
</script>
</pre>
</body>
--- a/dom/media/tests/mochitest/identity/test_setIdentityProvider.html
+++ b/dom/media/tests/mochitest/identity/test_setIdentityProvider.html
@@ -1,95 +1,115 @@
<!DOCTYPE HTML>
<html>
<head>
- <script type="application/javascript">var scriptRelativePath = "../";</script>
+ <meta charset="utf-8"/>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="../head.js"></script>
<script type="application/javascript" src="../pc.js"></script>
+ <script type="application/javascript" src="../templates.js"></script>
<script type="application/javascript" src="identityevent.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
- title: "setIdentityProvider leads to peerIdentity and assertions in SDP",
- bug: "942367"
+ title: "setIdentityProvider leads to peerIdentity and assertions in SDP"
});
var test;
function theTest() {
test = new PeerConnectionTest();
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.setIdentityProvider(test.pcLocal, "test1.example.com", "idp.html", "someone");
test.setIdentityProvider(test.pcRemote, "test2.example.com", "idp.html", "someone");
var localEvents = trapIdentityEvents(test.pcLocal._pc);
var remoteEvents = trapIdentityEvents(test.pcRemote._pc);
test.chain.append([
- function PEER_IDENTITY_IS_SET_CORRECTLY(test) {
+ [
+ "PEER_IDENTITY_IS_SET_CORRECTLY",
+ function(test) {
var outstanding = 0;
// we have to wait for the identity result in order to get the actual
// identity information, since the call will complete before the identity
// provider has a chance to finish verifying... that's OK, but it makes
// testing more difficult
- function checkOrSetupCheck(pc, prefix, idp, name) {
+ function checkOrSetupCheck(pc, pfx, idp, name) {
function checkIdentity() {
- ok(pc.peerIdentity, prefix + "peerIdentity is set");
- is(pc.peerIdentity.idp, idp, prefix + "IdP is correct");
- is(pc.peerIdentity.name, name + "@" + idp, prefix + "identity is correct");
+ ok(pc.peerIdentity, pfx + "peerIdentity is set");
+ is(pc.peerIdentity.idp, idp, pfx + "IdP is correct");
+ is(pc.peerIdentity.name, name + "@" + idp, pfx + "identity is correct");
}
if (pc.peerIdentity) {
- info(prefix + "peerIdentity already set");
+ info(pfx + "peerIdentity already set");
checkIdentity();
- return Promise.resolve();
+ } else {
+ ++outstanding;
+ info(pfx + "setting onpeeridentity handler");
+ pc.onpeeridentity = function checkIdentityEvent(e) {
+ info(pfx + "checking peerIdentity");
+ checkIdentity();
+ --outstanding;
+ if (outstanding <= 0) {
+ test.next();
+ }
+ };
}
-
- return new Promise(resolve => {
- info(prefix + "setting onpeeridentity handler");
- pc.onpeeridentity = e => {
- checkIdentity();
- resolve();
- };
- });
}
- return Promise.all([
- checkOrSetupCheck(test.pcLocal._pc, "local: ", "test2.example.com", "someone"),
- checkOrSetupCheck(test.pcRemote._pc, "remote: ", "test1.example.com", "someone")
- ]);
- },
-
- function CHECK_IDENTITY_EVENTS(test) {
+ checkOrSetupCheck(test.pcLocal._pc, "local: ", "test2.example.com", "someone");
+ checkOrSetupCheck(test.pcRemote._pc, "remote: ", "test1.example.com", "someone");
+ if (outstanding <= 0) {
+ test.next();
+ }
+ }
+ ],
+ [
+ "CHECK_IDENTITY_EVENTS",
+ function(test) {
ok(!localEvents.idpassertionerror , "No assertion generation errors on local");
ok(!remoteEvents.idpassertionerror, "No assertion generation errors on remote");
ok(!localEvents.idpvalidationerror, "No assertion validation errors on local");
- ok(!remoteEvents.idpvalidationerror, "No assertion validation errors on remote");
+ ok( !remoteEvents.idpvalidationerror, "No assertion validation errors on remote");
ok(localEvents.identityresult, "local acquired identity assertions");
ok(remoteEvents.identityresult, "remote acquired identity assertions");
ok(localEvents.peeridentity, "local got peer identity");
ok(remoteEvents.peeridentity, "remote got peer identity");
- },
-
- function OFFERS_AND_ANSWERS_INCLUDE_IDENTITY(test) {
+ test.next();
+ }
+ ],
+ [
+ "OFFERS_AND_ANSWERS_INCLUDE_IDENTITY",
+ function(test) {
ok(test.originalOffer.sdp.contains("a=identity"), "a=identity is in the offer SDP");
ok(test.originalAnswer.sdp.contains("a=identity"), "a=identity is in the answer SDP");
- },
-
- function DESCRIPTIONS_CONTAIN_IDENTITY(test) {
+ test.next();
+ }
+ ],
+ [
+ "DESCRIPTIONS_CONTAIN_IDENTITY",
+ function(test) {
ok(test.pcLocal.localDescription.sdp.contains("a=identity"),
- "a=identity is in the local copy of the offer");
+ "a=identity is in the local copy of the offer");
ok(test.pcRemote.localDescription.sdp.contains("a=identity"),
- "a=identity is in the remote copy of the offer");
+ "a=identity is in the remote copy of the offer");
ok(test.pcLocal.remoteDescription.sdp.contains("a=identity"),
- "a=identity is in the local copy of the answer");
+ "a=identity is in the local copy of the answer");
ok(test.pcRemote.remoteDescription.sdp.contains("a=identity"),
- "a=identity is in the remote copy of the answer");
+ "a=identity is in the remote copy of the answer");
+ test.next();
}
+ ]
]);
test.run();
}
runNetworkTest(theTest);
+
+
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/identity/test_setIdentityProviderWithErrors.html
+++ b/dom/media/tests/mochitest/identity/test_setIdentityProviderWithErrors.html
@@ -1,74 +1,85 @@
<!DOCTYPE HTML>
<html>
<head>
- <script type="application/javascript">var scriptRelativePath = "../";</script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="../head.js"></script>
<script type="application/javascript" src="../pc.js"></script>
+ <script type="application/javascript" src="../templates.js"></script>
<script type="application/javascript" src="identityevent.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
- title: "Identity Provider returning errors is handled correctly",
- bug: "942367"
+ title: "Identity Provider returning errors is handled correctly"
});
+var test;
runNetworkTest(function () {
- var test = new PeerConnectionTest();
+ test = new PeerConnectionTest();
test.setMediaConstraints([{audio: true}], [{audio: true}]);
// first example generates an error
test.setIdentityProvider(test.pcLocal, 'example.com', 'idp.html#error', 'nobody');
// second generates a bad assertion; which fails to validate
test.setIdentityProvider(test.pcRemote, 'example.com', 'idp.html#bad', 'nobody');
var localEvents = trapIdentityEvents(test.pcLocal._pc);
var remoteEvents = trapIdentityEvents(test.pcRemote._pc);
test.chain.append([
- function CHECK_IDENTITY_EVENTS(test) {
- function checkEvents() {
- ok(localEvents.idpassertionerror, 'local assertion generation should fail (idpassertionerror)');
- is(localEvents.idpassertionerror.idp, 'example.com', 'event IdP is correct');
- is(localEvents.idpassertionerror.protocol, 'idp.html#error', 'event IdP protocol is #error');
- ok(!remoteEvents.idpassertionerror, 'remote assertion generation should succeed (idpassertionerror)');
- ok(!localEvents.identityresult, 'local assertion generation should fail (identityresult)');
- ok(remoteEvents.identityresult, 'remote assertion generation should succeed (identityresult)');
+ [
+ 'CHECK_IDENTITY_EVENTS',
+ function(test) {
+ function checkEvents() {
+ ok(localEvents.idpassertionerror, 'local assertion generation should fail (idpassertionerror)');
+ is(localEvents.idpassertionerror.idp, 'example.com', 'event IdP is correct');
+ is(localEvents.idpassertionerror.protocol, 'idp.html#error', 'event IdP protocol is #error');
+ ok(!remoteEvents.idpassertionerror, 'remote assertion generation should succeed (idpassertionerror)');
+ ok(!localEvents.identityresult, 'local assertion generation should fail (identityresult)');
+ ok(remoteEvents.identityresult, 'remote assertion generation should succeed (identityresult)');
- ok(!localEvents.peeridentity, 'no peer identity event for local peer');
- ok(!remoteEvents.peeridentity, 'no peer identity event for remote peer');
- ok(localEvents.idpvalidationerror, 'local fails to validate');
- is(localEvents.idpvalidationerror.idp, 'example.com', 'event IdP is correct');
- is(localEvents.idpvalidationerror.protocol, 'idp.html#bad', 'event IdP protocol is #bad');
- ok(!remoteEvents.idpvalidationerror, 'remote doesn\'t even see an assertion');
+ ok(!localEvents.peeridentity, 'no peer identity event for local peer');
+ ok(!remoteEvents.peeridentity, 'no peer identity event for remote peer');
+ ok(localEvents.idpvalidationerror, 'local fails to validate');
+ is(localEvents.idpvalidationerror.idp, 'example.com', 'event IdP is correct');
+ is(localEvents.idpvalidationerror.protocol, 'idp.html#bad', 'event IdP protocol is #bad');
+ ok(!remoteEvents.idpvalidationerror, 'remote doesn\'t even see an assertion');
- }
+ test.next();
+ }
- // we actually have to wait on this because IdP validation happens asynchronously
- if (localEvents.idpvalidationerror) {
- checkEvents();
- return Promise.resolve();
+ // we actually have to wait on this because IdP validation happens asynchronously
+ if (localEvents.idpvalidationerror) {
+ checkEvents();
+ } else {
+ // have to let the other event handler have a chance to record success
+ // before we run the checks that rely on that recording
+ test.pcLocal._pc.onidpvalidationerror = setTimeout.bind(window, checkEvents, 1);
+ }
}
- // have to let the other event handler have a chance to record success
- // before we run the checks that rely on that recording
- return new Promise(resolve => {
- test.pcLocal._pc.onidpvalidationerror = resolve;
- }).then(checkEvents);
- },
-
- function PEER_IDENTITY_IS_EMPTY(test) {
- ok(!test.pcLocal._pc.peerIdentity, 'local peerIdentity is not set');
- ok(!test.pcRemote._pc.peerIdentity, 'remote peerIdentity is not set');
- },
-
- function ONLY_REMOTE_SDP_INCLUDES_IDENTITY_ASSERTION(test) {
- ok(!test.originalOffer.sdp.contains('a=identity'), 'a=identity not contained in the offer SDP');
- ok(test.originalAnswer.sdp.contains('a=identity'), 'a=identity is contained in the answer SDP');
- }
+ ],
+ [
+ 'PEER_IDENTITY_IS_EMPTY',
+ function(test) {
+ ok(!test.pcLocal._pc.peerIdentity, 'local peerIdentity is not set');
+ ok(!test.pcRemote._pc.peerIdentity, 'remote peerIdentity is not set');
+ test.next();
+ }
+ ],
+ [
+ 'ONLY_REMOTE_SDP_INCLUDES_IDENTITY_ASSERTION',
+ function(test) {
+ ok(!test.originalOffer.sdp.contains('a=identity'), 'a=identity not contained in the offer SDP');
+ ok(test.originalAnswer.sdp.contains('a=identity'), 'a=identity is contained in the answer SDP');
+ test.next();
+ }
+ ]
]);
test.run();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/mediaStreamPlayback.js
+++ b/dom/media/tests/mochitest/mediaStreamPlayback.js
@@ -32,123 +32,137 @@ MediaStreamPlayback.prototype = {
*
* @param {Boolean} isResume specifies if this media element is being resumed
* from a previous run
* @param {Function} onSuccess the success callback if the media playback
* start and stop cycle completes successfully
* @param {Function} onError the error callback if the media playback
* start and stop cycle fails
*/
- playMedia : function(isResume) {
- return this.startMedia(isResume)
- .then(() => this.stopMediaElement());
+ playMedia : function MSP_playMedia(isResume, onSuccess, onError) {
+ var self = this;
+
+ this.startMedia(isResume, function() {
+ self.stopMediaElement();
+ onSuccess();
+ }, onError);
},
/**
* Starts the media with the associated stream.
*
* @param {Boolean} isResume specifies if the media element playback
* is being resumed from a previous run
+ * @param {Function} onSuccess the success function call back
+ * if media starts correctly
+ * @param {Function} onError the error function call back
+ * if media fails to start
*/
- startMedia : function(isResume) {
+ startMedia : function MSP_startMedia(isResume, onSuccess, onError) {
+ var self = this;
var canPlayThroughFired = false;
// If we're initially running this media, check that the time is zero
if (!isResume) {
is(this.mediaStream.currentTime, 0,
"Before starting the media element, currentTime = 0");
}
- return new Promise((resolve, reject) => {
- /**
- * Callback fired when the canplaythrough event is fired. We only
- * run the logic of this function once, as this event can fire
- * multiple times while a HTMLMediaStream is playing content from
- * a real-time MediaStream.
- */
- var canPlayThroughCallback = () => {
- // Disable the canplaythrough event listener to prevent multiple calls
- canPlayThroughFired = true;
- this.mediaElement.removeEventListener('canplaythrough',
- canPlayThroughCallback, false);
+ /**
+ * Callback fired when the canplaythrough event is fired. We only
+ * run the logic of this function once, as this event can fire
+ * multiple times while a HTMLMediaStream is playing content from
+ * a real-time MediaStream.
+ */
+ var canPlayThroughCallback = function() {
+ // Disable the canplaythrough event listener to prevent multiple calls
+ canPlayThroughFired = true;
+ self.mediaElement.removeEventListener('canplaythrough',
+ canPlayThroughCallback, false);
- is(this.mediaElement.paused, false,
- "Media element should be playing");
- is(this.mediaElement.duration, Number.POSITIVE_INFINITY,
- "Duration should be infinity");
+ is(self.mediaElement.paused, false,
+ "Media element should be playing");
+ is(self.mediaElement.duration, Number.POSITIVE_INFINITY,
+ "Duration should be infinity");
- // When the media element is playing with a real-time stream, we
- // constantly switch between having data to play vs. queuing up data,
- // so we can only check that the ready state is one of those two values
- ok(this.mediaElement.readyState === HTMLMediaElement.HAVE_ENOUGH_DATA ||
- this.mediaElement.readyState === HTMLMediaElement.HAVE_CURRENT_DATA,
- "Ready state shall be HAVE_ENOUGH_DATA or HAVE_CURRENT_DATA");
-
- is(this.mediaElement.seekable.length, 0,
- "Seekable length shall be zero");
- is(this.mediaElement.buffered.length, 0,
- "Buffered length shall be zero");
+ // When the media element is playing with a real-time stream, we
+ // constantly switch between having data to play vs. queuing up data,
+ // so we can only check that the ready state is one of those two values
+ ok(self.mediaElement.readyState === HTMLMediaElement.HAVE_ENOUGH_DATA ||
+ self.mediaElement.readyState === HTMLMediaElement.HAVE_CURRENT_DATA,
+ "Ready state shall be HAVE_ENOUGH_DATA or HAVE_CURRENT_DATA");
- is(this.mediaElement.seeking, false,
- "MediaElement is not seekable with MediaStream");
- ok(isNaN(this.mediaElement.startOffsetTime),
- "Start offset time shall not be a number");
- is(this.mediaElement.loop, false, "Loop shall be false");
- is(this.mediaElement.preload, "", "Preload should not exist");
- is(this.mediaElement.src, "", "No src should be defined");
- is(this.mediaElement.currentSrc, "",
- "Current src should still be an empty string");
+ is(self.mediaElement.seekable.length, 0,
+ "Seekable length shall be zero");
+ is(self.mediaElement.buffered.length, 0,
+ "Buffered length shall be zero");
- var timeUpdateCallback = () => {
- if (this.mediaStream.currentTime > 0 &&
- this.mediaElement.currentTime > 0) {
- this.mediaElement.removeEventListener('timeupdate',
- timeUpdateCallback, false);
- resolve();
- }
- };
+ is(self.mediaElement.seeking, false,
+ "MediaElement is not seekable with MediaStream");
+ ok(isNaN(self.mediaElement.startOffsetTime),
+ "Start offset time shall not be a number");
+ is(self.mediaElement.loop, false, "Loop shall be false");
+ is(self.mediaElement.preload, "", "Preload should not exist");
+ is(self.mediaElement.src, "", "No src should be defined");
+ is(self.mediaElement.currentSrc, "",
+ "Current src should still be an empty string");
- // When timeupdate fires, we validate time has passed and move
- // onto the success condition
- this.mediaElement.addEventListener('timeupdate', timeUpdateCallback,
- false);
+ var timeUpdateFired = false;
- // If timeupdate doesn't fire in enough time, we fail the test
- setTimeout(() => {
- this.mediaElement.removeEventListener('timeupdate',
- timeUpdateCallback, false);
- reject(new Error("timeUpdate event never fired"));
- }, TIMEUPDATE_TIMEOUT_LENGTH);
+ var timeUpdateCallback = function() {
+ if (self.mediaStream.currentTime > 0 &&
+ self.mediaElement.currentTime > 0) {
+ timeUpdateFired = true;
+ self.mediaElement.removeEventListener('timeupdate',
+ timeUpdateCallback, false);
+ onSuccess();
+ }
};
- // Adds a listener intended to be fired when playback is available
- // without further buffering.
- this.mediaElement.addEventListener('canplaythrough', canPlayThroughCallback,
- false);
+ // When timeupdate fires, we validate time has passed and move
+ // onto the success condition
+ self.mediaElement.addEventListener('timeupdate', timeUpdateCallback,
+ false);
+
+ // If timeupdate doesn't fire in enough time, we fail the test
+ setTimeout(function() {
+ if (!timeUpdateFired) {
+ self.mediaElement.removeEventListener('timeupdate',
+ timeUpdateCallback, false);
+ onError("timeUpdate event never fired");
+ }
+ }, TIMEUPDATE_TIMEOUT_LENGTH);
+ };
- // Hooks up the media stream to the media element and starts playing it
- this.mediaElement.mozSrcObject = this.mediaStream;
- this.mediaElement.play();
+ // Adds a listener intended to be fired when playback is available
+ // without further buffering.
+ this.mediaElement.addEventListener('canplaythrough', canPlayThroughCallback,
+ false);
+
+ // Hooks up the media stream to the media element and starts playing it
+ this.mediaElement.mozSrcObject = this.mediaStream;
+ this.mediaElement.play();
- // If canplaythrough doesn't fire in enough time, we fail the test
- setTimeout(() => {
- this.mediaElement.removeEventListener('canplaythrough',
- canPlayThroughCallback, false);
- reject(new Error("canplaythrough event never fired"));
- }, CANPLAYTHROUGH_TIMEOUT_LENGTH);
- });
+ // If canplaythrough doesn't fire in enough time, we fail the test
+ setTimeout(function() {
+ if (!canPlayThroughFired) {
+ self.mediaElement.removeEventListener('canplaythrough',
+ canPlayThroughCallback, false);
+ onError("canplaythrough event never fired");
+ }
+ }, CANPLAYTHROUGH_TIMEOUT_LENGTH);
},
/**
* Stops the media with the associated stream.
*
* Precondition: The media stream and element should both be actively
* being played.
*/
- stopMediaElement : function() {
+ stopMediaElement : function MSP_stopMediaElement() {
this.mediaElement.pause();
this.mediaElement.mozSrcObject = null;
}
}
/**
* This class is basically the same as MediaStreamPlayback except
@@ -167,70 +181,69 @@ function LocalMediaStreamPlayback(mediaE
LocalMediaStreamPlayback.prototype = Object.create(MediaStreamPlayback.prototype, {
/**
* Starts media with a media stream, runs it until a canplaythrough and
* timeupdate event fires, and calls stop() on the stream.
*
* @param {Boolean} isResume specifies if this media element is being resumed
* from a previous run
+ * @param {Function} onSuccess the success callback if the media element
+ * successfully fires ended on a stop() call
+ * on the stream
+ * @param {Function} onError the error callback if the media element fails
+ * to fire an ended callback on a stop() call
+ * on the stream
*/
playMediaWithStreamStop : {
- value: function(isResume) {
- return this.startMedia(isResume)
- .then(() => this.stopStreamInMediaPlayback())
- .then(() => this.stopMediaElement());
+ value: function (isResume, onSuccess, onError) {
+ var self = this;
+
+ this.startMedia(isResume, function() {
+ self.stopStreamInMediaPlayback(function() {
+ self.stopMediaElement();
+ onSuccess();
+ }, onError);
+ }, onError);
}
},
/**
* Stops the local media stream while it's currently in playback in
* a media element.
*
* Precondition: The media stream and element should both be actively
* being played.
*
+ * @param {Function} onSuccess the success callback if the media element
+ * fires an ended event from stop() being called
+ * @param {Function} onError the error callback if the media element
+ * fails to fire an ended event from stop() being
+ * called
*/
stopStreamInMediaPlayback : {
- value: function () {
- return new Promise((resolve, reject) => {
- /**
- * Callback fired when the ended event fires when stop() is called on the
- * stream.
- */
- var endedCallback = () => {
- this.mediaElement.removeEventListener('ended', endedCallback, false);
- ok(true, "ended event successfully fired");
- resolve();
- };
+ value: function (onSuccess, onError) {
+ var endedFired = false;
+ var self = this;
- this.mediaElement.addEventListener('ended', endedCallback, false);
- this.mediaStream.stop();
+ /**
+ * Callback fired when the ended event fires when stop() is called on the
+ * stream.
+ */
+ var endedCallback = function() {
+ endedFired = true;
+ self.mediaElement.removeEventListener('ended', endedCallback, false);
+ ok(true, "ended event successfully fired");
+ onSuccess();
+ };
- // If ended doesn't fire in enough time, then we fail the test
- setTimeout(() => {
- reject(new Error("ended event never fired"));
- }, ENDED_TIMEOUT_LENGTH);
- });
+ this.mediaElement.addEventListener('ended', endedCallback, false);
+ this.mediaStream.stop();
+
+ // If ended doesn't fire in enough time, then we fail the test
+ setTimeout(function() {
+ if (!endedFired) {
+ onError("ended event never fired");
+ }
+ }, ENDED_TIMEOUT_LENGTH);
}
}
});
-
-// haxx to prevent SimpleTest from failing at window.onload
-function addLoadEvent() {}
-
-var scriptsReady = Promise.all([
- "/tests/SimpleTest/SimpleTest.js",
- "head.js"
-].map(script => {
- var el = document.createElement("script");
- el.src = script;
- document.head.appendChild(el);
- return new Promise(r => el.onload = r);
-}));
-
-function createHTML(options) {
- return scriptsReady.then(() => realCreateHTML(options));
-}
-
-function runTest(f) {
- return scriptsReady.then(() => runTestWhenReady(f));
-}
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -1,17 +1,16 @@
[DEFAULT]
# strictContentSandbox - bug 1042735, Android 2.3 - bug 981881
skip-if = (os == 'win' && strictContentSandbox) || android_version == '10'
support-files =
head.js
constraints.js
dataChannel.js
mediaStreamPlayback.js
- network.js
nonTrickleIce.js
pc.js
templates.js
NetworkPreparationChromeScript.js
blacksilence.js
turnConfig.js
[test_dataChannel_basicAudio.html]
@@ -39,17 +38,16 @@ skip-if = buildapp == 'b2g' || toolkit =
[test_getUserMedia_basicWindowshare.html]
skip-if = buildapp == 'b2g' || toolkit == 'android' # no windowshare on b2g/android
[test_getUserMedia_basicVideoAudio.html]
skip-if = (toolkit == 'gonk' && debug) # debug-only failure, turned an intermittent (bug 962579) into a permanant orange
[test_getUserMedia_constraints.html]
skip-if = toolkit == 'gonk' || toolkit == 'android' # Bug 907352, backwards-compatible behavior on mobile only
[test_getUserMedia_constraints_mobile.html]
skip-if = toolkit != 'gonk' && toolkit != 'android' # Bug 907352, backwards-compatible behavior on mobile only
-[test_getUserMedia_callbacks.html]
[test_getUserMedia_gumWithinGum.html]
[test_getUserMedia_playAudioTwice.html]
[test_getUserMedia_playVideoAudioTwice.html]
skip-if = (toolkit == 'gonk' && debug) # debug-only failure; bug 926558
[test_getUserMedia_playVideoTwice.html]
[test_getUserMedia_stopAudioStream.html]
[test_getUserMedia_stopAudioStreamWithFollowupAudio.html]
[test_getUserMedia_stopVideoAudioStream.html]
@@ -108,18 +106,16 @@ skip-if = toolkit == 'gonk' # b2g (Bug 1
[test_peerConnection_offerRequiresReceiveAudio.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_offerRequiresReceiveVideo.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_offerRequiresReceiveVideoAudio.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_promiseSendOnly.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
-[test_peerConnection_callbacks.html]
-skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_replaceTrack.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_syncSetDescription.html]
skip-if = toolkit == 'gonk' # b2g(Bug 960442, video support for WebRTC is disabled on b2g)
[test_peerConnection_setLocalAnswerInHaveLocalOffer.html]
skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
[test_peerConnection_setLocalAnswerInStable.html]
skip-if = toolkit == 'gonk' # b2g (Bug 1059867)
deleted file mode 100644
--- a/dom/media/tests/mochitest/network.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-/**
- * Query function for determining if any IP address is available for
- * generating SDP.
- *
- * @return false if required additional network setup.
- */
-function isNetworkReady() {
- // for gonk platform
- if ("nsINetworkInterfaceListService" in SpecialPowers.Ci) {
- var listService = SpecialPowers.Cc["@mozilla.org/network/interface-list-service;1"]
- .getService(SpecialPowers.Ci.nsINetworkInterfaceListService);
- var itfList = listService.getDataInterfaceList(
- SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_MMS_INTERFACES |
- SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_SUPL_INTERFACES |
- SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_IMS_INTERFACES |
- SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_DUN_INTERFACES);
- var num = itfList.getNumberOfInterface();
- for (var i = 0; i < num; i++) {
- var ips = {};
- var prefixLengths = {};
- var length = itfList.getInterface(i).getAddresses(ips, prefixLengths);
-
- for (var j = 0; j < length; j++) {
- var ip = ips.value[j];
- // skip IPv6 address until bug 797262 is implemented
- if (ip.indexOf(":") < 0) {
- safeInfo("Network interface is ready with address: " + ip);
- return true;
- }
- }
- }
- // ip address is not available
- safeInfo("Network interface is not ready, required additional network setup");
- return false;
- }
- safeInfo("Network setup is not required");
- return true;
-}
-
-/**
- * Network setup utils for Gonk
- *
- * @return {object} providing functions for setup/teardown data connection
- */
-function getNetworkUtils() {
- var url = SimpleTest.getTestFileURL("NetworkPreparationChromeScript.js");
- var script = SpecialPowers.loadChromeScript(url);
-
- var utils = {
- /**
- * Utility for setting up data connection.
- *
- * @param aCallback callback after data connection is ready.
- */
- prepareNetwork: function() {
- return new Promise(resolve => {
- script.addMessageListener('network-ready', () => {
- info("Network interface is ready");
- resolve();
- });
- info("Setting up network interface");
- script.sendAsyncMessage("prepare-network", true);
- });
- },
- /**
- * Utility for tearing down data connection.
- *
- * @param aCallback callback after data connection is closed.
- */
- tearDownNetwork: function() {
- if (!isNetworkReady()) {
- info("No network to tear down");
- return Promise.resolve();
- }
- return new Promise(resolve => {
- script.addMessageListener('network-disabled', message => {
- info("Network interface torn down");
- script.destroy();
- resolve();
- });
- info("Tearing down network interface");
- script.sendAsyncMessage("network-cleanup", true);
- });
- }
- };
-
- return utils;
-}
-
-/**
- * Setup network on Gonk if needed and execute test once network is up
- *
- */
-function startNetworkAndTest() {
- if (isNetworkReady()) {
- return Promise.resolve();
- }
- var utils = getNetworkUtils();
- // Trigger network setup to obtain IP address before creating any PeerConnection.
- return utils.prepareNetwork();
-}
-
-/**
- * A wrapper around SimpleTest.finish() to handle B2G network teardown
- */
-function networkTestFinished() {
- var p;
- if ("nsINetworkInterfaceListService" in SpecialPowers.Ci) {
- var utils = getNetworkUtils();
- p = utils.tearDownNetwork();
- } else {
- p = Promise.resolve();
- }
- return p.then(() => finish());
-}
--- a/dom/media/tests/mochitest/nonTrickleIce.js
+++ b/dom/media/tests/mochitest/nonTrickleIce.js
@@ -1,60 +1,130 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function makeOffererNonTrickle(chain) {
chain.replace('PC_LOCAL_SETUP_ICE_HANDLER', [
- function PC_LOCAL_SETUP_NOTRICKLE_ICE_HANDLER(test) {
- // We need to install this callback before calling setLocalDescription
- // otherwise we might miss callbacks
- test.pcLocal.setupIceCandidateHandler(test, () => {});
- // We ignore ICE candidates because we want the full offer
- }
+ ['PC_LOCAL_SETUP_NOTRICKLE_ICE_HANDLER',
+ function (test) {
+ test.pcLocalWaitingForEndOfTrickleIce = false;
+ // We need to install this callback before calling setLocalDescription
+ // otherwise we might miss callbacks
+ test.pcLocal.setupIceCandidateHandler(test, function () {
+ // We ignore ICE candidates because we want the full offer
+ } , function (label) {
+ if (test.pcLocalWaitingForEndOfTrickleIce) {
+ // This callback is needed for slow environments where ICE
+ // trickling has not finished before the other side needs the
+ // full SDP. In this case, this call to test.next() will complete
+ // the PC_REMOTE_WAIT_FOR_OFFER step (see below).
+ info("Looks like we were still waiting for Trickle to finish");
+ // TODO replace this with a Promise
+ test.next();
+ }
+ });
+ // We can't wait for trickle to finish here as it will only start once
+ // we have called setLocalDescription in the next step
+ test.next();
+ }
+ ]
]);
chain.replace('PC_REMOTE_GET_OFFER', [
- function PC_REMOTE_GET_FULL_OFFER(test) {
- return test.pcLocal.endOfTrickleIce.then(() => {
+ ['PC_REMOTE_WAIT_FOR_OFFER',
+ function (test) {
+ if (test.pcLocal.endOfTrickleIce) {
+ info("Trickle ICE finished already");
+ test.next();
+ } else {
+ info("Waiting for trickle ICE to finish");
+ test.pcLocalWaitingForEndOfTrickleIce = true;
+ // In this case we rely on the callback from
+ // PC_LOCAL_SETUP_NOTRICKLE_ICE_HANDLER above to proceed to the next
+ // step once trickle is finished.
+ }
+ }
+ ],
+ ['PC_REMOTE_GET_FULL_OFFER',
+ function (test) {
test._local_offer = test.pcLocal.localDescription;
test._offer_constraints = test.pcLocal.constraints;
test._offer_options = test.pcLocal.offerOptions;
- });
- }
+ test.next();
+ }
+ ]
]);
chain.insertAfter('PC_REMOTE_SANE_REMOTE_SDP', [
- function PC_REMOTE_REQUIRE_REMOTE_SDP_CANDIDATES(test) {
- info("test.pcLocal.localDescription.sdp: " + JSON.stringify(test.pcLocal.localDescription.sdp));
- info("test._local_offer.sdp" + JSON.stringify(test._local_offer.sdp));
- ok(!test.localRequiresTrickleIce, "Local does NOT require trickle");
- ok(test._local_offer.sdp.contains("a=candidate"), "offer has ICE candidates")
- ok(test._local_offer.sdp.contains("a=end-of-candidates"), "offer has end-of-candidates");
- }
+ ['PC_REMOTE_REQUIRE_REMOTE_SDP_CANDIDATES',
+ function (test) {
+ info("test.pcLocal.localDescription.sdp: " + JSON.stringify(test.pcLocal.localDescription.sdp));
+ info("test._local_offer.sdp" + JSON.stringify(test._local_offer.sdp));
+ ok(!test.localRequiresTrickleIce, "Local does NOT require trickle");
+ ok(test._local_offer.sdp.contains("a=candidate"), "offer has ICE candidates")
+ // TODO check for a=end-of-candidates once implemented
+ test.next();
+ }
+ ]
]);
}
function makeAnswererNonTrickle(chain) {
chain.replace('PC_REMOTE_SETUP_ICE_HANDLER', [
- function PC_REMOTE_SETUP_NOTRICKLE_ICE_HANDLER(test) {
- // We need to install this callback before calling setLocalDescription
- // otherwise we might miss callbacks
- test.pcRemote.setupIceCandidateHandler(test, () => {});
- // We ignore ICE candidates because we want the full offer
- }
+ ['PC_REMOTE_SETUP_NOTRICKLE_ICE_HANDLER',
+ function (test) {
+ test.pcRemoteWaitingForEndOfTrickleIce = false;
+ // We need to install this callback before calling setLocalDescription
+ // otherwise we might miss callbacks
+ test.pcRemote.setupIceCandidateHandler(test, function () {
+ // We ignore ICE candidates because we want the full answer
+ }, function (label) {
+ if (test.pcRemoteWaitingForEndOfTrickleIce) {
+ // This callback is needed for slow environments where ICE
+ // trickling has not finished before the other side needs the
+ // full SDP. In this case this callback will call the step after
+ // PC_LOCAL_WAIT_FOR_ANSWER
+ info("Looks like we were still waiting for Trickle to finish");
+ // TODO replace this with a Promise
+ test.next();
+ }
+ });
+ // We can't wait for trickle to finish here as it will only start once
+ // we have called setLocalDescription in the next step
+ test.next();
+ }
+ ]
]);
chain.replace('PC_LOCAL_GET_ANSWER', [
- function PC_LOCAL_GET_FULL_ANSWER(test) {
- return test.pcRemote.endOfTrickleIce.then(() => {
+ ['PC_LOCAL_WAIT_FOR_ANSWER',
+ function (test) {
+ if (test.pcRemote.endOfTrickleIce) {
+ info("Trickle ICE finished already");
+ test.next();
+ } else {
+ info("Waiting for trickle ICE to finish");
+ test.pcRemoteWaitingForEndOfTrickleIce = true;
+ // In this case we rely on the callback from
+ // PC_REMOTE_SETUP_NOTRICKLE_ICE_HANDLER above to proceed to the next
+ // step once trickle is finished.
+ }
+ }
+ ],
+ ['PC_LOCAL_GET_FULL_ANSWER',
+ function (test) {
test._remote_answer = test.pcRemote.localDescription;
test._answer_constraints = test.pcRemote.constraints;
- });
- }
+ test.next();
+ }
+ ]
]);
chain.insertAfter('PC_LOCAL_SANE_REMOTE_SDP', [
- function PC_LOCAL_REQUIRE_REMOTE_SDP_CANDIDATES(test) {
- info("test.pcRemote.localDescription.sdp: " + JSON.stringify(test.pcRemote.localDescription.sdp));
- info("test._remote_answer.sdp" + JSON.stringify(test._remote_answer.sdp));
- ok(!test.remoteRequiresTrickleIce, "Remote does NOT require trickle");
- ok(test._remote_answer.sdp.contains("a=candidate"), "answer has ICE candidates")
- ok(test._remote_answer.sdp.contains("a=end-of-candidates"), "answer has end-of-candidates");
- }
+ ['PC_LOCAL_REQUIRE_REMOTE_SDP_CANDIDATES',
+ function (test) {
+ info("test.pcRemote.localDescription.sdp: " + JSON.stringify(test.pcRemote.localDescription.sdp));
+ info("test._remote_answer.sdp" + JSON.stringify(test._remote_answer.sdp));
+ ok(!test.remoteRequiresTrickleIce, "Remote does NOT require trickle");
+ ok(test._remote_answer.sdp.contains("a=candidate"), "answer has ICE candidates")
+ // TODO check for a=end-of-candidates once implemented
+ test.next();
+ }
+ ]
]);
}
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -24,91 +24,355 @@ const signalingStateTransitions = {
"have-local-offer": ["have-remote-pranswer", "stable", "closed", "have-local-offer"],
"have-remote-pranswer": ["stable", "closed", "have-remote-pranswer"],
"have-remote-offer": ["have-local-pranswer", "stable", "closed", "have-remote-offer"],
"have-local-pranswer": ["stable", "closed", "have-local-pranswer"],
"closed": []
}
/**
+ * This class mimics a state machine and handles a list of commands by
+ * executing them synchronously.
+ *
+ * @constructor
+ * @param {object} framework
+ * A back reference to the framework which makes use of the class. It's
+ * getting passed in as parameter to each command callback.
+ * @param {Array[]} [commandList=[]]
+ * Default commands to set during initialization
+ */
+function CommandChain(framework, commandList) {
+ this._framework = framework;
+
+ this._commands = commandList || [ ];
+ this._current = 0;
+
+ this.onFinished = null;
+}
+
+CommandChain.prototype = {
+
+ /**
+ * Returns the index of the current command of the chain
+ *
+ * @returns {number} Index of the current command
+ */
+ get current() {
+ return this._current;
+ },
+
+ /**
+ * Checks if the chain has already processed all the commands
+ *
+ * @returns {boolean} True, if all commands have been processed
+ */
+ get finished() {
+ return this._current === this._commands.length;
+ },
+
+ /**
+ * Returns the assigned commands of the chain.
+ *
+ * @returns {Array[]} Commands of the chain
+ */
+ get commands() {
+ return this._commands;
+ },
+
+ /**
+ * Sets new commands for the chain. All existing commands will be replaced.
+ *
+ * @param {Array[]} commands
+ * List of commands
+ */
+ set commands(commands) {
+ this._commands = commands;
+ },
+
+ /**
+ * Execute the next command in the chain.
+ */
+ executeNext : function () {
+ var self = this;
+
+ function _executeNext() {
+ if (!self.finished) {
+ var step = self._commands[self._current];
+ self._current++;
+
+ self.currentStepLabel = step[0];
+ info("Run step: " + self.currentStepLabel);
+ step[1](self._framework); // Execute step
+ }
+ else if (typeof(self.onFinished) === 'function') {
+ self.onFinished();
+ }
+ }
+
+ // To prevent building up the stack we have to execute the next
+ // step asynchronously
+ window.setTimeout(_executeNext, 0);
+ },
+
+ /**
+ * Add new commands to the end of the chain
+ *
+ * @param {Array[]} commands
+ * List of commands
+ */
+ append: function (commands) {
+ this._commands = this._commands.concat(commands);
+ },
+
+ /**
+ * Returns the index of the specified command in the chain.
+ *
+ * @param {string} id
+ * Identifier of the command
+ * @returns {number} Index of the command
+ */
+ indexOf: function (id) {
+ for (var i = 0; i < this._commands.length; i++) {
+ if (this._commands[i][0] === id) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ /**
+ * Inserts the new commands after the specified command.
+ *
+ * @param {string} id
+ * Identifier of the command
+ * @param {Array[]} commands
+ * List of commands
+ */
+ insertAfter: function (id, commands) {
+ var index = this.indexOf(id);
+
+ if (index > -1) {
+ var tail = this.removeAfter(id);
+
+ this.append(commands);
+ this.append(tail);
+ }
+ },
+
+ /**
+ * Inserts the new commands before the specified command.
+ *
+ * @param {string} id
+ * Identifier of the command
+ * @param {Array[]} commands
+ * List of commands
+ */
+ insertBefore: function (id, commands) {
+ var index = this.indexOf(id);
+
+ if (index > -1) {
+ var tail = this.removeAfter(id);
+ var object = this.remove(id);
+
+ this.append(commands);
+ this.append(object);
+ this.append(tail);
+ }
+ },
+
+ /**
+ * Removes the specified command
+ *
+ * @param {string} id
+ * Identifier of the command
+ * @returns {object[]} Removed command
+ */
+ remove : function (id) {
+ return this._commands.splice(this.indexOf(id), 1);
+ },
+
+ /**
+ * Removes all commands after the specified one.
+ *
+ * @param {string} id
+ * Identifier of the command
+ * @returns {object[]} Removed commands
+ */
+ removeAfter : function (id) {
+ var index = this.indexOf(id);
+
+ if (index > -1) {
+ return this._commands.splice(index + 1);
+ }
+
+ return null;
+ },
+
+ /**
+ * Removes all commands before the specified one.
+ *
+ * @param {string} id
+ * Identifier of the command
+ * @returns {object[]} Removed commands
+ */
+ removeBefore : function (id) {
+ var index = this.indexOf(id);
+
+ if (index > -1) {
+ return this._commands.splice(0, index);
+ }
+
+ return null;
+ },
+
+ /**
+ * Replaces a single command.
+ *
+ * @param {string} id
+ * Identifier of the command to be replaced
+ * @param {Array[]} commands
+ * List of commands
+ * @returns {object[]} Removed commands
+ */
+ replace : function (id, commands) {
+ this.insertBefore(id, commands);
+ return this.remove(id);
+ },
+
+ /**
+ * Replaces all commands after the specified one.
+ *
+ * @param {string} id
+ * Identifier of the command
+ * @returns {object[]} Removed commands
+ */
+ replaceAfter : function (id, commands) {
+ var oldCommands = this.removeAfter(id);
+ this.append(commands);
+
+ return oldCommands;
+ },
+
+ /**
+ * Replaces all commands before the specified one.
+ *
+ * @param {string} id
+ * Identifier of the command
+ * @returns {object[]} Removed commands
+ */
+ replaceBefore : function (id, commands) {
+ var oldCommands = this.removeBefore(id);
+ this.insertBefore(id, commands);
+
+ return oldCommands;
+ },
+
+ /**
+ * Remove all commands whose identifiers match the specified regex.
+ *
+ * @param {regex} id_match
+ * Regular expression to match command identifiers.
+ */
+ filterOut : function (id_match) {
+ for (var i = this._commands.length - 1; i >= 0; i--) {
+ if (id_match.test(this._commands[i][0])) {
+ this._commands.splice(i, 1);
+ }
+ }
+ }
+};
+
+/**
* This class provides a state checker for media elements which store
* a media stream to check for media attribute state and events fired.
* When constructed by a caller, an object instance is created with
* a media element, event state checkers for canplaythrough, timeupdate, and
* time changing on the media element and stream.
*
* @param {HTMLMediaElement} element the media element being analyzed
*/
function MediaElementChecker(element) {
this.element = element;
this.canPlayThroughFired = false;
this.timeUpdateFired = false;
this.timePassed = false;
- var elementId = this.element.getAttribute('id');
+ var self = this;
+ var elementId = self.element.getAttribute('id');
// When canplaythrough fires, we track that it's fired and remove the
// event listener.
- var canPlayThroughCallback = () => {
+ var canPlayThroughCallback = function() {
info('canplaythrough fired for media element ' + elementId);
- this.canPlayThroughFired = true;
- this.element.removeEventListener('canplaythrough', canPlayThroughCallback,
+ self.canPlayThroughFired = true;
+ self.element.removeEventListener('canplaythrough', canPlayThroughCallback,
false);
};
// When timeupdate fires, we track that it's fired and check if time
// has passed on the media stream and media element.
- var timeUpdateCallback = () => {
- this.timeUpdateFired = true;
+ var timeUpdateCallback = function() {
+ self.timeUpdateFired = true;
info('timeupdate fired for media element ' + elementId);
// If time has passed, then track that and remove the timeupdate event
// listener.
if(element.mozSrcObject && element.mozSrcObject.currentTime > 0 &&
element.currentTime > 0) {
info('time passed for media element ' + elementId);
- this.timePassed = true;
- this.element.removeEventListener('timeupdate', timeUpdateCallback,
+ self.timePassed = true;
+ self.element.removeEventListener('timeupdate', timeUpdateCallback,
false);
}
};
element.addEventListener('canplaythrough', canPlayThroughCallback, false);
element.addEventListener('timeupdate', timeUpdateCallback, false);
}
MediaElementChecker.prototype = {
/**
* Waits until the canplaythrough & timeupdate events to fire along with
* ensuring time has passed on the stream and media element.
+ *
+ * @param {Function} onSuccess the success callback when media flow is
+ * established
*/
- waitForMediaFlow: function() {
- var elementId = this.element.getAttribute('id');
+ waitForMediaFlow : function MEC_WaitForMediaFlow(onSuccess) {
+ var self = this;
+ var elementId = self.element.getAttribute('id');
info('Analyzing element: ' + elementId);
- return waitUntil(() => this.canPlayThroughFired && this.timeUpdateFired && this.timePassed)
- .then(() => ok(true, 'Media flowing for ' + elementId));
+ if(self.canPlayThroughFired && self.timeUpdateFired && self.timePassed) {
+ ok(true, 'Media flowing for ' + elementId);
+ onSuccess();
+ } else {
+ setTimeout(function() {
+ self.waitForMediaFlow(onSuccess);
+ }, 100);
+ }
},
/**
* Checks if there is no media flow present by checking that the ready
* state of the media element is HAVE_METADATA.
*/
- checkForNoMediaFlow: function() {
+ checkForNoMediaFlow : function MEC_CheckForNoMediaFlow() {
ok(this.element.readyState === HTMLMediaElement.HAVE_METADATA,
'Media element has a ready state of HAVE_METADATA');
}
};
/**
* Only calls info() if SimpleTest.info() is available
*/
function safeInfo(message) {
- if (typeof info === "function") {
+ if (typeof(info) === "function") {
info(message);
}
}
// Also remove mode 0 if it's offered
// Note, we don't bother removing the fmtp lines, which makes a good test
// for some SDP parsing issues.
function removeVP8(sdp) {
@@ -117,16 +381,138 @@ function removeVP8(sdp) {
updated_sdp = updated_sdp.replace("RTP/SAVPF 120 126\r\n","RTP/SAVPF 126\r\n");
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack\r\n","");
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 nack pli\r\n","");
updated_sdp = updated_sdp.replace("a=rtcp-fb:120 ccm fir\r\n","");
return updated_sdp;
}
/**
+ * Query function for determining if any IP address is available for
+ * generating SDP.
+ *
+ * @return false if required additional network setup.
+ */
+function isNetworkReady() {
+ // for gonk platform
+ if ("nsINetworkInterfaceListService" in SpecialPowers.Ci) {
+ var listService = SpecialPowers.Cc["@mozilla.org/network/interface-list-service;1"]
+ .getService(SpecialPowers.Ci.nsINetworkInterfaceListService);
+ var itfList = listService.getDataInterfaceList(
+ SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_MMS_INTERFACES |
+ SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_SUPL_INTERFACES |
+ SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_IMS_INTERFACES |
+ SpecialPowers.Ci.nsINetworkInterfaceListService.LIST_NOT_INCLUDE_DUN_INTERFACES);
+ var num = itfList.getNumberOfInterface();
+ for (var i = 0; i < num; i++) {
+ var ips = {};
+ var prefixLengths = {};
+ var length = itfList.getInterface(i).getAddresses(ips, prefixLengths);
+
+ for (var j = 0; j < length; j++) {
+ var ip = ips.value[j];
+ // skip IPv6 address until bug 797262 is implemented
+ if (ip.indexOf(":") < 0) {
+ safeInfo("Network interface is ready with address: " + ip);
+ return true;
+ }
+ }
+ }
+ // ip address is not available
+ safeInfo("Network interface is not ready, required additional network setup");
+ return false;
+ }
+ safeInfo("Network setup is not required");
+ return true;
+}
+
+/**
+ * Network setup utils for Gonk
+ *
+ * @return {object} providing functions for setup/teardown data connection
+ */
+function getNetworkUtils() {
+ var url = SimpleTest.getTestFileURL("NetworkPreparationChromeScript.js");
+ var script = SpecialPowers.loadChromeScript(url);
+
+ var utils = {
+ /**
+ * Utility for setting up data connection.
+ *
+ * @param aCallback callback after data connection is ready.
+ */
+ prepareNetwork: function(onSuccess) {
+ script.addMessageListener('network-ready', function (message) {
+ info("Network interface is ready");
+ onSuccess();
+ });
+ info("Setting up network interface");
+ script.sendAsyncMessage("prepare-network", true);
+ },
+ /**
+ * Utility for tearing down data connection.
+ *
+ * @param aCallback callback after data connection is closed.
+ */
+ tearDownNetwork: function(onSuccess, onFailure) {
+ if (isNetworkReady()) {
+ script.addMessageListener('network-disabled', function (message) {
+ info("Network interface torn down");
+ script.destroy();
+ onSuccess();
+ });
+ info("Tearing down network interface");
+ script.sendAsyncMessage("network-cleanup", true);
+ } else {
+ info("No network to tear down");
+ onFailure();
+ }
+ }
+ };
+
+ return utils;
+}
+
+/**
+ * Setup network on Gonk if needed and execute test once network is up
+ *
+ */
+function startNetworkAndTest(onSuccess) {
+ if (!isNetworkReady()) {
+ SimpleTest.waitForExplicitFinish();
+ var utils = getNetworkUtils();
+ // Trigger network setup to obtain IP address before creating any PeerConnection.
+ utils.prepareNetwork(onSuccess);
+ } else {
+ onSuccess();
+ }
+}
+
+/**
+ * A wrapper around SimpleTest.finish() to handle B2G network teardown
+ */
+function networkTestFinished() {
+ if ("nsINetworkInterfaceListService" in SpecialPowers.Ci) {
+ var utils = getNetworkUtils();
+ utils.tearDownNetwork(SimpleTest.finish, SimpleTest.finish);
+ } else {
+ SimpleTest.finish();
+ }
+}
+
+/**
+ * A wrapper around runTest() which handles B2G network setup and teardown
+ */
+function runNetworkTest(testFunction) {
+ startNetworkAndTest(function() {
+ runTest(testFunction);
+ });
+}
+
+/**
* This class handles tests for peer connections.
*
* @constructor
* @param {object} [options={}]
* Optional options for the peer connection test
* @param {object} [options.commands=commandsPeerConnection]
* Commands to run for the test
* @param {bool} [options.is_local=true]
@@ -180,337 +566,637 @@ function PeerConnectionTest(options) {
// Create command chain instance and assign default commands
this.chain = new CommandChain(this, options.commands);
if (!options.is_local) {
this.chain.filterOut(/^PC_LOCAL/);
}
if (!options.is_remote) {
this.chain.filterOut(/^PC_REMOTE/);
}
-}
-/** TODO: consider removing this dependency on timeouts */
-function timerGuard(p, time, message) {
- return Promise.race([
- p,
- wait(time).then(() => {
- throw new Error('timeout after ' + (time / 1000) + 's: ' + message);
- })
- ]);
+ var self = this;
+ this.chain.onFinished = function () {
+ self.teardown();
+ };
}
/**
* Closes the peer connection if it is active
*
* @param {Function} onSuccess
* Callback to execute when the peer connection has been closed successfully
*/
-PeerConnectionTest.prototype.closePC = function() {
+PeerConnectionTest.prototype.closePC = function PCT_closePC(onSuccess) {
info("Closing peer connections");
- var closeIt = pc => {
- if (!pc || pc.signalingState === "closed") {
- return Promise.resolve();
+ var self = this;
+ var closeTimeout = null;
+ var waitingForLocal = false;
+ var waitingForRemote = false;
+ var everythingClosed = false;
+
+ function verifyClosed() {
+ if ((self.waitingForLocal || self.waitingForRemote) ||
+ (self.pcLocal && (self.pcLocal.signalingState !== "closed")) ||
+ (self.pcRemote && (self.pcRemote.signalingState !== "closed"))) {
+ info("still waiting for closure");
}
+ else if (!everythingClosed) {
+ info("No closure pending");
+ if (self.pcLocal) {
+ is(self.pcLocal.signalingState, "closed", "pcLocal is in 'closed' state");
+ }
+ if (self.pcRemote) {
+ is(self.pcRemote.signalingState, "closed", "pcRemote is in 'closed' state");
+ }
+ clearTimeout(closeTimeout);
+ everythingClosed = true;
+ onSuccess();
+ }
+ }
+
+ function signalingstatechangeLocalClose(e) {
+ info("'signalingstatechange' event received");
+ is(e.target.signalingState, "closed", "signalingState is closed");
+ self.waitingForLocal = false;
+ verifyClosed();
+ }
- return new Promise(resolve => {
- pc.onsignalingstatechange = e => {
- is(e.target.signalingState, "closed", "signalingState is closed");
- resolve();
- };
- pc.close();
- });
- };
+ function signalingstatechangeRemoteClose(e) {
+ info("'signalingstatechange' event received");
+ is(e.target.signalingState, "closed", "signalingState is closed");
+ self.waitingForRemote = false;
+ verifyClosed();
+ }
- return timerGuard(Promise.all([
- closeIt(this.pcLocal),
- closeIt(this.pcRemote)
- ]), 60000, "failed to close peer connection");
+ function closeEverything() {
+ if ((self.pcLocal) && (self.pcLocal.signalingState !== "closed")) {
+ info("Closing pcLocal");
+ self.pcLocal.onsignalingstatechange = signalingstatechangeLocalClose;
+ self.waitingForLocal = true;
+ self.pcLocal.close();
+ }
+ if ((self.pcRemote) && (self.pcRemote.signalingState !== "closed")) {
+ info("Closing pcRemote");
+ self.pcRemote.onsignalingstatechange = signalingstatechangeRemoteClose;
+ self.waitingForRemote = true;
+ self.pcRemote.close();
+ }
+ // give the signals handlers time to fire
+ setTimeout(verifyClosed, 1000);
+ }
+
+ closeTimeout = setTimeout(function() {
+ var closed = ((self.pcLocal && (self.pcLocal.signalingState === "closed")) &&
+ (self.pcRemote && (self.pcRemote.signalingState === "closed")));
+ ok(closed, "Closing PeerConnections timed out");
+ // it is not a success, but the show must go on
+ onSuccess();
+ }, 60000);
+
+ closeEverything();
};
/**
* Close the open data channels, followed by the underlying peer connection
+ *
+ * @param {Function} onSuccess
+ * Callback to execute when all connections have been closed
*/
-PeerConnectionTest.prototype.close = function() {
- var allChannels = (this.pcLocal || this.pcRemote).dataChannels;
- return timerGuard(
- Promise.all(allChannels.map((channel, i) => this.closeDataChannels(i))),
- 60000, "failed to close data channels")
- .then(() => this.closePC());
+PeerConnectionTest.prototype.close = function PCT_close(onSuccess) {
+ var self = this;
+ var pendingDcClose = []
+ var closeTimeout = null;
+
+ info("PeerConnectionTest.close() called");
+
+ function _closePeerConnection() {
+ info("Now closing PeerConnection");
+ self.closePC.call(self, onSuccess);
+ }
+
+ function _closePeerConnectionCallback(index) {
+ info("_closePeerConnection called with index " + index);
+ var pos = pendingDcClose.indexOf(index);
+ if (pos != -1) {
+ pendingDcClose.splice(pos, 1);
+ }
+ else {
+ info("_closePeerConnection index " + index + " is missing from pendingDcClose: " + pendingDcClose);
+ }
+ if (pendingDcClose.length === 0) {
+ clearTimeout(closeTimeout);
+ _closePeerConnection();
+ }
+ }
+
+ var myDataChannels = null;
+ if (self.pcLocal) {
+ myDataChannels = self.pcLocal.dataChannels;
+ }
+ else if (self.pcRemote) {
+ myDataChannels = self.pcRemote.dataChannels;
+ }
+ var length = myDataChannels.length;
+ for (var i = 0; i < length; i++) {
+ var dataChannel = myDataChannels[i];
+ if (dataChannel.readyState !== "closed") {
+ pendingDcClose.push(i);
+ self.closeDataChannels(i, _closePeerConnectionCallback);
+ }
+ }
+ if (pendingDcClose.length === 0) {
+ _closePeerConnection();
+ }
+ else {
+ closeTimeout = setTimeout(function() {
+ ok(false, "Failed to properly close data channels: " +
+ pendingDcClose);
+ _closePeerConnection();
+ }, 60000);
+ }
};
/**
* Close the specified data channels
*
* @param {Number} index
* Index of the data channels to close on both sides
+ * @param {Function} onSuccess
+ * Callback to execute when the data channels has been closed
*/
-PeerConnectionTest.prototype.closeDataChannels = function(index) {
+PeerConnectionTest.prototype.closeDataChannels = function PCT_closeDataChannels(index, onSuccess) {
info("closeDataChannels called with index: " + index);
var localChannel = null;
if (this.pcLocal) {
localChannel = this.pcLocal.dataChannels[index];
}
var remoteChannel = null;
if (this.pcRemote) {
remoteChannel = this.pcRemote.dataChannels[index];
}
- // We need to setup all the close listeners before calling close
- var setupClosePromise = channel => {
- if (!channel) {
- return Promise.resolve();
- }
- return new Promise(resolve => {
- channel.onclose = () => {
- is(channel.readyState, "closed", name + " channel " + index + " closed");
- resolve();
- };
- });
- };
+ var self = this;
+ var wait = false;
+ var pollingMode = false;
+ var everythingClosed = false;
+ var verifyInterval = null;
+ var remoteCloseTimer = null;
- // make sure to setup close listeners before triggering any actions
- var allClosed = Promise.all([
- setupClosePromise(localChannel),
- setupClosePromise(remoteChannel)
- ]);
- var complete = timerGuard(allClosed, 60000, "failed to close data channel pair");
+ function _allChannelsAreClosed() {
+ var ret = null;
+ if (localChannel) {
+ ret = (localChannel.readyState === "closed");
+ }
+ if (remoteChannel) {
+ if (ret !== null) {
+ ret = (ret && (remoteChannel.readyState === "closed"));
+ }
+ else {
+ ret = (remoteChannel.readyState === "closed");
+ }
+ }
+ return ret;
+ }
- // triggering close on one side should suffice
- if (remoteChannel) {
- remoteChannel.close();
- } else if (localChannel) {
- localChannel.close();
+ function verifyClosedChannels() {
+ if (everythingClosed) {
+ // safety protection against events firing late
+ return;
+ }
+ if (_allChannelsAreClosed()) {
+ ok(true, "DataChannel(s) have reached 'closed' state for data channel " + index);
+ if (remoteCloseTimer !== null) {
+ clearTimeout(remoteCloseTimer);
+ }
+ if (verifyInterval !== null) {
+ clearInterval(verifyInterval);
+ }
+ everythingClosed = true;
+ onSuccess(index);
+ }
+ else {
+ info("Still waiting for DataChannel closure");
+ }
}
- return complete;
+ if ((localChannel) && (localChannel.readyState !== "closed")) {
+ // in case of steeplechase there is no far end, so we can only poll
+ if (remoteChannel) {
+ remoteChannel.onclose = function () {
+ is(remoteChannel.readyState, "closed", "remoteChannel is in state 'closed'");
+ verifyClosedChannels();
+ };
+ }
+ else {
+ pollingMode = true;
+ verifyInterval = setInterval(verifyClosedChannels, 1000);
+ }
+
+ localChannel.close();
+ wait = true;
+ }
+ if ((remoteChannel) && (remoteChannel.readyState !== "closed")) {
+ if (localChannel) {
+ localChannel.onclose = function () {
+ is(localChannel.readyState, "closed", "localChannel is in state 'closed'");
+ verifyClosedChannels();
+ };
+
+ // Apparently we are running a local test which has both ends of the
+ // data channel locally available, so by default lets wait for the
+ // remoteChannel.onclose handler from above to confirm closure on both
+ // ends.
+ remoteCloseTimer = setTimeout(function() {
+ todo(false, "localChannel.close() did not resulted in close signal on remote side");
+ remoteChannel.close();
+ verifyClosedChannels();
+ }, 30000);
+ }
+ else {
+ pollingMode = true;
+ verifyTimer = setInterval(verifyClosedChannels, 1000);
+
+ remoteChannel.close();
+ }
+
+ wait = true;
+ }
+
+ if (!wait) {
+ onSuccess(index);
+ }
+};
+
+
+/**
+ * Wait for the initial data channel to get into the open state
+ *
+ * @param {PeerConnectionWrapper} peer
+ * The peer connection wrapper to run the command on
+ * @param {Function} onSuccess
+ * Callback when the creation was successful
+ */
+PeerConnectionTest.prototype.waitForInitialDataChannel =
+ function PCT_waitForInitialDataChannel(peer, onSuccess, onFailure) {
+ var dcConnectionTimeout = null;
+ var dcOpened = false;
+
+ function dataChannelConnected(channel) {
+ // in case the switch statement below had called onSuccess already we
+ // don't want to call it again
+ if (!dcOpened) {
+ clearTimeout(dcConnectionTimeout);
+ is(channel.readyState, "open", peer + " dataChannels[0] switched to state: 'open'");
+ dcOpened = true;
+ onSuccess();
+ } else {
+ info("dataChannelConnected() called, but data channel was open already");
+ }
+ }
+
+ // TODO: drno: convert dataChannels into an object and make
+ // registerDataChannelOpenEvent a generic function
+ if (peer == this.pcLocal) {
+ peer.dataChannels[0].onopen = dataChannelConnected;
+ } else {
+ peer.registerDataChannelOpenEvents(dataChannelConnected);
+ }
+
+ if (peer.dataChannels.length >= 1) {
+ // snapshot of the live value as it might change during test execution
+ const readyState = peer.dataChannels[0].readyState;
+ switch (readyState) {
+ case "open": {
+ is(readyState, "open", peer + " dataChannels[0] is already in state: 'open'");
+ dcOpened = true;
+ onSuccess();
+ break;
+ }
+ case "connecting": {
+ is(readyState, "connecting", peer + " dataChannels[0] is in state: 'connecting'");
+ if (onFailure) {
+ dcConnectionTimeout = setTimeout(function () {
+ is(peer.dataChannels[0].readyState, "open", peer + " timed out while waiting for dataChannels[0] to open");
+ onFailure();
+ }, 60000);
+ }
+ break;
+ }
+ default: {
+ ok(false, "dataChannels[0] is in unexpected state " + readyState);
+ if (onFailure) {
+ onFailure()
+ }
+ }
+ }
+ }
};
/**
* Send data (message or blob) to the other peer
*
* @param {String|Blob} data
* Data to send to the other peer. For Blobs the MIME type will be lost.
+ * @param {Function} onSuccess
+ * Callback to execute when data has been sent
* @param {Object} [options={ }]
* Options to specify the data channels to be used
* @param {DataChannelWrapper} [options.sourceChannel=pcLocal.dataChannels[length - 1]]
* Data channel to use for sending the message
* @param {DataChannelWrapper} [options.targetChannel=pcRemote.dataChannels[length - 1]]
* Data channel to use for receiving the message
*/
-PeerConnectionTest.prototype.send = function(data, options) {
+PeerConnectionTest.prototype.send = function PCT_send(data, onSuccess, options) {
options = options || { };
var source = options.sourceChannel ||
this.pcLocal.dataChannels[this.pcLocal.dataChannels.length - 1];
var target = options.targetChannel ||
this.pcRemote.dataChannels[this.pcRemote.dataChannels.length - 1];
- return new Promise(resolve => {
- // Register event handler for the target channel
- target.onmessage = e => {
- resolve({ channel: target, data: e.data });
- };
+ // Register event handler for the target channel
+ target.onmessage = function (recv_data) {
+ onSuccess(target, recv_data);
+ };
- source.send(data);
- });
+ source.send(data);
};
/**
* Create a data channel
*
* @param {Dict} options
* Options for the data channel (see nsIPeerConnection)
+ * @param {Function} onSuccess
+ * Callback when the creation was successful
*/
-PeerConnectionTest.prototype.createDataChannel = function(options) {
- var remotePromise;
- if (!options.negotiated) {
- this.pcRemote.expectDataChannel();
- remotePromise = this.pcRemote.nextDataChannel;
+PeerConnectionTest.prototype.createDataChannel = function DCT_createDataChannel(options, onSuccess) {
+ var localChannel = null;
+ var remoteChannel = null;
+ var self = this;
+
+ // Method to synchronize all asynchronous events.
+ function check_next_test() {
+ if (localChannel && remoteChannel) {
+ onSuccess(localChannel, remoteChannel);
+ }
}
- // Create the datachannel
- var localChannel = this.pcLocal.createDataChannel(options)
- var localPromise = localChannel.opened;
-
- if (options.negotiated) {
- remotePromise = localPromise.then(localChannel => {
- // externally negotiated - we need to open from both ends
- options.id = options.id || channel.id; // allow for no id on options
- var remoteChannel = this.pcRemote.createDataChannel(options);
- return remoteChannel.opened;
+ if (!options.negotiated) {
+ // Register handlers for the remote peer
+ this.pcRemote.registerDataChannelOpenEvents(function (channel) {
+ remoteChannel = channel;
+ check_next_test();
});
}
- return Promise.all([localPromise, remotePromise]).then(result => {
- return { local: result[0], remote: result[1] };
+ // Create the datachannel and handle the local 'onopen' event
+ this.pcLocal.createDataChannel(options, function (channel) {
+ localChannel = channel;
+
+ if (options.negotiated) {
+ // externally negotiated - we need to open from both ends
+ options.id = options.id || channel.id; // allow for no id to let the impl choose
+ self.pcRemote.createDataChannel(options, function (channel) {
+ remoteChannel = channel;
+ check_next_test();
+ });
+ } else {
+ check_next_test();
+ }
});
};
/**
+ * Executes the next command.
+ */
+PeerConnectionTest.prototype.next = function PCT_next() {
+ if (this._stepTimeout) {
+ clearTimeout(this._stepTimeout);
+ this._stepTimeout = null;
+ }
+ this.chain.executeNext();
+};
+
+/**
+ * Set a timeout for the current step.
+ * @param {long] ms the number of milliseconds to allow for this step
+ */
+PeerConnectionTest.prototype.setStepTimeout = function(ms) {
+ this._stepTimeout = setTimeout(function() {
+ ok(false, "Step timed out: " + this.chain.currentStepLabel);
+ this.next();
+ }.bind(this), ms);
+};
+
+/**
+ * Set a timeout for the over all PeerConnectionTest
+ * @param {long] ms the number of milliseconds to allow for the test
+ */
+PeerConnectionTest.prototype.setTimeout = function(ms) {
+ this._timeout = setTimeout(function() {
+ ok(false, "PeerConnectionTest timed out");
+ this.teardown();
+ }.bind(this), ms);
+};
+
+/**
* Creates an answer for the specified peer connection instance
* and automatically handles the failure case.
*
* @param {PeerConnectionWrapper} peer
* The peer connection wrapper to run the command on
+ * @param {function} onSuccess
+ * Callback to execute if the offer was created successfully
*/
-PeerConnectionTest.prototype.createAnswer = function(peer) {
- return peer.createAnswer().then(answer => {
+PeerConnectionTest.prototype.createAnswer =
+function PCT_createAnswer(peer, onSuccess) {
+ var self = this;
+
+ peer.createAnswer(function (answer) {
// make a copy so this does not get updated with ICE candidates
- this.originalAnswer = new mozRTCSessionDescription(JSON.parse(JSON.stringify(answer)));
- return answer;
+ self.originalAnswer = new mozRTCSessionDescription(JSON.parse(JSON.stringify(answer)));
+ onSuccess(answer);
});
};
/**
* Creates an offer for the specified peer connection instance
* and automatically handles the failure case.
*
* @param {PeerConnectionWrapper} peer
* The peer connection wrapper to run the command on
+ * @param {function} onSuccess
+ * Callback to execute if the offer was created successfully
*/
-PeerConnectionTest.prototype.createOffer = function(peer) {
- return peer.createOffer().then(offer => {
+PeerConnectionTest.prototype.createOffer =
+function PCT_createOffer(peer, onSuccess) {
+ var self = this;
+
+ peer.createOffer(function (offer) {
// make a copy so this does not get updated with ICE candidates
- this.originalOffer = new mozRTCSessionDescription(JSON.parse(JSON.stringify(offer)));
- return offer;
+ self.originalOffer = new mozRTCSessionDescription(JSON.parse(JSON.stringify(offer)));
+ onSuccess(offer);
});
};
PeerConnectionTest.prototype.setIdentityProvider =
function(peer, provider, protocol, identity) {
peer.setIdentityProvider(provider, protocol, identity);
};
/**
* Sets the local description for the specified peer connection instance
* and automatically handles the failure case.
*
* @param {PeerConnectionWrapper} peer
The peer connection wrapper to run the command on
* @param {mozRTCSessionDescription} desc
* Session description for the local description request
+ * @param {function} onSuccess
+ * Callback to execute if the local description was set successfully
*/
PeerConnectionTest.prototype.setLocalDescription =
-function(peer, desc, stateExpected) {
- var eventFired = new Promise(resolve => {
- peer.onsignalingstatechange = e => {
- info(peer + ": 'signalingstatechange' event received");
- var state = e.target.signalingState;
- if (stateExpected === state) {
- peer.setLocalDescStableEventDate = new Date();
- resolve();
- } else {
- ok(false, "This event has either already fired or there has been a " +
- "mismatch between event received " + state +
- " and event expected " + stateExpected);
- }
- };
+function PCT_setLocalDescription(peer, desc, stateExpected, onSuccess) {
+ var eventFired = false;
+ var stateChanged = false;
+
+ function check_next_test() {
+ if (eventFired && stateChanged) {
+ onSuccess();
+ }
+ }
+
+ peer.onsignalingstatechange = function (e) {
+ info(peer + ": 'signalingstatechange' event received");
+ var state = e.target.signalingState;
+ if(stateExpected === state && !eventFired) {
+ eventFired = true;
+ peer.setLocalDescStableEventDate = new Date();
+ check_next_test();
+ } else {
+ ok(false, "This event has either already fired or there has been a " +
+ "mismatch between event received " + state +
+ " and event expected " + stateExpected);
+ }
+ };
+
+ peer.setLocalDescription(desc, function () {
+ stateChanged = true;
+ peer.setLocalDescDate = new Date();
+ check_next_test();
});
-
- var stateChanged = peer.setLocalDescription(desc).then(() => {
- peer.setLocalDescDate = new Date();
- });
-
- return Promise.all([eventFired, stateChanged]);
};
/**
* Sets the media constraints for both peer connection instances.
*
* @param {object} constraintsLocal
* Media constrains for the local peer connection instance
* @param constraintsRemote
*/
PeerConnectionTest.prototype.setMediaConstraints =
-function(constraintsLocal, constraintsRemote) {
- if (this.pcLocal) {
+function PCT_setMediaConstraints(constraintsLocal, constraintsRemote) {
+ if (this.pcLocal)
this.pcLocal.constraints = constraintsLocal;
- }
- if (this.pcRemote) {
+ if (this.pcRemote)
this.pcRemote.constraints = constraintsRemote;
- }
};
/**
* Sets the media options used on a createOffer call in the test.
*
* @param {object} options the media constraints to use on createOffer
*/
-PeerConnectionTest.prototype.setOfferOptions = function(options) {
- if (this.pcLocal) {
+PeerConnectionTest.prototype.setOfferOptions =
+function PCT_setOfferOptions(options) {
+ if (this.pcLocal)
this.pcLocal.offerOptions = options;
- }
};
/**
* Sets the remote description for the specified peer connection instance
* and automatically handles the failure case.
*
* @param {PeerConnectionWrapper} peer
The peer connection wrapper to run the command on
* @param {mozRTCSessionDescription} desc
* Session description for the remote description request
+ * @param {function} onSuccess
+ * Callback to execute if the local description was set successfully
*/
PeerConnectionTest.prototype.setRemoteDescription =
-function(peer, desc, stateExpected) {
- var eventFired = new Promise(resolve => {
- peer.onsignalingstatechange = e => {
- info(peer + ": 'signalingstatechange' event received");
- var state = e.target.signalingState;
- if (stateExpected === state) {
- peer.setRemoteDescStableEventDate = new Date();
- resolve();
- } else {
- ok(false, "This event has either already fired or there has been a " +
- "mismatch between event received " + state +
- " and event expected " + stateExpected);
- }
- };
+function PCT_setRemoteDescription(peer, desc, stateExpected, onSuccess) {
+ var eventFired = false;
+ var stateChanged = false;
+
+ function check_next_test() {
+ if (eventFired && stateChanged) {
+ onSuccess();
+ }
+ }
+
+ peer.onsignalingstatechange = function(e) {
+ info(peer + ": 'signalingstatechange' event received");
+ var state = e.target.signalingState;
+ if(stateExpected === state && !eventFired) {
+ eventFired = true;
+ peer.setRemoteDescStableEventDate = new Date();
+ check_next_test();
+ } else {
+ ok(false, "This event has either already fired or there has been a " +
+ "mismatch between event received " + state +
+ " and event expected " + stateExpected);
+ }
+ };
+
+ peer.setRemoteDescription(desc, function () {
+ stateChanged = true;
+ peer.setRemoteDescDate = new Date();
+ check_next_test();
});
-
- var stateChanged = peer.setRemoteDescription(desc).then(() => {
- peer.setRemoteDescDate = new Date();
- });
-
- return Promise.all([eventFired, stateChanged]);
};
/**
* Start running the tests as assigned to the command chain.
*/
-PeerConnectionTest.prototype.run = function() {
- return this.chain.execute()
- .then(() => this.close())
- .then(() => {
- if (window.SimpleTest) {
- networkTestFinished();
- } else {
- finish();
- }
- })
- .catch(e =>
- ok(false, 'Error in test execution: ' + e +
- ((typeof e.stack === 'string') ?
- (' ' + e.stack.split('\n').join(' ... ')) : '')));
+PeerConnectionTest.prototype.run = function PCT_run() {
+ this.next();
+};
+
+/**
+ * Clean up the objects used by the test
+ */
+PeerConnectionTest.prototype.teardown = function PCT_teardown() {
+ this.close(function () {
+ info("Test finished");
+ if (window.SimpleTest)
+ networkTestFinished();
+ else
+ finish();
+ });
};
/**
* Routes ice candidates from one PCW to the other PCW
*/
-PeerConnectionTest.prototype.iceCandidateHandler = function(caller, candidate) {
+PeerConnectionTest.prototype.iceCandidateHandler = function
+PCT_iceCandidateHandler(caller, candidate) {
+ var self = this;
+
info("Received: " + JSON.stringify(candidate) + " from " + caller);
var target = null;
if (caller.contains("pcLocal")) {
- if (this.pcRemote) {
- target = this.pcRemote;
+ if (self.pcRemote) {
+ target = self.pcRemote;
}
} else if (caller.contains("pcRemote")) {
- if (this.pcLocal) {
- target = this.pcLocal;
+ if (self.pcLocal) {
+ target = self.pcLocal;
}
} else {
ok(false, "received event from unknown caller: " + caller);
return;
}
if (target) {
target.storeOrAddIceCandidate(candidate);
@@ -519,83 +1205,110 @@ PeerConnectionTest.prototype.iceCandidat
send_message({"type": "ice_candidate", "ice_candidate": candidate});
}
};
/**
* Installs a polling function for the socket.io client to read
* all messages from the chat room into a message queue.
*/
-PeerConnectionTest.prototype.setupSignalingClient = function() {
- this.signalingMessageQueue = [];
- this.signalingCallbacks = {};
- this.signalingLoopRun = true;
+PeerConnectionTest.prototype.setupSignalingClient = function
+PCT_setupSignalingClient() {
+ var self = this;
- var queueMessage = message => {
+ self.signalingMessageQueue = [];
+ self.signalingCallbacks = {};
+ self.signalingLoopRun = true;
+
+ function queueMessage(message) {
info("Received signaling message: " + JSON.stringify(message));
var fired = false;
- Object.keys(this.signalingCallbacks).forEach(name => {
+ Object.keys(self.signalingCallbacks).forEach(function(name) {
if (name === message.type) {
info("Invoking callback for message type: " + name);
- this.signalingCallbacks[name](message);
+ self.signalingCallbacks[name](message);
fired = true;
}
});
if (!fired) {
- this.signalingMessageQueue.push(message);
- info("signalingMessageQueue.length: " + this.signalingMessageQueue.length);
+ self.signalingMessageQueue.push(message);
+ info("signalingMessageQueue.length: " + self.signalingMessageQueue.length);
}
- if (this.signalingLoopRun) {
+ if (self.signalingLoopRun) {
wait_for_message().then(queueMessage);
} else {
info("Exiting signaling message event loop");
}
- };
+ }
+
wait_for_message().then(queueMessage);
}
/**
* Sets a flag to stop reading further messages from the chat room.
*/
-PeerConnectionTest.prototype.signalingMessagesFinished = function() {
+PeerConnectionTest.prototype.signalingMessagesFinished = function
+PCT_signalingMessagesFinished() {
this.signalingLoopRun = false;
}
/**
+ * Callback to stop reading message from chat room once trickle ICE
+ * on the far end is over.
+ *
+ * @param {string} caller
+ * The lable of the caller of the function
+ */
+PeerConnectionTest.prototype.signalEndOfTrickleIce = function
+PCT_signalEndOfTrickleIce(caller) {
+ if (this.steeplechase) {
+ send_message({"type": "end_of_trickle_ice"});
+ }
+};
+
+/**
* Register a callback function to deliver messages from the chat room
* directly instead of storing them in the message queue.
*
* @param {string} messageType
* For which message types should the callback get invoked.
*
* @param {function} onMessage
* The function which gets invoked if a message of the messageType
* has been received from the chat room.
*/
-PeerConnectionTest.prototype.registerSignalingCallback = function(messageType, onMessage) {
+PeerConnectionTest.prototype.registerSignalingCallback = function
+PCT_registerSignalingCallback(messageType, onMessage) {
this.signalingCallbacks[messageType] = onMessage;
-};
+}
/**
* Searches the message queue for the first message of a given type
* and invokes the given callback function, or registers the callback
* function for future messages if the queue contains no such message.
*
* @param {string} messageType
* The type of message to search and register for.
+ *
+ * @param {function} onMessage
+ * The callback function which gets invoked with the messages
+ * of the given mesage type.
*/
-PeerConnectionTest.prototype.getSignalingMessage = function(messageType) {
- var i = this.signalingMessageQueue.findIndex(m => m.type === messageType);
- if (i >= 0) {
- info("invoking callback on message " + i + " from message queue, for message type:" + messageType);
- return Promise.resolve(this.signalingMessageQueue.splice(i, 1)[0]);
+PeerConnectionTest.prototype.getSignalingMessage = function
+PCT_getSignalingMessage(messageType, onMessage) {
+ for(var i=0; i < this.signalingMessageQueue.length; i++) {
+ if (messageType === this.signalingMessageQueue[i].type) {
+ //FIXME
+ info("invoking callback on message " + i + " from message queue, for message type:" + messageType);
+ onMessage(this.signalingMessageQueue.splice(i, 1)[0]);
+ return;
+ }
}
- return new Promise(resolve =>
- this.registerSignalingCallback(messageType, resolve));
-};
+ this.registerSignalingCallback(messageType, onMessage);
+}
/**
* This class acts as a wrapper around a DataChannel instance.
*
* @param dataChannel
* @param peerConnectionWrapper
* @constructor
@@ -604,27 +1317,62 @@ function DataChannelWrapper(dataChannel,
this._channel = dataChannel;
this._pc = peerConnectionWrapper;
info("Creating " + this);
/**
* Setup appropriate callbacks
*/
- createOneShotEventWrapper(this, this._channel, 'close');
- createOneShotEventWrapper(this, this._channel, 'error');
- createOneShotEventWrapper(this, this._channel, 'message');
+
+ this.onclose = unexpectedEventAndFinish(this, 'onclose');
+ this.onerror = unexpectedEventAndFinish(this, 'onerror');
+ this.onmessage = unexpectedEventAndFinish(this, 'onmessage');
+ this.onopen = unexpectedEventAndFinish(this, 'onopen');
+
+ var self = this;
+
+ /**
+ * Callback for native data channel 'onclose' events. If no custom handler
+ * has been specified via 'this.onclose', a failure will be raised if an
+ * event of this type gets caught.
+ */
+ this._channel.onclose = function () {
+ info(self + ": 'onclose' event fired");
+
+ self.onclose(self);
+ self.onclose = unexpectedEventAndFinish(self, 'onclose');
+ };
- this.opened = timerGuard(new Promise(resolve => {
- this._channel.onopen = () => {
- this._channel.onopen = unexpectedEvent(this, 'onopen');
- is(this.readyState, "open", "data channel is 'open' after 'onopen'");
- resolve(this);
- };
- }), 60000, "channel didn't open in time");
+ /**
+ * Callback for native data channel 'onmessage' events. If no custom handler
+ * has been specified via 'this.onmessage', a failure will be raised if an
+ * event of this type gets caught.
+ *
+ * @param {Object} event
+ * Event data which includes the sent message
+ */
+ this._channel.onmessage = function (event) {
+ info(self + ": 'onmessage' event fired for '" + event.data + "'");
+
+ self.onmessage(event.data);
+ self.onmessage = unexpectedEventAndFinish(self, 'onmessage');
+ };
+
+ /**
+ * Callback for native data channel 'onopen' events. If no custom handler
+ * has been specified via 'this.onopen', a failure will be raised if an
+ * event of this type gets caught.
+ */
+ this._channel.onopen = function () {
+ info(self + ": 'onopen' event fired");
+
+ self.onopen(self);
+ self.onopen = unexpectedEventAndFinish(self, 'onopen');
+ };
}
DataChannelWrapper.prototype = {
/**
* Returns the binary type of the channel
*
* @returns {String} The binary type
*/
@@ -698,27 +1446,27 @@ DataChannelWrapper.prototype = {
},
/**
* Send data through the data channel
*
* @param {String|Object} data
* Data which has to be sent through the data channel
*/
- send: function(data) {
+ send: function DCW_send(data) {
info(this + ": Sending data '" + data + "'");
this._channel.send(data);
},
/**
* Returns the string representation of the class
*
* @returns {String} The string representation
*/
- toString: function() {
+ toString: function DCW_toString() {
return "DataChannelWrapper (" + this._pc.label + '_' + this._channel.label + ")";
}
};
/**
* This class acts as a wrapper around a PeerConnection instance.
*
@@ -735,73 +1483,119 @@ function PeerConnectionWrapper(label, co
this.constraints = [ ];
this.offerOptions = {};
this.streams = [ ];
this.mediaCheckers = [ ];
this.dataChannels = [ ];
- this.addStreamCounter = {audio: 0, video: 0 };
+ this.onAddStreamAudioCounter = 0;
+ this.onAddStreamVideoCounter = 0;
+ this.addStreamCallbacks = {};
this._local_ice_candidates = [];
this._remote_ice_candidates = [];
- this.holdIceCandidates = new Promise(r => this.releaseIceCandidates = r);
+ this._ice_candidates_to_add = [];
+ this.holdIceCandidates = true;
+ this.endOfTrickleIce = false;
this.localRequiresTrickleIce = false;
- this.remoteRequiresTrickleIce = false;
- this.localMediaElements = [];
+ this.remoteRequiresTrickleIce = false;
this.h264 = typeof h264 !== "undefined" ? true : false;
info("Creating " + this);
this._pc = new mozRTCPeerConnection(this.configuration);
/**
* Setup callback handlers
*/
+ var self = this;
+ // This enables tests to validate that the next ice state is the one they expect to happen
+ this.next_ice_state = ""; // in most cases, the next state will be "checking", but in some tests "closed"
// This allows test to register their own callbacks for ICE connection state changes
this.ice_connection_callbacks = {};
- this._pc.oniceconnectionstatechange = e => {
- isnot(typeof this._pc.iceConnectionState, "undefined",
- "iceConnectionState should not be undefined");
- info(this + ": oniceconnectionstatechange fired, new state is: " + this._pc.iceConnectionState);
- Object.keys(this.ice_connection_callbacks).forEach(name => {
- this.ice_connection_callbacks[name]();
+ this._pc.oniceconnectionstatechange = function() {
+ ok(self._pc.iceConnectionState !== undefined, "iceConnectionState should not be undefined");
+ info(self + ": oniceconnectionstatechange fired, new state is: " + self._pc.iceConnectionState);
+ Object.keys(self.ice_connection_callbacks).forEach(function(name) {
+ self.ice_connection_callbacks[name]();
});
+ if (self.next_ice_state !== "") {
+ is(self._pc.iceConnectionState, self.next_ice_state, "iceConnectionState changed to '" +
+ self.next_ice_state + "'");
+ self.next_ice_state = "";
+ }
};
/**
* Callback for native peer connection 'onaddstream' events.
*
* @param {Object} event
* Event data which includes the stream to be added
*/
- this._pc.onaddstream = event => {
- info(this + ": 'onaddstream' event fired for " + JSON.stringify(event.stream));
+ this._pc.onaddstream = function (event) {
+ info(self + ": 'onaddstream' event fired for " + JSON.stringify(event.stream));
var type = '';
if (event.stream.getAudioTracks().length > 0) {
type = 'audio';
- this.addStreamCounter.audio += this.countTracksInStreams('audio', [event.stream]);
+ self.onAddStreamAudioCounter += event.stream.getAudioTracks().length;
}
if (event.stream.getVideoTracks().length > 0) {
type += 'video';
- this.addStreamCounter.video += this.countTracksInStreams('video', [event.stream]);
+ self.onAddStreamVideoCounter += event.stream.getVideoTracks().length;
}
- this.attachMedia(event.stream, type, 'remote');
+ self.attachMedia(event.stream, type, 'remote');
+
+ Object.keys(self.addStreamCallbacks).forEach(function(name) {
+ info(self + " calling addStreamCallback " + name);
+ self.addStreamCallbacks[name]();
+ });
+ };
+
+ this.ondatachannel = unexpectedEventAndFinish(this, 'ondatachannel');
+
+ /**
+ * Callback for native peer connection 'ondatachannel' events. If no custom handler
+ * has been specified via 'this.ondatachannel', a failure will be raised if an
+ * event of this type gets caught.
+ *
+ * @param {Object} event
+ * Event data which includes the newly created data channel
+ */
+ this._pc.ondatachannel = function (event) {
+ info(self + ": 'ondatachannel' event fired for " + event.channel.label);
+
+ self.ondatachannel(new DataChannelWrapper(event.channel, self));
+ self.ondatachannel = unexpectedEventAndFinish(self, 'ondatachannel');
};
- createOneShotEventWrapper(this, this._pc, 'datachannel');
- this._pc.addEventListener('datachannel', e => {
- var wrapper = new DataChannelWrapper(e.channel, this);
- this.dataChannels.push(wrapper);
- });
+ this.onsignalingstatechange = unexpectedEventAndFinish(this, 'onsignalingstatechange');
+ this.signalingStateCallbacks = {};
- createOneShotEventWrapper(this, this._pc, 'signalingstatechange');
+ /**
+ * Callback for native peer connection 'onsignalingstatechange' events. If no
+ * custom handler has been specified via 'this.onsignalingstatechange', a
+ * failure will be raised if an event of this type is caught.
+ *
+ * @param {Object} aEvent
+ */
+ this._pc.onsignalingstatechange = function (anEvent) {
+ info(self + ": 'onsignalingstatechange' event fired");
+
+ Object.keys(self.signalingStateCallbacks).forEach(function(name) {
+ self.signalingStateCallbacks[name](anEvent);
+ });
+ // this calls the eventhandler only once and then overwrites it with the
+ // default unexpectedEvent handler
+ self.onsignalingstatechange(anEvent);
+ self.onsignalingstatechange = unexpectedEventAndFinish(self, 'onsignalingstatechange');
+ };
}
PeerConnectionWrapper.prototype = {
/**
* Returns the local description.
*
* @returns {object} The local description
@@ -866,380 +1660,489 @@ PeerConnectionWrapper.prototype = {
*
* @param {MediaStream} stream
* Media stream to handle
* @param {string} type
* The type of media stream ('audio' or 'video')
* @param {string} side
* The location the stream is coming from ('local' or 'remote')
*/
- attachMedia : function(stream, type, side) {
+ attachMedia : function PCW_attachMedia(stream, type, side) {
+ function isSenderOfTrack(sender) {
+ return sender.track == this;
+ }
+
info("Got media stream: " + type + " (" + side + ")");
this.streams.push(stream);
if (side === 'local') {
// In order to test both the addStream and addTrack APIs, we do video one
// way and audio + audiovideo the other.
if (type == "video") {
this._pc.addStream(stream);
- ok(this._pc.getSenders().find(sender => sender.track == stream.getVideoTracks()[0]),
+ ok(this._pc.getSenders().find(isSenderOfTrack,
+ stream.getVideoTracks()[0]),
"addStream adds sender");
} else {
- stream.getTracks().forEach(track => {
+ stream.getTracks().forEach(function(track) {
var sender = this._pc.addTrack(track, stream);
is(sender.track, track, "addTrack returns sender");
- });
+ }.bind(this));
}
}
- var element = createMediaElement(type, this.label + '_' + side + this.streams.length);
+ var element = createMediaElement(type, this.label + '_' + side);
this.mediaCheckers.push(new MediaElementChecker(element));
element.mozSrcObject = stream;
element.play();
-
- // Store local media elements so that we can stop them when done.
- // Don't store remote ones because they should stop when the PC does.
- if (side === 'local') {
- this.localMediaElements.push(element);
- }
},
/**
* Requests all the media streams as specified in the constrains property.
*
+ * @param {function} onSuccess
+ * Callback to execute if all media has been requested successfully
* @param {array} constraintsList
* Array of constraints for GUM calls
*/
- getAllUserMedia : function(constraintsList) {
- if (constraintsList.length === 0) {
- info("Skipping GUM: no UserMedia requested");
- return Promise.resolve();
+ getAllUserMedia : function PCW_GetAllUserMedia(constraintsList, onSuccess) {
+ var self = this;
+
+ function _getAllUserMedia(index) {
+ if (index < constraintsList.length) {
+ var constraints = constraintsList[index];
+
+ getUserMedia(constraints, function (stream) {
+ var type = '';
+
+ if (constraints.audio) {
+ type = 'audio';
+ }
+
+ if (constraints.video) {
+ type += 'video';
+ }
+
+ self.attachMedia(stream, type, 'local');
+
+ _getAllUserMedia(index + 1);
+ }, generateErrorCallback());
+ } else {
+ onSuccess();
+ }
}
- info("Get " + constraintsList.length + " local streams");
- return Promise.all(constraintsList.map(constraints => {
- return getUserMedia(constraints).then(stream => {
- var type = '';
- if (constraints.audio) {
- type = 'audio';
- }
- if (constraints.video) {
- type += 'video';
- }
- this.attachMedia(stream, type, 'local');
- });
- }));
- },
-
- /**
- * Create a new data channel instance. Also creates a promise called
- * `this.nextDataChannel` that resolves when the next data channel arrives.
- */
- expectDataChannel: function(message) {
- this.nextDataChannel = new Promise(resolve => {
- this.ondatachannel = e => {
- ok(e.channel, message);
- resolve(e.channel);
- };
- });
+ if (constraintsList.length === 0) {
+ info("Skipping GUM: no UserMedia requested");
+ onSuccess();
+ }
+ else {
+ info("Get " + constraintsList.length + " local streams");
+ _getAllUserMedia(0);
+ }
},
/**
* Create a new data channel instance
*
* @param {Object} options
* Options which get forwarded to nsIPeerConnection.createDataChannel
+ * @param {function} [onCreation=undefined]
+ * Callback to execute when the local data channel has been created
* @returns {DataChannelWrapper} The created data channel
*/
- createDataChannel : function(options) {
+ createDataChannel : function PCW_createDataChannel(options, onCreation) {
var label = 'channel_' + this.dataChannels.length;
info(this + ": Create data channel '" + label);
var channel = this._pc.createDataChannel(label, options);
var wrapper = new DataChannelWrapper(channel, this);
+
+ if (onCreation) {
+ wrapper.onopen = function () {
+ onCreation(wrapper);
+ };
+ }
+
this.dataChannels.push(wrapper);
return wrapper;
},
/**
* Creates an offer and automatically handles the failure case.
*
* @param {function} onSuccess
* Callback to execute if the offer was created successfully
*/
- createOffer : function() {
- return this._pc.createOffer(this.offerOptions).then(offer => {
+ createOffer : function PCW_createOffer(onSuccess) {
+ var self = this;
+
+ this._pc.createOffer(function (offer) {
info("Got offer: " + JSON.stringify(offer));
// note: this might get updated through ICE gathering
- this._latest_offer = offer;
- if (this.h264) {
+ self._latest_offer = offer;
+ if (self.h264) {
isnot(offer.sdp.search("H264/90000"), -1, "H.264 should be present in the SDP offer");
offer.sdp = removeVP8(offer.sdp);
}
- return offer;
- });
+ onSuccess(offer);
+ }, generateErrorCallback(), this.offerOptions);
},
/**
* Creates an answer and automatically handles the failure case.
+ *
+ * @param {function} onSuccess
+ * Callback to execute if the answer was created successfully
*/
- createAnswer : function() {
- return this._pc.createAnswer().then(answer => {
- info(this + ": Got answer: " + JSON.stringify(answer));
- this._last_answer = answer;
- return answer;
- });
+ createAnswer : function PCW_createAnswer(onSuccess) {
+ var self = this;
+
+ this._pc.createAnswer(function (answer) {
+ info(self + ": Got answer: " + JSON.stringify(answer));
+ self._last_answer = answer;
+ onSuccess(answer);
+ }, generateErrorCallback());
},
/**
* Sets the local description and automatically handles the failure case.
*
* @param {object} desc
* mozRTCSessionDescription for the local description request
+ * @param {function} onSuccess
+ * Callback to execute if the local description was set successfully
*/
- setLocalDescription : function(desc) {
- return this._pc.setLocalDescription(desc).then(() => {
- info(this + ": Successfully set the local description");
- });
+ setLocalDescription : function PCW_setLocalDescription(desc, onSuccess) {
+ var self = this;
+
+ if (onSuccess) {
+ this._pc.setLocalDescription(desc, function () {
+ info(self + ": Successfully set the local description");
+ onSuccess();
+ }, generateErrorCallback());
+ } else {
+ this._pc.setLocalDescription(desc);
+ }
},
/**
* Tries to set the local description and expect failure. Automatically
* causes the test case to fail if the call succeeds.
*
* @param {object} desc
* mozRTCSessionDescription for the local description request
- * @returns {Promise}
- * A promise that resolves to the expected error
+ * @param {function} onFailure
+ * Callback to execute if the call fails.
*/
- setLocalDescriptionAndFail : function(desc) {
- return this._pc.setLocalDescription(desc).then(
+ setLocalDescriptionAndFail : function PCW_setLocalDescriptionAndFail(desc, onFailure) {
+ var self = this;
+ this._pc.setLocalDescription(desc,
generateErrorCallback("setLocalDescription should have failed."),
- err => {
- info(this + ": As expected, failed to set the local description");
- return err;
- });
+ function (err) {
+ info(self + ": As expected, failed to set the local description");
+ onFailure(err);
+ });
},
/**
* Sets the remote description and automatically handles the failure case.
*
* @param {object} desc
* mozRTCSessionDescription for the remote description request
+ * @param {function} onSuccess
+ * Callback to execute if the remote description was set successfully
*/
- setRemoteDescription : function(desc) {
- return this._pc.setRemoteDescription(desc).then(() => {
- info(this + ": Successfully set remote description");
- this.releaseIceCandidates();
- });
+ setRemoteDescription : function PCW_setRemoteDescription(desc, onSuccess) {
+ var self = this;
+
+ if (!onSuccess) {
+ this._pc.setRemoteDescription(desc);
+ this.addStoredIceCandidates();
+ return;
+ }
+ this._pc.setRemoteDescription(desc, function () {
+ info(self + ": Successfully set remote description");
+ self.addStoredIceCandidates();
+ onSuccess();
+ }, generateErrorCallback());
},
/**
* Tries to set the remote description and expect failure. Automatically
* causes the test case to fail if the call succeeds.
*
* @param {object} desc
* mozRTCSessionDescription for the remote description request
- * @returns {Promise}
- * a promise that resolve to the returned error
+ * @param {function} onFailure
+ * Callback to execute if the call fails.
*/
- setRemoteDescriptionAndFail : function(desc) {
- return this._pc.setRemoteDescription(desc).then(
+ setRemoteDescriptionAndFail : function PCW_setRemoteDescriptionAndFail(desc, onFailure) {
+ var self = this;
+ this._pc.setRemoteDescription(desc,
generateErrorCallback("setRemoteDescription should have failed."),
- err => {
- info(this + ": As expected, failed to set the remote description");
- return err;
+ function (err) {
+ info(self + ": As expected, failed to set the remote description");
+ onFailure(err);
});
},
/**
* Registers a callback for the signaling state change and
* appends the new state to an array for logging it later.
*/
- logSignalingState: function() {
- this.signalingStateLog = [this._pc.signalingState];
- this._pc.addEventListener('signalingstatechange', e => {
- var newstate = this._pc.signalingState;
- var oldstate = this.signalingStateLog[this.signalingStateLog.length - 1]
- if (Object.keys(signalingStateTransitions).indexOf(oldstate) >= 0) {
- ok(signalingStateTransitions[oldstate].indexOf(newstate) >= 0, this + ": legal signaling state transition from " + oldstate + " to " + newstate);
+ logSignalingState: function PCW_logSignalingState() {
+ var self = this;
+
+ function _logSignalingState(e) {
+ var newstate = self._pc.signalingState;
+ var oldstate = self.signalingStateLog[self.signalingStateLog.length - 1]
+ if (Object.keys(signalingStateTransitions).indexOf(oldstate) != -1) {
+ ok(signalingStateTransitions[oldstate].indexOf(newstate) != -1, self + ": legal signaling state transition from " + oldstate + " to " + newstate);
} else {
- ok(false, this + ": old signaling state " + oldstate + " missing in signaling transition array");
+ ok(false, self + ": old signaling state " + oldstate + " missing in signaling transition array");
}
- this.signalingStateLog.push(newstate);
- });
+ self.signalingStateLog.push(newstate);
+ }
+
+ self.signalingStateLog = [self._pc.signalingState];
+ self.signalingStateCallbacks.logSignalingStatus = _logSignalingState;
},
/**
* Either adds a given ICE candidate right away or stores it to be added
* later, depending on the state of the PeerConnection.
*
* @param {object} candidate
* The mozRTCIceCandidate to be added or stored
*/
- storeOrAddIceCandidate : function(candidate) {
- this._remote_ice_candidates.push(candidate);
- if (this.signalingState === 'closed') {
+ storeOrAddIceCandidate : function PCW_storeOrAddIceCandidate(candidate) {
+ var self = this;
+
+ self._remote_ice_candidates.push(candidate);
+ if (self.signalingState === 'closed') {
info("Received ICE candidate for closed PeerConnection - discarding");
return;
}
- this.holdIceCandidates.then(() => {
- this.addIceCandidate(candidate);
- });
+ if (!self.holdIceCandidates) {
+ self.addIceCandidate(candidate);
+ } else {
+ self._ice_candidates_to_add.push(candidate);
+ }
+ },
+
+ addStoredIceCandidates : function PCW_addStoredIceCandidates() {
+ var self = this;
+
+ self.holdIceCandidates = false;
+ if ((self._ice_candidates_to_add) &&
+ (self._ice_candidates_to_add.length > 0)) {
+ info("adding stored ice candidates");
+ for (var i = 0; i < self._ice_candidates_to_add.length; i++) {
+ self.addIceCandidate(self._ice_candidates_to_add[i]);
+ }
+ self._ice_candidates_to_add = [];
+ }
},
/**
* Adds an ICE candidate and automatically handles the failure case.
*
* @param {object} candidate
* SDP candidate
+ * @param {function} onSuccess
+ * Callback to execute if the local description was set successfully
*/
- addIceCandidate : function(candidate) {
- info(this + ": adding ICE candidate " + JSON.stringify(candidate));
- return this._pc.addIceCandidate(candidate).then(() => {
- info(this + ": Successfully added an ICE candidate");
- });
+ addIceCandidate : function PCW_addIceCandidate(candidate, onSuccess) {
+ var self = this;
+
+ info(self + ": adding ICE candidate " + JSON.stringify(candidate));
+ this._pc.addIceCandidate(candidate, function () {
+ info(self + ": Successfully added an ICE candidate");
+ if (onSuccess) {
+ onSuccess();
+ }
+ }, generateErrorCallback());
+ },
+
+ /**
+ * Tries to add an ICE candidate and expects failure. Automatically
+ * causes the test case to fail if the call succeeds.
+ *
+ * @param {object} candidate
+ * SDP candidate
+ * @param {function} onFailure
+ * Callback to execute if the call fails.
+ */
+ addIceCandidateAndFail : function PCW_addIceCandidateAndFail(candidate, onFailure) {
+ var self = this;
+
+ this._pc.addIceCandidate(candidate,
+ generateErrorCallback("addIceCandidate should have failed."),
+ function (err) {
+ info(self + ": As expected, failed to add an ICE candidate");
+ onFailure(err);
+ }) ;
},
/**
* Returns if the ICE the connection state is "connected".
*
* @returns {boolean} True if the connection state is "connected", otherwise false.
*/
- isIceConnected : function() {
+ isIceConnected : function PCW_isIceConnected() {
info(this + ": iceConnectionState = " + this.iceConnectionState);
return this.iceConnectionState === "connected";
},
/**
* Returns if the ICE the connection state is "checking".
*
* @returns {boolean} True if the connection state is "checking", otherwise false.
*/
- isIceChecking : function() {
+ isIceChecking : function PCW_isIceChecking() {
return this.iceConnectionState === "checking";
},
/**
* Returns if the ICE the connection state is "new".
*
* @returns {boolean} True if the connection state is "new", otherwise false.
*/
- isIceNew : function() {
+ isIceNew : function PCW_isIceNew() {
return this.iceConnectionState === "new";
},
/**
* Checks if the ICE connection state still waits for a connection to get
* established.
*
* @returns {boolean} True if the connection state is "checking" or "new",
* otherwise false.
*/
- isIceConnectionPending : function() {
+ isIceConnectionPending : function PCW_isIceConnectionPending() {
return (this.isIceChecking() || this.isIceNew());
},
/**
* Registers a callback for the ICE connection state change and
* appends the new state to an array for logging it later.
*/
- logIceConnectionState: function() {
- this.iceConnectionLog = [this._pc.iceConnectionState];
- this.ice_connection_callbacks.logIceStatus = () => {
- var newstate = this._pc.iceConnectionState;
- var oldstate = this.iceConnectionLog[this.iceConnectionLog.length - 1]
+ logIceConnectionState: function PCW_logIceConnectionState() {
+ var self = this;
+
+ function logIceConState () {
+ var newstate = self._pc.iceConnectionState;
+ var oldstate = self.iceConnectionLog[self.iceConnectionLog.length - 1]
if (Object.keys(iceStateTransitions).indexOf(oldstate) != -1) {
- ok(iceStateTransitions[oldstate].indexOf(newstate) != -1, this + ": legal ICE state transition from " + oldstate + " to " + newstate);
+ ok(iceStateTransitions[oldstate].indexOf(newstate) != -1, self + ": legal ICE state transition from " + oldstate + " to " + newstate);
} else {
- ok(false, this + ": old ICE state " + oldstate + " missing in ICE transition array");
+ ok(false, self + ": old ICE state " + oldstate + " missing in ICE transition array");
}
- this.iceConnectionLog.push(newstate);
- };
+ self.iceConnectionLog.push(newstate);
+ }
+
+ self.iceConnectionLog = [self._pc.iceConnectionState];
+ self.ice_connection_callbacks.logIceStatus = logIceConState;
},
/**
* Registers a callback for the ICE connection state change and
* reports success (=connected) or failure via the callbacks.
* States "new" and "checking" are ignored.
*
- * @returns {Promise}
- * resolves when connected, rejects on failure
+ * @param {function} onSuccess
+ * Callback if ICE connection status is "connected".
+ * @param {function} onFailure
+ * Callback if ICE connection reaches a different state than
+ * "new", "checking" or "connected".
*/
- waitForIceConnected : function() {
- return new Promise((resolve, reject) => {
- var iceConnectedChanged = () => {
- if (this.isIceConnected()) {
- delete this.ice_connection_callbacks.waitForIceConnected;
- resolve();
- } else if (! this.isIceConnectionPending()) {
- delete this.ice_connection_callbacks.waitForIceConnected;
- resolve();
- }
+ waitForIceConnected : function PCW_waitForIceConnected(onSuccess, onFailure) {
+ var self = this;
+ var mySuccess = onSuccess;
+ var myFailure = onFailure;
+
+ function iceConnectedChanged () {
+ if (self.isIceConnected()) {
+ delete self.ice_connection_callbacks.waitForIceConnected;
+ mySuccess();
+ } else if (! self.isIceConnectionPending()) {
+ delete self.ice_connection_callbacks.waitForIceConnected;
+ myFailure();
}
+ }
- this.ice_connection_callbacks.waitForIceConnected = iceConnectedChanged;
- });
+ self.ice_connection_callbacks.waitForIceConnected = iceConnectedChanged;
},
/**
* Setup a onicecandidate handler
*
* @param {object} test
* A PeerConnectionTest object to which the ice candidates gets
* forwarded.
*/
- setupIceCandidateHandler : function(test, candidateHandler) {
- candidateHandler = candidateHandler || test.iceCandidateHandler.bind(test);
-
- var resolveEndOfTrickle;
- this.endOfTrickleIce = new Promise(r => resolveEndOfTrickle = r);
+ setupIceCandidateHandler : function
+ PCW_setupIceCandidateHandler(test, candidateHandler, endHandler) {
+ var self = this;
- this.endOfTrickleIce.then(() => {
- this._pc.onicecandidate = () =>
- ok(false, this.label + " received ICE candidate after end of trickle");
- });
+ candidateHandler = candidateHandler || test.iceCandidateHandler.bind(test);
+ endHandler = endHandler || test.signalEndOfTrickleIce.bind(test);
- this._pc.onicecandidate = anEvent => {
+ function iceCandidateCallback (anEvent) {
+ info(self.label + ": received iceCandidateEvent");
if (!anEvent.candidate) {
- info(this.label + ": received end of trickle ICE event");
- resolveEndOfTrickle(this.label);
- return;
+ info(self.label + ": received end of trickle ICE event");
+ self.endOfTrickleIce = true;
+ endHandler(self.label);
+ } else {
+ if (self.endOfTrickleIce) {
+ ok(false, "received ICE candidate after end of trickle");
+ }
+ info(self.label + ": iceCandidate = " + JSON.stringify(anEvent.candidate));
+ ok(anEvent.candidate.candidate.length > 0, "ICE candidate contains candidate");
+ // we don't support SDP MID's yet
+ ok(anEvent.candidate.sdpMid.length === 0, "SDP MID has length zero");
+ ok(typeof anEvent.candidate.sdpMLineIndex === 'number', "SDP MLine Index needs to exist");
+ self._local_ice_candidates.push(anEvent.candidate);
+ candidateHandler(self.label, anEvent.candidate);
}
+ }
- info(this.label + ": iceCandidate = " + JSON.stringify(anEvent.candidate));
- ok(anEvent.candidate.candidate.length > 0, "ICE candidate contains candidate");
- // we don't support SDP MID's yet
- ok(anEvent.candidate.sdpMid.length === 0, "SDP MID has length zero");
- ok(typeof anEvent.candidate.sdpMLineIndex === 'number', "SDP MLine Index needs to exist");
- this._local_ice_candidates.push(anEvent.candidate);
- candidateHandler(this.label, anEvent.candidate);
- };
+ self._pc.onicecandidate = iceCandidateCallback;
},
/**
* Counts the amount of audio tracks in a given media constraint.
*
* @param constraints
* The contraint to be examined.
*/
- countTracksInConstraint : function(type, constraints) {
- if (!Array.isArray(constraints)) {
+ countAudioTracksInMediaConstraint : function
+ PCW_countAudioTracksInMediaConstraint(constraints) {
+ if ((!constraints) || (constraints.length === 0)) {
return 0;
}
- return constraints.reduce((sum, c) => sum + (c[type] ? 1 : 0), 0);
+ var numAudioTracks = 0;
+ for (var i = 0; i < constraints.length; i++) {
+ if (constraints[i].audio) {
+ numAudioTracks++;
+ }
+ }
+ return numAudioTracks;
},
/**
* Checks for audio in given offer options.
*
* @param options
* The options to be examined.
*/
- audioInOfferOptions : function(options) {
+ audioInOfferOptions : function
+ PCW_audioInOfferOptions(options) {
if (!options) {
return 0;
}
var offerToReceiveAudio = options.offerToReceiveAudio;
// TODO: Remove tests of old constraint-like RTCOptions soon (Bug 1064223).
if (options.mandatory && options.mandatory.OfferToReceiveAudio !== undefined) {
@@ -1252,22 +2155,43 @@ PeerConnectionWrapper.prototype = {
if (offerToReceiveAudio) {
return 1;
} else {
return 0;
}
},
/**
+ * Counts the amount of video tracks in a given media constraint.
+ *
+ * @param constraint
+ * The contraint to be examined.
+ */
+ countVideoTracksInMediaConstraint : function
+ PCW_countVideoTracksInMediaConstraint(constraints) {
+ if ((!constraints) || (constraints.length === 0)) {
+ return 0;
+ }
+ var numVideoTracks = 0;
+ for (var i = 0; i < constraints.length; i++) {
+ if (constraints[i].video) {
+ numVideoTracks++;
+ }
+ }
+ return numVideoTracks;
+ },
+
+ /**
* Checks for video in given offer options.
*
* @param options
* The options to be examined.
*/
- videoInOfferOptions : function(options) {
+ videoInOfferOptions : function
+ PCW_videoInOfferOptions(options) {
if (!options) {
return 0;
}
var offerToReceiveVideo = options.offerToReceiveVideo;
// TODO: Remove tests of old constraint-like RTCOptions soon (Bug 1064223).
if (options.mandatory && options.mandatory.OfferToReceiveVideo !== undefined) {
@@ -1280,140 +2204,168 @@ PeerConnectionWrapper.prototype = {
if (offerToReceiveVideo) {
return 1;
} else {
return 0;
}
},
/*
- * Counts the amount of tracks of the given type in a set of streams.
+ * Counts the amount of audio tracks in a given set of streams.
*
- * @param type audio|video
* @param streams
* An array of streams (as returned by getLocalStreams()) to be
* examined.
*/
- countTracksInStreams: function(type, streams) {
- if (!Array.isArray(streams)) {
+ countAudioTracksInStreams : function PCW_countAudioTracksInStreams(streams) {
+ if (!streams || (streams.length === 0)) {
return 0;
}
- var f = (type === 'video') ? "getVideoTracks" : "getAudioTracks";
+ var numAudioTracks = 0;
+ streams.forEach(function(st) {
+ numAudioTracks += st.getAudioTracks().length;
+ });
+ return numAudioTracks;
+ },
- return streams.reduce((count, st) => {
- return count + st[f]().length;
- }, 0);
+ /*
+ * Counts the amount of video tracks in a given set of streams.
+ *
+ * @param streams
+ * An array of streams (as returned by getLocalStreams()) to be
+ * examined.
+ */
+ countVideoTracksInStreams: function PCW_countVideoTracksInStreams(streams) {
+ if (!streams || (streams.length === 0)) {
+ return 0;
+ }
+ var numVideoTracks = 0;
+ streams.forEach(function(st) {
+ numVideoTracks += st.getVideoTracks().length;
+ });
+ return numVideoTracks;
},
/**
* Checks that we are getting the media tracks we expect.
*
- * @param {object} constraints
- * The media constraints of the remote peer connection object
+ * @param {object} constraintsRemote
+ * The media constraints of the local and remote peer connection object
*/
- checkMediaTracks : function(remoteConstraints) {
- var waitForExpectedTracks = type => {
- var outstandingCount = this.countTracksInConstraint(type, remoteConstraints);
- outstandingCount -= this.addStreamCounter[type];
- if (outstandingCount <= 0) {
- return Promise.resolve();
- }
+ checkMediaTracks : function PCW_checkMediaTracks(constraintsRemote, onSuccess) {
+ var self = this;
+
+ function _checkMediaTracks(constraintsRemote, onSuccess) {
+
+ var localConstraintAudioTracks =
+ self.countAudioTracksInMediaConstraint(self.constraints);
+ var localStreams = self._pc.getLocalStreams();
+ var localAudioTracks = self.countAudioTracksInStreams(localStreams, false);
+ is(localAudioTracks, localConstraintAudioTracks, self + ' has ' +
+ localAudioTracks + ' local audio tracks');
+
+ var localConstraintVideoTracks =
+ self.countVideoTracksInMediaConstraint(self.constraints);
+ var localVideoTracks = self.countVideoTracksInStreams(localStreams, false);
+ is(localVideoTracks, localConstraintVideoTracks, self + ' has ' +
+ localVideoTracks + ' local video tracks');
+
+ var remoteConstraintAudioTracks =
+ self.countAudioTracksInMediaConstraint(constraintsRemote);
+ var remoteStreams = self._pc.getRemoteStreams();
+ var remoteAudioTracks = self.countAudioTracksInStreams(remoteStreams, false);
+ is(remoteAudioTracks, remoteConstraintAudioTracks, self + ' has ' +
+ remoteAudioTracks + ' remote audio tracks');
+
+ var remoteConstraintVideoTracks =
+ self.countVideoTracksInMediaConstraint(constraintsRemote);
+ var remoteVideoTracks = self.countVideoTracksInStreams(remoteStreams, false);
+ is(remoteVideoTracks, remoteConstraintVideoTracks, self + ' has ' +
+ remoteVideoTracks + ' remote video tracks');
- return new Promise(resolve => {
- this._pc.addEventListener('addstream', e => {
- outstandingCount -= this.countTracksInStreams(type, [e.stream]);
- if (outstandingCount <= 0) {
- resolve();
- }
- });
- });
- };
+ onSuccess();
+ }
+
+ // we have to do this check as the onaddstream never fires if the remote
+ // stream has no track at all!
+ var expectedRemoteTracks =
+ self.countAudioTracksInMediaConstraint(constraintsRemote) +
+ self.countVideoTracksInMediaConstraint(constraintsRemote);
+
+ // TODO: this whole counting of streams should be replaced with comparing
+ // media stream objects IDs and what we got in the SDP (bug 1089798)
+ function _compareReceivedAndExpectedTracks(constraintsRemote, onSuccess) {
+ var receivedRemoteTracks =
+ self.onAddStreamAudioCounter + self.onAddStreamVideoCounter;
- var checkTrackCounts = (side, streams, constraints) => {
- ['audio', 'video'].forEach(type => {
- var actual = this.countTracksInStreams(type, streams);
- var expected = this.countTracksInConstraint(type, constraints);
- is(actual, expected, this + ' has ' + actual + ' ' +
- side + ' ' + type + ' tracks');
- });
- };
+ if (receivedRemoteTracks === expectedRemoteTracks) {
+ _checkMediaTracks(constraintsRemote, onSuccess);
+ } else if (receivedRemoteTracks > expectedRemoteTracks) {
+ ok(false, "Received more streams " + receivedRemoteTracks +
+ " then expected " + expectedRemoteTracks);
+ _checkMediaTracks(constraintsRemote, onSuccess);
+ } else {
+ info("Still waiting for more remote streams to arrive (" +
+ receivedRemoteTracks + " vs " + expectedRemoteTracks + ")");
+ }
+ }
- info(this + " checkMediaTracks() got called before onAddStream fired");
- var checkPromise = Promise.all([
- waitForExpectedTracks('audio'),
- waitForExpectedTracks('video')
- ]).then(() => {
- checkTrackCounts('local', this._pc.getLocalStreams(), this.constraints);
- checkTrackCounts('remote', this._pc.getRemoteStreams(), remoteConstraints);
- });
- return timerGuard(checkPromise, 60000, "onaddstream never fired");
+ if (expectedRemoteTracks > (self.onAddStreamAudioCounter +
+ self.onAddStreamVideoCounter)) {
+ // This installs a callback handler for every time onaddstrem fires.
+ // We rely on the outer mochitest timeout to catch the case where
+ // onaddstream never fires
+ self.addStreamCallbacks.checkMediaTracks = function() {
+ _compareReceivedAndExpectedTracks(constraintsRemote, onSuccess);
+ };
+ }
+ _compareReceivedAndExpectedTracks(constraintsRemote, onSuccess);
+
},
- checkMsids: function() {
- var checkSdpForMsids = (desc, streams, side) => {
- streams.forEach(stream => {
- stream.getTracks().forEach(track => {
- // TODO(bug 1089798): Once DOMMediaStream has an id field, we
- // should be verifying that the SDP contains
- // a=msid:<stream-id> <track-id>
- ok(desc.sdp.match(new RegExp("a=msid:[^ ]+ " + track.id)),
- side + " SDP contains track id " + track.id );
- });
- });
- };
-
- checkSdpForMsids(this.localDescription, this._pc.getLocalStreams(),
- "local");
- checkSdpForMsids(this.remoteDescription, this._pc.getRemoteStreams(),
- "remote");
- },
-
- verifySdp: function(desc, expectedType, offerConstraintsList, offerOptions, isLocal) {
+ verifySdp : function PCW_verifySdp(desc, expectedType, offerConstraintsList,
+ offerOptions, trickleIceCallback) {
info("Examining this SessionDescription: " + JSON.stringify(desc));
info("offerConstraintsList: " + JSON.stringify(offerConstraintsList));
info("offerOptions: " + JSON.stringify(offerOptions));
ok(desc, "SessionDescription is not null");
is(desc.type, expectedType, "SessionDescription type is " + expectedType);
ok(desc.sdp.length > 10, "SessionDescription body length is plausible");
ok(desc.sdp.contains("a=ice-ufrag"), "ICE username is present in SDP");
ok(desc.sdp.contains("a=ice-pwd"), "ICE password is present in SDP");
ok(desc.sdp.contains("a=fingerprint"), "ICE fingerprint is present in SDP");
//TODO: update this for loopback support bug 1027350
ok(!desc.sdp.contains(LOOPBACK_ADDR), "loopback interface is absent from SDP");
- var requiresTrickleIce = !desc.sdp.contains("a=candidate");
- if (requiresTrickleIce) {
- info("at least one ICE candidate is present in SDP");
+ if (desc.sdp.contains("a=candidate")) {
+ ok(true, "at least one ICE candidate is present in SDP");
+ trickleIceCallback(false);
} else {
info("No ICE candidate in SDP -> requiring trickle ICE");
+ trickleIceCallback(true);
}
- if (isLocal) {
- this.localRequiresTrickleIce = requiresTrickleIce;
- } else {
- this.remoteRequiresTrickleIce = requiresTrickleIce;
- }
-
//TODO: how can we check for absence/presence of m=application?
var audioTracks =
- this.countTracksInConstraint('audio', offerConstraintsList) ||
+ this.countAudioTracksInMediaConstraint(offerConstraintsList) ||
this.audioInOfferOptions(offerOptions);
info("expected audio tracks: " + audioTracks);
if (audioTracks == 0) {
ok(!desc.sdp.contains("m=audio"), "audio m-line is absent from SDP");
} else {
ok(desc.sdp.contains("m=audio"), "audio m-line is present in SDP");
ok(desc.sdp.contains("a=rtpmap:109 opus/48000/2"), "OPUS codec is present in SDP");
//TODO: ideally the rtcp-mux should be for the m=audio, and not just
// anywhere in the SDP (JS SDP parser bug 1045429)
ok(desc.sdp.contains("a=rtcp-mux"), "RTCP Mux is offered in SDP");
+
}
var videoTracks =
- this.countTracksInConstraint('video', offerConstraintsList) ||
+ this.countVideoTracksInMediaConstraint(offerConstraintsList) ||
this.videoInOfferOptions(offerOptions);
info("expected video tracks: " + videoTracks);
if (videoTracks == 0) {
ok(!desc.sdp.contains("m=video"), "video m-line is absent from SDP");
} else {
ok(desc.sdp.contains("m=video"), "video m-line is present in SDP");
if (this.h264) {
@@ -1424,45 +2376,69 @@ PeerConnectionWrapper.prototype = {
ok(desc.sdp.contains("a=rtcp-mux"), "RTCP Mux is offered in SDP");
}
},
/**
* Check that media flow is present on all media elements involved in this
* test by waiting for confirmation that media flow is present.
+ *
+ * @param {Function} onSuccess the success callback when media flow
+ * is confirmed on all media elements
*/
- checkMediaFlowPresent : function() {
- return Promise.all(this.mediaCheckers.map(checker => checker.waitForMediaFlow()));
+ checkMediaFlowPresent : function PCW_checkMediaFlowPresent(onSuccess) {
+ var self = this;
+
+ function _checkMediaFlowPresent(index, onSuccess) {
+ if(index >= self.mediaCheckers.length) {
+ onSuccess();
+ } else {
+ var mediaChecker = self.mediaCheckers[index];
+ mediaChecker.waitForMediaFlow(function() {
+ _checkMediaFlowPresent(index + 1, onSuccess);
+ });
+ }
+ }
+
+ _checkMediaFlowPresent(0, onSuccess);
},
/**
* Check that stats are present by checking for known stats.
+ *
+ * @param {Function} onSuccess the success callback to return stats to
*/
- getStats : function(selector) {
- return this._pc.getStats(selector).then(stats => {
- info(this + ": Got stats: " + JSON.stringify(stats));
- this._last_stats = stats;
- return stats;
- });
+ getStats : function PCW_getStats(selector, onSuccess) {
+ var self = this;
+
+ this._pc.getStats(selector, function(stats) {
+ info(self + ": Got stats: " + JSON.stringify(stats));
+ self._last_stats = stats;
+ onSuccess(stats);
+ }, generateErrorCallback());
},
/**
* Checks that we are getting the media streams we expect.
*
* @param {object} stats
* The stats to check from this PeerConnectionWrapper
*/
- checkStats : function(stats, twoMachines) {
- var toNum = obj => obj? obj : 0;
- var numTracks = streams =>
- streams.reduce((count, stream) => count +
- stream.getAudioTracks().length +
- stream.getVideoTracks().length,
- 0);
+ checkStats : function PCW_checkStats(stats, twoMachines) {
+ function toNum(obj) {
+ return obj? obj : 0;
+ }
+ function numTracks(streams) {
+ var n = 0;
+ streams.forEach(function(stream) {
+ n += stream.getAudioTracks().length + stream.getVideoTracks().length;
+ });
+ return n;
+ }
const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
// Use spec way of enumerating stats
var counters = {};
for (var key in stats) {
if (stats.hasOwnProperty(key)) {
var res = stats[key];
@@ -1537,17 +2513,17 @@ PeerConnectionWrapper.prototype = {
break;
}
}
}
}
// Use MapClass way of enumerating stats
var counters2 = {};
- stats.forEach(res => {
+ stats.forEach(function(res) {
if (!res.isRemote) {
counters2[res.type] = toNum(counters2[res.type]) + 1;
}
});
is(JSON.stringify(counters), JSON.stringify(counters2),
"Spec and MapClass variant of RTCStatsReport enumeration agree");
var nin = numTracks(this._pc.getRemoteStreams());
var nout = numTracks(this._pc.getLocalStreams());
@@ -1573,20 +2549,21 @@ PeerConnectionWrapper.prototype = {
/**
* Compares the Ice server configured for this PeerConnectionWrapper
* with the ICE candidates received in the RTCP stats.
*
* @param {object} stats
* The stats to be verified for relayed vs. direct connection.
*/
- checkStatsIceConnectionType : function(stats) {
+ checkStatsIceConnectionType : function PCW_checkStatsIceConnectionType(stats)
+ {
var lId;
var rId;
- Object.keys(stats).forEach(name => {
+ Object.keys(stats).forEach(function(name) {
if ((stats[name].type === "candidatepair") &&
(stats[name].selected)) {
lId = stats[name].localCandidateId;
rId = stats[name].remoteCandidateId;
}
});
info("checkStatsIceConnectionType verifying: local=" +
JSON.stringify(stats[lId]) + " remote=" + JSON.stringify(stats[rId]));
@@ -1619,36 +2596,36 @@ PeerConnectionWrapper.prototype = {
*
* @param {object} stats
* The stats to check for ICE candidate pairs
* @param {object} counters
* The counters for media and data tracks based on constraints
* @param {object} answer
* The SDP answer to check for SDP bundle support
*/
- checkStatsIceConnections : function(stats,
+ checkStatsIceConnections : function PCW_checkStatsIceConnections(stats,
offerConstraintsList, offerOptions, answer) {
var numIceConnections = 0;
- Object.keys(stats).forEach(key => {
+ Object.keys(stats).forEach(function(key) {
if ((stats[key].type === "candidatepair") && stats[key].selected) {
numIceConnections += 1;
}
});
info("ICE connections according to stats: " + numIceConnections);
if (answer.sdp.contains('a=group:BUNDLE')) {
is(numIceConnections, 1, "stats reports exactly 1 ICE connection");
} else {
// This code assumes that no media sections have been rejected due to
// codec mismatch or other unrecoverable negotiation failures.
var numAudioTracks =
- this.countTracksInConstraint('audio', offerConstraintsList) ||
+ this.countAudioTracksInMediaConstraint(offerConstraintsList) ||
this.audioInOfferOptions(offerOptions);
var numVideoTracks =
- this.countTracksInConstraint('video', offerConstraintsList) ||
+ this.countVideoTracksInMediaConstraint(offerConstraintsList) ||
this.videoInOfferOptions(offerOptions);
var numDataTracks = this.dataChannels.length;
var numAudioVideoDataTracks = numAudioTracks + numVideoTracks + numDataTracks;
info("expected audio + video + data tracks: " + numAudioVideoDataTracks);
is(numAudioVideoDataTracks, numIceConnections, "stats ICE connections matches expected A/V tracks");
}
@@ -1658,17 +2635,17 @@ PeerConnectionWrapper.prototype = {
* Property-matching function for finding a certain stat in passed-in stats
*
* @param {object} stats
* The stats to check from this PeerConnectionWrapper
* @param {object} props
* The properties to look for
* @returns {boolean} Whether an entry containing all match-props was found.
*/
- hasStat : function(stats, props) {
+ hasStat : function PCW_hasStat(stats, props) {
for (var key in stats) {
if (stats.hasOwnProperty(key)) {
var res = stats[key];
var match = true;
for (var prop in props) {
if (res[prop] !== props[prop]) {
match = false;
break;
@@ -1680,53 +2657,39 @@ PeerConnectionWrapper.prototype = {
}
}
return false;
},
/**
* Closes the connection
*/
- close : function() {
+ close : function PCW_close() {
+ this._ice_candidates_to_add = [];
this._pc.close();
- this.localMediaElements.forEach(e => e.pause());
info(this + ": Closed connection.");
},
/**
+ * Register all events during the setup of the data channel
+ *
+ * @param {Function} onDataChannelOpened
+ * Callback to execute when the data channel has been opened
+ */
+ registerDataChannelOpenEvents : function (onDataChannelOpened) {
+ info(this + ": Register callback for 'ondatachannel'");
+
+ this.ondatachannel = function (targetChannel) {
+ this.dataChannels.push(targetChannel);
+ info(this + ": 'ondatachannel' fired, registering 'onopen' callback");
+ targetChannel.onopen = onDataChannelOpened;
+ };
+ },
+
+ /**
* Returns the string representation of the class
*
* @returns {String} The string representation
*/
- toString : function() {
+ toString : function PCW_toString() {
return "PeerConnectionWrapper (" + this.label + ")";
}
};
-
-// haxx to prevent SimpleTest from failing at window.onload
-function addLoadEvent() {}
-
-var scriptsReady = Promise.all([
- "/tests/SimpleTest/SimpleTest.js",
- "head.js",
- "templates.js",
- "turnConfig.js",
- "dataChannel.js",
- "network.js"
-].map(script => {
- var el = document.createElement("script");
- if (typeof scriptRelativePath === 'string' && script.charAt(0) !== '/') {
- script = scriptRelativePath + script;
- }
- el.src = script;
- document.head.appendChild(el);
- return new Promise(r => { el.onload = r; el.onerror = r; });
-}));
-
-function createHTML(options) {
- return scriptsReady.then(() => realCreateHTML(options));
-}
-
-function runNetworkTest(testFunction) {
- return scriptsReady
- .then(() => startNetworkAndTest())
- .then(() => runTestWhenReady(testFunction));
-}
--- a/dom/media/tests/mochitest/steeplechase.ini
+++ b/dom/media/tests/mochitest/steeplechase.ini
@@ -1,10 +1,9 @@
[DEFAULT]
support-files =
head.js
mediaStreamPlayback.js
- network.js
pc.js
templates.js
turnConfig.js
[test_peerConnection_basicAudio.html]
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -57,407 +57,668 @@ function dumpSdp(test) {
if ((test.pcLocal) && (test.pcRemote) &&
(typeof test.pcRemote.setLocalDescDate !== 'undefined') &&
(typeof test.pcRemote.setLocalDescStableEventDate !== 'undefined')) {
var delta = deltaSeconds(test.pcRemote.setLocalDescDate, test.pcRemote.setLocalDescStableEventDate);
dump("Delay between pcRemote.setLocal <-> pcRemote.signalingStateStable: " + delta + "\n");
}
}
-function waitForIceConnected(test, pc) {
- if (pc.isIceConnected()) {
- info(pc + ": ICE connection state log: " + pc.iceConnectionLog);
- ok(true, pc + ": ICE is in connected state");
- return Promise.resolve();
- }
-
- if (!pc.isIceConnectionPending()) {
- dumpSdp(test);
- var details = pc + ": ICE is already in bad state: " + pc.iceConnectionState;
- ok(false, details);
- return Promise.reject(new Error(details));
- }
-
- return pc.waitForIceConnected()
- .then(() => {
- info(pc + ": ICE connection state log: " + pc.iceConnectionLog);
- ok(pc.isIceConnected(), pc + ": ICE switched to 'connected' state");
- });
-}
-
-// We need to verify that at least one candidate has been (or will be) gathered.
-function waitForAnIceCandidate(pc) {
- return new Promise(resolve => {
- if (!pc.localRequiresTrickleIce ||
- pc._local_ice_candidates.length > 0) {
- resolve();
- } else {
- // In some circumstances, especially when both PCs are on the same
- // browser, even though we are connected, the connection can be
- // established without receiving a single candidate from one or other
- // peer. So we wait for at least one...
- pc._pc.addEventListener('icecandidate', resolve);
+var commandsPeerConnection = [
+ [
+ 'PC_SETUP_SIGNALING_CLIENT',
+ function (test) {
+ if (test.steeplechase) {
+ test.setTimeout(30000);
+ test.setupSignalingClient();
+ test.registerSignalingCallback("ice_candidate", function (message) {
+ var pc = test.pcRemote ? test.pcRemote : test.pcLocal;
+ pc.storeOrAddIceCandidate(new mozRTCIceCandidate(message.ice_candidate));
+ });
+ test.registerSignalingCallback("end_of_trickle_ice", function (message) {
+ test.signalingMessagesFinished();
+ });
+ }
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_SETUP_ICE_LOGGER',
+ function (test) {
+ test.pcLocal.logIceConnectionState();
+ test.next();
}
- }).then(() => {
- ok(pc._local_ice_candidates.length > 0,
- pc + " received local trickle ICE candidates");
- isnot(pc._pc.iceGatheringState, GATH_NEW,
- pc + " ICE gathering state is not 'new'");
- });
-}
-
-function checkTrackStats(pc, audio, outbound) {
- var stream = outbound ? pc._pc.getLocalStreams()[0] : pc._pc.getRemoteStreams()[0];
- if (!stream) {
- return Promise.resolve();
- }
- var track = audio ? stream.getAudioTracks()[0] : stream.getVideoTracks()[0];
- if (!track) {
- return Promise.resolve();
- }
- var msg = pc + " stats " + (outbound ? "outbound " : "inbound ") +
- (audio ? "audio" : "video") + " rtp ";
- return pc.getStats(track).then(stats => {
- ok(pc.hasStat(stats, {
- type: outbound ? "outboundrtp" : "inboundrtp",
- isRemote: false,
- mediaType: audio ? "audio" : "video"
- }), msg + "1");
- ok(!pc.hasStat(stats, {
- type: outbound ? "inboundrtp" : "outboundrtp",
- isRemote: false
- }), msg + "2");
- ok(!pc.hasStat(stats, {
- mediaType: audio ? "video" : "audio"
- }), msg + "3");
- });
-}
-
-// checks all stats combinations inbound/outbound, audio/video
-var checkAllTrackStats = pc =>
- Promise.all([0, 1, 2, 3].map(i => checkTrackStats(pc, i & 1, i & 2)));
-
-var commandsPeerConnection = [
- function PC_SETUP_SIGNALING_CLIENT(test) {
- if (test.steeplechase) {
- setTimeout(() => {
- ok(false, "PeerConnectionTest timed out");
- test.teardown();
- }, 30000);
- test.setupSignalingClient();
- test.registerSignalingCallback("ice_candidate", function (message) {
- var pc = test.pcRemote ? test.pcRemote : test.pcLocal;
- pc.storeOrAddIceCandidate(new mozRTCIceCandidate(message.ice_candidate));
+ ],
+ [
+ 'PC_REMOTE_SETUP_ICE_LOGGER',
+ function (test) {
+ test.pcRemote.logIceConnectionState();
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_SETUP_SIGNALING_LOGGER',
+ function (test) {
+ test.pcLocal.logSignalingState();
+ test.next();
+ }
+ ],
+ [
+ 'PC_REMOTE_SETUP_SIGNALING_LOGGER',
+ function (test) {
+ test.pcRemote.logSignalingState();
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_GUM',
+ function (test) {
+ test.pcLocal.getAllUserMedia(test.pcLocal.constraints, function () {
+ test.next();
});
- test.registerSignalingCallback("end_of_trickle_ice", function (message) {
- test.signalingMessagesFinished();
+ }
+ ],
+ [
+ 'PC_REMOTE_GUM',
+ function (test) {
+ test.pcRemote.getAllUserMedia(test.pcRemote.constraints, function () {
+ test.next();
});
}
- },
-
- function PC_LOCAL_SETUP_ICE_LOGGER(test) {
- test.pcLocal.logIceConnectionState();
- },
-
- function PC_REMOTE_SETUP_ICE_LOGGER(test) {
- test.pcRemote.logIceConnectionState();
- },
-
- function PC_LOCAL_SETUP_SIGNALING_LOGGER(test) {
- test.pcLocal.logSignalingState();
- },
-
- function PC_REMOTE_SETUP_SIGNALING_LOGGER(test) {
- test.pcRemote.logSignalingState();
- },
-
- function PC_LOCAL_GUM(test) {
- return test.pcLocal.getAllUserMedia(test.pcLocal.constraints);
- },
-
- function PC_REMOTE_GUM(test) {
- return test.pcRemote.getAllUserMedia(test.pcRemote.constraints);
- },
-
- function PC_LOCAL_CHECK_INITIAL_SIGNALINGSTATE(test) {
- is(test.pcLocal.signalingState, STABLE,
- "Initial local signalingState is 'stable'");
- },
-
- function PC_REMOTE_CHECK_INITIAL_SIGNALINGSTATE(test) {
- is(test.pcRemote.signalingState, STABLE,
- "Initial remote signalingState is 'stable'");
- },
-
- function PC_LOCAL_CHECK_INITIAL_ICE_STATE(test) {
- is(test.pcLocal.iceConnectionState, ICE_NEW,
- "Initial local ICE connection state is 'new'");
- },
-
- function PC_REMOTE_CHECK_INITIAL_ICE_STATE(test) {
- is(test.pcRemote.iceConnectionState, ICE_NEW,
- "Initial remote ICE connection state is 'new'");
- },
-
- function PC_LOCAL_SETUP_ICE_HANDLER(test) {
- test.pcLocal.setupIceCandidateHandler(test);
- if (test.steeplechase) {
- test.pcLocal.endOfTrickleIce.then(() => {
- send_message({"type": "end_of_trickle_ice"});
- });
+ ],
+ [
+ 'PC_LOCAL_CHECK_INITIAL_SIGNALINGSTATE',
+ function (test) {
+ is(test.pcLocal.signalingState, STABLE,
+ "Initial local signalingState is 'stable'");
+ test.next();
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_INITIAL_SIGNALINGSTATE',
+ function (test) {
+ is(test.pcRemote.signalingState, STABLE,
+ "Initial remote signalingState is 'stable'");
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_INITIAL_ICE_STATE',
+ function (test) {
+ is(test.pcLocal.iceConnectionState, ICE_NEW,
+ "Initial local ICE connection state is 'new'");
+ test.next();
}
- },
-
- function PC_REMOTE_SETUP_ICE_HANDLER(test) {
- test.pcRemote.setupIceCandidateHandler(test);
- if (test.steeplechase) {
- test.pcRemote.endOfTrickleIce.then(() => {
- send_message({"type": "end_of_trickle_ice"});
+ ],
+ [
+ 'PC_REMOTE_CHECK_INITIAL_ICE_STATE',
+ function (test) {
+ is(test.pcRemote.iceConnectionState, ICE_NEW,
+ "Initial remote ICE connection state is 'new'");
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_SETUP_ICE_HANDLER',
+ function (test) {
+ test.pcLocal.setupIceCandidateHandler(test);
+ test.next();
+ }
+ ],
+ [
+ 'PC_REMOTE_SETUP_ICE_HANDLER',
+ function (test) {
+ test.pcRemote.setupIceCandidateHandler(test);
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_CREATE_OFFER',
+ function (test) {
+ test.createOffer(test.pcLocal, function (offer) {
+ is(test.pcLocal.signalingState, STABLE,
+ "Local create offer does not change signaling state");
+ test.next();
});
}
- },
-
- function PC_LOCAL_CREATE_OFFER(test) {
- return test.createOffer(test.pcLocal).then(offer => {
- is(test.pcLocal.signalingState, STABLE,
- "Local create offer does not change signaling state");
- });
- },
-
- function PC_LOCAL_STEEPLECHASE_SIGNAL_OFFER(test) {
- if (test.steeplechase) {
- send_message({"type": "offer",
- "offer": test.originalOffer,
- "offer_constraints": test.pcLocal.constraints,
- "offer_options": test.pcLocal.offerOptions});
- test._local_offer = test.originalOffer;
- test._offer_constraints = test.pcLocal.constraints;
- test._offer_options = test.pcLocal.offerOptions;
+ ],
+ [
+ 'PC_LOCAL_STEEPLECHASE_SIGNAL_OFFER',
+ function (test) {
+ if (test.steeplechase) {
+ send_message({"type": "offer",
+ "offer": test.originalOffer,
+ "offer_constraints": test.pcLocal.constraints,
+ "offer_options": test.pcLocal.offerOptions});
+ test._local_offer = test.originalOffer;
+ test._offer_constraints = test.pcLocal.constraints;
+ test._offer_options = test.pcLocal.offerOptions;
+ }
+ test.next();
}
- },
-
- function PC_LOCAL_SET_LOCAL_DESCRIPTION(test) {
- return test.setLocalDescription(test.pcLocal, test.originalOffer, HAVE_LOCAL_OFFER)
- .then(() => {
+ ],
+ [
+ 'PC_LOCAL_SET_LOCAL_DESCRIPTION',
+ function (test) {
+ test.setLocalDescription(test.pcLocal, test.originalOffer, HAVE_LOCAL_OFFER, function () {
is(test.pcLocal.signalingState, HAVE_LOCAL_OFFER,
"signalingState after local setLocalDescription is 'have-local-offer'");
+ test.next();
});
- },
-
- function PC_REMOTE_GET_OFFER(test) {
- if (!test.steeplechase) {
- test._local_offer = test.originalOffer;
- test._offer_constraints = test.pcLocal.constraints;
- test._offer_options = test.pcLocal.offerOptions;
- return Promise.resolve();
}
- return test.getSignalingMessage("offer")
- .then(message => {
- ok("offer" in message, "Got an offer message");
- test._local_offer = new mozRTCSessionDescription(message.offer);
- test._offer_constraints = message.offer_constraints;
- test._offer_options = message.offer_options;
- });
- },
-
- function PC_REMOTE_SET_REMOTE_DESCRIPTION(test) {
- return test.setRemoteDescription(test.pcRemote, test._local_offer, HAVE_REMOTE_OFFER)
- .then(() => {
+ ],
+ [
+ 'PC_REMOTE_GET_OFFER',
+ function (test) {
+ if (!test.steeplechase) {
+ test._local_offer = test.originalOffer;
+ test._offer_constraints = test.pcLocal.constraints;
+ test._offer_options = test.pcLocal.offerOptions;
+ test.next();
+ } else {
+ test.getSignalingMessage("offer", function (message) {
+ ok("offer" in message, "Got an offer message");
+ test._local_offer = new mozRTCSessionDescription(message.offer);
+ test._offer_constraints = message.offer_constraints;
+ test._offer_options = message.offer_options;
+ test.next();
+ });
+ }
+ }
+ ],
+ [
+ 'PC_REMOTE_SET_REMOTE_DESCRIPTION',
+ function (test) {
+ test.setRemoteDescription(test.pcRemote, test._local_offer, HAVE_REMOTE_OFFER, function () {
is(test.pcRemote.signalingState, HAVE_REMOTE_OFFER,
"signalingState after remote setRemoteDescription is 'have-remote-offer'");
+ test.next();
});
- },
-
- function PC_LOCAL_SANE_LOCAL_SDP(test) {
- test.pcLocal.verifySdp(test._local_offer, "offer",
- test._offer_constraints, test._offer_options,
- true);
- },
-
- function PC_REMOTE_SANE_REMOTE_SDP(test) {
- test.pcRemote.verifySdp(test._local_offer, "offer",
- test._offer_constraints, test._offer_options,
- false);
- },
-
- function PC_REMOTE_CREATE_ANSWER(test) {
- return test.createAnswer(test.pcRemote)
- .then(answer => {
+ }
+ ],
+ [
+ 'PC_LOCAL_SANE_LOCAL_SDP',
+ function (test) {
+ test.pcLocal.verifySdp(test._local_offer, "offer",
+ test._offer_constraints, test._offer_options,
+ function(trickle) {
+ test.pcLocal.localRequiresTrickleIce = trickle;
+ });
+ test.next();
+ }
+ ],
+ [
+ 'PC_REMOTE_SANE_REMOTE_SDP',
+ function (test) {
+ test.pcRemote.verifySdp(test._local_offer, "offer",
+ test._offer_constraints, test._offer_options,
+ function (trickle) {
+ test.pcRemote.remoteRequiresTrickleIce = trickle;
+ });
+ test.next();
+ }
+ ],
+ [
+ 'PC_REMOTE_CREATE_ANSWER',
+ function (test) {
+ test.createAnswer(test.pcRemote, function (answer) {
is(test.pcRemote.signalingState, HAVE_REMOTE_OFFER,
"Remote createAnswer does not change signaling state");
if (test.steeplechase) {
send_message({"type": "answer",
"answer": test.originalAnswer,
"answer_constraints": test.pcRemote.constraints});
test._remote_answer = test.pcRemote._last_answer;
test._answer_constraints = test.pcRemote.constraints;
}
+ test.next();
});
- },
-
- function PC_REMOTE_CHECK_FOR_DUPLICATED_PORTS_IN_SDP(test) {
- var re = /a=candidate.* (UDP|TCP) [\d]+ ([\d\.]+) ([\d]+) typ host/g;
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_FOR_DUPLICATED_PORTS_IN_SDP',
+ function (test) {
+ var re = /a=candidate.* (UDP|TCP) [\d]+ ([\d\.]+) ([\d]+) typ host/g;
- var _sdpCandidatesIntoArray = sdp => {
- var regexArray = [];
- var resultArray = [];
- while ((regexArray = re.exec(sdp)) !== null) {
- info("regexArray: " + regexArray);
- if ((regexArray[1] === "TCP") && (regexArray[3] === "9")) {
- // As both sides can advertise TCP active connection on port 9 lets
- // ignore them all together
- info("Ignoring TCP candidate on port 9");
- continue;
+ function _sdpCandidatesIntoArray(sdp) {
+ var regexArray = [];
+ var resultArray = [];
+ while ((regexArray = re.exec(sdp)) !== null) {
+ info("regexArray: " + regexArray);
+ if ((regexArray[1] === "TCP") && (regexArray[3] === "9")) {
+ // As both sides can advertise TCP active connection on port 9 lets
+ // ignore them all together
+ info("Ignoring TCP candidate on port 9");
+ continue;
+ }
+ const triple = regexArray[1] + ":" + regexArray[2] + ":" + regexArray[3];
+ info("triple: " + triple);
+ if (resultArray.indexOf(triple) !== -1) {
+ dump("SDP: " + sdp.replace(/[\r]/g, '') + "\n");
+ ok(false, "This Transport:IP:Port " + triple + " appears twice in the SDP above!");
+ }
+ resultArray.push(triple);
}
- var triple = regexArray[1] + ":" + regexArray[2] + ":" + regexArray[3];
- info("triple: " + triple);
- if (resultArray.indexOf(triple) !== -1) {
- dump("SDP: " + sdp.replace(/[\r]/g, '') + "\n");
- ok(false, "This Transport:IP:Port " + triple + " appears twice in the SDP above!");
+ return resultArray;
+ }
+
+ const offerTriples = _sdpCandidatesIntoArray(test._local_offer.sdp);
+ info("Offer ICE host candidates: " + JSON.stringify(offerTriples));
+
+ const answerTriples = _sdpCandidatesIntoArray(test.originalAnswer.sdp);
+ info("Answer ICE host candidates: " + JSON.stringify(answerTriples));
+
+ for (var i=0; i< offerTriples.length; i++) {
+ if (answerTriples.indexOf(offerTriples[i]) !== -1) {
+ dump("SDP offer: " + test._local_offer.sdp.replace(/[\r]/g, '') + "\n");
+ dump("SDP answer: " + test.originalAnswer.sdp.replace(/[\r]/g, '') + "\n");
+ ok(false, "This IP:Port " + offerTriples[i] + " appears in SDP offer and answer!");
}
- resultArray.push(triple);
}
- return resultArray;
- };
- var offerTriples = _sdpCandidatesIntoArray(test._local_offer.sdp);
- info("Offer ICE host candidates: " + JSON.stringify(offerTriples));
-
- var answerTriples = _sdpCandidatesIntoArray(test.originalAnswer.sdp);
- info("Answer ICE host candidates: " + JSON.stringify(answerTriples));
-
- offerTriples.forEach(o => {
- if (answerTriples.indexOf(o) !== -1) {
- dump("SDP offer: " + test._local_offer.sdp.replace(/[\r]/g, '') + "\n");
- dump("SDP answer: " + test.originalAnswer.sdp.replace(/[\r]/g, '') + "\n");
- ok(false, "This IP:Port " + o + " appears in SDP offer and answer!");
+ test.next();
+ }
+ ],
+ [
+ 'PC_REMOTE_SET_LOCAL_DESCRIPTION',
+ function (test) {
+ test.setLocalDescription(test.pcRemote, test.originalAnswer, STABLE,
+ function () {
+ is(test.pcRemote.signalingState, STABLE,
+ "signalingState after remote setLocalDescription is 'stable'");
+ test.next();
+ }
+ );
+ }
+ ],
+ [
+ 'PC_LOCAL_GET_ANSWER',
+ function (test) {
+ if (!test.steeplechase) {
+ test._remote_answer = test.originalAnswer;
+ test._answer_constraints = test.pcRemote.constraints;
+ test.next();
+ } else {
+ test.getSignalingMessage("answer", function (message) {
+ ok("answer" in message, "Got an answer message");
+ test._remote_answer = new mozRTCSessionDescription(message.answer);
+ test._answer_constraints = message.answer_constraints;
+ test.next();
+ });
}
- });
- },
-
- function PC_REMOTE_SET_LOCAL_DESCRIPTION(test) {
- return test.setLocalDescription(test.pcRemote, test.originalAnswer, STABLE)
- .then(() => {
- is(test.pcRemote.signalingState, STABLE,
- "signalingState after remote setLocalDescription is 'stable'");
- });
- },
-
- function PC_LOCAL_GET_ANSWER(test) {
- if (!test.steeplechase) {
- test._remote_answer = test.originalAnswer;
- test._answer_constraints = test.pcRemote.constraints;
- return Promise.resolve();
+ }
+ ],
+ [
+ 'PC_LOCAL_SET_REMOTE_DESCRIPTION',
+ function (test) {
+ test.setRemoteDescription(test.pcLocal, test._remote_answer, STABLE,
+ function () {
+ is(test.pcLocal.signalingState, STABLE,
+ "signalingState after local setRemoteDescription is 'stable'");
+ test.next();
+ }
+ );
}
+ ],
+ [
+ 'PC_REMOTE_SANE_LOCAL_SDP',
+ function (test) {
+ test.pcRemote.verifySdp(test._remote_answer, "answer",
+ test._offer_constraints, test._offer_options,
+ function (trickle) {
+ test.pcRemote.localRequiresTrickleIce = trickle;
+ });
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_SANE_REMOTE_SDP',
+ function (test) {
+ test.pcLocal.verifySdp(test._remote_answer, "answer",
+ test._offer_constraints, test._offer_options,
+ function (trickle) {
+ test.pcLocal.remoteRequiresTrickleIce = trickle;
+ });
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_WAIT_FOR_ICE_CONNECTED',
+ function (test) {
+ var myTest = test;
+ var myPc = myTest.pcLocal;
- return test.getSignalingMessage("answer").then(message => {
- ok("answer" in message, "Got an answer message");
- test._remote_answer = new mozRTCSessionDescription(message.answer);
- test._answer_constraints = message.answer_constraints;
- });
- },
+ function onIceConnectedSuccess () {
+ info("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog);
+ ok(true, "pc_local: ICE switched to 'connected' state");
+ myTest.next();
+ };
+ function onIceConnectedFailed () {
+ dumpSdp(myTest);
+ ok(false, "pc_local: ICE failed to switch to 'connected' state: " + myPc.iceConnectionState);
+ myTest.next();
+ };
- function PC_LOCAL_SET_REMOTE_DESCRIPTION(test) {
- test.setRemoteDescription(test.pcLocal, test._remote_answer, STABLE)
- .then(() => {
- is(test.pcLocal.signalingState, STABLE,
- "signalingState after local setRemoteDescription is 'stable'");
- });
- },
- function PC_REMOTE_SANE_LOCAL_SDP(test) {
- test.pcRemote.verifySdp(test._remote_answer, "answer",
- test._offer_constraints, test._offer_options,
- true);
- },
- function PC_LOCAL_SANE_REMOTE_SDP(test) {
- test.pcLocal.verifySdp(test._remote_answer, "answer",
- test._offer_constraints, test._offer_options,
- false);
- },
+ if (myPc.isIceConnected()) {
+ info("pcLocal ICE connection state log: " + test.pcLocal.iceConnectionLog);
+ ok(true, "pc_local: ICE is in connected state");
+ myTest.next();
+ } else if (myPc.isIceConnectionPending()) {
+ myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed);
+ } else {
+ dumpSdp(myTest);
+ ok(false, "pc_local: ICE is already in bad state: " + myPc.iceConnectionState);
+ myTest.next();
+ }
+ }
+ ],
+ [
+ 'PC_LOCAL_VERIFY_ICE_GATHERING',
+ function (test) {
+ if (test.pcLocal.localRequiresTrickleIce) {
+ ok(test.pcLocal._local_ice_candidates.length > 0, "Received local trickle ICE candidates");
+ }
+ isnot(test.pcLocal._pc.iceGatheringState, GATH_NEW, "ICE gathering state is not 'new'");
+ test.next();
+ }
+ ],
+ [
+ 'PC_REMOTE_WAIT_FOR_ICE_CONNECTED',
+ function (test) {
+ var myTest = test;
+ var myPc = myTest.pcRemote;
+
+ function onIceConnectedSuccess () {
+ info("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog);
+ ok(true, "pc_remote: ICE switched to 'connected' state");
+ myTest.next();
+ };
+ function onIceConnectedFailed () {
+ dumpSdp(myTest);
+ ok(false, "pc_remote: ICE failed to switch to 'connected' state: " + myPc.iceConnectionState);
+ myTest.next();
+ };
- function PC_LOCAL_WAIT_FOR_ICE_CONNECTED(test) {
- return waitForIceConnected(test, test.pcLocal);
- },
-
- function PC_REMOTE_WAIT_FOR_ICE_CONNECTED(test) {
- return waitForIceConnected(test, test.pcRemote);
- },
-
- function PC_LOCAL_VERIFY_ICE_GATHERING(test) {
- return waitForAnIceCandidate(test.pcLocal);
- },
-
- function PC_REMOTE_VERIFY_ICE_GATHERING(test) {
- return waitForAnIceCandidate(test.pcRemote);
- },
-
- function PC_LOCAL_CHECK_MEDIA_TRACKS(test) {
- return test.pcLocal.checkMediaTracks(test._answer_constraints);
- },
-
- function PC_REMOTE_CHECK_MEDIA_TRACKS(test) {
- return test.pcRemote.checkMediaTracks(test._offer_constraints);
- },
-
- function PC_LOCAL_CHECK_MEDIA_FLOW_PRESENT(test) {
- return test.pcLocal.checkMediaFlowPresent();
- },
+ if (myPc.isIceConnected()) {
+ info("pcRemote ICE connection state log: " + test.pcRemote.iceConnectionLog);
+ ok(true, "pc_remote: ICE is in connected state");
+ myTest.next();
+ } else if (myPc.isIceConnectionPending()) {
+ myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed);
+ } else {
+ dumpSdp(myTest);
+ ok(false, "pc_remote: ICE is already in bad state: " + myPc.iceConnectionState);
+ myTest.next();
+ }
+ }
+ ],
+ [
+ 'PC_REMOTE_VERIFY_ICE_GATHERING',
+ function (test) {
+ if (test.pcRemote.localRequiresTrickleIce) {
+ ok(test.pcRemote._local_ice_candidates.length > 0, "Received local trickle ICE candidates");
+ }
+ isnot(test.pcRemote._pc.iceGatheringState, GATH_NEW, "ICE gathering state is not 'new'");
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_MEDIA_TRACKS',
+ function (test) {
+ test.pcLocal.checkMediaTracks(test._answer_constraints, function () {
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_MEDIA_TRACKS',
+ function (test) {
+ test.pcRemote.checkMediaTracks(test._offer_constraints, function () {
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_MEDIA_FLOW_PRESENT',
+ function (test) {
+ test.pcLocal.checkMediaFlowPresent(function () {
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT',
+ function (test) {
+ test.pcRemote.checkMediaFlowPresent(function () {
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_STATS',
+ function (test) {
+ test.pcLocal.getStats(null, function(stats) {
+ test.pcLocal.checkStats(stats, test.steeplechase);
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_STATS',
+ function (test) {
+ test.pcRemote.getStats(null, function(stats) {
+ test.pcRemote.checkStats(stats, test.steeplechase);
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_ICE_CONNECTION_TYPE',
+ function (test) {
+ test.pcLocal.getStats(null, function(stats) {
+ test.pcLocal.checkStatsIceConnectionType(stats);
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_ICE_CONNECTION_TYPE',
+ function (test) {
+ test.pcRemote.getStats(null, function(stats) {
+ test.pcRemote.checkStatsIceConnectionType(stats);
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_ICE_CONNECTIONS',
+ function (test) {
+ test.pcLocal.getStats(null, function(stats) {
+ test.pcLocal.checkStatsIceConnections(stats,
+ test._offer_constraints,
+ test._offer_options,
+ test._remote_answer);
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_ICE_CONNECTIONS',
+ function (test) {
+ test.pcRemote.getStats(null, function(stats) {
+ test.pcRemote.checkStatsIceConnections(stats,
+ test._offer_constraints,
+ test._offer_options,
+ test.originalAnswer);
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_GETSTATS_AUDIOTRACK_OUTBOUND',
+ function (test) {
+ var pc = test.pcLocal;
+ var stream = pc._pc.getLocalStreams()[0];
+ var track = stream && stream.getAudioTracks()[0];
+ if (track) {
+ var msg = "pcLocal.HasStat outbound audio rtp ";
+ pc.getStats(track, function(stats) {
+ ok(pc.hasStat(stats,
+ { type:"outboundrtp", isRemote:false, mediaType:"audio" }),
+ msg + "1");
+ ok(!pc.hasStat(stats, { type:"inboundrtp", isRemote:false }), msg + "2");
+ ok(!pc.hasStat(stats, { mediaType:"video" }), msg + "3");
+ test.next();
+ });
+ } else {
+ test.next();
+ }
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_GETSTATS_VIDEOTRACK_OUTBOUND',
+ function (test) {
+ var pc = test.pcLocal;
+ var stream = pc._pc.getLocalStreams()[0];
+ var track = stream && stream.getVideoTracks()[0];
+ if (track) {
+ var msg = "pcLocal.HasStat outbound video rtp ";
+ pc.getStats(track, function(stats) {
+ ok(pc.hasStat(stats,
+ { type:"outboundrtp", isRemote:false, mediaType:"video" }),
+ msg + "1");
+ ok(!pc.hasStat(stats, { type:"inboundrtp", isRemote:false }), msg + "2");
+ ok(!pc.hasStat(stats, { mediaType:"audio" }), msg + "3");
+ test.next();
+ });
+ } else {
+ test.next();
+ }
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_GETSTATS_AUDIOTRACK_INBOUND',
+ function (test) {
+ var pc = test.pcLocal;
+ var stream = pc._pc.getRemoteStreams()[0];
+ var track = stream && stream.getAudioTracks()[0];
+ if (track) {
+ var msg = "pcLocal.HasStat inbound audio rtp ";
+ pc.getStats(track, function(stats) {
+ ok(pc.hasStat(stats,
+ { type:"inboundrtp", isRemote:false, mediaType:"audio" }),
+ msg + "1");
+ ok(!pc.hasStat(stats, { type:"outboundrtp", isRemote:false }), msg + "2");
+ ok(!pc.hasStat(stats, { mediaType:"video" }), msg + "3");
+ test.next();
+ });
+ } else {
+ test.next();
+ }
+ }
+ ],
+ [
+ 'PC_LOCAL_CHECK_GETSTATS_VIDEOTRACK_INBOUND',
+ function (test) {
+ var pc = test.pcLocal;
+ var stream = pc._pc.getRemoteStreams()[0];
+ var track = stream && stream.getVideoTracks()[0];
+ if (track) {
+ var msg = "pcLocal.HasStat inbound video rtp ";
+ pc.getStats(track, function(stats) {
+ ok(pc.hasStat(stats,
+ { type:"inboundrtp", isRemote:false, mediaType:"video" }),
+ msg + "1");
+ ok(!pc.hasStat(stats, { type:"outboundrtp", isRemote:false }), msg + "2");
+ ok(!pc.hasStat(stats, { mediaType:"audio" }), msg + "3");
+ test.next();
+ });
+ } else {
+ test.next();
+ }
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_GETSTATS_AUDIOTRACK_OUTBOUND',
+ function (test) {
+ var pc = test.pcRemote;
+ var stream = pc._pc.getLocalStreams()[0];
+ var track = stream && stream.getAudioTracks()[0];
+ if (track) {
+ var msg = "pcRemote.HasStat outbound audio rtp ";
+ pc.getStats(track, function(stats) {
+ ok(pc.hasStat(stats,
+ { type:"outboundrtp", isRemote:false, mediaType:"audio" }),
+ msg + "1");
+ ok(!pc.hasStat(stats, { type:"inboundrtp", isRemote:false }), msg + "2");
+ ok(!pc.hasStat(stats, { mediaType:"video" }), msg + "3");
+ test.next();
+ });
+ } else {
+ test.next();
+ }
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_GETSTATS_VIDEOTRACK_OUTBOUND',
+ function (test) {
+ var pc = test.pcRemote;
+ var stream = pc._pc.getLocalStreams()[0];
+ var track = stream && stream.getVideoTracks()[0];
+ if (track) {
+ var msg = "pcRemote.HasStat outbound audio rtp ";
+ pc.getStats(track, function(stats) {
+ ok(pc.hasStat(stats,
+ { type:"outboundrtp", isRemote:false, mediaType:"video" }),
+ msg + "1");
+ ok(!pc.hasStat(stats, { type:"inboundrtp", isRemote:false }), msg + "2");
+ ok(!pc.hasStat(stats, { mediaType:"audio" }), msg + "3");
+ test.next();
+ });
+ } else {
+ test.next();
+ }
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_GETSTATS_AUDIOTRACK_INBOUND',
+ function (test) {
+ var pc = test.pcRemote;
+ var stream = pc._pc.getRemoteStreams()[0];
+ var track = stream && stream.getAudioTracks()[0];
+ if (track) {
+ var msg = "pcRemote.HasStat inbound audio rtp ";
+ pc.getStats(track, function(stats) {
+ ok(pc.hasStat(stats,
+ { type:"inboundrtp", isRemote:false, mediaType:"audio" }),
+ msg + "1");
+ ok(!pc.hasStat(stats, { type:"outboundrtp", isRemote:false }), msg + "2");
+ ok(!pc.hasStat(stats, { mediaType:"video" }), msg + "3");
+ test.next();
+ });
+ } else {
+ test.next();
+ }
+ }
+ ],
+ [
+ 'PC_REMOTE_CHECK_GETSTATS_VIDEOTRACK_INBOUND',
+ function (test) {
+ var pc = test.pcRemote;
+ var stream = pc._pc.getRemoteStreams()[0];
+ var track = stream && stream.getVideoTracks()[0];
+ if (track) {
+ var msg = "pcRemote.HasStat inbound video rtp ";
+ pc.getStats(track, function(stats) {
+ ok(pc.hasStat(stats,
+ { type:"inboundrtp", isRemote:false, mediaType:"video" }),
+ msg + "1");
+ ok(!pc.hasStat(stats, { type:"outboundrtp", isRemote:false }), msg + "2");
+ ok(!pc.hasStat(stats, { mediaType:"audio" }), msg + "3");
+ test.next();
+ });
+ } else {
+ test.next();
+ }
+ }
+ ]
+];
- function PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT(test) {
- return test.pcRemote.checkMediaFlowPresent();
- },
-/* TODO: re-enable when Bug 1095218 lands
- function PC_LOCAL_CHECK_MSID(test) {
- test.pcLocal.checkMsids();
- },
- function PC_REMOTE_CHECK_MSID(test) {
- test.pcRemote.checkMsids();
- },
-*/
- function PC_LOCAL_CHECK_STATS(test) {
- return test.pcLocal.getStats(null).then(stats => {
- test.pcLocal.checkStats(stats, test.steeplechase);
- });
- },
-
- function PC_REMOTE_CHECK_STATS(test) {
- test.pcRemote.getStats(null).then(stats => {
- test.pcRemote.checkStats(stats, test.steeplechase);
- });
- },
-
- function PC_LOCAL_CHECK_ICE_CONNECTION_TYPE(test) {
- test.pcLocal.getStats(null).then(stats => {
- test.pcLocal.checkStatsIceConnectionType(stats);
- });
- },
-
- function PC_REMOTE_CHECK_ICE_CONNECTION_TYPE(test) {
- test.pcRemote.getStats(null).then(stats => {
- test.pcRemote.checkStatsIceConnectionType(stats);
- });
- },
-
- function PC_LOCAL_CHECK_ICE_CONNECTIONS(test) {
- test.pcLocal.getStats(null).then(stats => {
- test.pcLocal.checkStatsIceConnections(stats,
- test._offer_constraints,
- test._offer_options,
- test._remote_answer);
- });
- },
-
- function PC_REMOTE_CHECK_ICE_CONNECTIONS(test) {
- test.pcRemote.getStats(null).then(stats => {
- test.pcRemote.checkStatsIceConnections(stats,
- test._offer_constraints,
- test._offer_options,
- test.originalAnswer);
- });
- },
-
- function PC_LOCAL_CHECK_STATS(test) {
- return checkAllTrackStats(test.pcLocal);
- },
- function PC_REMOTE_CHECK_STATS(test) {
- return checkAllTrackStats(test.pcRemote);
- }
-];
--- a/dom/media/tests/mochitest/test_dataChannel_basicAudio.html
+++ b/dom/media/tests/mochitest/test_dataChannel_basicAudio.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="dataChannel.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796895",
title: "Basic data channel audio connection"
});
--- a/dom/media/tests/mochitest/test_dataChannel_basicAudioVideo.html
+++ b/dom/media/tests/mochitest/test_dataChannel_basicAudioVideo.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="dataChannel.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796891",
title: "Basic data channel audio/video connection"
});
--- a/dom/media/tests/mochitest/test_dataChannel_basicAudioVideoCombined.html
+++ b/dom/media/tests/mochitest/test_dataChannel_basicAudioVideoCombined.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="dataChannel.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796891",
title: "Basic data channel audio/video connection"
});
--- a/dom/media/tests/mochitest/test_dataChannel_basicAudioVideoNoBundle.html
+++ b/dom/media/tests/mochitest/test_dataChannel_basicAudioVideoNoBundle.html
@@ -1,33 +1,44 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="dataChannel.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1016476",
title: "Basic data channel audio/video connection without bundle"
});
-var test;
-runNetworkTest(function () {
- test = new PeerConnectionTest();
- addInitialDataChannel(test.chain);
- test.chain.insertAfter("PC_LOCAL_CREATE_OFFER", [
- function PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER(test) {
- // Just replace a=group:BUNDLE with something that will be ignored.
- test.originalOffer.sdp = test.originalOffer.sdp.replace(
- "a=group:BUNDLE",
- "a=foo:");
- }
- ]);
- test.setMediaConstraints([{audio: true}, {video: true}],
- [{audio: true}, {video: true}]);
- test.run();
-});
+ var test;
+ runNetworkTest(function () {
+ test = new PeerConnectionTest();
+ addInitialDataChannel(test.chain);
+ test.chain.insertAfter("PC_LOCAL_CREATE_OFFER",
+ [[
+ 'PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER',
+ function (test) {
+ // Just replace a=group:BUNDLE with something that will be ignored.
+ test.originalOffer.sdp = test.originalOffer.sdp.replace(
+ "a=group:BUNDLE",
+ "a=foo:");
+ test.next();
+ }
+ ]]
+ );
+ test.setMediaConstraints([{audio: true}, {video: true}],
+ [{audio: true}, {video: true}]);
+ test.run();
+ });
+
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_dataChannel_basicDataOnly.html
+++ b/dom/media/tests/mochitest/test_dataChannel_basicDataOnly.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="dataChannel.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796894",
title: "Basic datachannel only connection"
});
--- a/dom/media/tests/mochitest/test_dataChannel_basicVideo.html
+++ b/dom/media/tests/mochitest/test_dataChannel_basicVideo.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="dataChannel.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796889",
title: "Basic data channel video connection"
});
--- a/dom/media/tests/mochitest/test_dataChannel_bug1013809.html
+++ b/dom/media/tests/mochitest/test_dataChannel_bug1013809.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="dataChannel.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796895",
title: "Basic data channel audio connection"
});
--- a/dom/media/tests/mochitest/test_dataChannel_noOffer.html
+++ b/dom/media/tests/mochitest/test_dataChannel_noOffer.html
@@ -1,11 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "856319",
title: "Don't offer m=application unless createDataChannel is called first"
--- a/dom/media/tests/mochitest/test_getUserMedia_basicAudio.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicAudio.html
@@ -1,29 +1,46 @@
<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=781534
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Basic Audio Test</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=781534">mozGetUserMedia Basic Audio Test</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <audio id="testAudio"></audio>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({ title: "getUserMedia Basic Audio Test", bug: "781534" });
/**
* Run a test to verify that we can complete a start and stop media playback
* cycle for an audio LocalMediaStream on an audio HTMLMediaElement.
*/
runTest(function () {
- var testAudio = createMediaElement('audio', 'testAudio');
+ var testAudio = document.getElementById('testAudio');
var constraints = {audio: true};
- getUserMedia(constraints).then(aStream => {
+ getUserMedia(constraints, function (aStream) {
checkMediaStreamTracks(constraints, aStream);
var playback = new LocalMediaStreamPlayback(testAudio, aStream);
- return playback.playMedia(false);
- }).then(() => SimpleTest.finish(), generateErrorCallback());
+ playback.playMedia(false, function () {
+ aStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
+
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
@@ -1,45 +1,58 @@
<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=983504
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Basic Screenshare Test</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=983504">mozGetUserMedia Basic Screenshare Test</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({
- title: "getUserMedia Basic Screenshare Test",
- bug: "983504"
- });
/**
* Run a test to verify that we can complete a start and stop media playback
* cycle for an screenshare LocalMediaStream on a video HTMLMediaElement.
*/
runTest(function () {
const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
if (IsMacOSX10_6orOlder() || isWinXP) {
ok(true, "Screensharing disabled for OSX10.6 and WinXP");
SimpleTest.finish();
return;
}
- var testVideo = createMediaElement('video', 'testVideo');
+ var testVideo = document.getElementById('testVideo');
var constraints = {
video: {
mozMediaSource: "screen",
mediaSource: "screen"
},
fake: false
};
- getUserMedia(constraints).then(aStream => {
+ getUserMedia(constraints, function (aStream) {
checkMediaStreamTracks(constraints, aStream);
var playback = new LocalMediaStreamPlayback(testVideo, aStream);
- return playback.playMediaWithStreamStop(false);
- }).then(() => SimpleTest.finish(), generateErrorCallback());
+ playback.playMediaWithStreamStop(false, function () {
+ aStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_basicVideo.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicVideo.html
@@ -1,32 +1,46 @@
<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=781534
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Basic Video Test</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=781534">mozGetUserMedia Basic Video Test</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({
- title: "getUserMedia Basic Video Test",
- bug: "781534"
- });
/**
* Run a test to verify that we can complete a start and stop media playback
* cycle for an video LocalMediaStream on a video HTMLMediaElement.
*/
runTest(function () {
- var testVideo = createMediaElement('video', 'testVideo');
+ var testVideo = document.getElementById('testVideo');
var constraints = {video: true};
- getUserMedia(constraints).then(aStream => {
+ getUserMedia(constraints, function (aStream) {
checkMediaStreamTracks(constraints, aStream);
var playback = new LocalMediaStreamPlayback(testVideo, aStream);
- return playback.playMedia(false);
- }).then(() => SimpleTest.finish(), generateErrorCallback());
+ playback.playMedia(false, function () {
+ aStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
+
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_basicVideoAudio.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicVideoAudio.html
@@ -1,32 +1,45 @@
<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=781534
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Basic Video & Audio Test</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=781534">mozGetUserMedia Basic Video & Audio Test</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideoAudio"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({
- title: "getUserMedia Basic Video & Audio Test",
- bug: "781534"
- });
/**
* Run a test to verify that we can complete a start and stop media playback
* cycle for a video and audio LocalMediaStream on a video HTMLMediaElement.
*/
runTest(function () {
- var testVideoAudio = createMediaElement('video', 'testVideoAudio');
+ var testVideoAudio = document.getElementById('testVideoAudio');
var constraints = {video: true, audio: true};
- getUserMedia(constraints).then(aStream => {
+ getUserMedia(constraints, function (aStream) {
checkMediaStreamTracks(constraints, aStream);
var playback = new LocalMediaStreamPlayback(testVideoAudio, aStream);
- return playback.playMedia(false);
- }).then(() => SimpleTest.finish(), generateErrorCallback());
+ playback.playMedia(false, function () {
+ aStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_basicWindowshare.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicWindowshare.html
@@ -1,45 +1,58 @@
<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=983504
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Basic Windowshare Test</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1038926">mozGetUserMedia Basic Windowshare Test</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({
- title: "getUserMedia Basic Windowshare Test",
- bug: "1038926"
- });
/**
* Run a test to verify that we can complete a start and stop media playback
* cycle for an screenshare LocalMediaStream on a video HTMLMediaElement.
*/
runTest(function () {
const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
if (IsMacOSX10_6orOlder() || isWinXP) {
ok(true, "Screensharing disabled for OSX10.6 and WinXP");
SimpleTest.finish();
return;
}
- var testVideo = createMediaElement('video', 'testVideo');
+ var testVideo = document.getElementById('testVideo');
var constraints = {
video: {
mozMediaSource: "window",
mediaSource: "window"
},
fake: false
};
- getUserMedia(constraints).then(aStream => {
+ getUserMedia(constraints, function (aStream) {
checkMediaStreamTracks(constraints, aStream);
var playback = new LocalMediaStreamPlayback(testVideo, aStream);
- return playback.playMediaWithStreamStop(false);
- }).then(() => SimpleTest.finish(), generateErrorCallback());
+ playback.playMediaWithStreamStop(false, function () {
+ aStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
deleted file mode 100644
--- a/dom/media/tests/mochitest/test_getUserMedia_callbacks.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <script type="application/javascript" src="mediaStreamPlayback.js"></script>
-</head>
-<body>
-<pre id="test">
-<script type="application/javascript">
- createHTML({
- title: "navigator.mozGetUserMedia Callback Test",
- bug: "1119593"
- });
- /**
- * Check that the old fashioned callback-based function works.
- */
- runTest(function () {
- var testAudio = createMediaElement('audio', 'testAudio');
- var constraints = {audio: true};
-
- SimpleTest.waitForExplicitFinish();
- navigator.mozGetUserMedia(constraints, aStream => {
- checkMediaStreamTracks(constraints, aStream);
-
- var playback = new LocalMediaStreamPlayback(testAudio, aStream);
- return playback.playMedia(false)
- .then(() => SimpleTest.finish(), generateErrorCallback());
- }, generateErrorCallback());
- });
-
-</script>
-</pre>
-</body>
-</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_constraints.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_constraints.html
@@ -1,18 +1,29 @@
<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=882145
+-->
<head>
- <script src="mediaStreamPlayback.js"></script>
- <script src="constraints.js"></script>
+ <meta charset="utf-8">
+ <title>Test mozGetUserMedia Constraints</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="constraints.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=882145">Test mozGetUserMedia Constraints (desktop)</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
<pre id="test">
<script type="application/javascript">
-createHTML({ title: "Test getUserMedia constraints (desktop)", bug: "882145" });
/**
See constraints.js for testConstraints() and common_tests.
TODO(jib): Merge desktop and mobile version of these tests again (Bug 997365)
*/
var desktop_tests = [
{ message: "legacy facingMode ignored (desktop)",
constraints: { video: { mandatory: { facingMode:'left' } }, fake: true },
error: null },
--- a/dom/media/tests/mochitest/test_getUserMedia_constraints_mobile.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_constraints_mobile.html
@@ -1,18 +1,29 @@
<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=882145
+-->
<head>
- <script src="mediaStreamPlayback.js"></script>
- <script src="constraints.js"></script>
+ <meta charset="utf-8">
+ <title>Test mozGetUserMedia Constraints</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="constraints.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=882145">Test mozGetUserMedia Constraints (mobile)</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
<pre id="test">
<script type="application/javascript">
-createHTML({ title: "Test getUserMedia constraints (mobile)", bug: "882145" });
/**
See constraints.js for testConstraints() and common_tests.
TODO(jib): Merge desktop and mobile version of these tests again (Bug 997365)
*/
var mobile_tests = [
{ message: "legacy facingMode overconstrains video (mobile)",
constraints: { video: { mandatory: { facingMode:'left' } }, fake: true },
error: "NotFoundError" },
--- a/dom/media/tests/mochitest/test_getUserMedia_gumWithinGum.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_gumWithinGum.html
@@ -1,40 +1,56 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia gum within gum</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia gum within gum</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+ <audio id="testAudio"></audio>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({title: "getUserMedia within getUserMedia", bug: "822109" });
/**
* Run a test that we can complete a playback cycle for a video,
* then upon completion, do a playback cycle with audio, such that
* the audio gum call happens within the video gum call.
*/
runTest(function () {
- getUserMedia({video: true})
- .then(videoStream => {
- var testVideo = createMediaElement('video', 'testVideo');
- var videoPlayback = new LocalMediaStreamPlayback(testVideo,
- videoStream);
+ getUserMedia({video: true}, function(videoStream) {
+ var testVideo = document.getElementById('testVideo');
+ var videoStreamPlayback = new LocalMediaStreamPlayback(testVideo,
+ videoStream);
+
+ videoStreamPlayback.playMedia(false, function() {
+ getUserMedia({audio: true}, function(audioStream) {
+ var testAudio = document.getElementById('testAudio');
+ var audioStreamPlayback = new LocalMediaStreamPlayback(testAudio,
+ audioStream);
- return videoPlayback.playMedia(false)
- .then(() => getUserMedia({audio: true}))
- .then(audioStream => {
- var testAudio = createMediaElement('audio', 'testAudio');
- var audioPlayback = new LocalMediaStreamPlayback(testAudio,
- audioStream);
+ audioStreamPlayback.playMedia(false, function() {
+ audioStream.stop();
+ videoStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
- return audioPlayback.playMedia(false)
- .then(() => audioStream.stop());
- })
- .then(() => videoStream.stop());
- })
- .then(() => SimpleTest.finish(), generateErrorCallback());
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
@@ -1,18 +1,29 @@
<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=942367
+-->
<head>
- <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+ <meta charset="utf-8">
+ <title>Test mozGetUserMedia peerIdentity Constraint</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="blacksilence.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=942367">Test mozGetUserMedia peerIdentity Constraint</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
<pre id="test">
<script type="application/javascript">
-createHTML({ title: "Test getUserMedia peerIdentity Constraint", bug: "942367" });
function theTest() {
function testPeerIdentityConstraint(withConstraint, done) {
var config = { audio: true, video: true, fake: true };
if (withConstraint) {
config.peerIdentity = 'user@example.com';
}
info('getting media with constraints: ' + JSON.stringify(config));
navigator.mediaDevices.getUserMedia(config).then(function(stream) {
--- a/dom/media/tests/mochitest/test_getUserMedia_playAudioTwice.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_playAudioTwice.html
@@ -1,26 +1,46 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Play Audio Twice</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia Play Audio Twice</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <audio id="testAudio"></audio>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({title: "getUserMedia Play Audio Twice", bug: "822109" });
/**
* Run a test that we can complete an audio playback cycle twice in a row.
*/
runTest(function () {
- getUserMedia({audio: true}).then(audioStream => {
- var testAudio = createMediaElement('audio', 'testAudio');
- var playback = new LocalMediaStreamPlayback(testAudio, audioStream);
+ getUserMedia({audio: true}, function(audioStream) {
+ var testAudio = document.getElementById('testAudio');
+ var audioStreamPlayback = new LocalMediaStreamPlayback(testAudio,
+ audioStream);
+
+ audioStreamPlayback.playMedia(false, function() {
- return playback.playMedia(false)
- .then(() => playback.playMedia(true))
- .then(() => audioStream.stop());
- }).then(() => SimpleTest.finish(), generateErrorCallback());
+ audioStreamPlayback.playMedia(true, function() {
+ audioStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
+
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_playVideoAudioTwice.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_playVideoAudioTwice.html
@@ -1,27 +1,45 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Play Video and Audio Twice</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia Play Video and Audio Twice</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({title: "getUserMedia Play Video and Audio Twice", bug: "822109" });
/**
* Run a test that we can complete a video playback cycle twice in a row.
*/
runTest(function () {
- getUserMedia({video: true, audio: true}).then(stream => {
- var testVideo = createMediaElement('video', 'testVideo');
- var playback = new LocalMediaStreamPlayback(testVideo, stream);
+ getUserMedia({video: true, audio: true}, function(stream) {
+ var testVideo = document.getElementById('testVideo');
+ var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
+
+ streamPlayback.playMedia(false, function() {
- return playback.playMedia(false)
- .then(() => playback.playMedia(true))
- .then(() => stream.stop());
- }).then(() => SimpleTest.finish(), generateErrorCallback());
+ streamPlayback.playMedia(true, function() {
+ stream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_playVideoTwice.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_playVideoTwice.html
@@ -1,27 +1,46 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Play Video Twice</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia Play Video Twice</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({ title: "getUserMedia Play Video Twice", bug: "822109" });
/**
* Run a test that we can complete a video playback cycle twice in a row.
*/
runTest(function () {
- getUserMedia({video: true}).then(stream => {
- var testVideo = createMediaElement('video', 'testVideo');
- var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
+ getUserMedia({video: true}, function(videoStream) {
+ var testVideo = document.getElementById('testVideo');
+ var videoStreamPlayback = new LocalMediaStreamPlayback(testVideo,
+ videoStream);
+
+ videoStreamPlayback.playMedia(false, function() {
- return streamPlayback.playMedia(false)
- .then(() => streamPlayback.playMedia(true))
- .then(() => stream.stop());
- }).then(() => SimpleTest.finish(), generateErrorCallback());
+ videoStreamPlayback.playMedia(true, function() {
+ videoStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_stopAudioStream.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopAudioStream.html
@@ -1,28 +1,39 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Stop Audio Stream</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia Stop Audio Stream</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <audio id="testAudio"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({ title: "getUserMedia Stop Audio Stream", bug: "822109" });
/**
* Run a test to verify that we can start an audio stream in a media element,
* call stop() on the stream, and successfully get an ended event fired.
*/
runTest(function () {
- getUserMedia({audio: true})
- .then(stream => {
- var testAudio = createMediaElement('audio', 'testAudio');
- var streamPlayback = new LocalMediaStreamPlayback(testAudio, stream);
+ getUserMedia({audio: true}, function(stream) {
+ var testAudio = document.getElementById('testAudio');
+ var audioStreamPlayback = new LocalMediaStreamPlayback(testAudio, stream);
- return streamPlayback.playMediaWithStreamStop(false);
- })
- .then(() => SimpleTest.finish(), generateErrorCallback());
+ audioStreamPlayback.playMediaWithStreamStop(false, SimpleTest.finish,
+ generateErrorCallback());
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_stopAudioStreamWithFollowupAudio.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopAudioStreamWithFollowupAudio.html
@@ -1,36 +1,51 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Stop Audio Stream With Followup Audio</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia Stop Audio Stream With Followup Audio</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <audio id="testAudio"></audio>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({ title: "getUserMedia Stop Audio Stream With Followup Audio", bug: "822109" });
/**
* Run a test to verify that I can complete an audio gum playback in a media
* element, stop the stream, and then complete another audio gum playback
* in a media element.
*/
runTest(function () {
- getUserMedia({audio: true})
- .then(firstStream => {
- var testAudio = createMediaElement('audio', 'testAudio');
- var streamPlayback = new LocalMediaStreamPlayback(testAudio, firstStream);
+ getUserMedia({audio: true}, function(firstStream) {
+ var testAudio = document.getElementById('testAudio');
+ var streamPlayback = new LocalMediaStreamPlayback(testAudio, firstStream);
+
+ streamPlayback.playMediaWithStreamStop(false, function() {
+ getUserMedia({audio: true}, function(secondStream) {
+ streamPlayback.mediaStream = secondStream;
- return streamPlayback.playMediaWithStreamStop(false)
- .then(() => getUserMedia({audio: true}))
- .then(secondStream => {
- streamPlayback.mediaStream = secondStream;
+ streamPlayback.playMedia(false, function() {
+ secondStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
- return streamPlayback.playMedia(false)
- .then(() => secondStream.stop());
- });
- })
- .then(() => SimpleTest.finish(), generateErrorCallback());
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStream.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStream.html
@@ -1,29 +1,40 @@
<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Stop Video Audio Stream</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia Stop Video Audio Stream</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({ title: "getUserMedia Stop Video Audio Stream", bug: "822109" });
/**
* Run a test to verify that we can start a video+audio stream in a
* media element, call stop() on the stream, and successfully get an
* ended event fired.
*/
runTest(function () {
- getUserMedia({video: true, audio: true})
- .then(stream => {
- var testVideo = createMediaElement('video', 'testVideo');
- var playback = new LocalMediaStreamPlayback(testVideo, stream);
+ getUserMedia({video: true, audio: true}, function(stream) {
+ var testVideo = document.getElementById('testVideo');
+ var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
- return playback.playMediaWithStreamStop(false);
- })
- .then(() => SimpleTest.finish(), generateErrorCallback());
+ streamPlayback.playMediaWithStreamStop(false, SimpleTest.finish,
+ generateErrorCallback());
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html
@@ -1,39 +1,51 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Stop Video+Audio Stream With Followup Video+Audio</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia Stop Video+Audio Stream With Followup Video+Audio</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({
- title: "getUserMedia Stop Video+Audio Stream With Followup Video+Audio",
- bug: "822109"
- });
/**
* Run a test to verify that I can complete an video+audio gum playback in a
* media element, stop the stream, and then complete another video+audio gum
* playback in a media element.
*/
runTest(function () {
- getUserMedia({video: true, audio: true})
- .then(stream => {
- var testVideo = createMediaElement('video', 'testVideo');
- var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
+ getUserMedia({video: true, audio: true}, function(firstStream) {
+ var testVideo = document.getElementById('testVideo');
+ var streamPlayback = new LocalMediaStreamPlayback(testVideo, firstStream);
+
+ streamPlayback.playMediaWithStreamStop(false, function() {
+ getUserMedia({video: true, audio: true}, function(secondStream) {
+ streamPlayback.mediaStream = secondStream;
- return streamPlayback.playMediaWithStreamStop(false)
- .then(() => getUserMedia({video: true, audio: true}))
- .then(secondStream => {
- streamPlayback.mediaStream = secondStream;
+ streamPlayback.playMedia(false, function() {
+ secondStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
- return streamPlayback.playMedia(false)
- .then(() => secondStream.stop());
- });
- })
- .then(() => SimpleTest.finish(), generateErrorCallback());
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_stopVideoStream.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopVideoStream.html
@@ -1,29 +1,39 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Stop Video Stream</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia Stop Video Stream</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({ title: "getUserMedia Stop Video Stream", bug: "822109" });
/**
- * Run a test to verify that we can start a video stream in a
- * media element, call stop() on the stream, and successfully get an
- * ended event fired.
+ * Run a test to verify that we can start a video stream in a media element,
+ * call stop() on the stream, and successfully get an ended event fired.
*/
runTest(function () {
- getUserMedia({video: true})
- .then(stream => {
- var testVideo = createMediaElement('video', 'testVideo');
- var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
+ getUserMedia({video: true}, function(stream) {
+ var testVideo = document.getElementById('testVideo');
+ var videoStreamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
- return streamPlayback.playMediaWithStreamStop(false);
- })
- .then(() => SimpleTest.finish(), generateErrorCallback());
+ videoStreamPlayback.playMediaWithStreamStop(false, SimpleTest.finish,
+ generateErrorCallback());
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_getUserMedia_stopVideoStreamWithFollowupVideo.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopVideoStreamWithFollowupVideo.html
@@ -1,36 +1,52 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822109
+-->
<head>
- <script src="mediaStreamPlayback.js"></script>
+ <meta charset="utf-8">
+ <title>mozGetUserMedia Stop Video Stream With Followup Video</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">mozGetUserMedia Stop Video Stream With Followup Video</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <video id="testVideo"></video>
+</div>
<pre id="test">
<script type="application/javascript">
- createHTML({ title: "getUserMedia Stop Video Stream With Followup Video", bug: "822109" });
/**
- * Run a test to verify that I can complete an video gum playback in a
- * media element, stop the stream, and then complete another video gum
- * playback in a media element.
+ * Run a test to verify that I can complete an audio gum playback in a media
+ * element, stop the stream, and then complete another audio gum playback
+ * in a media element.
*/
runTest(function () {
- getUserMedia({video: true})
- .then(stream => {
- var testVideo = createMediaElement('video', 'testVideo');
- var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
+ getUserMedia({video: true}, function(firstStream) {
+ var testVideo = document.getElementById('testVideo');
+ var streamPlayback = new LocalMediaStreamPlayback(testVideo,
+ firstStream);
+
+ streamPlayback.playMediaWithStreamStop(false, function() {
+ getUserMedia({video: true}, function(secondStream) {
+ streamPlayback.mediaStream = secondStream;
- return streamPlayback.playMediaWithStreamStop(false)
- .then(() => getUserMedia({video: true}))
- .then(secondStream => {
- streamPlayback.mediaStream = secondStream;
+ streamPlayback.playMedia(false, function() {
+ secondStream.stop();
+ SimpleTest.finish();
+ }, generateErrorCallback());
- return streamPlayback.playMedia(false)
- .then(() => secondStream.stop());
- });
- })
- .then(() => SimpleTest.finish(), generateErrorCallback());
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
+
+ }, generateErrorCallback());
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_addCandidateInHaveLocalOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_addCandidateInHaveLocalOffer.html
@@ -1,37 +1,45 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "784519",
title: "addCandidate (answer) in 'have-local-offer'"
});
var test;
runNetworkTest(function () {
test = new PeerConnectionTest();
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.chain.removeAfter("PC_LOCAL_SET_LOCAL_DESCRIPTION");
- test.chain.append([
- function PC_LOCAL_ADD_CANDIDATE(test) {
- var candidate = new mozRTCIceCandidate(
- {candidate:"1 1 UDP 2130706431 192.168.2.1 50005 typ host",
- sdpMLineIndex: 1});
- return test.pcLocal._pc.addIceCandidate(candidate).then(
- generateErrorCallback("addIceCandidate should have failed."),
- err => {
+ test.chain.append([[
+ "PC_LOCAL_ADD_CANDIDATE",
+ function (test) {
+ test.pcLocal.addIceCandidateAndFail(
+ new mozRTCIceCandidate(
+ {candidate:"1 1 UDP 2130706431 192.168.2.1 50005 typ host",
+ sdpMLineIndex: 1}),
+ function(err) {
is(err.name, "InvalidStateError", "Error is InvalidStateError");
- });
- }
- ]);
+ test.next();
+ } );
+ }
+ ]]);
+
test.run();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html
+++ b/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html
@@ -1,59 +1,102 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1091242",
title: "Renegotiation: add second audio stream"
});
var test;
runNetworkTest(function (options) {
test = new PeerConnectionTest(options);
test.chain.append([
- function PC_LOCAL_SETUP_NEGOTIATION_CALLBACK(test) {
+ [
+ 'PC_LOCAL_SETUP_NEGOTIATION_CALLBACK',
+ function (test) {
test.pcLocal.onNegotiationneededFired = false;
- test.pcLocal._pc.onnegotiationneeded = anEvent => {
+ test.pcLocal._pc.onnegotiationneeded = function (anEvent) {
info("pcLocal.onnegotiationneeded fired");
test.pcLocal.onNegotiationneededFired = true;
};
- },
- function PC_LOCAL_ADD_SECOND_STREAM(test) {
- return test.pcLocal.getAllUserMedia([{audio: true}]);
- },
- function PC_LOCAL_CREATE_NEW_OFFER(test) {
+ test.next();
+ }
+ ],
+ [
+ 'PC_LOCAL_ADD_SECOND_STREAM',
+ function (test) {
+ test.pcLocal.getAllUserMedia([{audio: true}], function () {
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_LOCAL_CREATE_NEW_OFFER',
+ function (test) {
ok(test.pcLocal.onNegotiationneededFired, "onnegotiationneeded");
- return test.createOffer(test.pcLocal).then(offer => {
+ test.createOffer(test.pcLocal, function (offer) {
test._new_offer = offer;
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_LOCAL_SET_NEW_LOCAL_DESCRIPTION',
+ function (test) {
+ test.setLocalDescription(test.pcLocal, test._new_offer, HAVE_LOCAL_OFFER, function () {
+ test.next();
});
- },
- function PC_LOCAL_SET_NEW_LOCAL_DESCRIPTION(test) {
- return test.setLocalDescription(test.pcLocal, test._new_offer, HAVE_LOCAL_OFFER);
- },
- function PC_REMOTE_SET_NEW_REMOTE_DESCRIPTION(test) {
- return test.setRemoteDescription(test.pcRemote, test._new_offer, HAVE_REMOTE_OFFER);
- },
- function PC_REMOTE_CREATE_NEW_ANSWER(test) {
- return test.createAnswer(test.pcRemote).then(answer => {
+ }
+ ],
+ [
+ 'PC_REMOTE_SET_NEW_REMOTE_DESCRIPTION',
+ function (test) {
+ test.setRemoteDescription(test.pcRemote, test._new_offer, HAVE_REMOTE_OFFER, function () {
+ test.next();
+ });
+ }
+ ],
+ [
+ 'PC_REMOTE_CREATE_NEW_ANSWER',
+ function (test) {
+ test.createAnswer(test.pcRemote, function (answer) {
test._new_answer = answer;
+ test.next();
});
- },
- function PC_REMOTE_SET_NEW_LOCAL_DESCRIPTION(test) {
- return test.setLocalDescription(test.pcRemote, test._new_answer, STABLE);
- },
- function PC_LOCAL_SET_NEW_REMOTE_DESCRIPTION(test) {
- return test.setRemoteDescription(test.pcLocal, test._new_answer, STABLE);
+ }
+ ],
+ [
+ 'PC_REMOTE_SET_NEW_LOCAL_DESCRIPTION',
+ function (test) {
+ test.setLocalDescription(test.pcRemote, test._new_answer, STABLE, function () {
+ test.next();
+ });
}
- // TODO(bug 1093835): figure out how to verify if media flows through the new stream
+ ],
+ [
+ 'PC_LOCAL_SET_NEW_REMOTE_DESCRIPTION',
+ function (test) {
+ test.setRemoteDescription(test.pcLocal, test._new_answer, STABLE, function () {
+ test.next();
+ });
+ }
+ ]
+ // TODO(bug 1093835): figure out how to verify if media flows through the new stream
]);
test.setMediaConstraints([{audio: true}], [{audio: true}]);
test.run();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudio.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796892",
title: "Basic audio-only peer connection"
});
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioVideo.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796890",
title: "Basic audio/video (separate) peer connection"
});
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoCombined.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoCombined.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796890",
title: "Basic audio/video (combined) peer connection"
});
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoCombined_long.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoCombined_long.html
@@ -1,37 +1,44 @@
<!DOCTYPE HTML>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="long.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1014328",
title: "Basic audio/video (combined) peer connection, long running",
visible: true
});
var test;
- runNetworkTest(function (options) {
+ runTest(function (options) {
options = options || {};
options.commands = commandsPeerConnection.slice(0);
options.commands.push(generateIntervalCommand(verifyConnectionStatus,
1000 * 10,
1000 * 3600 * 3));
test = new PeerConnectionTest(options);
test.setMediaConstraints([{audio: true, video: true, fake: false}],
[{audio: true, video: true, fake: false}]);
test.run();
});
</script>
</pre>
</body>
</html>
+
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoNoBundle.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudioVideoNoBundle.html
@@ -1,34 +1,43 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1016476",
title: "Basic audio/video peer connection with no Bundle"
});
- runNetworkTest(options => {
- var test = new PeerConnectionTest(options);
- test.chain.insertAfter(
- 'PC_LOCAL_CREATE_OFFER',
- [
- function PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER(test) {
- test.originalOffer.sdp = test.originalOffer.sdp.replace(
- /a=group:BUNDLE .*\r\n/g,
- ""
- );
- info("Updated no bundle offer: " + JSON.stringify(test.originalOffer));
- }
- ]);
+ SimpleTest.requestFlakyTimeout("WebRTC is full of inherent timeouts");
+
+ var test;
+ runNetworkTest(function (options) {
+ test = new PeerConnectionTest(options);
+ test.chain.insertAfter('PC_LOCAL_CREATE_OFFER',
+ [['PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER',
+ function (test) {
+ test.originalOffer.sdp = test.originalOffer.sdp.replace(
+ /a=group:BUNDLE .*\r\n/g,
+ ""
+ );
+ info("Updated no bundle offer: " + JSON.stringify(test.originalOffer));
+ test.next();
+ }
+ ]]);
test.setMediaConstraints([{audio: true}, {video: true}],
[{audio: true}, {video: true}]);
test.run();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudio_long.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudio_long.html
@@ -1,18 +1,24 @@
<!DOCTYPE HTML>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="long.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796892",
title: "Basic audio-only peer connection",
visible: true
--- a/dom/media/tests/mochitest/test_peerConnection_basicH264Video.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicH264Video.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript;version=1.8">
createHTML({
bug: "1040346",
title: "Basic H.264 GMP video-only peer connection"
});
--- a/dom/media/tests/mochitest/test_peerConnection_basicScreenshare.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicScreenshare.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1039666",
title: "Basic screenshare-only peer connection"
});
--- a/dom/media/tests/mochitest/test_peerConnection_basicVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicVideo.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796888",
title: "Basic video-only peer connection"
});
--- a/dom/media/tests/mochitest/test_peerConnection_basicVideo_long.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicVideo_long.html
@@ -1,18 +1,24 @@
<!DOCTYPE HTML>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="long.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "796888",
title: "Basic video-only peer connection",
visible: true
--- a/dom/media/tests/mochitest/test_peerConnection_basicWindowshare.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicWindowshare.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1038926",
title: "Basic windowshare-only peer connection"
});
--- a/dom/media/tests/mochitest/test_peerConnection_bug1013809.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug1013809.html
@@ -1,12 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1013809",
title: "Audio-only peer connection with swapped setLocal and setRemote steps"
});
--- a/dom/media/tests/mochitest/test_peerConnection_bug1042791.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug1042791.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript;version=1.8">
createHTML({
bug: "1040346",
title: "Basic H.264 GMP video-only peer connection"
});
@@ -14,23 +20,25 @@
var test;
runNetworkTest(function (options) {
options = options || { };
options.h264 = true;
test = new PeerConnectionTest(options);
test.setMediaConstraints([{video: true}], [{video: true}]);
test.chain.removeAfter("PC_LOCAL_CREATE_OFFER");
- test.chain.append([
- function PC_LOCAL_VERIFY_H264_OFFER(test) {
+ test.chain.append([[
+ "PC_LOCAL_VERIFY_H264_OFFER",
+ function (test) {
ok(!test.pcLocal._latest_offer.sdp.toLowerCase().contains("profile-level-id=0x42e0"),
- "H264 offer does not contain profile-level-id=0x42e0");
+ "H264 offer does not contain profile-level-id=0x42e0");
ok(test.pcLocal._latest_offer.sdp.toLowerCase().contains("profile-level-id=42e0"),
- "H264 offer contains profile-level-id=42e0");
+ "H264 offer contains profile-level-id=42e0");
+ test.next();
}
- ]);
+ ]]);
test.run();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_bug822674.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug822674.html
@@ -1,11 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "822674",
title: "mozRTCPeerConnection isn't a true javascript object as it should be"
--- a/dom/media/tests/mochitest/test_peerConnection_bug825703.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug825703.html
@@ -1,80 +1,83 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "825703",
title: "RTCConfiguration valid/invalid permutations"
});
-var makePC = (config, expected_error) => {
- var exception;
- try {
- new mozRTCPeerConnection(config).close();
- } catch (e) {
- exception = e;
- }
- is((exception? exception.name : "success"), expected_error || "success",
- "mozRTCPeerConnection(" + JSON.stringify(config) + ")");
-};
-
-// This is a test of the iceServers parsing code + readable errors
-runNetworkTest(() => {
- var exception = null;
-
- try {
- new mozRTCPeerConnection().close();
- } catch (e) {
- exception = e;
- }
- ok(!exception, "mozRTCPeerConnection() succeeds");
- exception = null;
-
- makePC();
-
- makePC(1, "TypeError");
-
- makePC({});
-
- makePC({ iceServers: [] });
-
- makePC({ iceServers: [{ urls:"" }] }, "SyntaxError");
-
- makePC({ iceServers: [
- { urls:"stun:127.0.0.1" },
- { urls:"stun:localhost", foo:"" },
- { urls: ["stun:127.0.0.1", "stun:localhost"] },
- { urls:"stuns:localhost", foo:"" },
- { urls:"turn:[::1]:3478", username:"p", credential:"p" },
- { urls:"turn:localhost:3478?transport=udp", username:"p", credential:"p" },
- { urls: ["turn:[::1]:3478", "turn:localhost"], username:"p", credential:"p" },
- { urls:"turns:localhost:3478?transport=udp", username:"p", credential:"p" },
- { url:"stun:localhost", foo:"" },
- { url:"turn:localhost", username:"p", credential:"p" }
- ]});
-
- makePC({ iceServers: [{ urls: ["stun:127.0.0.1", ""] }] }, "SyntaxError");
-
- makePC({ iceServers: [{ urls:"turns:localhost:3478", username:"p" }] }, "InvalidAccessError");
-
- makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, "InvalidAccessError");
-
- makePC({ iceServers: [{ urls:"http:0.0.0.0" }] }, "SyntaxError");
-
- try {
- new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }).close();
- } catch (e) {
- ok(e.message.indexOf("http") > 0,
- "mozRTCPeerConnection() constructor has readable exceptions");
+ makePC = (config, expected_error) => {
+ var exception;
+ try {
+ new mozRTCPeerConnection(config).close();
+ } catch (e) {
+ exception = e;
+ }
+ is((exception? exception.name : "success"), expected_error || "success",
+ "mozRTCPeerConnection(" + JSON.stringify(config) + ")");
}
- networkTestFinished();
-});
+ // This is a test of the iceServers parsing code + readable errors
+
+ runNetworkTest(function () {
+ var exception = null;
+
+ try {
+ new mozRTCPeerConnection().close();
+ } catch (e) {
+ exception = e;
+ }
+ ok(!exception, "mozRTCPeerConnection() succeeds");
+ exception = null;
+
+ makePC();
+
+ makePC(1, "TypeError");
+
+ makePC({});
+
+ makePC({ iceServers: [] });
+
+ makePC({ iceServers: [{ urls:"" }] }, "SyntaxError");
+
+ makePC({ iceServers: [
+ { urls:"stun:127.0.0.1" },
+ { urls:"stun:localhost", foo:"" },
+ { urls: ["stun:127.0.0.1", "stun:localhost"] },
+ { urls:"stuns:localhost", foo:"" },
+ { urls:"turn:[::1]:3478", username:"p", credential:"p" },
+ { urls:"turn:localhost:3478?transport=udp", username:"p", credential:"p" },
+ { urls: ["turn:[::1]:3478", "turn:localhost"], username:"p", credential:"p" },
+ { urls:"turns:localhost:3478?transport=udp", username:"p", credential:"p" },
+ { url:"stun:localhost", foo:"" },
+ { url:"turn:localhost", username:"p", credential:"p" }
+ ]});
+
+ makePC({ iceServers: [{ urls: ["stun:127.0.0.1", ""] }] }, "SyntaxError");
+
+ makePC({ iceServers: [{ urls:"turns:localhost:3478", username:"p" }] }, "InvalidAccessError");
+
+ makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, "InvalidAccessError");
+
+ makePC({ iceServers: [{ urls:"http:0.0.0.0" }] }, "SyntaxError");
+ try {
+ new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] }).close();
+ } catch (e) {
+ ok(e.message.indexOf("http") > 0,
+ "mozRTCPeerConnection() constructor has readable exceptions");
+ }
+
+ networkTestFinished();
+ });
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_bug827843.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug827843.html
@@ -1,70 +1,72 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "827843",
title: "Ensure that localDescription and remoteDescription are null after close"
});
-var steps = [
- function CHECK_SDP_ON_CLOSED_PC(test) {
- var description;
- var exception = null;
+ var steps = [
+ [
+ "CHECK_SDP_ON_CLOSED_PC",
+ function (test) {
+ var description;
+ var exception = null;
- // handle the event which the close() triggers
- var localClosed = new Promise(resolve => {
- test.pcLocal.onsignalingstatechange = e => {
- is(e.target.signalingState, "closed",
- "Received expected onsignalingstatechange event on 'closed'");
- resolve();
- }
- });
+ // handle the event which the close() triggers
+ test.pcLocal.onsignalingstatechange = function (e) {
+ is(e.target.signalingState, "closed",
+ "Received expected onsignalingstatechange event on 'closed'");
+ }
+
+ test.pcLocal.close();
- test.pcLocal.close();
+ try { description = test.pcLocal.localDescription; } catch (e) { exception = e; }
+ ok(exception, "Attempt to access localDescription of pcLocal after close throws exception");
+ exception = null;
- try { description = test.pcLocal.localDescription; } catch (e) { exception = e; }
- ok(exception, "Attempt to access localDescription of pcLocal after close throws exception");
- exception = null;
-
- try { description = test.pcLocal.remoteDescription; } catch (e) { exception = e; }
- ok(exception, "Attempt to access remoteDescription of pcLocal after close throws exception");
- exception = null;
+ try { description = test.pcLocal.remoteDescription; } catch (e) { exception = e; }
+ ok(exception, "Attempt to access remoteDescription of pcLocal after close throws exception");
+ exception = null;
- // handle the event which the close() triggers
- var remoteClosed = new Promise(resolve => {
- test.pcRemote.onsignalingstatechange = e => {
- is(e.target.signalingState, "closed",
- "Received expected onsignalingstatechange event on 'closed'");
- resolve();
- }
- });
+ // handle the event which the close() triggers
+ test.pcRemote.onsignalingstatechange = function (e) {
+ is(e.target.signalingState, "closed",
+ "Received expected onsignalingstatechange event on 'closed'");
+ }
- test.pcRemote.close();
+ test.pcRemote.close();
- try { description = test.pcRemote.localDescription; } catch (e) { exception = e; }
- ok(exception, "Attempt to access localDescription of pcRemote after close throws exception");
- exception = null;
+ try { description = test.pcRemote.localDescription; } catch (e) { exception = e; }
+ ok(exception, "Attempt to access localDescription of pcRemote after close throws exception");
+ exception = null;
- try { description = test.pcRemote.remoteDescription; } catch (e) { exception = e; }
- ok(exception, "Attempt to access remoteDescription of pcRemote after close throws exception");
+ try { description = test.pcRemote.remoteDescription; } catch (e) { exception = e; }
+ ok(exception, "Attempt to access remoteDescription of pcRemote after close throws exception");
- return Promise.all([localClosed, remoteClosed]);
- }
-];
+ test.next();
+ }
+ ]
+ ];
-var test;
-runNetworkTest(() => {
- test = new PeerConnectionTest();
- test.setMediaConstraints([{audio: true}], [{audio: true}]);
- test.chain.append(steps);
- test.run();
-});
+ var test;
+ runNetworkTest(function () {
+ test = new PeerConnectionTest();
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.chain.append(steps);
+ test.run();
+ });
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_bug834153.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug834153.html
@@ -1,11 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "834153",
title: "Queue CreateAnswer in PeerConnection.js"
deleted file mode 100644
--- a/dom/media/tests/mochitest/test_peerConnection_callbacks.html
+++ /dev/null
@@ -1,92 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <script type="application/javascript" src="pc.js"></script>
-</head>
-<body>
-<pre id="test">
-<script type="application/javascript;version=1.8">
- createHTML({
- title: "PeerConnection using callback functions",
- bug: "1119593",
- visible: true
- });
-
-// This still aggressively uses promises, but it is testing that the callback functions
-// are properly in place.
-
-// wrapper that turns a callback-based function call into a promise
-function pcall(o, f, beforeArg) {
- return new Promise((resolve, reject) => {
- var args = [resolve, reject];
- if (typeof beforeArg !== 'undefined') {
- args.unshift(beforeArg);
- }
- info('Calling ' + f.name);
- f.apply(o, args);
- });
-}
-
-var pc1 = new mozRTCPeerConnection();
-var pc2 = new mozRTCPeerConnection();
-
-var pc2_haveRemoteOffer = new Promise(resolve => {
- pc2.onsignalingstatechange =
- e => (e.target.signalingState == "have-remote-offer") && resolve();
-});
-var pc1_stable = new Promise(resolve => {
- pc1.onsignalingstatechange =
- e => (e.target.signalingState == "stable") && resolve();
-});
-
-pc1.onicecandidate = e => {
- pc2_haveRemoteOffer
- .then(() => !e.candidate || pcall(pc2, pc2.addIceCandidate, e.candidate))
- .catch(generateErrorCallback());
-};
-pc2.onicecandidate = e => {
- pc1_stable
- .then(() => !e.candidate || pcall(pc1, pc1.addIceCandidate, e.candidate))
- .catch(generateErrorCallback());
-};
-
-var v1, v2;
-var delivered = new Promise(resolve => {
- pc2.onaddstream = e => {
- v2.mozSrcObject = e.stream;
- resolve(e.stream);
- };
-});
-
-runNetworkTest(function() {
- v1 = createMediaElement('video', 'v1');
- v2 = createMediaElement('video', 'v2');
- var canPlayThrough = new Promise(resolve => v2.canplaythrough = resolve);
- is(v2.currentTime, 0, "v2.currentTime is zero at outset");
-
- // not testing legacy gUM here
- navigator.mediaDevices.getUserMedia({ fake: true, video: true, audio: true })
- .then(stream => pc1.addStream(v1.mozSrcObject = stream))
- .then(() => pcall(pc1, pc1.createOffer))
- .then(offer => pcall(pc1, pc1.setLocalDescription, offer))
- .then(() => pcall(pc2, pc2.setRemoteDescription, pc1.localDescription))
- .then(() => pcall(pc2, pc2.createAnswer))
- .then(answer => pcall(pc2, pc2.setLocalDescription, answer))
- .then(() => pcall(pc1, pc1.setRemoteDescription, pc2.localDescription))
- .then(() => delivered)
- // .then(() => canPlayThrough) // why doesn't this fire?
- .then(() => waitUntil(() => v2.currentTime > 0 && v2.mozSrcObject.currentTime > 0))
- .then(() => ok(v2.currentTime > 0, "v2.currentTime is moving (" + v2.currentTime + ")"))
- .then(() => ok(true, "Connected."))
- .then(() => pcall(pc1, pc1.getStats, null))
- .then(stats => ok(Object.keys(stats).length > 0, "pc1 has stats"))
- .then(() => pcall(pc2, pc2.getStats, null))
- .then(stats => ok(Object.keys(stats).length > 0, "pc2 has stats"))
- .then(() => { v1.pause(); v2.pause(); })
- .catch(reason => ok(false, "unexpected failure: " + reason))
- .then(networkTestFinished);
-});
-</script>
-</pre>
-</body>
-</html>
--- a/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html
@@ -1,45 +1,55 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<video id="v1" src="../../test/vp9cake.webm" height="120" width="160" autoplay muted></video>
<pre id="test">
<script type="application/javascript;version=1.8">
createHTML({
bug: "1081409",
title: "Captured video-only over peer connection",
visible: true
});
-var metadataLoaded = new Promise(resolve => {
- if (v1.readyState < v1.HAVE_METADATA) {
- v1.onloadedmetadata = resolve;
- } else {
+ var metadataLoaded = new Promise(resolve => {
+ if (v1.readyState < v1.HAVE_METADATA) {
+ v1.onloadedmetadata = e => resolve();
+ return;
+ }
resolve();
- }
-});
+ });
-runNetworkTest(function() {
- var test = new PeerConnectionTest();
- test.setOfferOptions({ offerToReceiveVideo: false,
- offerToReceiveAudio: false });
- test.chain.insertAfter("PC_LOCAL_GUM", [
- function PC_LOCAL_CAPTUREVIDEO(test) {
- return metadataLoaded
- .then(() => {
- var stream = v1.mozCaptureStreamUntilEnded();
- is(stream.getTracks().length, 2, "Captured stream has 2 tracks");
- stream.getTracks().forEach(tr => test.pcLocal._pc.addTrack(tr, stream));
- test.pcLocal.constraints = [{ video: true, audio:true }]; // fool tests
- });
+ runNetworkTest(function() {
+ var test = new PeerConnectionTest();
+ test.setOfferOptions({ offerToReceiveVideo: false,
+ offerToReceiveAudio: false });
+ test.chain.insertAfter("PC_LOCAL_GUM", [["PC_LOCAL_CAPTUREVIDEO", function (test) {
+ metadataLoaded
+ .then(function() {
+ var stream = v1.mozCaptureStreamUntilEnded();
+ is(stream.getTracks().length, 2, "Captured stream has 2 tracks");
+ stream.getTracks().forEach(tr => test.pcLocal._pc.addTrack(tr, stream));
+ test.pcLocal.constraints = [{ video: true, audio:true }]; // fool tests
+ test.next();
+ })
+ .catch(function(reason) {
+ ok(false, "unexpected failure: " + reason);
+ SimpleTest.finish();
+ });
}
- ]);
- test.chain.removeAfter("PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT");
- test.run();
-});
+ ]]);
+ test.chain.removeAfter("PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT");
+ test.run();
+ });
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_close.html
+++ b/dom/media/tests/mochitest/test_peerConnection_close.html
@@ -1,11 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "991877",
title: "Basic RTCPeerConnection.close() tests"
--- a/dom/media/tests/mochitest/test_peerConnection_errorCallbacks.html
+++ b/dom/media/tests/mochitest/test_peerConnection_errorCallbacks.html
@@ -1,11 +1,14 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "834270",
title: "Align PeerConnection error handling with WebRTC specification"
--- a/dom/media/tests/mochitest/test_peerConnection_noTrickleAnswer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_noTrickleAnswer.html
@@ -1,13 +1,19 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="nonTrickleIce.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1060102",
title: "Basic audio only SDP answer without trickle ICE"
});
--- a/dom/media/tests/mochitest/test_peerConnection_noTrickleOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_noTrickleOffer.html
@@ -1,13 +1,19 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="nonTrickleIce.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1060102",
title: "Basic audio only SDP offer without trickle ICE"
});
--- a/dom/media/tests/mochitest/test_peerConnection_noTrickleOfferAnswer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_noTrickleOfferAnswer.html
@@ -1,13 +1,19 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="nonTrickleIce.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "1060102",
title: "Basic audio only SDP offer and answer without trickle ICE"
});
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
@@ -1,12 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "850275",
title: "Simple offer media constraint test with audio"
});
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
@@ -1,12 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "850275",
title: "Simple offer media constraint test with video"
});
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
@@ -1,12 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "850275",
title: "Simple offer media constraint test with video/audio"
});
--- a/dom/media/tests/mochitest/test_peerConnection_promiseSendOnly.html
+++ b/dom/media/tests/mochitest/test_peerConnection_promiseSendOnly.html
@@ -1,57 +1,62 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
<script type="application/javascript" src="pc.js"></script>
</head>
<body>
+<video id="v1" controls="controls" height="120" width="160" autoplay></video>
+<video id="v2" controls="controls" height="120" width="160" autoplay></video><br>
<pre id="test">
<script type="application/javascript;version=1.8">
createHTML({
bug: "1091898",
title: "PeerConnection with promises (sendonly)",
visible: true
});
+ var waituntil = func => new Promise(resolve => {
+ var inter = setInterval(() => func() && resolve(clearInterval(inter)), 200);
+ });
+
var pc1 = new mozRTCPeerConnection();
var pc2 = new mozRTCPeerConnection();
var pc2_haveRemoteOffer = new Promise(resolve => pc2.onsignalingstatechange =
e => (e.target.signalingState == "have-remote-offer") && resolve());
var pc1_stable = new Promise(resolve => pc1.onsignalingstatechange =
e => (e.target.signalingState == "stable") && resolve());
pc1.onicecandidate = e => pc2_haveRemoteOffer.then(() => !e.candidate ||
pc2.addIceCandidate(e.candidate)).catch(generateErrorCallback());
pc2.onicecandidate = e => pc1_stable.then(() => !e.candidate ||
pc1.addIceCandidate(e.candidate)).catch(generateErrorCallback());
- var v1, v2;
var delivered = new Promise(resolve =>
pc2.onaddstream = e => resolve(v2.mozSrcObject = e.stream));
+ var canPlayThrough = new Promise(resolve => v2.canplaythrough = e => resolve());
runNetworkTest(function() {
- v1 = createMediaElement('video', 'v1');
- v2 = createMediaElement('video', 'v2');
- var canPlayThrough = new Promise(resolve => v2.canplaythrough = e => resolve());
-
is(v2.currentTime, 0, "v2.currentTime is zero at outset");
navigator.mediaDevices.getUserMedia({ fake: true, video: true, audio: true })
.then(stream => pc1.addStream(v1.mozSrcObject = stream))
.then(() => pc1.createOffer())
.then(offer => pc1.setLocalDescription(offer))
.then(() => pc2.setRemoteDescription(pc1.localDescription))
.then(() => pc2.createAnswer())
.then(answer => pc2.setLocalDescription(answer))
.then(() => pc1.setRemoteDescription(pc2.localDescription))
.then(() => delivered)
// .then(() => canPlayThrough) // why doesn't this fire?
- .then(() => waitUntil(() => v2.currentTime > 0 && v2.mozSrcObject.currentTime > 0))
+ .then(() => waituntil(() => v2.currentTime > 0 && v2.mozSrcObject.currentTime > 0))
.then(() => ok(v2.currentTime > 0, "v2.currentTime is moving (" + v2.currentTime + ")"))
.then(() => ok(true, "Connected."))
.catch(reason => ok(false, "unexpected failure: " + reason))
.then(networkTestFinished);
});
</script>
</pre>
</body>
--- a/dom/media/tests/mochitest/test_peerConnection_replaceTrack.html
+++ b/dom/media/tests/mochitest/test_peerConnection_replaceTrack.html
@@ -1,12 +1,18 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript;version=1.8">
createHTML({
bug: "1032839",
title: "Replace video track",
visible: true
@@ -20,33 +26,37 @@
var test;
runNetworkTest(function () {
test = new PeerConnectionTest();
test.setMediaConstraints([{video: true}], [{video: true}]);
test.chain.removeAfter("PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT");
var flowtest = test.chain.remove("PC_REMOTE_CHECK_MEDIA_FLOW_PRESENT");
test.chain.append(flowtest);
- test.chain.append([
- function PC_LOCAL_REPLACE_VIDEOTRACK(test) {
+ test.chain.append([["PC_LOCAL_REPLACE_VIDEOTRACK",
+ function (test) {
var stream = test.pcLocal._pc.getLocalStreams()[0];
var track = stream.getVideoTracks()[0];
var sender = test.pcLocal._pc.getSenders().find(isSenderOfTrack, track);
ok(sender, "track has a sender");
var newtrack;
- return navigator.mediaDevices.getUserMedia({video:true, fake: true})
- .then(newStream => {
- newtrack = newStream.getVideoTracks()[0];
- return sender.replaceTrack(newtrack);
- })
- .then(() => {
- is(sender.track, newtrack, "sender.track has been replaced");
- });
+ navigator.mediaDevices.getUserMedia({video:true, fake: true})
+ .then(function(newStream) {
+ newtrack = newStream.getVideoTracks()[0];
+ return sender.replaceTrack(newtrack);
+ })
+ .then(function() {
+ is(sender.track, newtrack, "sender.track has been replaced");
+ })
+ .catch(function(reason) {
+ ok(false, "unexpected error = " + reason.message);
+ })
+ .then(test.next.bind(test));
}
- ]);
+ ]]);
test.chain.append(flowtest);
test.run();
});
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInHaveLocalOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInHaveLocalOffer.html
@@ -1,34 +1,43 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "784519",
title: "setLocalDescription (answer) in 'have-local-offer'"
});
-runNetworkTest(function () {
- var test = new PeerConnectionTest();
- test.setMediaConstraints([{audio: true}], [{audio: true}]);
- test.chain.removeAfter("PC_LOCAL_SET_LOCAL_DESCRIPTION");
+ var test;
+ runNetworkTest(function () {
+ test = new PeerConnectionTest();
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.chain.removeAfter("PC_LOCAL_SET_LOCAL_DESCRIPTION");
- test.chain.append([
- function PC_LOCAL_SET_LOCAL_ANSWER(test) {
- test.pcLocal._latest_offer.type = "answer";
- return test.pcLocal.setLocalDescriptionAndFail(test.pcLocal._latest_offer)
- .then(err => {
- is(err.name, "InvalidStateError", "Error is InvalidStateError");
- });
- }
- ]);
+ test.chain.append([[
+ "PC_LOCAL_SET_LOCAL_ANSWER",
+ function (test) {
+ test.pcLocal._latest_offer.type="answer";
+ test.pcLocal.setLocalDescriptionAndFail(test.pcLocal._latest_offer,
+ function(err) {
+ is(err.name, "InvalidStateError", "Error is InvalidStateError");
+ test.next();
+ } );
+ }
+ ]]);
- test.run();
-});
+ test.run();
+ });
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInStable.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInStable.html
@@ -1,34 +1,43 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "784519",
title: "setLocalDescription (answer) in 'stable'"
});
-runNetworkTest(function () {
- var test = new PeerConnectionTest();
- test.setMediaConstraints([{audio: true}], [{audio: true}]);
- test.chain.removeAfter("PC_LOCAL_CREATE_OFFER");
+ var test;
+ runNetworkTest(function () {
+ test = new PeerConnectionTest();
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.chain.removeAfter("PC_LOCAL_CREATE_OFFER");
- test.chain.append([
- function PC_LOCAL_SET_LOCAL_ANSWER(test) {
- test.pcLocal._latest_offer.type = "answer";
- return test.pcLocal.setLocalDescriptionAndFail(test.pcLocal._latest_offer)
- .then(err => {
- is(err.name, "InvalidStateError", "Error is InvalidStateError");
- });
- }
- ]);
+ test.chain.append([[
+ "PC_LOCAL_SET_LOCAL_ANSWER",
+ function (test) {
+ test.pcLocal._latest_offer.type="answer";
+ test.pcLocal.setLocalDescriptionAndFail(test.pcLocal._latest_offer,
+ function(err) {
+ is(err.name, "InvalidStateError", "Error is InvalidStateError");
+ test.next();
+ } );
+ }
+ ]]);
- test.run();
-});
+ test.run();
+ });
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_setLocalOfferInHaveRemoteOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setLocalOfferInHaveRemoteOffer.html
@@ -1,33 +1,42 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "784519",
title: "setLocalDescription (offer) in 'have-remote-offer'"
});
-runNetworkTest(function () {
- var test = new PeerConnectionTest();
- test.setMediaConstraints([{audio: true}], [{audio: true}]);
- test.chain.removeAfter("PC_REMOTE_SET_REMOTE_DESCRIPTION");
+ var test;
+ runNetworkTest(function () {
+ test = new PeerConnectionTest();
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.chain.removeAfter("PC_REMOTE_SET_REMOTE_DESCRIPTION");
- test.chain.append([
- function PC_REMOTE_SET_LOCAL_OFFER(test) {
- test.pcRemote.setLocalDescriptionAndFail(test.pcLocal._latest_offer)
- .then(err => {
- is(err.name, "InvalidStateError", "Error is InvalidStateError");
- });
- }
- ]);
+ test.chain.append([[
+ "PC_REMOTE_SET_LOCAL_OFFER",
+ function (test) {
+ test.pcRemote.setLocalDescriptionAndFail(test.pcLocal._latest_offer,
+ function(err) {
+ is(err.name, "InvalidStateError", "Error is InvalidStateError");
+ test.next();
+ } );
+ }
+ ]]);
- test.run();
-});
+ test.run();
+ });
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html
@@ -1,34 +1,43 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "784519",
title: "setRemoteDescription (answer) in 'have-remote-offer'"
});
-runNetworkTest(function () {
- var test = new PeerConnectionTest();
- test.setMediaConstraints([{audio: true}], [{audio: true}]);
- test.chain.removeAfter("PC_REMOTE_SET_REMOTE_DESCRIPTION");
+ var test;
+ runNetworkTest(function () {
+ test = new PeerConnectionTest();
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.chain.removeAfter("PC_REMOTE_SET_REMOTE_DESCRIPTION");
- test.chain.append([
- function PC_REMOTE_SET_REMOTE_ANSWER(test) {
- test.pcLocal._latest_offer.type = "answer";
- test.pcRemote._pc.setRemoteDescription(test.pcLocal._latest_offer)
- .then(generateErrorCallback('setRemoteDescription should fail'),
- err =>
- is(err.name, "InvalidStateError", "Error is InvalidStateError"));
- }
- ]);
+ test.chain.append([[
+ "PC_REMOTE_SET_REMOTE_ANSWER",
+ function (test) {
+ test.pcLocal._latest_offer.type="answer";
+ test.pcRemote.setRemoteDescriptionAndFail(test.pcLocal._latest_offer,
+ function(err) {
+ is(err.name, "InvalidStateError", "Error is InvalidStateError");
+ test.next();
+ } );
+ }
+ ]]);
- test.run();
-});
+ test.run();
+ });
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInStable.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInStable.html
@@ -1,34 +1,43 @@
<!DOCTYPE HTML>
<html>
<head>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="head.js"></script>
+ <script type="application/javascript" src="mediaStreamPlayback.js"></script>
<script type="application/javascript" src="pc.js"></script>
+ <script type="application/javascript" src="templates.js"></script>
+ <script type="application/javascript" src="turnConfig.js"></script>
</head>
<body>
<pre id="test">
<script type="application/javascript">
createHTML({
bug: "784519",
title: "setRemoteDescription (answer) in 'stable'"
});
-runNetworkTest(function () {
- var test = new PeerConnectionTest();
- test.setMediaConstraints([{audio: true}], [{audio: true}]);
- test.chain.removeAfter("PC_LOCAL_CREATE_OFFER");
+ var test;
+ runNetworkTest(function () {
+ test = new PeerConnectionTest();
+ test.setMediaConstraints([{audio: true}], [{audio: true}]);
+ test.chain.removeAfter("PC_LOCAL_CREATE_OFFER");
- test.chain.append([
- function PC_LOCAL_SET_REMOTE_ANSWER(test) {
- test.pcLocal._latest_offer.type = "answer";
- test.pcLocal._pc.setRemoteDescription(test.pcLocal._latest_offer)
- .then(generateErrorCallback('setRemoteDescription should fail'),
- err =>
- is(err.name, "InvalidStateError", "Error is InvalidStateError"));
- }
- ]);
+ test.chain.append([[
+ "PC_LOCAL_SET_REMOTE_ANSWER",
+ function (test) {
+ test.pcLocal._latest_offer.type="answer";
+ test.pcLocal.setRemoteDescriptionAndFail(test.pcLocal._latest_offer,
+ function(err) {
+ is(err.name, "InvalidStateError", "Error is InvalidStateError");
+ test.next();
+ } );
+ }
+ ]]);
- test.run();
-});
+ test.run();
+ });
</script>
</pre>
</body>
</html>
--- a/dom/media/tests/mochitest/test_peerConne