summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/scroll-animations/scroll-timelines/scroll-animation-inactive-timeline.html
blob: 02220cee141b0f33591c7e8a00ff8013b15e5219 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<!DOCTYPE html>
<meta charset=utf-8>
<title>Test basic functionality of scroll linked animation.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/web-animations/testcommon.js"></script>
<script src="testcommon.js"></script>
<style>
  .scroller {
    overflow: auto;
    height: 100px;
    width: 100px;
    will-change: transform;
  }

  .contents {
    height: 1000px;
    width: 100%;
  }
</style>
<div id="log"></div>
<script>
'use strict';

promise_test(async t => {
    const animation = createScrollLinkedAnimation(t);
    const scroller = animation.timeline.source;

    // Ensure we have a valid animation frame time before continuing the test.
    // This is so that we can properly determine frame advancement after the
    // style change.
    await waitForNextFrame();

    // Make the scroll timeline inactive.
    scroller.style.overflow = 'visible';
    // Wait for new animation frame which allows the timeline to compute new
    // current time.
    await waitForNextFrame();
    assert_equals(animation.timeline.currentTime, null,
                  'Sanity check the timeline is inactive.');
    // Play the animation when the timeline is inactive.
    animation.play();
    assert_equals(animation.currentTime, null,
                  'The current time is null when the timeline is inactive.');
    assert_equals(animation.startTime, null,
                  'The start time is unresolved while play-pending.');
    await waitForNextFrame();
    assert_true(animation.pending,
                'Animation has play pending task while timeline is inactive.');
    assert_equals(animation.playState, 'running',
                  `State is 'running' in Pending state.`);
}, `Play pending task doesn't run when the timeline is inactive.`);

promise_test(async t => {
    const animation = createScrollLinkedAnimation(t);
    const scroller = animation.timeline.source;

    await waitForNextFrame();

    // Make the scroll timeline inactive.
    scroller.style.overflow = 'visible';
    // Wait for new animation frame which allows the timeline to compute new
    // current time.
    await waitForNextFrame();
    assert_equals(animation.timeline.currentTime, null,
                  'Sanity check the timeline is inactive.');
    // Play the animation when the timeline is inactive.
    animation.play();

    // Make the scroll timeline active.
    scroller.style.overflow = 'auto';
    await animation.ready;
    // Ready promise is resolved as a result of the timeline becoming active.
    assert_percents_equal(animation.currentTime, 0,
        'Animation current time is resolved when the animation is ready.');
    assert_percents_equal(animation.startTime, 0,
        'Animation start time is resolved when the animation is ready.');
}, 'Animation start and current times are correct if scroll timeline is ' +
   'activated after animation.play call.');

promise_test(async t => {
    const animation = createScrollLinkedAnimation(t);
    const scroller = animation.timeline.source;
    const target = animation.effect.target;

    await waitForNextFrame();

    // Make the scroll timeline inactive.
    scroller.style.overflow = 'visible';
    scroller.scrollTop;
    // Wait for new animation frame which allows the timeline to compute new
    // current time.
    await waitForNextFrame();
    assert_equals(animation.timeline.currentTime, null,
                  'Sanity check the timeline is inactive.');
    // Set start time when the timeline is inactive.
    animation.startTime = CSSNumericValue.parse("0%");
    assert_equals(animation.currentTime, null,
                  'Sanity check current time is unresolved when the timeline ' +
                  'is inactive.');

    // Make the scroll timeline active.
    scroller.style.overflow = 'auto';
    // Wait for new animation frame which allows the timeline to compute new
    // current time.
    await waitForNextFrame();

    assert_percents_equal(animation.currentTime, 0,
        'Animation current time is resolved when the timeline is active.');
    assert_percents_equal(animation.startTime, 0,
                          'Animation start time is resolved.');
    assert_percents_equal(animation.effect.getComputedTiming().localTime, 0,
        'Effect local time is resolved when the timeline is active.');
    assert_equals(Number(getComputedStyle(target).opacity), 0,
        'Animation has an effect when the timeline is active.');
}, 'Animation start and current times are correct if scroll timeline is ' +
   'activated after setting start time.');

promise_test(async t => {
    const animation = createScrollLinkedAnimation(t);
    const scroller = animation.timeline.source;
    const maxScroll = scroller.scrollHeight - scroller.clientHeight;
    const target = animation.effect.target;

    await waitForNextFrame();

    // Advance the scroller.
    scroller.scrollTop = 0.2 * maxScroll;

    // Wait for new animation frame which allows the timeline to compute new
    // current time.
    await waitForNextFrame();
    // Play the animation when the timeline is active.
    animation.play();
    await animation.ready;

    // Make the scroll timeline inactive.
    scroller.style.overflow = 'visible';
    scroller.scrollTop;
    await waitForNextFrame();
    assert_equals(animation.timeline.currentTime, null,
                  'Sanity check the timeline is inactive.');
    assert_equals(animation.playState, 'running',
                  `State is 'running' when the timeline is inactive.`);
    assert_equals(animation.currentTime, null,
                  'Current time is unresolved when the timeline is inactive.');
    assert_percents_equal(animation.startTime, 0,
                          'Start time is zero when the timeline is inactive.');
    assert_equals(animation.effect.getComputedTiming().localTime, null,
                  'Effect local time is null when the timeline is inactive.');
    assert_equals(Number(getComputedStyle(target).opacity), 1,
        'Animation does not have an effect when the timeline is inactive.');

    // Make the scroll timeline active.
    scroller.style.overflow = 'auto';
    await waitForNextFrame();

    assert_equals(animation.playState, 'running',
                  `State is 'running' when the timeline is active.`);
    assert_percents_equal(animation.currentTime, 20,
        'Current time is resolved when the timeline is active.');
    assert_percents_equal(animation.startTime, 0,
                          'Start time is zero when the timeline is active.');
    assert_percents_equal(animation.effect.getComputedTiming().localTime, 20,
        'Effect local time is resolved when the timeline is active.');
    assert_equals(Number(getComputedStyle(target).opacity), 0.2,
        'Animation has an effect when the timeline is active.');
}, 'Animation current time is correct when the timeline becomes newly ' +
   'inactive and then active again.');
</script>