diff options
Diffstat (limited to 'browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js')
-rw-r--r-- | browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js b/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js new file mode 100644 index 000000000..642ffd50c --- /dev/null +++ b/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js @@ -0,0 +1,308 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Bug 723069: test the debugger breakpoint API and connection to the source + * editor. + */ + +const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html"; + +let gPane = null; +let gTab = null; +let gDebuggee = null; +let gDebugger = null; +let gEditor = null; +let gSources = null; +let gBreakpoints = null; + +function test() +{ + let scriptShown = false; + let framesAdded = false; + let resumed = false; + let testStarted = false; + + debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) { + gTab = aTab; + gDebuggee = aDebuggee; + gPane = aPane; + gDebugger = gPane.panelWin; + resumed = true; + + gDebugger.addEventListener("Debugger:SourceShown", onSourceShown); + + gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() { + framesAdded = true; + executeSoon(startTest); + }); + + executeSoon(function() { + gDebuggee.firstCall(); + }); + }); + + function onSourceShown(aEvent) + { + scriptShown = aEvent.detail.url.indexOf("-02.js") != -1; + executeSoon(startTest); + } + + function startTest() + { + if (scriptShown && framesAdded && !testStarted) { + gDebugger.removeEventListener("Debugger:SourceShown", onSourceShown); + testStarted = true; + Services.tm.currentThread.dispatch({ run: performTest }, 0); + } + } + + function performTest() + { + gSources = gDebugger.DebuggerView.Sources; + gEditor = gDebugger.editor; + gBreakpoints = gPane.getAllBreakpoints(); + + is(gDebugger.DebuggerController.activeThread.state, "paused", + "Should only be getting stack frames while paused."); + + is(gSources.itemCount, 2, + "Found the expected number of scripts."); + + isnot(gEditor.getText().indexOf("debugger"), -1, + "The correct script was loaded initially."); + + isnot(gSources.selectedValue, gSources.values[0], + "The correct script is selected"); + + is(Object.keys(gBreakpoints), 0, "no breakpoints"); + ok(!gPane.getBreakpoint("foo", 3), "getBreakpoint('foo', 3) returns falsey"); + is(gEditor.getBreakpoints().length, 0, "no breakpoints in the editor"); + + gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddFirst); + executeSoon(function() { + gPane.addBreakpoint({url: gSources.selectedValue, line: 6}, onBreakpointAddFirst); + }); + } + + let breakpointsAdded = 0; + let breakpointsRemoved = 0; + let editorBreakpointChanges = 0; + + function onEditorBreakpointAddFirst(aEvent) + { + gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddFirst); + editorBreakpointChanges++; + + ok(aEvent, "breakpoint1 added to the editor"); + is(aEvent.added.length, 1, "one breakpoint added to the editor"); + is(aEvent.removed.length, 0, "no breakpoint was removed from the editor"); + is(aEvent.added[0].line, 5, "editor breakpoint line is correct"); + + is(gEditor.getBreakpoints().length, 1, + "editor.getBreakpoints().length is correct"); + } + + function onBreakpointAddFirst(aBreakpointClient, aResponseError) + { + breakpointsAdded++; + + ok(aBreakpointClient, "breakpoint1 added, client received"); + ok(!aResponseError, "breakpoint1 added without errors"); + is(aBreakpointClient.location.url, gSources.selectedValue, + "breakpoint1 client url is correct"); + is(aBreakpointClient.location.line, 6, + "breakpoint1 client line is correct"); + + executeSoon(function() { + ok(aBreakpointClient.actor in gBreakpoints, + "breakpoint1 client found in the list of debugger breakpoints"); + is(Object.keys(gBreakpoints).length, 1, + "the list of debugger breakpoints holds only one breakpoint"); + is(gPane.getBreakpoint(gSources.selectedValue, 6), aBreakpointClient, + "getBreakpoint returns the correct breakpoint"); + + info("remove the first breakpoint"); + gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveFirst); + gPane.removeBreakpoint(aBreakpointClient, onBreakpointRemoveFirst); + }); + } + + function onBreakpointRemoveFirst(aLocation) + { + breakpointsRemoved++; + + ok(aLocation, "breakpoint1 removed"); + is(aLocation.url, gSources.selectedValue, "breakpoint1 remove: url is correct"); + is(aLocation.line, 6, "breakpoint1 remove: line is correct"); + + executeSoon(testBreakpointAddBackground); + } + + function onEditorBreakpointRemoveFirst(aEvent) + { + gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveFirst); + editorBreakpointChanges++; + + ok(aEvent, "breakpoint1 removed from the editor"); + is(aEvent.added.length, 0, "no breakpoint was added to the editor"); + is(aEvent.removed.length, 1, "one breakpoint was removed from the editor"); + is(aEvent.removed[0].line, 5, "editor breakpoint line is correct"); + + is(gEditor.getBreakpoints().length, 0, + "editor.getBreakpoints().length is correct"); + } + + function testBreakpointAddBackground() + { + info("add a breakpoint to the second script which is not selected"); + + is(Object.keys(gBreakpoints).length, 0, + "no breakpoints in the debugger"); + ok(!gPane.getBreakpoint(gSources.selectedValue, 6), + "getBreakpoint(selectedScript, 6) returns no breakpoint"); + isnot(gSources.values[0], gSources.selectedValue, + "first script location is not the currently selected script"); + + gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap); + gPane.addBreakpoint({url: gSources.values[0], line: 5}, onBreakpointAddBackground); + } + + function onEditorBreakpointAddBackgroundTrap(aEvent) + { + // Trap listener: no breakpoint must be added to the editor when a + // breakpoint is added to a script that is not currently selected. + gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap); + editorBreakpointChanges++; + ok(false, "breakpoint2 must not be added to the editor"); + } + + function onBreakpointAddBackground(aBreakpointClient, aResponseError) + { + breakpointsAdded++; + + ok(aBreakpointClient, "breakpoint2 added, client received"); + ok(!aResponseError, "breakpoint2 added without errors"); + is(aBreakpointClient.location.url, gSources.values[0], + "breakpoint2 client url is correct"); + is(aBreakpointClient.location.line, 5, + "breakpoint2 client line is correct"); + + executeSoon(function() { + ok(aBreakpointClient.actor in gBreakpoints, + "breakpoint2 client found in the list of debugger breakpoints"); + + is(Object.keys(gBreakpoints).length, 1, + "one breakpoint in the debugger"); + is(gPane.getBreakpoint(gSources.values[0], 5), aBreakpointClient, + "getBreakpoint(locations[0], 5) returns the correct breakpoint"); + + // remove the trap listener + gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddBackgroundTrap); + + info("switch to the second script"); + gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddSwitch); + gEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onEditorTextChanged); + gSources.selectedIndex = 0; + }); + } + + function onEditorBreakpointAddSwitch(aEvent) + { + gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointAddSwitch); + editorBreakpointChanges++; + + ok(aEvent, "breakpoint2 added to the editor"); + is(aEvent.added.length, 1, "one breakpoint added to the editor"); + is(aEvent.removed.length, 0, "no breakpoint was removed from the editor"); + is(aEvent.added[0].line, 4, "editor breakpoint line is correct"); + + is(gEditor.getBreakpoints().length, 1, + "editor.getBreakpoints().length is correct"); + } + + function onEditorTextChanged() + { + // Wait for the actual text to be shown. + if (gDebugger.editor.getText() == gDebugger.L10N.getStr("loadingText")) { + return; + } + // The requested source text has been shown, remove the event listener. + gEditor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onEditorTextChanged); + + is(gEditor.getText().indexOf("debugger"), -1, + "The second script is no longer displayed."); + + isnot(gEditor.getText().indexOf("firstCall"), -1, + "The first script is displayed."); + + let window = gEditor.editorElement.contentWindow; + executeSoon(() => window.mozRequestAnimationFrame(onReadyForClick)); + } + + function onReadyForClick() + { + info("remove the second breakpoint using the mouse"); + gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveSecond); + + let iframe = gEditor.editorElement; + let testWin = iframe.ownerDocument.defaultView; + + // flush the layout for the iframe + info("rect " + iframe.contentDocument.documentElement.getBoundingClientRect()); + + let utils = testWin.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + + let lineOffset = gEditor.getLineStart(4); + let coords = gEditor.getLocationAtOffset(lineOffset); + + let rect = iframe.getBoundingClientRect(); + let left = rect.left + 10; + let top = rect.top + coords.y + 4; + utils.sendMouseEventToWindow("mousedown", left, top, 0, 1, 0, false, 0, 0); + utils.sendMouseEventToWindow("mouseup", left, top, 0, 1, 0, false, 0, 0); + } + + function onEditorBreakpointRemoveSecond(aEvent) + { + gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE, onEditorBreakpointRemoveSecond); + editorBreakpointChanges++; + + ok(aEvent, "breakpoint2 removed from the editor"); + is(aEvent.added.length, 0, "no breakpoint was added to the editor"); + is(aEvent.removed.length, 1, "one breakpoint was removed from the editor"); + is(aEvent.removed[0].line, 4, "editor breakpoint line is correct"); + + is(gEditor.getBreakpoints().length, 0, + "editor.getBreakpoints().length is correct"); + + executeSoon(function() { + gDebugger.gClient.addOneTimeListener("resumed", function() { + finalCheck(); + closeDebuggerAndFinish(); + }); + gDebugger.DebuggerController.activeThread.resume(); + }); + } + + function finalCheck() { + is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger"); + ok(!gPane.getBreakpoint(gSources.values[0], 5), + "getBreakpoint(locations[0], 5) returns no breakpoint"); + } + + registerCleanupFunction(function() { + removeTab(gTab); + is(breakpointsAdded, 2, "correct number of breakpoints have been added"); + is(breakpointsRemoved, 1, "correct number of breakpoints have been removed"); + is(editorBreakpointChanges, 4, "correct number of editor breakpoint changes"); + gPane = null; + gTab = null; + gDebuggee = null; + gDebugger = null; + gEditor = null; + gSources = null; + gBreakpoints = null; + }); +} |