diff -r 000000000000 -r 6474c204b198 browser/devtools/debugger/test/browser_dbg_tracing-01.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browser/devtools/debugger/test/browser_dbg_tracing-01.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,109 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test that we get the expected frame enter/exit logs in the tracer view. + */ + +const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html"; + +let gTab, gDebuggee, gPanel, gDebugger; + +function test() { + SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => { + initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => { + gTab = aTab; + gDebuggee = aDebuggee; + gPanel = aPanel; + gDebugger = gPanel.panelWin; + + waitForSourceShown(gPanel, "code_tracing-01.js") + .then(() => startTracing(gPanel)) + .then(clickButton) + .then(() => waitForClientEvents(aPanel, "traces")) + .then(testTraceLogs) + .then(() => stopTracing(gPanel)) + .then(() => { + const deferred = promise.defer(); + SpecialPowers.popPrefEnv(deferred.resolve); + return deferred.promise; + }) + .then(() => closeDebuggerAndFinish(gPanel)) + .then(null, aError => { + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); + }); + }); + }); +} + +function clickButton() { + EventUtils.sendMouseEvent({ type: "click" }, + gDebuggee.document.querySelector("button"), + gDebuggee); +} + +function testTraceLogs() { + const onclickLogs = filterTraces(gPanel, + t => t.querySelector(".trace-name[value=onclick]")); + is(onclickLogs.length, 2, "Should have two logs from 'onclick'"); + ok(onclickLogs[0].querySelector(".trace-call"), + "The first 'onclick' log should be a call."); + ok(onclickLogs[1].querySelector(".trace-return"), + "The second 'onclick' log should be a return."); + for (let t of onclickLogs) { + ok(t.querySelector(".trace-item").getAttribute("tooltiptext") + .contains("doc_tracing-01.html")); + } + + const nonOnclickLogs = filterTraces(gPanel, + t => !t.querySelector(".trace-name[value=onclick]")); + for (let t of nonOnclickLogs) { + ok(t.querySelector(".trace-item").getAttribute("tooltiptext") + .contains("code_tracing-01.js")); + } + + const mainLogs = filterTraces(gPanel, + t => t.querySelector(".trace-name[value=main]")); + is(mainLogs.length, 2, "Should have an enter and an exit for 'main'"); + ok(mainLogs[0].querySelector(".trace-call"), + "The first 'main' log should be a call."); + ok(mainLogs[1].querySelector(".trace-return"), + "The second 'main' log should be a return."); + + const factorialLogs = filterTraces(gPanel, + t => t.querySelector(".trace-name[value=factorial]")); + is(factorialLogs.length, 10, "Should have 5 enter, and 5 exit frames for 'factorial'"); + ok(factorialLogs.slice(0, 5).every(t => t.querySelector(".trace-call")), + "The first five 'factorial' logs should be calls."); + ok(factorialLogs.slice(5).every(t => t.querySelector(".trace-return")), + "The second five 'factorial' logs should be returns.") + + // Test that the depth affects padding so that calls are indented properly. + let lastDepth = -Infinity; + for (let t of factorialLogs.slice(0, 5)) { + let depth = parseInt(t.querySelector(".trace-item").style.MozPaddingStart, 10); + ok(depth > lastDepth, "The depth should be increasing"); + lastDepth = depth; + } + lastDepth = Infinity; + for (let t of factorialLogs.slice(5)) { + let depth = parseInt(t.querySelector(".trace-item").style.MozPaddingStart, 10); + ok(depth < lastDepth, "The depth should be decreasing"); + lastDepth = depth; + } + + const throwerLogs = filterTraces(gPanel, + t => t.querySelector(".trace-name[value=thrower]")); + is(throwerLogs.length, 2, "Should have an enter and an exit for 'thrower'"); + ok(throwerLogs[0].querySelector(".trace-call"), + "The first 'thrower' log should be a call."); + ok(throwerLogs[1].querySelector(".trace-throw", + "The second 'thrower' log should be a throw.")); +} + +registerCleanupFunction(function() { + gTab = null; + gDebuggee = null; + gPanel = null; + gDebugger = null; +});