diff --git a/devtools/client/inspector/animation/animation.js b/devtools/client/inspector/animation/animation.js index 114c9b943578..a0a16f2115f1 100644 --- a/devtools/client/inspector/animation/animation.js +++ b/devtools/client/inspector/animation/animation.js @@ -64,6 +64,8 @@ class AnimationInspector { return; } + const done = this.inspector.updating("newanimationinspector"); + const selection = this.inspector.selection; const animations = selection.isConnected() && selection.isElementNode() @@ -74,6 +76,8 @@ class AnimationInspector { this.inspector.store.dispatch(updateAnimations(animations)); this.animations = animations; } + + done(); } isPanelVisible() { diff --git a/devtools/client/inspector/animation/test/browser.ini b/devtools/client/inspector/animation/test/browser.ini index eaccaa80a80d..cb41ed27d937 100644 --- a/devtools/client/inspector/animation/test/browser.ini +++ b/devtools/client/inspector/animation/test/browser.ini @@ -2,6 +2,7 @@ tags = devtools subsuite = devtools support-files = + doc_simple_animation.html head.js !/devtools/client/framework/test/shared-head.js !/devtools/client/inspector/test/head.js @@ -9,4 +10,6 @@ support-files = !/devtools/client/shared/test/test-actor-registry.js !/devtools/client/shared/test/test-actor.js -[browser_animation_inspector_exists.js] \ No newline at end of file +[browser_animation_animation_list_exists.js] +[browser_animation_empty_on_invalid_nodes.js] +[browser_animation_inspector_exists.js] diff --git a/devtools/client/inspector/animation/test/browser_animation_animation_list_exists.js b/devtools/client/inspector/animation/test/browser_animation_animation_list_exists.js new file mode 100644 index 000000000000..958c0487e7a5 --- /dev/null +++ b/devtools/client/inspector/animation/test/browser_animation_animation_list_exists.js @@ -0,0 +1,43 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +requestLongerTimeout(2); + +// Test that whether animations ui could be displayed + +add_task(async function () { + await addTab(URL_ROOT + "doc_simple_animation.html"); + + const { animationInspector, inspector, panel } = await openAnimationInspector(); + + info("Checking animation list and items existence"); + ok(panel.querySelector(".animation-list"), + "The animation-list is in the DOM"); + is(panel.querySelectorAll(".animation-list .animation-item").length, + animationInspector.animations.length, + "The number of animations displayed matches the number of animations"); + + info("Checking the background color for the animation list items"); + const animationItemEls = panel.querySelectorAll(".animation-list .animation-item"); + const evenColor = + panel.ownerGlobal.getComputedStyle(animationItemEls[0]).backgroundColor; + const oddColor = + panel.ownerGlobal.getComputedStyle(animationItemEls[1]).backgroundColor; + isnot(evenColor, oddColor, + "Background color of an even animation should be different from odd"); + + info("Checking list and items existence after select a element which has an animation"); + const animatedNode = await getNodeFront(".animated", inspector); + await selectNodeAndWaitForAnimations(animatedNode, inspector); + is(panel.querySelectorAll(".animation-list .animation-item").length, 1, + "The number of animations displayed should be 1 for .animated element"); + + // TODO: We need to add following tests after implement since this test has same role + // of animationinspector/test/browser_animation_timeline_ui.js + // * header existance. + // * name label in animation element existance. + // * target node in animation element existance. + // * summary graph in animation element existance. +}); diff --git a/devtools/client/inspector/animation/test/browser_animation_empty_on_invalid_nodes.js b/devtools/client/inspector/animation/test/browser_animation_empty_on_invalid_nodes.js new file mode 100644 index 000000000000..d41db9cc5e20 --- /dev/null +++ b/devtools/client/inspector/animation/test/browser_animation_empty_on_invalid_nodes.js @@ -0,0 +1,34 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +requestLongerTimeout(2); + +// Test that the panel shows no animation data for invalid or not animated nodes + +add_task(async function () { + await addTab(URL_ROOT + "doc_simple_animation.html"); + + const { inspector, panel } = await openAnimationInspector(); + + info("Checking animation list and error message existence for a still node"); + const stillNode = await getNodeFront(".still", inspector); + await selectNodeAndWaitForAnimations(stillNode, inspector); + + ok(panel.querySelector(".animation-error-message"), + "Element which has animation-error-message class should exist for a still node"); + is(panel.querySelector(".animation-error-message > p").textContent, + ANIMATION_L10N.getStr("panel.noAnimation"), + "The correct error message is displayed"); + ok(!panel.querySelector(".animation-list"), + "Element which has animations class should not exist for a still node"); + + info("Checking animation list and error message existence for a text node"); + const commentNode = await inspector.walker.previousSibling(stillNode); + await selectNodeAndWaitForAnimations(commentNode, inspector); + + ok(panel.querySelector(".animation-error-message"), + "Element which has animation-error-message class should exist for a text node"); + ok(!panel.querySelector(".animation-list"), + "Element which has animations class should not exist for a text node"); +}); diff --git a/devtools/client/inspector/animation/test/doc_simple_animation.html b/devtools/client/inspector/animation/test/doc_simple_animation.html new file mode 100644 index 000000000000..e8ce33a5ddca --- /dev/null +++ b/devtools/client/inspector/animation/test/doc_simple_animation.html @@ -0,0 +1,158 @@ + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + + diff --git a/devtools/client/inspector/animation/test/head.js b/devtools/client/inspector/animation/test/head.js index 55fc24427430..7dbb5fff02a2 100644 --- a/devtools/client/inspector/animation/test/head.js +++ b/devtools/client/inspector/animation/test/head.js @@ -9,8 +9,13 @@ Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/devtools/client/inspector/test/head.js", this); +const COMMON_FRAME_SCRIPT_URL = "chrome://devtools/content/shared/frame-script-utils.js"; +const FRAME_SCRIPT_URL = CHROME_URL_ROOT + "doc_frame_script.js"; const TAB_NAME = "newanimationinspector"; +const ANIMATION_L10N = + new LocalizationHelper("devtools/client/locales/animationinspector.properties"); + // Enable new animation inspector. Services.prefs.setBoolPref("devtools.new-animationinspector.enabled", true); @@ -29,9 +34,10 @@ registerCleanupFunction(() => { */ const openAnimationInspector = async function () { const { inspector, toolbox } = await openInspectorSidebarTab(TAB_NAME); + await inspector.once("inspector-updated"); const { animationinspector: animationInspector } = inspector; const panel = inspector.panelWin.document.getElementById("animation-container"); - return { toolbox, inspector, animationInspector, panel }; + return { animationInspector, toolbox, inspector, panel }; }; /** @@ -43,3 +49,58 @@ const closeAnimationInspector = async function () { const target = TargetFactory.forTab(gBrowser.selectedTab); return gDevTools.closeToolbox(target); }; + +/** + * Some animation features are not enabled by default in release/beta channels + * yet including: + * * parts of the Web Animations API (Bug 1264101), and + * * the frames() timing function (Bug 1379582). + */ +const enableAnimationFeatures = function () { + return new Promise(resolve => { + SpecialPowers.pushPrefEnv({"set": [ + ["dom.animations-api.core.enabled", true], + ["layout.css.frames-timing.enabled", true], + ]}, resolve); + }); +}; + +/** + * Add a new test tab in the browser and load the given url. + * + * @param {String} url The url to be loaded in the new tab + * @return a promise that resolves to the tab object when the url is loaded + */ +const _addTab = addTab; +addTab = async function (url) { + await enableAnimationFeatures(); + const tab = await _addTab(url); + const browser = tab.linkedBrowser; + info("Loading the helper frame script " + FRAME_SCRIPT_URL); + browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false); + info("Loading the helper frame script " + COMMON_FRAME_SCRIPT_URL); + browser.messageManager.loadFrameScript(COMMON_FRAME_SCRIPT_URL, false); + return tab; +}; + +/** + * Set the inspector's current selection to a node or to the first match of the + * given css selector and wait for the animations to be displayed + * + * @param {String|NodeFront} + * data The node to select + * @param {InspectorPanel} inspector + * The instance of InspectorPanel currently loaded in the toolbox + * @param {String} reason + * Defaults to "test" which instructs the inspector not + * to highlight the node upon selection + * @return {Promise} Resolves when the inspector is updated with the new node + * and animations of its subtree are properly displayed. + */ +const selectNodeAndWaitForAnimations = async function (data, inspector, reason = "test") { + // We want to make sure the rest of the test waits for the animations to + // be properly displayed (wait for all target DOM nodes to be previewed). + const onUpdated = inspector.once("inspector-updated"); + await selectNode(data, inspector, reason); + await onUpdated; +};