Bug 1546655 - Modernize test_streams_element_capture.html. r=jib a=jcristau
authorAndreas Pehrson <apehrson@mozilla.com>
Mon, 27 May 2019 12:32:00 +0000
changeset 536576 18e5f48ade65db5526283fa0c54e769f1e970549
parent 536575 3c9393f08fc69af0b0ba31f1dbba9a02204f6502
child 536577 d68ba2d3844c731135e9fbdf750e727fd8412fea
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjib, jcristau
bugs1546655
milestone68.0
Bug 1546655 - Modernize test_streams_element_capture.html. r=jib a=jcristau This async/await-ifies the test to put checks in logical order. It also, as a drive-by, adds `v.token = token` since this is a cue to the test framework in manifest.js to mozDumpDebugInfo() on the right element after timeout of a token. Differential Revision: https://phabricator.services.mozilla.com/D32114
dom/media/test/test_streams_element_capture.html
--- a/dom/media/test/test_streams_element_capture.html
+++ b/dom/media/test/test_streams_element_capture.html
@@ -4,118 +4,117 @@
   <title>Test that a MediaStream captured from one element plays back in another</title>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
   <script type="text/javascript" src="manifest.js"></script>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
-let manager = new MediaTestManager();
+const manager = new MediaTestManager();
 
 function checkDrawImage(vout, msg) {
-  var canvas = document.createElement("canvas");
-  var ctx = canvas.getContext("2d");
+  const canvas = document.createElement("canvas");
+  const ctx = canvas.getContext("2d");
   ctx.drawImage(vout, 0, 0);
-  var imgData = ctx.getImageData(0, 0, 1, 1);
+  const imgData = ctx.getImageData(0, 0, 1, 1);
   is(imgData.data[3], 255, msg);
 }
 
 function isGreaterThanOrEqualEps(a, b, msg) {
   ok(a >= b, `Got ${a}, expected at least ${b}; ${msg}`);
 }
 
-function startTest(test, token) {
+async function startTest(test, token) {
   manager.started(token);
-  var v = document.createElement('video');
-  var vout = document.createElement('video');
+  const v = document.createElement('video');
+  const vout = document.createElement('video');
 
+  v.token = token;
   v.id = "MediaDecoder";
   vout.id = "MediaStream";
 
-  v.src = test.name;
-  var stream;
-
-  var checkEnded = function() {
-    let duration = test.duration;
-    if (typeof(test.contentDuration) == "number") {
-      duration = test.contentDuration;
-    }
-    if (duration) {
-      isGreaterThanOrEqualEps(vout.currentTime, duration,
-        `${token} current time at end`);
-    }
-    is(vout.readyState, vout.HAVE_CURRENT_DATA,
-      `${token} checking readyState`);
-    ok(vout.ended, `${token} checking playback has ended`);
-    isnot(stream.getTracks().length, 0, `${token} results in some tracks`);
-    if (stream.getVideoTracks().length > 0) {
-      ok(test.type.match(/^video/), `${token} is a video resource`);
-      checkDrawImage(vout, `${token} checking video frame pixel has been drawn`);
-    }
-    vout.remove();
-    removeNodeAndSource(v);
-    manager.finished(token);
-  };
-  Promise.race([
-    Promise.all([
-      new Promise(r => vout.addEventListener("ended", r, {once:true})),
-      new Promise(r => v.addEventListener("ended", r, {once:true})),
-    ]),
-    new Promise((res, rej) => vout.addEventListener("error", rej, {once:true})),
-    new Promise((res, rej) => v.addEventListener("error", rej, {once:true})),
-  ]).then(() => checkEnded(), e => {
-    ok(false, `Error: ${e.target.id} ${token}, ${e.target.error.message}`);
-    manager.finished(token);
-  });
-
   document.body.appendChild(vout);
 
-  var onloadedmetadata = async function (ev) {
-    stream = v.mozCaptureStreamUntilEnded();
-    vout.srcObject = stream;
-    is(vout.srcObject, stream,
-      `${token} set output element .srcObject correctly`);
-    // Wait for the resource fetch algorithm to have run, so that the media
-    // element is hooked up to the MediaStream and ready to go. If we don't do
-    // this, we're not guaranteed to render the very first video frame, which
-    // can make this test fail the drawImage test when a video resource only
-    // contains one frame.
-    await new Promise(r => vout.addEventListener('loadstart', r));
-    v.play();
-    vout.play();
-  }
-
-  v.preload = 'metadata';
-  v.addEventListener('loadedmetadata', onloadedmetadata);
-
   // Log events for debugging.
-  var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
+  const events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata",
                 "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort",
                 "waiting", "pause"];
   function logEvent(e) {
     Log(token, `${e.target.id} got ${e.type}`);
   }
-  events.forEach(function(e) {
+  for (const e of events) {
     v.addEventListener(e, logEvent);
     vout.addEventListener(e, logEvent);
-  });
+  };
+
+  v.src = test.name;
+  v.preload = 'metadata';
+  await new Promise(r => v.onloadedmetadata = r);
+
+  const stream = v.mozCaptureStreamUntilEnded();
+  vout.srcObject = stream;
+  is(vout.srcObject, stream,
+    `${token} set output element .srcObject correctly`);
+  // Wait for the resource fetch algorithm to have run, so that the media
+  // element is hooked up to the MediaStream and ready to go. If we don't do
+  // this, we're not guaranteed to render the very first video frame, which
+  // can make this test fail the drawImage test when a video resource only
+  // contains one frame.
+  await new Promise(r => vout.onloadstart = r);
+  v.play();
+  vout.play();
 
+  await Promise.race([
+    Promise.all([
+      new Promise(r => vout.onended = r),
+      new Promise(r => v.onended = r),
+    ]),
+    new Promise((_, r) => vout.onerror = _ => r(new Error(vout.error.message))),
+    new Promise((_, r) => v.onerror = _ => r(new Error(v.error.message))),
+  ]);
+
+  let duration = test.duration;
+  if (typeof(test.contentDuration) == "number") {
+    duration = test.contentDuration;
+  }
+  if (duration) {
+    isGreaterThanOrEqualEps(vout.currentTime, duration,
+      `${token} current time at end`);
+  }
+  is(vout.readyState, vout.HAVE_CURRENT_DATA,
+    `${token} checking readyState`);
+  ok(vout.ended, `${token} checking playback has ended`);
+  isnot(stream.getTracks().length, 0, `${token} results in some tracks`);
+  if (stream.getVideoTracks().length > 0) {
+    ok(test.type.match(/^video/), `${token} is a video resource`);
+    checkDrawImage(vout, `${token} checking video frame pixel has been drawn`);
+  }
+  vout.remove();
+  removeNodeAndSource(v);
 }
 
 (async () => {
   SimpleTest.requestCompleteLog();
   SimpleTest.waitForExplicitFinish();
   await SpecialPowers.pushPrefEnv(
     { "set": [
       ["privacy.reduceTimerPrecision", false],
       // This test exhibits bug 1543980 with RDD enabled.
       ["media.rdd-process.enabled", false],
     ]});
   let tests = gPlayTests;
   // Filter out bug1377278.webm due to bug 1541401.
   tests = tests.filter(t => !t.name.includes("1377278"));
-  manager.runTests(tests, startTest);
+
+  manager.runTests(tests, async (test, token) => {
+    try {
+      await startTest(test, token);
+    } catch(e) {
+      ok(false, `Caught exception for ${token}: ${e}`);
+    }
+    manager.finished(token);
+  });
 })();
 </script>
 </pre>
 </body>
 </html>