Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(491)

Side by Side Diff: third_party/WebKit/LayoutTests/animations/responsive/resources/responsive-test.js

Issue 2973013002: Group all responsive animation tests together (Closed)
Patch Set: Rebase Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /*
6 Exported functions:
7 assertCSSResponsive
8 assertSVGResponsive
9
10 Exported objects:
11 neutralKeyframe
12
13 Options format: {
14 ?targetTag: <Target element tag name>,
15 property: <Property/Attribute name>,
16 ?getter(target): <Reads animated value from target>,
17 from: <Value>,
18 to: <Value>,
19 configurations: [{
20 state: {
21 ?underlying: <Value>,
22 ?inherited: <CSS Value>,
23 },
24 expect: [
25 { at: <Float>, is: <Value> },
26 ],
27 }],
28 }
29
30 Description:
31 assertCSSResponsive() and assertSVGResponsive() take a property
32 specific interpolation and a list of style configurations with interpolation
33 expectations that apply to each configuration.
34 It starts the interpolation in every configuration, changes the
35 state to every other configuration (n * (n - 1) complexity) and asserts that
36 each destination configuration's expectations are met.
37 Each animation target can be assigned custom styles via the ".target" selector.
38 This test is designed to catch stale interpolation caches.
39 Set from/to to the exported neutralKeyframe object to use neutral keyframes.
40 */
41
42 (function() {
43 'use strict';
44 var pendingResponsiveTests = [];
45 var htmlNamespace = 'http://www.w3.org/1999/xhtml';
46 var svgNamespace = 'http://www.w3.org/2000/svg';
47 var neutralKeyframe = {};
48
49 function assertCSSResponsive(options) {
50 pendingResponsiveTests.push({
51 options,
52 bindings: {
53 prefixProperty(property) {
54 return toCamelCase(property);
55 },
56 createTargetContainer(container) {
57 if (options.targetTag) {
58 var svgRoot = createElement('svg', container, 'svg-root', svgNamespace );
59 svgRoot.setAttribute('width', 0);
60 svgRoot.setAttribute('height', 0);
61 return svgRoot;
62 }
63
64 return createElement('div', container);
65 },
66 createTarget(container) {
67 if (options.targetTag)
68 return createElement(options.targetTag, container, 'target', svgNamesp ace);
69
70 return createElement('div', container, 'target');
71 },
72 setValue(target, property, value) {
73 test(function() {
74 assert_true(CSS.supports(property, value), 'CSS.supports ' + property + ' ' + value);
75 });
76 target.style[property] = value;
77 },
78 getAnimatedValue(target, property) {
79 return getComputedStyle(target)[property];
80 },
81 },
82 });
83 }
84
85 function assertSVGResponsive(options) {
86 pendingResponsiveTests.push({
87 options,
88 bindings: {
89 prefixProperty(property) {
90 return 'svg-' + property;
91 },
92 createTargetContainer(container) {
93 var svgRoot = createElement('svg', container, 'svg-root', svgNamespace);
94 svgRoot.setAttribute('width', 0);
95 svgRoot.setAttribute('height', 0);
96 return svgRoot;
97 },
98 createTarget(targetContainer) {
99 console.assert(options.targetTag);
100 return createElement(options.targetTag, targetContainer, 'target', svgNa mespace);
101 },
102 setValue(target, property, value) {
103 target.setAttribute(property, value);
104 },
105 getAnimatedValue(target, property) {
106 return options.getter ? options.getter(target) : target[property].animVa l;
107 },
108 },
109 });
110 }
111
112 function createStateTransitions(configurations) {
113 var stateTransitions = [];
114 for (var i = 0; i < configurations.length; i++) {
115 var beforeConfiguration = configurations[i];
116 for (var j = 0; j < configurations.length; j++) {
117 var afterConfiguration = configurations[j];
118 if (j != i) {
119 stateTransitions.push({
120 before: beforeConfiguration,
121 after: afterConfiguration,
122 });
123 }
124 }
125 }
126 return stateTransitions;
127 }
128
129 function createElement(tag, container, className, namespace) {
130 var element = document.createElementNS(namespace || htmlNamespace, tag);
131 if (container) {
132 container.appendChild(element);
133 }
134 if (className) {
135 element.classList.add(className);
136 }
137 return element;
138 }
139
140 function createTargets(bindings, n, container) {
141 var targets = [];
142 for (var i = 0; i < n; i++) {
143 targets.push(bindings.createTarget(container));
144 }
145 return targets;
146 }
147
148 function setState(bindings, targets, property, state) {
149 for (var item in state) {
150 switch (item) {
151 case 'inherited':
152 var parent = targets[0].parentElement;
153 console.assert(targets.every(target => target.parentElement === parent));
154 bindings.setValue(parent, property, state.inherited);
155 break;
156 case 'underlying':
157 for (var target of targets) {
158 bindings.setValue(target, property, state.underlying);
159 }
160 break;
161 default:
162 for (var target of targets) {
163 bindings.setValue(target, item, state[item]);
164 }
165 break;
166 }
167 }
168 }
169
170 function isNeutralKeyframe(keyframe) {
171 return keyframe === neutralKeyframe;
172 }
173
174 function keyframeText(keyframe) {
175 return isNeutralKeyframe(keyframe) ? 'neutral' : `[${keyframe}]`;
176 }
177
178 function toCamelCase(property) {
179 for (var i = property.length - 2; i > 0; --i) {
180 if (property[i] === '-') {
181 property = property.substring(0, i) + property[i + 1].toUpperCase() + prop erty.substring(i + 2);
182 }
183 }
184 return property;
185 }
186
187 function createKeyframes(prefixedProperty, from, to) {
188 var keyframes = [];
189 if (!isNeutralKeyframe(from)) {
190 keyframes.push({
191 offset: 0,
192 [prefixedProperty]: from,
193 });
194 }
195 if (!isNeutralKeyframe(to)) {
196 keyframes.push({
197 offset: 1,
198 [prefixedProperty]: to,
199 });
200 }
201 return keyframes;
202 }
203
204 function createPausedAnimations(targets, keyframes, fractions) {
205 console.assert(targets.length == fractions.length);
206 return targets.map((target, i) => {
207 var fraction = fractions[i];
208 console.assert(fraction >= 0 && fraction < 1);
209 var animation = target.animate(keyframes, 1);
210 animation.pause();
211 animation.currentTime = fraction;
212 return animation;
213 });
214 }
215
216 function runPendingResponsiveTests() {
217 return new Promise(resolve => {
218 var stateTransitionTests = [];
219 pendingResponsiveTests.forEach(responsiveTest => {
220 var options = responsiveTest.options;
221 var bindings = responsiveTest.bindings;
222 var property = options.property;
223 var prefixedProperty = bindings.prefixProperty(property);
224 assert_true('from' in options);
225 assert_true('to' in options);
226 var from = options.from;
227 var to = options.to;
228 var keyframes = createKeyframes(prefixedProperty, from, to);
229
230 var stateTransitions = createStateTransitions(options.configurations);
231 stateTransitions.forEach(stateTransition => {
232 var before = stateTransition.before;
233 var after = stateTransition.after;
234 var container = bindings.createTargetContainer(document.body);
235 var targets = createTargets(bindings, after.expect.length, container);
236 var expectationTargets = createTargets(bindings, after.expect.length, co ntainer);
237
238 setState(bindings, targets, property, before.state);
239 var animations = createPausedAnimations(targets, keyframes, after.expect .map(expectation => expectation.at));
240 stateTransitionTests.push({
241 applyStateTransition() {
242 setState(bindings, targets, property, after.state);
243 },
244 assert() {
245 for (var i = 0; i < targets.length; i++) {
246 var target = targets[i];
247 var expectation = after.expect[i];
248 var expectationTarget = expectationTargets[i];
249 bindings.setValue(expectationTarget, property, expectation.is);
250 var actual = bindings.getAnimatedValue(target, property);
251 test(() => {
252 assert_equals(actual, bindings.getAnimatedValue(expectationTarge t, property));
253 }, `Animation on property <${prefixedProperty}> from ${keyframeTex t(from)} to ${keyframeText(to)} with ${JSON.stringify(before.state)} changed to ${JSON.stringify(after.state)} at (${expectation.at}) is [${expectation.is}]`);
254 }
255 },
256 });
257 });
258 });
259
260 requestAnimationFrame(() => {
261 for (var stateTransitionTest of stateTransitionTests) {
262 stateTransitionTest.applyStateTransition();
263 }
264
265 requestAnimationFrame(() => {
266 for (var stateTransitionTest of stateTransitionTests) {
267 stateTransitionTest.assert();
268 }
269 resolve();
270 });
271 });
272 });
273 }
274
275 function loadScript(url) {
276 return new Promise(resolve => {
277 var script = document.createElement('script');
278 script.src = url;
279 script.onload = resolve;
280 document.head.appendChild(script);
281 });
282 }
283
284 loadScript('../../resources/testharness.js').then(() => {
285 return loadScript('../../resources/testharnessreport.js');
286 }).then(() => {
287 var asyncHandle = async_test('This test uses responsive-test.js.')
288 runPendingResponsiveTests().then(() => {
289 asyncHandle.done();
290 });
291 });
292
293
294 window.assertCSSResponsive = assertCSSResponsive;
295 window.assertSVGResponsive = assertSVGResponsive;
296 window.neutralKeyframe = neutralKeyframe;
297
298 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698