Bug 1119593 - Aggressively removing boilerplate on tests, r=drno, a=testonly
authorMartin Thomson <martin.thomson@gmail.com>
Sat, 21 Feb 2015 10:15:05 +1300
changeset 249897 02405fe4e525fcf652c4e68ad4819ed5521fd4ab
parent 249896 75fda1c812091da1b0832ccca088efea77fcacdd
child 249898 b80b63eb2878153cdebc878e721f15bb70af401c
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrno, testonly
bugs1119593, 825703
milestone37.0a2
Bug 1119593 - Aggressively removing boilerplate on tests, r=drno, a=testonly Conflicts: dom/media/tests/mochitest/test_getUserMedia_exceptions.html Conflicts: dom/media/tests/mochitest/test_peerConnection_bug825703.html
dom/media/tests/mochitest/head.js
dom/media/tests/mochitest/identity/identityevent.js
dom/media/tests/mochitest/identity/test_getIdentityAssertion.html
dom/media/tests/mochitest/identity/test_peerConnection_peerIdentity.html
dom/media/tests/mochitest/identity/test_setIdentityProvider.html
dom/media/tests/mochitest/identity/test_setIdentityProviderWithErrors.html
dom/media/tests/mochitest/mediaStreamPlayback.js
dom/media/tests/mochitest/mochitest.ini
dom/media/tests/mochitest/network.js
dom/media/tests/mochitest/pc.js
dom/media/tests/mochitest/test_dataChannel_basicAudio.html
dom/media/tests/mochitest/test_dataChannel_basicAudioVideo.html
dom/media/tests/mochitest/test_dataChannel_basicAudioVideoCombined.html
dom/media/tests/mochitest/test_dataChannel_basicAudioVideoNoBundle.html
dom/media/tests/mochitest/test_dataChannel_basicDataOnly.html
dom/media/tests/mochitest/test_dataChannel_basicVideo.html
dom/media/tests/mochitest/test_dataChannel_bug1013809.html
dom/media/tests/mochitest/test_dataChannel_noOffer.html
dom/media/tests/mochitest/test_getUserMedia_basicAudio.html
dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
dom/media/tests/mochitest/test_getUserMedia_basicVideo.html
dom/media/tests/mochitest/test_getUserMedia_basicVideoAudio.html
dom/media/tests/mochitest/test_getUserMedia_basicWindowshare.html
dom/media/tests/mochitest/test_getUserMedia_callbacks.html
dom/media/tests/mochitest/test_getUserMedia_constraints.html
dom/media/tests/mochitest/test_getUserMedia_constraints_mobile.html
dom/media/tests/mochitest/test_getUserMedia_exceptions.html
dom/media/tests/mochitest/test_getUserMedia_gumWithinGum.html
dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
dom/media/tests/mochitest/test_getUserMedia_playAudioTwice.html
dom/media/tests/mochitest/test_getUserMedia_playVideoAudioTwice.html
dom/media/tests/mochitest/test_getUserMedia_playVideoTwice.html
dom/media/tests/mochitest/test_getUserMedia_stopAudioStream.html
dom/media/tests/mochitest/test_getUserMedia_stopAudioStreamWithFollowupAudio.html
dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStream.html
dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html
dom/media/tests/mochitest/test_getUserMedia_stopVideoStream.html
dom/media/tests/mochitest/test_getUserMedia_stopVideoStreamWithFollowupVideo.html
dom/media/tests/mochitest/test_peerConnection_addCandidateInHaveLocalOffer.html
dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html
dom/media/tests/mochitest/test_peerConnection_basicAudio.html
dom/media/tests/mochitest/test_peerConnection_basicAudioVideo.html
dom/media/tests/mochitest/test_peerConnection_basicAudioVideoCombined.html
dom/media/tests/mochitest/test_peerConnection_basicAudioVideoCombined_long.html
dom/media/tests/mochitest/test_peerConnection_basicAudioVideoNoBundle.html
dom/media/tests/mochitest/test_peerConnection_basicAudio_long.html
dom/media/tests/mochitest/test_peerConnection_basicH264Video.html
dom/media/tests/mochitest/test_peerConnection_basicScreenshare.html
dom/media/tests/mochitest/test_peerConnection_basicVideo.html
dom/media/tests/mochitest/test_peerConnection_basicVideo_long.html
dom/media/tests/mochitest/test_peerConnection_basicWindowshare.html
dom/media/tests/mochitest/test_peerConnection_bug1013809.html
dom/media/tests/mochitest/test_peerConnection_bug1042791.html
dom/media/tests/mochitest/test_peerConnection_bug822674.html
dom/media/tests/mochitest/test_peerConnection_bug825703.html
dom/media/tests/mochitest/test_peerConnection_bug827843.html
dom/media/tests/mochitest/test_peerConnection_bug834153.html
dom/media/tests/mochitest/test_peerConnection_callbacks.html
dom/media/tests/mochitest/test_peerConnection_capturedVideo.html
dom/media/tests/mochitest/test_peerConnection_close.html
dom/media/tests/mochitest/test_peerConnection_errorCallbacks.html
dom/media/tests/mochitest/test_peerConnection_noTrickleAnswer.html
dom/media/tests/mochitest/test_peerConnection_noTrickleOffer.html
dom/media/tests/mochitest/test_peerConnection_noTrickleOfferAnswer.html
dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
dom/media/tests/mochitest/test_peerConnection_promiseSendOnly.html
dom/media/tests/mochitest/test_peerConnection_replaceTrack.html
dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInHaveLocalOffer.html
dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInStable.html
dom/media/tests/mochitest/test_peerConnection_setLocalOfferInHaveRemoteOffer.html
dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html
dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInStable.html
dom/media/tests/mochitest/test_peerConnection_setRemoteOfferInHaveLocalOffer.html
dom/media/tests/mochitest/test_peerConnection_syncSetDescription.html
dom/media/tests/mochitest/test_peerConnection_throwInCallbacks.html
dom/media/tests/mochitest/test_peerConnection_toJSON.html
dom/media/tests/mochitest/test_peerConnection_twoAudioStreams.html
dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreams.html
dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreamsCombined.html
dom/media/tests/mochitest/test_peerConnection_twoVideoStreams.html
dom/media/tests/mochitest/test_zmedia_cleanup.html
--- a/dom/media/tests/mochitest/head.js
+++ b/dom/media/tests/mochitest/head.js
@@ -1,17 +1,16 @@
 /* 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');
@@ -29,37 +28,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 createHTML(meta) {
+function realCreateHTML(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.setAttribute('target', '_blank');
-
+  anchor.textContent = meta.title;
   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');
@@ -78,24 +77,26 @@ function createHTML(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
@@ -117,17 +118,17 @@ function getUserMedia(constraints) {
 /**
  * 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) {
+function realRunTest(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],
@@ -164,20 +165,20 @@ function runTest(aCallback) {
  *
  * @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');
   }
 }
 
@@ -507,17 +508,25 @@ CommandChain.prototype = {
 };
 
 
 function IsMacOSX10_6orOlder() {
     var is106orOlder = false;
 
     if (navigator.platform.indexOf("Mac") == 0) {
         var version = Cc["@mozilla.org/system-info;1"]
-                        .getService(SpecialPowers.Ci.nsIPropertyBag2)
+                        .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.
         is106orOlder = (parseFloat(version) < 11.0);
     }
     return is106orOlder;
 }
+
+(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 = function(target) {
+  g.trapIdentityEvents = 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,22 +1,20 @@
 <!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">var scriptRelativePath = "../";</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"
+    title: "getIdentityAssertion Tests",
+    bug: "942367"
   });
 
 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 + "'");
--- a/dom/media/tests/mochitest/identity/test_peerConnection_peerIdentity.html
+++ b/dom/media/tests/mochitest/identity/test_peerConnection_peerIdentity.html
@@ -1,26 +1,21 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-  <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">var scriptRelativePath = "../";</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"
+    title: "setIdentityProvider leads to peerIdentity and assertions in SDP",
+    bug: "942367"
   });
 
 var test;
 function theTest() {
   var id1 = 'someone@test1.example.com';
   var id2 = 'someone@test2.example.com';
   test = new PeerConnectionTest({
     config_local: {
--- a/dom/media/tests/mochitest/identity/test_setIdentityProvider.html
+++ b/dom/media/tests/mochitest/identity/test_setIdentityProvider.html
@@ -1,24 +1,21 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-  <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">var scriptRelativePath = "../";</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"
+    title: "setIdentityProvider leads to peerIdentity and assertions in SDP",
+    bug: "942367"
   });
 
 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");
@@ -87,14 +84,12 @@ function theTest() {
       ok(test.pcRemote.remoteDescription.sdp.contains("a=identity"),
          "a=identity is in the remote copy of the answer");
     }
   ]);
   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,28 +1,25 @@
 <!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">var scriptRelativePath = "../";</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"
+    title: "Identity Provider returning errors is handled correctly",
+    bug: "942367"
   });
 
-var test;
 runNetworkTest(function () {
-  test = new PeerConnectionTest();
+  var 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);
--- a/dom/media/tests/mochitest/mediaStreamPlayback.js
+++ b/dom/media/tests/mochitest/mediaStreamPlayback.js
@@ -208,8 +208,32 @@ LocalMediaStreamPlayback.prototype = Obj
         // If ended doesn't fire in enough time, then we fail the test
         setTimeout(() => {
           reject(new Error("ended event never fired"));
         }, ENDED_TIMEOUT_LENGTH);
       });
     }
   }
 });
+
+function runTest(f) {
+  // Use addEventListener to avoid SimpleTest hacking an .onload assignment
+  window.addEventListener('load', () => {
+    SimpleTest.waitForExplicitFinish();
+    realRunTest(f);
+  });
+}
+
+function createHTML(options) {
+  window.addEventListener('load', () => {
+    realCreateHTML(options);
+  });
+}
+
+[
+  "/tests/SimpleTest/SimpleTest.js",
+  "head.js"
+].forEach(script => {
+  console.log('msp');
+  var el = document.createElement("script");
+  el.src = script;
+  document.head.appendChild(el);
+});
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -1,16 +1,17 @@
 [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]
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/network.js
@@ -0,0 +1,121 @@
+/* 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(() => SimpleTest.finish());
+}
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -117,138 +117,25 @@ 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() {
-      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(() => SimpleTest.finish());
-}
-
-/**
  * A wrapper around runTest() which handles B2G network setup and teardown
  */
 function runNetworkTest(testFunction) {
-  SimpleTest.waitForExplicitFinish();
-  return startNetworkAndTest()
-    .then(() => runTest(testFunction));
+  // Use addEventListener to avoid SimpleTest hacking an .onload assignment
+  window.addEventListener('load', () => {
+    SimpleTest.waitForExplicitFinish();
+    startNetworkAndTest()
+      .then(() => realRunTest(testFunction));
+  });
 }
 
 /**
  * This class handles tests for peer connections.
  *
  * @constructor
  * @param {object} [options={}]
  *        Optional options for the peer connection test
@@ -1893,8 +1780,31 @@ PeerConnectionWrapper.prototype = {
    * Returns the string representation of the class
    *
    * @returns {String} The string representation
    */
   toString : function() {
     return "PeerConnectionWrapper (" + this.label + ")";
   }
 };
+
+function createHTML(options) {
+  window.addEventListener('load', () => {
+    realCreateHTML(options);
+  });
+}
+
+[
+  "/tests/SimpleTest/SimpleTest.js",
+  "head.js",
+  "templates.js",
+  "turnConfig.js",
+  "dataChannel.js",
+  "network.js"
+].forEach(script => {
+  var el = document.createElement("script");
+  if (typeof scriptRelativePath === 'string' && script.charAt(0) !== "/") {
+    el.src = scriptRelativePath + script;
+  } else {
+    el.src = script;
+  }
+  document.head.appendChild(el);
+});
--- a/dom/media/tests/mochitest/test_dataChannel_basicAudio.html
+++ b/dom/media/tests/mochitest/test_dataChannel_basicAudio.html
@@ -1,18 +1,12 @@
 <!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,18 +1,12 @@
 <!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,18 +1,12 @@
 <!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,18 +1,12 @@
 <!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"
   });
--- a/dom/media/tests/mochitest/test_dataChannel_basicDataOnly.html
+++ b/dom/media/tests/mochitest/test_dataChannel_basicDataOnly.html
@@ -1,18 +1,12 @@
 <!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,18 +1,12 @@
 <!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,18 +1,12 @@
 <!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,14 +1,11 @@
 <!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,35 +1,23 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=781534
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testAudio');
+    var testAudio = createMediaElement('audio', 'testAudio');
     var constraints = {audio: true};
 
     getUserMedia(constraints).then(aStream => {
       checkMediaStreamTracks(constraints, aStream);
 
       var playback = new LocalMediaStreamPlayback(testAudio, aStream);
       return playback.playMedia(false);
     }).then(() => SimpleTest.finish(), generateErrorCallback());
--- a/dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicScreenshare.html
@@ -1,41 +1,32 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=983504
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testVideo');
+    var testVideo = createMediaElement('video', 'testVideo');
     var constraints = {
       video: {
          mozMediaSource: "screen",
          mediaSource: "screen"
       },
       fake: false
     };
 
--- a/dom/media/tests/mochitest/test_getUserMedia_basicVideo.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicVideo.html
@@ -1,35 +1,26 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=781534
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testVideo');
+    var testVideo = createMediaElement('video', 'testVideo');
     var constraints = {video: true};
 
     getUserMedia(constraints).then(aStream => {
       checkMediaStreamTracks(constraints, aStream);
 
       var playback = new LocalMediaStreamPlayback(testVideo, aStream);
       return playback.playMedia(false);
     }).then(() => SimpleTest.finish(), generateErrorCallback());
--- a/dom/media/tests/mochitest/test_getUserMedia_basicVideoAudio.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicVideoAudio.html
@@ -1,35 +1,26 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=781534
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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">
+<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 = document.getElementById('testVideoAudio');
+    var testVideoAudio = createMediaElement('video', 'testVideoAudio');
     var constraints = {video: true, audio: true};
 
     getUserMedia(constraints).then(aStream => {
       checkMediaStreamTracks(constraints, aStream);
 
       var playback = new LocalMediaStreamPlayback(testVideoAudio, aStream);
       return playback.playMedia(false);
     }).then(() => SimpleTest.finish(), generateErrorCallback());
--- a/dom/media/tests/mochitest/test_getUserMedia_basicWindowshare.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_basicWindowshare.html
@@ -1,41 +1,32 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=983504
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testVideo');
+    var testVideo = createMediaElement('video', 'testVideo');
     var constraints = {
       video: {
          mozMediaSource: "window",
          mediaSource: "window"
       },
       fake: false
     };
 
--- a/dom/media/tests/mochitest/test_getUserMedia_callbacks.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_callbacks.html
@@ -1,34 +1,25 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=781534
--->
 <head>
-  <meta charset="utf-8">
-  <title>navigator.mozGetUserMedia Callback 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">navigator.mozGetUserMedia Callback 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: "navigator.mozGetUserMedia Callback Test",
+    bug: "1119593"
+  });
   /**
    * Check that the old fashioned callback-based function works.
    */
   runTest(function () {
-    var testAudio = document.getElementById('testAudio');
+    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)
--- a/dom/media/tests/mochitest/test_getUserMedia_constraints.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_constraints.html
@@ -1,29 +1,18 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=882145
--->
 <head>
-  <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>
+  <script src="mediaStreamPlayback.js"></script>
+  <script 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,29 +1,18 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=882145
--->
 <head>
-  <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>
+  <script src="mediaStreamPlayback.js"></script>
+  <script 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_exceptions.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_exceptions.html
@@ -66,29 +66,25 @@ function unexpectedCall(obj) {
 }
 
 /**
  * Starts the test run by running through each exception
  * test by verifying that the correct exception type specified
  * is thrown on the mozGetUserMedia call with the parameters
  * specified.
  */
-runTest(function () {
-  exceptionTests.forEach(function (test) {
-    var exception = false;
-    try {
-      navigator.mozGetUserMedia.apply(navigator, test.params);
-    } catch (e) {
-      exception = (e.message === test.error);
-      if(!exception) {
-        info(e.message);
-      }
+exceptionTests.forEach(function (test) {
+  var exception = false;
+  try {
+    navigator.mozGetUserMedia.apply(navigator, test.params);
+  } catch (e) {
+    exception = (e.message === test.error);
+    if(!exception) {
+      info(e.message);
     }
-    ok(exception, "Exception for " + test.message);
-  });
-
-  SimpleTest.finish();
+  }
+  ok(exception, "Exception for " + test.message);
 });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_gumWithinGum.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_gumWithinGum.html
@@ -1,50 +1,37 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testVideo');
-        var videoStreamPlayback = new LocalMediaStreamPlayback(testVideo,
-                                                               videoStream);
+        var testVideo = createMediaElement('video', 'testVideo');
+        var videoPlayback = new LocalMediaStreamPlayback(testVideo,
+                                                         videoStream);
 
-        return videoStreamPlayback.playMedia(false)
+        return videoPlayback.playMedia(false)
           .then(() => getUserMedia({audio: true}))
           .then(audioStream => {
-            var testAudio = document.getElementById('testAudio');
-            var audioStreamPlayback = new LocalMediaStreamPlayback(testAudio,
-                                                                   audioStream);
+            var testAudio = createMediaElement('audio', 'testAudio');
+            var audioPlayback = new LocalMediaStreamPlayback(testAudio,
+                                                             audioStream);
 
-            return audioStreamPlayback.playMedia(false)
+            return audioPlayback.playMedia(false)
               .then(() => audioStream.stop());
           })
           .then(() => videoStream.stop());
       })
       .then(() => SimpleTest.finish(), generateErrorCallback());
   });
 
 </script>
--- a/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_peerIdentity.html
@@ -1,29 +1,18 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=942367
--->
 <head>
-  <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="mediaStreamPlayback.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,39 +1,26 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testAudio');
-      var audioStreamPlayback = new LocalMediaStreamPlayback(testAudio,
-        audioStream);
+      var testAudio = createMediaElement('audio', 'testAudio');
+      var playback = new LocalMediaStreamPlayback(testAudio, audioStream);
 
-      return audioStreamPlayback.playMedia(false)
-        .then(() => audioStreamPlayback.playMedia(true))
+      return playback.playMedia(false)
+        .then(() => playback.playMedia(true))
         .then(() => audioStream.stop());
     }).then(() => SimpleTest.finish(), generateErrorCallback());
   });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_playVideoAudioTwice.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_playVideoAudioTwice.html
@@ -1,39 +1,27 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testVideo');
-      var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
+      var testVideo = createMediaElement('video', 'testVideo');
+      var playback = new LocalMediaStreamPlayback(testVideo, stream);
 
-      return streamPlayback.playMedia(false)
-        .then(() => streamPlayback.playMedia(true))
+      return playback.playMedia(false)
+        .then(() => playback.playMedia(true))
         .then(() => stream.stop());
     }).then(() => SimpleTest.finish(), generateErrorCallback());
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_playVideoTwice.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_playVideoTwice.html
@@ -1,35 +1,23 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testVideo');
+      var testVideo = createMediaElement('video', 'testVideo');
       var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
 
       return streamPlayback.playMedia(false)
         .then(() => streamPlayback.playMedia(true))
         .then(() => stream.stop());
     }).then(() => SimpleTest.finish(), generateErrorCallback());
   });
 
--- a/dom/media/tests/mochitest/test_getUserMedia_stopAudioStream.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopAudioStream.html
@@ -1,37 +1,25 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testAudio');
+        var testAudio = createMediaElement('audio', 'testAudio');
         var streamPlayback = new LocalMediaStreamPlayback(testAudio, stream);
 
         return streamPlayback.playMediaWithStreamStop(false);
       })
       .then(() => SimpleTest.finish(), generateErrorCallback());
   });
 
 </script>
--- a/dom/media/tests/mochitest/test_getUserMedia_stopAudioStreamWithFollowupAudio.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopAudioStreamWithFollowupAudio.html
@@ -1,38 +1,26 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testAudio');
+        var testAudio = createMediaElement('audio', 'testAudio');
         var streamPlayback = new LocalMediaStreamPlayback(testAudio, firstStream);
 
         return streamPlayback.playMediaWithStreamStop(false)
           .then(() => getUserMedia({audio: true}))
           .then(secondStream => {
             streamPlayback.mediaStream = secondStream;
 
             return streamPlayback.playMedia(false)
--- a/dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStream.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStream.html
@@ -1,41 +1,29 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testVideo');
-        var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
+        var testVideo = createMediaElement('video', 'testVideo');
+        var playback = new LocalMediaStreamPlayback(testVideo, stream);
 
-        return streamPlayback.playMediaWithStreamStop(false);
+        return playback.playMediaWithStreamStop(false);
       })
       .then(() => SimpleTest.finish(), generateErrorCallback());
   });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopVideoAudioStreamWithFollowupVideoAudio.html
@@ -1,38 +1,29 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 = document.getElementById('testVideo');
+        var testVideo = createMediaElement('video', 'testVideo');
         var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
 
         return streamPlayback.playMediaWithStreamStop(false)
           .then(() => getUserMedia({video: true, audio: true}))
           .then(secondStream => {
             streamPlayback.mediaStream = secondStream;
 
             return streamPlayback.playMedia(false)
--- a/dom/media/tests/mochitest/test_getUserMedia_stopVideoStream.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopVideoStream.html
@@ -1,38 +1,26 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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">getUserMedia 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 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.
    */
   runTest(function () {
     getUserMedia({video: true})
       .then(stream => {
-        var testVideo = document.getElementById('testVideo');
+        var testVideo = createMediaElement('video', 'testVideo');
         var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
 
         return streamPlayback.playMediaWithStreamStop(false);
       })
       .then(() => SimpleTest.finish(), generateErrorCallback());
   });
 
 </script>
--- a/dom/media/tests/mochitest/test_getUserMedia_stopVideoStreamWithFollowupVideo.html
+++ b/dom/media/tests/mochitest/test_getUserMedia_stopVideoStreamWithFollowupVideo.html
@@ -1,38 +1,26 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=822109
--->
 <head>
-  <meta charset="utf-8">
-  <title>getUserMedia 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>
+  <script src="mediaStreamPlayback.js"></script>
 </head>
 <body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822109">getUserMedia 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.
    */
   runTest(function () {
     getUserMedia({video: true})
       .then(stream => {
-        var testVideo = document.getElementById('testVideo');
+        var testVideo = createMediaElement('video', 'testVideo');
         var streamPlayback = new LocalMediaStreamPlayback(testVideo, stream);
 
         return streamPlayback.playMediaWithStreamStop(false)
           .then(() => getUserMedia({video: true}))
           .then(secondStream => {
             streamPlayback.mediaStream = secondStream;
 
             return streamPlayback.playMedia(false)
--- a/dom/media/tests/mochitest/test_peerConnection_addCandidateInHaveLocalOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_addCandidateInHaveLocalOffer.html
@@ -1,18 +1,12 @@
 <!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'"
   });
--- a/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html
+++ b/dom/media/tests/mochitest/test_peerConnection_addSecondAudioStream.html
@@ -1,18 +1,12 @@
 <!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"
   });
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudio.html
@@ -1,18 +1,12 @@
 <!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,18 +1,12 @@
 <!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,18 +1,12 @@
 <!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,44 +1,37 @@
 <!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;
-  runTest(function (options) {
+  runNetworkTest(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,32 +1,23 @@
 <!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"
   });
 
-  SimpleTest.requestFlakyTimeout("WebRTC is full of inherent timeouts");
-
-  var test;
-  runNetworkTest(function (options) {
-    test = new PeerConnectionTest(options);
+  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,
             ""
           );
--- a/dom/media/tests/mochitest/test_peerConnection_basicAudio_long.html
+++ b/dom/media/tests/mochitest/test_peerConnection_basicAudio_long.html
@@ -1,24 +1,18 @@
 <!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,18 +1,12 @@
 <!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,18 +1,12 @@
 <!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,18 +1,12 @@
 <!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,24 +1,18 @@
 <!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,18 +1,12 @@
 <!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,17 +1,12 @@
 <!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,18 +1,12 @@
 <!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_bug822674.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug822674.html
@@ -1,14 +1,11 @@
 <!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,91 +1,91 @@
 <!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(() => {
+<!DOCTYPE HTML>
+<html>
+<head>
   <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"
   });
 
-  makePC = function (config, expect_success) {
-      var exception = null;
-      var pc = null;
-
-      try {
-          pc = new mozRTCPeerConnection(config);
-      } catch (e) {
-          exception = e;
-      }
-      if (pc !== null) {
-        pc.close();
-      }
-      pc = null
-
-      if (expect_success) {
-          ok(!exception, "mozRTCPeerConnection(" +
-             JSON.stringify(config) + ") succeeds");
-      } else {
-          ok(exception, "mozRTCPeerConnection(" +
-             JSON.stringify(config) + ") throws");
-      }
-  }
+  var makePC = (config, expectSuccess) => {
+    var exception;
+    try {
+      new mozRTCPeerConnection(config).close();
+    } catch (e) {
+      exception = e;
+    }
+    ok(expectSuccess ? !exception : !!exception,
+       "mozRTCPeerConnection(" + JSON.stringify(config) + ")");
+  };
 
   // This is a test of the iceServers parsing code + readable errors
-
-  runNetworkTest(function () {
+  runNetworkTest(() => {
     var pcs = null;
     var exception = null;
     var config;
 
-    try {
-      pcs = new mozRTCPeerConnection();
-    } catch (e) {
-      exception = e;
-    }
-    ok(!exception, "mozRTCPeerConnection() succeeds");
-    if (pcs !== null) {
-      pcs.close();
-    }
-    pcs = null;
-    exception = null;
+    makePC(undefined, true);
 
     makePC(1, false);
 
     makePC({}, true);
 
     makePC({ iceServers: [] }, true);
 
     makePC({ iceServers: [{ url:"" }] }, false);
 
     makePC({ iceServers: [
-                { url:"stun:127.0.0.1" },
-                { url:"stuns:localhost", foo:"" },
-                { url:"turn:[::1]:3478", username:"p", credential:"p" },
-                { url:"turns:localhost:3478?transport=udp", username:"p", credential:"p" }
-                ]}, true);
+      { url:"stun:127.0.0.1" },
+      { url:"stuns:localhost", foo:"" },
+      { url:"turn:[::1]:3478", username:"p", credential:"p" },
+      { url:"turns:localhost:3478?transport=udp", username:"p", credential:"p" }
+    ]}, true);
 
     makePC({ iceServers: [{ url:"turns:localhost:3478", username:"p" }] }, false);
 
     makePC({ iceServers: [{ url:"turns:localhost:3478", credential:"p" }] }, false);
 
     makePC({ iceServers: [{ url:"http:0.0.0.0" }] }, false);
     try {
-        pcs = new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] });
+      pcs = new mozRTCPeerConnection({ iceServers: [{ url:"http:0.0.0.0" }] });
     } catch (e) {
-        ok(e.message.indexOf("http") > 0,
-           "mozRTCPeerConnection() constructor has readable exceptions");
+      ok(e.message.indexOf("http") > 0,
+         "mozRTCPeerConnection() constructor has readable exceptions");
     }
     if (pcs !== null) {
       pcs.close();
     }
     pcs = null;
 
     networkTestFinished();
   });
--- a/dom/media/tests/mochitest/test_peerConnection_bug827843.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug827843.html
@@ -1,17 +1,12 @@
 <!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"
   });
--- a/dom/media/tests/mochitest/test_peerConnection_bug834153.html
+++ b/dom/media/tests/mochitest/test_peerConnection_bug834153.html
@@ -1,14 +1,11 @@
 <!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"
--- a/dom/media/tests/mochitest/test_peerConnection_callbacks.html
+++ b/dom/media/tests/mochitest/test_peerConnection_callbacks.html
@@ -1,31 +1,24 @@
 <!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({
     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.
-var waituntil = func => new Promise(resolve => {
-  var inter = setInterval(() => func() && resolve(clearInterval(inter)), 200);
-});
 
 // 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);
     }
@@ -52,39 +45,42 @@ pc1.onicecandidate = e => {
     .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);
   };
 });
-var canPlayThrough = new Promise(resolve => v2.canplaythrough = resolve);
 
 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(() => 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))
--- a/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_capturedVideo.html
@@ -1,18 +1,12 @@
 <!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",
--- a/dom/media/tests/mochitest/test_peerConnection_close.html
+++ b/dom/media/tests/mochitest/test_peerConnection_close.html
@@ -1,14 +1,11 @@
 <!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,14 +1,11 @@
 <!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,19 +1,13 @@
 <!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,19 +1,13 @@
 <!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,19 +1,13 @@
 <!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,17 +1,12 @@
 <!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,17 +1,12 @@
 <!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,17 +1,12 @@
 <!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,62 +1,57 @@
 <!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,18 +1,12 @@
 <!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
--- a/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInHaveLocalOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInHaveLocalOffer.html
@@ -1,30 +1,23 @@
 <!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'"
   });
 
-var test;
 runNetworkTest(function () {
-  test = new PeerConnectionTest();
+  var 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 => {
--- a/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInStable.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInStable.html
@@ -1,30 +1,23 @@
 <!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'"
   });
 
-var test;
 runNetworkTest(function () {
-  test = new PeerConnectionTest();
+  var 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 => {
--- a/dom/media/tests/mochitest/test_peerConnection_setLocalOfferInHaveRemoteOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setLocalOfferInHaveRemoteOffer.html
@@ -1,30 +1,23 @@
 <!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'"
   });
 
-var test;
 runNetworkTest(function () {
-  test = new PeerConnectionTest();
+  var 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");
--- a/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html
@@ -1,30 +1,23 @@
 <!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'"
   });
 
-var test;
 runNetworkTest(function () {
-  test = new PeerConnectionTest();
+  var 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'),
--- a/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInStable.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInStable.html
@@ -1,30 +1,23 @@
 <!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'"
   });
 
-var test;
 runNetworkTest(function () {
-  test = new PeerConnectionTest();
+  var 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'),
--- a/dom/media/tests/mochitest/test_peerConnection_setRemoteOfferInHaveLocalOffer.html
+++ b/dom/media/tests/mochitest/test_peerConnection_setRemoteOfferInHaveLocalOffer.html
@@ -1,30 +1,23 @@
 <!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 (offer) in 'have-local-offer'"
   });
 
-var test;
 runNetworkTest(function () {
-  test = new PeerConnectionTest();
+  var test = new PeerConnectionTest();
   test.setMediaConstraints([{audio: true}], [{audio: true}]);
   test.chain.removeAfter("PC_LOCAL_SET_LOCAL_DESCRIPTION");
 
   test.chain.append([
     function PC_LOCAL_SET_REMOTE_OFFER(test) {
       test.pcLocal._pc.setRemoteDescription(test.pcLocal._latest_offer)
         .then(generateErrorCallback('setRemoteDescription should fail'),
               err =>
--- a/dom/media/tests/mochitest/test_peerConnection_syncSetDescription.html
+++ b/dom/media/tests/mochitest/test_peerConnection_syncSetDescription.html
@@ -1,18 +1,12 @@
 <!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: "1063971",
     title: "Legacy sync setDescription calls",
     visible: true
--- a/dom/media/tests/mochitest/test_peerConnection_throwInCallbacks.html
+++ b/dom/media/tests/mochitest/test_peerConnection_throwInCallbacks.html
@@ -1,85 +1,79 @@
 <!DOCTYPE HTML>
 <html>
 <head>
-  <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>
 </head>
 <body>
 <pre id="test">
 <script type="application/javascript;version=1.8">
   createHTML({
     bug: "857765",
     title: "Throw in PeerConnection callbacks"
   });
 
+runNetworkTest(function () {
+  function finish() {
+    window.onerror = oldOnError;
+    is(error_count, 7, "Seven expected errors verified.");
+    networkTestFinished();
+  }
+
+  function getFail() {
+    return err => {
+      window.onerror = oldOnError;
+      generateErrorCallback()(err);
+    };
+  }
+
   let error_count = 0;
   let oldOnError = window.onerror;
-  window.onerror = function (errorMsg, url, lineNumber) {
+  window.onerror = (errorMsg, url, lineNumber) => {
     if (errorMsg.indexOf("Expected") == -1) {
       getFail()(errorMsg);
     }
     error_count += 1;
     info("onerror " + error_count + ": " + errorMsg);
     if (error_count == 7) {
       finish();
     }
     throw new Error("window.onerror may throw");
     return false;
   }
 
   let pc0, pc1, pc2;
-
-  runNetworkTest(function () {
-    error_count = 0;
-
-    // Test failure callbacks (limited to 1 for now)
-    pc0 = new mozRTCPeerConnection();
-    pc0.createOffer(getFail(), function(err) {
-      pc1 = new mozRTCPeerConnection();
-      pc2 = new mozRTCPeerConnection();
+  // Test failure callbacks (limited to 1 for now)
+  pc0 = new mozRTCPeerConnection();
+  pc0.createOffer(getFail(), function(err) {
+    pc1 = new mozRTCPeerConnection();
+    pc2 = new mozRTCPeerConnection();
 
-      // Test success callbacks (happy path)
-      navigator.mozGetUserMedia({video:true, fake: true}, function(video1) {
-        pc1.addStream(video1);
-        pc1.createOffer(function(offer) {
-          pc1.setLocalDescription(offer, function() {
-            pc2.setRemoteDescription(offer, function() {
-              pc2.createAnswer(function(answer) {
-                pc2.setLocalDescription(answer, function() {
-                  pc1.setRemoteDescription(answer, function() {
-                    throw new Error("Expected");
-                  }, getFail());
+    // Test success callbacks (happy path)
+    navigator.mozGetUserMedia({video:true, fake: true}, function(video1) {
+      pc1.addStream(video1);
+      pc1.createOffer(function(offer) {
+        pc1.setLocalDescription(offer, function() {
+          pc2.setRemoteDescription(offer, function() {
+            pc2.createAnswer(function(answer) {
+              pc2.setLocalDescription(answer, function() {
+                pc1.setRemoteDescription(answer, function() {
                   throw new Error("Expected");
                 }, getFail());
                 throw new Error("Expected");
               }, getFail());
               throw new Error("Expected");
             }, getFail());
             throw new Error("Expected");
           }, getFail());
           throw new Error("Expected");
         }, getFail());
+        throw new Error("Expected");
       }, getFail());
-      throw new Error("Expected");
-    });
+    }, getFail());
+    throw new Error("Expected");
   });
+});
 
-  function finish() {
-    window.onerror = oldOnError;
-    is(error_count, 7, "Seven expected errors verified.");
-    networkTestFinished();
-  }
-
-  function getFail() {
-    return function (err) {
-      window.onerror = oldOnError;
-      generateErrorCallback()(err);
-    };
-  }
 </script>
 </pre>
 </body>
 </html>
--- a/dom/media/tests/mochitest/test_peerConnection_toJSON.html
+++ b/dom/media/tests/mochitest/test_peerConnection_toJSON.html
@@ -1,19 +1,11 @@
 <!DOCTYPE HTML>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=872377
--->
 <head>
-  <meta charset="utf-8">
-  <title>Test for Bug 872377 and Bug 928304</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="pc.js"></script>
 </head>
 <body>
 <pre id="test">
 <script type="application/javascript">
   createHTML({
     bug: "928304",
     title: "test toJSON() on mozRTCSessionDescription and mozRTCIceCandidate"
--- a/dom/media/tests/mochitest/test_peerConnection_twoAudioStreams.html
+++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioStreams.html
@@ -1,18 +1,12 @@
 <!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: "Multistream: Two audio streams"
   });
--- a/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreams.html
+++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreams.html
@@ -1,18 +1,12 @@
 <!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: "Multistream: Two audio streams, two video streams"
--- a/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreamsCombined.html
+++ b/dom/media/tests/mochitest/test_peerConnection_twoAudioVideoStreamsCombined.html
@@ -1,18 +1,12 @@
 <!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: "Multistream: Two audio/video streams"
--- a/dom/media/tests/mochitest/test_peerConnection_twoVideoStreams.html
+++ b/dom/media/tests/mochitest/test_peerConnection_twoVideoStreams.html
@@ -1,18 +1,12 @@
 <!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: "Multistream: Two video streams"
   });
--- a/dom/media/tests/mochitest/test_zmedia_cleanup.html
+++ b/dom/media/tests/mochitest/test_zmedia_cleanup.html
@@ -1,29 +1,27 @@
 <!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="pc.js"></script>
+    <script src="/tests/SimpleTest/SimpleTest.js"></script>
+    <script src="network.js"></script>
   </head>
 <body>
 <pre id="test">
 <script type="application/javascript">
+
 SimpleTest.waitForExplicitFinish();
 
 if ("nsINetworkInterfaceListService" in SpecialPowers.Ci) {
-  var utils = getNetworkUtils();
-  utils.tearDownNetwork(function() {
-    ok(true, 'Successfully teared down network interface');
-    SimpleTest.finish();
-  }, function() {
-    ok(true, 'Network interface was in down state already');
-    SimpleTest.finish();
-  });
+  getNetworkUtils().tearDownNetwork()
+    .then(() =>
+          ok(true, 'Successfully teared down network interface'),
+          () =>
+          ok(true, 'Network interface was in down state already'))
+    .then(() => SimpleTest.finish());
 } else {
   ok(true, 'No need to cleanup network interface');
   SimpleTest.finish();
 }
 
 </script>
 </pre>
 </body>