Commit a259bc1b authored by pol@apple.com's avatar pol@apple.com

2008-12-10 Pierre-Olivier Latour <pol@apple.com>

        Reviewed by Darin Adler.

        Rewrote animations/animation-test-helpers.js to take advantage of the pauseAnimationAtTimeOnElementWithId()
        API when available in DRT.

        Updated all animations tests that check for values of animated CSS properties to use these new helper functions.

        https://bugs.webkit.org/show_bug.cgi?id=22796

        * animations/animation-test-helpers.js:
        (isCloseEnough):
        (checkExpectedValue):
        (endTest):
        (startTest):
        (runAnimationTest):
        * animations/big-rotation-expected.txt:
        * animations/big-rotation.html:
        * animations/change-keyframes-expected.txt:
        * animations/change-keyframes-name-expected.txt:
        * animations/change-keyframes-name.html:
        * animations/change-keyframes.html:
        * animations/change-one-anim-expected.txt:
        * animations/change-one-anim.html:
        * animations/generic-from-to-expected.txt:
        * animations/generic-from-to.html:
        * animations/import-expected.txt:
        * animations/import.html:
        * animations/keyframe-timing-functions-expected.txt:
        * animations/keyframe-timing-functions.html:
        * animations/keyframes-comma-separated-expected.txt:
        * animations/keyframes-comma-separated.html:
        * animations/keyframes-expected.txt:
        * animations/keyframes-from-missing.html:
        * animations/keyframes-out-of-order-expected.txt:
        * animations/keyframes-out-of-order.html:
        * animations/keyframes-to-missing.html:
        * animations/keyframes.html:
        * animations/lineheight-animation-expected.txt:
        * animations/lineheight-animation.html:
        * animations/matrix-anim-expected.txt:
        * animations/matrix-anim.html:
        * animations/multiple-animations-expected.txt:
        * animations/multiple-animations.html:
        * animations/multiple-keyframes-expected.txt:
        * animations/multiple-keyframes.html:
        * animations/transition-and-animation-1-expected.txt:
        * animations/transition-and-animation-1.html:
        * animations/transition-and-animation-2-expected.txt:
        * animations/transition-and-animation-2.html:
        * animations/width-using-ems-expected.txt:
        * animations/width-using-ems.html:
        * platform/win/Skipped:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@39187 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 417e002f
2008-12-10 Pierre-Olivier Latour <pol@apple.com>
Reviewed by Darin Adler.
Rewrote animations/animation-test-helpers.js to take advantage of the pauseAnimationAtTimeOnElementWithId()
API when available in DRT.
Updated all animations tests that check for values of animated CSS properties to use these new helper functions.
https://bugs.webkit.org/show_bug.cgi?id=22796
* animations/animation-test-helpers.js:
(isCloseEnough):
(checkExpectedValue):
(endTest):
(startTest):
(runAnimationTest):
* animations/big-rotation-expected.txt:
* animations/big-rotation.html:
* animations/change-keyframes-expected.txt:
* animations/change-keyframes-name-expected.txt:
* animations/change-keyframes-name.html:
* animations/change-keyframes.html:
* animations/change-one-anim-expected.txt:
* animations/change-one-anim.html:
* animations/generic-from-to-expected.txt:
* animations/generic-from-to.html:
* animations/import-expected.txt:
* animations/import.html:
* animations/keyframe-timing-functions-expected.txt:
* animations/keyframe-timing-functions.html:
* animations/keyframes-comma-separated-expected.txt:
* animations/keyframes-comma-separated.html:
* animations/keyframes-expected.txt:
* animations/keyframes-from-missing.html:
* animations/keyframes-out-of-order-expected.txt:
* animations/keyframes-out-of-order.html:
* animations/keyframes-to-missing.html:
* animations/keyframes.html:
* animations/lineheight-animation-expected.txt:
* animations/lineheight-animation.html:
* animations/matrix-anim-expected.txt:
* animations/matrix-anim.html:
* animations/multiple-animations-expected.txt:
* animations/multiple-animations.html:
* animations/multiple-keyframes-expected.txt:
* animations/multiple-keyframes.html:
* animations/transition-and-animation-1-expected.txt:
* animations/transition-and-animation-1.html:
* animations/transition-and-animation-2-expected.txt:
* animations/transition-and-animation-2.html:
* animations/width-using-ems-expected.txt:
* animations/width-using-ems.html:
* platform/win/Skipped:
2008-12-10 Alice Liu <alice.liu@apple.com>
Adding tweak to .conf files needed for
......
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
/* This is the helper function to run animation tests:
result = "";
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 isCloseEnough(actual, desired, tolerance)
{
if (tolerance == undefined || tolerance == 0)
tolerance = defaultTolerance;
var diff = Math.abs(actual - desired);
return diff < tolerance;
}
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)
event [optional]: which DOM event to wait for before starting the test ("webkitAnimationStart" by default)
function checkExpectedValue(index)
{
var property = expected[index][1];
var id = expected[index][2];
var expectedValue = expected[index][3];
var computedStyle = window.getComputedStyle(document.getElementById(id)).getPropertyCSSValue(property);
var computedValue = computedStyle.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
if (isCloseEnough(computedValue, expectedValue))
result += "PASS - " + id + " at " + expected[index][0] + " saw something close to: " + expectedValue + "<br>";
else
result += "FAIL - " + id + " at " + expected[index][0] + " expected: " + expectedValue + " but saw: " + computedValue + "<br>";
}
Each sub-array must contain these items in this order:
- the name of the CSS animation (may be null) [1]
- 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 [2]
- the expected value for the CSS property
- the tolerance to use when comparing the effective CSS property value with its expected value
function checkFunctionWithParameter(i)
{
return function() {
checkExpectedValue(i);
};
}
[1] If null is passed, a regular setTimeout() will be used instead to snapshot the animated property in the future,
instead of fast forwarding using the pauseAnimationAtTimeOnElementWithId() JS API from DRT
[2] If the CSS property name is "webkitTransform", 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 "webkitTransform.N", expected value must be a number corresponding to the Nth element of the matrix
function setup()
*/
function runAnimationTest(expected, callback, event)
{
for (var i=0; i < expected.length; i++) {
window.setTimeout(checkFunctionWithParameter(i), expected[i][0]);
var result = "";
var hasPauseAnimationAPI = window.layoutTestController && layoutTestController.pauseAnimationAtTimeOnElementWithId;
function isCloseEnough(actual, desired, tolerance)
{
var diff = Math.abs(actual - desired);
return diff <= tolerance;
}
}
function cleanup()
{
document.getElementById('result').innerHTML = result;
if (window.layoutTestController)
layoutTestController.notifyDone();
}
\ No newline at end of file
function checkExpectedValue(expected, index)
{
var animationName = expected[index][0];
var time = expected[index][1];
var elementId = expected[index][2];
var property = expected[index][3];
var expectedValue = expected[index][4];
var tolerance = expected[index][5];
if (animationName && hasPauseAnimationAPI && !layoutTestController.pauseAnimationAtTimeOnElementWithId(animationName, time, elementId)) {
result += "FAIL - animation \"" + animationName + "\" is not running" + "<br>";
return;
}
var computedValue;
var pass;
if (!property.indexOf("webkitTransform")) {
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(16))]), 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 == "lineHeight") {
computedValue = parseInt(window.getComputedStyle(document.getElementById(elementId)).lineHeight);
pass = isCloseEnough(computedValue, expectedValue, tolerance);
} else {
var computedStyle = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property);
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>";
}
function endTest()
{
document.getElementById('result').innerHTML = result;
if (window.layoutTestController)
layoutTestController.notifyDone();
}
function checkExpectedValueCallback(expected, index)
{
return function() { checkExpectedValue(expected, index); };
}
var testStarted = false;
function startTest(expected, callback)
{
if (testStarted) return;
testStarted = true;
if (callback)
callback();
var maxTime = 0;
for (var i = 0; i < expected.length; ++i) {
var animationName = expected[i][0];
var time = expected[i][1];
// We can only use the animation fast-forward mechanism if there's an animation name
// and DRT implements pauseAnimationAtTimeOnElementWithId()
if (animationName && hasPauseAnimationAPI)
checkExpectedValue(expected, i);
else {
if (time > maxTime)
maxTime = time;
window.setTimeout(checkExpectedValueCallback(expected, i), time * 1000);
}
}
if (maxTime > 0)
window.setTimeout(endTest, maxTime * 1000 + 50);
else
endTest();
}
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
if (!expected)
throw("Expected results are missing!");
var target = document;
if (event == undefined)
event = "webkitAnimationStart";
else if (event == "load")
target = window;
target.addEventListener(event, function() { startTest(expected, callback); }, false);
}
This test shows rotation of > 180 degrees. The box should make one and a half rotations.
PASS
PASS - "webkitTransform" property for "box" element at 1s saw something close to: -1,0,0,-1
PASS - "webkitTransform" property for "box" element at 2s saw something close to: 1,0,0,1
PASS - "webkitTransform" property for "box" element at 3s saw something close to: -1,0,0,-1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
......@@ -11,64 +9,26 @@
height: 100px;
width: 100px;
background-color: blue;
-webkit-animation-duration: 1.03s;
-webkit-animation-duration: 3s;
-webkit-animation-timing-function: linear;
-webkit-animation-name: "rotate";
}
@-webkit-keyframes "rotate" {
from { -webkit-transform: rotate(0); }
to { -webkit-transform: rotate(558deg); }
to { -webkit-transform: rotate(540deg); }
}
</style>
<script src="animation-test-helpers.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
result = "PASS";
const defaultTolerance = 0.2;
const expected = [ [ -1,0,0,-1 ],
[ 1,0,0,1 ],
[ -1,0,0,-1 ] ];
function isEqual(actual, desired, tolerance)
{
if (tolerance == undefined || tolerance == 0)
tolerance = defaultTolerance;
var diff = Math.abs(actual - desired);
return diff < tolerance;
}
function snapshot(which)
{
if (result != "PASS")
return;
var s = window.getComputedStyle(document.getElementById('box')).webkitTransform;
var a = s.split("(");
var a = a[1].split(",");
for (i = 0; i < 4; ++i)
if (!isEqual(a[i], expected[which][i])) {
result = "FAIL(property'"+i+"' was:"+a[i]+", expected:"+expected[which][i]+")";
return;
}
}
function start()
{
setTimeout("snapshot(0)", 333);
setTimeout("snapshot(1)", 667);
setTimeout("snapshot(2)", 1000);
window.setTimeout(function() {
document.getElementById('result').innerHTML = result;
if (window.layoutTestController)
layoutTestController.notifyDone();
}, 1100);
}
const expectedValues = [
// [animation-name, time, element-id, property, expected-value, tolerance]
["rotate", 1, "box", "webkitTransform", [-1,0,0,-1], 0.2],
["rotate", 2, "box", "webkitTransform", [1,0,0,1], 0.2],
["rotate", 3, "box", "webkitTransform", [-1,0,0,-1], 0.2],
];
document.addEventListener('webkitAnimationStart', start, false);
runAnimationTest(expectedValues);
</script>
</head>
......
This test performs an animation of the left property and makes sure it is animating. Then it stops the animation, changes the keyframes to an animation of the top property, restarts the animation and makes sure top is animating.
PASS
PASS - "left" property for "box" element at 0.5s saw something close to: 200
PASS - "top" property for "box" element at 1s saw something close to: 100
This test starts by making sure the animation is not running, because the animation-name and the name of they @keyframes rule do not match. Then it changes the name of the @keyframes rule so they match and makes sure the animation is now running.
PASS
PASS: animation is not running
PASS - "left" property for "box" element at 0.45s saw something close to: 200
......@@ -24,33 +24,14 @@
to { left: 300px; }
}
</style>
<script src="animation-test-helpers.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
result = "PASS";
const defaultTolerance = 10;
function isEqual(actual, desired, tolerance)
{
if (tolerance == undefined || tolerance == 0)
tolerance = defaultTolerance;
var diff = Math.abs(actual - desired);
return diff < tolerance;
}
function snapshot(expected)
{
if (result != "PASS")
return;
var prop = parseInt(window.getComputedStyle(document.getElementById('box')).left);
if (!isEqual(prop, expected))
result = "FAIL('left' property was:"+prop+", expected:"+expected+")";
}
const expectedValues = [
// [animation-name, time, element-id, property, expected-value, tolerance]
[null, 0.2 + 0.25, "box", "left", 200, 10],
];
function findKeyframesRule(rule)
{
var ss = document.styleSheets;
......@@ -72,20 +53,17 @@
document.getElementById('box').style.webkitAnimationName = "anim";
}
function start()
function setup()
{
document.removeEventListener('webkitAnimationStart', start, false);
setTimeout("snapshot(200)", 250);
window.setTimeout(function() {
document.getElementById('result').innerHTML = result;
if (window.layoutTestController)
layoutTestController.notifyDone();
}, 300);
if (layoutTestController.pauseAnimationAtTimeOnElementWithId("bar", 0.5, "box"))
document.getElementById("pre-result").innerHTML = "FAIL: animation is running";
else
document.getElementById("pre-result").innerHTML = "PASS: animation is not running";
setTimeout("change()", 200);
}
document.addEventListener('webkitAnimationStart', start, false);
setTimeout("snapshot(0)", 100);
setTimeout("change()", 200);
runAnimationTest(expectedValues, setup, "load");
</script>
</head>
......@@ -95,6 +73,8 @@ name of they @keyframes rule do not match. Then it changes the name of the @keyf
match and makes sure the animation is now running.
<div id="box">
</div>
<div id="pre-result">
</div>
<div id="result">
</div>
</body>
......
......@@ -24,33 +24,15 @@
to { left: 300px; }
}
</style>
<script src="animation-test-helpers.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
result = "PASS";
const defaultTolerance = 10;
function isEqual(actual, desired, tolerance)
{
if (tolerance == undefined || tolerance == 0)
tolerance = defaultTolerance;
var diff = Math.abs(actual - desired);
return diff < tolerance;
}
function snapshot(property, expected)
{
if (result != "PASS")
return;
var prop = parseInt(window.getComputedStyle(document.getElementById('box'))[property]);
if (!isEqual(prop, expected))
result = "FAIL('"+property+"' property was:"+prop+", expected:"+expected+")";
}
const expectedValues = [
// [animation-name, time, element-id, property, expected-value, tolerance]
[null, 0.5, "box", "left", 200, 10],
[null, 0.5 + 0.5, "box", "top", 100, 10],
];
function findKeyframesRule(rule)
{
var ss = document.styleSheets;
......@@ -77,14 +59,6 @@
keyframes.insertRule("60% { top: 100px; }");
keyframes.insertRule("100% { top: 150px; }");
document.getElementById('box').style.webkitAnimationName = "anim";
setTimeout("snapshot('top', 100)", 500);
window.setTimeout(function() {
document.getElementById('result').innerHTML = result;
if (window.layoutTestController)
layoutTestController.notifyDone();
}, 600);
}
function startChange()
......@@ -92,15 +66,13 @@
document.getElementById('box').style.webkitAnimationName = "none";
setTimeout("change()", 0);
}
function start()
function setup()
{
document.removeEventListener('webkitAnimationStart', start, false);
setTimeout("snapshot('left', 200)", 500);
setTimeout("startChange()", 600);
}
document.addEventListener('webkitAnimationStart', start, false);
runAnimationTest(expectedValues, setup);
</script>
</head>
......
This test performs two animations, left and top. It animates over 1 second. At 0.5 second it removes the left animation and the top animation should continue from where it left off.
PASS
PASS - "left" property for "box" element at 0.75s saw something close to: 150
PASS - "top" property for "box" element at 0.75s saw something close to: 225
......@@ -27,24 +27,14 @@
to { top: 300px; }
}
</style>
<script src="animation-test-helpers.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
result = "PASS";
const defaultTolerance = 15;
const expected = [ 1, 0, 0, 1, 0, 0 ];
function isEqual(actual, desired, tolerance)
{
if (tolerance == undefined || tolerance == 0)
tolerance = defaultTolerance;
var diff = Math.abs(actual - desired);
return diff < tolerance;
}
const expectedValues = [
// [animation-name, time, element-id, property, expected-value, tolerance]
[null, 0.75, "box", "left", 150, 15],
[null, 0.75, "box", "top", 225, 15],
];
function removeAnim()
{
......@@ -54,39 +44,12 @@
target.style.left = left;
}
function snapshot()
{
var target = document.getElementById("box");
var left = parseInt(window.getComputedStyle(target).left);
var top = parseInt(window.getComputedStyle(target).top);
if (!isEqual(left, 150)) {
result = "FAIL('left' was:"+left+", expected:150)";
return;
}
if (!isEqual(top, 225)) {
result = "FAIL('top' was:"+top+", expected:225)";
return;
}
}
function start(event)
function setup()
{
// We only want to continue for one of the two animations running
if (event.animationName == "horiz")
return;
setTimeout("removeAnim()", 500);
setTimeout("snapshot()", 750);
window.setTimeout(function() {
document.getElementById('result').innerHTML = result;
if (window.layoutTestController)
layoutTestController.notifyDone();
}, 800);
}
document.addEventListener('webkitAnimationStart', start, false);
runAnimationTest(expectedValues, setup);
</script>
</head>
<body>
......
This test performs an animation of the left property. It animates over 1 second. It takes 3 snapshots and expects each result to be within a specified range.
PASS - box at 250 saw something close to: 125
PASS - box at 500 saw something close to: 150
PASS - box at 750 saw something close to: 175
PASS - "left" property for "box" element at 0.25s saw something close to: 125
PASS - "left" property for "box" element at 0.5s saw something close to: 150
PASS - "left" property for "box" element at 0.75s saw something close to: 175
......@@ -25,25 +25,14 @@
<script src="animation-test-helpers.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
const defaultTolerance = 5;
const expected = [