Bug 1256503 - Part 3: Introduce addDivAndAnimate function checking animation duration is longer than 100s to avoid intermittent test failures. r=dholbert
authorHiroyuki Ikezoe <hiikezoe@mozilla-japan.org>
Fri, 01 Apr 2016 06:03:30 +0900
changeset 291151 f2375d1e124a0d64564c732759755793558fcde0
parent 291150 1e36930172f00a729dd235dc2dc9ed3e6e82f834
child 291152 0d2dd90e33f4957e20a78cb08e49fedb1161056b
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1256503
milestone48.0a1
Bug 1256503 - Part 3: Introduce addDivAndAnimate function checking animation duration is longer than 100s to avoid intermittent test failures. r=dholbert MozReview-Commit-ID: 2zIKFNPBjoK
dom/animation/test/chrome/test_animation_performance_warning.html
dom/animation/test/chrome/test_running_on_compositor.html
dom/animation/test/testcommon.js
--- a/dom/animation/test/chrome/test_animation_performance_warning.html
+++ b/dom/animation/test/chrome/test_animation_performance_warning.html
@@ -210,18 +210,19 @@ var gAnimationsTests = [
         warning: 'AnimationWarningTransformWithGeometricProperties'
       }
     ]
   },
 ];
 
 gAnimationsTests.forEach(function(subtest) {
   promise_test(function(t) {
-    var div = addDiv(t, { class: 'compositable' });
-    var animation = div.animate(subtest.frames, 100 * MS_PER_SEC);
+    var animation = addDivAndAnimate(t,
+                                     { class: 'compositable' },
+                                     subtest.frames, 100 * MS_PER_SEC);
     return animation.ready.then(function() {
       assert_animation_property_state_equals(
         animation.effect.getProperties(),
         subtest.expected);
     });
   }, subtest.desc);
 });
 
@@ -496,41 +497,43 @@ var gMultipleAsyncAnimationsWithGeometri
 function start() {
   var bundleService = SpecialPowers.Cc['@mozilla.org/intl/stringbundle;1']
     .getService(SpecialPowers.Ci.nsIStringBundleService);
   gStringBundle = bundleService
     .createBundle("chrome://global/locale/layout_errors.properties");
 
   gAnimationsTests.forEach(function(subtest) {
     promise_test(function(t) {
-      var div = addDiv(t, { class: 'compositable' });
-      var animation = div.animate(subtest.frames, 100 * MS_PER_SEC);
+      var animation = addDivAndAnimate(t,
+                                       { class: 'compositable' },
+                                       subtest.frames, 100 * MS_PER_SEC);
       return animation.ready.then(function() {
         assert_animation_property_state_equals(
           animation.effect.getProperties(),
           subtest.expected);
       });
     }, subtest.desc);
   });
 
   gPerformanceWarningTests.forEach(function(subtest) {
     promise_test(function(t) {
-      var div = addDiv(t, { class: 'compositable' });
-      var animation = div.animate(subtest.frames, 100 * MS_PER_SEC);
+      var animation = addDivAndAnimate(t,
+                                       { class: 'compositable' },
+                                       subtest.frames, 100 * MS_PER_SEC);
       return animation.ready.then(function() {
         assert_property_state_on_compositor(
           animation.effect.getProperties(),
           subtest.expected);
-        div.style = subtest.style;
+        animation.effect.target.style = subtest.style;
         return waitForFrame();
       }).then(function() {
         assert_animation_property_state_equals(
           animation.effect.getProperties(),
           subtest.expected);
-        div.style = '';
+        animation.effect.target.style = '';
         return waitForFrame();
       }).then(function() {
         assert_property_state_on_compositor(
           animation.effect.getProperties(),
           subtest.expected);
       });
     }, subtest.desc);
   });
@@ -633,39 +636,41 @@ function start() {
             anim.effect.getProperties(),
             anim.expected);
         });
       });
     }, 'Multiple async animations and geometric animation: ' + subtest.desc);
   });
 
   promise_test(function(t) {
-    var div = addDiv(t, { class: 'compositable' });
-    var animation = div.animate(
-      { transform: ['translate(0px)', 'translate(100px)'] }, 100 * MS_PER_SEC);
+    var animation = addDivAndAnimate(t,
+                                     { class: 'compositable' },
+                                     { transform: [ 'translate(0px)',
+                                                    'translate(100px)'] },
+                                     100 * MS_PER_SEC);
     return animation.ready.then(function() {
       assert_animation_property_state_equals(
         animation.effect.getProperties(),
         [ { property: 'transform', runningOnCompositor: true } ]);
-      div.style = 'width: 10000px; height: 10000px';
+      animation.effect.target.style = 'width: 10000px; height: 10000px';
       return waitForFrame();
     }).then(function() {
       // viewport depends on test environment.
       var expectedWarning = new RegExp(
         "Async animation disabled because frame size \\(10000, 10000\\) is " +
         "bigger than the viewport \\(\\d+, \\d+\\) or the visual rectangle " +
         "\\(10000, 10000\\) is larger than the max allowed value \\(\\d+\\)");
       assert_animation_property_state_equals(
         animation.effect.getProperties(),
         [ {
           property: 'transform',
           runningOnCompositor: false,
           warning: expectedWarning
         } ]);
-      div.style = 'width: 100px; height: 100px';
+      animation.effect.target.style = 'width: 100px; height: 100px';
       return waitForFrame();
     }).then(function() {
       // FIXME: Bug 1253164: the animation should get back on compositor.
       assert_animation_property_state_equals(
         animation.effect.getProperties(),
         [ { property: 'transform', runningOnCompositor: false } ]);
     });
   }, 'transform on too big element');
--- a/dom/animation/test/chrome/test_running_on_compositor.html
+++ b/dom/animation/test/chrome/test_running_on_compositor.html
@@ -281,36 +281,38 @@ promise_test(function(t) {
        + 'property that cannot (due to Gecko limitations) but where the latter'
        + 'property is overridden in the CSS cascade, the animation should '
        + 'still report that it is running on the compositor');
   }));
 }, 'isRunningOnCompositor is true when a property that would otherwise block ' +
    'running on the compositor is overridden in the CSS cascade');
 
 promise_test(function(t) {
-  var div = addDiv(t);
-  var animation = div.animate({ opacity: [ 0, 1 ] }, 200 * MS_PER_SEC);
+  var animation = addDivAndAnimate(t,
+                                   {},
+                                   { opacity: [ 0, 1 ] }, 200 * MS_PER_SEC);
 
   return animation.ready.then(t.step_func(function() {
     assert_equals(animation.isRunningOnCompositor, omtaEnabled,
       'Animation reports that it is running on the compositor');
 
     animation.currentTime = 150 * MS_PER_SEC;
     animation.effect.timing.duration = 100 * MS_PER_SEC;
 
     assert_equals(animation.isRunningOnCompositor, false,
        'Animation reports that it is NOT running on the compositor'
        + ' when the animation is set a shorter duration than current time');
   }));
 }, 'animation is immediately removed from compositor' +
    'when timing.duration is made shorter than the current time');
 
 promise_test(function(t) {
-  var div = addDiv(t);
-  var animation = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
+  var animation = addDivAndAnimate(t,
+                                   {},
+                                   { opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
 
   return animation.ready.then(t.step_func(function() {
     assert_equals(animation.isRunningOnCompositor, omtaEnabled,
       'Animation reports that it is running on the compositor');
 
     animation.currentTime = 500 * MS_PER_SEC;
 
     assert_equals(animation.isRunningOnCompositor, false,
@@ -323,18 +325,19 @@ promise_test(function(t) {
     assert_equals(animation.isRunningOnCompositor, omtaEnabled,
       'Animation reports that it is running on the compositor'
       + ' when restarted');
   }));
 }, 'animation is added to compositor' +
    ' when timing.duration is made longer than the current time');
 
 promise_test(function(t) {
-  var div = addDiv(t);
-  var animation = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
+  var animation = addDivAndAnimate(t,
+                                   {},
+                                   { opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
 
   return animation.ready.then(t.step_func(function() {
     assert_equals(animation.isRunningOnCompositor, omtaEnabled,
       'Animation reports that it is running on the compositor');
 
     animation.effect.timing.endDelay = 100 * MS_PER_SEC;
 
     assert_equals(animation.isRunningOnCompositor, omtaEnabled,
@@ -347,36 +350,38 @@ promise_test(function(t) {
     assert_equals(animation.isRunningOnCompositor, false,
       'Animation reports that it is NOT running on the compositor'
       + ' when currentTime is during endDelay');
   }));
 }, 'animation is removed from compositor' +
    ' when current time is made longer than the duration even during endDelay');
 
 promise_test(function(t) {
-  var div = addDiv(t);
-  var animation = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
+  var animation = addDivAndAnimate(t,
+                                   {},
+                                   { opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
 
   return animation.ready.then(t.step_func(function() {
     assert_equals(animation.isRunningOnCompositor, omtaEnabled,
       'Animation reports that it is running on the compositor');
 
     animation.effect.timing.endDelay = -200 * MS_PER_SEC;
     return waitForFrame();
   })).then(t.step_func(function() {
     assert_equals(animation.isRunningOnCompositor, false,
       'Animation reports that it is NOT running on the compositor'
       + ' when endTime is negative value');
   }));
 }, 'animation is removed from compositor' +
    ' when endTime is negative value');
 
 promise_test(function(t) {
-  var div = addDiv(t);
-  var animation = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
+  var animation = addDivAndAnimate(t,
+                                   {},
+                                   { opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
 
   return animation.ready.then(t.step_func(function() {
     assert_equals(animation.isRunningOnCompositor, omtaEnabled,
       'Animation reports that it is running on the compositor');
 
     animation.effect.timing.endDelay = -50 * MS_PER_SEC;
     return waitForFrame();
   })).then(t.step_func(function() {
--- a/dom/animation/test/testcommon.js
+++ b/dom/animation/test/testcommon.js
@@ -11,16 +11,43 @@
  * might be finished when animation.ready has been fulfilled because of slow
  * platforms or busyness of the main thread.
  * Setting short duration to cancel its animation does not matter but
  * if you don't want to cancel the animation, consider using longer duration.
  */
 const MS_PER_SEC = 1000;
 
 /**
+ * Appends a div to the document body and creates an animation on the div.
+ * NOTE: This function asserts when trying to create animations with durations
+ * shorter than 100s because the shorter duration may cause intermittent
+ * failures.  If you are not sure how long it is suitable, use 100s; it's
+ * long enough but shorter than our test framework timeout (330s).
+ * If you really need to use shorter durations, use animate() function directly.
+ *
+ * @param t  The testharness.js Test object. If provided, this will be used
+ *           to register a cleanup callback to remove the div when the test
+ *           finishes.
+ * @param attrs  A dictionary object with attribute names and values to set on
+ *               the div.
+ * @param frames  The keyframes passed to Element.animate().
+ * @param options  The options passed to Element.animate().
+ */
+function addDivAndAnimate(t, attrs, frames, options) {
+  let animDur = (typeof options === 'object') ?
+    options.duration : options;
+  assert_greater_than_equal(animDur, 100 * MS_PER_SEC,
+      'Clients of this addDivAndAnimate API must request a duration ' +
+      'of at least 100s, to avoid intermittent failures from e.g.' +
+      'the main thread being busy for an extended period');
+
+  return addDiv(t, attrs).animate(frames, options);
+}
+
+/**
  * Appends a div to the document body.
  *
  * @param t  The testharness.js Test object. If provided, this will be used
  *           to register a cleanup callback to remove the div when the test
  *           finishes.
  *
  * @param attrs  A dictionary object with attribute names and values to set on
  *               the div.