2011-04-12 Ilya Tikhonovsky <loislo@chromium.org>
[WebKit-https.git] / LayoutTests / http / tests / inspector / inspector-test.js
1 var initialize_InspectorTest = function() {
2
3 var results = [];
4 var resultsSynchronized = false;
5
6 function consoleOutputHook(messageType)
7 {
8     InspectorTest.addResult(messageType + ": " + Array.prototype.slice.call(arguments, 1));
9 }
10
11 console.log = consoleOutputHook.bind(InspectorTest, "log");
12 console.error = consoleOutputHook.bind(InspectorTest, "error");
13 console.info = consoleOutputHook.bind(InspectorTest, "info");
14
15 InspectorTest.completeTest = function()
16 {
17     InspectorAgent.didEvaluateForTestInFrontend(InspectorTest.completeTestCallId, "");
18 }
19
20 InspectorTest.evaluateInConsole = function(code, callback)
21 {
22     callback = InspectorTest.safeWrap(callback);
23
24     WebInspector.console.visible = true;
25     WebInspector.console.prompt.text = code;
26     var event = document.createEvent("KeyboardEvent");
27     event.initKeyboardEvent("keydown", true, true, null, "Enter", "");
28     WebInspector.console.promptElement.dispatchEvent(event);
29     InspectorTest.addSniffer(WebInspector.ConsoleView.prototype, "addMessage",
30         function(commandResult) {
31             callback(commandResult.toMessageElement().textContent);
32         });
33 }
34
35 InspectorTest.evaluateInConsoleAndDump = function(code, callback)
36 {
37     callback = InspectorTest.safeWrap(callback);
38
39     function mycallback(text)
40     {
41         InspectorTest.addResult(code + " = " + text);
42         callback(text);
43     }
44     InspectorTest.evaluateInConsole(code, mycallback);
45 }
46
47 InspectorTest.evaluateInPage = function(code, callback)
48 {
49     callback = InspectorTest.safeWrap(callback);
50
51     function mycallback(error, result)
52     {
53         if (!error)
54             callback(WebInspector.RemoteObject.fromPayload(result));
55     }
56     RuntimeAgent.evaluate(code, "console", false, mycallback);
57 }
58
59 InspectorTest.evaluateInPageWithTimeout = function(code)
60 {
61     InspectorTest.evaluateInPage("setTimeout(unescape('" + escape(code) + "'))");
62 }
63
64 InspectorTest.addResult = function(text)
65 {
66     results.push(text);
67     if (resultsSynchronized)
68         addResultToPage(text);
69     else {
70         clearResults();
71         for (var i = 0; i < results.length; ++i)
72             addResultToPage(results[i]);
73         resultsSynchronized = true;
74     }
75
76     function clearResults()
77     {
78         InspectorTest.evaluateInPage("clearOutput()");
79     }
80
81     function addResultToPage(text)
82     {
83         InspectorTest.evaluateInPage("output(unescape('" + escape(text) + "'))");
84     }
85 }
86
87 InspectorTest.addResults = function(textArray)
88 {
89     if (!textArray)
90         return;
91     for (var i = 0, size = textArray.length; i < size; ++i)
92         InspectorTest.addResult(textArray[i]);
93 }
94
95 function onError(event)
96 {
97     window.removeEventListener("error", onError);
98     InspectorTest.addResult("Uncaught exception in inspector front-end: " + event.message + " [" + event.filename + ":" + event.lineno + "]");
99     InspectorTest.completeTest();
100 }
101
102 window.addEventListener("error", onError);
103
104 InspectorTest.addObject = function(object, nondeterministicProps, prefix, firstLinePrefix)
105 {
106     prefix = prefix || "";
107     firstLinePrefix = firstLinePrefix || prefix;
108     InspectorTest.addResult(firstLinePrefix + "{");
109     for (var prop in object) {
110         if (typeof object.hasOwnProperty === "function" && !object.hasOwnProperty(prop))
111             continue;
112         var prefixWithName = "    " + prefix + prop + " : ";
113         var propValue = object[prop];
114         if (nondeterministicProps && prop in nondeterministicProps)
115             InspectorTest.addResult(prefixWithName + "<" + typeof propValue + ">");
116         else
117             InspectorTest.dump(propValue, nondeterministicProps, "    " + prefix, prefixWithName);
118     }
119     InspectorTest.addResult(prefix + "}");
120 }
121
122 InspectorTest.addArray = function(array, nondeterministicProps, prefix, firstLinePrefix)
123 {
124     prefix = prefix || "";
125     firstLinePrefix = firstLinePrefix || prefix;
126     InspectorTest.addResult(firstLinePrefix + "[");
127     for (var i = 0; i < array.length; ++i)
128         InspectorTest.dump(array[i], nondeterministicProps, prefix + "    ");
129     InspectorTest.addResult(prefix + "]");
130 }
131
132 InspectorTest.dump = function(value, nondeterministicProps, prefix, prefixWithName)
133 {
134     prefixWithName = prefixWithName || prefix;
135     if (value === null)
136         InspectorTest.addResult(prefixWithName + "null");
137     else if (value instanceof Array)
138         InspectorTest.addArray(value, nondeterministicProps, prefix, prefixWithName);
139     else if (typeof value === "object")
140         InspectorTest.addObject(value, nondeterministicProps, prefix, prefixWithName);
141     else if (typeof value === "string")
142         InspectorTest.addResult(prefixWithName + "\"" + value + "\"");
143     else
144         InspectorTest.addResult(prefixWithName + value);
145 }
146
147 InspectorTest.assertGreaterOrEqual = function(expected, actual, message)
148 {
149     if (actual < expected)
150         InspectorTest.addResult("FAILED: " + (message ? message + ": " : "") + actual + " < " + expected);
151 }
152
153 InspectorTest.reloadPage = function(callback)
154 {
155     InspectorTest._reloadPageCallback = InspectorTest.safeWrap(callback);
156
157     if (WebInspector.panels.network)
158         WebInspector.panels.network._reset();
159     PageAgent.reloadPage(false);
160 }
161
162 InspectorTest.pageReloaded = function()
163 {
164     resultsSynchronized = false;
165     InspectorTest.addResult("Page reloaded.");
166     if (InspectorTest._reloadPageCallback) {
167         var callback = InspectorTest._reloadPageCallback;
168         delete InspectorTest._reloadPageCallback;
169         callback();
170     }
171 }
172
173 InspectorTest.runWhenPageLoads = function(callback)
174 {
175     var oldCallback = InspectorTest._reloadPageCallback;
176     function chainedCallback()
177     {
178         if (oldCallback)
179             oldCallback();
180         callback();
181     }
182     InspectorTest._reloadPageCallback = InspectorTest.safeWrap(chainedCallback);
183 }
184
185 InspectorTest.runAfterPendingDispatches = function(callback)
186 {
187     callback = InspectorTest.safeWrap(callback);
188     InspectorBackend.runAfterPendingDispatches(callback);
189 }
190
191 InspectorTest.createKeyEvent = function(keyIdentifier, ctrlKey, altKey, shiftKey, metaKey)
192 {
193     var evt = document.createEvent("KeyboardEvent");
194     evt.initKeyboardEvent("keydown", true /* can bubble */, true /* can cancel */, null /* view */, keyIdentifier, "", ctrlKey, altKey, shiftKey, metaKey);
195     return evt;
196 }
197
198 InspectorTest.runTestSuite = function(testSuite)
199 {
200     var testSuiteTests = testSuite.slice();
201
202     function runner()
203     {
204         if (!testSuiteTests.length) {
205             InspectorTest.completeTest();
206             return;
207         }
208         var nextTest = testSuiteTests.shift();
209         InspectorTest.addResult("");
210         InspectorTest.addResult("Running: " + /function\s([^(]*)/.exec(nextTest)[1]);
211         InspectorTest.safeWrap(nextTest)(runner, runner);
212     }
213     runner();
214 }
215
216 InspectorTest.assertEquals = function(expected, found, message)
217 {
218     if (expected === found)
219         return;
220
221     var error;
222     if (message)
223         error = "Failure (" + message + "):";
224     else
225         error = "Failure:";
226     throw new Error(error + " expected <" + expected + "> found <" + found + ">");
227 }
228
229 InspectorTest.safeWrap = function(func, onexception)
230 {
231     function result()
232     {
233         if (!func)
234             return;
235         var wrapThis = this;
236         try {
237             return func.apply(wrapThis, arguments);
238         } catch(e) {
239             InspectorTest.addResult("Exception while running: " + func + "\n" + (e.stack || e));
240             if (onexception)
241                 InspectorTest.safeWrap(onexception)();
242             else
243                 InspectorTest.completeTest();
244         }
245     }
246     return result;
247 }
248
249 InspectorTest.addSniffer = function(receiver, methodName, override, opt_sticky)
250 {
251     override = InspectorTest.safeWrap(override);
252
253     var original = receiver[methodName];
254     if (typeof original !== "function")
255         throw ("Cannot find method to override: " + methodName);
256
257     receiver[methodName] = function(var_args) {
258         try {
259             var result = original.apply(this, arguments);
260         } finally {
261             if (!opt_sticky)
262                 receiver[methodName] = original;
263         }
264         // In case of exception the override won't be called.
265         try {
266             override.apply(this, arguments);
267         } catch (e) {
268             throw ("Exception in overriden method '" + methodName + "': " + e);
269         }
270         return result;
271     };
272 }
273
274 InspectorTest.override = function(receiver, methodName, override, opt_sticky)
275 {
276     override = InspectorTest.safeWrap(override);
277
278     var original = receiver[methodName];
279     if (typeof original !== "function")
280         throw ("Cannot find method to override: " + methodName);
281
282     receiver[methodName] = function(var_args) {
283         try {
284             try {
285                 var result = override.apply(this, arguments);
286             } catch (e) {
287                 throw ("Exception in overriden method '" + methodName + "': " + e);
288             }
289         } finally {
290             if (!opt_sticky)
291                 receiver[methodName] = original;
292         }
293         return result;
294     };
295
296     return original;
297 }
298
299 InspectorTest.textContentWithLineBreaks = function(node)
300 {
301     var buffer = "";
302     var currentNode = node;
303     while (currentNode = currentNode.traverseNextNode(node)) {
304         if (currentNode.nodeType === Node.TEXT_NODE)
305             buffer += currentNode.nodeValue;
306         else if (currentNode.nodeName === "LI")
307             buffer += "\n    ";
308         else if (currentNode.classList.contains("console-message"))
309             buffer += "\n\n";
310     }
311     return buffer;
312 }
313
314 };
315
316 var runTestCallId = 0;
317 var completeTestCallId = 1;
318
319 function runAfterIframeIsLoaded()
320 {
321     if (window.layoutTestController)
322         layoutTestController.waitUntilDone();
323     function step()
324     {
325         if (!window.iframeLoaded)
326             setTimeout(step, 100);
327         else
328             runTest();
329     }
330     setTimeout(step, 100);
331 }
332
333 function runTest(enableWatchDogWhileDebugging)
334 {
335     if (!window.layoutTestController)
336         return;
337
338     layoutTestController.dumpAsText();
339     layoutTestController.waitUntilDone();
340
341     function runTestInFrontend(initializationFunctions, testFunction, completeTestCallId)
342     {
343         if (window.InspectorTest) {
344             InspectorTest.pageReloaded();
345             return;
346         }
347
348         InspectorTest = {};
349         InspectorTest.completeTestCallId = completeTestCallId;
350
351         for (var i = 0; i < initializationFunctions.length; ++i) {
352             try {
353                 initializationFunctions[i]();
354             } catch (e) {
355                 console.error("Exception in test initialization: " + e);
356                 InspectorTest.completeTest();
357             }
358         }
359
360         WebInspector.showPanel("console");
361         try {
362             testFunction();
363         } catch (e) {
364             console.error("Exception during test execution: " + e);
365             InspectorTest.completeTest();
366         }
367     }
368
369     var initializationFunctions = [];
370     for (var name in window) {
371         if (name.indexOf("initialize_") === 0 && typeof window[name] === "function")
372             initializationFunctions.push(window[name].toString());
373     }
374     var parameters = ["[" + initializationFunctions + "]", test, completeTestCallId];
375     var toEvaluate = "(" + runTestInFrontend + ")(" + parameters.join(", ") + ");";
376     layoutTestController.evaluateInWebInspector(runTestCallId, toEvaluate);
377
378     if (enableWatchDogWhileDebugging) {
379         function watchDog()
380         {
381             console.log("Internal watchdog triggered at 10 seconds. Test timed out.");
382             closeInspectorAndNotifyDone();
383         }
384         window._watchDogTimer = setTimeout(watchDog, 10000);
385     }
386 }
387
388 function didEvaluateForTestInFrontend(callId)
389 {
390     if (callId !== completeTestCallId)
391         return;
392     delete window.completeTestCallId;
393     // Close inspector asynchrously to allow caller of this
394     // function send response before backend dispatcher and frontend are destroyed.
395     setTimeout(closeInspectorAndNotifyDone, 0);
396 }
397
398 function closeInspectorAndNotifyDone()
399 {
400     if (window._watchDogTimer)
401         clearTimeout(window._watchDogTimer);
402
403     layoutTestController.closeWebInspector();
404     setTimeout(function() {
405         layoutTestController.notifyDone();
406     }, 0);
407 }
408
409 var outputElement;
410
411 function output(text)
412 {
413     if (!outputElement) {
414         var intermediate = document.createElement("div");
415         document.body.appendChild(intermediate);
416
417         var intermediate2 = document.createElement("div");
418         intermediate.appendChild(intermediate2);
419
420         outputElement = document.createElement("div");
421         outputElement.className = "output";
422         outputElement.style.whiteSpace = "pre";
423         intermediate2.appendChild(outputElement);
424     }
425     outputElement.appendChild(document.createTextNode(text));
426     outputElement.appendChild(document.createElement("br"));
427 }
428
429 function clearOutput()
430 {
431     if (outputElement) {
432         outputElement.parentNode.removeChild(outputElement);
433         outputElement = null;
434     }
435 }