browser/devtools/inspector/test/head.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:f7b69d66e867
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 const Cu = Components.utils;
6 const Ci = Components.interfaces;
7 const Cc = Components.classes;
8
9 // Services.prefs.setBoolPref("devtools.debugger.log", true);
10 // SimpleTest.registerCleanupFunction(() => {
11 // Services.prefs.clearUserPref("devtools.debugger.log");
12 // });
13
14 //Services.prefs.setBoolPref("devtools.dump.emit", true);
15
16 let tempScope = {};
17 Cu.import("resource://gre/modules/devtools/LayoutHelpers.jsm", tempScope);
18 let LayoutHelpers = tempScope.LayoutHelpers;
19
20 let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", tempScope);
21 let TargetFactory = devtools.TargetFactory;
22
23 Components.utils.import("resource://gre/modules/devtools/Console.jsm", tempScope);
24 let console = tempScope.console;
25
26 // Import the GCLI test helper
27 let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
28 Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
29
30 gDevTools.testing = true;
31 SimpleTest.registerCleanupFunction(() => {
32 gDevTools.testing = false;
33 });
34
35 SimpleTest.registerCleanupFunction(() => {
36 console.error("Here we are\n");
37 let {DebuggerServer} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
38 console.error("DebuggerServer open connections: " + Object.getOwnPropertyNames(DebuggerServer._connections).length);
39
40 Services.prefs.clearUserPref("devtools.dump.emit");
41 Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
42 });
43
44 /**
45 * Simple DOM node accesor function that takes either a node or a string css
46 * selector as argument and returns the corresponding node
47 * @param {String|DOMNode} nodeOrSelector
48 * @return {DOMNode}
49 */
50 function getNode(nodeOrSelector) {
51 return typeof nodeOrSelector === "string" ?
52 content.document.querySelector(nodeOrSelector) :
53 nodeOrSelector;
54 }
55
56 /**
57 * Set the inspector's current selection to a node or to the first match of the
58 * given css selector
59 * @param {InspectorPanel} inspector The instance of InspectorPanel currently
60 * loaded in the toolbox
61 * @param {String} reason Defaults to "test" which instructs the inspector not
62 * to highlight the node upon selection
63 * @param {String} reason Defaults to "test" which instructs the inspector not to highlight the node upon selection
64 * @return a promise that resolves when the inspector is updated with the new
65 * node
66 */
67 function selectNode(nodeOrSelector, inspector, reason="test") {
68 info("Selecting the node " + nodeOrSelector);
69 let node = getNode(nodeOrSelector);
70 let updated = inspector.once("inspector-updated");
71 inspector.selection.setNode(node, reason);
72 return updated;
73 }
74
75 /**
76 * Open the toolbox, with the inspector tool visible.
77 * @param {Function} cb Optional callback, if you don't want to use the returned
78 * promise
79 * @return a promise that resolves when the inspector is ready
80 */
81 let openInspector = Task.async(function*(cb) {
82 info("Opening the inspector");
83 let target = TargetFactory.forTab(gBrowser.selectedTab);
84
85 let inspector, toolbox;
86
87 // Checking if the toolbox and the inspector are already loaded
88 // The inspector-updated event should only be waited for if the inspector
89 // isn't loaded yet
90 toolbox = gDevTools.getToolbox(target);
91 if (toolbox) {
92 inspector = toolbox.getPanel("inspector");
93 if (inspector) {
94 info("Toolbox and inspector already open");
95 if (cb) {
96 return cb(inspector, toolbox);
97 } else {
98 return {
99 toolbox: toolbox,
100 inspector: inspector
101 };
102 }
103 }
104 }
105
106 info("Opening the toolbox");
107 toolbox = yield gDevTools.showToolbox(target, "inspector");
108 yield waitForToolboxFrameFocus(toolbox);
109 inspector = toolbox.getPanel("inspector");
110
111 info("Waiting for the inspector to update");
112 yield inspector.once("inspector-updated");
113
114 if (cb) {
115 return cb(inspector, toolbox);
116 } else {
117 return {
118 toolbox: toolbox,
119 inspector: inspector
120 };
121 }
122 });
123
124 /**
125 * Wait for the toolbox frame to receive focus after it loads
126 * @param {Toolbox} toolbox
127 * @return a promise that resolves when focus has been received
128 */
129 function waitForToolboxFrameFocus(toolbox) {
130 info("Making sure that the toolbox's frame is focused");
131 let def = promise.defer();
132 let win = toolbox.frame.contentWindow;
133 waitForFocus(def.resolve, win);
134 return def.promise;
135 }
136
137 /**
138 * Open the toolbox, with the inspector tool visible, and the sidebar that
139 * corresponds to the given id selected
140 * @return a promise that resolves when the inspector is ready and the sidebar
141 * view is visible and ready
142 */
143 let openInspectorSideBar = Task.async(function*(id) {
144 let {toolbox, inspector} = yield openInspector();
145
146 if (!hasSideBarTab(inspector, id)) {
147 info("Waiting for the " + id + " sidebar to be ready");
148 yield inspector.sidebar.once(id + "-ready");
149 }
150
151 info("Selecting the " + id + " sidebar");
152 inspector.sidebar.select(id);
153
154 return {
155 toolbox: toolbox,
156 inspector: inspector,
157 view: inspector.sidebar.getWindowForTab(id)[id].view
158 };
159 });
160
161 /**
162 * Open the toolbox, with the inspector tool visible, and the computed-view
163 * sidebar tab selected.
164 * @return a promise that resolves when the inspector is ready and the computed
165 * view is visible and ready
166 */
167 function openComputedView() {
168 return openInspectorSideBar("computedview");
169 }
170
171 /**
172 * Open the toolbox, with the inspector tool visible, and the rule-view
173 * sidebar tab selected.
174 * @return a promise that resolves when the inspector is ready and the rule
175 * view is visible and ready
176 */
177 function openRuleView() {
178 return openInspectorSideBar("ruleview");
179 }
180
181 /**
182 * Checks whether the inspector's sidebar corresponding to the given id already
183 * exists
184 * @param {InspectorPanel}
185 * @param {String}
186 * @return {Boolean}
187 */
188 function hasSideBarTab(inspector, id) {
189 return !!inspector.sidebar.getWindowForTab(id);
190 }
191
192 function getActiveInspector()
193 {
194 let target = TargetFactory.forTab(gBrowser.selectedTab);
195 return gDevTools.getToolbox(target).getPanel("inspector");
196 }
197
198 function getNodeFront(node)
199 {
200 let inspector = getActiveInspector();
201 return inspector.walker.frontForRawNode(node);
202 }
203
204 function getHighlighter()
205 {
206 return gBrowser.selectedBrowser.parentNode.querySelector(".highlighter-container");
207 }
208
209 function getSimpleBorderRect() {
210 let {p1, p2, p3, p4} = getBoxModelStatus().border.points;
211
212 return {
213 top: p1.y,
214 left: p1.x,
215 width: p2.x - p1.x,
216 height: p4.y - p1.y
217 };
218 }
219
220 function getBoxModelRoot() {
221 let highlighter = getHighlighter();
222 return highlighter.querySelector(".box-model-root");
223 }
224
225 function getBoxModelStatus() {
226 let root = getBoxModelRoot();
227 let inspector = getActiveInspector();
228
229 return {
230 visible: !root.hasAttribute("hidden"),
231 currentNode: inspector.walker.currentNode,
232 margin: {
233 points: getPointsForRegion("margin"),
234 visible: isRegionHidden("margin")
235 },
236 border: {
237 points: getPointsForRegion("border"),
238 visible: isRegionHidden("border")
239 },
240 padding: {
241 points: getPointsForRegion("padding"),
242 visible: isRegionHidden("padding")
243 },
244 content: {
245 points: getPointsForRegion("content"),
246 visible: isRegionHidden("content")
247 },
248 guides: {
249 top: getGuideStatus("top"),
250 right: getGuideStatus("right"),
251 bottom: getGuideStatus("bottom"),
252 left: getGuideStatus("left")
253 }
254 };
255 }
256
257 function getGuideStatus(location) {
258 let root = getBoxModelRoot();
259 let guide = root.querySelector(".box-model-guide-" + location);
260
261 return {
262 visible: !guide.hasAttribute("hidden"),
263 x1: guide.getAttribute("x1"),
264 y1: guide.getAttribute("y1"),
265 x2: guide.getAttribute("x2"),
266 y2: guide.getAttribute("y2")
267 };
268 }
269
270 function getPointsForRegion(region) {
271 let root = getBoxModelRoot();
272 let box = root.querySelector(".box-model-" + region);
273 let points = box.getAttribute("points").split(/[, ]/);
274
275 // We multiply each value by 1 to cast it into a number
276 return {
277 p1: {
278 x: parseFloat(points[0]),
279 y: parseFloat(points[1])
280 },
281 p2: {
282 x: parseFloat(points[2]),
283 y: parseFloat(points[3])
284 },
285 p3: {
286 x: parseFloat(points[4]),
287 y: parseFloat(points[5])
288 },
289 p4: {
290 x: parseFloat(points[6]),
291 y: parseFloat(points[7])
292 }
293 };
294 }
295
296 function isRegionHidden(region) {
297 let root = getBoxModelRoot();
298 let box = root.querySelector(".box-model-" + region);
299
300 return !box.hasAttribute("hidden");
301 }
302
303 function isHighlighting()
304 {
305 let root = getBoxModelRoot();
306 return !root.hasAttribute("hidden");
307 }
308
309 function getHighlitNode()
310 {
311 if (isHighlighting()) {
312 let helper = new LayoutHelpers(window.content);
313 let points = getBoxModelStatus().content.points;
314 let x = (points.p1.x + points.p2.x + points.p3.x + points.p4.x) / 4;
315 let y = (points.p1.y + points.p2.y + points.p3.y + points.p4.y) / 4;
316
317 return helper.getElementFromPoint(window.content.document, x, y);
318 }
319 }
320
321 function computedView()
322 {
323 let sidebar = getActiveInspector().sidebar;
324 let iframe = sidebar.tabbox.querySelector(".iframe-computedview");
325 return iframe.contentWindow.computedView;
326 }
327
328 function computedViewTree()
329 {
330 return computedView().view;
331 }
332
333 function ruleView()
334 {
335 let sidebar = getActiveInspector().sidebar;
336 let iframe = sidebar.tabbox.querySelector(".iframe-ruleview");
337 return iframe.contentWindow.ruleView;
338 }
339
340 function getComputedView() {
341 let inspector = getActiveInspector();
342 return inspector.sidebar.getWindowForTab("computedview").computedview.view;
343 }
344
345 function waitForView(aName, aCallback) {
346 let inspector = getActiveInspector();
347 if (inspector.sidebar.getTab(aName)) {
348 aCallback();
349 } else {
350 inspector.sidebar.once(aName + "-ready", aCallback);
351 }
352 }
353
354 function synthesizeKeyFromKeyTag(aKeyId) {
355 let key = document.getElementById(aKeyId);
356 isnot(key, null, "Successfully retrieved the <key> node");
357
358 let modifiersAttr = key.getAttribute("modifiers");
359
360 let name = null;
361
362 if (key.getAttribute("keycode"))
363 name = key.getAttribute("keycode");
364 else if (key.getAttribute("key"))
365 name = key.getAttribute("key");
366
367 isnot(name, null, "Successfully retrieved keycode/key");
368
369 let modifiers = {
370 shiftKey: modifiersAttr.match("shift"),
371 ctrlKey: modifiersAttr.match("ctrl"),
372 altKey: modifiersAttr.match("alt"),
373 metaKey: modifiersAttr.match("meta"),
374 accelKey: modifiersAttr.match("accel")
375 }
376
377 EventUtils.synthesizeKey(name, modifiers);
378 }
379
380 function focusSearchBoxUsingShortcut(panelWin, callback) {
381 panelWin.focus();
382 let key = panelWin.document.getElementById("nodeSearchKey");
383 isnot(key, null, "Successfully retrieved the <key> node");
384
385 let modifiersAttr = key.getAttribute("modifiers");
386
387 let name = null;
388
389 if (key.getAttribute("keycode")) {
390 name = key.getAttribute("keycode");
391 } else if (key.getAttribute("key")) {
392 name = key.getAttribute("key");
393 }
394
395 isnot(name, null, "Successfully retrieved keycode/key");
396
397 let modifiers = {
398 shiftKey: modifiersAttr.match("shift"),
399 ctrlKey: modifiersAttr.match("ctrl"),
400 altKey: modifiersAttr.match("alt"),
401 metaKey: modifiersAttr.match("meta"),
402 accelKey: modifiersAttr.match("accel")
403 }
404
405 let searchBox = panelWin.document.getElementById("inspector-searchbox");
406 searchBox.addEventListener("focus", function onFocus() {
407 searchBox.removeEventListener("focus", onFocus, false);
408 callback && callback();
409 }, false);
410 EventUtils.synthesizeKey(name, modifiers);
411 }
412
413 function getComputedPropertyValue(aName)
414 {
415 let computedview = getComputedView();
416 let props = computedview.styleDocument.querySelectorAll(".property-view");
417
418 for (let prop of props) {
419 let name = prop.querySelector(".property-name");
420
421 if (name.textContent === aName) {
422 let value = prop.querySelector(".property-value");
423 return value.textContent;
424 }
425 }
426 }
427
428 function getContainerForRawNode(markupView, rawNode)
429 {
430 let front = markupView.walker.frontForRawNode(rawNode);
431 let container = markupView.getContainer(front);
432 return container;
433 }
434
435 SimpleTest.registerCleanupFunction(function () {
436 let target = TargetFactory.forTab(gBrowser.selectedTab);
437 gDevTools.closeToolbox(target);
438 });

mercurial