|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 /** |
|
5 * Tests if the function searching works properly. |
|
6 */ |
|
7 |
|
8 const TAB_URL = EXAMPLE_URL + "doc_function-search.html"; |
|
9 |
|
10 let gTab, gDebuggee, gPanel, gDebugger; |
|
11 let gEditor, gSources, gSearchBox, gFilteredFunctions; |
|
12 |
|
13 function test() { |
|
14 initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { |
|
15 gTab = aTab; |
|
16 gDebuggee = aDebuggee; |
|
17 gPanel = aPanel; |
|
18 gDebugger = gPanel.panelWin; |
|
19 gEditor = gDebugger.DebuggerView.editor; |
|
20 gSources = gDebugger.DebuggerView.Sources; |
|
21 gSearchBox = gDebugger.DebuggerView.Filtering._searchbox; |
|
22 gFilteredFunctions = gDebugger.DebuggerView.FilteredFunctions; |
|
23 |
|
24 waitForSourceShown(gPanel, "-01.js") |
|
25 .then(() => showSource("doc_function-search.html")) |
|
26 .then(htmlSearch) |
|
27 .then(() => showSource("code_function-search-01.js")) |
|
28 .then(firstJsSearch) |
|
29 .then(() => showSource("code_function-search-02.js")) |
|
30 .then(secondJsSearch) |
|
31 .then(() => showSource("code_function-search-03.js")) |
|
32 .then(thirdJsSearch) |
|
33 .then(saveSearch) |
|
34 .then(filterSearch) |
|
35 .then(bogusSearch) |
|
36 .then(incrementalSearch) |
|
37 .then(emptySearch) |
|
38 .then(() => closeDebuggerAndFinish(gPanel)) |
|
39 .then(null, aError => { |
|
40 ok(false, "Got an error: " + aError.message + "\n" + aError.stack); |
|
41 }); |
|
42 }); |
|
43 } |
|
44 |
|
45 function htmlSearch() { |
|
46 let deferred = promise.defer(); |
|
47 |
|
48 once(gDebugger, "popupshown").then(() => { |
|
49 writeInfo(); |
|
50 |
|
51 is(gFilteredFunctions.selectedIndex, 0, |
|
52 "An item should be selected in the filtered functions view (1)."); |
|
53 ok(gFilteredFunctions.selectedItem, |
|
54 "An item should be selected in the filtered functions view (2)."); |
|
55 |
|
56 if (gSources.selectedValue.indexOf(".html") != -1) { |
|
57 let expectedResults = [ |
|
58 ["inline", ".html", "", 19, 16], |
|
59 ["arrow", ".html", "", 20, 11], |
|
60 ["foo", ".html", "", 22, 11], |
|
61 ["foo2", ".html", "", 23, 11], |
|
62 ["bar2", ".html", "", 23, 18] |
|
63 ]; |
|
64 |
|
65 for (let [label, value, description, line, column] of expectedResults) { |
|
66 let target = gFilteredFunctions.selectedItem.target; |
|
67 |
|
68 if (label) { |
|
69 is(target.querySelector(".results-panel-item-label").getAttribute("value"), |
|
70 gDebugger.SourceUtils.trimUrlLength(label + "()"), |
|
71 "The corect label (" + label + ") is currently selected."); |
|
72 } else { |
|
73 ok(!target.querySelector(".results-panel-item-label"), |
|
74 "Shouldn't create empty label nodes."); |
|
75 } |
|
76 if (value) { |
|
77 ok(target.querySelector(".results-panel-item-label-below").getAttribute("value").contains(value), |
|
78 "The corect value (" + value + ") is attached."); |
|
79 } else { |
|
80 ok(!target.querySelector(".results-panel-item-label-below"), |
|
81 "Shouldn't create empty label nodes."); |
|
82 } |
|
83 if (description) { |
|
84 is(target.querySelector(".results-panel-item-label-before").getAttribute("value"), description, |
|
85 "The corect description (" + description + ") is currently shown."); |
|
86 } else { |
|
87 ok(!target.querySelector(".results-panel-item-label-before"), |
|
88 "Shouldn't create empty label nodes."); |
|
89 } |
|
90 |
|
91 ok(isCaretPos(gPanel, line, column), |
|
92 "The editor didn't jump to the correct line."); |
|
93 |
|
94 EventUtils.sendKey("DOWN", gDebugger); |
|
95 } |
|
96 |
|
97 ok(isCaretPos(gPanel, expectedResults[0][3], expectedResults[0][4]), |
|
98 "The editor didn't jump to the correct line again."); |
|
99 |
|
100 deferred.resolve(); |
|
101 } else { |
|
102 ok(false, "How did you get here? Go away, you."); |
|
103 } |
|
104 }); |
|
105 |
|
106 setText(gSearchBox, "@"); |
|
107 return deferred.promise; |
|
108 } |
|
109 |
|
110 function firstJsSearch() { |
|
111 let deferred = promise.defer(); |
|
112 |
|
113 once(gDebugger, "popupshown").then(() => { |
|
114 writeInfo(); |
|
115 |
|
116 is(gFilteredFunctions.selectedIndex, 0, |
|
117 "An item should be selected in the filtered functions view (1)."); |
|
118 ok(gFilteredFunctions.selectedItem, |
|
119 "An item should be selected in the filtered functions view (2)."); |
|
120 |
|
121 if (gSources.selectedValue.indexOf("-01.js") != -1) { |
|
122 let s = " " + gDebugger.L10N.getStr("functionSearchSeparatorLabel") + " "; |
|
123 let expectedResults = [ |
|
124 ["test", "-01.js", "", 4, 10], |
|
125 ["anonymousExpression", "-01.js", "test.prototype", 9, 3], |
|
126 ["namedExpression" + s + "NAME", "-01.js", "test.prototype", 11, 3], |
|
127 ["a_test", "-01.js", "foo", 22, 3], |
|
128 ["n_test" + s + "x", "-01.js", "foo", 24, 3], |
|
129 ["a_test", "-01.js", "foo.sub", 27, 5], |
|
130 ["n_test" + s + "y", "-01.js", "foo.sub", 29, 5], |
|
131 ["a_test", "-01.js", "foo.sub.sub", 32, 7], |
|
132 ["n_test" + s + "z", "-01.js", "foo.sub.sub", 34, 7], |
|
133 ["test_SAME_NAME", "-01.js", "foo.sub.sub.sub", 37, 9] |
|
134 ]; |
|
135 |
|
136 for (let [label, value, description, line, column] of expectedResults) { |
|
137 let target = gFilteredFunctions.selectedItem.target; |
|
138 |
|
139 if (label) { |
|
140 is(target.querySelector(".results-panel-item-label").getAttribute("value"), |
|
141 gDebugger.SourceUtils.trimUrlLength(label + "()"), |
|
142 "The corect label (" + label + ") is currently selected."); |
|
143 } else { |
|
144 ok(!target.querySelector(".results-panel-item-label"), |
|
145 "Shouldn't create empty label nodes."); |
|
146 } |
|
147 if (value) { |
|
148 ok(target.querySelector(".results-panel-item-label-below").getAttribute("value").contains(value), |
|
149 "The corect value (" + value + ") is attached."); |
|
150 } else { |
|
151 ok(!target.querySelector(".results-panel-item-label-below"), |
|
152 "Shouldn't create empty label nodes."); |
|
153 } |
|
154 if (description) { |
|
155 is(target.querySelector(".results-panel-item-label-before").getAttribute("value"), description, |
|
156 "The corect description (" + description + ") is currently shown."); |
|
157 } else { |
|
158 ok(!target.querySelector(".results-panel-item-label-before"), |
|
159 "Shouldn't create empty label nodes."); |
|
160 } |
|
161 |
|
162 ok(isCaretPos(gPanel, line, column), |
|
163 "The editor didn't jump to the correct line."); |
|
164 |
|
165 EventUtils.sendKey("DOWN", gDebugger); |
|
166 } |
|
167 |
|
168 ok(isCaretPos(gPanel, expectedResults[0][3], expectedResults[0][4]), |
|
169 "The editor didn't jump to the correct line again."); |
|
170 |
|
171 deferred.resolve() |
|
172 } else { |
|
173 ok(false, "How did you get here? Go away, you."); |
|
174 } |
|
175 }); |
|
176 |
|
177 setText(gSearchBox, "@"); |
|
178 return deferred.promise; |
|
179 } |
|
180 |
|
181 function secondJsSearch() { |
|
182 let deferred = promise.defer(); |
|
183 |
|
184 once(gDebugger, "popupshown").then(() => { |
|
185 writeInfo(); |
|
186 |
|
187 is(gFilteredFunctions.selectedIndex, 0, |
|
188 "An item should be selected in the filtered functions view (1)."); |
|
189 ok(gFilteredFunctions.selectedItem, |
|
190 "An item should be selected in the filtered functions view (2)."); |
|
191 |
|
192 if (gSources.selectedValue.indexOf("-02.js") != -1) { |
|
193 let s = " " + gDebugger.L10N.getStr("functionSearchSeparatorLabel") + " "; |
|
194 let expectedResults = [ |
|
195 ["test2", "-02.js", "", 4, 5], |
|
196 ["test3" + s + "test3_NAME", "-02.js", "", 8, 5], |
|
197 ["test4_SAME_NAME", "-02.js", "", 11, 5], |
|
198 ["x" + s + "X", "-02.js", "test.prototype", 14, 1], |
|
199 ["y" + s + "Y", "-02.js", "test.prototype.sub", 16, 1], |
|
200 ["z" + s + "Z", "-02.js", "test.prototype.sub.sub", 18, 1], |
|
201 ["t", "-02.js", "test.prototype.sub.sub.sub", 20, 1], |
|
202 ["x", "-02.js", "this", 20, 32], |
|
203 ["y", "-02.js", "this", 20, 41], |
|
204 ["z", "-02.js", "this", 20, 50] |
|
205 ]; |
|
206 |
|
207 for (let [label, value, description, line, column] of expectedResults) { |
|
208 let target = gFilteredFunctions.selectedItem.target; |
|
209 |
|
210 if (label) { |
|
211 is(target.querySelector(".results-panel-item-label").getAttribute("value"), |
|
212 gDebugger.SourceUtils.trimUrlLength(label + "()"), |
|
213 "The corect label (" + label + ") is currently selected."); |
|
214 } else { |
|
215 ok(!target.querySelector(".results-panel-item-label"), |
|
216 "Shouldn't create empty label nodes."); |
|
217 } |
|
218 if (value) { |
|
219 ok(target.querySelector(".results-panel-item-label-below").getAttribute("value").contains(value), |
|
220 "The corect value (" + value + ") is attached."); |
|
221 } else { |
|
222 ok(!target.querySelector(".results-panel-item-label-below"), |
|
223 "Shouldn't create empty label nodes."); |
|
224 } |
|
225 if (description) { |
|
226 is(target.querySelector(".results-panel-item-label-before").getAttribute("value"), description, |
|
227 "The corect description (" + description + ") is currently shown."); |
|
228 } else { |
|
229 ok(!target.querySelector(".results-panel-item-label-before"), |
|
230 "Shouldn't create empty label nodes."); |
|
231 } |
|
232 |
|
233 ok(isCaretPos(gPanel, line, column), |
|
234 "The editor didn't jump to the correct line."); |
|
235 |
|
236 EventUtils.sendKey("DOWN", gDebugger); |
|
237 } |
|
238 |
|
239 ok(isCaretPos(gPanel, expectedResults[0][3], expectedResults[0][4]), |
|
240 "The editor didn't jump to the correct line again."); |
|
241 |
|
242 deferred.resolve(); |
|
243 } else { |
|
244 ok(false, "How did you get here? Go away, you."); |
|
245 } |
|
246 }); |
|
247 |
|
248 setText(gSearchBox, "@"); |
|
249 return deferred.promise; |
|
250 } |
|
251 |
|
252 function thirdJsSearch() { |
|
253 let deferred = promise.defer(); |
|
254 |
|
255 once(gDebugger, "popupshown").then(() => { |
|
256 writeInfo(); |
|
257 |
|
258 is(gFilteredFunctions.selectedIndex, 0, |
|
259 "An item should be selected in the filtered functions view (1)."); |
|
260 ok(gFilteredFunctions.selectedItem, |
|
261 "An item should be selected in the filtered functions view (2)."); |
|
262 |
|
263 if (gSources.selectedValue.indexOf("-03.js") != -1) { |
|
264 let s = " " + gDebugger.L10N.getStr("functionSearchSeparatorLabel") + " "; |
|
265 let expectedResults = [ |
|
266 ["namedEventListener", "-03.js", "", 4, 43], |
|
267 ["a" + s + "A", "-03.js", "bar", 10, 5], |
|
268 ["b" + s + "B", "-03.js", "bar.alpha", 15, 5], |
|
269 ["c" + s + "C", "-03.js", "bar.alpha.beta", 20, 5], |
|
270 ["d" + s + "D", "-03.js", "this.theta", 25, 5], |
|
271 ["fun", "-03.js", "", 29, 7], |
|
272 ["foo", "-03.js", "", 29, 13], |
|
273 ["bar", "-03.js", "", 29, 19], |
|
274 ["t_foo", "-03.js", "this", 29, 25], |
|
275 ["w_bar" + s + "baz", "-03.js", "window", 29, 38] |
|
276 ]; |
|
277 |
|
278 for (let [label, value, description, line, column] of expectedResults) { |
|
279 let target = gFilteredFunctions.selectedItem.target; |
|
280 |
|
281 if (label) { |
|
282 is(target.querySelector(".results-panel-item-label").getAttribute("value"), |
|
283 gDebugger.SourceUtils.trimUrlLength(label + "()"), |
|
284 "The corect label (" + label + ") is currently selected."); |
|
285 } else { |
|
286 ok(!target.querySelector(".results-panel-item-label"), |
|
287 "Shouldn't create empty label nodes."); |
|
288 } |
|
289 if (value) { |
|
290 ok(target.querySelector(".results-panel-item-label-below").getAttribute("value").contains(value), |
|
291 "The corect value (" + value + ") is attached."); |
|
292 } else { |
|
293 ok(!target.querySelector(".results-panel-item-label-below"), |
|
294 "Shouldn't create empty label nodes."); |
|
295 } |
|
296 if (description) { |
|
297 is(target.querySelector(".results-panel-item-label-before").getAttribute("value"), description, |
|
298 "The corect description (" + description + ") is currently shown."); |
|
299 } else { |
|
300 ok(!target.querySelector(".results-panel-item-label-before"), |
|
301 "Shouldn't create empty label nodes."); |
|
302 } |
|
303 |
|
304 ok(isCaretPos(gPanel, line, column), |
|
305 "The editor didn't jump to the correct line."); |
|
306 |
|
307 EventUtils.sendKey("DOWN", gDebugger); |
|
308 } |
|
309 |
|
310 ok(isCaretPos(gPanel, expectedResults[0][3], expectedResults[0][4]), |
|
311 "The editor didn't jump to the correct line again."); |
|
312 |
|
313 deferred.resolve(); |
|
314 } else { |
|
315 ok(false, "How did you get here? Go away, you."); |
|
316 } |
|
317 }); |
|
318 |
|
319 setText(gSearchBox, "@"); |
|
320 return deferred.promise; |
|
321 } |
|
322 |
|
323 function filterSearch() { |
|
324 let deferred = promise.defer(); |
|
325 |
|
326 once(gDebugger, "popupshown").then(() => { |
|
327 writeInfo(); |
|
328 |
|
329 is(gFilteredFunctions.selectedIndex, 0, |
|
330 "An item should be selected in the filtered functions view (1)."); |
|
331 ok(gFilteredFunctions.selectedItem, |
|
332 "An item should be selected in the filtered functions view (2)."); |
|
333 |
|
334 if (gSources.selectedValue.indexOf("-03.js") != -1) { |
|
335 let s = " " + gDebugger.L10N.getStr("functionSearchSeparatorLabel") + " "; |
|
336 let expectedResults = [ |
|
337 ["namedEventListener", "-03.js", "", 4, 43], |
|
338 ["bar", "-03.js", "", 29, 19], |
|
339 ["w_bar" + s + "baz", "-03.js", "window", 29, 38], |
|
340 ["anonymousExpression", "-01.js", "test.prototype", 9, 3], |
|
341 ["namedExpression" + s + "NAME", "-01.js", "test.prototype", 11, 3], |
|
342 ["arrow", ".html", "", 20, 11], |
|
343 ["bar2", ".html", "", 23, 18] |
|
344 ]; |
|
345 |
|
346 for (let [label, value, description, line, column] of expectedResults) { |
|
347 let target = gFilteredFunctions.selectedItem.target; |
|
348 |
|
349 if (label) { |
|
350 is(target.querySelector(".results-panel-item-label").getAttribute("value"), |
|
351 gDebugger.SourceUtils.trimUrlLength(label + "()"), |
|
352 "The corect label (" + label + ") is currently selected."); |
|
353 } else { |
|
354 ok(!target.querySelector(".results-panel-item-label"), |
|
355 "Shouldn't create empty label nodes."); |
|
356 } |
|
357 if (value) { |
|
358 ok(target.querySelector(".results-panel-item-label-below").getAttribute("value").contains(value), |
|
359 "The corect value (" + value + ") is attached."); |
|
360 } else { |
|
361 ok(!target.querySelector(".results-panel-item-label-below"), |
|
362 "Shouldn't create empty label nodes."); |
|
363 } |
|
364 if (description) { |
|
365 is(target.querySelector(".results-panel-item-label-before").getAttribute("value"), description, |
|
366 "The corect description (" + description + ") is currently shown."); |
|
367 } else { |
|
368 ok(!target.querySelector(".results-panel-item-label-before"), |
|
369 "Shouldn't create empty label nodes."); |
|
370 } |
|
371 |
|
372 ok(isCaretPos(gPanel, line, column), |
|
373 "The editor didn't jump to the correct line."); |
|
374 |
|
375 EventUtils.sendKey("DOWN", gDebugger); |
|
376 } |
|
377 |
|
378 ok(isCaretPos(gPanel, expectedResults[0][3], expectedResults[0][4]), |
|
379 "The editor didn't jump to the correct line again."); |
|
380 |
|
381 deferred.resolve(); |
|
382 } else { |
|
383 ok(false, "How did you get here? Go away, you."); |
|
384 } |
|
385 }); |
|
386 |
|
387 setText(gSearchBox, "@r"); |
|
388 return deferred.promise; |
|
389 } |
|
390 |
|
391 function bogusSearch() { |
|
392 let deferred = promise.defer(); |
|
393 |
|
394 once(gDebugger, "popuphidden").then(() => { |
|
395 ok(true, "Popup was successfully hidden after no matches were found."); |
|
396 deferred.resolve(); |
|
397 }); |
|
398 |
|
399 setText(gSearchBox, "@bogus"); |
|
400 return deferred.promise; |
|
401 } |
|
402 |
|
403 function incrementalSearch() { |
|
404 let deferred = promise.defer(); |
|
405 |
|
406 once(gDebugger, "popupshown").then(() => { |
|
407 ok(true, "Popup was successfully shown after some matches were found."); |
|
408 deferred.resolve(); |
|
409 }); |
|
410 |
|
411 setText(gSearchBox, "@NAME"); |
|
412 return deferred.promise; |
|
413 } |
|
414 |
|
415 function emptySearch() { |
|
416 let deferred = promise.defer(); |
|
417 |
|
418 once(gDebugger, "popuphidden").then(() => { |
|
419 ok(true, "Popup was successfully hidden when nothing was searched."); |
|
420 deferred.resolve(); |
|
421 }); |
|
422 |
|
423 clearText(gSearchBox); |
|
424 return deferred.promise; |
|
425 } |
|
426 |
|
427 function showSource(aLabel) { |
|
428 let deferred = promise.defer(); |
|
429 |
|
430 waitForSourceShown(gPanel, aLabel).then(deferred.resolve); |
|
431 gSources.selectedItem = e => e.attachment.label == aLabel; |
|
432 |
|
433 return deferred.promise; |
|
434 } |
|
435 |
|
436 function saveSearch() { |
|
437 let finished = once(gDebugger, "popuphidden"); |
|
438 |
|
439 // Either by pressing RETURN or clicking on an item in the popup, |
|
440 // the popup should hide and the item should become selected. |
|
441 let random = Math.random(); |
|
442 if (random >= 0.33) { |
|
443 EventUtils.sendKey("RETURN", gDebugger); |
|
444 } else if (random >= 0.66) { |
|
445 EventUtils.sendKey("RETURN", gDebugger); |
|
446 } else { |
|
447 EventUtils.sendMouseEvent({ type: "click" }, |
|
448 gFilteredFunctions.selectedItem.target, |
|
449 gDebugger); |
|
450 } |
|
451 |
|
452 return finished; |
|
453 } |
|
454 |
|
455 function writeInfo() { |
|
456 info("Current source url:\n" + gSources.selectedValue); |
|
457 info("Debugger editor text:\n" + gEditor.getText()); |
|
458 } |
|
459 |
|
460 registerCleanupFunction(function() { |
|
461 gTab = null; |
|
462 gDebuggee = null; |
|
463 gPanel = null; |
|
464 gDebugger = null; |
|
465 gEditor = null; |
|
466 gSources = null; |
|
467 gSearchBox = null; |
|
468 gFilteredFunctions = null; |
|
469 }); |