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