gecko/browser/devtools/debugger/test/browser_dbg_breakpoints-contextmenu.js

328 lines
13 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test if the context menu associated with each breakpoint does what it should.
*/
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
let gTab, gDebuggee, gPanel, gDebugger;
let gSources, gBreakpoints;
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gSources = gDebugger.DebuggerView.Sources;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
waitForSourceShown(gPanel, "-01.js")
.then(performTestWhileNotPaused)
.then(performTestWhilePaused)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
});
function addBreakpoints() {
return promise.resolve(null)
.then(() => gPanel.addBreakpoint({ url: gSources.values[0], line: 5 }))
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 6 }))
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 7 }))
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 8 }))
.then(() => gPanel.addBreakpoint({ url: gSources.values[1], line: 9 }))
.then(() => ensureThreadClientState(gPanel, "resumed"));
}
function performTestWhileNotPaused() {
info("Performing test while not paused...");
return addBreakpoints()
.then(initialChecks)
.then(() => checkBreakpointToggleSelf(0))
.then(() => checkBreakpointToggleOthers(0))
.then(() => checkBreakpointToggleSelf(1))
.then(() => checkBreakpointToggleOthers(1))
.then(() => checkBreakpointToggleSelf(2))
.then(() => checkBreakpointToggleOthers(2))
.then(() => checkBreakpointToggleSelf(3))
.then(() => checkBreakpointToggleOthers(3))
.then(() => checkBreakpointToggleSelf(4))
.then(() => checkBreakpointToggleOthers(4))
.then(testDeleteAll);
}
function performTestWhilePaused() {
info("Performing test while paused...");
return addBreakpoints()
.then(initialChecks)
.then(pauseAndCheck)
.then(() => checkBreakpointToggleSelf(0))
.then(() => checkBreakpointToggleOthers(0))
.then(() => checkBreakpointToggleSelf(1))
.then(() => checkBreakpointToggleOthers(1))
.then(() => checkBreakpointToggleSelf(2))
.then(() => checkBreakpointToggleOthers(2))
.then(() => checkBreakpointToggleSelf(3))
.then(() => checkBreakpointToggleOthers(3))
.then(() => checkBreakpointToggleSelf(4))
.then(() => checkBreakpointToggleOthers(4))
.then(testDeleteAll);
}
function pauseAndCheck() {
let finished = waitForSourceAndCaretAndScopes(gPanel, "-01.js", 5).then(() => {
is(gSources.selectedValue, EXAMPLE_URL + "code_script-switching-01.js",
"The currently selected source is incorrect (3).");
is(gSources.selectedIndex, 0,
"The currently selected source is incorrect (4).");
ok(isCaretPos(gPanel, 5),
"The editor location is correct after pausing.");
});
is(gSources.selectedValue, EXAMPLE_URL + "code_script-switching-02.js",
"The currently selected source is incorrect (1).");
is(gSources.selectedIndex, 1,
"The currently selected source is incorrect (2).");
ok(isCaretPos(gPanel, 9),
"The editor location is correct before pausing.");
// Spin the event loop before causing the debuggee to pause, to allow
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
return finished;
}
function initialChecks() {
for (let source of gSources) {
for (let breakpoint of source) {
ok(gBreakpoints._getAdded(breakpoint.attachment),
"All breakpoint items should have corresponding promises (1).");
ok(!gBreakpoints._getRemoving(breakpoint.attachment),
"All breakpoint items should have corresponding promises (2).");
ok(breakpoint.attachment.actor,
"All breakpoint items should have corresponding promises (3).");
is(!!breakpoint.attachment.disabled, false,
"All breakpoints should initially be enabled.");
let prefix = "bp-cMenu-"; // "breakpoints context menu"
let identifier = gBreakpoints.getIdentifier(breakpoint.attachment);
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
"The 'Enable breakpoint' context menu item should initially be hidden'.");
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
"The 'Disable breakpoint' context menu item should initially not be hidden'.");
is(breakpoint.attachment.view.checkbox.getAttribute("checked"), "true",
"All breakpoints should initially have a checked checkbox.");
}
}
}
function checkBreakpointToggleSelf(aIndex) {
let deferred = promise.defer();
EventUtils.sendMouseEvent({ type: "click" },
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
gDebugger);
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(gBreakpoints._getAdded(selectedBreakpoint.attachment),
"There should be a breakpoint client available (1).");
ok(!gBreakpoints._getRemoving(selectedBreakpoint.attachment),
"There should be a breakpoint client available (2).");
ok(selectedBreakpoint.attachment.actor,
"There should be a breakpoint client available (3).");
is(!!selectedBreakpoint.attachment.disabled, false,
"The breakpoint should not be disabled yet (" + aIndex + ").");
gBreakpoints._getAdded(selectedBreakpoint.attachment).then(aBreakpointClient => {
ok(aBreakpointClient,
"There should be a breakpoint client available as a promise.");
});
let prefix = "bp-cMenu-"; // "breakpoints context menu"
let identifier = gBreakpoints.getIdentifier(selectedBreakpoint.attachment);
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
"The 'Enable breakpoint' context menu item should be hidden'.");
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
"The 'Disable breakpoint' context menu item should not be hidden'.");
ok(isCaretPos(gPanel, selectedBreakpoint.attachment.line),
"The source editor caret position was incorrect (" + aIndex + ").");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED).then(() => {
ok(!gBreakpoints._getAdded(selectedBreakpoint.attachment),
"There should be no breakpoint client available (4).");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED).then(() => {
ok(gBreakpoints._getAdded(selectedBreakpoint.attachment),
"There should be a breakpoint client available (5).");
deferred.resolve();
});
// Test re-disabling this breakpoint.
gSources._onEnableSelf(selectedBreakpoint.attachment);
is(selectedBreakpoint.attachment.disabled, false,
"The current breakpoint should now be enabled.")
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
"The 'Enable breakpoint' context menu item should be hidden'.");
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
"The 'Disable breakpoint' context menu item should not be hidden'.");
ok(selectedBreakpoint.attachment.view.checkbox.hasAttribute("checked"),
"The breakpoint should now be checked.");
});
// Test disabling this breakpoint.
gSources._onDisableSelf(selectedBreakpoint.attachment);
is(selectedBreakpoint.attachment.disabled, true,
"The current breakpoint should now be disabled.")
ok(!gDebugger.document.getElementById(enableSelfId).hasAttribute("hidden"),
"The 'Enable breakpoint' context menu item should not be hidden'.");
is(gDebugger.document.getElementById(disableSelfId).getAttribute("hidden"), "true",
"The 'Disable breakpoint' context menu item should be hidden'.");
ok(!selectedBreakpoint.attachment.view.checkbox.hasAttribute("checked"),
"The breakpoint should now be unchecked.");
return deferred.promise;
}
function checkBreakpointToggleOthers(aIndex) {
let deferred = promise.defer();
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 4).then(() => {
let selectedBreakpoint = gSources._selectedBreakpointItem;
ok(gBreakpoints._getAdded(selectedBreakpoint.attachment),
"There should be a breakpoint client available (6).");
ok(!gBreakpoints._getRemoving(selectedBreakpoint.attachment),
"There should be a breakpoint client available (7).");
ok(selectedBreakpoint.attachment.actor,
"There should be a breakpoint client available (8).");
is(!!selectedBreakpoint.attachment.disabled, false,
"The targetted breakpoint should not have been disabled (" + aIndex + ").");
for (let source of gSources) {
for (let otherBreakpoint of source) {
if (otherBreakpoint != selectedBreakpoint) {
ok(!gBreakpoints._getAdded(otherBreakpoint.attachment),
"There should be no breakpoint client for a disabled breakpoint (9).");
is(otherBreakpoint.attachment.disabled, true,
"Non-targetted breakpoints should have been disabled (10).");
}
}
}
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 4).then(() => {
for (let source of gSources) {
for (let someBreakpoint of source) {
ok(gBreakpoints._getAdded(someBreakpoint.attachment),
"There should be a breakpoint client for all enabled breakpoints (11).");
is(someBreakpoint.attachment.disabled, false,
"All breakpoints should now have been enabled (12).");
}
}
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 5).then(() => {
for (let source of gSources) {
for (let someBreakpoint of source) {
ok(!gBreakpoints._getAdded(someBreakpoint.attachment),
"There should be no breakpoint client for a disabled breakpoint (13).");
is(someBreakpoint.attachment.disabled, true,
"All breakpoints should now have been disabled (14).");
}
}
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 5).then(() => {
for (let source of gSources) {
for (let someBreakpoint of source) {
ok(gBreakpoints._getAdded(someBreakpoint.attachment),
"There should be a breakpoint client for all enabled breakpoints (15).");
is(someBreakpoint.attachment.disabled, false,
"All breakpoints should now have been enabled (16).");
}
}
// Done.
deferred.resolve();
});
// Test re-enabling all breakpoints.
enableAll();
});
// Test disabling all breakpoints.
disableAll();
});
// Test re-enabling other breakpoints.
enableOthers();
});
// Test disabling other breakpoints.
disableOthers();
return deferred.promise;
}
function testDeleteAll() {
let deferred = promise.defer();
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_REMOVED, 5).then(() => {
ok(!gSources._selectedBreakpointItem,
"There should be no breakpoint available after removing all breakpoints.");
for (let source of gSources) {
for (let otherBreakpoint of source) {
ok(false, "It's a trap!");
}
}
// Done.
deferred.resolve()
});
// Test deleting all breakpoints.
deleteAll();
return deferred.promise;
}
function disableOthers() {
gSources._onDisableOthers(gSources._selectedBreakpointItem.attachment);
}
function enableOthers() {
gSources._onEnableOthers(gSources._selectedBreakpointItem.attachment);
}
function disableAll() {
gSources._onDisableAll();
}
function enableAll() {
gSources._onEnableAll();
}
function deleteAll() {
gSources._onDeleteAll();
}
}