| OLD | NEW |
| 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 15 matching lines...) Expand all Loading... |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 /* | 31 /* |
| 32 * This script is intended to be used for constructing layout tests which | 32 * This script is intended to be used for constructing layout tests which |
| 33 * exercise the interpolation functionaltiy of the animation system. | 33 * exercise the interpolation functionaltiy of the animation system. |
| 34 * Tests which run using this script should be portable across browsers. | 34 * Tests which run using this script should be portable across browsers. |
| 35 * | 35 * |
| 36 * The following functions are exported: | 36 * The following function is exported: |
| 37 * * runAsRefTest - indicates that the test is a ref test and disables | |
| 38 * dumping of textual output. | |
| 39 * * testInterpolationAt([timeFractions], {property: x, from: y, to: z}) | |
| 40 * Constructs a test case for the interpolation of property x from | |
| 41 * value y to value z at each of the times in timeFractions. | |
| 42 * * assertInterpolation({property: x, from: y, to: z}, [{at: fraction, is: val
ue}]) | 37 * * assertInterpolation({property: x, from: y, to: z}, [{at: fraction, is: val
ue}]) |
| 43 * Constructs a test case which for each fraction will output a PASS | 38 * Constructs a test case which for each fraction will output a PASS |
| 44 * or FAIL depending on whether the interpolated result matches | 39 * or FAIL depending on whether the interpolated result matches |
| 45 * 'value'. Replica elements are constructed to aid eyeballing test | 40 * 'value'. Replica elements are constructed to aid eyeballing test |
| 46 * results. This function may not be used in a ref test. | 41 * results. This function may not be used in a ref test. |
| 47 * * convertToReference - This is intended to be used interactively to | |
| 48 * construct a reference given the results of a test. To build a | |
| 49 * reference, run the test, open the inspector and trigger this | |
| 50 * function, then copy/paste the results. | |
| 51 */ | 42 */ |
| 52 'use strict'; | 43 'use strict'; |
| 53 (function() { | 44 (function() { |
| 54 var webkitPrefix = 'webkitAnimation' in document.documentElement.style ? '-web
kit-' : ''; | 45 var webkitPrefix = 'webkitAnimation' in document.documentElement.style ? '-web
kit-' : ''; |
| 55 var isRefTest = false; | |
| 56 var webAnimationsTest = typeof Element.prototype.animate === 'function'; | 46 var webAnimationsTest = typeof Element.prototype.animate === 'function'; |
| 57 var startEvent = webkitPrefix ? 'webkitAnimationStart' : 'animationstart'; | 47 var startEvent = webkitPrefix ? 'webkitAnimationStart' : 'animationstart'; |
| 58 var endEvent = webkitPrefix ? 'webkitAnimationEnd' : 'animationend'; | 48 var endEvent = webkitPrefix ? 'webkitAnimationEnd' : 'animationend'; |
| 59 var testCount = 0; | 49 var testCount = 0; |
| 60 var animationEventCount = 0; | 50 var animationEventCount = 0; |
| 61 // FIXME: This should be 0, but 0 duration animations are broken in at least | 51 // FIXME: This should be 0, but 0 duration animations are broken in at least |
| 62 // pre-Web-Animations Blink, WebKit and Gecko. | 52 // pre-Web-Animations Blink, WebKit and Gecko. |
| 63 var durationSeconds = 0.001; | 53 var durationSeconds = 0.001; |
| 64 var iterationCount = 0.5; | 54 var iterationCount = 0.5; |
| 65 var delaySeconds = 0; | 55 var delaySeconds = 0; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 setTimeout(function() { | 89 setTimeout(function() { |
| 100 updateScheduled = false; | 90 updateScheduled = false; |
| 101 style.innerHTML = cssText; | 91 style.innerHTML = cssText; |
| 102 document.body.appendChild(fragment); | 92 document.body.appendChild(fragment); |
| 103 fragmentAttachedListeners.forEach(function(listener) {listener();}); | 93 fragmentAttachedListeners.forEach(function(listener) {listener();}); |
| 104 }, 0); | 94 }, 0); |
| 105 } | 95 } |
| 106 | 96 |
| 107 function dumpResults() { | 97 function dumpResults() { |
| 108 var targets = document.querySelectorAll('.target.active'); | 98 var targets = document.querySelectorAll('.target.active'); |
| 109 if (isRefTest) { | 99 var cssResultString = 'CSS Animations:\n'; |
| 110 // Convert back to reference to avoid cases where the computed style is | 100 var waResultString = 'Web Animations API:\n'; |
| 111 // out of sync with the compositor. | 101 for (var i = 0; i < targets.length; i++) { |
| 112 for (var i = 0; i < targets.length; i++) { | 102 if (targets[i].testType === 'css') { |
| 113 targets[i].convertToReference(); | 103 cssResultString += targets[i].getResultString() + '\n'; |
| 104 } else { |
| 105 waResultString += targets[i].getResultString() + '\n'; |
| 114 } | 106 } |
| 115 style.parentNode.removeChild(style); | |
| 116 } else { | |
| 117 var cssResultString = 'CSS Animations:\n'; | |
| 118 var waResultString = 'Web Animations API:\n'; | |
| 119 for (var i = 0; i < targets.length; i++) { | |
| 120 if (targets[i].testType === 'css') { | |
| 121 cssResultString += targets[i].getResultString() + '\n'; | |
| 122 } else { | |
| 123 waResultString += targets[i].getResultString() + '\n'; | |
| 124 } | |
| 125 } | |
| 126 var results = document.createElement('pre'); | |
| 127 results.textContent = cssResultString + (waTestsDiv ? '\n' + waResultStrin
g : ''); | |
| 128 results.id = 'results'; | |
| 129 document.body.appendChild(results); | |
| 130 } | 107 } |
| 131 } | 108 var results = document.createElement('pre'); |
| 132 | 109 results.textContent = cssResultString + (waTestsDiv ? '\n' + waResultString
: ''); |
| 133 function convertToReference() { | 110 results.id = 'results'; |
| 134 console.assert(isRefTest); | 111 document.body.appendChild(results); |
| 135 var scripts = document.querySelectorAll('script'); | |
| 136 for (var i = 0; i < scripts.length; i++) { | |
| 137 scripts[i].parentNode.removeChild(scripts[i]); | |
| 138 } | |
| 139 style.parentNode.removeChild(style); | |
| 140 var html = document.documentElement.outerHTML; | |
| 141 document.documentElement.style.whiteSpace = 'pre'; | |
| 142 document.documentElement.textContent = html; | |
| 143 } | 112 } |
| 144 | 113 |
| 145 function afterTest(callback) { | 114 function afterTest(callback) { |
| 146 afterTestCallback = callback; | 115 afterTestCallback = callback; |
| 147 } | 116 } |
| 148 | 117 |
| 149 function runAsRefTest() { | |
| 150 console.assert(!isRefTest); | |
| 151 isRefTest = true; | |
| 152 } | |
| 153 | |
| 154 // Constructs a timing function which produces 'y' at x = 0.5 | 118 // Constructs a timing function which produces 'y' at x = 0.5 |
| 155 function createEasing(y) { | 119 function createEasing(y) { |
| 156 // FIXME: if 'y' is > 0 and < 1 use a linear timing function and allow | 120 // FIXME: if 'y' is > 0 and < 1 use a linear timing function and allow |
| 157 // 'x' to vary. Use a bezier only for values < 0 or > 1. | 121 // 'x' to vary. Use a bezier only for values < 0 or > 1. |
| 158 if (y == 0) { | 122 if (y == 0) { |
| 159 return 'steps(1, end)'; | 123 return 'steps(1, end)'; |
| 160 } | 124 } |
| 161 if (y == 1) { | 125 if (y == 1) { |
| 162 return 'steps(1, start)'; | 126 return 'steps(1, start)'; |
| 163 } | 127 } |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 var anchor = document.createElement('a'); | 247 var anchor = document.createElement('a'); |
| 284 anchor.href = url; | 248 anchor.href = url; |
| 285 anchor.pathname = '...' + anchor.pathname.substring(anchor.pathname.last
IndexOf('/')); | 249 anchor.pathname = '...' + anchor.pathname.substring(anchor.pathname.last
IndexOf('/')); |
| 286 value = value.replace(matches[i], 'url(' + anchor.href + ')'); | 250 value = value.replace(matches[i], 'url(' + anchor.href + ')'); |
| 287 } | 251 } |
| 288 } | 252 } |
| 289 return value; | 253 return value; |
| 290 } | 254 } |
| 291 | 255 |
| 292 function makeInterpolationTest(testType, fraction, testId, caseId, params, exp
ectation) { | 256 function makeInterpolationTest(testType, fraction, testId, caseId, params, exp
ectation) { |
| 293 console.assert(expectation === undefined || !isRefTest); | |
| 294 var targetContainer = createTargetContainer(caseId); | 257 var targetContainer = createTargetContainer(caseId); |
| 295 var target = targetContainer.querySelector('.target') || targetContainer; | 258 var target = targetContainer.querySelector('.target') || targetContainer; |
| 296 target.classList.add('active'); | 259 target.classList.add('active'); |
| 297 var replicaContainer, replica; | 260 var replicaContainer, replica; |
| 298 if (expectation !== undefined) { | 261 if (expectation !== undefined) { |
| 299 replicaContainer = createTargetContainer(caseId); | 262 replicaContainer = createTargetContainer(caseId); |
| 300 replica = replicaContainer.querySelector('.target') || replicaContainer; | 263 replica = replicaContainer.querySelector('.target') || replicaContainer; |
| 301 replica.classList.add('replica'); | 264 replica.classList.add('replica'); |
| 302 replica.style.setProperty(params.property, expectation); | 265 replica.style.setProperty(params.property, expectation); |
| 303 } | 266 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 315 var pass = normalizeValue(value) === normalizeValue(parsedExpectation); | 278 var pass = normalizeValue(value) === normalizeValue(parsedExpectation); |
| 316 result = pass ? 'PASS: ' : 'FAIL: '; | 279 result = pass ? 'PASS: ' : 'FAIL: '; |
| 317 reason = pass ? '' : ', expected [' + expectation + ']' + | 280 reason = pass ? '' : ', expected [' + expectation + ']' + |
| 318 (expectation === parsedExpectation ? '' : ' (parsed as [' + sanitize
Urls(roundNumbers(parsedExpectation)) + '])'); | 281 (expectation === parsedExpectation ? '' : ' (parsed as [' + sanitize
Urls(roundNumbers(parsedExpectation)) + '])'); |
| 319 value = pass ? expectation : sanitizeUrls(value); | 282 value = pass ? expectation : sanitizeUrls(value); |
| 320 } | 283 } |
| 321 return result + property + ' from [' + params.from + '] to ' + | 284 return result + property + ' from [' + params.from + '] to ' + |
| 322 '[' + params.to + '] was [' + value + ']' + | 285 '[' + params.to + '] was [' + value + ']' + |
| 323 ' at ' + fraction + reason; | 286 ' at ' + fraction + reason; |
| 324 }; | 287 }; |
| 325 target.convertToReference = function() { | |
| 326 this.style[params.property] = getComputedStyle(this).getPropertyValue(para
ms.property); | |
| 327 }; | |
| 328 var easing = createEasing(fraction); | 288 var easing = createEasing(fraction); |
| 329 testCount++; | 289 testCount++; |
| 330 if (testType === 'css') { | 290 if (testType === 'css') { |
| 331 cssText += '.' + testId + ' .' + caseId + '.active {\n' + | 291 cssText += '.' + testId + ' .' + caseId + '.active {\n' + |
| 332 ' ' + webkitPrefix + 'animation: ' + testId + ' ' + durationSeconds +
's forwards;\n' + | 292 ' ' + webkitPrefix + 'animation: ' + testId + ' ' + durationSeconds +
's forwards;\n' + |
| 333 ' ' + webkitPrefix + 'animation-timing-function: ' + easing + ';\n' + | 293 ' ' + webkitPrefix + 'animation-timing-function: ' + easing + ';\n' + |
| 334 ' ' + webkitPrefix + 'animation-iteration-count: ' + iterationCount +
';\n' + | 294 ' ' + webkitPrefix + 'animation-iteration-count: ' + iterationCount +
';\n' + |
| 335 ' ' + webkitPrefix + 'animation-delay: ' + delaySeconds + 's;\n' + | 295 ' ' + webkitPrefix + 'animation-delay: ' + delaySeconds + 's;\n' + |
| 336 '}\n'; | 296 '}\n'; |
| 337 } else { | 297 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 357 } | 317 } |
| 358 | 318 |
| 359 var finished = false; | 319 var finished = false; |
| 360 function finishTest() { | 320 function finishTest() { |
| 361 finished = true; | 321 finished = true; |
| 362 dumpResults(); | 322 dumpResults(); |
| 363 if (afterTestCallback) { | 323 if (afterTestCallback) { |
| 364 afterTestCallback(); | 324 afterTestCallback(); |
| 365 } | 325 } |
| 366 if (window.testRunner) { | 326 if (window.testRunner) { |
| 367 if (!isRefTest) { | 327 var results = document.querySelector('#results'); |
| 368 var results = document.querySelector('#results'); | 328 document.documentElement.textContent = ''; |
| 369 document.documentElement.textContent = ''; | 329 document.documentElement.appendChild(results); |
| 370 document.documentElement.appendChild(results); | 330 testRunner.dumpAsText(); |
| 371 testRunner.dumpAsText(); | |
| 372 } | |
| 373 testRunner.notifyDone(); | 331 testRunner.notifyDone(); |
| 374 } | 332 } |
| 375 } | 333 } |
| 376 | 334 |
| 377 if (window.testRunner) { | 335 if (window.testRunner) { |
| 378 testRunner.waitUntilDone(); | 336 testRunner.waitUntilDone(); |
| 379 } | 337 } |
| 380 | 338 |
| 381 function isLastAnimationEvent() { | 339 function isLastAnimationEvent() { |
| 382 return !finished && animationEventCount === testCount; | 340 return !finished && animationEventCount === testCount; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 return; | 372 return; |
| 415 } | 373 } |
| 416 finishTest(); | 374 finishTest(); |
| 417 }, 10000); | 375 }, 10000); |
| 418 } | 376 } |
| 419 | 377 |
| 420 function disableWebAnimationsTest() { | 378 function disableWebAnimationsTest() { |
| 421 webAnimationsTest = false; | 379 webAnimationsTest = false; |
| 422 } | 380 } |
| 423 | 381 |
| 424 window.runAsRefTest = runAsRefTest; | |
| 425 window.testInterpolationAt = testInterpolationAt; | 382 window.testInterpolationAt = testInterpolationAt; |
| 426 window.assertInterpolation = assertInterpolation; | 383 window.assertInterpolation = assertInterpolation; |
| 427 window.convertToReference = convertToReference; | |
| 428 window.afterTest = afterTest; | 384 window.afterTest = afterTest; |
| 429 window.disableWebAnimationsTest = disableWebAnimationsTest; | 385 window.disableWebAnimationsTest = disableWebAnimationsTest; |
| 430 })(); | 386 })(); |
| OLD | NEW |