|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 /** |
|
5 * Test if the context menu associated with each breakpoint does what it should. |
|
6 */ |
|
7 |
|
8 const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html"; |
|
9 |
|
10 function test() { |
|
11 // Debug test slaves are a bit slow at this test. |
|
12 requestLongerTimeout(2); |
|
13 |
|
14 let gTab, gDebuggee, gPanel, gDebugger; |
|
15 let gSources, gBreakpoints; |
|
16 |
|
17 initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { |
|
18 gTab = aTab; |
|
19 gDebuggee = aDebuggee; |
|
20 gPanel = aPanel; |
|
21 gDebugger = gPanel.panelWin; |
|
22 gSources = gDebugger.DebuggerView.Sources; |
|
23 gBreakpoints = gDebugger.DebuggerController.Breakpoints; |
|
24 |
|
25 waitForSourceShown(gPanel, "-01.js") |
|
26 .then(performTestWhileNotPaused) |
|
27 .then(performTestWhilePaused) |
|
28 .then(() => resumeDebuggerThenCloseAndFinish(gPanel)) |
|
29 .then(null, aError => { |
|
30 ok(false, "Got an error: " + aError.message + "\n" + aError.stack); |
|
31 }); |
|
32 }); |
|
33 |
|
34 function addBreakpoints() { |
|
35 return promise.resolve(null) |
|
36 .then(() => gPanel.addBreakpoint({ url: gSources.values[0], line: 5 })) |
|
37 .then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 6 })) |
|
38 .then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 7 })) |
|
39 .then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 8 })) |
|
40 .then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 9 })) |
|
41 .then(() => ensureThreadClientState(gPanel, "resumed")); |
|
42 } |
|
43 |
|
44 function performTestWhileNotPaused() { |
|
45 info("Performing test while not paused..."); |
|
46 |
|
47 return addBreakpoints() |
|
48 .then(initialChecks) |
|
49 .then(() => checkBreakpointToggleSelf(0)) |
|
50 .then(() => checkBreakpointToggleOthers(0)) |
|
51 .then(() => checkBreakpointToggleSelf(1)) |
|
52 .then(() => checkBreakpointToggleOthers(1)) |
|
53 .then(() => checkBreakpointToggleSelf(2)) |
|
54 .then(() => checkBreakpointToggleOthers(2)) |
|
55 .then(() => checkBreakpointToggleSelf(3)) |
|
56 .then(() => checkBreakpointToggleOthers(3)) |
|
57 .then(() => checkBreakpointToggleSelf(4)) |
|
58 .then(() => checkBreakpointToggleOthers(4)) |
|
59 .then(testDeleteAll); |
|
60 } |
|
61 |
|
62 function performTestWhilePaused() { |
|
63 info("Performing test while paused..."); |
|
64 |
|
65 return addBreakpoints() |
|
66 .then(initialChecks) |
|
67 .then(pauseAndCheck) |
|
68 .then(() => checkBreakpointToggleSelf(0)) |
|
69 .then(() => checkBreakpointToggleOthers(0)) |
|
70 .then(() => checkBreakpointToggleSelf(1)) |
|
71 .then(() => checkBreakpointToggleOthers(1)) |
|
72 .then(() => checkBreakpointToggleSelf(2)) |
|
73 .then(() => checkBreakpointToggleOthers(2)) |
|
74 .then(() => checkBreakpointToggleSelf(3)) |
|
75 .then(() => checkBreakpointToggleOthers(3)) |
|
76 .then(() => checkBreakpointToggleSelf(4)) |
|
77 .then(() => checkBreakpointToggleOthers(4)) |
|
78 .then(testDeleteAll); |
|
79 } |
|
80 |
|
81 function pauseAndCheck() { |
|
82 let finished = waitForSourceAndCaretAndScopes(gPanel, "-01.js", 5).then(() => { |
|
83 is(gSources.selectedValue, EXAMPLE_URL + "code_script-switching-01.js", |
|
84 "The currently selected source is incorrect (3)."); |
|
85 is(gSources.selectedIndex, 0, |
|
86 "The currently selected source is incorrect (4)."); |
|
87 ok(isCaretPos(gPanel, 5), |
|
88 "The editor location is correct after pausing."); |
|
89 }); |
|
90 |
|
91 is(gSources.selectedValue, EXAMPLE_URL + "code_script-switching-02.js", |
|
92 "The currently selected source is incorrect (1)."); |
|
93 is(gSources.selectedIndex, 1, |
|
94 "The currently selected source is incorrect (2)."); |
|
95 ok(isCaretPos(gPanel, 9), |
|
96 "The editor location is correct before pausing."); |
|
97 |
|
98 // Spin the event loop before causing the debuggee to pause, to allow |
|
99 // this function to return first. |
|
100 executeSoon(() => { |
|
101 EventUtils.sendMouseEvent({ type: "click" }, |
|
102 gDebuggee.document.querySelector("button"), |
|
103 gDebuggee); |
|
104 }); |
|
105 |
|
106 return finished; |
|
107 } |
|
108 |
|
109 function initialChecks() { |
|
110 for (let source of gSources) { |
|
111 for (let breakpoint of source) { |
|
112 ok(gBreakpoints._getAdded(breakpoint.attachment), |
|
113 "All breakpoint items should have corresponding promises (1)."); |
|
114 ok(!gBreakpoints._getRemoving(breakpoint.attachment), |
|
115 "All breakpoint items should have corresponding promises (2)."); |
|
116 ok(breakpoint.attachment.actor, |
|
117 "All breakpoint items should have corresponding promises (3)."); |
|
118 is(!!breakpoint.attachment.disabled, false, |
|
119 "All breakpoints should initially be enabled."); |
|
120 |
|
121 let prefix = "bp-cMenu-"; // "breakpoints context menu" |
|
122 let identifier = gBreakpoints.getIdentifier(breakpoint.attachment); |
|
123 let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem"; |
|
124 let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem"; |
|
125 |
|
126 is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true", |
|
127 "The 'Enable breakpoint' context menu item should initially be hidden'."); |
|
128 ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"), |
|
129 "The 'Disable breakpoint' context menu item should initially not be hidden'."); |
|
130 is(breakpoint.attachment.view.checkbox.getAttribute("checked"), "true", |
|
131 "All breakpoints should initially have a checked checkbox."); |
|
132 } |
|
133 } |
|
134 } |
|
135 |
|
136 function checkBreakpointToggleSelf(aIndex) { |
|
137 let deferred = promise.defer(); |
|
138 |
|
139 EventUtils.sendMouseEvent({ type: "click" }, |
|
140 gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex], |
|
141 gDebugger); |
|
142 |
|
143 let selectedBreakpoint = gSources._selectedBreakpointItem; |
|
144 |
|
145 ok(gBreakpoints._getAdded(selectedBreakpoint.attachment), |
|
146 "There should be a breakpoint client available (1)."); |
|
147 ok(!gBreakpoints._getRemoving(selectedBreakpoint.attachment), |
|
148 "There should be a breakpoint client available (2)."); |
|
149 ok(selectedBreakpoint.attachment.actor, |
|
150 "There should be a breakpoint client available (3)."); |
|
151 is(!!selectedBreakpoint.attachment.disabled, false, |
|
152 "The breakpoint should not be disabled yet (" + aIndex + ")."); |
|
153 |
|
154 gBreakpoints._getAdded(selectedBreakpoint.attachment).then(aBreakpointClient => { |
|
155 ok(aBreakpointClient, |
|
156 "There should be a breakpoint client available as a promise."); |
|
157 }); |
|
158 |
|
159 let prefix = "bp-cMenu-"; // "breakpoints context menu" |
|
160 let identifier = gBreakpoints.getIdentifier(selectedBreakpoint.attachment); |
|
161 let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem"; |
|
162 let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem"; |
|
163 |
|
164 is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true", |
|
165 "The 'Enable breakpoint' context menu item should be hidden'."); |
|
166 ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"), |
|
167 "The 'Disable breakpoint' context menu item should not be hidden'."); |
|
168 |
|
169 ok(isCaretPos(gPanel, selectedBreakpoint.attachment.line), |
|
170 "The source editor caret position was incorrect (" + aIndex + ")."); |
|
171 |
|
172 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED).then(() => { |
|
173 ok(!gBreakpoints._getAdded(selectedBreakpoint.attachment), |
|
174 "There should be no breakpoint client available (4)."); |
|
175 |
|
176 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED).then(() => { |
|
177 ok(gBreakpoints._getAdded(selectedBreakpoint.attachment), |
|
178 "There should be a breakpoint client available (5)."); |
|
179 |
|
180 deferred.resolve(); |
|
181 }); |
|
182 |
|
183 // Test re-disabling this breakpoint. |
|
184 gSources._onEnableSelf(selectedBreakpoint.attachment); |
|
185 is(selectedBreakpoint.attachment.disabled, false, |
|
186 "The current breakpoint should now be enabled.") |
|
187 |
|
188 is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true", |
|
189 "The 'Enable breakpoint' context menu item should be hidden'."); |
|
190 ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"), |
|
191 "The 'Disable breakpoint' context menu item should not be hidden'."); |
|
192 ok(selectedBreakpoint.attachment.view.checkbox.hasAttribute("checked"), |
|
193 "The breakpoint should now be checked."); |
|
194 }); |
|
195 |
|
196 // Test disabling this breakpoint. |
|
197 gSources._onDisableSelf(selectedBreakpoint.attachment); |
|
198 is(selectedBreakpoint.attachment.disabled, true, |
|
199 "The current breakpoint should now be disabled.") |
|
200 |
|
201 ok(!gDebugger.document.getElementById(enableSelfId).hasAttribute("hidden"), |
|
202 "The 'Enable breakpoint' context menu item should not be hidden'."); |
|
203 is(gDebugger.document.getElementById(disableSelfId).getAttribute("hidden"), "true", |
|
204 "The 'Disable breakpoint' context menu item should be hidden'."); |
|
205 ok(!selectedBreakpoint.attachment.view.checkbox.hasAttribute("checked"), |
|
206 "The breakpoint should now be unchecked."); |
|
207 |
|
208 return deferred.promise; |
|
209 } |
|
210 |
|
211 function checkBreakpointToggleOthers(aIndex) { |
|
212 let deferred = promise.defer(); |
|
213 |
|
214 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 4).then(() => { |
|
215 let selectedBreakpoint = gSources._selectedBreakpointItem; |
|
216 |
|
217 ok(gBreakpoints._getAdded(selectedBreakpoint.attachment), |
|
218 "There should be a breakpoint client available (6)."); |
|
219 ok(!gBreakpoints._getRemoving(selectedBreakpoint.attachment), |
|
220 "There should be a breakpoint client available (7)."); |
|
221 ok(selectedBreakpoint.attachment.actor, |
|
222 "There should be a breakpoint client available (8)."); |
|
223 is(!!selectedBreakpoint.attachment.disabled, false, |
|
224 "The targetted breakpoint should not have been disabled (" + aIndex + ")."); |
|
225 |
|
226 for (let source of gSources) { |
|
227 for (let otherBreakpoint of source) { |
|
228 if (otherBreakpoint != selectedBreakpoint) { |
|
229 ok(!gBreakpoints._getAdded(otherBreakpoint.attachment), |
|
230 "There should be no breakpoint client for a disabled breakpoint (9)."); |
|
231 is(otherBreakpoint.attachment.disabled, true, |
|
232 "Non-targetted breakpoints should have been disabled (10)."); |
|
233 } |
|
234 } |
|
235 } |
|
236 |
|
237 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 4).then(() => { |
|
238 for (let source of gSources) { |
|
239 for (let someBreakpoint of source) { |
|
240 ok(gBreakpoints._getAdded(someBreakpoint.attachment), |
|
241 "There should be a breakpoint client for all enabled breakpoints (11)."); |
|
242 is(someBreakpoint.attachment.disabled, false, |
|
243 "All breakpoints should now have been enabled (12)."); |
|
244 } |
|
245 } |
|
246 |
|
247 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 5).then(() => { |
|
248 for (let source of gSources) { |
|
249 for (let someBreakpoint of source) { |
|
250 ok(!gBreakpoints._getAdded(someBreakpoint.attachment), |
|
251 "There should be no breakpoint client for a disabled breakpoint (13)."); |
|
252 is(someBreakpoint.attachment.disabled, true, |
|
253 "All breakpoints should now have been disabled (14)."); |
|
254 } |
|
255 } |
|
256 |
|
257 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 5).then(() => { |
|
258 for (let source of gSources) { |
|
259 for (let someBreakpoint of source) { |
|
260 ok(gBreakpoints._getAdded(someBreakpoint.attachment), |
|
261 "There should be a breakpoint client for all enabled breakpoints (15)."); |
|
262 is(someBreakpoint.attachment.disabled, false, |
|
263 "All breakpoints should now have been enabled (16)."); |
|
264 } |
|
265 } |
|
266 |
|
267 // Done. |
|
268 deferred.resolve(); |
|
269 }); |
|
270 |
|
271 // Test re-enabling all breakpoints. |
|
272 enableAll(); |
|
273 }); |
|
274 |
|
275 // Test disabling all breakpoints. |
|
276 disableAll(); |
|
277 }); |
|
278 |
|
279 // Test re-enabling other breakpoints. |
|
280 enableOthers(); |
|
281 }); |
|
282 |
|
283 // Test disabling other breakpoints. |
|
284 disableOthers(); |
|
285 |
|
286 return deferred.promise; |
|
287 } |
|
288 |
|
289 function testDeleteAll() { |
|
290 let deferred = promise.defer(); |
|
291 |
|
292 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 5).then(() => { |
|
293 ok(!gSources._selectedBreakpointItem, |
|
294 "There should be no breakpoint available after removing all breakpoints."); |
|
295 |
|
296 for (let source of gSources) { |
|
297 for (let otherBreakpoint of source) { |
|
298 ok(false, "It's a trap!"); |
|
299 } |
|
300 } |
|
301 |
|
302 // Done. |
|
303 deferred.resolve() |
|
304 }); |
|
305 |
|
306 // Test deleting all breakpoints. |
|
307 deleteAll(); |
|
308 |
|
309 return deferred.promise; |
|
310 } |
|
311 |
|
312 function disableOthers() { |
|
313 gSources._onDisableOthers(gSources._selectedBreakpointItem.attachment); |
|
314 } |
|
315 function enableOthers() { |
|
316 gSources._onEnableOthers(gSources._selectedBreakpointItem.attachment); |
|
317 } |
|
318 function disableAll() { |
|
319 gSources._onDisableAll(); |
|
320 } |
|
321 function enableAll() { |
|
322 gSources._onEnableAll(); |
|
323 } |
|
324 function deleteAll() { |
|
325 gSources._onDeleteAll(); |
|
326 } |
|
327 } |