/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /** * Make sure that pausing on exceptions works. */ const TAB_URL = EXAMPLE_URL + "doc_pause-exceptions.html"; var gTab, gPanel, gDebugger; var gFrames, gVariables, gPrefs, gOptions; function test() { requestLongerTimeout(2); let options = { source: TAB_URL, line: 1 }; initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => { gTab = aTab; gPanel = aPanel; gDebugger = gPanel.panelWin; gFrames = gDebugger.DebuggerView.StackFrames; gVariables = gDebugger.DebuggerView.Variables; gPrefs = gDebugger.Prefs; gOptions = gDebugger.DebuggerView.Options; is(gPrefs.pauseOnExceptions, false, "The pause-on-exceptions pref should be disabled by default."); isnot(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true", "The pause-on-exceptions menu item should not be checked."); testPauseOnExceptionsDisabled() .then(enablePauseOnExceptions) .then(disableIgnoreCaughtExceptions) .then(testPauseOnExceptionsEnabled) .then(disablePauseOnExceptions) .then(enableIgnoreCaughtExceptions) .then(() => closeDebuggerAndFinish(gPanel)) .then(null, aError => { ok(false, "Got an error: " + aError.message + "\n" + aError.stack); }); }); } function testPauseOnExceptionsDisabled() { let finished = waitForCaretAndScopes(gPanel, 26).then(() => { info("Testing disabled pause-on-exceptions."); is(gDebugger.gThreadClient.state, "paused", "Should only be getting stack frames while paused (1)."); ok(isCaretPos(gPanel, 26), "Should be paused on the debugger statement (1)."); let innerScope = gVariables.getScopeAtIndex(0); let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes; is(gFrames.itemCount, 1, "Should have one frame."); is(gVariables._store.length, 4, "Should have four scopes."); is(innerNodes[0].querySelector(".name").getAttribute("value"), "this", "Should have the right property name for 'this'."); is(innerNodes[0].querySelector(".value").getAttribute("value"), "<button>", "Should have the right property value for 'this'."); let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => { isnot(gDebugger.gThreadClient.state, "paused", "Should not be paused after resuming."); ok(isCaretPos(gPanel, 26), "Should be idle on the debugger statement."); ok(true, "Frames were cleared, debugger didn't pause again."); }); EventUtils.sendMouseEvent({ type: "mousedown" }, gDebugger.document.getElementById("resume"), gDebugger); return finished; }); generateMouseClickInTab(gTab, "content.document.querySelector('button')"); return finished; } function testPauseOnExceptionsEnabled() { let finished = waitForCaretAndScopes(gPanel, 19).then(() => { info("Testing enabled pause-on-exceptions."); is(gDebugger.gThreadClient.state, "paused", "Should only be getting stack frames while paused."); ok(isCaretPos(gPanel, 19), "Should be paused on the debugger statement."); let innerScope = gVariables.getScopeAtIndex(0); let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes; is(gFrames.itemCount, 1, "Should have one frame."); is(gVariables._store.length, 4, "Should have four scopes."); is(innerNodes[0].querySelector(".name").getAttribute("value"), "<exception>", "Should have the right property name for <exception>."); is(innerNodes[0].querySelector(".value").getAttribute("value"), "Error", "Should have the right property value for <exception>."); let finished = waitForCaretAndScopes(gPanel, 26).then(() => { info("Testing enabled pause-on-exceptions and resumed after pause."); is(gDebugger.gThreadClient.state, "paused", "Should only be getting stack frames while paused."); ok(isCaretPos(gPanel, 26), "Should be paused on the debugger statement."); let innerScope = gVariables.getScopeAtIndex(0); let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes; is(gFrames.itemCount, 1, "Should have one frame."); is(gVariables._store.length, 4, "Should have four scopes."); is(innerNodes[0].querySelector(".name").getAttribute("value"), "this", "Should have the right property name for 'this'."); is(innerNodes[0].querySelector(".value").getAttribute("value"), "<button>", "Should have the right property value for 'this'."); let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => { isnot(gDebugger.gThreadClient.state, "paused", "Should not be paused after resuming."); ok(isCaretPos(gPanel, 26), "Should be idle on the debugger statement."); ok(true, "Frames were cleared, debugger didn't pause again."); }); EventUtils.sendMouseEvent({ type: "mousedown" }, gDebugger.document.getElementById("resume"), gDebugger); return finished; }); EventUtils.sendMouseEvent({ type: "mousedown" }, gDebugger.document.getElementById("resume"), gDebugger); return finished; }); generateMouseClickInTab(gTab, "content.document.querySelector('button')"); return finished; } function enablePauseOnExceptions() { let deferred = promise.defer(); gDebugger.gThreadClient.addOneTimeListener("resumed", () => { is(gPrefs.pauseOnExceptions, true, "The pause-on-exceptions pref should now be enabled."); is(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true", "The pause-on-exceptions menu item should now be checked."); ok(true, "Pausing on exceptions was enabled."); deferred.resolve(); }); gOptions._pauseOnExceptionsItem.setAttribute("checked", "true"); gOptions._togglePauseOnExceptions(); return deferred.promise; } function disablePauseOnExceptions() { let deferred = promise.defer(); gDebugger.gThreadClient.addOneTimeListener("resumed", () => { is(gPrefs.pauseOnExceptions, false, "The pause-on-exceptions pref should now be disabled."); isnot(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true", "The pause-on-exceptions menu item should now be unchecked."); ok(true, "Pausing on exceptions was disabled."); deferred.resolve(); }); gOptions._pauseOnExceptionsItem.setAttribute("checked", "false"); gOptions._togglePauseOnExceptions(); return deferred.promise; } function enableIgnoreCaughtExceptions() { let deferred = promise.defer(); gDebugger.gThreadClient.addOneTimeListener("resumed", () => { is(gPrefs.ignoreCaughtExceptions, true, "The ignore-caught-exceptions pref should now be enabled."); is(gOptions._ignoreCaughtExceptionsItem.getAttribute("checked"), "true", "The ignore-caught-exceptions menu item should now be checked."); ok(true, "Ignore caught exceptions was enabled."); deferred.resolve(); }); gOptions._ignoreCaughtExceptionsItem.setAttribute("checked", "true"); gOptions._toggleIgnoreCaughtExceptions(); return deferred.promise; } function disableIgnoreCaughtExceptions() { let deferred = promise.defer(); gDebugger.gThreadClient.addOneTimeListener("resumed", () => { is(gPrefs.ignoreCaughtExceptions, false, "The ignore-caught-exceptions pref should now be disabled."); isnot(gOptions._ignoreCaughtExceptionsItem.getAttribute("checked"), "true", "The ignore-caught-exceptions menu item should now be unchecked."); ok(true, "Ignore caught exceptions was disabled."); deferred.resolve(); }); gOptions._ignoreCaughtExceptionsItem.setAttribute("checked", "false"); gOptions._toggleIgnoreCaughtExceptions(); return deferred.promise; } registerCleanupFunction(function () { gTab = null; gPanel = null; gDebugger = null; gFrames = null; gVariables = null; gPrefs = null; gOptions = null; });