Bug 1234403 - Part 3: Test for the CSSPseudoElement objects returned by effect.target. r=birtles
authorBoris Chiou <boris.chiou@gmail.com>
Wed, 24 Feb 2016 03:12:00 +0100
changeset 321900 d49c6a43b80a4e95b5dcbac0878a6757011e39db
parent 321899 df84913f9ff2bcc124162e2e898df54efe743fd5
child 321901 a40b8d9d7e46b3f4f7d9fc52d7939cf5d1323cf3
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbirtles
bugs1234403
milestone47.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 1234403 - Part 3: Test for the CSSPseudoElement objects returned by effect.target. r=birtles
dom/animation/test/css-animations/file_effect-target.html
dom/animation/test/css-transitions/file_effect-target.html
dom/animation/test/testcommon.js
--- a/dom/animation/test/css-animations/file_effect-target.html
+++ b/dom/animation/test/css-animations/file_effect-target.html
@@ -9,13 +9,46 @@
 'use strict';
 
 test(function(t) {
   var div = addDiv(t);
   div.style.animation = 'anim 100s';
   var animation = div.getAnimations()[0];
   assert_equals(animation.effect.target, div,
     'Animation.target is the animatable div');
-}, 'Returned CSS animations have the correct Animation.target');
+}, 'Returned CSS animations have the correct effect target');
+
+test(function(t) {
+  addStyle(t, { '.after::after': 'animation: anim 10s, anim 100s;' });
+  var div = addDiv(t, { class: 'after' });
+  var anims = document.getAnimations();
+  assert_equals(anims.length, 2,
+                'Got animations running on ::after pseudo element');
+  assert_equals(anims[0].effect.target, anims[1].effect.target,
+                'Both animations return the same target object');
+}, 'effect.target should return the same CSSPseudoElement object each time');
+
+test(function(t) {
+  addStyle(t, { '.after::after': 'animation: anim 10s;' });
+  var div = addDiv(t, { class: 'after' });
+  var pseudoTarget = document.getAnimations()[0].effect.target;
+  var effect = new KeyframeEffectReadOnly(pseudoTarget,
+                                          { background: ["blue", "red"] },
+                                          3000);
+  var newAnim = new Animation(effect, document.timeline);
+  newAnim.play();
+  var anims = document.getAnimations();
+  assert_equals(anims.length, 2,
+                'Got animations running on ::after pseudo element');
+  assert_not_equals(anims[0], newAnim,
+                    'The scriped-generated animation appears last');
+  assert_equals(newAnim.effect.target, pseudoTarget,
+                'The effect.target of the scripted-generated animation is ' +
+                'the same as the one from the argument of ' +
+                'KeyframeEffectReadOnly constructor');
+  assert_equals(anims[0].effect.target, newAnim.effect.target,
+                'Both animations return the same target object');
+}, 'effect.target from the script-generated animation should return the same ' +
+   'CSSPseudoElement object as that from the CSS generated animation');
 
 done();
 </script>
 </body>
--- a/dom/animation/test/css-transitions/file_effect-target.html
+++ b/dom/animation/test/css-transitions/file_effect-target.html
@@ -13,11 +13,54 @@ test(function(t) {
   div.style.transition = 'left 100s';
   div.style.left = '100px';
 
   var animation = div.getAnimations()[0];
   assert_equals(animation.effect.target, div,
     'Animation.target is the animatable div');
 }, 'Returned CSS transitions have the correct Animation.target');
 
+test(function(t) {
+  addStyle(t, { '.init::after': 'content: ""; width: 0px; height: 0px; ' +
+                                'transition: all 10s;',
+                '.change::after': 'width: 100px; height: 100px;' });
+  var div = addDiv(t, { class: 'init' });
+  flushComputedStyle(div);
+  div.classList.add('change');
+
+  var anims = document.getAnimations();
+  assert_equals(anims.length, 2,
+                'Got transitions running on ::after pseudo element');
+  assert_equals(anims[0].effect.target, anims[1].effect.target,
+                'Both transitions return the same target object');
+}, 'effect.target should return the same CSSPseudoElement object each time');
+
+test(function(t) {
+  addStyle(t, { '.init::after': 'content: ""; width: 0px; transition: all 10s;',
+                '.change::after': 'width: 100px;' });
+  var div = addDiv(t, { class: 'init' });
+  flushComputedStyle(div);
+  div.classList.add('change');
+  var pseudoTarget = document.getAnimations()[0].effect.target;
+  var effect = new KeyframeEffectReadOnly(pseudoTarget,
+                                          { background: ["blue", "red"] },
+                                          3000);
+  var newAnim = new Animation(effect, document.timeline);
+  newAnim.play();
+
+  var anims = document.getAnimations();
+  assert_equals(anims.length, 2,
+                'Got animations running on ::after pseudo element');
+  assert_not_equals(anims[0], newAnim,
+                    'The scriped-generated animation appears last');
+  assert_equals(newAnim.effect.target, pseudoTarget,
+                'The effect.target of the scripted-generated animation is ' +
+                'the same as the one from the argument of ' +
+                'KeyframeEffectReadOnly constructor');
+  assert_equals(anims[0].effect.target, newAnim.effect.target,
+                'Both the transition and the scripted-generated animation ' +
+                'return the same target object');
+}, 'effect.target from the script-generated animation should return the same ' +
+   'CSSPseudoElement object as that from the CSS generated transition');
+
 done();
 </script>
 </body>
--- a/dom/animation/test/testcommon.js
+++ b/dom/animation/test/testcommon.js
@@ -25,16 +25,44 @@ function addDiv(t, attrs) {
         div.parentNode.removeChild(div);
       }
     });
   }
   return div;
 }
 
 /**
+ * Appends a style div to the document head.
+ *
+ * @param t  The testharness.js Test object. If provided, this will be used
+ *           to register a cleanup callback to remove the style element
+ *           when the test finishes.
+ *
+ * @param rules  A dictionary object with selector names and rules to set on
+ *               the style sheet.
+ */
+function addStyle(t, rules) {
+  var extraStyle = document.createElement('style');
+  document.head.appendChild(extraStyle);
+  if (rules) {
+    var sheet = extraStyle.sheet;
+    for (var selector in rules) {
+      sheet.insertRule(selector + '{' + rules[selector] + '}',
+                       sheet.cssRules.length);
+    }
+  }
+
+  if (t && typeof t.add_cleanup === 'function') {
+    t.add_cleanup(function() {
+      extraStyle.remove();
+    });
+  }
+}
+
+/**
  * Promise wrapper for requestAnimationFrame.
  */
 function waitForFrame() {
   return new Promise(function(resolve, reject) {
     window.requestAnimationFrame(resolve);
   });
 }