|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 /** |
|
5 * Make sure that the variables view correctly re-expands nodes after pauses, |
|
6 * with the caveat that there are no ignored items in the hierarchy. |
|
7 */ |
|
8 |
|
9 const TAB_URL = EXAMPLE_URL + "doc_with-frame.html"; |
|
10 |
|
11 let gTab, gDebuggee, gPanel, gDebugger; |
|
12 let gBreakpoints, gSources, gVariables; |
|
13 |
|
14 function test() { |
|
15 // Debug test slaves are a bit slow at this test. |
|
16 requestLongerTimeout(4); |
|
17 |
|
18 initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { |
|
19 gTab = aTab; |
|
20 gDebuggee = aDebuggee; |
|
21 gPanel = aPanel; |
|
22 gDebugger = gPanel.panelWin; |
|
23 gBreakpoints = gDebugger.DebuggerController.Breakpoints; |
|
24 gSources = gDebugger.DebuggerView.Sources; |
|
25 gVariables = gDebugger.DebuggerView.Variables; |
|
26 |
|
27 // Always expand all items between pauses. |
|
28 gVariables.commitHierarchyIgnoredItems = Object.create(null); |
|
29 |
|
30 waitForSourceShown(gPanel, ".html") |
|
31 .then(addBreakpoint) |
|
32 .then(() => ensureThreadClientState(gPanel, "resumed")) |
|
33 .then(pauseDebuggee) |
|
34 .then(prepareVariablesAndProperties) |
|
35 .then(stepInDebuggee) |
|
36 .then(testVariablesExpand) |
|
37 .then(() => resumeDebuggerThenCloseAndFinish(gPanel)) |
|
38 .then(null, aError => { |
|
39 ok(false, "Got an error: " + aError.message + "\n" + aError.stack); |
|
40 }); |
|
41 }); |
|
42 } |
|
43 |
|
44 function addBreakpoint() { |
|
45 return gBreakpoints.addBreakpoint({ url: gSources.selectedValue, line: 21 }); |
|
46 } |
|
47 |
|
48 function pauseDebuggee() { |
|
49 // Spin the event loop before causing the debuggee to pause, to allow |
|
50 // this function to return first. |
|
51 executeSoon(() => { |
|
52 EventUtils.sendMouseEvent({ type: "click" }, |
|
53 gDebuggee.document.querySelector("button"), |
|
54 gDebuggee); |
|
55 }); |
|
56 |
|
57 // The first 'with' scope should be expanded by default, but the |
|
58 // variables haven't been fetched yet. This is how 'with' scopes work. |
|
59 return promise.all([ |
|
60 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES), |
|
61 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES) |
|
62 ]); |
|
63 } |
|
64 |
|
65 function stepInDebuggee() { |
|
66 // Spin the event loop before causing the debuggee to pause, to allow |
|
67 // this function to return first. |
|
68 executeSoon(() => { |
|
69 EventUtils.sendMouseEvent({ type: "mousedown" }, |
|
70 gDebugger.document.querySelector("#step-in"), |
|
71 gDebugger); |
|
72 }); |
|
73 |
|
74 return promise.all([ |
|
75 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES, 1), |
|
76 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 3), |
|
77 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 4), |
|
78 ]); |
|
79 } |
|
80 |
|
81 function testVariablesExpand() { |
|
82 let localScope = gVariables.getScopeAtIndex(0); |
|
83 let withScope = gVariables.getScopeAtIndex(1); |
|
84 let functionScope = gVariables.getScopeAtIndex(2); |
|
85 let globalScope = gVariables.getScopeAtIndex(3); |
|
86 |
|
87 let thisVar = localScope.get("this"); |
|
88 let windowVar = thisVar.get("window"); |
|
89 let documentVar = windowVar.get("document"); |
|
90 let locationVar = documentVar.get("location"); |
|
91 |
|
92 is(localScope.target.querySelector(".arrow").hasAttribute("open"), true, |
|
93 "The localScope arrow should still be expanded."); |
|
94 is(withScope.target.querySelector(".arrow").hasAttribute("open"), true, |
|
95 "The withScope arrow should still be expanded."); |
|
96 is(functionScope.target.querySelector(".arrow").hasAttribute("open"), true, |
|
97 "The functionScope arrow should still be expanded."); |
|
98 is(globalScope.target.querySelector(".arrow").hasAttribute("open"), true, |
|
99 "The globalScope arrow should still be expanded."); |
|
100 is(thisVar.target.querySelector(".arrow").hasAttribute("open"), true, |
|
101 "The thisVar arrow should still be expanded."); |
|
102 is(windowVar.target.querySelector(".arrow").hasAttribute("open"), true, |
|
103 "The windowVar arrow should still be expanded."); |
|
104 is(documentVar.target.querySelector(".arrow").hasAttribute("open"), true, |
|
105 "The documentVar arrow should still be expanded."); |
|
106 is(locationVar.target.querySelector(".arrow").hasAttribute("open"), true, |
|
107 "The locationVar arrow should still be expanded."); |
|
108 |
|
109 is(localScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true, |
|
110 "The localScope enumerables should still be expanded."); |
|
111 is(withScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true, |
|
112 "The withScope enumerables should still be expanded."); |
|
113 is(functionScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true, |
|
114 "The functionScope enumerables should still be expanded."); |
|
115 is(globalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true, |
|
116 "The globalScope enumerables should still be expanded."); |
|
117 is(thisVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true, |
|
118 "The thisVar enumerables should still be expanded."); |
|
119 is(windowVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true, |
|
120 "The windowVar enumerables should still be expanded."); |
|
121 is(documentVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true, |
|
122 "The documentVar enumerables should still be expanded."); |
|
123 is(locationVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true, |
|
124 "The locationVar enumerables should still be expanded."); |
|
125 |
|
126 is(localScope.expanded, true, |
|
127 "The localScope expanded getter should return true."); |
|
128 is(withScope.expanded, true, |
|
129 "The withScope expanded getter should return true."); |
|
130 is(functionScope.expanded, true, |
|
131 "The functionScope expanded getter should return true."); |
|
132 is(globalScope.expanded, true, |
|
133 "The globalScope expanded getter should return true."); |
|
134 is(thisVar.expanded, true, |
|
135 "The thisVar expanded getter should return true."); |
|
136 is(windowVar.expanded, true, |
|
137 "The windowVar expanded getter should return true."); |
|
138 is(documentVar.expanded, true, |
|
139 "The documentVar expanded getter should return true."); |
|
140 is(locationVar.expanded, true, |
|
141 "The locationVar expanded getter should return true."); |
|
142 } |
|
143 |
|
144 function prepareVariablesAndProperties() { |
|
145 let deferred = promise.defer(); |
|
146 |
|
147 let localScope = gVariables.getScopeAtIndex(0); |
|
148 let withScope = gVariables.getScopeAtIndex(1); |
|
149 let functionScope = gVariables.getScopeAtIndex(2); |
|
150 let globalScope = gVariables.getScopeAtIndex(3); |
|
151 |
|
152 is(localScope.expanded, true, |
|
153 "The localScope should be expanded."); |
|
154 is(withScope.expanded, false, |
|
155 "The withScope should not be expanded yet."); |
|
156 is(functionScope.expanded, false, |
|
157 "The functionScope should not be expanded yet."); |
|
158 is(globalScope.expanded, false, |
|
159 "The globalScope should not be expanded yet."); |
|
160 |
|
161 // Wait for only two events to be triggered, because the Function scope is |
|
162 // an environment to which scope arguments and variables are already attached. |
|
163 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => { |
|
164 is(localScope.expanded, true, |
|
165 "The localScope should now be expanded."); |
|
166 is(withScope.expanded, true, |
|
167 "The withScope should now be expanded."); |
|
168 is(functionScope.expanded, true, |
|
169 "The functionScope should now be expanded."); |
|
170 is(globalScope.expanded, true, |
|
171 "The globalScope should now be expanded."); |
|
172 |
|
173 let thisVar = localScope.get("this"); |
|
174 |
|
175 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => { |
|
176 let windowVar = thisVar.get("window"); |
|
177 |
|
178 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => { |
|
179 let documentVar = windowVar.get("document"); |
|
180 |
|
181 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => { |
|
182 let locationVar = documentVar.get("location"); |
|
183 |
|
184 waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => { |
|
185 is(thisVar.expanded, true, |
|
186 "The local scope 'this' should be expanded."); |
|
187 is(windowVar.expanded, true, |
|
188 "The local scope 'this.window' should be expanded."); |
|
189 is(documentVar.expanded, true, |
|
190 "The local scope 'this.window.document' should be expanded."); |
|
191 is(locationVar.expanded, true, |
|
192 "The local scope 'this.window.document.location' should be expanded."); |
|
193 |
|
194 deferred.resolve(); |
|
195 }); |
|
196 |
|
197 locationVar.expand(); |
|
198 }); |
|
199 |
|
200 documentVar.expand(); |
|
201 }); |
|
202 |
|
203 windowVar.expand(); |
|
204 }); |
|
205 |
|
206 thisVar.expand(); |
|
207 }); |
|
208 |
|
209 withScope.expand(); |
|
210 functionScope.expand(); |
|
211 globalScope.expand(); |
|
212 |
|
213 return deferred.promise; |
|
214 } |
|
215 |
|
216 registerCleanupFunction(function() { |
|
217 gTab = null; |
|
218 gDebuggee = null; |
|
219 gPanel = null; |
|
220 gDebugger = null; |
|
221 gBreakpoints = null; |
|
222 gSources = null; |
|
223 gVariables = null; |
|
224 }); |