Bug 1330544 - Part 3: Add test of altering properties. r?pbro draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Fri, 06 Jul 2018 17:26:53 +0900
changeset 814797 0e5c73b6758c
parent 814796 716714ca3ff1
push id115349
push userbmo:dakatsuka@mozilla.com
push dateFri, 06 Jul 2018 08:30:25 +0000
reviewerspbro
bugs1330544
milestone63.0a1
Bug 1330544 - Part 3: Add test of altering properties. r?pbro MozReview-Commit-ID: 2vvlQgL53UW
devtools/client/inspector/animation/test/browser.ini
devtools/client/inspector/animation/test/browser_animation_logic_mutations_properties.js
devtools/client/inspector/animation/test/doc_frame_script.js
devtools/client/inspector/animation/test/head.js
devtools/client/shared/test/frame-script-utils.js
--- a/devtools/client/inspector/animation/test/browser.ini
+++ b/devtools/client/inspector/animation/test/browser.ini
@@ -59,16 +59,17 @@ skip-if = (verify && !debug)
 [browser_animation_keyframes-progress-bar_after-resuming.js]
 [browser_animation_logic_adjust-time.js]
 [browser_animation_logic_adjust-time-with-playback-rate.js]
 [browser_animation_logic_auto-stop.js]
 [browser_animation_logic_avoid-updating-during-hiding.js]
 [browser_animation_logic_created-time.js]
 [browser_animation_logic_mutations.js]
 [browser_animation_logic_mutations_fast.js]
+[browser_animation_logic_mutations_properties.js]
 [browser_animation_logic_scroll-amount.js]
 [browser_animation_pause-resume-button.js]
 [browser_animation_pause-resume-button_end-time.js]
 [browser_animation_pause-resume-button_respectively.js]
 [browser_animation_pause-resume-button_spacebar.js]
 [browser_animation_playback-rate-selector.js]
 [browser_animation_pseudo-element.js]
 [browser_animation_rewind-button.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/animation/test/browser_animation_logic_mutations_properties.js
@@ -0,0 +1,81 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test whether animation was changed after altering following properties.
+// * delay
+// * direction
+// * duration
+// * easing (animationTimingFunction in case of CSS Animationns)
+// * fill
+// * iterations
+// * endDelay (script animation only)
+// * iterationStart (script animation only)
+// * playbackRate (script animation only)
+
+const SEC = 1000;
+const TEST_EFFECT_TIMING = {
+  delay: 20 * SEC,
+  direction: "reverse",
+  duration: 20 * SEC,
+  easing: "steps(1)",
+  endDelay: 20 * SEC,
+  fill: "backwards",
+  iterations: 20,
+  iterationStart: 20 * SEC,
+};
+const TEST_PLAYBACK_RATE = 0.1;
+
+add_task(async function() {
+  await addTab(URL_ROOT + "doc_simple_animation.html");
+  await removeAnimatedElementsExcept([".animated", ".end-delay"]);
+  const { animationInspector } = await openAnimationInspector();
+  await setCSSAnimationProperties(animationInspector);
+  assertProperties(animationInspector.state.animations[0], false);
+  await setScriptAnimationProperties(animationInspector);
+  assertProperties(animationInspector.state.animations[1], true);
+});
+
+async function setCSSAnimationProperties(animationInspector) {
+  const properties = {
+    animationDelay: `${ TEST_EFFECT_TIMING.delay }ms`,
+    animationDirection: TEST_EFFECT_TIMING.direction,
+    animationDuration: `${ TEST_EFFECT_TIMING.duration }ms`,
+    animationFillMode: TEST_EFFECT_TIMING.fill,
+    animationIterationCount: TEST_EFFECT_TIMING.iterations,
+    animationTimingFunction: TEST_EFFECT_TIMING.easing,
+  };
+
+  await setStyles(animationInspector, ".animated", properties);
+}
+
+async function setScriptAnimationProperties(animationInspector) {
+  await setEffectTimingAndPlayback(animationInspector, ".end-delay",
+                                   TEST_EFFECT_TIMING, TEST_PLAYBACK_RATE);
+}
+
+function assertProperties(animation, isScriptAnimation) {
+  is(animation.state.delay, TEST_EFFECT_TIMING.delay,
+     `Delay should be ${ TEST_EFFECT_TIMING.delay }`);
+  is(animation.state.direction, TEST_EFFECT_TIMING.direction,
+     `Direction should be ${ TEST_EFFECT_TIMING.direction }`);
+  is(animation.state.duration, TEST_EFFECT_TIMING.duration,
+     `Duration should be ${ TEST_EFFECT_TIMING.duration }`);
+  is(animation.state.fill, TEST_EFFECT_TIMING.fill,
+     `Fill should be ${ TEST_EFFECT_TIMING.fill }`);
+  is(animation.state.iterationCount, TEST_EFFECT_TIMING.iterations,
+     `Iterations should be ${ TEST_EFFECT_TIMING.iterations }`);
+
+  if (isScriptAnimation) {
+    is(animation.state.easing, TEST_EFFECT_TIMING.easing,
+       `Easing should be ${ TEST_EFFECT_TIMING.easing }`);
+    is(animation.state.iterationStart, TEST_EFFECT_TIMING.iterationStart,
+       `IterationStart should be ${ TEST_EFFECT_TIMING.iterationStart }`);
+    is(animation.state.playbackRate, TEST_PLAYBACK_RATE,
+       `PlaybackRate should be ${ TEST_PLAYBACK_RATE }`);
+  } else {
+    is(animation.state.animationTimingFunction, TEST_EFFECT_TIMING.easing,
+       `AnimationTimingFunction should be ${ TEST_EFFECT_TIMING.easing }`);
+  }
+}
--- a/devtools/client/inspector/animation/test/doc_frame_script.js
+++ b/devtools/client/inspector/animation/test/doc_frame_script.js
@@ -13,16 +13,37 @@ addMessageListener("Test:RemoveAnimatedE
     if (isRemovableElement(animation, selectors)) {
       animation.effect.target.remove();
     }
   }
 
   sendAsyncMessage("Test:RemoveAnimatedElementsExcept");
 });
 
+addMessageListener("Test:SetEffectTimingAndPlayback", function(msg) {
+  const { effectTiming, playbackRate, selector } = msg.data;
+  let selectedAnimation = null;
+
+  for (const animation of content.document.getAnimations()) {
+    if (animation.effect.target.matches(selector)) {
+      selectedAnimation = animation;
+      break;
+    }
+  }
+
+  if (!selectedAnimation) {
+    return;
+  }
+
+  selectedAnimation.playbackRate = playbackRate;
+  selectedAnimation.effect.updateTiming(effectTiming);
+
+  sendAsyncMessage("Test:SetEffectTimingAndPlayback");
+});
+
 function isRemovableElement(animation, selectors) {
   for (const selector of selectors) {
     if (animation.effect.target.matches(selector)) {
       return false;
     }
   }
 
   return true;
--- a/devtools/client/inspector/animation/test/head.js
+++ b/devtools/client/inspector/animation/test/head.js
@@ -473,16 +473,38 @@ const setClassAttribute = async function
     attributeValue: cls,
     selector,
   };
   await executeInContent("devtools:test:setAttribute", options);
   await waitForSummaryAndDetail(animationInspector);
 };
 
 /**
+ * Set a new style properties to the node for the given selector.
+ *
+ * @param {AnimationInspector} animationInspector
+ * @param {String} selector
+ * @param {Object} properties
+ *        e.g. {
+ *               animationDuration: "1000ms",
+ *               animationTimingFunction: "linear",
+ *             }
+ */
+const setEffectTimingAndPlayback = async function(animationInspector,
+                                                  selector, effectTiming, playbackRate) {
+  const options = {
+    effectTiming,
+    playbackRate,
+    selector,
+  };
+  await executeInContent("Test:SetEffectTimingAndPlayback", options);
+  await waitForSummaryAndDetail(animationInspector);
+};
+
+/**
  * Set the sidebar width by given parameter.
  *
  * @param {String} width
  *        Change sidebar width by given parameter.
  * @param {InspectorPanel} inspector
  *        The instance of InspectorPanel currently loaded in the toolbox
  * @return {Promise} Resolves when the sidebar size changed.
  */
@@ -509,16 +531,36 @@ const setStyle = async function(animatio
     propertyValue,
     selector,
   };
   await executeInContent("devtools:test:setStyle", options);
   await waitForSummaryAndDetail(animationInspector);
 };
 
 /**
+ * Set a new style properties to the node for the given selector.
+ *
+ * @param {AnimationInspector} animationInspector
+ * @param {String} selector
+ * @param {Object} properties
+ *        e.g. {
+ *               animationDuration: "1000ms",
+ *               animationTimingFunction: "linear",
+ *             }
+ */
+const setStyles = async function(animationInspector, selector, properties) {
+  const options = {
+    properties,
+    selector,
+  };
+  await executeInContent("devtools:test:setMultipleStyles", options);
+  await waitForSummaryAndDetail(animationInspector);
+};
+
+/**
  * Wait for rendering.
  *
  * @param {AnimationInspector} animationInspector
  */
 const waitForRendering = async function(animationInspector) {
   await Promise.all([
     waitForAllAnimationTargets(animationInspector),
     waitForAllSummaryGraph(animationInspector),
--- a/devtools/client/shared/test/frame-script-utils.js
+++ b/devtools/client/shared/test/frame-script-utils.js
@@ -149,16 +149,43 @@ addMessageListener("devtools:test:setSty
   }
 
   node.style[propertyName] = propertyValue;
 
   sendAsyncMessage("devtools:test:setStyle");
 });
 
 /**
+ * Set multiple styles to the node for the given selector at once.
+ * @param {Object} data
+ * - {String} selector The CSS selector to get the node (can be a "super"
+ *   selector).
+ * - {Object} properties
+ *            e.g. {
+ *              opacity: 0,
+ *              color: "red",
+ *              animationTimingFunction: "linear",
+ *            }
+ */
+addMessageListener("devtools:test:setMultipleStyles", function(msg) {
+  const {selector, properties} = msg.data;
+  const node = superQuerySelector(selector);
+  if (!node) {
+    return;
+  }
+
+  for (const propertyName in properties) {
+    const propertyValue = properties[propertyName];
+    node.style[propertyName] = propertyValue;
+  }
+
+  sendAsyncMessage("devtools:test:setMultipleStyles");
+});
+
+/**
  * Set a given attribute value on a node.
  * @param {Object} data
  * - {String} selector The CSS selector to get the node (can be a "super"
  *   selector).
  * - {String} attributeName The name of the attribute to set.
  * - {String} attributeValue The value for the attribute.
  */
 addMessageListener("devtools:test:setAttribute", function(msg) {