|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 /** |
|
5 * Test that we get the expected frame enter/exit logs in the tracer view. |
|
6 */ |
|
7 |
|
8 const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html"; |
|
9 |
|
10 let gTab, gDebuggee, gPanel, gDebugger; |
|
11 |
|
12 function test() { |
|
13 SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => { |
|
14 initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { |
|
15 gTab = aTab; |
|
16 gDebuggee = aDebuggee; |
|
17 gPanel = aPanel; |
|
18 gDebugger = gPanel.panelWin; |
|
19 |
|
20 waitForSourceShown(gPanel, "code_tracing-01.js") |
|
21 .then(() => startTracing(gPanel)) |
|
22 .then(clickButton) |
|
23 .then(() => waitForClientEvents(aPanel, "traces")) |
|
24 .then(testTraceLogs) |
|
25 .then(() => stopTracing(gPanel)) |
|
26 .then(() => { |
|
27 const deferred = promise.defer(); |
|
28 SpecialPowers.popPrefEnv(deferred.resolve); |
|
29 return deferred.promise; |
|
30 }) |
|
31 .then(() => closeDebuggerAndFinish(gPanel)) |
|
32 .then(null, aError => { |
|
33 ok(false, "Got an error: " + aError.message + "\n" + aError.stack); |
|
34 }); |
|
35 }); |
|
36 }); |
|
37 } |
|
38 |
|
39 function clickButton() { |
|
40 EventUtils.sendMouseEvent({ type: "click" }, |
|
41 gDebuggee.document.querySelector("button"), |
|
42 gDebuggee); |
|
43 } |
|
44 |
|
45 function testTraceLogs() { |
|
46 const onclickLogs = filterTraces(gPanel, |
|
47 t => t.querySelector(".trace-name[value=onclick]")); |
|
48 is(onclickLogs.length, 2, "Should have two logs from 'onclick'"); |
|
49 ok(onclickLogs[0].querySelector(".trace-call"), |
|
50 "The first 'onclick' log should be a call."); |
|
51 ok(onclickLogs[1].querySelector(".trace-return"), |
|
52 "The second 'onclick' log should be a return."); |
|
53 for (let t of onclickLogs) { |
|
54 ok(t.querySelector(".trace-item").getAttribute("tooltiptext") |
|
55 .contains("doc_tracing-01.html")); |
|
56 } |
|
57 |
|
58 const nonOnclickLogs = filterTraces(gPanel, |
|
59 t => !t.querySelector(".trace-name[value=onclick]")); |
|
60 for (let t of nonOnclickLogs) { |
|
61 ok(t.querySelector(".trace-item").getAttribute("tooltiptext") |
|
62 .contains("code_tracing-01.js")); |
|
63 } |
|
64 |
|
65 const mainLogs = filterTraces(gPanel, |
|
66 t => t.querySelector(".trace-name[value=main]")); |
|
67 is(mainLogs.length, 2, "Should have an enter and an exit for 'main'"); |
|
68 ok(mainLogs[0].querySelector(".trace-call"), |
|
69 "The first 'main' log should be a call."); |
|
70 ok(mainLogs[1].querySelector(".trace-return"), |
|
71 "The second 'main' log should be a return."); |
|
72 |
|
73 const factorialLogs = filterTraces(gPanel, |
|
74 t => t.querySelector(".trace-name[value=factorial]")); |
|
75 is(factorialLogs.length, 10, "Should have 5 enter, and 5 exit frames for 'factorial'"); |
|
76 ok(factorialLogs.slice(0, 5).every(t => t.querySelector(".trace-call")), |
|
77 "The first five 'factorial' logs should be calls."); |
|
78 ok(factorialLogs.slice(5).every(t => t.querySelector(".trace-return")), |
|
79 "The second five 'factorial' logs should be returns.") |
|
80 |
|
81 // Test that the depth affects padding so that calls are indented properly. |
|
82 let lastDepth = -Infinity; |
|
83 for (let t of factorialLogs.slice(0, 5)) { |
|
84 let depth = parseInt(t.querySelector(".trace-item").style.MozPaddingStart, 10); |
|
85 ok(depth > lastDepth, "The depth should be increasing"); |
|
86 lastDepth = depth; |
|
87 } |
|
88 lastDepth = Infinity; |
|
89 for (let t of factorialLogs.slice(5)) { |
|
90 let depth = parseInt(t.querySelector(".trace-item").style.MozPaddingStart, 10); |
|
91 ok(depth < lastDepth, "The depth should be decreasing"); |
|
92 lastDepth = depth; |
|
93 } |
|
94 |
|
95 const throwerLogs = filterTraces(gPanel, |
|
96 t => t.querySelector(".trace-name[value=thrower]")); |
|
97 is(throwerLogs.length, 2, "Should have an enter and an exit for 'thrower'"); |
|
98 ok(throwerLogs[0].querySelector(".trace-call"), |
|
99 "The first 'thrower' log should be a call."); |
|
100 ok(throwerLogs[1].querySelector(".trace-throw", |
|
101 "The second 'thrower' log should be a throw.")); |
|
102 } |
|
103 |
|
104 registerCleanupFunction(function() { |
|
105 gTab = null; |
|
106 gDebuggee = null; |
|
107 gPanel = null; |
|
108 gDebugger = null; |
|
109 }); |