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