[Web Animations] Turn Web Animations with CSS integration on
[WebKit-https.git] / LayoutTests / transitions / transition-end-event-helpers.js
1 var _recordedEvents = new Array();
2 // Number of events we're supposed to receive.
3 var _expectedEventCount = 0;
4 // Function invoked when we've received _expectedEventCount events.
5 var _endFunction;
6 // Have we processed the events? This is used to make sure we process the
7 // events only once.
8 var _processedEvents = false;
9
10 /* Call this function to record manually transition end events:
11
12 Function parameters:
13     event [required]: the event passed with "webkitTransitionEnd" or "transitionend"
14
15 */
16 function recordTransitionEndEvent(event)
17 {
18   if (event.type != "webkitTransitionEnd" && event.type != "transitionend" )
19     throw("Invalid transition end event!");
20
21   _recordedEvents.push([
22     event.propertyName,
23     event.target.id,
24     Math.round(event.elapsedTime * 1000) / 1000 // round to ms to avoid floating point imprecision
25     ]);
26   if (_recordedEvents.length == _expectedEventCount)
27     _endFunction();
28 }
29
30 /* This is the helper function to run transition end event tests:
31
32 Test page requirements:
33 - The body must contain an empty div with id "result"
34 - The body must contain a div with with id "container"
35 - Call this function directly from the <script> inside the test page
36
37 Function parameters:
38     expected [required]: an array of arrays defining the expected parameter values for the recorded transition end events (see below)
39     callback [optional]: a function to be executed just before the test starts (none by default)
40
41     Each sub-array must contain these items in this order:
42     - the name of the CSS property that was transitioning
43     - the id of the element on which the CSS property was transitioning
44     - the elapsed time in seconds at which the CSS property finished transitioning
45     - a boolean indicating if an event listener should be automatically added to the element to record the transition end event or if the script calls recordTransitionEndEvent() directly
46
47 */
48 function runTransitionTest(expected, callback)
49 {
50   _expectedEventCount = expected.length;
51
52   if (window.testRunner) {
53     testRunner.dumpAsText();
54     testRunner.waitUntilDone();
55   }
56   
57   function processEndEvents(expected)
58   {
59     if (_processedEvents)
60       return;  // Only need to process events once
61
62     _processedEvents = true;
63
64     function compareEventInfo(e1, e2)
65     {
66       // Sort by property name then event target id
67
68       // Index 0 is the property name
69       if (e1[0]<e2[0]) return -1;
70       if (e1[0]>e2[0]) return +1;
71
72       // Index 1 is the target id
73       if (e1[1]<e2[1]) return -1;
74       if (e1[1]>e2[1]) return +1;
75
76       return 0;
77     }
78
79     function examineResults(results, expected)
80     {
81       // Sort recorded and expected events arrays so they have the same ordering
82       expected.sort(compareEventInfo);
83       results.sort(compareEventInfo);
84
85       var result = '<p>';
86       for (var i=0; i < results.length && i < expected.length; ++i) {
87         var pass = expected[i][0] == results[i][0] && expected[i][1] == results[i][1] && expected[i][2] == results[i][2];
88
89         if (pass)
90           result += "PASS --- ";
91         else
92           result += "FAIL --- ";
93
94         result += "[Expected] Property: " + expected[i][0] + " ";
95         result += "Target: " + expected[i][1] + " ";
96         result += "Elapsed Time: " + expected[i][2];
97
98         if (!pass) {
99           result += " --- ";
100           result += "[Received] Property: " + results[i][0] + " ";
101           result += "Target: " + results[i][1] + " ";
102           result += "Elapsed Time: " + results[i][2];
103         }
104
105         result += "<br>";
106       }
107       result += "</p>";
108
109       if (expected.length > results.length) {
110         result += "<p>FAIL - Missing events<br>";
111         for (i=results.length; i < expected.length; ++i) {
112           result += "[Missing] Property: " + expected[i][0] + " ";
113           result += "Target: " + expected[i][1] + " ";
114           result += "Elapsed Time: " + expected[i][2] + "<br>";
115         }
116         result += "</p>";
117       } else if (expected.length < results.length) {
118         result += "<p>FAIL - Unexpected events<br>";
119         for (i=expected.length; i < results.length; ++i) {
120           result += "[Unexpected] Property: " + results[i][0] + " ";
121           result += "Target: " + results[i][1] + " ";
122           result += "Elapsed Time: " + results[i][2] + "<br>";
123         }
124         result += "</p>";
125       }
126
127       return result;
128     }
129
130     document.body.removeChild(document.getElementById('container'));
131     document.getElementById('result').innerHTML = examineResults(_recordedEvents, expected);
132
133     if (window.testRunner)
134         testRunner.notifyDone();
135   }
136
137   function startTest(expected, callback, maxTime)
138   {
139     if (callback)
140       callback();
141     
142     if (!maxTime)
143         maxTime = 0;
144
145     for (var i=0; i < expected.length; ++i) {
146       if (expected[i][3]) {
147         var box = document.getElementById(expected[i][1]);
148         box.addEventListener("webkitTransitionEnd", recordTransitionEndEvent, false);
149       }
150
151       var time = expected[i][2];
152       if (time > maxTime)
153           maxTime = time;
154     }
155     
156     _endFunction = function() { processEndEvents(expected); };
157     // Add one second of fudge. We don't just use the run-webkit-tests timeout
158     // because processEndEvents gives more information on what failed.
159     window.setTimeout(_endFunction, maxTime * 1000 + 1000);
160   }
161   
162   window.addEventListener('load', function() { startTest(expected, callback) }, false);
163 }