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

Unified Diff: LayoutTests/animations/resources/animation-test-helpers.js

Issue 15738009: Beat the transition tests with a sanity stick. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: More better. Created 7 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | LayoutTests/compositing/animation/animated-composited-inside-hidden.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: LayoutTests/animations/resources/animation-test-helpers.js
diff --git a/LayoutTests/animations/resources/animation-test-helpers.js b/LayoutTests/animations/resources/animation-test-helpers.js
index 4670e89d9b088e829b7281d405d006285f346ee9..96109374de97111b3ccfd30609efef3d8a4dbc2e 100644
--- a/LayoutTests/animations/resources/animation-test-helpers.js
+++ b/LayoutTests/animations/resources/animation-test-helpers.js
@@ -40,6 +40,11 @@ function isCloseEnough(actual, desired, tolerance)
return diff <= tolerance;
}
+function roundNumber(num, decimalPlaces)
+{
+ return Math.round(num * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces);
+}
+
function matrixStringToArray(s)
{
if (s == "none")
@@ -270,6 +275,165 @@ function checkExpectedValue(expected, index)
}
}
+function compareRGB(rgb, expected, tolerance)
+{
+ return (isCloseEnough(parseInt(rgb[0]), expected[0], tolerance) &&
+ isCloseEnough(parseInt(rgb[1]), expected[1], tolerance) &&
+ isCloseEnough(parseInt(rgb[2]), expected[2], tolerance));
+}
+
+function parseCrossFade(s)
+{
+ var matches = s.match("-webkit-cross-fade\\((.*)\\s*,\\s*(.*)\\s*,\\s*(.*)\\)");
+
+ if (!matches)
+ return null;
+
+ return {"from": matches[1], "to": matches[2], "percent": parseFloat(matches[3])}
+}
+
+function checkExpectedTransitionValue(expected, index)
Steve Block 2013/05/23 03:47:09 Have you changed this function at all from transit
dstockwell 2013/05/23 03:59:33 Only some trivial changes, inlining some simple fu
+{
+ expected[index].shift();
+ var time = expected[index][0];
+ var elementId = expected[index][1];
+ var property = expected[index][2];
+ var expectedValue = expected[index][3];
+ var tolerance = expected[index][4];
+ var postCompletionCallback = expected[index][5];
+
+ var computedValue;
+ var pass = false;
+ var transformRegExp = /^-webkit-transform(\.\d+)?$/;
+ if (transformRegExp.test(property)) {
+ computedValue = window.getComputedStyle(document.getElementById(elementId)).webkitTransform;
+ if (typeof expectedValue == "string")
+ pass = (computedValue == expectedValue);
+ else if (typeof expectedValue == "number") {
+ var m = computedValue.split("(");
+ var m = m[1].split(",");
+ pass = isCloseEnough(parseFloat(m[parseInt(property.substring(18))]), expectedValue, tolerance);
+ } else {
+ var m = computedValue.split("(");
+ var m = m[1].split(",");
+ for (i = 0; i < expectedValue.length; ++i) {
+ pass = isCloseEnough(parseFloat(m[i]), expectedValue[i], tolerance);
+ if (!pass)
+ break;
+ }
+ }
+ } else if (property == "fill" || property == "stroke") {
+ computedValue = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property).rgbColor;
+ if (compareRGB([computedValue.red.cssText, computedValue.green.cssText, computedValue.blue.cssText], expectedValue, tolerance))
+ pass = true;
+ else {
+ // We failed. Make sure computed value is something we can read in the error message
+ computedValue = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property).cssText;
+ }
+ } else if (property == "stop-color" || property == "flood-color" || property == "lighting-color") {
+ computedValue = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property);
+ // The computedValue cssText is rgb(num, num, num)
+ var components = computedValue.cssText.split("(")[1].split(")")[0].split(",");
+ if (compareRGB(components, expectedValue, tolerance))
+ pass = true;
+ else {
+ // We failed. Make sure computed value is something we can read in the error message
+ computedValue = computedValue.cssText;
+ }
+ } else if (property == "lineHeight") {
+ computedValue = parseInt(window.getComputedStyle(document.getElementById(elementId)).lineHeight);
+ pass = isCloseEnough(computedValue, expectedValue, tolerance);
+ } else if (property == "background-image"
+ || property == "border-image-source"
+ || property == "border-image"
+ || property == "list-style-image"
+ || property == "-webkit-mask-image"
+ || property == "-webkit-mask-box-image") {
+ if (property == "border-image" || property == "-webkit-mask-image" || property == "-webkit-mask-box-image")
+ property += "-source";
+
+ computedValue = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property).cssText;
+ computedCrossFade = parseCrossFade(computedValue);
+
+ if (!computedCrossFade) {
+ pass = false;
+ } else {
+ pass = isCloseEnough(computedCrossFade.percent, expectedValue, tolerance);
+ }
+ } else {
+ var computedStyle = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property);
+ if (computedStyle.cssValueType == CSSValue.CSS_VALUE_LIST) {
+ var values = [];
+ for (var i = 0; i < computedStyle.length; ++i) {
+ switch (computedStyle[i].cssValueType) {
+ case CSSValue.CSS_PRIMITIVE_VALUE:
+ values.push(computedStyle[i].getFloatValue(CSSPrimitiveValue.CSS_NUMBER));
+ break;
+ case CSSValue.CSS_CUSTOM:
+ // arbitrarily pick shadow-x and shadow-y
+ if (property == 'box-shadow' || property == 'text-shadow') {
+ var text = computedStyle[i].cssText;
+ // Shadow cssText looks like "rgb(0, 0, 255) 0px -3px 10px 0px"
+ var shadowPositionRegExp = /\)\s*(-?\d+)px\s*(-?\d+)px/;
+ var match = shadowPositionRegExp.exec(text);
+ var shadowXY = [parseInt(match[1]), parseInt(match[2])];
+ values.push(shadowXY[0]);
+ values.push(shadowXY[1]);
+ } else
+ values.push(computedStyle[i].cssText);
+ break;
+ }
+ }
+ computedValue = values.join(',');
+ pass = true;
+ for (var i = 0; i < values.length; ++i)
+ pass &= isCloseEnough(values[i], expectedValue[i], tolerance);
+ } else if (computedStyle.cssValueType == CSSValue.CSS_PRIMITIVE_VALUE) {
+ switch (computedStyle.primitiveType) {
+ case CSSPrimitiveValue.CSS_STRING:
+ case CSSPrimitiveValue.CSS_IDENT:
+ computedValue = computedStyle.getStringValue();
+ pass = computedValue == expectedValue;
+ break;
+ case CSSPrimitiveValue.CSS_RGBCOLOR:
+ var rgbColor = computedStyle.getRGBColorValue();
+ computedValue = [rgbColor.red.getFloatValue(CSSPrimitiveValue.CSS_NUMBER),
+ rgbColor.green.getFloatValue(CSSPrimitiveValue.CSS_NUMBER),
+ rgbColor.blue.getFloatValue(CSSPrimitiveValue.CSS_NUMBER)]; // alpha is not exposed to JS
+ pass = true;
+ for (var i = 0; i < 3; ++i)
+ pass &= isCloseEnough(computedValue[i], expectedValue[i], tolerance);
+ break;
+ case CSSPrimitiveValue.CSS_RECT:
+ computedValue = computedStyle.getRectValue();
+ computedValue = [computedValue.top.getFloatValue(CSSPrimitiveValue.CSS_NUMBER),
+ computedValue.right.getFloatValue(CSSPrimitiveValue.CSS_NUMBER),
+ computedValue.bottom.getFloatValue(CSSPrimitiveValue.CSS_NUMBER),
+ computedValue.left.getFloatValue(CSSPrimitiveValue.CSS_NUMBER)];
+ pass = true;
+ for (var i = 0; i < 4; ++i)
+ pass &= isCloseEnough(computedValue[i], expectedValue[i], tolerance);
+ break;
+ case CSSPrimitiveValue.CSS_PERCENTAGE:
+ computedValue = parseFloat(computedStyle.cssText);
+ pass = isCloseEnough(computedValue, expectedValue, tolerance);
+ break;
+ default:
+ computedValue = computedStyle.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
+ pass = isCloseEnough(computedValue, expectedValue, tolerance);
+ }
+ }
+ }
+
+ if (pass)
+ result += "PASS - \"" + property + "\" property for \"" + elementId + "\" element at " + time + "s saw something close to: " + expectedValue + "<br>";
+ else
+ result += "FAIL - \"" + property + "\" property for \"" + elementId + "\" element at " + time + "s expected: " + expectedValue + " but saw: " + computedValue + "<br>";
+
+ if (postCompletionCallback)
+ result += postCompletionCallback();
+}
+
function getPropertyValue(property, elementId, iframeId)
{
@@ -402,6 +566,12 @@ var useResultElement = false;
var result = "";
var hasPauseAnimationAPI;
var animStartTime;
+var isTransitionsTest = false;
+
+var usePauseAPI = true;
+var dontUsePauseAPI = false;
+var shouldBeTransitioning = 'should-be-transitioning';
+var shouldNotBeTransitioning = 'should-not-be-transitioning';
// FIXME: remove deprecatedEvent, disablePauseAnimationAPI and doPixelTest
function runAnimationTest(expected, callbacks, deprecatedEvent, disablePauseAnimationAPI, doPixelTest)
@@ -418,10 +588,22 @@ function runAnimationTest(expected, callbacks, deprecatedEvent, disablePauseAnim
hasPauseAnimationAPI = false;
var checks = {};
+ var trigger = function() {};
+
+ if (isTransitionsTest) {
+ var transitionTrigger = callbacks;
+ callbacks = null;
+ trigger = function() {
+ transitionTrigger();
+ document.body.offsetTop
+ if (window.testRunner)
+ testRunner.display();
+ };
+ }
- if (typeof callbacks == 'function')
+ if (typeof callbacks == 'function') {
checks[0] = [callbacks];
- else for (var time in callbacks) {
+ } else for (var time in callbacks) {
timeMs = Math.round(time * 1000);
checks[timeMs] = [callbacks[time]];
}
@@ -431,7 +613,10 @@ function runAnimationTest(expected, callbacks, deprecatedEvent, disablePauseAnim
var timeMs = Math.round(expectation[1] * 1000);
if (!checks[timeMs])
checks[timeMs] = [];
- checks[timeMs].push(checkExpectedValue.bind(null, expected, i));
+ if (isTransitionsTest)
+ checks[timeMs].push(checkExpectedTransitionValue.bind(null, expected, i));
+ else
+ checks[timeMs].push(checkExpectedValue.bind(null, expected, i));
}
var doPixelTest = Boolean(doPixelTest);
@@ -443,9 +628,12 @@ function runAnimationTest(expected, callbacks, deprecatedEvent, disablePauseAnim
}
var started = false;
- document.addEventListener('webkitAnimationStart', function() {
+ var target = isTransitionsTest ? window : document;
+ var event = isTransitionsTest ? 'load' : 'webkitAnimationStart';
+ target.addEventListener(event, function() {
if (!started) {
started = true;
+ trigger();
animStartTime = performance.now();
// delay to give hardware animations a chance to start
setTimeout(function() {
@@ -454,3 +642,31 @@ function runAnimationTest(expected, callbacks, deprecatedEvent, disablePauseAnim
}
}, false);
}
+
+/* This is the helper function to run transition tests:
+
+Test page requirements:
+- The body must contain an empty div with id "result"
+- Call this function directly from the <script> inside the test page
+
+Function parameters:
+ expected [required]: an array of arrays defining a set of CSS properties that must have given values at specific times (see below)
+ callback [optional]: a function to be executed just before the test starts (none by default)
+
+ Each sub-array must contain these items in this order:
+ - the time in seconds at which to snapshot the CSS property
+ - the id of the element on which to get the CSS property value
+ - the name of the CSS property to get [1]
+ - the expected value for the CSS property
+ - the tolerance to use when comparing the effective CSS property value with its expected value
+
+ [1] If the CSS property name is "-webkit-transform", expected value must be an array of 1 or more numbers corresponding to the matrix elements,
+ or a string which will be compared directly (useful if the expected value is "none")
+ If the CSS property name is "-webkit-transform.N", expected value must be a number corresponding to the Nth element of the matrix
+
+*/
+function runTransitionTest(expected, callback, usePauseAPI, doPixelTest) {
+ expected = expected.map(function(expectation) { expectation.unshift(null); return expectation; });
+ isTransitionsTest = true;
+ runAnimationTest(expected, callback, undefined, usePauseAPI !== true, doPixelTest);
Steve Block 2013/05/23 03:47:09 Regarding usePauseAPI, are there really cases wher
dstockwell 2013/05/23 03:59:33 Done.
+}
« no previous file with comments | « no previous file | LayoutTests/compositing/animation/animated-composited-inside-hidden.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698