|
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 is keyboard accessible. |
|
6 */ |
|
7 |
|
8 let gTab, gDebuggee, gPanel, gDebugger; |
|
9 let gVariablesView; |
|
10 |
|
11 function test() { |
|
12 initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => { |
|
13 gTab = aTab; |
|
14 gDebuggee = aDebuggee; |
|
15 gPanel = aPanel; |
|
16 gDebugger = gPanel.panelWin; |
|
17 gVariablesView = gDebugger.DebuggerView.Variables; |
|
18 |
|
19 performTest().then(null, aError => { |
|
20 ok(false, "Got an error: " + aError.message + "\n" + aError.stack); |
|
21 }); |
|
22 }); |
|
23 } |
|
24 |
|
25 function performTest() { |
|
26 let arr = [ |
|
27 42, |
|
28 true, |
|
29 "nasu", |
|
30 undefined, |
|
31 null, |
|
32 [0, 1, 2], |
|
33 { prop1: 9, prop2: 8 } |
|
34 ]; |
|
35 |
|
36 let obj = { |
|
37 p0: 42, |
|
38 p1: true, |
|
39 p2: "nasu", |
|
40 p3: undefined, |
|
41 p4: null, |
|
42 p5: [3, 4, 5], |
|
43 p6: { prop1: 7, prop2: 6 }, |
|
44 get p7() { return arr; }, |
|
45 set p8(value) { arr[0] = value } |
|
46 }; |
|
47 |
|
48 let test = { |
|
49 someProp0: 42, |
|
50 someProp1: true, |
|
51 someProp2: "nasu", |
|
52 someProp3: undefined, |
|
53 someProp4: null, |
|
54 someProp5: arr, |
|
55 someProp6: obj, |
|
56 get someProp7() { return arr; }, |
|
57 set someProp7(value) { arr[0] = value } |
|
58 }; |
|
59 |
|
60 gVariablesView.eval = function() {}; |
|
61 gVariablesView.switch = function() {}; |
|
62 gVariablesView.delete = function() {}; |
|
63 gVariablesView.rawObject = test; |
|
64 gVariablesView.scrollPageSize = 5; |
|
65 |
|
66 return Task.spawn(function() { |
|
67 yield waitForTick(); |
|
68 |
|
69 // Part 0: Test generic focus methods on the variables view. |
|
70 |
|
71 gVariablesView.focusFirstVisibleItem(); |
|
72 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
73 "The 'someProp0' item should be focused."); |
|
74 |
|
75 gVariablesView.focusNextItem(); |
|
76 is(gVariablesView.getFocusedItem().name, "someProp1", |
|
77 "The 'someProp1' item should be focused."); |
|
78 |
|
79 gVariablesView.focusPrevItem(); |
|
80 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
81 "The 'someProp0' item should be focused."); |
|
82 |
|
83 // Part 1: Make sure that UP/DOWN keys don't scroll the variables view. |
|
84 |
|
85 yield synthesizeKeyAndWaitForTick("VK_DOWN", {}); |
|
86 is(gVariablesView._parent.scrollTop, 0, |
|
87 "The 'variables' view shouldn't scroll when pressing the DOWN key."); |
|
88 |
|
89 yield synthesizeKeyAndWaitForTick("VK_UP", {}); |
|
90 is(gVariablesView._parent.scrollTop, 0, |
|
91 "The 'variables' view shouldn't scroll when pressing the UP key."); |
|
92 |
|
93 // Part 2: Make sure that RETURN/ESCAPE toggle input elements. |
|
94 |
|
95 yield synthesizeKeyAndWaitForElement("VK_RETURN", {}, ".element-value-input", true); |
|
96 yield synthesizeKeyAndWaitForElement("VK_ESCAPE", {}, ".element-value-input", false); |
|
97 yield synthesizeKeyAndWaitForElement("VK_RETURN", { shiftKey: true }, ".element-name-input", true); |
|
98 yield synthesizeKeyAndWaitForElement("VK_ESCAPE", {}, ".element-name-input", false); |
|
99 |
|
100 // Part 3: Test simple navigation. |
|
101 |
|
102 EventUtils.sendKey("DOWN", gDebugger); |
|
103 is(gVariablesView.getFocusedItem().name, "someProp1", |
|
104 "The 'someProp1' item should be focused."); |
|
105 |
|
106 EventUtils.sendKey("UP", gDebugger); |
|
107 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
108 "The 'someProp0' item should be focused."); |
|
109 |
|
110 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
111 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
112 "The 'someProp5' item should be focused."); |
|
113 |
|
114 EventUtils.sendKey("PAGE_UP", gDebugger); |
|
115 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
116 "The 'someProp0' item should be focused."); |
|
117 |
|
118 EventUtils.sendKey("END", gDebugger); |
|
119 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
120 "The '__proto__' item should be focused."); |
|
121 |
|
122 EventUtils.sendKey("HOME", gDebugger); |
|
123 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
124 "The 'someProp0' item should be focused."); |
|
125 |
|
126 // Part 4: Test if pressing the same navigation key twice works as expected. |
|
127 |
|
128 EventUtils.sendKey("DOWN", gDebugger); |
|
129 is(gVariablesView.getFocusedItem().name, "someProp1", |
|
130 "The 'someProp1' item should be focused."); |
|
131 |
|
132 EventUtils.sendKey("DOWN", gDebugger); |
|
133 is(gVariablesView.getFocusedItem().name, "someProp2", |
|
134 "The 'someProp2' item should be focused."); |
|
135 |
|
136 EventUtils.sendKey("UP", gDebugger); |
|
137 is(gVariablesView.getFocusedItem().name, "someProp1", |
|
138 "The 'someProp1' item should be focused."); |
|
139 |
|
140 EventUtils.sendKey("UP", gDebugger); |
|
141 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
142 "The 'someProp0' item should be focused."); |
|
143 |
|
144 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
145 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
146 "The 'someProp5' item should be focused."); |
|
147 |
|
148 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
149 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
150 "The '__proto__' item should be focused."); |
|
151 |
|
152 EventUtils.sendKey("PAGE_UP", gDebugger); |
|
153 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
154 "The 'someProp5' item should be focused."); |
|
155 |
|
156 EventUtils.sendKey("PAGE_UP", gDebugger); |
|
157 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
158 "The 'someProp0' item should be focused."); |
|
159 |
|
160 // Part 5: Test that HOME/PAGE_UP/PAGE_DOWN are symmetrical. |
|
161 |
|
162 EventUtils.sendKey("HOME", gDebugger); |
|
163 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
164 "The 'someProp0' item should be focused."); |
|
165 |
|
166 EventUtils.sendKey("HOME", gDebugger); |
|
167 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
168 "The 'someProp0' item should be focused."); |
|
169 |
|
170 EventUtils.sendKey("PAGE_UP", gDebugger); |
|
171 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
172 "The 'someProp0' item should be focused."); |
|
173 |
|
174 EventUtils.sendKey("HOME", gDebugger); |
|
175 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
176 "The 'someProp0' item should be focused."); |
|
177 |
|
178 EventUtils.sendKey("END", gDebugger); |
|
179 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
180 "The '__proto__' item should be focused."); |
|
181 |
|
182 EventUtils.sendKey("END", gDebugger); |
|
183 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
184 "The '__proto__' item should be focused."); |
|
185 |
|
186 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
187 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
188 "The '__proto__' item should be focused."); |
|
189 |
|
190 EventUtils.sendKey("END", gDebugger); |
|
191 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
192 "The '__proto__' item should be focused."); |
|
193 |
|
194 // Part 6: Test that focus doesn't leave the variables view. |
|
195 |
|
196 EventUtils.sendKey("PAGE_UP", gDebugger); |
|
197 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
198 "The 'someProp5' item should be focused."); |
|
199 |
|
200 EventUtils.sendKey("PAGE_UP", gDebugger); |
|
201 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
202 "The 'someProp0' item should be focused."); |
|
203 |
|
204 EventUtils.sendKey("UP", gDebugger); |
|
205 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
206 "The 'someProp0' item should be focused."); |
|
207 |
|
208 EventUtils.sendKey("UP", gDebugger); |
|
209 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
210 "The 'someProp0' item should be focused."); |
|
211 |
|
212 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
213 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
214 "The 'someProp5' item should be focused."); |
|
215 |
|
216 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
217 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
218 "The '__proto__' item should be focused."); |
|
219 |
|
220 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
221 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
222 "The '__proto__' item should be focused."); |
|
223 |
|
224 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
225 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
226 "The '__proto__' item should be focused."); |
|
227 |
|
228 // Part 7: Test that random offsets don't occur in tandem with HOME/END. |
|
229 |
|
230 EventUtils.sendKey("HOME", gDebugger); |
|
231 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
232 "The 'someProp0' item should be focused."); |
|
233 |
|
234 EventUtils.sendKey("DOWN", gDebugger); |
|
235 is(gVariablesView.getFocusedItem().name, "someProp1", |
|
236 "The 'someProp1' item should be focused."); |
|
237 |
|
238 EventUtils.sendKey("END", gDebugger); |
|
239 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
240 "The '__proto__' item should be focused."); |
|
241 |
|
242 EventUtils.sendKey("DOWN", gDebugger); |
|
243 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
244 "The '__proto__' item should be focused."); |
|
245 |
|
246 // Part 8: Test that the RIGHT key expands elements as intended. |
|
247 |
|
248 EventUtils.sendKey("PAGE_UP", gDebugger); |
|
249 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
250 "The 'someProp5' item should be focused."); |
|
251 is(gVariablesView.getFocusedItem().expanded, false, |
|
252 "The 'someProp5' item should not be expanded yet."); |
|
253 |
|
254 yield synthesizeKeyAndWaitForTick("VK_RIGHT", {}); |
|
255 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
256 "The 'someProp5' item should be focused."); |
|
257 is(gVariablesView.getFocusedItem().expanded, true, |
|
258 "The 'someProp5' item should now be expanded."); |
|
259 is(gVariablesView.getFocusedItem()._store.size, 9, |
|
260 "There should be 9 properties in the selected variable."); |
|
261 is(gVariablesView.getFocusedItem()._enumItems.length, 7, |
|
262 "There should be 7 enumerable properties in the selected variable."); |
|
263 is(gVariablesView.getFocusedItem()._nonEnumItems.length, 2, |
|
264 "There should be 2 non-enumerable properties in the selected variable."); |
|
265 |
|
266 yield waitForChildNodes(gVariablesView.getFocusedItem()._enum, 7); |
|
267 yield waitForChildNodes(gVariablesView.getFocusedItem()._nonenum, 2); |
|
268 |
|
269 EventUtils.sendKey("RIGHT", gDebugger); |
|
270 is(gVariablesView.getFocusedItem().name, "0", |
|
271 "The '0' item should be focused."); |
|
272 |
|
273 EventUtils.sendKey("RIGHT", gDebugger); |
|
274 is(gVariablesView.getFocusedItem().name, "0", |
|
275 "The '0' item should still be focused."); |
|
276 |
|
277 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
278 is(gVariablesView.getFocusedItem().name, "5", |
|
279 "The '5' item should be focused."); |
|
280 is(gVariablesView.getFocusedItem().expanded, false, |
|
281 "The '5' item should not be expanded yet."); |
|
282 |
|
283 yield synthesizeKeyAndWaitForTick("VK_RIGHT", {}); |
|
284 is(gVariablesView.getFocusedItem().name, "5", |
|
285 "The '5' item should be focused."); |
|
286 is(gVariablesView.getFocusedItem().expanded, true, |
|
287 "The '5' item should now be expanded."); |
|
288 is(gVariablesView.getFocusedItem()._store.size, 5, |
|
289 "There should be 5 properties in the selected variable."); |
|
290 is(gVariablesView.getFocusedItem()._enumItems.length, 3, |
|
291 "There should be 3 enumerable properties in the selected variable."); |
|
292 is(gVariablesView.getFocusedItem()._nonEnumItems.length, 2, |
|
293 "There should be 2 non-enumerable properties in the selected variable."); |
|
294 |
|
295 yield waitForChildNodes(gVariablesView.getFocusedItem()._enum, 3); |
|
296 yield waitForChildNodes(gVariablesView.getFocusedItem()._nonenum, 2); |
|
297 |
|
298 EventUtils.sendKey("RIGHT", gDebugger); |
|
299 is(gVariablesView.getFocusedItem().name, "0", |
|
300 "The '0' item should be focused."); |
|
301 |
|
302 EventUtils.sendKey("RIGHT", gDebugger); |
|
303 is(gVariablesView.getFocusedItem().name, "0", |
|
304 "The '0' item should still be focused."); |
|
305 |
|
306 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
307 is(gVariablesView.getFocusedItem().name, "6", |
|
308 "The '6' item should be focused."); |
|
309 is(gVariablesView.getFocusedItem().expanded, false, |
|
310 "The '6' item should not be expanded yet."); |
|
311 |
|
312 yield synthesizeKeyAndWaitForTick("VK_RIGHT", {}); |
|
313 is(gVariablesView.getFocusedItem().name, "6", |
|
314 "The '6' item should be focused."); |
|
315 is(gVariablesView.getFocusedItem().expanded, true, |
|
316 "The '6' item should now be expanded."); |
|
317 is(gVariablesView.getFocusedItem()._store.size, 3, |
|
318 "There should be 3 properties in the selected variable."); |
|
319 is(gVariablesView.getFocusedItem()._enumItems.length, 2, |
|
320 "There should be 2 enumerable properties in the selected variable."); |
|
321 is(gVariablesView.getFocusedItem()._nonEnumItems.length, 1, |
|
322 "There should be 1 non-enumerable properties in the selected variable."); |
|
323 |
|
324 yield waitForChildNodes(gVariablesView.getFocusedItem()._enum, 2); |
|
325 yield waitForChildNodes(gVariablesView.getFocusedItem()._nonenum, 1); |
|
326 |
|
327 EventUtils.sendKey("RIGHT", gDebugger); |
|
328 is(gVariablesView.getFocusedItem().name, "prop1", |
|
329 "The 'prop1' item should be focused."); |
|
330 |
|
331 EventUtils.sendKey("RIGHT", gDebugger); |
|
332 is(gVariablesView.getFocusedItem().name, "prop1", |
|
333 "The 'prop1' item should still be focused."); |
|
334 |
|
335 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
336 is(gVariablesView.getFocusedItem().name, "someProp6", |
|
337 "The 'someProp6' item should be focused."); |
|
338 is(gVariablesView.getFocusedItem().expanded, false, |
|
339 "The 'someProp6' item should not be expanded yet."); |
|
340 |
|
341 // Part 9: Test that the RIGHT key collapses elements as intended. |
|
342 |
|
343 EventUtils.sendKey("LEFT", gDebugger); |
|
344 is(gVariablesView.getFocusedItem().name, "someProp6", |
|
345 "The 'someProp6' item should be focused."); |
|
346 |
|
347 EventUtils.sendKey("UP", gDebugger); |
|
348 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
349 "The '__proto__' item should be focused."); |
|
350 |
|
351 EventUtils.sendKey("LEFT", gDebugger); |
|
352 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
353 "The 'someProp5' item should be focused."); |
|
354 is(gVariablesView.getFocusedItem().expanded, true, |
|
355 "The '6' item should still be expanded."); |
|
356 |
|
357 EventUtils.sendKey("LEFT", gDebugger); |
|
358 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
359 "The 'someProp5' item should still be focused."); |
|
360 is(gVariablesView.getFocusedItem().expanded, false, |
|
361 "The '6' item should still not be expanded anymore."); |
|
362 |
|
363 EventUtils.sendKey("LEFT", gDebugger); |
|
364 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
365 "The 'someProp5' item should still be focused."); |
|
366 |
|
367 // Part 9: Test continuous navigation. |
|
368 |
|
369 EventUtils.sendKey("UP", gDebugger); |
|
370 is(gVariablesView.getFocusedItem().name, "someProp4", |
|
371 "The 'someProp4' item should be focused."); |
|
372 |
|
373 EventUtils.sendKey("UP", gDebugger); |
|
374 is(gVariablesView.getFocusedItem().name, "someProp3", |
|
375 "The 'someProp3' item should be focused."); |
|
376 |
|
377 EventUtils.sendKey("UP", gDebugger); |
|
378 is(gVariablesView.getFocusedItem().name, "someProp2", |
|
379 "The 'someProp2' item should be focused."); |
|
380 |
|
381 EventUtils.sendKey("UP", gDebugger); |
|
382 is(gVariablesView.getFocusedItem().name, "someProp1", |
|
383 "The 'someProp1' item should be focused."); |
|
384 |
|
385 EventUtils.sendKey("UP", gDebugger); |
|
386 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
387 "The 'someProp0' item should be focused."); |
|
388 |
|
389 EventUtils.sendKey("PAGE_UP", gDebugger); |
|
390 is(gVariablesView.getFocusedItem().name, "someProp0", |
|
391 "The 'someProp0' item should be focused."); |
|
392 |
|
393 EventUtils.sendKey("PAGE_DOWN", gDebugger); |
|
394 is(gVariablesView.getFocusedItem().name, "someProp5", |
|
395 "The 'someProp5' item should be focused."); |
|
396 |
|
397 EventUtils.sendKey("DOWN", gDebugger); |
|
398 is(gVariablesView.getFocusedItem().name, "someProp6", |
|
399 "The 'someProp6' item should be focused."); |
|
400 |
|
401 EventUtils.sendKey("DOWN", gDebugger); |
|
402 is(gVariablesView.getFocusedItem().name, "someProp7", |
|
403 "The 'someProp7' item should be focused."); |
|
404 |
|
405 EventUtils.sendKey("DOWN", gDebugger); |
|
406 is(gVariablesView.getFocusedItem().name, "get", |
|
407 "The 'get' item should be focused."); |
|
408 |
|
409 EventUtils.sendKey("DOWN", gDebugger); |
|
410 is(gVariablesView.getFocusedItem().name, "set", |
|
411 "The 'set' item should be focused."); |
|
412 |
|
413 EventUtils.sendKey("DOWN", gDebugger); |
|
414 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
415 "The '__proto__' item should be focused."); |
|
416 |
|
417 // Part 10: Test that BACKSPACE deletes items in the variables view. |
|
418 |
|
419 EventUtils.sendKey("BACK_SPACE", gDebugger); |
|
420 is(gVariablesView.getFocusedItem().name, "__proto__", |
|
421 "The '__proto__' variable should still be focused."); |
|
422 is(gVariablesView.getFocusedItem().value, "[object Object]", |
|
423 "The '__proto__' variable should not have an empty value."); |
|
424 is(gVariablesView.getFocusedItem().visible, false, |
|
425 "The '__proto__' variable should be hidden."); |
|
426 |
|
427 EventUtils.sendKey("UP", gDebugger); |
|
428 is(gVariablesView.getFocusedItem().name, "set", |
|
429 "The 'set' item should be focused."); |
|
430 is(gVariablesView.getFocusedItem().value, "[object Object]", |
|
431 "The 'set' item should not have an empty value."); |
|
432 is(gVariablesView.getFocusedItem().visible, true, |
|
433 "The 'set' item should be visible."); |
|
434 |
|
435 EventUtils.sendKey("BACK_SPACE", gDebugger); |
|
436 is(gVariablesView.getFocusedItem().name, "set", |
|
437 "The 'set' item should still be focused."); |
|
438 is(gVariablesView.getFocusedItem().value, "[object Object]", |
|
439 "The 'set' item should not have an empty value."); |
|
440 is(gVariablesView.getFocusedItem().visible, true, |
|
441 "The 'set' item should be visible."); |
|
442 is(gVariablesView.getFocusedItem().twisty, false, |
|
443 "The 'set' item should be disabled and have a hidden twisty."); |
|
444 |
|
445 EventUtils.sendKey("UP", gDebugger); |
|
446 is(gVariablesView.getFocusedItem().name, "get", |
|
447 "The 'get' item should be focused."); |
|
448 is(gVariablesView.getFocusedItem().value, "[object Object]", |
|
449 "The 'get' item should not have an empty value."); |
|
450 is(gVariablesView.getFocusedItem().visible, true, |
|
451 "The 'get' item should be visible."); |
|
452 |
|
453 EventUtils.sendKey("BACK_SPACE", gDebugger); |
|
454 is(gVariablesView.getFocusedItem().name, "get", |
|
455 "The 'get' item should still be focused."); |
|
456 is(gVariablesView.getFocusedItem().value, "[object Object]", |
|
457 "The 'get' item should not have an empty value."); |
|
458 is(gVariablesView.getFocusedItem().visible, true, |
|
459 "The 'get' item should be visible."); |
|
460 is(gVariablesView.getFocusedItem().twisty, false, |
|
461 "The 'get' item should be disabled and have a hidden twisty."); |
|
462 |
|
463 EventUtils.sendKey("UP", gDebugger); |
|
464 is(gVariablesView.getFocusedItem().name, "someProp7", |
|
465 "The 'someProp7' item should be focused."); |
|
466 is(gVariablesView.getFocusedItem().value, undefined, |
|
467 "The 'someProp7' variable should have an empty value."); |
|
468 is(gVariablesView.getFocusedItem().visible, true, |
|
469 "The 'someProp7' variable should be visible."); |
|
470 |
|
471 EventUtils.sendKey("BACK_SPACE", gDebugger); |
|
472 is(gVariablesView.getFocusedItem().name, "someProp7", |
|
473 "The 'someProp7' variable should still be focused."); |
|
474 is(gVariablesView.getFocusedItem().value, undefined, |
|
475 "The 'someProp7' variable should have an empty value."); |
|
476 is(gVariablesView.getFocusedItem().visible, false, |
|
477 "The 'someProp7' variable should be hidden."); |
|
478 |
|
479 // Part 11: Test that Ctrl-C copies the current item to the system clipboard |
|
480 |
|
481 gVariablesView.focusFirstVisibleItem(); |
|
482 let copied = promise.defer(); |
|
483 let expectedValue = gVariablesView.getFocusedItem().name |
|
484 + gVariablesView.getFocusedItem().separatorStr |
|
485 + gVariablesView.getFocusedItem().value; |
|
486 |
|
487 waitForClipboard(expectedValue, function setup() { |
|
488 EventUtils.synthesizeKey("C", { metaKey: true }, gDebugger); |
|
489 }, copied.resolve, copied.reject |
|
490 ); |
|
491 |
|
492 try { |
|
493 yield copied.promise; |
|
494 ok(true, |
|
495 "Ctrl-C copied the selected item to the clipboard."); |
|
496 } catch (e) { |
|
497 ok(false, |
|
498 "Ctrl-C didn't copy the selected item to the clipboard."); |
|
499 } |
|
500 |
|
501 yield closeDebuggerAndFinish(gPanel); |
|
502 }); |
|
503 } |
|
504 |
|
505 registerCleanupFunction(function() { |
|
506 gTab = null; |
|
507 gDebuggee = null; |
|
508 gPanel = null; |
|
509 gDebugger = null; |
|
510 gVariablesView = null; |
|
511 }); |
|
512 |
|
513 function synthesizeKeyAndWaitForElement(aKey, aModifiers, aSelector, aExistence) { |
|
514 EventUtils.synthesizeKey(aKey, aModifiers, gDebugger); |
|
515 return waitForElement(aSelector, aExistence); |
|
516 } |
|
517 |
|
518 function synthesizeKeyAndWaitForTick(aKey, aModifiers) { |
|
519 EventUtils.synthesizeKey(aKey, aModifiers, gDebugger); |
|
520 return waitForTick(); |
|
521 } |
|
522 |
|
523 function waitForElement(aSelector, aExistence) { |
|
524 return waitForPredicate(() => { |
|
525 return !!gVariablesView._list.querySelector(aSelector) == aExistence; |
|
526 }); |
|
527 } |
|
528 |
|
529 function waitForChildNodes(aTarget, aCount) { |
|
530 return waitForPredicate(() => { |
|
531 return aTarget.childNodes.length == aCount; |
|
532 }); |
|
533 } |
|
534 |
|
535 function waitForPredicate(aPredicate, aInterval = 10) { |
|
536 let deferred = promise.defer(); |
|
537 |
|
538 // Poll every few milliseconds until the element is retrieved. |
|
539 let count = 0; |
|
540 let intervalID = window.setInterval(() => { |
|
541 // Make sure we don't wait for too long. |
|
542 if (++count > 1000) { |
|
543 deferred.reject("Timed out while polling for the element."); |
|
544 window.clearInterval(intervalID); |
|
545 return; |
|
546 } |
|
547 // Check if the predicate condition is fulfilled. |
|
548 if (!aPredicate()) { |
|
549 return; |
|
550 } |
|
551 // We got the element, it's safe to callback. |
|
552 window.clearInterval(intervalID); |
|
553 deferred.resolve(); |
|
554 }, aInterval); |
|
555 |
|
556 return deferred.promise; |
|
557 } |