summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/css/css-transitions/CSSTransition-canceling.tentative.html
blob: 72b1dbff436fd12574beece0dd295ca3d779b73c (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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
<!doctype html>
<meta charset=utf-8>
<title>Canceling a CSS transition</title>
<link rel="help" href="https://drafts.csswg.org/css-transitions/#starting">
<!-- TODO: Add a more specific link for this once it is specified. -->
<link rel="help" href="https://drafts.csswg.org/css-transitions-2/#csstransition">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/helper.js"></script>
<div id="log"></div>
<script>
'use strict';

promise_test(async t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  await transition.ready;
  await waitForFrame();

  assert_not_equals(getComputedStyle(div).marginLeft, '1000px',
                    'transform style is animated before canceling');
  transition.cancel();
  assert_equals(getComputedStyle(div).marginLeft, div.style.marginLeft,
                'transform style is no longer animated after canceling');
}, 'Animated style is cleared after canceling a running CSS transition');

promise_test(async t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  await transition.ready;

  transition.cancel();
  assert_equals(getComputedStyle(div).marginLeft, '1000px',
                'margin-left style is not animated after canceling');
  transition.play();
  assert_equals(getComputedStyle(div).marginLeft, '0px',
                'margin-left style is animated after re-starting transition');

  await transition.ready;

  assert_equals(transition.playState, 'running',
                'Transition succeeds in running after being re-started');
}, 'After canceling a transition, it can still be re-used');

promise_test(async t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  await transition.ready;

  transition.finish();
  transition.cancel();
  assert_equals(getComputedStyle(div).marginLeft, '1000px',
                'margin-left style is not animated after canceling');
  transition.play();
  assert_equals(getComputedStyle(div).marginLeft, '0px',
                'margin-left style is animated after re-starting transition');

  await transition.ready;

  assert_equals(transition.playState, 'running',
                'Transition succeeds in running after being re-started');
}, 'After canceling a finished transition, it can still be re-used');

test(t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  transition.cancel();
  assert_equals(getComputedStyle(div).marginLeft, '1000px',
                'margin-left style is not animated after canceling');

  // Trigger a change to a transition property and check that this
  // doesn't cause the animation to become live again
  div.style.transitionDuration = '200s';
  getComputedStyle(div).marginLeft;
  assert_equals(getComputedStyle(div).marginLeft, '1000px',
                'margin-left style is still not animated after updating'
                + ' transition-duration');
  assert_equals(transition.playState, 'idle',
                'Transition is still idle after updating transition-duration');
}, 'After canceling a transition, updating transition properties doesn\'t make'
   + ' it live again');

promise_test(async t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  await transition.ready;

  assert_equals(transition.playState, 'running');
  div.style.display = 'none';

  await waitForFrame();

  assert_equals(transition.playState, 'idle');
  assert_equals(getComputedStyle(div).marginLeft, '1000px');
}, 'Setting display:none on an element cancels its transitions');

promise_test(async t => {
  const parentDiv = addDiv(t);
  const childDiv = document.createElement('div');
  parentDiv.appendChild(childDiv);
  childDiv.setAttribute('style', 'margin-left: 0px');

  getComputedStyle(childDiv).marginLeft;

  childDiv.style.transition = 'margin-left 100s';
  childDiv.style.marginLeft = '1000px';

  const transition = childDiv.getAnimations()[0];
  await transition.ready;

  assert_equals(transition.playState, 'running');
  parentDiv.style.display = 'none';
  await waitForFrame();

  assert_equals(transition.playState, 'idle');
  assert_equals(getComputedStyle(childDiv).marginLeft, '1000px');
}, 'Setting display:none cancels transitions on a child element');

promise_test(async t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  await transition.ready;

  assert_equals(transition.playState, 'running');
  // Set an unrecognized property value
  div.style.transitionProperty = 'none';
  getComputedStyle(div).marginLeft;
  await waitForFrame();

  assert_equals(transition.playState, 'idle');
  assert_equals(getComputedStyle(div).marginLeft, '1000px');
}, 'Removing a property from transition-property cancels transitions on that '+
   'property');

promise_test(async t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  await transition.ready;

  assert_equals(transition.playState, 'running');
  div.style.transition = 'margin-left 10s -10s'; // combined duration is zero

  // Note that simply setting the combined duration to zero is not enough to
  // cancel the transition. We must also update the end value so that the,
  // "the end value of the running transition is not equal to the value of the
  // property in the after-change style" condition is true.
  //
  // (And note that the zero combined duration is not strictly necessary to
  // cancel the original transition--but it does ensure another transition is
  // not generated in its place.)

  div.style.marginLeft = '2000px';
  getComputedStyle(div).marginLeft;
  await waitForFrame();

  assert_equals(transition.playState, 'idle');
  assert_equals(getComputedStyle(div).marginLeft, '2000px');
}, 'Setting zero combined duration');

promise_test(async t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  await transition.ready;

  assert_equals(transition.playState, 'running');
  div.style.marginLeft = '2000px';
  getComputedStyle(div).marginLeft;
  await waitForFrame();

  assert_equals(transition.playState, 'idle');
}, 'Changing style to another interpolable value cancels the original ' +
   'transition');

promise_test(async t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  await transition.ready;

  assert_equals(transition.playState, 'running');
  div.style.marginLeft = 'auto';
  getComputedStyle(div).marginLeft;
  await waitForFrame();

  assert_equals(div.getAnimations().length, 0,
                'There should be no transitions');
  assert_equals(transition.playState, 'idle');
}, 'An after-change style value can\'t be interpolated');

promise_test(async t => {
  const div = addDiv(t, { style: 'margin-left: 0px' });
  getComputedStyle(div).marginLeft;

  div.style.transition = 'margin-left 100s';
  div.style.marginLeft = '1000px';

  const transition = div.getAnimations()[0];
  await transition.ready;

  assert_equals(transition.playState, 'running');
  div.style.marginLeft = '0px';
  getComputedStyle(div).marginLeft;
  await waitForFrame();

  assert_equals(transition.playState, 'idle');
}, 'Reversing a running transition cancels the original transition');

</script>