Web Inspector: clean up initialization of managers and observers in InspectorTest
[WebKit-https.git] / LayoutTests / http / tests / inspector-protocol / resources / InspectorTest.js
1 /*
2  * Copyright (C) 2012 Samsung Electronics. All rights reserved.
3  * Copyright (C) 2014 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 InspectorFrontendAPI = {};
27
28 InspectorTest = {};
29 InspectorTest._dispatchTable = [];
30 InspectorTest._requestId = -1;
31 InspectorTest.eventHandler = {};
32
33 /**
34  * @param {string} method
35  * @param {object} params
36  * @param {function({object} messageObject)=} handler
37  */
38 InspectorTest.sendCommand = function(method, params, handler)
39 {
40     this._dispatchTable[++this._requestId] = handler;
41
42     var messageObject = { "method": method,
43                           "params": params,
44                           "id": this._requestId };
45
46     InspectorFrontendHost.sendMessageToBackend(JSON.stringify(messageObject));
47
48     return this._requestId;
49 }
50
51 /**
52  * @param {object} messageObject
53  */
54 InspectorFrontendAPI.dispatchMessageAsync = function(messageObject)
55 {
56     var messageId = messageObject["id"];
57     if (typeof messageId === "number") {
58         var handler = InspectorTest._dispatchTable[messageId];
59         if (handler && typeof handler === "function")
60             handler(messageObject);
61     } else {
62         var eventName = messageObject["method"];
63         var eventHandler = InspectorTest.eventHandler[eventName];
64         if (eventHandler)
65             eventHandler(messageObject);
66         else if (InspectorTest.defaultEventHandler)
67             InspectorTest.defaultEventHandler(messageObject);
68     }
69 }
70
71 /**
72 * Registers an event handler for messages coming from the InspectorBackend.
73 * If multiple callbacks are registered for the same event, it will chain the execution.
74 * @param {string} event name
75 * @param {function} handler to be executed
76 * @param {boolean} execute the handler before all other handlers
77 */
78 InspectorTest.addEventListener = function(eventName, callback, capture)
79 {
80     if (!InspectorTest.eventHandler[eventName]) {
81         InspectorTest.eventHandler[eventName] = callback;
82         return;
83     }
84     var firstHandler = InspectorTest.eventHandler[eventName];
85     var secondHandler = callback;
86     if (capture) {
87         // Swap firstHandler with the new callback, so that we execute the callback first.
88         [firstHandler, secondHandler] = [secondHandler, firstHandler];
89     }
90     InspectorTest.eventHandler[eventName] = function(messageObject)
91     {
92         firstHandler(messageObject);
93         secondHandler(messageObject);
94     };
95 }
96
97 /**
98 * Logs message to document.
99 * @param {string} message
100 */
101 InspectorTest.log = function(message)
102 {
103     this.sendCommand("Runtime.evaluate", { "expression": "log(" + JSON.stringify(message) + ")" } );
104 }
105
106 /**
107 * Logs an assert message to document.
108 * @param {boolean} condition
109 * @param {string} message
110 */
111 InspectorTest.assert = function(condition, message)
112 {
113     var status = condition ? "PASS" : "FAIL";
114     this.sendCommand("Runtime.evaluate", { "expression": "log(" + JSON.stringify(status + ": " + message) + ")" } );
115 }
116
117 /**
118 * Logs message directly to process stdout via alert function (hopefully followed by flush call).
119 * This message should survive process crash or kill by timeout.
120 * @param {string} message
121 */
122 InspectorTest.debugLog = function(message)
123 {
124     this.sendCommand("Runtime.evaluate", { "expression": "debugLog(" + JSON.stringify(message) + ")" } );
125 }
126
127 InspectorTest.completeTest = function()
128 {
129     this.sendCommand("Runtime.evaluate", { "expression": "closeTest();"} );
130 }
131
132 InspectorTest.checkForError = function(responseObject)
133 {
134     if (responseObject.error) {
135         InspectorTest.log("PROTOCOL ERROR: " + JSON.stringify(responseObject.error));
136         InspectorTest.completeTest();
137         throw "PROTOCOL ERROR";
138     }
139 }
140
141 /**
142  * @param {string} scriptName
143  */
144 InspectorTest.importScript = function(scriptName)
145 {
146     var xhr = new XMLHttpRequest();
147     xhr.open("GET", scriptName, false);
148     xhr.send(null);
149     if (xhr.status !== 0 && xhr.status !== 200)
150         throw new Error("Invalid script URL: " + scriptName);
151     var script = "try { " + xhr.responseText + "} catch (e) { alert(" + JSON.stringify("Error in: " + scriptName) + "); throw e; }";
152     window.eval(script);
153 }
154
155 InspectorTest.initializeInspectorModels = function()
156 {
157     // Catch any errors and finish the test early.
158     console.error = window.onerror = function()
159     {
160         InspectorTest.log(Array.prototype.join.call(arguments, ', '));
161         InspectorTest.completeTest();
162     };
163
164     console.assert = function(assertion, message)
165     {
166         if (assertion)
167             return;
168         InspectorTest.completeTest();
169         InspectorTest.log("ASSERT:" + message);
170     };
171
172     // Note: This function overwrites the InspectorFrontendAPI, so there's currently no
173     // way to intercept the messages from the backend.
174
175     var inspectorScripts = [
176         "Utilities",
177         "WebInspector",
178         "Object",
179         "InspectorBackend",
180         "InspectorFrontendAPI",
181         "InspectorFrontendHostStub",
182         "InspectorJSBackendCommands",
183         "InspectorWebBackendCommands",
184         "URLUtilities",
185         "MessageDispatcher",
186         "Setting",
187         "InspectorObserver",
188         "PageObserver",
189         "DOMObserver",
190         "CSSObserver",
191         "FrameResourceManager",
192         "RuntimeManager",
193         "Frame",
194         "Revision",
195         "SourceCodeRevision",
196         "SourceCode",
197         "Resource",
198         "ResourceCollection",
199         "DOMTreeManager",
200         "DOMNode",
201         "ContentFlow",
202         "DOMTree",
203         "DOMUtilities",
204         "ExecutionContext",
205         "ExecutionContextList",
206         "CSSStyleManager",
207         "Color",
208         "RuntimeObserver",
209         "RuntimeManager"
210     ];
211
212     // This corresponds to loading the scripts in Main.hml.
213     for (var i = 0; i < inspectorScripts.length; ++i)
214         InspectorTest.importScript("../../../../../Source/WebInspectorUI/UserInterface/" + inspectorScripts[i] + ".js");
215
216     // The initialization should be in sync with WebInspector.loaded in Main.js.
217     // FIXME: As soon as we can support all the observers and managers we should remove UI related tasks
218     // from WebInspector.loaded, so that it can be used from the LayoutTests.
219
220     InspectorFrontendHost.loaded();
221
222     // Enable agents.
223     InspectorAgent.enable();
224
225     InspectorBackend.registerInspectorDispatcher(new WebInspector.InspectorObserver);
226     InspectorBackend.registerPageDispatcher(new WebInspector.PageObserver);
227     InspectorBackend.registerDOMDispatcher(new WebInspector.DOMObserver);
228     InspectorBackend.registerCSSDispatcher(new WebInspector.CSSObserver);
229     if (InspectorBackend.registerRuntimeDispatcher)
230         InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeObserver);
231
232     WebInspector.frameResourceManager = new WebInspector.FrameResourceManager;
233     WebInspector.domTreeManager = new WebInspector.DOMTreeManager;
234     WebInspector.cssStyleManager = new WebInspector.CSSStyleManager;
235     WebInspector.runtimeManager = new WebInspector.RuntimeManager;
236 }
237
238
239 window.addEventListener("message", function(event) {
240     try {
241         eval(event.data);
242     } catch (e) {
243         alert(e.stack);
244         InspectorTest.completeTest();
245         throw e;
246     }
247 });