7c68b20ff66c82e78c9f3792d716af062ea429da
[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 if (propValue === null)
117             InspectorTest.addResult(prefixWithName + "null");
118         else if (typeof propValue === "object")
119             InspectorTest.addObject(propValue, nondeterministicProps, prefix + "    ", prefixWithName);
120         else if (typeof propValue === "string")
121             InspectorTest.addResult(prefixWithName + "\"" + propValue + "\"");
122         else
123             InspectorTest.addResult(prefixWithName + propValue);
124     }
125     InspectorTest.addResult(prefix + "}");
126 }
127
128 InspectorTest.assertGreaterOrEqual = function(expected, actual, message)
129 {
130     if (actual < expected)
131         InspectorTest.addResult("FAILED: " + (message ? message + ": " : "") + actual + " < " + expected);
132 }
133
134 InspectorTest.reloadPage = function(callback)
135 {
136     InspectorTest._reloadPageCallback = InspectorTest.safeWrap(callback);
137
138     if (WebInspector.panels.network)
139         WebInspector.panels.network._reset();
140     PageAgent.reloadPage(false);
141 }
142
143 InspectorTest.pageReloaded = function()
144 {
145     resultsSynchronized = false;
146     InspectorTest.addResult("Page reloaded.");
147     if (InspectorTest._reloadPageCallback) {
148         var callback = InspectorTest._reloadPageCallback;
149         delete InspectorTest._reloadPageCallback;
150         callback();
151     }
152 }
153
154 InspectorTest.runAfterPendingDispatches = function(callback)
155 {
156     callback = InspectorTest.safeWrap(callback);
157     InspectorBackend.runAfterPendingDispatches(callback);
158 }
159
160 InspectorTest.createKeyEvent = function(keyIdentifier, ctrlKey, altKey, shiftKey, metaKey)
161 {
162     var evt = document.createEvent("KeyboardEvent");
163     evt.initKeyboardEvent("keydown", true /* can bubble */, true /* can cancel */, null /* view */, keyIdentifier, "", ctrlKey, altKey, shiftKey, metaKey);
164     return evt;
165 }
166
167 InspectorTest.runTestSuite = function(testSuite)
168 {
169     var testSuiteTests = testSuite.slice();
170
171     function runner()
172     {
173         if (!testSuiteTests.length) {
174             InspectorTest.completeTest();
175             return;
176         }
177         var nextTest = testSuiteTests.shift();
178         InspectorTest.addResult("");
179         InspectorTest.addResult("Running: " + /function\s([^(]*)/.exec(nextTest)[1]);
180         InspectorTest.safeWrap(nextTest)(runner, runner);
181     }
182     runner();
183 }
184
185 InspectorTest.assertEquals = function(expected, found, message)
186 {
187     if (expected === found)
188         return;
189
190     var error;
191     if (message)
192         error = "Failure (" + message + "):";
193     else
194         error = "Failure:";
195     throw new Error(error + " expected <" + expected + "> found <" + found + ">");
196 }
197
198 InspectorTest.safeWrap = function(func, onexception)
199 {
200     function result()
201     {
202         if (!func)
203             return;
204         var wrapThis = this;
205         try {
206             return func.apply(wrapThis, arguments);
207         } catch(e) {
208             InspectorTest.addResult("Exception while running: " + func + "\n" + (e.stack || e));
209             if (onexception)
210                 InspectorTest.safeWrap(onexception)();
211             else
212                 InspectorTest.completeTest();
213         }
214     }
215     return result;
216 }
217
218 InspectorTest.addSniffer = function(receiver, methodName, override, opt_sticky)
219 {
220     override = InspectorTest.safeWrap(override);
221
222     var original = receiver[methodName];
223     if (typeof original !== "function")
224         throw ("Cannot find method to override: " + methodName);
225
226     receiver[methodName] = function(var_args) {
227         try {
228             var result = original.apply(this, arguments);
229         } finally {
230             if (!opt_sticky)
231                 receiver[methodName] = original;
232         }
233         // In case of exception the override won't be called.
234         try {
235             override.apply(this, arguments);
236         } catch (e) {
237             throw ("Exception in overriden method '" + methodName + "': " + e);
238         }
239         return result;
240     };
241 }
242
243 InspectorTest.override = function(receiver, methodName, override, opt_sticky)
244 {
245     override = InspectorTest.safeWrap(override);
246
247     var original = receiver[methodName];
248     if (typeof original !== "function")
249         throw ("Cannot find method to override: " + methodName);
250
251     receiver[methodName] = function(var_args) {
252         try {
253             try {
254                 var result = override.apply(this, arguments);
255             } catch (e) {
256                 throw ("Exception in overriden method '" + methodName + "': " + e);
257             }
258         } finally {
259             if (!opt_sticky)
260                 receiver[methodName] = original;
261         }
262         return result;
263     };
264
265     return original;
266 }
267
268 InspectorTest.textContentWithLineBreaks = function(node)
269 {
270     var buffer = "";
271     var currentNode = node;
272     while (currentNode = currentNode.traverseNextNode(node)) {
273         if (currentNode.nodeType === Node.TEXT_NODE)
274             buffer += currentNode.nodeValue;
275         else if (currentNode.nodeName === "LI")
276             buffer += "\n    ";
277         else if (currentNode.classList.contains("console-message"))
278             buffer += "\n\n";
279     }
280     return buffer;
281 }
282
283 };
284
285 var runTestCallId = 0;
286 var completeTestCallId = 1;
287
288 function runAfterIframeIsLoaded()
289 {
290     if (window.layoutTestController)
291         layoutTestController.waitUntilDone();
292     function step()
293     {
294         if (!window.iframeLoaded)
295             setTimeout(step, 100);
296         else
297             runTest();
298     }
299     setTimeout(step, 100);
300 }
301
302 function runTest(enableWatchDogWhileDebugging)
303 {
304     if (!window.layoutTestController)
305         return;
306
307     layoutTestController.dumpAsText();
308     layoutTestController.waitUntilDone();
309
310     function runTestInFrontend(initializationFunctions, testFunction, completeTestCallId)
311     {
312         if (window.InspectorTest) {
313             InspectorTest.pageReloaded();
314             return;
315         }
316
317         InspectorTest = {};
318         InspectorTest.completeTestCallId = completeTestCallId;
319
320         for (var i = 0; i < initializationFunctions.length; ++i) {
321             try {
322                 initializationFunctions[i]();
323             } catch (e) {
324                 console.error("Exception in test initialization: " + e);
325                 InspectorTest.completeTest();
326             }
327         }
328
329         WebInspector.showPanel("console");
330         try {
331             testFunction();
332         } catch (e) {
333             console.error("Exception during test execution: " + e);
334             InspectorTest.completeTest();
335         }
336     }
337
338     var initializationFunctions = [];
339     for (var name in window) {
340         if (name.indexOf("initialize_") === 0 && typeof window[name] === "function")
341             initializationFunctions.push(window[name].toString());
342     }
343     var parameters = ["[" + initializationFunctions + "]", test, completeTestCallId];
344     var toEvaluate = "(" + runTestInFrontend + ")(" + parameters.join(", ") + ");";
345     layoutTestController.evaluateInWebInspector(runTestCallId, toEvaluate);
346
347     if (enableWatchDogWhileDebugging) {
348         function watchDog()
349         {
350             console.log("Internal watchdog triggered at 10 seconds. Test timed out.");
351             closeInspectorAndNotifyDone();
352         }
353         window._watchDogTimer = setTimeout(watchDog, 10000);
354     }
355 }
356
357 function didEvaluateForTestInFrontend(callId)
358 {
359     if (callId !== completeTestCallId)
360         return;
361     delete window.completeTestCallId;
362     // Close inspector asynchrously to allow caller of this
363     // function send response before backend dispatcher and frontend are destroyed.
364     setTimeout(closeInspectorAndNotifyDone, 0);
365 }
366
367 function closeInspectorAndNotifyDone()
368 {
369     if (window._watchDogTimer)
370         clearTimeout(window._watchDogTimer);
371
372     layoutTestController.closeWebInspector();
373     setTimeout(function() {
374         layoutTestController.notifyDone();
375     }, 0);
376 }
377
378 var outputElement;
379
380 function output(text)
381 {
382     if (!outputElement) {
383         var intermediate = document.createElement("div");
384         document.body.appendChild(intermediate);
385
386         var intermediate2 = document.createElement("div");
387         intermediate.appendChild(intermediate2);
388
389         outputElement = document.createElement("div");
390         outputElement.className = "output";
391         outputElement.style.whiteSpace = "pre";
392         intermediate2.appendChild(outputElement);
393     }
394     outputElement.appendChild(document.createTextNode(text));
395     outputElement.appendChild(document.createElement("br"));
396 }
397
398 function clearOutput()
399 {
400     if (outputElement) {
401         outputElement.parentNode.removeChild(outputElement);
402         outputElement = null;
403     }
404 }