Bug 1404801 - Part 6: Add mochitests. r=gl,pbro

MozReview-Commit-ID: 6iskCXC4Fa8

--HG--
extra : rebase_source : 0f21ea5f4eb808a098963c405e12e19154ba118d
This commit is contained in:
Daisuke Akatsuka 2017-10-26 16:59:55 +09:00
parent 2fa3256051
commit 59e80b6a95
6 changed files with 305 additions and 2 deletions

View File

@ -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() {

View File

@ -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]
[browser_animation_animation_list_exists.js]
[browser_animation_empty_on_invalid_nodes.js]
[browser_animation_inspector_exists.js]

View File

@ -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.
});

View File

@ -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");
});

View File

@ -0,0 +1,158 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
.ball {
width: 80px;
height: 80px;
/* Add a border here to avoid layout warnings in Linux debug builds: Bug 1329784 */
border: 1px solid transparent;
border-radius: 50%;
background: #f06;
position: absolute;
}
.still {
top: 0;
left: 10px;
}
.animated {
top: 100px;
left: 10px;
animation: simple-animation 2s infinite alternate;
}
.multi {
top: 200px;
left: 10px;
animation: simple-animation 2s infinite alternate,
other-animation 5s infinite alternate;
}
.delayed {
top: 300px;
left: 10px;
background: rebeccapurple;
animation: simple-animation 3s 60s 10;
}
.multi-finite {
top: 400px;
left: 10px;
background: yellow;
animation: simple-animation 3s,
other-animation 4s;
}
.short {
top: 500px;
left: 10px;
background: red;
animation: simple-animation 2s normal;
}
.long {
top: 600px;
left: 10px;
background: blue;
animation: simple-animation 120s;
}
.negative-delay {
top: 700px;
left: 10px;
background: gray;
animation: simple-animation 15s -10s;
animation-fill-mode: forwards;
}
.no-compositor {
top: 0;
right: 10px;
background: gold;
animation: no-compositor 10s cubic-bezier(.57,-0.02,1,.31) forwards;
}
.compositor-all {
animation: compositor-all 2s infinite;
}
.compositor-notall {
animation: compositor-notall 2s infinite;
}
@keyframes simple-animation {
100% {
transform: translateX(300px);
}
}
@keyframes other-animation {
100% {
background: blue;
}
}
@keyframes no-compositor {
100% {
margin-right: 600px;
}
}
@keyframes compositor-all {
to { opacity: 0.5 }
}
@keyframes compositor-notall {
from {
opacity: 0;
width: 0px;
transform: translate(0px);
}
to {
opacity: 1;
width: 100px;
transform: translate(100px);
}
}
</style>
</head>
<body>
<!-- Comment node -->
<div class="ball still"></div>
<div class="ball animated"></div>
<div class="ball multi"></div>
<div class="ball delayed"></div>
<div class="ball multi-finite"></div>
<div class="ball short"></div>
<div class="ball long"></div>
<div class="ball negative-delay"></div>
<div class="ball no-compositor"></div>
<div class="ball" id="endDelayed"></div>
<div class="ball compositor-all"></div>
<div class="ball compositor-notall"></div>
<script>
/* globals KeyframeEffect, Animation */
"use strict";
var el = document.getElementById("endDelayed");
let effect = new KeyframeEffect(el, [
{ opacity: 0, offset: 0 },
{ opacity: 1, offset: 1 }
], { duration: 1000000, endDelay: 500000, fill: "none" });
let animation = new Animation(effect, document.timeline);
animation.play();
</script>
</body>
</html>

View File

@ -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;
};