|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 // Tests that the developer toolbar errors count works properly. |
|
5 |
|
6 function test() { |
|
7 const TEST_URI = "http://example.com/browser/browser/devtools/shared/test/" + |
|
8 "browser_toolbar_webconsole_errors_count.html"; |
|
9 |
|
10 let gDevTools = Cu.import("resource:///modules/devtools/gDevTools.jsm", |
|
11 {}).gDevTools; |
|
12 |
|
13 let webconsole = document.getElementById("developer-toolbar-toolbox-button"); |
|
14 let tab1, tab2; |
|
15 |
|
16 Services.prefs.setBoolPref("javascript.options.strict", true); |
|
17 |
|
18 registerCleanupFunction(() => { |
|
19 Services.prefs.clearUserPref("javascript.options.strict"); |
|
20 }); |
|
21 |
|
22 ignoreAllUncaughtExceptions(); |
|
23 addTab(TEST_URI, openToolbar); |
|
24 |
|
25 function openToolbar(browser, tab) { |
|
26 tab1 = tab; |
|
27 ignoreAllUncaughtExceptions(false); |
|
28 |
|
29 expectUncaughtException(); |
|
30 |
|
31 if (!DeveloperToolbar.visible) { |
|
32 DeveloperToolbar.show(true, onOpenToolbar); |
|
33 } |
|
34 else { |
|
35 onOpenToolbar(); |
|
36 } |
|
37 } |
|
38 |
|
39 function onOpenToolbar() { |
|
40 ok(DeveloperToolbar.visible, "DeveloperToolbar is visible"); |
|
41 |
|
42 waitForButtonUpdate({ |
|
43 name: "web console button shows page errors", |
|
44 errors: 3, |
|
45 warnings: 0, |
|
46 callback: addErrors, |
|
47 }); |
|
48 } |
|
49 |
|
50 function addErrors() { |
|
51 expectUncaughtException(); |
|
52 |
|
53 waitForFocus(function() { |
|
54 let button = content.document.querySelector("button"); |
|
55 executeSoon(function() { |
|
56 EventUtils.synthesizeMouse(button, 3, 2, {}, content); |
|
57 }); |
|
58 }, content); |
|
59 |
|
60 waitForButtonUpdate({ |
|
61 name: "button shows one more error after click in page", |
|
62 errors: 4, |
|
63 warnings: 1, |
|
64 callback: () => { |
|
65 ignoreAllUncaughtExceptions(); |
|
66 addTab(TEST_URI, onOpenSecondTab); |
|
67 }, |
|
68 }); |
|
69 } |
|
70 |
|
71 function onOpenSecondTab(browser, tab) { |
|
72 tab2 = tab; |
|
73 |
|
74 ignoreAllUncaughtExceptions(false); |
|
75 expectUncaughtException(); |
|
76 |
|
77 waitForButtonUpdate({ |
|
78 name: "button shows correct number of errors after new tab is open", |
|
79 errors: 3, |
|
80 warnings: 0, |
|
81 callback: switchToTab1, |
|
82 }); |
|
83 } |
|
84 |
|
85 function switchToTab1() { |
|
86 gBrowser.selectedTab = tab1; |
|
87 waitForButtonUpdate({ |
|
88 name: "button shows the page errors from tab 1", |
|
89 errors: 4, |
|
90 warnings: 1, |
|
91 callback: openWebConsole.bind(null, tab1, onWebConsoleOpen), |
|
92 }); |
|
93 } |
|
94 |
|
95 function onWebConsoleOpen(hud) { |
|
96 dump("lolz!!\n"); |
|
97 waitForValue({ |
|
98 name: "web console shows the page errors", |
|
99 validator: function() { |
|
100 return hud.outputNode.querySelectorAll(".message[category=exception][severity=error]").length; |
|
101 }, |
|
102 value: 4, |
|
103 success: checkConsoleOutput.bind(null, hud), |
|
104 failure: () => { |
|
105 finish(); |
|
106 }, |
|
107 }); |
|
108 } |
|
109 |
|
110 function checkConsoleOutput(hud) { |
|
111 let msgs = ["foobarBug762996a", "foobarBug762996b", "foobarBug762996load", |
|
112 "foobarBug762996click", "foobarBug762996consoleLog", |
|
113 "foobarBug762996css", "fooBug788445"]; |
|
114 msgs.forEach(function(msg) { |
|
115 isnot(hud.outputNode.textContent.indexOf(msg), -1, |
|
116 msg + " found in the Web Console output"); |
|
117 }); |
|
118 |
|
119 hud.jsterm.clearOutput(); |
|
120 |
|
121 is(hud.outputNode.textContent.indexOf("foobarBug762996color"), -1, |
|
122 "clearOutput() worked"); |
|
123 |
|
124 expectUncaughtException(); |
|
125 let button = content.document.querySelector("button"); |
|
126 EventUtils.synthesizeMouse(button, 2, 2, {}, content); |
|
127 |
|
128 waitForButtonUpdate({ |
|
129 name: "button shows one more error after another click in page", |
|
130 errors: 5, |
|
131 warnings: 1, // warnings are not repeated by the js engine |
|
132 callback: () => waitForValue(waitForNewError), |
|
133 }); |
|
134 |
|
135 let waitForNewError = { |
|
136 name: "the Web Console displays the new error", |
|
137 validator: function() { |
|
138 return hud.outputNode.textContent.indexOf("foobarBug762996click") > -1; |
|
139 }, |
|
140 success: doClearConsoleButton.bind(null, hud), |
|
141 failure: finish, |
|
142 }; |
|
143 } |
|
144 |
|
145 function doClearConsoleButton(hud) { |
|
146 let clearButton = hud.ui.rootElement |
|
147 .querySelector(".webconsole-clear-console-button"); |
|
148 EventUtils.synthesizeMouse(clearButton, 2, 2, {}, hud.iframeWindow); |
|
149 |
|
150 is(hud.outputNode.textContent.indexOf("foobarBug762996click"), -1, |
|
151 "clear console button worked"); |
|
152 is(getErrorsCount(), 0, "page errors counter has been reset"); |
|
153 let tooltip = getTooltipValues(); |
|
154 is(tooltip[1], 0, "page warnings counter has been reset"); |
|
155 |
|
156 doPageReload(hud); |
|
157 } |
|
158 |
|
159 function doPageReload(hud) { |
|
160 tab1.linkedBrowser.addEventListener("load", onReload, true); |
|
161 |
|
162 ignoreAllUncaughtExceptions(); |
|
163 content.location.reload(); |
|
164 |
|
165 function onReload() { |
|
166 tab1.linkedBrowser.removeEventListener("load", onReload, true); |
|
167 ignoreAllUncaughtExceptions(false); |
|
168 expectUncaughtException(); |
|
169 |
|
170 waitForButtonUpdate({ |
|
171 name: "the Web Console button count has been reset after page reload", |
|
172 errors: 3, |
|
173 warnings: 0, |
|
174 callback: waitForValue.bind(null, waitForConsoleOutputAfterReload), |
|
175 }); |
|
176 } |
|
177 |
|
178 let waitForConsoleOutputAfterReload = { |
|
179 name: "the Web Console displays the correct number of errors after reload", |
|
180 validator: function() { |
|
181 return hud.outputNode.querySelectorAll(".message[category=exception][severity=error]").length; |
|
182 }, |
|
183 value: 3, |
|
184 success: function() { |
|
185 isnot(hud.outputNode.textContent.indexOf("foobarBug762996load"), -1, |
|
186 "foobarBug762996load found in console output after page reload"); |
|
187 testEnd(); |
|
188 }, |
|
189 failure: testEnd, |
|
190 }; |
|
191 } |
|
192 |
|
193 function testEnd() { |
|
194 document.getElementById("developer-toolbar-closebutton").doCommand(); |
|
195 let target1 = TargetFactory.forTab(tab1); |
|
196 gDevTools.closeToolbox(target1).then(() => { |
|
197 gBrowser.removeTab(tab1); |
|
198 gBrowser.removeTab(tab2); |
|
199 finish(); |
|
200 }); |
|
201 } |
|
202 |
|
203 // Utility functions |
|
204 |
|
205 function getErrorsCount() { |
|
206 let count = webconsole.getAttribute("error-count"); |
|
207 return count ? count : "0"; |
|
208 } |
|
209 |
|
210 function getTooltipValues() { |
|
211 let matches = webconsole.getAttribute("tooltiptext") |
|
212 .match(/(\d+) errors?, (\d+) warnings?/); |
|
213 return matches ? [matches[1], matches[2]] : [0, 0]; |
|
214 } |
|
215 |
|
216 function waitForButtonUpdate(options) { |
|
217 function check() { |
|
218 let errors = getErrorsCount(); |
|
219 let tooltip = getTooltipValues(); |
|
220 let result = errors == options.errors && tooltip[1] == options.warnings; |
|
221 if (result) { |
|
222 ok(true, options.name); |
|
223 is(errors, tooltip[0], "button error-count is the same as in the tooltip"); |
|
224 |
|
225 // Get out of the toolbar event execution loop. |
|
226 executeSoon(options.callback); |
|
227 } |
|
228 return result; |
|
229 } |
|
230 |
|
231 if (!check()) { |
|
232 info("wait for: " + options.name); |
|
233 DeveloperToolbar.on("errors-counter-updated", function onUpdate(event) { |
|
234 if (check()) { |
|
235 DeveloperToolbar.off(event, onUpdate); |
|
236 } |
|
237 }); |
|
238 } |
|
239 } |
|
240 |
|
241 function openWebConsole(tab, callback) |
|
242 { |
|
243 let target = TargetFactory.forTab(tab); |
|
244 gDevTools.showToolbox(target, "webconsole").then((toolbox) => |
|
245 callback(toolbox.getCurrentPanel().hud)); |
|
246 } |
|
247 } |