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

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

Issue 203723005: Web Animations API: Update interpolation test harness to test element.animate() (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Review changes, added section headers and rebased Created 6 years, 9 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 * results. This function may not be used in a ref test. 46 * results. This function may not be used in a ref test.
47 * * convertToReference - This is intended to be used interactively to 47 * * convertToReference - This is intended to be used interactively to
48 * construct a reference given the results of a test. To build a 48 * construct a reference given the results of a test. To build a
49 * reference, run the test, open the inspector and trigger this 49 * reference, run the test, open the inspector and trigger this
50 * function, then copy/paste the results. 50 * function, then copy/paste the results.
51 */ 51 */
52 'use strict'; 52 'use strict';
53 (function() { 53 (function() {
54 var webkitPrefix = 'webkitAnimation' in document.documentElement.style ? '-web kit-' : ''; 54 var webkitPrefix = 'webkitAnimation' in document.documentElement.style ? '-web kit-' : '';
55 var isRefTest = false; 55 var isRefTest = false;
56 var webAnimationsTest = typeof Element.prototype.animate === 'function';
56 var startEvent = webkitPrefix ? 'webkitAnimationStart' : 'animationstart'; 57 var startEvent = webkitPrefix ? 'webkitAnimationStart' : 'animationstart';
57 var endEvent = webkitPrefix ? 'webkitAnimationEnd' : 'animationend'; 58 var endEvent = webkitPrefix ? 'webkitAnimationEnd' : 'animationend';
58 var testCount = 0; 59 var testCount = 0;
59 var animationEventCount = 0; 60 var animationEventCount = 0;
60 // FIXME: This should be 0, but 0 duration animations are broken in at least 61 // FIXME: This should be 0, but 0 duration animations are broken in at least
61 // pre-Web-Animations Blink, WebKit and Gecko. 62 // pre-Web-Animations Blink, WebKit and Gecko.
62 var durationSeconds = 0.001; 63 var durationSeconds = 0.001;
63 var iterationCount = 0.5; 64 var iterationCount = 0.5;
64 var delaySeconds = 0; 65 var delaySeconds = 0;
65 var cssText = '.test:hover:before {\n' + 66 var cssText = '.test:hover:before {\n' +
66 ' content: attr(description);\n' + 67 ' content: attr(description);\n' +
67 ' position: absolute;\n' + 68 ' position: absolute;\n' +
68 ' z-index: 1000;\n' + 69 ' z-index: 1000;\n' +
69 ' background: gold;\n' + 70 ' background: gold;\n' +
70 '}\n'; 71 '}\n';
71 var fragment = document.createDocumentFragment(); 72 var fragment = document.createDocumentFragment();
73 var fragmentAttachedListeners = [];
72 var style = document.createElement('style'); 74 var style = document.createElement('style');
75 var cssTests = document.createElement('div');
76 cssTests.id = 'css-tests';
77 cssTests.textContent = 'CSS Animations:';
73 var afterTestCallback = null; 78 var afterTestCallback = null;
74 fragment.appendChild(style); 79 fragment.appendChild(style);
80 fragment.appendChild(cssTests);
81
82 if (webAnimationsTest) {
83 var waTests = document.createElement('div');
84 waTests.id = 'web-animations-tests';
85 waTests.textContent = 'Web Animations API:';
86 fragment.appendChild(waTests);
87 }
75 88
76 var updateScheduled = false; 89 var updateScheduled = false;
77 function maybeScheduleUpdate() { 90 function maybeScheduleUpdate() {
78 if (updateScheduled) { 91 if (updateScheduled) {
79 return; 92 return;
80 } 93 }
81 updateScheduled = true; 94 updateScheduled = true;
82 setTimeout(function() { 95 setTimeout(function() {
83 updateScheduled = false; 96 updateScheduled = false;
84 style.innerHTML = cssText; 97 style.innerHTML = cssText;
85 document.body.appendChild(fragment); 98 document.body.appendChild(fragment);
99 fragmentAttachedListeners.forEach(function(listener) {listener();});
86 }, 0); 100 }, 0);
87 } 101 }
88 102
89 function dumpResults() { 103 function dumpResults() {
90 var targets = document.querySelectorAll('.target.active'); 104 var targets = document.querySelectorAll('.target.active');
91 if (isRefTest) { 105 if (isRefTest) {
92 // Convert back to reference to avoid cases where the computed style is 106 // Convert back to reference to avoid cases where the computed style is
93 // out of sync with the compositor. 107 // out of sync with the compositor.
94 for (var i = 0; i < targets.length; i++) { 108 for (var i = 0; i < targets.length; i++) {
95 targets[i].convertToReference(); 109 targets[i].convertToReference();
96 } 110 }
97 style.parentNode.removeChild(style); 111 style.parentNode.removeChild(style);
98 } else { 112 } else {
99 var resultString = ''; 113 var cssResultString = 'CSS Animations:\n';
114 var waResultString = 'Web Animations API:\n';
100 for (var i = 0; i < targets.length; i++) { 115 for (var i = 0; i < targets.length; i++) {
101 resultString += targets[i].getResultString() + '\n'; 116 if (targets[i].isCSSTest) {
117 cssResultString += targets[i].getResultString() + '\n';
118 } else {
119 waResultString += targets[i].getResultString() + '\n';
120 }
102 } 121 }
103 var results = document.createElement('div'); 122 var results = document.createElement('pre');
104 results.style.whiteSpace = 'pre'; 123 results.textContent = cssResultString + (webAnimationsTest ? '\n' + waResu ltString : '');
105 results.textContent = resultString;
106 results.id = 'results'; 124 results.id = 'results';
107 document.body.appendChild(results); 125 document.body.appendChild(results);
108 } 126 }
109 } 127 }
110 128
111 function convertToReference() { 129 function convertToReference() {
112 console.assert(isRefTest); 130 console.assert(isRefTest);
113 var scripts = document.querySelectorAll('script'); 131 var scripts = document.querySelectorAll('script');
114 for (var i = 0; i < scripts.length; i++) { 132 for (var i = 0; i < scripts.length; i++) {
115 scripts[i].parentNode.removeChild(scripts[i]); 133 scripts[i].parentNode.removeChild(scripts[i]);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 167
150 function testInterpolationAt(fractions, params) { 168 function testInterpolationAt(fractions, params) {
151 if (!Array.isArray(fractions)) { 169 if (!Array.isArray(fractions)) {
152 fractions = [fractions]; 170 fractions = [fractions];
153 } 171 }
154 assertInterpolation(params, fractions.map(function(fraction) { 172 assertInterpolation(params, fractions.map(function(fraction) {
155 return {at: fraction}; 173 return {at: fraction};
156 })); 174 }));
157 } 175 }
158 176
159 function describeTest(params) { 177 function createTestContainer(description, className) {
160 return params.property + ': from [' + params.from + '] to [' + params.to + ' ]'; 178 var testContainer = document.createElement('div');
179 testContainer.setAttribute('description', description);
180 testContainer.classList.add('test');
181 if (className) {
182 testContainer.classList.add(className);
183 }
184 return testContainer;
185 }
186
187 function convertPropertyToCamelCase(property) {
188 return property.replace(/^-/, '').replace(/-\w/g, function(m) {return m[1].t oUpperCase();});
189 }
190
191 function describeCSSTest(params) {
192 return 'CSS ' + params.property + ': from [' + params.from + '] to [' + para ms.to + ']';
193 }
194
195 function describeWATest(params) {
196 return 'element.animate() ' + convertPropertyToCamelCase(params.property) + ': from [' + params.from + '] to [' + params.to + ']';
161 } 197 }
162 198
163 function assertInterpolation(params, expectations) { 199 function assertInterpolation(params, expectations) {
164 // If the prefixed property is not supported, try to unprefix it. 200 // If the prefixed property is not supported, try to unprefix it.
165 if (/^-[^-]+-/.test(params.property) && !CSS.supports(params.property, 'init ial')) { 201 if (/^-[^-]+-/.test(params.property) && !CSS.supports(params.property, 'init ial')) {
166 var unprefixed = params.property.replace(/^-[^-]+-/, ''); 202 var unprefixed = params.property.replace(/^-[^-]+-/, '');
167 if (CSS.supports(unprefixed, 'initial')) { 203 if (CSS.supports(unprefixed, 'initial')) {
168 params.property = unprefixed; 204 params.property = unprefixed;
169 } 205 }
170 } 206 }
171 var testId = defineKeyframes(params); 207 var testId = defineKeyframes(params);
172 var nextCaseId = 0; 208 var nextCaseId = 0;
173 var testContainer = document.createElement('div'); 209 var cssTestContainer = createTestContainer(describeCSSTest(params), testId);
174 testContainer.setAttribute('description', describeTest(params)); 210 cssTests.appendChild(cssTestContainer);
175 testContainer.classList.add('test'); 211 if (webAnimationsTest) {
176 testContainer.classList.add(testId); 212 var waTestContainer = createTestContainer(describeWATest(params), testId);
177 fragment.appendChild(testContainer); 213 waTests.appendChild(waTestContainer);
214 }
178 expectations.forEach(function(expectation) { 215 expectations.forEach(function(expectation) {
179 testContainer.appendChild(makeInterpolationTest( 216 cssTestContainer.appendChild(makeInterpolationTest(
180 expectation.at, testId, 'case-' + ++nextCaseId, params, expectation.is )); 217 true, expectation.at, testId, 'case-' + ++nextCaseId, params, expectat ion.is));
181 }); 218 });
219 if (webAnimationsTest) {
220 expectations.forEach(function(expectation) {
221 waTestContainer.appendChild(makeInterpolationTest(
222 false, expectation.at, testId, 'case-' + ++nextCaseId, params, expec tation.is));
223 });
224 }
182 maybeScheduleUpdate(); 225 maybeScheduleUpdate();
183 } 226 }
184 227
185 var nextKeyframeId = 0; 228 var nextKeyframeId = 0;
186 function defineKeyframes(params) { 229 function defineKeyframes(params) {
187 var testId = 'test-' + ++nextKeyframeId; 230 var testId = 'test-' + ++nextKeyframeId;
188 cssText += '@' + webkitPrefix + 'keyframes ' + testId + ' { \n' + 231 cssText += '@' + webkitPrefix + 'keyframes ' + testId + ' { \n' +
189 ' 0% { ' + params.property + ': ' + params.from + '; }\n' + 232 ' 0% { ' + params.property + ': ' + params.from + '; }\n' +
190 ' 100% { ' + params.property + ': ' + params.to + '; }\n' + 233 ' 100% { ' + params.property + ': ' + params.to + '; }\n' +
191 '}\n'; 234 '}\n';
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 var url = /url\(([^\)]*)\)/g.exec(matches[i])[1]; 279 var url = /url\(([^\)]*)\)/g.exec(matches[i])[1];
237 var anchor = document.createElement('a'); 280 var anchor = document.createElement('a');
238 anchor.href = url; 281 anchor.href = url;
239 anchor.pathname = '...' + anchor.pathname.substring(anchor.pathname.last IndexOf('/')); 282 anchor.pathname = '...' + anchor.pathname.substring(anchor.pathname.last IndexOf('/'));
240 value = value.replace(matches[i], 'url(' + anchor.href + ')'); 283 value = value.replace(matches[i], 'url(' + anchor.href + ')');
241 } 284 }
242 } 285 }
243 return value; 286 return value;
244 } 287 }
245 288
246 function makeInterpolationTest(fraction, testId, caseId, params, expectation) { 289 function makeInterpolationTest(cssTest, fraction, testId, caseId, params, expe ctation) {
dstockwell 2014/03/20 05:47:24 Instead of a boolean parameter, cssTest could be '
alancutter (OOO until 2018) 2014/03/20 05:55:59 Done.
247 console.assert(expectation === undefined || !isRefTest); 290 console.assert(expectation === undefined || !isRefTest);
248 var targetContainer = createTargetContainer(caseId); 291 var targetContainer = createTargetContainer(caseId);
249 var target = targetContainer.querySelector('.target') || targetContainer; 292 var target = targetContainer.querySelector('.target') || targetContainer;
250 target.classList.add('active'); 293 target.classList.add('active');
251 var replicaContainer, replica; 294 var replicaContainer, replica;
252 if (expectation !== undefined) { 295 if (expectation !== undefined) {
253 replicaContainer = createTargetContainer(caseId); 296 replicaContainer = createTargetContainer(caseId);
254 replica = replicaContainer.querySelector('.target') || replicaContainer; 297 replica = replicaContainer.querySelector('.target') || replicaContainer;
255 replica.classList.add('replica'); 298 replica.classList.add('replica');
256 replica.style.setProperty(params.property, expectation); 299 replica.style.setProperty(params.property, expectation);
257 } 300 }
301 target.isCSSTest = cssTest;
dstockwell 2014/03/20 05:47:24 here too
alancutter (OOO until 2018) 2014/03/20 05:55:59 Done.
258 target.getResultString = function() { 302 target.getResultString = function() {
259 if (!CSS.supports(params.property, expectation)) { 303 if (!CSS.supports(params.property, expectation)) {
260 return 'FAIL: [' + params.property + ': ' + expectation + '] is not supp orted'; 304 return 'FAIL: [' + params.property + ': ' + expectation + '] is not supp orted';
261 } 305 }
262 var value = getComputedStyle(this).getPropertyValue(params.property); 306 var value = getComputedStyle(this).getPropertyValue(params.property);
263 var result = ''; 307 var result = '';
264 var reason = ''; 308 var reason = '';
309 var property = cssTest ? params.property : convertPropertyToCamelCase(para ms.property);
265 if (expectation !== undefined) { 310 if (expectation !== undefined) {
266 var parsedExpectation = getComputedStyle(replica).getPropertyValue(param s.property); 311 var parsedExpectation = getComputedStyle(replica).getPropertyValue(param s.property);
267 var pass = normalizeValue(value) === normalizeValue(parsedExpectation); 312 var pass = normalizeValue(value) === normalizeValue(parsedExpectation);
268 result = pass ? 'PASS: ' : 'FAIL: '; 313 result = pass ? 'PASS: ' : 'FAIL: ';
269 reason = pass ? '' : ', expected [' + expectation + ']' + 314 reason = pass ? '' : ', expected [' + expectation + ']' +
270 (expectation === parsedExpectation ? '' : ' (parsed as [' + sanitize Urls(parsedExpectation) + '])'); 315 (expectation === parsedExpectation ? '' : ' (parsed as [' + sanitize Urls(parsedExpectation) + '])');
271 value = pass ? expectation : sanitizeUrls(value); 316 value = pass ? expectation : sanitizeUrls(value);
272 } 317 }
273 return result + params.property + ' from [' + params.from + '] to ' + 318 return result + property + ' from [' + params.from + '] to ' +
274 '[' + params.to + '] was [' + value + ']' + 319 '[' + params.to + '] was [' + value + ']' +
275 ' at ' + fraction + reason; 320 ' at ' + fraction + reason;
276 }; 321 };
277 target.convertToReference = function() { 322 target.convertToReference = function() {
278 this.style[params.property] = getComputedStyle(this).getPropertyValue(para ms.property); 323 this.style[params.property] = getComputedStyle(this).getPropertyValue(para ms.property);
279 }; 324 };
280 var easing = createEasing(fraction); 325 var easing = createEasing(fraction);
281 cssText += '.' + testId + ' .' + caseId + '.active {\n' +
282 ' ' + webkitPrefix + 'animation: ' + testId + ' ' + durationSeconds + ' s forwards;\n' +
283 ' ' + webkitPrefix + 'animation-timing-function: ' + easing + ';\n' +
284 ' ' + webkitPrefix + 'animation-iteration-count: ' + iterationCount + ' ;\n' +
285 ' ' + webkitPrefix + 'animation-delay: ' + delaySeconds + 's;\n' +
286 '}\n';
287 testCount++; 326 testCount++;
327 if (cssTest) {
328 cssText += '.' + testId + ' .' + caseId + '.active {\n' +
329 ' ' + webkitPrefix + 'animation: ' + testId + ' ' + durationSeconds + 's forwards;\n' +
330 ' ' + webkitPrefix + 'animation-timing-function: ' + easing + ';\n' +
331 ' ' + webkitPrefix + 'animation-iteration-count: ' + iterationCount + ';\n' +
332 ' ' + webkitPrefix + 'animation-delay: ' + delaySeconds + 's;\n' +
333 '}\n';
334 } else {
335 var keyframes = [{}, {}];
336 keyframes[0][convertPropertyToCamelCase(params.property)] = params.from;
337 keyframes[1][convertPropertyToCamelCase(params.property)] = params.to;
338 fragmentAttachedListeners.push(function() {
339 target.animate(keyframes, {
340 fill: 'forwards',
341 duration: 1,
342 easing: easing,
343 delay: -0.5,
344 iterations: 0.5,
345 });
346 animationEnded();
347 });
348 }
288 var testFragment = document.createDocumentFragment(); 349 var testFragment = document.createDocumentFragment();
289 testFragment.appendChild(targetContainer); 350 testFragment.appendChild(targetContainer);
290 replica && testFragment.appendChild(replicaContainer); 351 replica && testFragment.appendChild(replicaContainer);
291 testFragment.appendChild(document.createTextNode('\n')); 352 testFragment.appendChild(document.createTextNode('\n'));
292 return testFragment; 353 return testFragment;
293 } 354 }
294 355
295 var finished = false; 356 var finished = false;
296 function finishTest() { 357 function finishTest() {
297 finished = true; 358 finished = true;
(...skipping 13 matching lines...) Expand all
311 } 372 }
312 373
313 if (window.testRunner) { 374 if (window.testRunner) {
314 testRunner.waitUntilDone(); 375 testRunner.waitUntilDone();
315 } 376 }
316 377
317 function isLastAnimationEvent() { 378 function isLastAnimationEvent() {
318 return !finished && animationEventCount === testCount; 379 return !finished && animationEventCount === testCount;
319 } 380 }
320 381
321 function endEventListener() { 382 function animationEnded() {
322 animationEventCount++; 383 animationEventCount++;
323 if (!isLastAnimationEvent()) { 384 if (!isLastAnimationEvent()) {
324 return; 385 return;
325 } 386 }
326 finishTest(); 387 finishTest();
327 } 388 }
328 389
329 if (window.internals) { 390 if (window.internals) {
330 durationSeconds = 0; 391 durationSeconds = 0;
331 document.documentElement.addEventListener(endEvent, endEventListener); 392 document.documentElement.addEventListener(endEvent, animationEnded);
332 } else if (webkitPrefix) { 393 } else if (webkitPrefix) {
333 durationSeconds = 1e9; 394 durationSeconds = 1e9;
334 iterationCount = 1; 395 iterationCount = 1;
335 delaySeconds = -durationSeconds / 2; 396 delaySeconds = -durationSeconds / 2;
336 document.documentElement.addEventListener(startEvent, function() { 397 document.documentElement.addEventListener(startEvent, function() {
337 animationEventCount++; 398 animationEventCount++;
338 if (!isLastAnimationEvent()) { 399 if (!isLastAnimationEvent()) {
339 return; 400 return;
340 } 401 }
341 setTimeout(finishTest, 0); 402 setTimeout(finishTest, 0);
342 }); 403 });
343 } else { 404 } else {
344 document.documentElement.addEventListener(endEvent, endEventListener); 405 document.documentElement.addEventListener(endEvent, animationEnded);
345 } 406 }
346 407
347 if (!window.testRunner) { 408 if (!window.testRunner) {
348 setTimeout(function() { 409 setTimeout(function() {
349 if (finished) { 410 if (finished) {
350 return; 411 return;
351 } 412 }
352 finishTest(); 413 finishTest();
353 }, 10000); 414 }, 10000);
354 } 415 }
355 416
356 window.runAsRefTest = runAsRefTest; 417 window.runAsRefTest = runAsRefTest;
357 window.testInterpolationAt = testInterpolationAt; 418 window.testInterpolationAt = testInterpolationAt;
358 window.assertInterpolation = assertInterpolation; 419 window.assertInterpolation = assertInterpolation;
359 window.convertToReference = convertToReference; 420 window.convertToReference = convertToReference;
360 window.afterTest = afterTest; 421 window.afterTest = afterTest;
361 })(); 422 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698