summaryrefslogtreecommitdiff
path: root/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
diff options
context:
space:
mode:
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.js308
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;
+ });
+}