2008-12-18 Pierre-Olivier Latour <pol@apple.com>
[WebKit-https.git] / LayoutTests / transitions / transition-test-helpers.js
1 /* This is the helper function to run transition tests:
2
3 Test page requirements:
4 - The body must contain an empty div with id "result"
5 - Call this function directly from the <script> inside the test page
6
7 Function parameters:
8     expected [required]: an array of arrays defining a set of CSS properties that must have given values at specific times (see below)
9     callback [optional]: a function to be executed just before the test starts (none by default)
10     
11     Each sub-array must contain these items in this order:
12     - the time in seconds at which to snapshot the CSS property
13     - the id of the element on which to get the CSS property value
14     - the name of the CSS property to get [1]
15     - the expected value for the CSS property
16     - the tolerance to use when comparing the effective CSS property value with its expected value
17     
18     [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,
19     or a string which will be compared directly (useful if the expected value is "none")
20     If the CSS property name is "-webkit-transform.N", expected value must be a number corresponding to the Nth element of the matrix
21
22 */
23 function runTransitionTest(expected, callback)
24 {
25     var result = "";
26     var hasPauseTransitionAPI = window.layoutTestController && layoutTestController.pauseTransitionAtTimeOnElementWithId;
27
28     function isCloseEnough(actual, desired, tolerance)
29     {
30         var diff = Math.abs(actual - desired);
31         return diff <= tolerance;
32     }
33
34     function checkExpectedValue(expected, index)
35     {
36         var time = expected[index][0];
37         var elementId = expected[index][1];
38         var property = expected[index][2];
39         var expectedValue = expected[index][3];
40         var tolerance = expected[index][4];
41
42         var computedValue;
43         var pass;
44         if (!property.indexOf("-webkit-transform")) {
45             computedValue = window.getComputedStyle(document.getElementById(elementId)).webkitTransform;
46
47             if (typeof expectedValue == "string")
48                 pass = (computedValue == expectedValue);
49             else if (typeof expectedValue == "number") {
50                 var m = computedValue.split("(");
51                 var m = m[1].split(",");
52                 pass = isCloseEnough(parseFloat(m[parseInt(property.substring(18))]), expectedValue, tolerance);
53             } else {
54                 var m = computedValue.split("(");
55                 var m = m[1].split(",");
56                 for (i = 0; i < expectedValue.length; ++i) {
57                     pass = isCloseEnough(parseFloat(m[i]), expectedValue[i], tolerance);
58                     if (!pass)
59                         break;
60                 }
61             }
62         } else if (property == "lineHeight") {
63             computedValue = parseInt(window.getComputedStyle(document.getElementById(elementId)).lineHeight);
64             pass = isCloseEnough(computedValue, expectedValue, tolerance);
65         } else {    
66             var computedStyle = window.getComputedStyle(document.getElementById(elementId)).getPropertyCSSValue(property);
67             computedValue = computedStyle.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
68             pass = isCloseEnough(computedValue, expectedValue, tolerance);
69         }
70
71         if (pass)
72             result += "PASS - \"" + property + "\" property for \"" + elementId + "\" element at " + time + "s saw something close to: " + expectedValue + "<br>";
73         else
74             result += "FAIL - \"" + property + "\" property for \"" + elementId + "\" element at " + time + "s expected: " + expectedValue + " but saw: " + computedValue + "<br>";
75     }
76
77     function endTest()
78     {
79         document.getElementById('result').innerHTML = result;
80
81         if (window.layoutTestController)
82             layoutTestController.notifyDone();
83     }
84
85     function checkExpectedValueCallback(expected, index)
86     {
87         return function() { checkExpectedValue(expected, index); };
88     }
89
90     function runTest(expected)
91     {
92         var maxTime = 0;
93
94         for (var i = 0; i < expected.length; ++i) {
95             var time = expected[i][0];
96             var elementId = expected[i][1];
97             var property = expected[i][2];
98             if (!property.indexOf("-webkit-transform"))
99             property = "-webkit-transform";
100
101             // We can only use the transition fast-forward mechanism if DRT implements pauseTransitionAtTimeOnElementWithId()
102             if (hasPauseTransitionAPI) {
103                 layoutTestController.pauseTransitionAtTimeOnElementWithId(property, time, elementId);
104                 checkExpectedValue(expected, i);
105             }
106             else {
107                 if (time > maxTime)
108                     maxTime = time;
109
110                 window.setTimeout(checkExpectedValueCallback(expected, i), time * 1000);
111             }
112         }
113
114         if (maxTime > 0)
115             window.setTimeout(endTest, maxTime * 1000 + 50);
116         else
117             endTest();
118     }
119     
120     function startTest(expected, callback)
121     {
122         if (callback)
123             callback();
124
125         window.setTimeout(function() { runTest(expected); }, 0);
126     }
127     
128     if (window.layoutTestController) {
129         layoutTestController.dumpAsText();
130         layoutTestController.waitUntilDone();
131     }
132     
133     if (!expected)
134         throw("Expected results are missing!");
135     
136     window.addEventListener("load", function() { startTest(expected, callback); }, false);
137 }