mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-20 00:35:44 +00:00
Bug 1431573 - Part 12: Add tests. r=gl
MozReview-Commit-ID: E9WzhYeUm5R
This commit is contained in:
parent
c4bdd329b4
commit
9bff79382a
@ -2,6 +2,7 @@
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
doc_custom_playback_rate.html
|
||||
doc_multi_easings.html
|
||||
doc_multi_keyframes.html
|
||||
doc_multi_timings.html
|
||||
@ -22,11 +23,19 @@ support-files =
|
||||
[browser_animation_animation-list.js]
|
||||
[browser_animation_animation-target.js]
|
||||
[browser_animation_animation-timeline-tick.js]
|
||||
[browser_animation_current-time-label.js]
|
||||
[browser_animation_current-time-scrubber.js]
|
||||
[browser_animation_empty_on_invalid_nodes.js]
|
||||
[browser_animation_inspector_exists.js]
|
||||
[browser_animation_keyframes-graph_computed-value-path.js]
|
||||
[browser_animation_keyframes-graph_computed-value-path_easing-hint.js]
|
||||
[browser_animation_keyframes-graph_keyframe-marker.js]
|
||||
[browser_animation_keyframes-progress-bar.js]
|
||||
[browser_animation_logic_auto-stop.js]
|
||||
[browser_animation_pause-resume-button.js]
|
||||
[browser_animation_pause-resume-button_spacebar.js]
|
||||
[browser_animation_playback-rate-selector.js]
|
||||
[browser_animation_rewind-button.js]
|
||||
[browser_animation_summary-graph_animation-name.js]
|
||||
[browser_animation_summary-graph_compositor.js]
|
||||
[browser_animation_summary-graph_computed-timing-path.js]
|
||||
|
@ -0,0 +1,61 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test for following CurrentTimeLabel component:
|
||||
// * element existence
|
||||
// * label content at plural timing
|
||||
|
||||
add_task(async function () {
|
||||
await addTab(URL_ROOT + "doc_multi_timings.html");
|
||||
const { animationInspector, inspector, panel } = await openAnimationInspector();
|
||||
|
||||
info("Checking current time label existence");
|
||||
const labelEl = panel.querySelector(".current-time-label");
|
||||
ok(labelEl, "current time label should exist");
|
||||
|
||||
info("Checking current time label content");
|
||||
await selectNodeAndWaitForAnimations(".keyframes-easing-step", inspector);
|
||||
await clickOnCurrentTimeScrubberController(animationInspector, panel, 0.5);
|
||||
assertLabelContent(labelEl, animationInspector.state.animations[0].state.currentTime);
|
||||
await clickOnCurrentTimeScrubberController(animationInspector, panel, 0.2);
|
||||
assertLabelContent(labelEl, animationInspector.state.animations[0].state.currentTime);
|
||||
|
||||
info("Checking current time label content during running");
|
||||
// Resume
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
const previousContent = labelEl.textContent;
|
||||
await wait(1000);
|
||||
const currentContent = labelEl.textContent;
|
||||
isnot(previousContent, currentContent, "Current time label should change");
|
||||
});
|
||||
|
||||
function assertLabelContent(labelEl, time) {
|
||||
const expected = formatStopwatchTime(time);
|
||||
is(labelEl.textContent, expected, `Content of label should be ${ expected }`);
|
||||
}
|
||||
|
||||
function formatStopwatchTime(time) {
|
||||
// Format falsy values as 0
|
||||
if (!time) {
|
||||
return "00:00.000";
|
||||
}
|
||||
|
||||
let milliseconds = parseInt(time % 1000, 10);
|
||||
let seconds = parseInt((time / 1000) % 60, 10);
|
||||
let minutes = parseInt((time / (1000 * 60)), 10);
|
||||
|
||||
let pad = (nb, max) => {
|
||||
if (nb < max) {
|
||||
return new Array((max + "").length - (nb + "").length + 1).join("0") + nb;
|
||||
}
|
||||
return nb;
|
||||
};
|
||||
|
||||
minutes = pad(minutes, 10);
|
||||
seconds = pad(seconds, 10);
|
||||
milliseconds = pad(milliseconds, 100);
|
||||
|
||||
return `${minutes}:${seconds}.${milliseconds}`;
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test for following CurrentTimeScrubber and CurrentTimeScrubberController components:
|
||||
// * element existence
|
||||
// * scrubber position validity
|
||||
// * make animations currentTime to change by click on the controller
|
||||
// * mouse drag on the scrubber
|
||||
|
||||
add_task(async function () {
|
||||
await addTab(URL_ROOT + "doc_multi_timings.html");
|
||||
const { animationInspector, inspector, panel } = await openAnimationInspector();
|
||||
|
||||
info("Checking scrubber controller existence");
|
||||
const controllerEl = panel.querySelector(".current-time-scrubber-controller");
|
||||
ok(controllerEl, "scrubber controller should exist");
|
||||
|
||||
info("Checking scrubber existence");
|
||||
const scrubberEl = controllerEl.querySelector(".current-time-scrubber");
|
||||
ok(scrubberEl, "scrubber should exist");
|
||||
|
||||
info("Checking scrubber changes current time of animation and the position");
|
||||
await selectNodeAndWaitForAnimations(".enddelay-with-iterations-infinity", inspector);
|
||||
const duration = animationInspector.state.timeScale.getDuration();
|
||||
await clickOnCurrentTimeScrubberController(animationInspector, panel, 0);
|
||||
assertAnimationsCurrentTime(animationInspector, 0);
|
||||
assertPosition(scrubberEl, controllerEl, 0, animationInspector);
|
||||
|
||||
await clickOnCurrentTimeScrubberController(animationInspector, panel, 1);
|
||||
assertAnimationsCurrentTime(animationInspector, duration);
|
||||
assertPosition(scrubberEl, controllerEl, duration, animationInspector);
|
||||
|
||||
await clickOnCurrentTimeScrubberController(animationInspector, panel, 0.5);
|
||||
assertAnimationsCurrentTime(animationInspector, duration * 0.5);
|
||||
assertPosition(scrubberEl, controllerEl, duration * 0.5, animationInspector);
|
||||
|
||||
info("Checking current time scrubber position during running");
|
||||
// Running again
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
let previousX = scrubberEl.getBoundingClientRect().x;
|
||||
await wait(100);
|
||||
let currentX = scrubberEl.getBoundingClientRect().x;
|
||||
isnot(previousX, currentX, "Scrubber should be moved");
|
||||
|
||||
info("Checking draggable on scrubber over animation list");
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
previousX = scrubberEl.getBoundingClientRect().x;
|
||||
await dragOnCurrentTimeScrubber(animationInspector, panel, 0.5, 2, 30);
|
||||
currentX = scrubberEl.getBoundingClientRect().x;
|
||||
isnot(previousX, currentX, "Scrubber should be draggable");
|
||||
|
||||
info("Checking a behavior which mouse out from animation inspector area " +
|
||||
"during dragging from controller");
|
||||
await dragOnCurrentTimeScrubberController(animationInspector, panel, 0.5, 2);
|
||||
ok(!panel.querySelector(".animation-list-container")
|
||||
.classList.contains("active-scrubber"), "Click and DnD should be inactive");
|
||||
});
|
||||
|
||||
function assertPosition(scrubberEl, controllerEl, time, animationInspector) {
|
||||
const controllerBounds = controllerEl.getBoundingClientRect();
|
||||
const scrubberBounds = scrubberEl.getBoundingClientRect();
|
||||
const scrubberX = scrubberBounds.x + scrubberBounds.width / 2 - controllerBounds.x;
|
||||
const timeScale = animationInspector.state.timeScale;
|
||||
const expected = Math.round(time / timeScale.getDuration() * controllerBounds.width);
|
||||
is(scrubberX, expected, `Position should be ${ expected } at ${ time }ms`);
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test for following KeyframesProgressBar:
|
||||
// * element existence
|
||||
// * progress bar position in multi effect timings
|
||||
// * progress bar position after changing playback rate
|
||||
// * progress bar position when select another animation
|
||||
|
||||
const POSITION_TESTCASES = [
|
||||
{
|
||||
targetClassName: "cssanimation-linear",
|
||||
scrubberPositions: [0, 0.25, 0.5, 0.75, 1],
|
||||
expectedPositions: [0, 0.25, 0.5, 0.75, 0],
|
||||
},
|
||||
{
|
||||
targetClassName: "easing-step",
|
||||
scrubberPositions: [0, 0.49, 0.5, 0.99],
|
||||
expectedPositions: [0, 0, 0.5, 0.5],
|
||||
},
|
||||
{
|
||||
targetClassName: "delay-positive",
|
||||
scrubberPositions: [0, 0.33, 0.5],
|
||||
expectedPositions: [0, 0, 0.25],
|
||||
},
|
||||
{
|
||||
targetClassName: "delay-negative",
|
||||
scrubberPositions: [0, 0.49, 0.5, 0.75],
|
||||
expectedPositions: [0, 0, 0.5, 0.75],
|
||||
},
|
||||
{
|
||||
targetClassName: "enddelay-positive",
|
||||
scrubberPositions: [0, 0.66, 0.67, 0.99],
|
||||
expectedPositions: [0, 0.99, 0, 0],
|
||||
},
|
||||
{
|
||||
targetClassName: "enddelay-negative",
|
||||
scrubberPositions: [0, 0.49, 0.5, 0.99],
|
||||
expectedPositions: [0, 0.49, 0, 0],
|
||||
},
|
||||
{
|
||||
targetClassName: "direction-reverse-with-iterations-infinity",
|
||||
scrubberPositions: [0, 0.25, 0.5, 0.75, 1],
|
||||
expectedPositions: [1, 0.75, 0.5, 0.25, 1],
|
||||
},
|
||||
{
|
||||
targetClassName: "fill-both-width-delay-iterationstart",
|
||||
scrubberPositions: [0, 0.33, 0.66, 0.833, 1],
|
||||
expectedPositions: [0.5, 0.5, 0.99, 0.25, 0.5],
|
||||
},
|
||||
];
|
||||
|
||||
add_task(async function () {
|
||||
await addTab(URL_ROOT + "doc_multi_timings.html");
|
||||
const { animationInspector, inspector, panel } = await openAnimationInspector();
|
||||
|
||||
info("Checking progress bar position in multi effect timings");
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
|
||||
for (const testcase of POSITION_TESTCASES) {
|
||||
info(`Checking progress bar position for ${ testcase.targetClassName }`);
|
||||
await selectNodeAndWaitForAnimations(`.${ testcase.targetClassName }`, inspector);
|
||||
|
||||
info("Checking progress bar existence");
|
||||
const areaEl = panel.querySelector(".keyframes-progress-bar-area");
|
||||
ok(areaEl, "progress bar area should exist");
|
||||
const barEl = areaEl.querySelector(".keyframes-progress-bar");
|
||||
ok(barEl, "progress bar should exist");
|
||||
|
||||
const scrubberPositions = testcase.scrubberPositions;
|
||||
const expectedPositions = testcase.expectedPositions;
|
||||
|
||||
for (let i = 0; i < scrubberPositions.length; i++) {
|
||||
info(`Scrubber position is ${ scrubberPositions[i] }`);
|
||||
await clickOnCurrentTimeScrubberController(animationInspector,
|
||||
panel, scrubberPositions[i]);
|
||||
assertPosition(barEl, areaEl, expectedPositions[i], animationInspector);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function assertPosition(barEl, areaEl, expectedRate, animationInspector) {
|
||||
const controllerBounds = areaEl.getBoundingClientRect();
|
||||
const barBounds = barEl.getBoundingClientRect();
|
||||
const barX = barBounds.x + barBounds.width / 2 - controllerBounds.x;
|
||||
const expected = controllerBounds.width * expectedRate;
|
||||
ok(expected - 1 < barX && barX < expected + 1,
|
||||
`Position should apploximately be ${ expected } (x of bar is ${ barX })`);
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Animation inspector makes the current time to stop
|
||||
// after end of animation duration except iterations infinity.
|
||||
// Test followings:
|
||||
// * state of animations and UI components after end of animation duration
|
||||
// * state of animations and UI components after end of animation duration
|
||||
// but iteration count is infinity
|
||||
|
||||
add_task(async function () {
|
||||
await addTab(URL_ROOT + "doc_multi_timings.html");
|
||||
const { animationInspector, inspector, panel } = await openAnimationInspector();
|
||||
|
||||
info("Checking state after end of animation duration");
|
||||
await selectNodeAndWaitForAnimations(".easing-step", inspector);
|
||||
const pixelsData = getDurationAndRate(animationInspector, panel, 5);
|
||||
await clickOnCurrentTimeScrubberController(animationInspector,
|
||||
panel, 1 - pixelsData.rate);
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
// Must be able to catch rendering event after stopping the animation.
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
await assertStates(animationInspector, panel, false);
|
||||
|
||||
info("Checking state after end of animation duration and infinity iterations");
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
await selectNodeAndWaitForAnimations(".enddelay-with-iterations-infinity", inspector);
|
||||
await clickOnCurrentTimeScrubberController(animationInspector, panel, 1);
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
await assertStates(animationInspector, panel, true);
|
||||
});
|
||||
|
||||
async function assertStates(animationInspector, panel, shouldRunning) {
|
||||
const buttonEl = panel.querySelector(".pause-resume-button");
|
||||
const labelEl = panel.querySelector(".current-time-label");
|
||||
const scrubberEl = panel.querySelector(".current-time-scrubber");
|
||||
|
||||
const previousLabelContent = labelEl.textContent;
|
||||
const previousScrubberX = scrubberEl.getBoundingClientRect().x;
|
||||
await wait(100);
|
||||
const currentLabelContent = labelEl.textContent;
|
||||
const currentScrubberX = scrubberEl.getBoundingClientRect().x;
|
||||
|
||||
if (shouldRunning) {
|
||||
isnot(previousLabelContent, currentLabelContent,
|
||||
"Current time label content should change");
|
||||
isnot(previousScrubberX, currentScrubberX,
|
||||
"Current time scrubber position should change");
|
||||
ok(!buttonEl.classList.contains("paused"),
|
||||
"State of button should be running");
|
||||
assertAnimationsRunning(animationInspector, panel);
|
||||
} else {
|
||||
is(previousLabelContent, currentLabelContent,
|
||||
"Current time label Content should not change");
|
||||
is(previousScrubberX, currentScrubberX,
|
||||
"Current time scrubber position should not change");
|
||||
ok(buttonEl.classList.contains("paused"),
|
||||
"State of button should be paused");
|
||||
assertAnimationsPausing(animationInspector, panel);
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test for following PauseResumeButton component:
|
||||
// * element existence
|
||||
// * state during running animations
|
||||
// * state during pausing animations
|
||||
// * make animations to pause by push button
|
||||
// * make animations to resume by push button
|
||||
|
||||
add_task(async function () {
|
||||
await addTab(URL_ROOT + "doc_custom_playback_rate.html");
|
||||
const { animationInspector, panel } = await openAnimationInspector();
|
||||
|
||||
info("Checking pause/resume button existence");
|
||||
const buttonEl = panel.querySelector(".pause-resume-button");
|
||||
ok(buttonEl, "pause/resume button should exist");
|
||||
|
||||
info("Checking state during running animations");
|
||||
ok(!buttonEl.classList.contains("paused"), "State of button should be running");
|
||||
|
||||
info("Checking button makes animations to pause");
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
assertAnimationsPausing(animationInspector, panel);
|
||||
ok(buttonEl.classList.contains("paused"), "State of button should be paused");
|
||||
|
||||
info("Checking button makes animations to resume");
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
assertAnimationsRunning(animationInspector, panel);
|
||||
ok(!buttonEl.classList.contains("paused"), "State of button should be resumed");
|
||||
});
|
@ -0,0 +1,33 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test for following PauseResumeButton component with spacebar:
|
||||
// * make animations to pause/resume by spacebar
|
||||
// * combination with other UI components
|
||||
|
||||
add_task(async function () {
|
||||
await addTab(URL_ROOT + "doc_custom_playback_rate.html");
|
||||
const { animationInspector, panel } = await openAnimationInspector();
|
||||
|
||||
info("Checking spacebar makes animations to pause");
|
||||
await sendSpaceKeyEvent(animationInspector, panel);
|
||||
assertAnimationsPausing(animationInspector, panel);
|
||||
await sendSpaceKeyEvent(animationInspector, panel);
|
||||
assertAnimationsRunning(animationInspector, panel);
|
||||
|
||||
info("Checking spacebar works with other UI components");
|
||||
// To pause
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
// To resume
|
||||
await sendSpaceKeyEvent(animationInspector, panel);
|
||||
assertAnimationsRunning(animationInspector, panel);
|
||||
// To pause
|
||||
await clickOnCurrentTimeScrubberController(animationInspector, panel, 0.5);
|
||||
// To resume
|
||||
await clickOnPauseResumeButton(animationInspector, panel);
|
||||
// To pause
|
||||
await sendSpaceKeyEvent(animationInspector, panel);
|
||||
assertAnimationsPausing(animationInspector, panel);
|
||||
});
|
@ -0,0 +1,54 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test for following PlaybackRateSelector component:
|
||||
// * element existence
|
||||
// * make playback rate of animations by the selector
|
||||
// * in case of animations have mixed playback rate
|
||||
// * in case of animations have playback rate which is not default selectable value
|
||||
|
||||
add_task(async function () {
|
||||
await addTab(URL_ROOT + "doc_custom_playback_rate.html");
|
||||
const { animationInspector, inspector, panel } = await openAnimationInspector();
|
||||
|
||||
info("Checking playback rate selector existence");
|
||||
const selectEl = panel.querySelector(".playback-rate-selector");
|
||||
ok(selectEl, "scrubber controller should exist");
|
||||
|
||||
info("Checking playback rate existence which includes custom rate of animations");
|
||||
const selectableRates = [0.1, 0.25, 0.5, 1, 1.5, 2, 5, 10];
|
||||
is(selectEl.options.length, selectableRates.length,
|
||||
`Length of options should be ${ selectableRates.length }`);
|
||||
for (let i = 0; i < selectEl.options.length; i++) {
|
||||
const optionEl = selectEl.options[i];
|
||||
const selectableRate = selectableRates[i];
|
||||
is(Number(optionEl.value), selectableRate,
|
||||
`Option of index[${ i }] should be ${ selectableRate }`);
|
||||
}
|
||||
|
||||
info("Checking selected playback rate");
|
||||
is(Number(selectEl.value), 1.5, "Selected option should be 1.5");
|
||||
|
||||
info("Checking playback rate of animations");
|
||||
await clickOnPlaybackRateSelector(animationInspector, panel, 0.5);
|
||||
assertPlaybackRate(animationInspector, 0.5);
|
||||
|
||||
info("Checking mixed playback rate");
|
||||
await selectNodeAndWaitForAnimations("div", inspector);
|
||||
await clickOnPlaybackRateSelector(animationInspector, panel, 2);
|
||||
assertPlaybackRate(animationInspector, 2);
|
||||
await selectNodeAndWaitForAnimations("body", inspector);
|
||||
is(selectEl.value, "", "Selected option should be empty");
|
||||
|
||||
info("Checking playback rate after re-setting");
|
||||
await clickOnPlaybackRateSelector(animationInspector, panel, 1);
|
||||
assertPlaybackRate(animationInspector, 1);
|
||||
});
|
||||
|
||||
async function assertPlaybackRate(animationInspector, rate) {
|
||||
const isRateEqual =
|
||||
animationInspector.state.animations.every(({state}) => state.playbackRate === rate);
|
||||
ok(isRateEqual, `Playback rate of animations should be ${ rate }`);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test for following RewindButton component:
|
||||
// * element existence
|
||||
// * make animations to rewind to zero
|
||||
// * the state should be always paused after rewinding
|
||||
|
||||
add_task(async function () {
|
||||
await addTab(URL_ROOT + "doc_custom_playback_rate.html");
|
||||
const { animationInspector, panel } = await openAnimationInspector();
|
||||
|
||||
info("Checking button existence");
|
||||
ok(panel.querySelector(".rewind-button"), "Rewind button should exist");
|
||||
|
||||
info("Checking rewind button makes animations to rewind to zero");
|
||||
await clickOnRewindButton(animationInspector, panel);
|
||||
assertAnimationsCurrentTime(animationInspector, 0);
|
||||
assertAnimationsPausing(animationInspector, panel);
|
||||
|
||||
info("Checking rewind button makes animations after clicking scrubber");
|
||||
await clickOnCurrentTimeScrubberController(animationInspector, panel, 0.5);
|
||||
await clickOnRewindButton(animationInspector, panel);
|
||||
assertAnimationsCurrentTime(animationInspector, 0);
|
||||
assertAnimationsPausing(animationInspector, panel);
|
||||
});
|
@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<style>
|
||||
div {
|
||||
background-color: lime;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
const duration = 100000;
|
||||
|
||||
function createAnimation() {
|
||||
const div = document.createElement("div");
|
||||
document.body.appendChild(div);
|
||||
const animation = div.animate([{ opacity: 0 }], duration);
|
||||
animation.playbackRate = 1.5;
|
||||
}
|
||||
|
||||
createAnimation();
|
||||
createAnimation();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -121,6 +121,178 @@ const clickOnDetailCloseButton = function (panel) {
|
||||
EventUtils.synthesizeMouse(buttonEl, x, y, {}, buttonEl.ownerGlobal);
|
||||
};
|
||||
|
||||
/**
|
||||
* Click on pause/resume button.
|
||||
*
|
||||
* @param {AnimationInspector} animationInspector
|
||||
* @param {AnimationsPanel} panel
|
||||
* The panel instance.
|
||||
*/
|
||||
const clickOnPauseResumeButton = async function (animationInspector, panel) {
|
||||
info("Click on pause/resume button");
|
||||
const buttonEl = panel.querySelector(".pause-resume-button");
|
||||
const bounds = buttonEl.getBoundingClientRect();
|
||||
const x = bounds.width / 2;
|
||||
const y = bounds.height / 2;
|
||||
EventUtils.synthesizeMouse(buttonEl, x, y, {}, buttonEl.ownerGlobal);
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Click on rewind button.
|
||||
*
|
||||
* @param {AnimationInspector} animationInspector
|
||||
* @param {AnimationsPanel} panel
|
||||
* The panel instance.
|
||||
*/
|
||||
const clickOnRewindButton = async function (animationInspector, panel) {
|
||||
info("Click on rewind button");
|
||||
const buttonEl = panel.querySelector(".rewind-button");
|
||||
const bounds = buttonEl.getBoundingClientRect();
|
||||
const x = bounds.width / 2;
|
||||
const y = bounds.height / 2;
|
||||
EventUtils.synthesizeMouse(buttonEl, x, y, {}, buttonEl.ownerGlobal);
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Click on the scrubber controller pane to update the animation current time.
|
||||
*
|
||||
* @param {AnimationsPanel} panel
|
||||
* @param {Number} mouseDownPosition
|
||||
* rate on scrubber controller pane.
|
||||
* This method calculates
|
||||
* `mouseDownPosition * offsetWidth + offsetLeft of scrubber controller pane`
|
||||
* as the clientX of MouseEvent.
|
||||
*/
|
||||
const clickOnCurrentTimeScrubberController = async function (animationInspector,
|
||||
panel,
|
||||
mouseDownPosition,
|
||||
mouseMovePosition) {
|
||||
const controllerEl = panel.querySelector(".current-time-scrubber-controller");
|
||||
const bounds = controllerEl.getBoundingClientRect();
|
||||
const mousedonwX = bounds.width * mouseDownPosition;
|
||||
|
||||
info(`Click ${ mousedonwX } on scrubber controller`);
|
||||
EventUtils.synthesizeMouse(controllerEl, mousedonwX, 0, {}, controllerEl.ownerGlobal);
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Click on playback rate selector to select given rate.
|
||||
*
|
||||
* @param {AnimationInspector} animationInspector
|
||||
* @param {AnimationsPanel} panel
|
||||
* @param {Number} rate
|
||||
*/
|
||||
const clickOnPlaybackRateSelector = async function (animationInspector, panel, rate) {
|
||||
info(`Click on playback rate selector to select ${rate}`);
|
||||
const selectEl = panel.querySelector(".playback-rate-selector");
|
||||
const optionEl = [...selectEl.options].filter(o => Number(o.value) === rate)[0];
|
||||
|
||||
if (!optionEl) {
|
||||
ok(false, `Could not find an option for rate ${ rate } in the rate selector. ` +
|
||||
`Values are: ${ [...selectEl.options].map(o => o.value) }`);
|
||||
return;
|
||||
}
|
||||
|
||||
const win = selectEl.ownerGlobal;
|
||||
EventUtils.synthesizeMouseAtCenter(selectEl, { type: "mousedown" }, win);
|
||||
EventUtils.synthesizeMouseAtCenter(optionEl, { type: "mouseup" }, win);
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Drag on the scrubber to update the animation current time.
|
||||
*
|
||||
* @param {AnimationsPanel} panel
|
||||
* @param {Number} mouseDownPosition
|
||||
* rate on scrubber controller pane.
|
||||
* This method calculates
|
||||
* `mouseDownPosition * offsetWidth + offsetLeft of scrubber controller pane`
|
||||
* as the clientX of MouseEvent.
|
||||
* @param {Number} mouseMovePosition
|
||||
* Dispatch mousemove event with mouseMovePosition after mousedown.
|
||||
* Calculation for clinetX is same to above.
|
||||
* @param {Number} mouseYPixel
|
||||
* Y of mouse in pixel.
|
||||
*/
|
||||
const dragOnCurrentTimeScrubber = async function (animationInspector,
|
||||
panel,
|
||||
mouseDownPosition,
|
||||
mouseMovePosition,
|
||||
mouseYPixel) {
|
||||
const controllerEl = panel.querySelector(".current-time-scrubber");
|
||||
const bounds = controllerEl.getBoundingClientRect();
|
||||
const mousedonwX = bounds.width * mouseDownPosition;
|
||||
const mousemoveX = bounds.width * mouseMovePosition;
|
||||
|
||||
info(`Drag on scrubber from ${ mousedonwX } to ${ mousemoveX }`);
|
||||
EventUtils.synthesizeMouse(controllerEl, mousedonwX, mouseYPixel,
|
||||
{ type: "mousedown" }, controllerEl.ownerGlobal);
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
EventUtils.synthesizeMouse(controllerEl, mousemoveX, mouseYPixel,
|
||||
{ type: "mousemove" }, controllerEl.ownerGlobal);
|
||||
EventUtils.synthesizeMouse(controllerEl, mousemoveX, mouseYPixel,
|
||||
{ type: "mouseup" }, controllerEl.ownerGlobal);
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Drag on the scrubber controller pane to update the animation current time.
|
||||
*
|
||||
* @param {AnimationsPanel} panel
|
||||
* @param {Number} mouseDownPosition
|
||||
* rate on scrubber controller pane.
|
||||
* This method calculates
|
||||
* `mouseDownPosition * offsetWidth + offsetLeft of scrubber controller pane`
|
||||
* as the clientX of MouseEvent.
|
||||
* @param {Number} mouseMovePosition
|
||||
* Dispatch mousemove event with mouseMovePosition after mousedown.
|
||||
* Calculation for clinetX is same to above.
|
||||
*/
|
||||
const dragOnCurrentTimeScrubberController = async function (animationInspector,
|
||||
panel,
|
||||
mouseDownPosition,
|
||||
mouseMovePosition) {
|
||||
const controllerEl = panel.querySelector(".current-time-scrubber-controller");
|
||||
const bounds = controllerEl.getBoundingClientRect();
|
||||
const mousedonwX = bounds.width * mouseDownPosition;
|
||||
const mousemoveX = bounds.width * mouseMovePosition;
|
||||
|
||||
info(`Drag on scrubber controller from ${ mousedonwX } to ${ mousemoveX }`);
|
||||
EventUtils.synthesizeMouse(controllerEl, mousedonwX, 0,
|
||||
{ type: "mousedown" }, controllerEl.ownerGlobal);
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
EventUtils.synthesizeMouse(controllerEl, mousemoveX, 0,
|
||||
{ type: "mousemove" }, controllerEl.ownerGlobal);
|
||||
EventUtils.synthesizeMouse(controllerEl, mousemoveX, 0,
|
||||
{ type: "mouseup" }, controllerEl.ownerGlobal);
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get current animation duration and rate of
|
||||
* clickOrDragOnCurrentTimeScrubberController in given pixels.
|
||||
*
|
||||
* @param {AnimationInspector} animationInspector
|
||||
* @param {AnimationsPanel} panel
|
||||
* @param {Number} pixels
|
||||
* @return {Object}
|
||||
* {
|
||||
* duration,
|
||||
* rate,
|
||||
* }
|
||||
*/
|
||||
const getDurationAndRate = function (animationInspector, panel, pixels) {
|
||||
const controllerEl = panel.querySelector(".current-time-scrubber-controller");
|
||||
const bounds = controllerEl.getBoundingClientRect();
|
||||
const duration =
|
||||
animationInspector.state.timeScale.getDuration() / bounds.width * pixels;
|
||||
const rate = 1 / bounds.width * pixels;
|
||||
return { duration, rate };
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -144,6 +316,18 @@ const selectNodeAndWaitForAnimations = async function (data, inspector, reason =
|
||||
await waitForRendering(inspector.animationinspector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Send keyboard event of space to given panel.
|
||||
*
|
||||
* @param {AnimationInspector} animationInspector
|
||||
* @param {AnimationsPanel} panel
|
||||
*/
|
||||
const sendSpaceKeyEvent = async function (animationInspector, panel) {
|
||||
panel.focus();
|
||||
EventUtils.sendKey("SPACE", panel.ownerGlobal);
|
||||
await waitForSummaryAndDetail(animationInspector);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the sidebar width by given parameter.
|
||||
*
|
||||
@ -178,7 +362,8 @@ const waitForRendering = async function (animationInspector) {
|
||||
* @param {AnimationInspector} inspector
|
||||
*/
|
||||
const waitForAnimationDetail = async function (animationInspector) {
|
||||
if (animationInspector.state.animations.length === 1) {
|
||||
if (animationInspector.state.selectedAnimation &&
|
||||
animationInspector.state.detailVisibility) {
|
||||
await animationInspector.once("animation-keyframes-rendered");
|
||||
}
|
||||
};
|
||||
@ -206,6 +391,69 @@ const waitForAllSummaryGraph = async function (animationInspector) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Wait for rendering of all summary graph and detail.
|
||||
*
|
||||
* @param {AnimationInspector} inspector
|
||||
*/
|
||||
const waitForSummaryAndDetail = async function (animationInspector) {
|
||||
await Promise.all([
|
||||
waitForAllSummaryGraph(animationInspector),
|
||||
waitForAnimationDetail(animationInspector),
|
||||
]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether current time of all animations and UI are given specified time.
|
||||
*
|
||||
* @param {AnimationInspector} animationInspector
|
||||
* @param {AnimationsPanel} panel
|
||||
* @param {Number} time
|
||||
*/
|
||||
function assertAnimationsCurrentTime(animationInspector, time) {
|
||||
const isTimeEqual =
|
||||
animationInspector.state.animations.every(({state}) => state.currentTime === time);
|
||||
ok(isTimeEqual, `Current time of animations should be ${ time }`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the animations are pausing.
|
||||
*
|
||||
* @param {AnimationInspector} animationInspector
|
||||
* @param {AnimationsPanel} panel
|
||||
*/
|
||||
function assertAnimationsPausing(animationInspector, panel) {
|
||||
assertAnimationsPausingOrRunning(animationInspector, panel, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the animations are pausing/running.
|
||||
*
|
||||
* @param {AnimationInspector} animationInspector
|
||||
* @param {AnimationsPanel} panel
|
||||
* @param {boolean} shouldPause
|
||||
*/
|
||||
function assertAnimationsPausingOrRunning(animationInspector, panel, shouldPause) {
|
||||
const hasRunningAnimation =
|
||||
animationInspector.state.animations.some(({state}) => state.playState === "running");
|
||||
|
||||
if (shouldPause) {
|
||||
is(hasRunningAnimation, false, "All animations should be paused");
|
||||
} else {
|
||||
is(hasRunningAnimation, true, "Animations should be running at least one");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the animations are running.
|
||||
*
|
||||
* @param {AnimationInspector} animationInspector
|
||||
* @param {AnimationsPanel} panel
|
||||
*/
|
||||
function assertAnimationsRunning(animationInspector, panel) {
|
||||
assertAnimationsPausingOrRunning(animationInspector, panel, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the <stop> element in the given linearGradientEl for the correct offset
|
||||
* and color attributes.
|
||||
|
Loading…
Reference in New Issue
Block a user