Bug 1440555 - P2: Re-write tests that check for end after suspend. r=cpearce
authorDan Glastonbury <dan.glastonbury@gmail.com>
Mon, 26 Feb 2018 18:38:42 +1000
changeset 405882 4048365eb9c544b6ebde747fc985830252b77637
parent 405881 a4357de13e0fde8ac68049ea48e9f3c9a153798f
child 405883 18a7f08a6cdc379574836737f776c62c6e755134
push id60385
push userdglastonbury@mozilla.com
push dateThu, 01 Mar 2018 00:42:11 +0000
treeherderautoland@4048365eb9c5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1440555
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1440555 - P2: Re-write tests that check for end after suspend. r=cpearce These two tests had intermittent orange failures. The logging shows that the suspend happens but the `ended` event is never received. Test re-written on the presumption that `ended` event is fired and lost between checking `video.ended` and registering `ended` event in `waitUnitEnded()` MozReview-Commit-ID: GnAFADFOJje
dom/media/test/background_video.js
dom/media/test/test_background_video_suspend.html
dom/media/test/test_background_video_suspend_ends.html
--- a/dom/media/test/background_video.js
+++ b/dom/media/test/background_video.js
@@ -1,39 +1,71 @@
 /* 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/. */
 /* jshint esversion: 6, -W097 */
-/* globals SimpleTest, SpecialPowers, info, is, ok */
+/* globals SimpleTest, SpecialPowers, document, info, is, manager, ok */
 
 "use strict";
 
 function startTest(test) {
   info(test.desc);
   SimpleTest.waitForExplicitFinish();
   SpecialPowers.pushPrefEnv({ 'set': test.prefs }, () => {
     manager.runTests(test.tests, test.runTest);
   });
 }
 
 /**
+ * @param {HTMLMediaElement} video target of interest.
+ * @param {string} eventName the event to wait on.
+ * @returns {Promise} A promise that is resolved when event happens.
+ */
+function nextEvent(video, eventName) {
+  return new Promise(function (resolve, reject) {
+    let f = function (event) {
+      ok(true, `${video.token} ${eventName}.`);
+      video.removeEventListener(eventName, f, false);
+      resolve(event);
+    };
+    video.addEventListener(eventName, f, false);
+  });
+}
+
+function nextVideoEnded(video) {
+  return nextEvent(video, 'ended');
+}
+
+function nextVideoPlaying(video) {
+  return nextEvent(video, 'playing');
+}
+
+function nextVideoResumes(video) {
+  return nextEvent(video, 'mozexitvideosuspend');
+}
+
+function nextVideoSuspends(video) {
+  return nextEvent(video, 'mozentervideosuspend');
+}
+
+/**
  * @param {string} url video src.
  * @returns {HTMLMediaElement} The created video element.
  */
 function appendVideoToDoc(url, token, width, height) {
   // Default size of (160, 120) is used by other media tests.
   if (width === undefined) { width = 160; }
-  if (height === undefined) { height = 3*width/4; }
+  if (height === undefined) { height = 3 * width / 4; }
 
   let v = document.createElement('video');
   v.token = token;
-  document.body.appendChild(v);
   v.width = width;
   v.height = height;
   v.src = url;
+  document.body.appendChild(v);
   return v;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video 'playing' event fires.
  */
 function waitUntilPlaying(video) {
@@ -84,44 +116,44 @@ function testVideoSuspendsWhenHidden(vid
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video decode resumes.
  */
 function testVideoResumesWhenShown(video) {
-  var p  = once(video, 'mozexitvideosuspend').then(() => {
+  var p = once(video, 'mozexitvideosuspend').then(() => {
     ok(true, `${video.token} resumes`);
   });
   Log(video.token, "Set visible");
   video.setVisible(true);
   return p;
 }
 
 /**
  * @param {HTMLMediaElement} video Video element under test.
  * @returns {Promise} Promise that is resolved when video decode resumes.
  */
 function testVideoOnlySeekCompletedWhenShown(video) {
-  var p  = once(video, 'mozvideoonlyseekcompleted').then(() => {
+  var p = once(video, 'mozvideoonlyseekcompleted').then(() => {
     ok(true, `${video.token} resumes`);
   });
   Log(video.token, "Set visible");
   video.setVisible(true);
   return p;
 }
 
 /**
  * @param {HTMLVideoElement} video Video element under test.
  * @returns {Promise} Promise that is resolved if video ends and rejects if video suspends.
  */
 function checkVideoDoesntSuspend(video) {
   let p = Promise.race([
-    waitUntilEnded(video).then(() => { ok(true, `${video.token} ended before decode was suspended`)}),
+    waitUntilEnded(video).then(() => { ok(true, `${video.token} ended before decode was suspended`) }),
     once(video, 'mozentervideosuspend', () => { Promise.reject(new Error(`${video.token} suspended`)) })
   ]);
   Log(video.token, "Set hidden.");
   video.setVisible(false);
   return p;
 }
 
 /**
--- a/dom/media/test/test_background_video_suspend.html
+++ b/dom/media/test/test_background_video_suspend.html
@@ -1,51 +1,74 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
 <title>Test Background Video Suspends</title>
 <script src="/tests/SimpleTest/SimpleTest.js"></script>
 <script src="manifest.js"></script>
 <script src="background_video.js"></script>
-<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css" />
 <script type="text/javascript">
-"use strict";
-
-var manager = new MediaTestManager;
+  "use strict";
 
-var MIN_DELAY = 100;
+  var manager = new MediaTestManager;
 
-function testDelay(v, start, min) {
-  let end = performance.now();
-  let delay = end - start;
-  ok(delay > min, `${v.token} suspended with a delay of ${delay} ms`);
-}
+  var MIN_DELAY = 100;
 
-startTest({
-  desc: 'Test Background Video Suspends',
-  prefs: [
-    [ "media.test.video-suspend", true ],
-    [ "media.suspend-bkgnd-video.enabled", true ],
-    // Use a short delay to ensure video decode suspend happens before end
-    // of video.
-    [ "media.suspend-bkgnd-video.delay-ms", MIN_DELAY ],
-    [ "privacy.reduceTimerPrecision", false ]
-  ],
-  tests: gDecodeSuspendTests,
-  runTest: (test, token) => {
-    let v = appendVideoToDoc(test.name, token);
+  function testDelay(v, start, min) {
+    let end = performance.now();
+    let delay = end - start;
+    ok(delay > min, `${v.token} suspended with a delay of ${delay} ms`);
+  }
+
+  async function runTest(test, token) {
+    let video = appendVideoToDoc(test.name, token);
     manager.started(token);
 
-    let start;
-    waitUntilPlaying(v)
-      .then(() => { start = performance.now(); })
-      .then(() => testVideoSuspendsWhenHidden(v))
-      .then(() => {
-        testDelay(v, start, MIN_DELAY);
-        return testVideoResumesWhenShown(v);
-      })
-      .then(() => waitUntilEnded(v))
-      .then(() => {
-        removeNodeAndSource(v);
-        manager.finished(token);
-      });
+    let ended = nextVideoEnded(video);
+    let playing = nextVideoPlaying(video);
+    let resumes = nextVideoResumes(video);
+    let suspends = nextVideoSuspends(video);
+
+    Log(token, "Start playing");
+    video.play();
+
+    Log(token, "Waiting for video playing");
+    await playing;
+
+    let start = performance.now();
+
+    Log(token, "Set hidden");
+    video.setVisible(false);
+
+    Log(token, "Waiting for video suspend");
+    await suspends;
+
+    testDelay(video, start, MIN_DELAY);
+
+    Log(token, "Set visible");
+    video.setVisible(true);
+
+    Log(token, "Waiting for video resume");
+    await resumes;
+
+    Log(token, "Waiting for ended");
+    await ended;
+
+    ok(video.currentTime >= video.duration, 'current time approximates duration.');
+
+    removeNodeAndSource(video);
+    manager.finished(token);
   }
-});
-</script>
+
+  startTest({
+    desc: 'Test Background Video Suspends',
+    prefs: [
+      ["media.test.video-suspend", true],
+      ["media.suspend-bkgnd-video.enabled", true],
+      // Use a short delay to ensure video decode suspend happens before end
+      // of video.
+      ["media.suspend-bkgnd-video.delay-ms", MIN_DELAY],
+      ["privacy.reduceTimerPrecision", false]
+    ],
+    tests: gDecodeSuspendTests,
+    runTest: runTest
+  });
+</script>
\ No newline at end of file
--- a/dom/media/test/test_background_video_suspend_ends.html
+++ b/dom/media/test/test_background_video_suspend_ends.html
@@ -1,39 +1,53 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
 <title>Test Background Suspended Video Fires 'ended' Event</title>
 <script src="/tests/SimpleTest/SimpleTest.js"></script>
 <script src="manifest.js"></script>
 <script src="background_video.js"></script>
-<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css" />
 <script type="text/javascript">
-"use strict";
-
-var manager = new MediaTestManager;
+  "use strict";
 
-startTest({
-  desc: "Test Background Suspended Video Fires 'ended' Event",
-  prefs: [
-    [ "media.test.video-suspend", true ],
-    [ "media.suspend-bkgnd-video.enabled", true ],
-    // User a short delay to ensure video decode suspend happens before end
-    // of video.
-    [ "media.suspend-bkgnd-video.delay-ms", 1000 ]
-  ],
-  tests: gDecodeSuspendTests,
-  runTest: (test, token) => {
-    let v = appendVideoToDoc(test.name, token);
+  var manager = new MediaTestManager;
+
+  async function runTest(test, token) {
+    let video = appendVideoToDoc(test.name, token);
     manager.started(token);
 
     // This test checks that 'ended' event is received for videos with
     // suspended video decoding. This is important for looping video logic
     // handling in HTMLMediaElement.
-    waitUntilPlaying(v)
-      .then(() => testVideoSuspendsWhenHidden(v))
-      .then(() => waitUntilEnded(v))
-      .then(() => {
-        ok(v.currentTime >= v.duration, 'current time approximates duration.');
-        manager.finished(token);
-      });
+
+    let ended = nextVideoEnded(video);
+    let suspends = nextVideoSuspends(video);
+
+    Log(token, "Start playing");
+    video.play();
+
+    Log(token, "Set hidden");
+    video.setVisible(false);
+
+    Log(token, "Waiting for video suspend");
+    await suspends;
+
+    Log(token, "Waiting for ended");
+    await ended;
+
+    ok(video.currentTime >= video.duration, 'current time approximates duration.');
+
+    manager.finished(token);
   }
-});
-</script>
+
+  startTest({
+    desc: "Test Background Suspended Video Fires 'ended' Event",
+    prefs: [
+      ["media.test.video-suspend", true],
+      ["media.suspend-bkgnd-video.enabled", true],
+      // User a short delay to ensure video decode suspend happens before end
+      // of video.
+      ["media.suspend-bkgnd-video.delay-ms", 1000]
+    ],
+    tests: gDecodeSuspendTests,
+    runTest: runTest
+  });
+</script>
\ No newline at end of file