summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/animation-worklet/inactive-timeline.https.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/animation-worklet/inactive-timeline.https.html
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/animation-worklet/inactive-timeline.https.html')
-rw-r--r--testing/web-platform/tests/animation-worklet/inactive-timeline.https.html139
1 files changed, 139 insertions, 0 deletions
diff --git a/testing/web-platform/tests/animation-worklet/inactive-timeline.https.html b/testing/web-platform/tests/animation-worklet/inactive-timeline.https.html
new file mode 100644
index 0000000000..3938cb3092
--- /dev/null
+++ b/testing/web-platform/tests/animation-worklet/inactive-timeline.https.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Correctness of worklet animation state when timeline becomes newly
+ active or inactive.</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/web-animations/testcommon.js"></script>
+<script src="common.js"></script>
+<style>
+ .scroller {
+ overflow: auto;
+ height: 100px;
+ width: 100px;
+ }
+ .contents {
+ height: 1000px;
+ width: 100%;
+ }
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+function createScroller(test) {
+ var scroller = createDiv(test);
+ scroller.innerHTML = "<div class='contents'></div>";
+ scroller.classList.add('scroller');
+ return scroller;
+}
+
+function createScrollLinkedWorkletAnimation(test) {
+ const timeline = new ScrollTimeline({
+ scrollSource: createScroller(test),
+ });
+ const DURATION = 1000; // ms
+ const KEYFRAMES = { transform: ['translateY(100px)', 'translateY(200px)'] };
+ return new WorkletAnimation('passthrough', new KeyframeEffect(createDiv(test),
+ KEYFRAMES, DURATION), timeline);
+}
+
+setup(setupAndRegisterTests, {explicit_done: true});
+
+function setupAndRegisterTests() {
+ registerPassthroughAnimator().then(() => {
+
+ promise_test(async t => {
+ const animation = createScrollLinkedWorkletAnimation(t);
+ const scroller = animation.timeline.scrollSource;
+ const target = animation.effect.target;
+
+ // There is no direct way to control when local times of composited
+ // animations are synced to the main thread. This test uses another
+ // composited worklet animation with an always active timeline as an
+ // indicator of when the sync is ready. The sync is done when animation
+ // effect's output has changed as a result of advancing the timeline.
+ const animationRef = createScrollLinkedWorkletAnimation(t);
+ const scrollerRef = animationRef.timeline.scrollSource;
+ const targetRef = animationRef.effect.target;
+
+ const maxScroll = scroller.scrollHeight - scroller.clientHeight;
+ scroller.scrollTop = 0.2 * maxScroll;
+
+ // Make the timeline inactive.
+ scroller.style.display = "none"
+ // Force relayout.
+ scroller.scrollTop;
+
+ animation.play();
+ animationRef.play();
+ assert_equals(animation.currentTime, null,
+ 'Initial current time must be unresolved in idle state.');
+ assert_equals(animation.startTime, null,
+ 'Initial start time must be unresolved in idle state.');
+ waitForAnimationFrameWithCondition(_=> {
+ return animation.playState == "running"
+ });
+ assert_equals(animation.currentTime, null,
+ 'Initial current time must be unresolved in playing state.');
+ assert_equals(animation.startTime, null,
+ 'Initial start time must be unresolved in playing state.');
+
+ scrollerRef.scrollTop = 0.2 * maxScroll;
+
+ // Wait until local times are synced back to the main thread.
+ await waitForAnimationFrameWithCondition(_ => {
+ return animationRef.effect.getComputedTiming().localTime == 200;
+ });
+
+ assert_equals(animation.effect.getComputedTiming().localTime, null,
+ 'The underlying effect local time must be undefined while the ' +
+ 'timeline is inactive.');
+
+ // Make the timeline active.
+ scroller.style.display = "";
+ // Wait for new animation frame which allows the timeline to compute new
+ // current time.
+ await waitForNextFrame();
+
+ assert_times_equal(animation.currentTime, 200,
+ 'Current time must be initialized.');
+ assert_times_equal(animation.startTime, 0,
+ 'Start time must be initialized.');
+
+ scrollerRef.scrollTop = 0.4 * maxScroll;
+ // Wait until local times are synced back to the main thread.
+ await waitForAnimationFrameWithCondition(_ => {
+ return animationRef.effect.getComputedTiming().localTime == 400;
+ });
+ assert_times_equal(animation.effect.getComputedTiming().localTime, 200,
+ 'When the timeline becomes newly active, the underlying effect\'s ' +
+ 'timing should be properly updated.');
+
+ // Make the timeline inactive again.
+ scroller.style.display = "none"
+ await waitForNextFrame();
+
+ assert_times_equal(animation.currentTime, 200,
+ 'Current time must be the previous current time.');
+ assert_equals(animation.startTime, null,
+ 'Initial start time must be unresolved.');
+
+ scrollerRef.scrollTop = 0.6 * maxScroll;
+ // Wait until local times are synced back to the main thread.
+ await waitForAnimationFrameWithCondition(_ => {
+ return animationRef.effect.getComputedTiming().localTime == 600;
+ });
+
+ assert_times_equal(animation.effect.getComputedTiming().localTime, 200,
+ 'When the timeline becomes newly inactive, the underlying effect\'s ' +
+ 'timing should stay unchanged.');
+ }, 'When timeline time becomes inactive previous current time must be ' +
+ 'the current time and start time unresolved');
+ done();
+ });
+}
+</script>
+</body> \ No newline at end of file