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

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

Issue 1181253006: Add test for style responsive animation behaviour (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « LayoutTests/animations/responsive/left-responsive.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 function:
7 assertResponsive
8
9 Call signature:
10 assertResponsive({
11 property: <CSS Property>,
12 from: ?<CSS Value>,
13 to: ?<CSS Value>,
14 configurations: [{
15 state: {
16 ?targetStyle: { <CSS Property>: <CSS Value> },
17 ?parentStyle: { <CSS Property>: <CSS Value> },
18 },
19 expect: [
20 { at: <Float>, is: <CSS Value> }
21 ],
22 }],
23 })
24
25 Description:
26 assertResponsive takes a property specific interpolation and a list of style
27 configurations with interpolation expectations that apply to each
28 configuration.
29 It starts the interpolation in every configuration, changes the
30 state to every other configuration (n * (n - 1) complexity) and asserts that
31 each destination configuration's expectations are met.
32 This test is designed to catch stale interpolation caches.
33 */
34
35 (function() {
36 'use strict';
37 var sharedStyle = null;
38 var animationCount = 0;
39 var pendingResponsiveTests = [];
40
41 function assertResponsive(options) {
42 pendingResponsiveTests.push(options);
43 }
44
45 function createTransitions(configurations) {
46 var transitions = [];
47 for (var i = 0; i < configurations.length; i++) {
48 var beforeConfiguration = configurations[i];
49 var beforeExpect = beforeConfiguration.expect;
50 for (var j = i; j < configurations.length; j++) {
51 if (j == i) {
52 continue;
53 }
shans 2015/06/18 06:26:02 for (var j = i + 1; ...
alancutter (OOO until 2018) 2015/06/18 07:11:32 "var j = i" was a debugging tweak that got acciden
54 var afterConfiguration = configurations[j];
55 var afterExpect = afterConfiguration.expect;
56
57 console.assert(beforeExpect.length == afterExpect.length);
58 for (var k = 0; k < beforeExpect.length; k++) {
59 console.assert(beforeExpect[k].at == afterExpect[k].at);
shans 2015/06/18 06:26:02 It's really not very obvious from the input data s
alancutter (OOO until 2018) 2015/06/18 07:11:32 On second thought there's no reason to require thi
60 }
61
62 transitions.push({
63 before: beforeConfiguration,
64 after: afterConfiguration,
65 });
66 }
67 }
68 return transitions;
69 }
70
71 function createElement(tag, container) {
72 var element = document.createElement(tag);
73 if (container) {
74 container.appendChild(element);
75 }
76 return element;
77 }
78
79 function createTargets(n, container) {
80 var targets = [];
81 for (var i = 0; i < n; i++) {
82 targets.push(createElement('div', container));
83 }
84 return targets;
85 }
86
87 function setInlineStyle(target, style) {
shans 2015/06/18 06:26:02 This seems predicated on specifying style dictiona
alancutter (OOO until 2018) 2015/06/18 07:11:32 I can't think of any tests that would need more th
88 for (var property in style) {
89 target.style[property] = style[property];
90 }
91 }
92
93 function setState(targets, state) {
94 var parentStyle = state.parentStyle;
95 if (parentStyle) {
96 var parent = targets[0].parentElement;
97 console.assert(targets.every(function(target) { return target.parentElement === parent; }));
98 setInlineStyle(parent, parentStyle);
99 }
100 var targetStyle = state.targetStyle;
101 if (targetStyle) {
102 for (var target of targets) {
103 setInlineStyle(target, targetStyle);
104 }
105 }
106 }
107
108 function createAnimationName() {
109 return 'anim' + (animationCount++);
110 }
111
112 function createKeyframes(animationName, property, from, to) {
113 return `
114 @keyframes ${animationName} {
115 from { ${property}: ${from}; }
116 to { ${property}: ${to}; }
117 }`;
118 }
119
120 function addGlobalStyle(styleText) {
121 if (!sharedStyle) {
122 sharedStyle = createElement('style', document.documentElement);
123 }
124 sharedStyle.textContent += styleText;
125 }
126
127 function startPausedAnimations(targets, animationName, fractions) {
128 console.assert(targets.length == fractions.length);
129 for (var i = 0; i < targets.length; i++) {
130 var target = targets[i];
131 var fraction = fractions[i];
132 console.assert(fraction >= 0 && fraction <= 1);
133 target.style.animation = `${animationName} 1s linear both paused`;
134 target.style.animationDelay = `${-fraction}s`;
135 }
136 }
137
138 function runPendingResponsiveTests() {
139 var transitionTests = [];
140 pendingResponsiveTests.forEach(function(options) {
141 var property = options.property;
142 var from = options.from;
143 var to = options.to;
144 var animationName = createAnimationName();
145 addGlobalStyle(createKeyframes(animationName, property, from, to));
146
147 var transitions = createTransitions(options.configurations);
148 transitions.forEach(function(transition) {
149 var before = transition.before;
150 var after = transition.after;
151 var container = createElement('div', document.body);
152 var targets = createTargets(before.expect.length, container);
153
154 setState(targets, before.state);
155 startPausedAnimations(targets, animationName, before.expect.map(function(e xpectation) { return expectation.at; }));
156 transitionTests.push({
157 applyTransition() {
158 setState(targets, after.state);
159 },
160 assert() {
161 for (var i = 0; i < targets.length; i++) {
162 var target = targets[i];
163 var expectation = after.expect[i];
164 var actual = getComputedStyle(target)[property];
165 test(function() {
166 assert_equals(actual, expectation.is);
167 }, `Animation on property <${property}> from [${from}] to [${to}] wi th ${JSON.stringify(before.state)} changed to ${JSON.stringify(after.state)} at (${expectation.at}) is [${expectation.is}]`);
168 }
169 },
170 });
171 });
172 });
173
174 // Force style recalc to instantiate animations internally.
175 getComputedStyle(document.body).color;
176
177 // Separate style application and measurement into different phases to avoid a style recalc storm.
178 for (var transitionTest of transitionTests) {
179 transitionTest.applyTransition();
180 }
181 for (var transitionTest of transitionTests) {
182 transitionTest.assert();
183 }
shans 2015/06/18 06:26:02 why are these separate loops?
alancutter (OOO until 2018) 2015/06/18 07:11:32 The above comment describes. I batch the style mod
184 }
185
186 function loadScript(url) {
187 return new Promise(function(resolve) {
188 var script = document.createElement('script');
189 script.src = url;
190 script.onload = resolve;
191 document.head.appendChild(script);
192 });
193 }
194
195 loadScript('../../resources/testharness.js').then(function() {
196 return loadScript('../../resources/testharnessreport.js');
197 }).then(function() {
198 var asyncHandle = async_test('This test uses responsive-test.js.')
199 requestAnimationFrame(function() {
200 runPendingResponsiveTests();
201 asyncHandle.done()
202 });
203 });
204
205
206 window.assertResponsive = assertResponsive;
207
208 })();
OLDNEW
« no previous file with comments | « LayoutTests/animations/responsive/left-responsive.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698