Backed out 18 changesets (bug 1900395, bug 1918241) for causing dt failures related to browser_dbg. CLOSED TREE

Backed out changeset dd22a3b092ae (bug 1900395)
Backed out changeset 398f6bc67c2e (bug 1918241)
Backed out changeset 09dc669541de (bug 1900395)
Backed out changeset 532f750e2c54 (bug 1900395)
Backed out changeset 2e8f2a91f5c1 (bug 1900395)
Backed out changeset cd15f5429cdf (bug 1900395)
Backed out changeset 95947b399560 (bug 1900395)
Backed out changeset 2dc1ddefcf04 (bug 1900395)
Backed out changeset 3de72d16955d (bug 1900395)
Backed out changeset af2e38994b34 (bug 1900395)
Backed out changeset 8b8dc9c00a8c (bug 1900395)
Backed out changeset 4ef9e765dbcb (bug 1900395)
Backed out changeset 647fb47e8c33 (bug 1900395)
Backed out changeset ee8513f8c8a3 (bug 1900395)
Backed out changeset c2206d5fb1aa (bug 1900395)
Backed out changeset 7520078bc879 (bug 1900395)
Backed out changeset 50e5971e58f7 (bug 1900395)
Backed out changeset d755aed04871 (bug 1900395)
This commit is contained in:
Tamas Szentpeteri 2024-10-10 12:17:15 +03:00
parent b9cb4c61b9
commit f5dc1f7793
96 changed files with 588 additions and 1006 deletions

View File

@ -57,7 +57,7 @@ add_task(async function () {
info("Wait for the debugger to pause");
await waitForPaused(debuggerContext);
const script = findSource(debuggerContext, SCRIPT_FILE);
await assertPausedAtSourceAndLine(debuggerContext, script.id, 10);
assertPausedAtSourceAndLine(debuggerContext, script.id, 10);
info("Resume");
await resume(debuggerContext);

View File

@ -47,7 +47,7 @@ add_task(async function () {
});
await waitForPaused(debuggerContext);
const workerScript = findSource(debuggerContext, "debug-sw.js");
await assertPausedAtSourceAndLine(debuggerContext, workerScript.id, 11);
assertPausedAtSourceAndLine(debuggerContext, workerScript.id, 11);
await resume(debuggerContext);
// remove breakpoint

View File

@ -94,18 +94,6 @@ class ColumnBreakpoints extends Component {
);
return breakpointNode;
},
getMarkerEqualityValue: (line, column) => {
const lineNumber = fromEditorLine(selectedSource.id, line);
const columnBreakpoint = columnBreakpoints.find(
bp => bp.location.line === lineNumber && bp.location.column === column
);
return {
id: columnBreakpoint?.breakpoint?.id,
condition: columnBreakpoint?.breakpoint?.options.condition,
log: columnBreakpoint?.breakpoint?.options.logValue,
disabled: columnBreakpoint?.breakpoint?.disabled,
};
},
});
}

View File

@ -61,9 +61,7 @@ export class ConditionalPanel extends PureComponent {
if (this.input) {
this.input.focus();
} else if (this.breakpointPanelEditor) {
if (!this.breakpointPanelEditor.isDestroyed()) {
this.breakpointPanelEditor.focus();
}
this.breakpointPanelEditor.focus();
}
}

View File

@ -221,21 +221,13 @@ class SearchInFileBar extends Component {
/**
* Update the state with the results and matches from the search.
* The cursor location is also set for CM6.
* The cusor loccation is also set for CM6.
* @param {Object} results
* @param {Array} matches
* @returns
*/
setSearchResults(results, matches) {
if (!results) {
this.setState({
results: {
matches,
matchIndex: 0,
count: matches.length,
index: -1,
},
});
return;
}
const { ch, line } = results;

View File

@ -505,7 +505,8 @@ class Editor extends PureComponent {
}
}
};
// Note: The line is optional, if not passed it fallsback to lineAtHeight.
// Note: The line is optional, if not passed (as is likely for codemirror 6)
// it fallsback to lineAtHeight.
openMenu(event, line, ch) {
event.stopPropagation();
event.preventDefault();
@ -530,9 +531,7 @@ class Editor extends PureComponent {
const target = event.target;
const { id: sourceId } = selectedSource;
if (!features.codemirrorNext) {
line = line ?? lineAtHeight(editor, sourceId, event);
}
line = line ?? lineAtHeight(editor, sourceId, event);
if (typeof line != "number") {
return;

View File

@ -14,10 +14,10 @@ add_task(async function test() {
invokeInTab("main");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "async.js").id, 8);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "async.js").id, 8);
await stepOver(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "async.js").id, 9);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "async.js").id, 9);
await assertBreakpoint(dbg, 8);
});

View File

@ -107,7 +107,6 @@ add_task(async function test_backgroundtask_debugger() {
getCM,
getEditorContent,
getCMEditor,
isCm6Enabled,
log: (msg, data) =>
console.log(`${msg} ${!data ? "" : JSON.stringify(data)}`),
info: (msg, data) =>

View File

@ -64,15 +64,15 @@ add_task(async function testBlackBoxOnReload() {
const onReloaded = reload(dbg, file);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 8);
assertPausedAtSourceAndLine(dbg, source.id, 8);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 12);
assertPausedAtSourceAndLine(dbg, source.id, 12);
await resume(dbg);
info("Wait for reload to complete after resume");
@ -91,7 +91,7 @@ add_task(async function testBlackBoxOnReload() {
const onReloaded2 = reload(dbg, file);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 12);
assertPausedAtSourceAndLine(dbg, source.id, 12);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded2;
@ -132,7 +132,7 @@ add_task(async function testBlackBoxOnToolboxRestart() {
await waitForPaused(dbg);
info("Assert it paused at the debugger statement");
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
await resume(dbg);
await onReloaded;
@ -194,7 +194,7 @@ async function testBlackBoxSource(dbg, source) {
await selectBlackBoxContextMenuItem(dbg, "blackbox");
info("Assert that all lines in the source are styled correctly");
await assertIgnoredStyleInSourceLines(dbg, { hasBlackboxedLinesClass: true });
assertIgnoredStyleInSourceLines(dbg, { hasBlackboxedLinesClass: true });
info("Assert that the source tree for simple4.js has the ignored style");
const node = findSourceNodeWithText(dbg, "simple4.js");
@ -237,9 +237,7 @@ async function testBlackBoxSource(dbg, source) {
await selectBlackBoxContextMenuItem(dbg, "blackbox");
info("Assert that all lines in the source are un-styled correctly");
await assertIgnoredStyleInSourceLines(dbg, {
hasBlackboxedLinesClass: false,
});
assertIgnoredStyleInSourceLines(dbg, { hasBlackboxedLinesClass: false });
info(
"Assert that the source tree for simple4.js does not have the ignored style"
@ -254,12 +252,12 @@ async function testBlackBoxSource(dbg, source) {
info("assert the pause at the debugger statement on line 2");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
await resume(dbg);
info("assert the pause at the breakpoint set on line 8");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 8);
assertPausedAtSourceAndLine(dbg, source.id, 8);
await resume(dbg);
assertNotPaused(dbg);
@ -310,7 +308,7 @@ async function testBlackBoxMultipleLines(dbg, source) {
});
info("Assert that the ignored lines are styled correctly");
await assertIgnoredStyleInSourceLines(dbg, {
assertIgnoredStyleInSourceLines(dbg, {
lines: [7, 13],
hasBlackboxedLinesClass: true,
});
@ -327,7 +325,7 @@ async function testBlackBoxMultipleLines(dbg, source) {
info("assert the pause at the debugger statement on line 2");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
await resume(dbg);
info(
@ -359,7 +357,7 @@ async function testBlackBoxMultipleLines(dbg, source) {
});
info("Assert that the un-ignored lines are no longer have the style");
await assertIgnoredStyleInSourceLines(dbg, {
assertIgnoredStyleInSourceLines(dbg, {
lines: [7, 13],
hasBlackboxedLinesClass: false,
});
@ -377,12 +375,12 @@ async function testBlackBoxMultipleLines(dbg, source) {
// assert the pause at the debugger statement on line 2
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
await resume(dbg);
// assert the pause at the breakpoint set on line 8
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 8);
assertPausedAtSourceAndLine(dbg, source.id, 8);
await resume(dbg);
assertNotPaused(dbg);
@ -413,7 +411,7 @@ async function testBlackBoxSingleLine(dbg, source) {
});
info("Assert that the ignored line 2 is styled correctly");
await assertIgnoredStyleInSourceLines(dbg, {
assertIgnoredStyleInSourceLines(dbg, {
lines: [2],
hasBlackboxedLinesClass: true,
});
@ -423,7 +421,7 @@ async function testBlackBoxSingleLine(dbg, source) {
await selectBlackBoxContextMenuItem(dbg, "blackbox-line");
info("Assert that the ignored line 4 is styled correctly");
await assertIgnoredStyleInSourceLines(dbg, {
assertIgnoredStyleInSourceLines(dbg, {
lines: [4],
hasBlackboxedLinesClass: true,
});
@ -432,17 +430,14 @@ async function testBlackBoxSingleLine(dbg, source) {
// assert the pause at the breakpoint set on line 8
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 8);
assertPausedAtSourceAndLine(dbg, source.id, 8);
await resume(dbg);
assertNotPaused(dbg);
info("Un-blackbox line 2 of funcA()");
await selectEditorLinesAndOpenContextMenu(
dbg,
{ startLine: 2, endLine: 2 },
"CodeMirrorLines"
);
selectEditorLines(dbg, 2, 2);
await openContextMenuInDebugger(dbg, "CodeMirrorLines");
await selectBlackBoxContextMenuItem(dbg, "blackbox-line");
await assertEditorBlackBoxBoxContextMenuItems(dbg, {
@ -465,7 +460,7 @@ async function testBlackBoxSingleLine(dbg, source) {
});
info("Assert that the un-ignored line 2 is styled correctly");
await assertIgnoredStyleInSourceLines(dbg, {
assertIgnoredStyleInSourceLines(dbg, {
lines: [2],
hasBlackboxedLinesClass: false,
});
@ -474,12 +469,12 @@ async function testBlackBoxSingleLine(dbg, source) {
// assert the pause at the debugger statement on line 2
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
await resume(dbg);
// assert the pause at the breakpoint set on line 8
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 8);
assertPausedAtSourceAndLine(dbg, source.id, 8);
await resume(dbg);
assertNotPaused(dbg);
@ -722,3 +717,16 @@ async function assertEditorBlackBoxBoxContextMenuItems(dbg, testFixtures) {
await closeContextMenu(dbg, popup);
}
}
/**
* Selects a range of lines
* @param {Object} dbg
* @param {Number} startLine
* @param {Number} endLine
*/
function selectEditorLines(dbg, startLine, endLine) {
getCM(dbg).setSelection(
{ line: startLine - 1, ch: 0 },
{ line: endLine, ch: 0 }
);
}

View File

@ -32,7 +32,7 @@ add_task(async function () {
"The selected source is the console evaluation and doesn't have a URL"
);
is(getEditorContent(dbg), "debugger");
await assertPausedAtSourceAndLine(dbg, selectedSource.id, 1);
assertPausedAtSourceAndLine(dbg, selectedSource.id, 1);
await resume(dbg);
});

View File

@ -27,11 +27,7 @@ add_task(async function () {
);
is(whyPaused, "Paused on breakpoint");
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-scripts.html").id,
21
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "doc-scripts.html").id, 21);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
@ -41,7 +37,7 @@ add_task(async function () {
await waitForPaused(dbg);
const source = getSelectedSource();
ok(!source.url, "It is an eval source");
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
whyPaused = await waitFor(
() => dbg.win.document.querySelector(".why-paused")?.innerText
@ -53,7 +49,7 @@ add_task(async function () {
await addBreakpoint(dbg, source, 5);
invokeInTab("evaledFunc");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 5);
assertPausedAtSourceAndLine(dbg, source.id, 5);
await resume(dbg);
});

View File

@ -19,7 +19,7 @@ add_task(async function () {
pressKey(dbg, "toggleCondPanel");
await waitForConditionalPanelFocus(dbg);
ok(
!!(await getConditionalPanelAtLine(dbg, 1)),
!!getConditionalPanel(dbg, 1),
"conditional panel panel is open on line 1"
);
is(
@ -38,10 +38,7 @@ add_task(async function () {
pressKey(dbg, "toggleCondPanel");
await waitForConditionalPanelFocus(dbg);
ok(
!!(await getConditionalPanelAtLine(dbg, 32)),
"conditional panel is open on line 32"
);
ok(!!getConditionalPanel(dbg, 32), "conditional panel is open on line 32");
is(
dbg.selectors.getConditionalPanelLocation().line,
32,
@ -56,7 +53,7 @@ add_task(async function () {
info(
"toggle conditional panel with shortcut and add condition to first breakpoint"
);
await setConditionalBreakpointWithKeyboardShortcut(dbg, "1");
setConditionalBreakpointWithKeyboardShortcut(dbg, "1");
await waitForCondition(dbg, 1);
const firstBreakpoint = findColumnBreakpoint(dbg, "long.js", 32, 2);
is(
@ -72,7 +69,7 @@ add_task(async function () {
info(
"toggle conditional panel with shortcut and add condition to second breakpoint"
);
await setConditionalBreakpointWithKeyboardShortcut(dbg, "2");
setConditionalBreakpointWithKeyboardShortcut(dbg, "2");
await waitForCondition(dbg, 2);
const secondBreakpoint = findColumnBreakpoint(dbg, "long.js", 32, 26);
is(
@ -86,7 +83,7 @@ add_task(async function () {
);
setEditorCursorAt(dbg, 31, 7);
info("toggle conditional panel and edit condition using shortcut");
await setConditionalBreakpointWithKeyboardShortcut(dbg, "2");
setConditionalBreakpointWithKeyboardShortcut(dbg, "2");
ok(
!!waitForCondition(dbg, "12"),
"breakpoint closest to cursor position has been edited"
@ -100,7 +97,7 @@ add_task(async function () {
);
setEditorCursorAt(dbg, 31, 21);
info("toggle conditional panel and edit condition using shortcut");
await setConditionalBreakpointWithKeyboardShortcut(dbg, "3");
setConditionalBreakpointWithKeyboardShortcut(dbg, "3");
ok(
!!waitForCondition(dbg, "13"),
"breakpoint closest to cursor position has been edited"
@ -112,7 +109,7 @@ add_task(async function () {
info("toggle log panel with shortcut: cursor on line 33");
setEditorCursorAt(dbg, 33, 1);
await setLogBreakpointWithKeyboardShortcut(dbg, "3");
setLogBreakpointWithKeyboardShortcut(dbg, "3");
ok(
!!waitForLog(dbg, "3"),
"breakpoint closest to cursor position has been edited"
@ -122,6 +119,16 @@ add_task(async function () {
pressKey(dbg, "Escape");
});
// from test/mochitest/browser_dbg-breakpoints-cond-source-maps.js
function getConditionalPanel(dbg, line) {
return getCM(dbg).doc.getLineHandle(line - 1).widgets[0];
}
// from devtools browser_dbg-breakpoints-cond-source-maps.js
async function waitForConditionalPanelFocus(dbg) {
await waitFor(() => dbg.win.document.activeElement.tagName === "TEXTAREA");
}
// from browser_dbg-breakpoints-columns.js
async function enableFirstBreakpoint(dbg) {
setEditorCursorAt(dbg, 32, 0);
@ -148,10 +155,10 @@ async function enableSecondBreakpoint(dbg) {
// use shortcut to open conditional panel.
function setConditionalBreakpointWithKeyboardShortcut(dbg, condition) {
pressKey(dbg, "toggleCondPanel");
return typeInPanel(dbg, condition);
typeInPanel(dbg, condition);
}
function setLogBreakpointWithKeyboardShortcut(dbg, condition) {
pressKey(dbg, "toggleLogPanel");
return typeInPanel(dbg, condition, true);
typeInPanel(dbg, condition, true);
}

View File

@ -11,12 +11,12 @@ add_task(async function () {
const dbg = await initDebugger("doc-sourcemaps.html", "entry.js");
await selectSource(dbg, "bundle.js");
await scrollEditorIntoView(dbg, 55, 0);
getCM(dbg).scrollIntoView({ line: 55, ch: 0 });
await setLogPoint(dbg, 55);
await waitForConditionalPanelFocus(dbg);
ok(
!!(await getConditionalPanelAtLine(dbg, 55)),
!!getConditionalPanel(dbg, 55),
"conditional panel panel is open on line 55"
);
is(
@ -27,13 +27,19 @@ add_task(async function () {
});
async function setLogPoint(dbg, index) {
const el = await (isCm6Enabled
? scrollAndGetEditorLineGutterElement(dbg, index)
: codeMirrorGutterElement(dbg, index));
rightClickEl(dbg, el);
const gutterEl = await getEditorLineGutter(dbg, index);
rightClickEl(dbg, gutterEl.firstChild);
await waitForContextMenu(dbg);
selectContextMenuItem(
dbg,
`${selectors.addLogItem},${selectors.editLogItem}`
);
}
async function waitForConditionalPanelFocus(dbg) {
await waitFor(() => dbg.win.document.activeElement.tagName === "TEXTAREA");
}
function getConditionalPanel(dbg, line) {
return getCM(dbg).doc.getLineHandle(line - 1).widgets[0];
}

View File

@ -76,7 +76,11 @@ add_task(async function () {
info("Double click the conditional breakpoint in secondary pane");
dblClickElement(dbg, "conditionalBreakpointInSecPane");
assertConditonalBreakpointPanelFocus(dbg, { isCm6Enabled });
is(
dbg.win.document.activeElement.tagName,
"TEXTAREA",
"The textarea of conditional breakpoint panel is focused"
);
info("Click the conditional breakpoint in secondary pane");
await clickElement(dbg, "conditionalBreakpointInSecPane");
@ -105,7 +109,11 @@ add_task(async function () {
info("Double click the logpoint in secondary pane");
dblClickElement(dbg, "logPointInSecPane");
assertConditonalBreakpointPanelFocus(dbg, { isLogPoint: true, isCm6Enabled });
is(
dbg.win.document.activeElement.tagName,
"TEXTAREA",
"The textarea of logpoint panel is focused"
);
info("Click the logpoint in secondary pane");
await clickElement(dbg, "logPointInSecPane");
@ -130,21 +138,6 @@ async function setConditionalBreakpoint(dbg, index, condition) {
typeInPanel(dbg, condition);
}
function assertConditonalBreakpointPanelFocus(
dbg,
{ isLogPoint = false, isCm6Enabled }
) {
const focusedElement = dbg.win.document.activeElement;
const isPanelFocused = isCm6Enabled
? focusedElement.classList.contains("cm-content") &&
focusedElement.closest(
`.conditional-breakpoint-panel${isLogPoint ? ".log-point" : ""}`
)
: focusedElement.tagName == "TEXTAREA";
ok(
isPanelFocused,
`The content element of ${
isLogPoint ? "log point" : "conditional breakpoint"
} panel is focused`
);
async function waitForConditionalPanelFocus(dbg) {
await waitFor(() => dbg.win.document.activeElement.tagName === "TEXTAREA");
}

View File

@ -31,7 +31,7 @@ add_task(async function () {
await waitForPaused(dbg);
source = findSource(dbg, "doc-duplicate-functions.html");
await assertPausedAtSourceAndLine(dbg, source.id, 21);
assertPausedAtSourceAndLine(dbg, source.id, 21);
await assertBreakpoint(dbg, 21);
await resume(dbg);

View File

@ -51,7 +51,7 @@ add_task(async function () {
);
const evaledSource = dbg.selectors.getSelectedSource();
await assertPausedAtSourceAndLine(dbg, evaledSource.id, 2);
assertPausedAtSourceAndLine(dbg, evaledSource.id, 2);
info("Add a breakpoint in the evaled source");
await addBreakpoint(dbg, evaledSource, 3);
@ -59,7 +59,7 @@ add_task(async function () {
info("Resume and check that we hit the breakpoint");
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, evaledSource.id, 3);
assertPausedAtSourceAndLine(dbg, evaledSource.id, 3);
info("Close the toolbox");
await dbg.toolbox.closeToolbox();
@ -84,7 +84,7 @@ add_task(async function () {
await waitForPaused(dbg2);
const scriptSource = dbg2.selectors.getSelectedSource();
await assertPausedAtSourceAndLine(dbg2, scriptSource.id, 21);
assertPausedAtSourceAndLine(dbg2, scriptSource.id, 21);
await resume(dbg2);
info("Wait for reload to complete after resume");

View File

@ -88,7 +88,7 @@ add_task(async function testPausedByBreakpoint() {
);
source = await waitForSource(dbg, POPUP_URL);
await assertPausedAtSourceAndLine(dbg, source.id, 4);
assertPausedAtSourceAndLine(dbg, source.id, 4);
await resume(dbg);
is(
@ -112,7 +112,7 @@ add_task(async function testPausedByDebuggerStatement() {
);
const source = findSource(dbg, POPUP_DEBUGGER_STATEMENT_URL);
await assertPausedAtSourceAndLine(dbg, source.id, 4);
assertPausedAtSourceAndLine(dbg, source.id, 4);
await resume(dbg);
is(

View File

@ -44,7 +44,7 @@ add_task(async function () {
);
info("Assert that the breakpoint pauses on line 5");
await assertPausedAtSourceAndLine(dbg, source.id, 5);
assertPausedAtSourceAndLine(dbg, source.id, 5);
// This fails at the moment as there is no visible breakpoint on this line
info("Assert that there is a breakpoint displayed on line 5");
@ -69,7 +69,7 @@ add_task(async function () {
);
info("Assert that the breakpoint pauses on line 5");
await assertPausedAtSourceAndLine(dbg, source.id, 5);
assertPausedAtSourceAndLine(dbg, source.id, 5);
info("Assert that there is a breakpoint dispalyed on line 5");
await assertBreakpoint(dbg, 5);
@ -100,7 +100,7 @@ add_task(async function () {
);
info("Assert that the breakpoint pauses on line 5");
await assertPausedAtSourceAndLine(dbg, source.id, 5);
assertPausedAtSourceAndLine(dbg, source.id, 5);
info("Assert that there is a breakpoint displayed on line 5");
await assertBreakpoint(dbg, 5);

View File

@ -16,9 +16,10 @@ add_task(async function () {
await waitForBreakpoint(dbg, "long.js", 66);
info("scroll editor to the top");
await scrollEditorIntoView(dbg, 0, 0);
const cm = getCM(dbg);
cm.scrollTo(0, 0);
ok(isScrolledPositionVisible(dbg, 0, 0), "editor is scrolled to the top.");
is(cm.getScrollInfo().top, 0, "editor is scrolled to the top.");
info("open breakpointContextMenu and select add log");
await openBreakpointContextMenu(dbg);
@ -32,15 +33,12 @@ add_task(async function () {
await typeInPanel(dbg, "this.todos");
await waitForDispatch(dbg.store, "SET_BREAKPOINT");
ok(
isScrolledPositionVisible(dbg, 66),
"editor is scrolled to the log input line."
);
is(cm.getScrollInfo().top, 870, "editor is scrolled to the log input line.");
info("scroll editor to the top");
await scrollEditorIntoView(dbg, 0, 0);
cm.scrollTo(0, 0);
ok(isScrolledPositionVisible(dbg, 0, 0), "editor is scrolled to the top.");
is(cm.getScrollInfo().top, 0, "editor is scrolled to the top.");
info("open breakpointContextMenu and select edit log");
await openBreakpointContextMenu(dbg);
@ -54,10 +52,7 @@ add_task(async function () {
await typeInPanel(dbg, ".id");
await waitForDispatch(dbg.store, "SET_BREAKPOINT");
ok(
isScrolledPositionVisible(dbg, 66),
"editor is scrolled to the log input line."
);
is(cm.getScrollInfo().top, 870, "editor is scrolled to the log input line.");
});
async function openBreakpointContextMenu(dbg) {

View File

@ -14,7 +14,7 @@ add_task(async function () {
await addBreakpoint(dbg, "xbundle.js", 5);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "xbundle.js").id, 5);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "xbundle.js").id, 5);
// Switch to original source
await dbg.actions.jumpToMappedSelectedLocation();
@ -23,5 +23,5 @@ add_task(async function () {
await waitForSelectedSource(dbg, "xsource.js");
const originalSource = findSource(dbg, "xsource.js");
await assertPausedAtSourceAndLine(dbg, originalSource.id, 3);
assertPausedAtSourceAndLine(dbg, originalSource.id, 3);
});

View File

@ -46,8 +46,6 @@ add_task(async function () {
selectSource,
assertTextContentOnLine,
getEditorContent,
isCm6Enabled,
getCMEditor,
});
await addTab(`${EXAMPLE_URL}doc-all-workers.html`);

View File

@ -13,9 +13,9 @@ add_task(async function () {
await selectSource(dbg, "simple2.js", 1);
clickElement(dbg, "CodeMirrorLines");
await waitForElement(dbg, "CodeMirrorCode");
await waitForElementWithSelector(dbg, ".CodeMirror-code");
setSelection(dbg, 1, 7);
getCM(dbg).setSelection({ line: 0, ch: 0 }, { line: 8, ch: 0 });
rightClickElement(dbg, "CodeMirrorLines");
await waitForContextMenu(dbg);

View File

@ -14,7 +14,7 @@ add_task(async function () {
await waitFor(() => toolbox.getPanel("jsdebugger"));
const dbg = createDebuggerContext(toolbox);
await waitForElement(dbg, "highlightLine");
await waitForElementWithSelector(dbg, ".CodeMirror-code > .highlight-line");
assertHighlightLocation(dbg, "script-switching-02.js", 18);
});

View File

@ -38,7 +38,7 @@ add_task(async function () {
() => findElementWithSelector(dbg, ".sources-list .focused"),
"Source is focused"
);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "content_script.js").id,
2

View File

@ -30,7 +30,7 @@ add_task(async function () {
// waitForPaused properly waits for the scopes to be available
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "pause-points.js").id,
lineToContinueTo,

View File

@ -15,7 +15,7 @@ add_task(async function () {
await waitForInlinePreviews(dbg);
await continueToLine(dbg, 31);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "pause-points.js").id,
31,
@ -29,7 +29,7 @@ add_task(async function () {
await waitForInlinePreviews(dbg);
await continueToColumn(dbg, { line: 31, column: 8 });
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "pause-points.js").id,
31,

View File

@ -18,7 +18,7 @@ add_task(async function () {
let onReloaded = reload(dbg, "doc-debugger-statements.html");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-debugger-statements.html").id,
11
@ -27,7 +27,7 @@ add_task(async function () {
info("resume");
await clickResume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-debugger-statements.html").id,
16
@ -35,7 +35,7 @@ add_task(async function () {
info("step over");
await clickStepOver(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-debugger-statements.html").id,
17
@ -43,7 +43,7 @@ add_task(async function () {
info("step into");
await clickStepIn(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-debugger-statements.html").id,
22
@ -51,7 +51,7 @@ add_task(async function () {
info("step over");
await clickStepOver(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-debugger-statements.html").id,
24
@ -59,7 +59,7 @@ add_task(async function () {
info("step out");
await clickStepOut(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-debugger-statements.html").id,
18
@ -87,7 +87,7 @@ add_task(async function () {
onReloaded = reload(dbg, "doc-debugger-statements.html");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-debugger-statements.html").id,
11

View File

@ -109,7 +109,7 @@ add_task(async function testGutterBreakpointsForSourceWithIgnoredLines() {
await closeContextMenu(dbg, popup);
info("Assert that the lines 17 to 21 are still ignored");
await assertIgnoredStyleInSourceLines(dbg, {
assertIgnoredStyleInSourceLines(dbg, {
lines: [17, 21],
hasBlackboxedLinesClass: true,
});

View File

@ -25,7 +25,7 @@ add_task(async function () {
info("Select line 16 and make sure the editor scrolled.");
await selectSource(dbg, "long.js", 16);
await waitForElement(dbg, "highlightLine");
await waitForElementWithSelector(dbg, ".CodeMirror-code > .highlight-line");
assertHighlightLocation(dbg, "long.js", 16);
info("Select several locations and check that we have one highlight");

View File

@ -19,44 +19,34 @@ add_task(async function () {
await selectSource(dbg, "simple1.js");
await addBreakpoint(dbg, "simple1.js", 26);
const cm = getCM(dbg);
info("Open long file, scroll down to line below the fold");
await selectSource(dbg, "long.js");
await scrollEditorIntoView(dbg, 24, 0);
ok(isScrolledPositionVisible(dbg, 24), "Scroll position is visible");
cm.scrollTo(0, 600);
info("Ensure vertical scroll is the same after switching documents");
let onScrolled = waitForScrolling(dbg);
await selectSource(dbg, "simple1.js");
// Wait for any codemirror editor scroll that can happen
await onScrolled;
ok(isScrolledPositionVisible(dbg, 0), "Scrolled to the top of the editor");
onScrolled = waitForScrolling(dbg);
is(cm.getScrollInfo().top, 0);
await selectSource(dbg, "long.js");
await onScrolled;
ok(isScrolledPositionVisible(dbg, 24), "Scroll position is visible");
is(cm.getScrollInfo().top, 600);
info("Trigger a pause, click on a frame, ensure the right line is selected");
onScrolled = waitForScrolling(dbg);
invokeInTab("doNamedEval");
await waitForPaused(dbg);
await onScrolled;
ok(
isScrolledPositionVisible(dbg, 26),
"Frame scrolled down to correct location"
findElement(dbg, "frame", 1).focus();
await clickElement(dbg, "frame", 1);
Assert.notEqual(
cm.getScrollInfo().top,
0,
"frame scrolled down to correct location"
);
info("Navigating while paused, goes to the correct location");
onScrolled = waitForScrolling(dbg);
await selectSource(dbg, "long.js");
await onScrolled;
ok(isScrolledPositionVisible(dbg, 24), "Scroll position is visible");
is(cm.getScrollInfo().top, 600);
info("Open new source, ensure it's at 0 scroll");
onScrolled = waitForScrolling(dbg);
await selectSource(dbg, "frames.js");
await onScrolled;
ok(isScrolledPositionVisible(dbg, 0), "Scrolled to the top of the editor");
is(cm.getScrollInfo().top, 0);
});

View File

@ -69,19 +69,19 @@ add_task(async function () {
invokeInTab("main");
await waitForPaused(dbg);
await waitForSelectedSource(dbg, "simple1.js");
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple1.js").id, 4);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple1.js").id, 4);
assertCursorPosition(dbg, 4, 16, "on pause, the cursor updates");
info("Step into another file.");
await stepOver(dbg);
await stepIn(dbg);
await waitForSelectedSource(dbg, "simple2.js");
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 3);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 3);
assertCursorPosition(dbg, 3, 5, "on step-in, the cursor updates");
info("Step out to the initial file.");
await stepOut(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple1.js").id, 6);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple1.js").id, 6);
assertCursorPosition(dbg, 6, 3, "on step-out, the cursor updates");
await resume(dbg);
@ -94,7 +94,7 @@ add_task(async function () {
await waitForPaused(dbg);
await waitForSelectedSource(dbg, "long.js");
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "long.js").id, 66);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "long.js").id, 66);
ok(
isVisibleInEditor(dbg, findElement(dbg, "breakpoint")),
"Breakpoint is visible"

View File

@ -51,7 +51,7 @@ add_task(async function () {
});
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 3);
assertPausedAtSourceAndLine(dbg, source.id, 3);
assertTextContentOnLine(dbg, 3, `console.log("breakpoint line");`);
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => {

View File

@ -25,7 +25,7 @@ add_task(async function () {
const waitForReload = reloadBrowser();
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-event-breakpoints-fission.html").id,
17
@ -48,7 +48,7 @@ add_task(async function () {
async function invokeAndAssertBreakpoints(dbg) {
invokeInTabRemoteFrame("clickHandler");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "event-breakpoints.js").id,
12
@ -57,7 +57,7 @@ async function invokeAndAssertBreakpoints(dbg) {
invokeInTabRemoteFrame("xhrHandler");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "event-breakpoints.js").id,
20

View File

@ -22,7 +22,7 @@ add_task(async function () {
invokeInTab("clickHandler");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 12);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 12);
const whyPaused = await waitFor(
() => dbg.win.document.querySelector(".why-paused")?.innerText
@ -37,24 +37,24 @@ add_task(async function () {
await toggleEventBreakpoint(dbg, "XHR", "event.xhr.load");
invokeInTab("xhrHandler");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 20);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 20);
await resume(dbg);
await toggleEventBreakpoint(dbg, "Timer", "timer.timeout.set");
await toggleEventBreakpoint(dbg, "Timer", "timer.timeout.fire");
invokeInTab("timerHandler");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 27);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 27);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 28);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 28);
await resume(dbg);
await toggleEventBreakpoint(dbg, "Script", "script.source.firstStatement");
invokeInTab("evalHandler");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "eval-test.js").id, 2);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "eval-test.js").id, 2);
await resume(dbg);
await toggleEventBreakpoint(dbg, "Script", "script.source.firstStatement");
@ -62,12 +62,12 @@ add_task(async function () {
await toggleEventBreakpoint(dbg, "Control", "event.control.focusout");
invokeOnElement("#focus-text", "focus");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 43);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 43);
await resume(dbg);
// wait for focus-out event to fire
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 48);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 48);
await resume(dbg);
info("Deselect focus events");
@ -79,7 +79,7 @@ add_task(async function () {
await toggleEventBreakpoint(dbg, "Control", "event.control.invoke");
invokeOnElement("#invoker", "click");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 73);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 73);
await resume(dbg);
info("Enable beforetoggle and toggle events");
@ -88,11 +88,11 @@ add_task(async function () {
invokeOnElement("#popover-toggle", "click");
info("Wait for pause in beforetoggle event listener");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 89);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 89);
await resume(dbg);
info("And wait for pause in toggle event listener after resuming");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 93);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 93);
await resume(dbg);
await toggleEventBreakpoint(
@ -106,7 +106,7 @@ add_task(async function () {
invokeComposition();
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 53);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 53);
await resume(dbg);
info("Deselect compositionstart and select compositionupdate");
@ -127,7 +127,7 @@ add_task(async function () {
invokeComposition();
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 58);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 58);
await resume(dbg);
info("Deselect compositionupdate and select compositionend");
@ -149,7 +149,7 @@ add_task(async function () {
});
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 63);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 63);
await resume(dbg);
info("Test textInput");
@ -157,7 +157,7 @@ add_task(async function () {
invokeOnElement("#focus-text", "focus");
EventUtils.sendChar("N");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 98);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 98);
await resume(dbg);
await toggleEventBreakpoint(dbg, "Keyboard", "event.keyboard.textInput");
@ -169,13 +169,13 @@ add_task(async function () {
});
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 68);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 68);
await resume(dbg);
info("Check that the click event breakpoint is still enabled");
invokeInTab("clickHandler");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 12);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 12);
await resume(dbg);
info("Check that disabling an event breakpoint works");
@ -189,7 +189,7 @@ add_task(async function () {
await toggleEventBreakpoint(dbg, "Mouse", "event.mouse.click");
invokeInTab("clickHandler");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 12);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 12);
await resume(dbg);
info(
@ -221,7 +221,7 @@ add_task(async function () {
await toggleEventBreakpoint(dbg, "Load", "event.load.beforeunload");
let onReload = reload(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 78);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 78);
await resume(dbg);
await onReload;
await toggleEventBreakpoint(dbg, "Load", "event.load.beforeunload");
@ -230,7 +230,7 @@ add_task(async function () {
await toggleEventBreakpoint(dbg, "Load", "event.load.unload");
onReload = reload(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 83);
assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 83);
await resume(dbg);
await onReload;
await toggleEventBreakpoint(dbg, "Load", "event.load.unload");

View File

@ -64,7 +64,7 @@ add_task(async function () {
info(
"So that we miss info about the ASM sources and lines are not breakables"
);
await assertLineIsBreakable(dbg, legitSource.url, 7, false);
assertLineIsBreakable(dbg, legitSource.url, 7, false);
info("Reload and assert that ASM.js file are then debuggable");
await reload(dbg, "doc-asm.html", "asm.js");
@ -73,7 +73,7 @@ add_task(async function () {
// Ensure selecting the source before asserting breakable lines
// otherwise the gutter may not be yet updated
await selectSource(dbg, "asm.js");
await assertLineIsBreakable(dbg, legitSource.url, 7, true);
assertLineIsBreakable(dbg, legitSource.url, 7, true);
await waitForSourcesInSourceTree(dbg, ["doc-asm.html", "asm.js"]);
is(dbg.selectors.getSourceCount(), 2, "There is only the two sources");
@ -84,7 +84,7 @@ add_task(async function () {
invokeInTab("runAsm");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "asm.js").id, 7);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "asm.js").id, 7);
await assertBreakpoint(dbg, 7);
await removeBreakpoint(dbg, findSource(dbg, "asm.js").id, 7);

View File

@ -9,8 +9,6 @@ const testServer = createVersionizedHttpTestServer(
);
const TEST_URL = testServer.urlFor("index.html");
requestLongerTimeout(4);
// Assert the behavior of the gutter that grays out non-breakable lines
add_task(async function testBreakableLinesOverReloads() {
const dbg = await initDebuggerWithAbsoluteURL(

View File

@ -11,7 +11,7 @@ const TEST_URL = testServer.urlFor("index.html");
// getTokenFromPosition pauses 0.5s for each line,
// so this test is quite slow to complete
requestLongerTimeout(10);
requestLongerTimeout(4);
/**
* Cover the breakpoints positions/columns:
@ -155,7 +155,7 @@ add_task(async function testBreakableLinesOverReloads() {
{ line: 9, columns: [2, 8] },
{ line: 10, columns: [2, 10] },
{ line: 11, columns: [] },
{ line: 13, columns: [0, 8] },
{ line: 13, columns: [] },
]);
});
@ -178,7 +178,7 @@ async function assertBreakablePositions(
);
// If we don't have any position, only assert that the line isn't breakable
if (!positions) {
await assertLineIsBreakable(dbg, file, line, false);
assertLineIsBreakable(dbg, file, line, false);
continue;
}
const { columns } = positions;
@ -192,7 +192,7 @@ async function assertBreakablePositions(
// Last lines of inline script are reported as breakable lines and selectors reports
// one breakable column, but, we don't report any available column breakpoint for them.
if (!columns.length) {
// So, only ensure that there really is no marker on this line
// So, only ensure that the really is no marker on this line
const lineElement = await getTokenFromPosition(dbg, { line });
const columnMarkers = lineElement.querySelectorAll(".column-breakpoint");
is(
@ -240,9 +240,7 @@ async function assertBreakablePositions(
}
const tokenElement = await getTokenFromPosition(dbg, { line });
const lineElement = tokenElement.closest(
isCm6Enabled ? ".cm-line" : ".CodeMirror-line"
);
const lineElement = tokenElement.closest(".CodeMirror-line");
// Those are the breakpoint chevron we click on to set a breakpoint on a given column
const columnMarkers = [
...lineElement.querySelectorAll(".column-breakpoint"),
@ -254,27 +252,20 @@ async function assertBreakablePositions(
);
// The first breakable column received the line breakpoint when calling addBreakpoint()
const firstColumn = columns[0];
const firstColumn = columns.shift();
ok(
findColumnBreakpoint(dbg, file, line, firstColumn),
`The first column ${firstColumn} has a breakpoint automatically`
);
columnMarkers.shift();
for (const [index, column] of Object.entries(columns)) {
const columnMarkerIndex = Number(index);
// The first column breakpoint is shifted
if (columnMarkerIndex == 0) {
continue;
}
for (const column of columns) {
ok(
!findColumnBreakpoint(dbg, file, line, column),
`Before clicking on the marker, the column ${column} was not having a breakpoint`
);
const marker = columnMarkers.shift();
const onSetBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
let marker = isCm6Enabled
? getColumnMarker(lineElement, columnMarkerIndex)
: columnMarkers[columnMarkerIndex];
marker.click();
await onSetBreakpoint;
ok(
@ -286,10 +277,6 @@ async function assertBreakablePositions(
dbg.store,
"REMOVE_BREAKPOINT"
);
if (isCm6Enabled) {
// Get the marker again as the column marker has re rendered
marker = getColumnMarker(lineElement, columnMarkerIndex);
}
marker.click();
await onRemoveBreakpoint;
@ -302,7 +289,3 @@ async function assertBreakablePositions(
await removeBreakpoint(dbg, source.id, line);
}
}
function getColumnMarker(lineElement, index) {
return lineElement.querySelectorAll(".column-breakpoint")[index];
}

View File

@ -30,23 +30,19 @@ add_task(
invokeInTab("foo");
await waitForPausedInOriginalFileAndToggleMapScopes(dbg, "original.js");
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "original.js").id,
8
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 8);
info("Then stepping into a generated source");
await stepIn(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 5);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 5);
info("Stepping another time within the same generated source");
await stepIn(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 7);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 7);
info("And finally stepping into another original source");
await stepIn(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "removed-original.js").id,
4
@ -54,28 +50,20 @@ add_task(
info("Walk up the stack backward, until we resume execution");
await stepIn(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "removed-original.js").id,
5
);
await stepIn(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 8);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 8);
await stepIn(dbg);
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "original.js").id,
9
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 9);
await stepIn(dbg);
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "original.js").id,
10
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 10);
// We can't use the `stepIn` helper as this last step will resume
// and the helper is expecting to pause again

View File

@ -343,7 +343,7 @@ add_task(async function testSourceTextContent() {
is(sources.length, 1, "Got a unique source related to new Function source");
let newFunctionSource = sources[0];
// We acknowledge the function header as well as the new line in the first argument
await assertPausedAtSourceAndLine(dbg, newFunctionSource.id, 4, 0);
assertPausedAtSourceAndLine(dbg, newFunctionSource.id, 4, 0);
is(getEditorContent(dbg), "function anonymous(a\n,b1\n) {\ndebugger;\n}");
await resume(dbg);
@ -357,7 +357,7 @@ add_task(async function testSourceTextContent() {
is(sources.length, 1, "Got a unique source related to new Function source");
newFunctionSource = sources[0];
// We acknowledge the function header as well as the new line in the first argument
await assertPausedAtSourceAndLine(dbg, newFunctionSource.id, 4, 0);
assertPausedAtSourceAndLine(dbg, newFunctionSource.id, 4, 0);
is(getEditorContent(dbg), "function anonymous(a\n,b2\n) {\ndebugger;\n}");
await resume(dbg);

View File

@ -57,7 +57,7 @@ add_task(async function () {
// Ensure selecting the source before asserting breakable lines
// otherwise the gutter may not be yet updated
await selectSource(dbg, "fib.c");
await assertLineIsBreakable(dbg, source.url, 14, true);
assertLineIsBreakable(dbg, source.url, 14, true);
await waitForSourcesInSourceTree(dbg, [
"doc-wasm-sourcemaps.html",
@ -77,11 +77,7 @@ add_task(async function () {
await waitForPausedInOriginalFileAndToggleMapScopes(dbg);
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "fib.c").id,
breakpointLine
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "fib.c").id, breakpointLine);
await assertBreakpoint(dbg, breakpointLine);
// Capture the generated location line, so that we can better report
// when the binary code changed later in this test
@ -117,7 +113,7 @@ add_task(async function () {
keepContext: false,
});
await assertLineIsBreakable(dbg, binarySource.url, binaryLine, true);
assertLineIsBreakable(dbg, binarySource.url, binaryLine, true);
await addBreakpoint(dbg, binarySource, virtualBinaryLine);
invokeInTab("runWasm");
@ -126,7 +122,7 @@ add_task(async function () {
// so only assert that we are in paused state.
await waitForPaused(dbg);
// We don't try to assert paused line as there is two types of line in wasm
await assertPausedAtSourceAndLine(dbg, binarySource.id, virtualBinaryLine);
assertPausedAtSourceAndLine(dbg, binarySource.id, virtualBinaryLine);
// Switch to original source
info(
@ -138,11 +134,7 @@ add_task(async function () {
// to do all classic assertions for paused state.
await waitForPausedInOriginalFileAndToggleMapScopes(dbg);
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "fib.c").id,
breakpointLine
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "fib.c").id, breakpointLine);
info("Reselect the binary source");
await dbg.actions.selectLocation(createLocation({ source: binarySource }), {
@ -152,7 +144,7 @@ add_task(async function () {
assertFirstFrameTitleAndLocation(dbg, "(wasmcall)", "fib.wasm");
// We can't use this method as it uses internaly the breakpoint line, which isn't the line in CodeMirror
// await assertPausedAtSourceAndLine(dbg, binarySource.id, binaryLine);
// assertPausedAtSourceAndLine(dbg, binarySource.id, binaryLine);
await assertBreakpoint(dbg, binaryLine);
await removeBreakpoint(dbg, binarySource.id, virtualBinaryLine);

View File

@ -44,7 +44,7 @@ add_task(async function () {
"Selected source is simple2.js"
);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 7);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 7);
await waitForElement(dbg, "threadsPaneItems");
threadsEl = findAllElements(dbg, "threadsPaneItems");
@ -79,7 +79,7 @@ add_task(async function () {
);
await stepIn(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 7);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 7);
// We can't used `stepIn` helper as this last step will resume
// and the helper is expecting to pause again

View File

@ -17,7 +17,7 @@ add_task(async function () {
let onReloaded = reload(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc_dbg-fission-frame-pause-exceptions.html").id,
17
@ -33,7 +33,7 @@ add_task(async function () {
onReloaded = reload(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc_dbg-fission-frame-pause-exceptions.html").id,
13
@ -42,7 +42,7 @@ add_task(async function () {
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc_dbg-fission-frame-pause-exceptions.html").id,
17

View File

@ -37,18 +37,18 @@ add_task(async function () {
"The js source is not flagged as an html source"
);
await assertPausedAtSourceAndLine(dbg, htmlSource.id, 8);
assertPausedAtSourceAndLine(dbg, htmlSource.id, 8);
await resume(dbg);
await waitForBreakableLine(dbg, "doc-html-breakpoints.html", 15);
invokeInTab("test3");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, htmlSource.id, 15);
assertPausedAtSourceAndLine(dbg, htmlSource.id, 15);
await resume(dbg);
await waitForBreakableLine(dbg, "doc-html-breakpoints.html", 20);
invokeInTab("test4");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, htmlSource.id, 20);
assertPausedAtSourceAndLine(dbg, htmlSource.id, 20);
await resume(dbg);
});

View File

@ -21,17 +21,13 @@ add_task(async function () {
const onReloaded = reload(dbg);
await waitForPaused(dbg);
await waitForLoadedSource(dbg, "doc-iframes.html");
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-iframes.html").id,
11
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "doc-iframes.html").id, 11);
// test pausing in the iframe
await resume(dbg);
await waitForPaused(dbg);
await waitForLoadedSource(dbg, "doc-debugger-statements.html");
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-debugger-statements.html").id,
11
@ -40,7 +36,7 @@ add_task(async function () {
// test pausing in the iframe
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-debugger-statements.html").id,
16

View File

@ -15,22 +15,22 @@ add_task(async function () {
await waitForPaused(dbg);
await waitForLoadedSource(dbg, "doc-debugger-statements.html");
const source = findSource(dbg, "doc-debugger-statements.html");
await assertPausedAtSourceAndLine(dbg, source.id, 11);
assertPausedAtSourceAndLine(dbg, source.id, 11);
await pressResume(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 16);
assertPausedAtSourceAndLine(dbg, source.id, 16);
await pressStepOver(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 17);
assertPausedAtSourceAndLine(dbg, source.id, 17);
await pressStepIn(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 22);
assertPausedAtSourceAndLine(dbg, source.id, 22);
await pressStepOut(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 18);
assertPausedAtSourceAndLine(dbg, source.id, 18);
await pressStepOver(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 18);
assertPausedAtSourceAndLine(dbg, source.id, 18);
await resume(dbg);
info("Wait for reload to complete after resume");

View File

@ -34,7 +34,7 @@ add_task(async function () {
info("Check paused location\n");
const source = findSource(dbg, "doc-reload-link.html");
await assertPausedAtSourceAndLine(dbg, source.id, 3);
assertPausedAtSourceAndLine(dbg, source.id, 3);
await resume(dbg);

View File

@ -59,7 +59,7 @@ add_task(async function () {
await waitForPaused(dbg);
// We aren't pausing on secondCall's debugger statement,
// called by the condition, but only on the breakpoint we set on firstCall, line 8
await assertPausedAtSourceAndLine(dbg, source.id, 8);
assertPausedAtSourceAndLine(dbg, source.id, 8);
// The log point is visible, even if it had a debugger statement in it.
await hasConsoleMessage(dbg, "second call 44");
@ -80,7 +80,7 @@ add_task(async function () {
await waitForPaused(dbg);
// Exceptions in conditional breakpoint would not trigger a pause,
// So we end up pausing on the debugger statement in the other script.
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "script-switching-02.js").id,
6

View File

@ -13,7 +13,7 @@ add_task(async function () {
await waitForPaused(dbg, "doc-navigation-when-paused.html");
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-navigation-when-paused.html").id,
12
@ -34,7 +34,7 @@ add_task(async function () {
// source itself has loaded, which may not be the case if navigation cleared
// the source and nothing has sent it to the devtools client yet, as was
// the case in Bug 1581530.
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-navigation-when-paused.html").id,
12

View File

@ -40,7 +40,7 @@ add_task(async function () {
invokeInTab("main");
await waitForPaused(dbg);
const source = findSource(dbg, "simple1.js");
await assertPausedAtSourceAndLine(dbg, source.id, 4);
assertPausedAtSourceAndLine(dbg, source.id, 4);
is(countSources(dbg), 5, "5 sources are loaded.");
await waitForRequestsToSettle(dbg);

View File

@ -99,7 +99,7 @@ add_task(async function () {
const onReloaded = reload(dbg, "test.js");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "test.js").id, 2);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "test.js").id, 2);
is(
getEditorContent(dbg),
testOverrideSourceContent,

View File

@ -30,7 +30,7 @@ add_task(async function () {
await togglePauseOnExceptions(dbg, true, true);
uncaughtException();
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
const whyPaused = await waitFor(
() => dbg.win.document.querySelector(".why-paused")?.innerText
@ -43,18 +43,18 @@ add_task(async function () {
await togglePauseOnExceptions(dbg, true, true);
uncaughtException();
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
await resume(dbg);
info("3. Test pausing on a caught Error");
caughtException();
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 7);
assertPausedAtSourceAndLine(dbg, source.id, 7);
info("3.b Test pausing in the catch statement");
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 9);
assertPausedAtSourceAndLine(dbg, source.id, 9);
await resume(dbg);
info("4. Test skipping a caught error");
@ -63,7 +63,7 @@ add_task(async function () {
info("4.b Test pausing in the catch statement");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 9);
assertPausedAtSourceAndLine(dbg, source.id, 9);
await resume(dbg);
await togglePauseOnExceptions(dbg, true, true);
@ -71,46 +71,46 @@ add_task(async function () {
info("5. Only pause once when throwing deep in the stack");
invokeInTab("deepError");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 16);
assertPausedAtSourceAndLine(dbg, source.id, 16);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 22);
assertPausedAtSourceAndLine(dbg, source.id, 22);
await resume(dbg);
info("6. Only pause once on an exception when pausing in a finally block");
invokeInTab("deepErrorFinally");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 34);
assertPausedAtSourceAndLine(dbg, source.id, 34);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 31);
assertPausedAtSourceAndLine(dbg, source.id, 31);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 40);
assertPausedAtSourceAndLine(dbg, source.id, 40);
await resume(dbg);
info("7. Only pause once on an exception when it is rethrown from a catch");
invokeInTab("deepErrorCatch");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 53);
assertPausedAtSourceAndLine(dbg, source.id, 53);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 49);
assertPausedAtSourceAndLine(dbg, source.id, 49);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 59);
assertPausedAtSourceAndLine(dbg, source.id, 59);
await resume(dbg);
info("8. Pause on each exception thrown while unwinding");
invokeInTab("deepErrorThrowDifferent");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 71);
assertPausedAtSourceAndLine(dbg, source.id, 71);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 68);
assertPausedAtSourceAndLine(dbg, source.id, 68);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 77);
assertPausedAtSourceAndLine(dbg, source.id, 77);
await resume(dbg);
info("9. Pause in throwing new Function argument");
@ -125,7 +125,7 @@ add_task(async function () {
null,
"This new source looks like the new function one as it has no url"
);
await assertPausedAtSourceAndLine(dbg, newFunctionSource.id, 1, 0);
assertPausedAtSourceAndLine(dbg, newFunctionSource.id, 1, 0);
assertTextContentOnLine(dbg, 1, "function anonymous(f=doesntExists()");
await resume(dbg);
});

View File

@ -25,7 +25,7 @@ add_task(async function debuggerStatementOnUnload() {
await waitForPaused(dbg);
await waitForInlinePreviews(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, TEST_URL_1).id, 1, 56);
assertPausedAtSourceAndLine(dbg, findSource(dbg, TEST_URL_1).id, 1, 56);
await evaluated;
is(
@ -66,7 +66,7 @@ add_task(async function exceptionsOnUnload() {
// Cover catching exception on unload
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, TEST_URL_2).id, 2, 49);
assertPausedAtSourceAndLine(dbg, findSource(dbg, TEST_URL_2).id, 2, 49);
// But also that previous inline exceptions are still visible
await assertInlineExceptionPreview(dbg, 3, 4, {

View File

@ -15,43 +15,40 @@ add_task(async function () {
invokeInTab("testModel");
await waitForPaused(dbg, "long.js");
// Some spurious scroll may happen late related to text content *and* late fetching of symbols
await waitForScrolling(dbg);
await waitForScrolling(getCM(dbg));
ok(isScrolledPositionVisible(dbg, 66), "The paused line is visible");
const pauseScrollTop = getScrollTop(dbg);
info("1. adding a breakpoint should not scroll the editor");
await scrollEditorIntoView(dbg, 0, 0);
getCM(dbg).scrollTo(0, 0);
await addBreakpoint(dbg, longSrc, 11);
ok(isScrolledPositionVisible(dbg, 0), "scroll position");
is(getScrollTop(dbg), 0, "scroll position");
info("2. searching should jump to the match");
pressKey(dbg, "fileSearch");
type(dbg, "check");
const cm = getCM(dbg);
await waitFor(
() => getSearchSelection(dbg).text == "check",
() => cm.getSelection() == "check",
"Wait for actual selection in CodeMirror"
);
is(
getSearchSelection(dbg).line,
cm.getCursor().line,
26,
`The line of first check occurence in long.js is selected (this is ${
isCm6Enabled ? "one" : "zero"
}-based)`
"The line of first check occurence in long.js is selected (this is zero-based)"
);
// The column is the end of "check", so after 'k'
is(
getSearchSelection(dbg).column,
cm.getCursor().ch,
51,
"The column of first check occurence in long.js is selected (this is zero-based)"
);
ok(
!isScrolledPositionVisible(dbg, 66),
"The paused line is no longer visible"
);
ok(
isScrolledPositionVisible(dbg, 26),
"The line with the text match is now visible"
);
const matchScrollTop = getScrollTop(dbg);
Assert.notEqual(pauseScrollTop, matchScrollTop, "did not jump to debug line");
});
function getScrollTop(dbg) {
return getCM(dbg).doc.scrollTop;
}

View File

@ -57,7 +57,7 @@ add_task(async function () {
getSelectedSource().url.includes("simple2.js"),
"Selected source is simple2.js"
);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 5);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 5);
info("Test clicking the resume button");
await highlighterTestFront.clickPausedDebuggerOverlayButton(

View File

@ -96,7 +96,7 @@ async function reloadAndCheckNoBreakpointExists(dbg) {
info(
"Assert pause at the debugger statement in pretty.js:formatted (original source) and not the removed breakpoint"
);
await assertPausedAtSourceAndLine(dbg, sourcePretty.id, 8);
assertPausedAtSourceAndLine(dbg, sourcePretty.id, 8);
await selectSource(dbg, "pretty.js");
const source = findSource(dbg, "pretty.js");
@ -104,7 +104,7 @@ async function reloadAndCheckNoBreakpointExists(dbg) {
info(
"Assert pause at the debugger statement in pretty.js (generated source) and not the removed breakpoint"
);
await assertPausedAtSourceAndLine(dbg, source.id, 6);
assertPausedAtSourceAndLine(dbg, source.id, 6);
info(`Confirm that pretty.js:formatted does not have any breakpoints`);
is(dbg.selectors.getBreakpointCount(), 0, "Breakpoints should be cleared");

View File

@ -11,8 +11,6 @@ const PRETTY_PRINTED_FILENAME = `${TEST_FILENAME}:formatted`;
const BREAKABLE_LINE_HINT_CHAR = ``;
requestLongerTimeout(2);
// Import helpers for the inspector
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/inspector/test/shared-head.js",

View File

@ -31,11 +31,11 @@ add_task(async function () {
invokeInTab("arithmetic");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, ppSrc.id, 18);
assertPausedAtSourceAndLine(dbg, ppSrc.id, 18);
await stepOver(dbg);
await assertPausedAtSourceAndLine(dbg, ppSrc.id, 39);
assertPausedAtSourceAndLine(dbg, ppSrc.id, 39);
await resume(dbg);

View File

@ -72,44 +72,40 @@ add_task(async function () {
},
]);
info(
"Resize the editor until the content on line 6 => ` const cs2 = getComputedStyle(document.documentElement);` wraps"
);
info("Resize the editor until `myVeryLongVariableNameThatMayWrap` wraps");
// Use splitter to resize to make sure CodeMirror internal state is refreshed
// in such case (CodeMirror already handle window resize on its own).
const splitter = dbg.win.document.querySelectorAll(".splitter")[1];
const splitterOriginalX = splitter.getBoundingClientRect().left;
ok(splitter, "Got the splitter");
const lineEl = findElement(dbg, "line", 6);
const lineHeightBeforeWrap = getElementBoxQuadHeight(lineEl);
let lineHeightAfterWrap = 0;
info("Resize the editor width to one third of the size of the line element");
const lineElBoundingClientRect = lineEl.getBoundingClientRect();
let longToken = getTokenElAtLine(
dbg,
"myVeryLongVariableNameThatMayWrap",
16
);
const longTokenBoundingClientRect = longToken.getBoundingClientRect();
await resizeSplitter(
dbg,
splitter,
lineElBoundingClientRect.left + lineElBoundingClientRect.width / 3
longTokenBoundingClientRect.left + longTokenBoundingClientRect.width / 2
);
info("Wait until the line does wrap");
await waitFor(async () => {
const el = findElement(dbg, "line", 6);
lineHeightAfterWrap = getElementBoxQuadHeight(el);
return lineHeightAfterWrap > lineHeightBeforeWrap;
info("Wait until the token does wrap");
longToken = await waitFor(() => {
const token = getTokenElAtLine(
dbg,
"myVeryLongVariableNameThatMayWrap",
16
);
if (token.getBoxQuads().length === 1) {
return null;
}
return token;
});
info("Assert that the line wrapped");
const EXPECTED_LINES_TO_WRAP_OVER = 3;
is(
Math.floor(lineHeightAfterWrap),
Math.floor(lineHeightBeforeWrap * EXPECTED_LINES_TO_WRAP_OVER),
"The content on line 6 to wrap over 3 lines"
);
longToken.scrollIntoView();
info("Assert the previews still work with wrapping");
await assertPreviews(dbg, [
{
line: 16,
@ -132,6 +128,15 @@ add_task(async function () {
async function resizeSplitter(dbg, splitterEl, x) {
EventUtils.synthesizeMouse(splitterEl, 0, 0, { type: "mousedown" }, dbg.win);
// Resizing the editor should cause codeMirror to refresh
const cm = dbg.getCM();
const onEditorRefreshed = new Promise(resolve =>
cm.on("refresh", function onCmRefresh() {
cm.off("refresh", onCmRefresh);
resolve();
})
);
// Move the splitter of the secondary pane to the middle of the token,
// this should cause the token to wrap.
EventUtils.synthesizeMouseAtPoint(
@ -143,10 +148,7 @@ async function resizeSplitter(dbg, splitterEl, x) {
// Stop dragging
EventUtils.synthesizeMouseAtCenter(splitterEl, { type: "mouseup" }, dbg.win);
}
// Calculates the height of the element for the line
function getElementBoxQuadHeight(lineEl) {
const boxQ = lineEl.getBoxQuads()[0];
return boxQ.p4.y - boxQ.p1.y;
await onEditorRefreshed;
ok(true, "CodeMirror was refreshed when resizing the editor");
}

View File

@ -171,7 +171,10 @@ async function testHoveringInvalidTargetTokens(dbg) {
// Move the cursor to the top left corner to have a clean state
resetCursorPositionToTopLeftCorner(dbg);
const inlinePreviewEl = findElement(dbg, "inlinePreview");
const inlinePreviewEl = findElementWithSelector(
dbg,
".CodeMirror-code .CodeMirror-widget"
);
is(inlinePreviewEl.innerText, `myVar:"foo"`, "got expected inline preview");
const racePromise = Promise.any([
@ -258,8 +261,11 @@ async function testMovingFromATokenToAnother(dbg) {
await waitForPaused(dbg);
info("Hover token `Foo` in `Foo.#privateStatic` expression");
const fooTokenEl = await getTokenElAtLine(dbg, "Foo", 50, 44);
await scrollEditorIntoView(dbg, 49, 0);
const fooTokenEl = getTokenElAtLine(dbg, "Foo", 50, 44);
const cm = getCM(dbg);
const onScrolled = waitForScrolling(cm);
cm.scrollIntoView({ line: 49, ch: 0 }, 0);
await onScrolled;
const { element: fooPopupEl } = await tryHoverToken(dbg, fooTokenEl, "popup");
ok(!!fooPopupEl, "popup is displayed");
ok(
@ -273,12 +279,7 @@ async function testMovingFromATokenToAnother(dbg) {
info(
"Move mouse over the `#privateStatic` token in `Foo.#privateStatic` expression"
);
const privateStaticTokenEl = await getTokenElAtLine(
dbg,
"#privateStatic",
50,
48
);
const privateStaticTokenEl = getTokenElAtLine(dbg, "#privateStatic", 50, 48);
// The sequence of event to trigger the bug this is covering isn't easily reproducible
// by firing a few chosen events (because of React async rendering), so we are going to

View File

@ -16,5 +16,5 @@ add_task(async function () {
await addBreakpoint(dbg, "main.js", 3);
invokeInTab("foo");
await waitForPausedInOriginalFileAndToggleMapScopes(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "main.js").id, 3);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "main.js").id, 3);
});

View File

@ -46,7 +46,7 @@ add_task(async function () {
});
await waitForPaused(dbg, "original.js");
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 8);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 8);
// Also open the genertated source to populate the reducer for original and generated sources
await dbg.actions.jumpToMappedSelectedLocation();
await waitForSelectedSource(dbg, "bundle.js");

View File

@ -35,5 +35,5 @@ add_task(async function () {
);
await waitForPaused(dbg);
const source = findSource(dbg, "ember-application/index.js");
await assertPausedAtSourceAndLine(dbg, source.id, 4);
assertPausedAtSourceAndLine(dbg, source.id, 4);
});

View File

@ -8,7 +8,7 @@ add_task(async function () {
const dbg = await initDebugger("doc-scroll-run-to-completion.html");
invokeInTab("pauseOnce", "doc-scroll-run-to-completion.html");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-scroll-run-to-completion.html").id,
20

View File

@ -21,20 +21,18 @@ add_task(async function () {
await waitForPaused(dbg);
info("Starting a search for 'bar'");
const cm = getCM(dbg);
pressKey(dbg, "fileSearch");
is(dbg.selectors.getActiveSearch(), "file");
const el = getFocusedEl(dbg);
type(dbg, "bar");
await waitForSearchState(dbg);
await waitFor(() => {
return getSearchQuery(dbg).includes("bar");
});
is(getSearchSelection(dbg).line, 1);
info("Ensuring 'bar' matches are highlighted");
pressKey(dbg, "Enter");
is(getSearchSelection(dbg).line, 4);
is(cm.state.search.posFrom.line, 1);
pressKey(dbg, "Enter");
is(getSearchSelection(dbg).line, 1);
is(cm.state.search.posFrom.line, 4);
info("Switching files via frame click");
const frames = findAllElements(dbg, "frames");
@ -42,7 +40,8 @@ add_task(async function () {
// Ensure that the debug line is in view, and not the first "bar" instance,
// which the user would have to scroll down for
ok(isScrolledPositionVisible(dbg, 0), "First search term is not in view");
const { top } = cm.getScrollInfo();
is(top, 0, "First search term is not in view");
// Change the search term and go back to the first source in stack
info("Switching to paused file via frame click");
@ -51,16 +50,15 @@ add_task(async function () {
type(dbg, "func");
await waitForSearchState(dbg);
pressMouseDown(dbg, frames[0]);
await waitFor(() => {
return getSearchQuery(dbg).includes("func");
});
is(getSearchSelection(dbg).line, 0);
// Ensure there is a match for the new term and correct item is selected
await waitFor(() => cm.state.search.query === "func");
// Ensure there is a match for the new term
pressKey(dbg, "Enter");
await waitFor(() => getSearchSelection(dbg).line === 1);
await waitFor(() => cm.state.search.posFrom.line === 0);
is(cm.state.search.posFrom.line, 0);
pressKey(dbg, "Enter");
// There are only two items in the search so pressing enter will cycle back to the first
await waitFor(() => getSearchSelection(dbg).line === 0);
await waitFor(() => cm.state.search.posFrom.line === 1);
is(cm.state.search.posFrom.line, 1);
});
function getFocusedEl(dbg) {

View File

@ -22,6 +22,7 @@ add_task(async function () {
type(dbg, "con");
await waitForSearchState(dbg);
is(findElement(dbg, "fileSearchInput").value, "con");
is(getCM(dbg).state.search.query, "con");
// Close the search bar
pressKey(dbg, "Escape");
@ -34,5 +35,6 @@ add_task(async function () {
is(getActiveSearch(), "file");
// Test for the retained query
is(getCM(dbg).state.search.query, "con");
is(findElement(dbg, "fileSearchInput").value, "con");
});

View File

@ -38,7 +38,7 @@ add_task(async function openDebuggerFirst() {
info("Waiting for the debugger to be paused");
await waitForPaused(dbg);
const source = findSource(dbg, "doc-slow-script.html");
await assertPausedAtSourceAndLine(dbg, source.id, 14);
assertPausedAtSourceAndLine(dbg, source.id, 14);
info("Close toolbox and tab");
await dbg.toolbox.closeToolbox();
@ -93,7 +93,7 @@ add_task(async function openDebuggerFromDialog() {
info("Waiting for the debugger to be paused");
await waitForPaused(dbg);
const source = findSource(dbg, "doc-slow-script.html");
await assertPausedAtSourceAndLine(dbg, source.id, 14);
assertPausedAtSourceAndLine(dbg, source.id, 14);
info("Close toolbox and tab");
await dbg.toolbox.closeToolbox();

View File

@ -51,12 +51,7 @@ async function runSteps(dbg, source, steps) {
throw new Error("Unknown stepping type");
}
await assertPausedAtSourceAndLine(
dbg,
source.id,
position.line,
position.column
);
assertPausedAtSourceAndLine(dbg, source.id, position.line, position.column);
}
}

View File

@ -38,7 +38,7 @@ add_task(async function () {
await addBreakpoint(dbg, "non-existant-map.js", 4);
invokeInTab("runCode");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "non-existant-map.js").id,
4
@ -74,7 +74,7 @@ add_task(async function () {
await waitForPaused(dbg);
// As the original file can't be loaded, the generated source is automatically selected
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "map-with-failed-original-request.js").id,
7

View File

@ -33,14 +33,14 @@ add_task(async function () {
info("Assert paused in original-2.js as original-1.js is ignored");
const original2Source = findSource(dbg, "original-2.js");
await assertPausedAtSourceAndLine(dbg, original2Source.id, 2);
assertPausedAtSourceAndLine(dbg, original2Source.id, 2);
await resume(dbg);
await waitForPaused(dbg, null, { shouldWaitForLoadedScopes: false });
info("Assert paused in original-4.js as original-3.js is ignored");
const original4Source = findSource(dbg, "original-4.js");
await assertPausedAtSourceAndLine(dbg, original4Source.id, 2);
assertPausedAtSourceAndLine(dbg, original4Source.id, 2);
await resume(dbg);
await onReloaded;
@ -58,7 +58,7 @@ add_task(async function () {
info("Assert paused in original-1.js as it is no longer ignored");
const original1Source = findSource(dbg, "original-1.js");
await assertPausedAtSourceAndLine(dbg, original1Source.id, 2);
assertPausedAtSourceAndLine(dbg, original1Source.id, 2);
const originalSources = ["original-2.js", "original-3.js", "original-4.js"];
for (const fileName of originalSources) {
@ -66,7 +66,7 @@ add_task(async function () {
await waitForPaused(dbg, null, { shouldWaitForLoadedScopes: false });
const originalSource = findSource(dbg, fileName);
await assertPausedAtSourceAndLine(dbg, originalSource.id, 2);
assertPausedAtSourceAndLine(dbg, originalSource.id, 2);
}
await resume(dbg);

View File

@ -38,7 +38,7 @@ add_task(async function () {
invokeInTab("logMessage");
await waitForPausedInOriginalFileAndToggleMapScopes(dbg);
await assertPausedAtSourceAndLine(dbg, mainSrc.id, 4, 3);
assertPausedAtSourceAndLine(dbg, mainSrc.id, 4, 3);
// Tests the existence of the sourcemap link in the original source.
ok(findElement(dbg, "mappedSourceLink"), "Sourcemap link in original source");

View File

@ -32,7 +32,7 @@ add_task(async function () {
await waitForDispatch(dbg.store, "LOAD_ORIGINAL_SOURCE_TEXT");
await waitForPausedInOriginalFileAndToggleMapScopes(dbg, "entry.js");
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "entry.js").id, 5);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "entry.js").id, 5);
await waitForBreakpointCount(dbg, 2);
is(getBreakpointCount(), 2, "Two breakpoints exist");

View File

@ -78,16 +78,16 @@ add_task(async function () {
invokeInTab("keepMeAlive");
await waitForPausedInOriginalFileAndToggleMapScopes(dbg);
await assertPausedAtSourceAndLine(dbg, entrySrc.id, 15);
assertPausedAtSourceAndLine(dbg, entrySrc.id, 15);
await stepIn(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "times2.js").id, 2);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "times2.js").id, 2);
await stepOver(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "times2.js").id, 3);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "times2.js").id, 3);
await stepOut(dbg);
await assertPausedAtSourceAndLine(dbg, entrySrc.id, 16);
assertPausedAtSourceAndLine(dbg, entrySrc.id, 16);
pendingSelectedLocation = Services.prefs.getStringPref(
"devtools.debugger.pending-selected-location"
@ -127,7 +127,7 @@ add_task(async function () {
mappedSourceLink.click();
await waitForSelectedSource(dbg, bundleSrc);
await assertPausedAtSourceAndLine(dbg, bundleSrc.id, 62);
assertPausedAtSourceAndLine(dbg, bundleSrc.id, 62);
// The mapped source link is computed asynchronously when we are on the bundle
mappedSourceLink = await waitFor(() => findElement(dbg, "mappedSourceLink"));
mappedSourceLink = findElement(dbg, "mappedSourceLink");

View File

@ -38,7 +38,7 @@ add_task(async function () {
invokeInTab("logMessage");
await waitForPausedInOriginalFileAndToggleMapScopes(dbg);
await assertPausedAtSourceAndLine(dbg, mainSrc.id, 4);
assertPausedAtSourceAndLine(dbg, mainSrc.id, 4);
// Tests the existence of the sourcemap link in the original source.
let sourceMapLink = findElement(dbg, "mappedSourceLink");

View File

@ -37,7 +37,7 @@ add_task(async function () {
invokeInTab("test");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, sortedSrc.id, 9, 5);
assertPausedAtSourceAndLine(dbg, sortedSrc.id, 9, 5);
is(getScopeNodeLabel(dbg, 1), "Block");
is(getScopeNodeLabel(dbg, 2), "na");

View File

@ -26,7 +26,7 @@ add_task(async function () {
// Navigation should clear the stepping state
const reloaded = reload(dbg, "simple2.js");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "long.js").id, 1);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "long.js").id, 1);
await resume(dbg);
await reloaded;

View File

@ -15,7 +15,7 @@ add_task(async function test() {
await stepOver(dbg);
await stepIn(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-step-in-uninitialized.html").id,
8
@ -28,7 +28,7 @@ add_task(async function test() {
await stepOver(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-step-in-uninitialized.html").id,
9

View File

@ -19,11 +19,7 @@ add_task(async function test() {
// to the related original file. The debugger fallbacks to the generated source,
// but that highlights a bug in the example page.
await waitForPaused(dbg, "bundle.js");
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "bundle.js").id,
52411
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "bundle.js").id, 52411);
await stepIn(dbg);
@ -48,9 +44,5 @@ add_task(async function test() {
// Note that we are asserting against an original source here,
// See earlier comment about paused in bundle.js
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "step-in-test.js").id,
7679
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "step-in-test.js").id, 7679);
});

View File

@ -10,12 +10,10 @@ add_task(async function () {
const dbg = await initDebugger("doc-scripts.html", "long.js");
await selectSource(dbg, "long.js");
await scrollEditorIntoView(dbg, 20, 0);
ok(isScrolledPositionVisible(dbg, 20), "Editor is scrolled");
getCM(dbg).scrollTo(0, 284);
pressKey(dbg, "inspector");
pressKey(dbg, "debugger");
ok(isScrolledPositionVisible(dbg, 20), "Editor is still scrolled");
is(getCM(dbg).getScrollInfo().top, 284);
});

View File

@ -33,7 +33,7 @@ add_task(async function () {
const dbg = await assertDebuggerIsHighlightedAndPaused(toolbox);
const source = findSource(dbg, "doc-debugger-statements.html");
await assertPausedAtSourceAndLine(dbg, source.id, 16);
assertPausedAtSourceAndLine(dbg, source.id, 16);
await resume(dbg);
info("Wait for the paused code to complete after resume");
@ -58,7 +58,7 @@ add_task(async function () {
const dbg = await assertDebuggerIsHighlightedAndPaused(toolbox);
const source = findSource(dbg, IFRAME_TEST_COM_URI);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
await resume(dbg);
info("Wait for the paused code to complete after resume");
@ -107,11 +107,11 @@ add_task(async function () {
);
}
const source = findSource(dbg, IFRAME_TEST_COM_URI);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
info("Step over to the next line");
await stepOver(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 3);
assertPausedAtSourceAndLine(dbg, source.id, 3);
info("Now execute a debugger statement in the top level target");
const onPaused = waitForPausedThread(dbg, topLevelThread);
@ -144,7 +144,7 @@ add_task(async function () {
"The new paused state refers to the latest breakpoint being hit, on the top level target"
);
const source2 = findSource(dbg, IFRAME_TEST_URI);
await assertPausedAtSourceAndLine(dbg, source2.id, 2);
assertPausedAtSourceAndLine(dbg, source2.id, 2);
info("Resume the top level target");
await resume(dbg);
@ -167,7 +167,7 @@ add_task(async function () {
dbg.actions.selectThread(iframeThread);
await waitForPausedThread(dbg, iframeThread);
await waitForSelectedSource(dbg, source);
await assertPausedAtSourceAndLine(dbg, source.id, 3);
assertPausedAtSourceAndLine(dbg, source.id, 3);
info("Resume the iframe target");
await resume(dbg);

View File

@ -33,7 +33,7 @@ add_task(async function () {
await resume(dbg);
await waitForPaused(dbg);
await waitForState(dbg, () => dbg.selectors.getSelectedInlinePreviews());
await assertPausedAtSourceAndLine(dbg, sourceId, 17);
assertPausedAtSourceAndLine(dbg, sourceId, 17);
is(await getScopeNodeValue(dbg, 5), "3");
const whyPaused = await waitFor(
() => dbg.win.document.querySelector(".why-paused")?.innerText
@ -43,7 +43,7 @@ add_task(async function () {
info("Resume and wait to pause at the access to b in the first `obj.b;`");
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, sourceId, 19);
assertPausedAtSourceAndLine(dbg, sourceId, 19);
info("Remove the get watchpoint on b");
const removedWatchpoint1 = waitForDispatch(dbg.store, "REMOVE_WATCHPOINT");
@ -57,12 +57,12 @@ add_task(async function () {
);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, sourceId, 21);
assertPausedAtSourceAndLine(dbg, sourceId, 21);
info("Resume and pause on the debugger statement in getB");
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, sourceId, 5);
assertPausedAtSourceAndLine(dbg, sourceId, 5);
info("Add a get watchpoint to b");
await toggleScopeNode(dbg, 4);
@ -78,13 +78,13 @@ add_task(async function () {
info("Resume and wait to pause at the access to b in getB");
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, sourceId, 6);
assertPausedAtSourceAndLine(dbg, sourceId, 6);
info("Resume and pause on the debugger statement");
await waitForRequestsToSettle(dbg);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, sourceId, 24);
assertPausedAtSourceAndLine(dbg, sourceId, 24);
info("Remove the get watchpoint on b");
const removedWatchpoint2 = waitForDispatch(dbg.store, "REMOVE_WATCHPOINT");
@ -108,7 +108,7 @@ add_task(async function () {
info("Resume and wait to pause on the final `obj.b;`");
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, sourceId, 25);
assertPausedAtSourceAndLine(dbg, sourceId, 25);
info("Do a last resume to finalize the document load");
await resume(dbg);

View File

@ -25,7 +25,7 @@ add_task(async function () {
invokeInTab("fetchFromWorker");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
await assertPreviews(dbg, [
{
@ -42,7 +42,7 @@ add_task(async function () {
await reload(dbg, "service-worker.sjs");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
await assertPreviews(dbg, [
{

View File

@ -29,7 +29,7 @@ add_task(async function () {
invokeInTab("fetchFromWorker");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
// Leave the breakpoint and worker in place for the next subtest.
await resume(dbg);
await waitForRequestsToSettle(dbg);
@ -54,7 +54,7 @@ add_task(async function () {
const workerSource = await waitForSource(dbg, "service-worker.sjs");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
await checkAdditionalThreadCount(dbg, 1);
await resume(dbg);
@ -142,19 +142,19 @@ add_task(async function () {
await waitForBreakpointCount(dbg, 1);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource.id, 2);
assertPausedAtSourceAndLine(dbg, workerSource.id, 2);
await checkWorkerStatus(dbg, "parsed");
await addBreakpoint(dbg, "service-worker.sjs", 19);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource.id, 19);
assertPausedAtSourceAndLine(dbg, workerSource.id, 19);
await checkWorkerStatus(dbg, "installing");
await addBreakpoint(dbg, "service-worker.sjs", 5);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource.id, 5);
assertPausedAtSourceAndLine(dbg, workerSource.id, 5);
await checkWorkerStatus(dbg, "activating");
await resume(dbg);

View File

@ -21,7 +21,7 @@ add_task(async function () {
await waitForPaused(dbg, "simple-worker.js");
// We should be paused at the first line of simple-worker.js
await assertPausedAtSourceAndLine(dbg, workerSource.id, 1);
assertPausedAtSourceAndLine(dbg, workerSource.id, 1);
// We have to remove the first breakpoint, set on the first worker.
// All the workers use the same source.
// The first worker is loaded on the html page load.
@ -35,6 +35,6 @@ add_task(async function () {
await waitForPaused(dbg, "simple-worker.js");
// We should be paused in the message listener in simple-worker.js
await assertPausedAtSourceAndLine(dbg, workerSource.id, 10);
assertPausedAtSourceAndLine(dbg, workerSource.id, 10);
await removeBreakpoint(dbg, workerSource.id, 10, 3);
});

View File

@ -28,7 +28,7 @@ add_task(async function () {
assertNotPaused(dbg);
await dbg.actions.breakOnNext();
await waitForPaused(dbg, "doc-windowless-workers.html");
await assertPausedAtSourceAndLine(dbg, mainThreadSource.id, 10);
assertPausedAtSourceAndLine(dbg, mainThreadSource.id, 10);
threadIsSelected(dbg, 1);
info("Pause in the first worker");
@ -38,7 +38,7 @@ add_task(async function () {
await waitForPaused(dbg, "simple-worker.js");
threadIsSelected(dbg, 2);
const workerSource2 = dbg.selectors.getSelectedSource();
await assertPausedAtSourceAndLine(dbg, workerSource2.id, 3);
assertPausedAtSourceAndLine(dbg, workerSource2.id, 3);
info("Add a watch expression and view the value");
await addExpression(dbg, "count");
@ -48,7 +48,7 @@ add_task(async function () {
info("StepOver in the first worker");
await stepOver(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource2.id, 4);
assertPausedAtSourceAndLine(dbg, workerSource2.id, 4);
info("Ensure that the watch expression has updated");
await waitUntil(() => {
@ -63,7 +63,7 @@ add_task(async function () {
info("StepOver in the main thread");
dbg.actions.selectThread(mainThread);
await stepOver(dbg);
await assertPausedAtSourceAndLine(dbg, mainThreadSource.id, 11);
assertPausedAtSourceAndLine(dbg, mainThreadSource.id, 11);
info("Resume in the mainThread");
await resume(dbg);
@ -84,7 +84,7 @@ add_task(async function () {
info("View the first paused thread");
dbg.actions.selectThread(thread1);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource2.id, 10);
assertPausedAtSourceAndLine(dbg, workerSource2.id, 10);
info("View the second paused thread");
await dbg.actions.selectThread(thread2);
@ -96,13 +96,13 @@ add_task(async function () {
workerSource3,
"The selected source is the same as we have one source per URL"
);
await assertPausedAtSourceAndLine(dbg, workerSource3.id, 10);
assertPausedAtSourceAndLine(dbg, workerSource3.id, 10);
info("StepOver in second worker and not the first");
await stepOver(dbg);
await assertPausedAtSourceAndLine(dbg, workerSource3.id, 11);
assertPausedAtSourceAndLine(dbg, workerSource3.id, 11);
await dbg.actions.selectThread(thread1);
await assertPausedAtSourceAndLine(dbg, workerSource2.id, 10);
assertPausedAtSourceAndLine(dbg, workerSource2.id, 10);
info("Resume both worker execution");
await resume(dbg);

View File

@ -17,10 +17,10 @@ add_task(async function () {
info("Test pause on exceptions on worker load");
await waitForPaused(dbg);
const source = findSource(dbg, "worker-exception.js");
await assertPausedAtSourceAndLine(dbg, source.id, 4);
assertPausedAtSourceAndLine(dbg, source.id, 4);
await resume(dbg);
info("Test pause on exceptions on worker postMessage ");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
});

View File

@ -19,7 +19,7 @@ add_task(async function () {
await removeBreakpointViaGutter(dbg, 11);
// We should be paused at the first line of simple-worker.js
const workerSource2 = dbg.selectors.getSelectedSource();
await assertPausedAtSourceAndLine(dbg, workerSource2.id, 11);
assertPausedAtSourceAndLine(dbg, workerSource2.id, 11);
await toggleNode(dbg, "var_array");
Assert.equal(findNodeValue(dbg, "0"), '"mango"', "array elem0");

View File

@ -24,7 +24,7 @@ add_task(async function () {
);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-early-xhr.html").id,
10
@ -65,7 +65,7 @@ add_task(async function () {
invokeInTab("main", "doc-xhr.html");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(dbg, findSource(dbg, "fetch.js").id, 4);
assertPausedAtSourceAndLine(dbg, findSource(dbg, "fetch.js").id, 4);
await resume(dbg);
await dbg.actions.removeXHRBreakpoint(0);

View File

@ -11,7 +11,7 @@ add_task(async function () {
invokeInTab("singleRequest", "doc-xhr-run-to-completion.html");
await waitForPaused(dbg);
await waitForSelectedLocation(dbg, 23);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-xhr-run-to-completion.html").id,
23
@ -29,21 +29,21 @@ add_task(async function () {
const dbg = await initDebugger("doc-xhr-run-to-completion.html");
invokeInTab("multipleRequests", "doc-xhr-run-to-completion.html");
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-xhr-run-to-completion.html").id,
31
);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-xhr-run-to-completion.html").id,
33
);
await resume(dbg);
await waitForPaused(dbg);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "doc-xhr-run-to-completion.html").id,
34

View File

@ -236,12 +236,7 @@ async function assertBreakableLines(
`We show the expected number of lines in CodeMirror for ${source}`
);
for (let line = 1; line <= numberOfLines; line++) {
await assertLineIsBreakable(
dbg,
source,
line,
breakableLines.includes(line)
);
assertLineIsBreakable(dbg, source, line, breakableLines.includes(line));
}
}

View File

@ -36,7 +36,7 @@ addIntegrationTask(async function testReloadingRemovedOriginalSources(
invokeInTab("removedOriginal");
await waitForPaused(dbg);
const replacedSource = findSource(dbg, "removed-original.js");
await assertPausedAtSourceAndLine(dbg, replacedSource.id, 4);
assertPausedAtSourceAndLine(dbg, replacedSource.id, 4);
assertTextContentOnLine(dbg, 4, 'console.log("Removed original");');
await assertBreakpoint(dbg, 4);
@ -77,7 +77,7 @@ addIntegrationTask(async function testReloadingRemovedOriginalSources(
// and the UI updates itself to mention the new original file.
await waitForPaused(dbg);
const newSource = findSource(dbg, "new-original.js");
await assertPausedAtSourceAndLine(dbg, newSource.id, 4);
assertPausedAtSourceAndLine(dbg, newSource.id, 4);
assertTextContentOnLine(dbg, 4, 'console.log("New original");');
await assertBreakpoint(dbg, 4);

View File

@ -100,7 +100,7 @@ addIntegrationTask(async function testReloadingChangedGeneratedSource(
// early, therefore is pauses at the old position, where no breakpoint is
// displayed in the UI
info("Assert that the breakpoint paused in the other original file");
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "another-original.js").id,
5
@ -110,7 +110,7 @@ addIntegrationTask(async function testReloadingChangedGeneratedSource(
info("Switch to generated source and assert that the location is correct");
await dbg.actions.jumpToMappedSelectedLocation();
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "bundle-with-another-original.js").id,
82
@ -126,7 +126,7 @@ addIntegrationTask(async function testReloadingChangedGeneratedSource(
info(
"Check that the breakpoint is displayed and paused on the correct line"
);
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "original-with-no-update.js").id,
6
@ -150,12 +150,12 @@ addIntegrationTask(async function testReloadingChangedGeneratedSource(
await selectSource(dbg, "bundle-with-another-original.js");
// This scrolls the line into view so the content
// on the line is rendered and avaliable for dom querying.
await scrollEditorIntoView(dbg, 103, 0);
getCM(dbg).scrollIntoView({ line: 103, ch: 0 });
if (isCompressed) {
await assertBreakpoint(dbg, 1);
} else {
await assertPausedAtSourceAndLine(
assertPausedAtSourceAndLine(
dbg,
findSource(dbg, "bundle-with-another-original.js").id,
103

View File

@ -307,18 +307,21 @@ function getVisibleSelectedFrameColumn(dbg) {
* Assert that a given line is breakable or not.
* Verify that CodeMirror gutter is grayed out via the empty line classname if not breakable.
*/
async function assertLineIsBreakable(dbg, file, line, shouldBeBreakable) {
const el = await getNodeAtEditorGutterLine(dbg, line);
const lineText = `${line}| ${el.innerText.substring(0, 50)}${
el.innerText.length > 50 ? "…" : ""
function assertLineIsBreakable(dbg, file, line, shouldBeBreakable) {
const lineInfo = getCM(dbg).lineInfo(line - 1);
const lineText = `${line}| ${lineInfo.text.substring(0, 50)}${
lineInfo.text.length > 50 ? "…" : ""
} in ${file}`;
// When a line is not breakable, the "empty-line" class is added
// and the line is greyed out
if (shouldBeBreakable) {
ok(!el.classList.contains("empty-line"), `${lineText} should be breakable`);
ok(
!lineInfo.wrapClass?.includes("empty-line"),
`${lineText} should be breakable`
);
} else {
ok(
el.classList.contains("empty-line"),
lineInfo?.wrapClass?.includes("empty-line"),
`${lineText} should NOT be breakable`
);
}
@ -355,7 +358,8 @@ function assertHighlightLocation(dbg, source, line) {
ok(isVisibleInEditor(dbg, lineEl), "Highlighted line is visible");
const lineInfo = getCMEditor(dbg).lineInfo(isCm6Enabled ? line : line - 1);
const cm = getCM(dbg);
const lineInfo = cm.lineInfo(line - 1);
ok(lineInfo.wrapClass.includes("highlight-line"), "Line is highlighted");
}
@ -364,7 +368,7 @@ function assertHighlightLocation(dbg, source, line) {
*
* Assert that CodeMirror reports to be paused at the given line/column.
*/
async function _assertDebugLine(dbg, line, column) {
function _assertDebugLine(dbg, line, column) {
const source = dbg.selectors.getSelectedSource();
// WASM lines are hex addresses which have to be mapped to decimal line number
if (isWasmBinarySource(source)) {
@ -372,9 +376,7 @@ async function _assertDebugLine(dbg, line, column) {
}
// Check the debug line
// cm6 lines are 1-based, while cm5 are 0-based, to keep compatibility with
// .lineInfo usage in other locations.
const lineInfo = getCMEditor(dbg).lineInfo(isCm6Enabled ? line : line - 1);
const lineInfo = getCM(dbg).lineInfo(line - 1);
const sourceTextContent = dbg.selectors.getSelectedSourceTextContent();
if (source && !sourceTextContent) {
const url = source.url;
@ -387,7 +389,7 @@ async function _assertDebugLine(dbg, line, column) {
// Scroll the line into view to make sure the content
// on the line is rendered and in the dom.
await scrollEditorIntoView(dbg, line, 0);
getCM(dbg).scrollIntoView({ line, ch: 0 });
if (!lineInfo.wrapClass) {
const pauseLine = getVisibleSelectedFrameLine(dbg);
@ -429,6 +431,20 @@ async function _assertDebugLine(dbg, line, column) {
}
info(`Paused on line ${line}`);
}
/**
* Asserts the log point set
*/
async function assertEditorLogpoint(dbg, line, { hasLog = false } = {}) {
const el = await getEditorLineGutter(dbg, line);
const hasLogClass = isCm6Enabled
? !!el.querySelector(".has-log")
: el.classList.contains("has-log");
Assert.strictEqual(
hasLogClass,
hasLog,
`Breakpoint log ${hasLog ? "exists" : "does not exist"} on line ${line}`
);
}
/**
* Make sure the debugger is paused at a certain source ID and line.
@ -438,7 +454,7 @@ async function _assertDebugLine(dbg, line, column) {
* @param {Number} expectedLine
* @param {Number} [expectedColumn]
*/
async function assertPausedAtSourceAndLine(
function assertPausedAtSourceAndLine(
dbg,
expectedSourceId,
expectedLine,
@ -467,7 +483,7 @@ async function assertPausedAtSourceAndLine(
"Redux state for currently selected frame's column is correct"
);
}
await _assertDebugLine(dbg, pauseLine, pauseColumn);
_assertDebugLine(dbg, pauseLine, pauseColumn);
ok(isVisibleInEditor(dbg, findElement(dbg, "gutters")), "gutter is visible");
@ -1187,12 +1203,7 @@ async function invokeWithBreakpoint(
return;
}
await assertPausedAtSourceAndLine(
dbg,
findSource(dbg, filename).id,
line,
column
);
assertPausedAtSourceAndLine(dbg, findSource(dbg, filename).id, line, column);
await removeBreakpoint(dbg, source.id, line, column);
@ -1526,69 +1537,6 @@ async function getEditorLineGutter(dbg, line) {
return el;
}
// Handles virtualization scenarios
async function scrollAndGetEditorLineGutterElement(dbg, line) {
await scrollEditorIntoView(dbg, isCm6Enabled ? line : line - 1, 0);
const els = findAllElementsWithSelector(
dbg,
isCm6Enabled
? ".cm-gutter.cm-lineNumbers .cm-gutterElement"
: ".CodeMirror-code .CodeMirror-linenumber"
);
return [...els].find(el => el.innerText == line);
}
/**
* Gets node at a specific line in the editor
* @param {*} dbg
* @param {Number} line
* @returns {Element} DOM Element
*/
async function getNodeAtEditorLine(dbg, line) {
if (isCm6Enabled) {
// To handle virtualized lines accurately, lets use the
// cm6 utility here.
await scrollEditorIntoView(dbg, line, 0);
return getCMEditor(dbg).getElementAtLine(line);
}
return getEditorLineGutter(dbg, line);
}
/**
* Gets node at a specific line in the gutter
* @param {*} dbg
* @param {Number} line
* @returns {Element} DOM Element
*/
async function getNodeAtEditorGutterLine(dbg, line) {
if (isCm6Enabled) {
return scrollAndGetEditorLineGutterElement(dbg, line);
}
return getEditorLineGutter(dbg, line);
}
async function getConditionalPanelAtLine(dbg, line) {
info(`Get conditional panel at line ${line}`);
let el = await getNodeAtEditorLine(dbg, line);
if (isCm6Enabled) {
// In CM6 the conditional panel for a specific line
// is injected in a sibling node just after.
el = el.nextSibling;
}
return el.querySelector(".conditional-breakpoint-panel");
}
async function waitForConditionalPanelFocus(dbg) {
if (isCm6Enabled) {
return waitFor(
() =>
dbg.win.document.activeElement.classList.contains("cm-content") &&
dbg.win.document.activeElement.closest(".conditional-breakpoint-panel")
);
}
return waitFor(() => dbg.win.document.activeElement.tagName === "TEXTAREA");
}
/**
* Opens the debugger editor context menu in either codemirror or the
* the debugger gutter.
@ -1609,19 +1557,18 @@ async function openContextMenuInDebugger(dbg, elementName, line) {
* Select a range of lines in the editor and open the contextmenu
* @param {Object} dbg
* @param {Object} lines
* @param {String} elementName
* @returns
*/
async function selectEditorLinesAndOpenContextMenu(
dbg,
lines,
elementName = "line"
) {
async function selectEditorLinesAndOpenContextMenu(dbg, lines) {
const { startLine, endLine } = lines;
const elementName = "line";
if (!endLine) {
await clickElement(dbg, elementName, startLine);
} else {
setSelection(dbg, startLine, endLine);
getCM(dbg).setSelection(
{ line: startLine - 1, ch: 0 },
{ line: endLine, ch: 0 }
);
}
return openContextMenuInDebugger(dbg, elementName, startLine);
}
@ -1637,18 +1584,19 @@ async function selectEditorLinesAndOpenContextMenu(
* hasBlackboxedLinesClass
* If `true` assert that style exist, else assert that style does not exist
*/
async function assertIgnoredStyleInSourceLines(
function assertIgnoredStyleInSourceLines(
dbg,
{ lines, hasBlackboxedLinesClass }
) {
if (lines) {
let currentLine = lines[0];
do {
const element = await getNodeAtEditorLine(dbg, currentLine);
const hasStyle = element.classList.contains("blackboxed-line");
is(
const element = findElement(dbg, "line", currentLine);
const hasStyle = hasBlackboxedLinesClass
? element.parentNode.classList.contains("blackboxed-line")
: !element.parentNode.classList.contains("blackboxed-line");
ok(
hasStyle,
hasBlackboxedLinesClass,
`Line ${currentLine} ${
hasBlackboxedLinesClass ? "does not have" : "has"
} ignored styling`
@ -1656,8 +1604,14 @@ async function assertIgnoredStyleInSourceLines(
currentLine = currentLine + 1;
} while (currentLine <= lines[1]);
} else {
const codeLines = findAllElements(dbg, "codeLines");
const blackboxedLines = findAllElements(dbg, "blackboxedLines");
const codeLines = findAllElementsWithSelector(
dbg,
".CodeMirror-code .CodeMirror-line"
);
const blackboxedLines = findAllElementsWithSelector(
dbg,
".CodeMirror-code .blackboxed-line"
);
is(
hasBlackboxedLinesClass ? codeLines.length : 0,
blackboxedLines.length,
@ -1675,7 +1629,7 @@ async function assertIgnoredStyleInSourceLines(
* @param {String} expectedTextContent
*/
function assertTextContentOnLine(dbg, line, expectedTextContent) {
const lineInfo = getCMEditor(dbg).lineInfo(isCm6Enabled ? line : line - 1);
const lineInfo = getCM(dbg).lineInfo(line - 1);
const textContent = lineInfo.text.trim();
is(textContent, expectedTextContent, `Expected text content on line ${line}`);
}
@ -1690,11 +1644,9 @@ function assertTextContentOnLine(dbg, line, expectedTextContent) {
* @static
*/
async function assertNoBreakpoint(dbg, line) {
const el = await getNodeAtEditorGutterLine(dbg, line);
const el = await getEditorLineGutter(dbg, line);
const exists = el.classList.contains(
isCm6Enabled ? "cm6-gutter-breakpoint" : "new-breakpioint"
);
const exists = !!el.querySelector(".new-breakpoint");
ok(!exists, `Breakpoint doesn't exists on line ${line}`);
}
@ -1708,21 +1660,20 @@ async function assertNoBreakpoint(dbg, line) {
* @static
*/
async function assertBreakpoint(dbg, line) {
let el = await getNodeAtEditorGutterLine(dbg, line);
el = isCm6Enabled ? el.firstChild : el;
const el = await getEditorLineGutter(dbg, line);
ok(
el.classList.contains(selectors.gutterBreakpoint),
`Breakpoint exists on line ${line}`
);
const exists = !!el.querySelector(".new-breakpoint");
ok(exists, `Breakpoint exists on line ${line}`);
const hasConditionClass = el.classList.contains("has-condition");
ok(
!hasConditionClass,
`Regular breakpoint doesn't have condition on line ${line}`
);
const hasLogClass = el.classList.contains("has-log");
ok(!hasLogClass, `Regular breakpoint doesn't have log on line ${line}`);
}
@ -1735,18 +1686,17 @@ async function assertBreakpoint(dbg, line) {
* @static
*/
async function assertConditionBreakpoint(dbg, line) {
let el = await getNodeAtEditorGutterLine(dbg, line);
el = isCm6Enabled ? el.firstChild : el;
const el = await getEditorLineGutter(dbg, line);
ok(
el.classList.contains(selectors.gutterBreakpoint),
`Breakpoint exists on line ${line}`
);
const exists = !!el.querySelector(".new-breakpoint");
ok(exists, `Breakpoint exists on line ${line}`);
const hasConditionClass = el.classList.contains("has-condition");
ok(hasConditionClass, `Conditional breakpoint on line ${line}`);
const hasLogClass = el.classList.contains("has-log");
ok(
!hasLogClass,
`Conditional breakpoint doesn't have log breakpoint on line ${line}`
@ -1762,21 +1712,20 @@ async function assertConditionBreakpoint(dbg, line) {
* @static
*/
async function assertLogBreakpoint(dbg, line) {
let el = await getNodeAtEditorGutterLine(dbg, line);
el = isCm6Enabled ? el.firstChild : el;
const el = await getEditorLineGutter(dbg, line);
ok(
el.classList.contains(selectors.gutterBreakpoint),
`Breakpoint exists on line ${line}`
);
const exists = !!el.querySelector(".new-breakpoint");
ok(exists, `Breakpoint exists on line ${line}`);
const hasConditionClass = el.classList.contains("has-condition");
ok(
!hasConditionClass,
`Log breakpoint doesn't have condition on line ${line}`
);
const hasLogClass = el.classList.contains("has-log");
ok(hasLogClass, `Log breakpoint on line ${line}`);
}
@ -1815,12 +1764,6 @@ const selectors = {
removeOthers: "#node-menu-delete-other",
removeCondition: "#node-menu-remove-condition",
},
blackboxedLines: isCm6Enabled
? ".cm-content > .blackboxed-line"
: ".CodeMirror-code .blackboxed-line",
codeLines: isCm6Enabled
? ".cm-content > .cm-line"
: ".CodeMirror-code .CodeMirror-line",
editorContextMenu: {
continueToHere: "#node-menu-continue-to-here",
},
@ -1833,17 +1776,13 @@ const selectors = {
mapScopesCheckbox: ".map-scopes-header input",
frame: i => `.frames [role="list"] [role="listitem"]:nth-child(${i})`,
frames: '.frames [role="list"] [role="listitem"]',
gutterBreakpoint: isCm6Enabled ? "breakpoint-marker" : "new-breakpoint",
// This is used to trigger events (click etc) on the gutter
gutterElement: i =>
isCm6Enabled
? `.cm-gutter.cm-lineNumbers .cm-gutterElement:nth-child(${i + 1})`
: `.CodeMirror-code *:nth-child(${i}) .CodeMirror-linenumber`,
gutters: isCm6Enabled ? `.cm-gutters` : `.CodeMirror-gutters`,
line: i =>
isCm6Enabled
? `.cm-content > div.cm-line:nth-child(${i})`
: `.CodeMirror-code div:nth-child(${i}) .CodeMirror-line`,
line: i => `.CodeMirror-code div:nth-child(${i}) .CodeMirror-line`,
addConditionItem:
"#node-menu-add-condition, #node-menu-add-conditional-breakpoint",
editConditionItem:
@ -1851,15 +1790,11 @@ const selectors = {
addLogItem: "#node-menu-add-log-point",
editLogItem: "#node-menu-edit-log-point",
disableItem: "#node-menu-disable-breakpoint",
breakpoint: isCm6Enabled
? ".cm-gutter > .cm6-gutter-breakpoint"
: ".CodeMirror-code > .new-breakpoint",
highlightLine: isCm6Enabled
? ".cm-content > .highlight-line"
: ".CodeMirror-code > .highlight-line",
breakpoint: ".CodeMirror-code > .new-breakpoint",
highlightLine: ".CodeMirror-code > .highlight-line",
debugLine: ".new-debug-line",
debugErrorLine: ".new-debug-line-error",
codeMirror: isCm6Enabled ? ".cm-editor" : ".CodeMirror",
codeMirror: ".CodeMirror",
resume: ".resume.active",
pause: ".pause.active",
sourceTabs: ".source-tabs",
@ -1887,12 +1822,8 @@ const selectors = {
`.outline-list__element:nth-child(${i}) .function-signature`,
outlineItems: ".outline-list__element",
conditionalPanel: ".conditional-breakpoint-panel",
conditionalPanelInput: `.conditional-breakpoint-panel ${
isCm6Enabled ? ".cm-content" : "textarea"
}`,
logPanelInput: `.conditional-breakpoint-panel.log-point ${
isCm6Enabled ? ".cm-content" : "textarea"
}`,
conditionalPanelInput: ".conditional-breakpoint-panel textarea",
logPanelInput: ".conditional-breakpoint-panel.log-point textarea",
conditionalBreakpointInSecPane: ".breakpoint.is-conditional",
logPointPanel: ".conditional-breakpoint-panel.log-point",
logPointInSecPane: ".breakpoint.is-log",
@ -1912,11 +1843,7 @@ const selectors = {
threadsPaneItems: ".threads-pane .thread",
threadsPaneItem: i => `.threads-pane .thread:nth-child(${i})`,
threadsPaneItemPause: i => `${selectors.threadsPaneItem(i)}.paused`,
CodeMirrorLines: isCm6Enabled ? ".cm-content" : ".CodeMirror-lines",
CodeMirrorCode: isCm6Enabled ? ".cm-content" : ".CodeMirror-code",
inlinePreview: isCm6Enabled
? ".cm-content .inline-preview"
: ".CodeMirror-code .CodeMirror-widget",
CodeMirrorLines: ".CodeMirror-lines",
inlinePreviewLabels: ".inline-preview .inline-preview-label",
inlinePreviewValues: ".inline-preview .inline-preview-value",
inlinePreviewOpenInspector: ".inline-preview-value button.open-inspector",
@ -2027,10 +1954,12 @@ function shiftClickElement(dbg, elementName, ...args) {
function rightClickElement(dbg, elementName, ...args) {
const selector = getSelector(elementName, ...args);
return rightClickEl(dbg, dbg.win.document.querySelector(selector));
const doc = dbg.win.document;
return rightClickEl(dbg, doc.querySelector(selector));
}
function rightClickEl(dbg, el) {
const doc = dbg.win.document;
el.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(el, { type: "contextmenu" }, dbg.win);
}
@ -2048,16 +1977,12 @@ async function clearElement(dbg, elementName) {
}
async function clickGutter(dbg, line) {
const el = await (isCm6Enabled
? scrollAndGetEditorLineGutterElement(dbg, line)
: codeMirrorGutterElement(dbg, line));
const el = await codeMirrorGutterElement(dbg, line);
clickDOMElement(dbg, el);
}
async function cmdClickGutter(dbg, line) {
const el = await (isCm6Enabled
? scrollAndGetEditorLineGutterElement(dbg, line)
: codeMirrorGutterElement(dbg, line));
const el = await codeMirrorGutterElement(dbg, line);
clickDOMElement(dbg, el, cmdOrCtrl);
}
@ -2146,11 +2071,6 @@ async function typeInPanel(dbg, text, inLogPanel = false) {
// Position cursor reliably at the end of the text.
pressKey(dbg, "End");
type(dbg, text);
// Wait for any possible CM6 scroll actions in the conditional panel editor
// to complete
if (isCm6Enabled) {
await wait(1000);
}
pressKey(dbg, "Enter");
}
@ -2261,83 +2181,41 @@ function getEditorContent(dbg) {
* @returns
*/
function setEditorCursorAt(dbg, line, column) {
scrollEditorIntoView(dbg, line, 0);
return getCMEditor(dbg).setCursorAt(line, column);
}
/**
* Scrolls a specific line and column into view in the editor
*
* @param {*} dbg
* @param {Number} line
* @param {Number} column
* @returns
*/
async function scrollEditorIntoView(dbg, line, column) {
const onScrolled = waitForScrolling(dbg);
line = isCm6Enabled ? line + 1 : line;
getCMEditor(dbg).scrollTo(line, column);
// Ensure the line is visible with margin because the bar at the bottom of
// the editor overlaps into what the editor thinks is its own space, blocking
// the click event below.
return onScrolled;
}
// Gets the current codeMirror instance for CM5 tests
function getCM(dbg) {
const el = dbg.win.document.querySelector(".CodeMirror");
return el.CodeMirror;
}
/**
* Wrapper around source editor api to check if a scrolled position is visible
*
* @param {*} dbg
* @param {Number} line
* @param {Number} column
* @returns
*/
function isScrolledPositionVisible(dbg, line, column = 0) {
line = isCm6Enabled ? line + 1 : line;
return getCMEditor(dbg).isPositionVisible(line, column);
}
function setSelection(dbg, startLine, endLine) {
getCMEditor(dbg).setSelectionAt(
{ line: startLine, column: 0 },
{ line: endLine, column: 0 }
);
}
function getSearchQuery(dbg) {
return getCMEditor(dbg).getSearchQuery();
}
function getSearchSelection(dbg) {
return getCMEditor(dbg).getSearchSelection();
}
// Gets the mode used for the file
function getEditorFileMode(dbg) {
return getCMEditor(dbg).getEditorFileMode();
}
function getCoordsFromPosition(dbg, line, ch) {
return getCMEditor(dbg).getCoords(line, ch);
function getCoordsFromPosition(cm, { line, ch }) {
return cm.charCoords({ line: ~~line, ch: ~~ch });
}
async function getTokenFromPosition(dbg, { line, column = 0 }) {
info(`Get token at ${line}:${column}`);
const cm = getCM(dbg);
line = isCm6Enabled ? line : line - 1;
column = isCm6Enabled ? column : column - 1;
await scrollEditorIntoView(dbg, line, column);
if (isCm6Enabled) {
return getCMEditor(dbg).getElementAtPos(line, column);
}
// CodeMirror is 0-based while line and column arguments are 1-based.
// Pass "ch=-1" when there is no column argument passed.
const cmPosition = { line: line - 1, ch: column - 1 };
const { left, top } = getCoordsFromPosition(dbg, line, column);
const onScrolled = waitForScrolling(cm);
cm.scrollIntoView(cmPosition, 0);
// Ensure the line is visible with margin because the bar at the bottom of
// the editor overlaps into what the editor thinks is its own space, blocking
// the click event below.
await onScrolled;
const { left, top } = getCoordsFromPosition(cm, cmPosition);
// Adds a vertical offset due to increased line height
// https://github.com/firefox-devtools/debugger/pull/7934
@ -2346,30 +2224,11 @@ async function getTokenFromPosition(dbg, { line, column = 0 }) {
// Note that we might end up retrieving any popup if one is still shown over the expected token
return dbg.win.document.elementFromPoint(left, top + lineHeightOffset);
}
/**
* Waits for the currently triggered scroll to complete
*
* @param {*} dbg
* @param {Object} options
* @param {Boolean} options.useTimeoutFallback - defaults to true. When set to false
* a scroll must happen for the wait for scrolling to complete
* @returns
*/
async function waitForScrolling(dbg, { useTimeoutFallback = true } = {}) {
async function waitForScrolling(codeMirror) {
return new Promise(resolve => {
const editor = getCMEditor(dbg);
if (isCm6Enabled) {
editor.once("cm-editor-scrolled", resolve);
} else {
function onScroll() {
editor.codeMirror.off("scroll", onScroll);
resolve();
}
editor.codeMirror.on("scroll", onScroll);
}
if (useTimeoutFallback) {
setTimeout(resolve, 500);
}
codeMirror.on("scroll", resolve);
setTimeout(resolve, 500);
});
}
@ -2377,11 +2236,11 @@ async function codeMirrorGutterElement(dbg, line) {
info(`CodeMirror line ${line}`);
const cm = getCM(dbg);
line = isCm6Enabled ? line : line - 1;
await scrollEditorIntoView(dbg, line, 0);
await waitForScrolling(dbg);
const position = { line: line - 1, ch: 0 };
cm.scrollIntoView(position, 0);
await waitForScrolling(cm);
const coords = getCoordsFromPosition(dbg, line);
const coords = getCoordsFromPosition(cm, position);
const { left, top } = coords;
@ -2414,21 +2273,16 @@ async function clickAtPos(dbg, pos) {
info(
`Clicking on token ${tokenEl.innerText} in line ${tokenEl.parentNode.innerText}`
);
// TODO: Unify the usage for CM6 and CM5 Bug 1919694
if (isCm6Enabled) {
EventUtils.synthesizeMouseAtCenter(tokenEl, {}, dbg.win);
} else {
tokenEl.dispatchEvent(
new PointerEvent("click", {
bubbles: true,
cancelable: true,
view: dbg.win,
// Shift by one as we might be on the edge of the element and click on previous line/column
clientX: left + 1,
clientY: top + 1,
})
);
}
tokenEl.dispatchEvent(
new PointerEvent("click", {
bubbles: true,
cancelable: true,
view: dbg.win,
// Shift by one as we might be on the edge of the element and click on previous line/column
clientX: left + 1,
clientY: top + 1,
})
);
}
async function rightClickAtPos(dbg, pos) {
@ -2436,12 +2290,8 @@ async function rightClickAtPos(dbg, pos) {
if (!el) {
return;
}
// In CM6 when clicking in the editor an extra click is needed
// TODO: Investiaget and remove Bug 1919693
if (isCm6Enabled) {
EventUtils.synthesizeMouseAtCenter(el, {}, dbg.win);
}
rightClickEl(dbg, el);
EventUtils.synthesizeMouseAtCenter(el, { type: "contextmenu" }, dbg.win);
}
async function hoverAtPos(dbg, pos) {
@ -2599,10 +2449,13 @@ async function tryHovering(dbg, line, column, elementName) {
*/
async function tryHoverTokenAtLine(dbg, expression, line, column, elementName) {
info("Scroll codeMirror to make the token visible");
await scrollEditorIntoView(dbg, line, 0);
const cm = getCM(dbg);
const onScrolled = waitForScrolling(cm);
cm.scrollIntoView({ line: line - 1, ch: 0 }, 0);
await onScrolled;
// Lookup for the token matching the passed expression
const tokenEl = await getTokenElAtLine(dbg, expression, line, column);
const tokenEl = getTokenElAtLine(dbg, expression, line, column);
if (!tokenEl) {
throw new Error(
`Couldn't find token <${expression}> on ${line}:${column}\n`
@ -2631,26 +2484,29 @@ async function tryHoverToken(dbg, tokenEl, elementName) {
* @param {Integer} column: The column the token should be at
* @returns {Element} the token element, or null if not found
*/
async function getTokenElAtLine(dbg, expression, line, column = 0) {
function getTokenElAtLine(dbg, expression, line, column = 0) {
info(`Search for <${expression}> token on ${line}:${column}`);
// Get the line gutter element matching the passed line
const lineGutterEl = [
...dbg.win.document.querySelectorAll(".CodeMirror-linenumber"),
].find(el => el.textContent === `${line}`);
// Get the related editor line
const editorLineEl = await getNodeAtEditorLine(dbg, line);
const editorLineEl = lineGutterEl
.closest(".CodeMirror-gutter-wrapper")
.parentElement.querySelector(".CodeMirror-line");
// Lookup for the token matching the passed expression
const tokenParent = isCm6Enabled
? editorLineEl
: editorLineEl.querySelector(".CodeMirror-line > span");
const tokenElements = [...tokenParent.childNodes];
let currentColumn = 1;
return tokenElements.find(el => {
const childText = el.textContent;
return Array.from(editorLineEl.childNodes[0].childNodes).find(child => {
const childText = child.textContent;
currentColumn += childText.length;
// Only consider elements that are after the passed column
if (currentColumn < column) {
return false;
}
return childText == expression;
return childText === expression;
});
}

View File

@ -92,7 +92,7 @@ add_task(async function runTest() {
await onPaused;
const source = findSource(dbg, fileName);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
assertTextContentOnLine(dbg, 2, "const foo = 1;");
is(
dbg.selectors.getBreakpointCount(),
@ -102,7 +102,7 @@ add_task(async function runTest() {
await stepIn(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 3);
assertPausedAtSourceAndLine(dbg, source.id, 3);
assertTextContentOnLine(dbg, 3, "return foo;");
is(
dbg.selectors.getBreakpointCount(),
@ -156,14 +156,14 @@ add_task(async function runTest() {
await onPaused;
const source = findSource(dbg, fileName);
await assertPausedAtSourceAndLine(dbg, source.id, 2);
assertPausedAtSourceAndLine(dbg, source.id, 2);
assertTextContentOnLine(dbg, 2, "const plop = 1;");
await assertBreakpoint(dbg, 2);
is(dbg.selectors.getBreakpointCount(), 1, "We have exactly one breakpoint");
await stepIn(dbg);
await assertPausedAtSourceAndLine(dbg, source.id, 3);
assertPausedAtSourceAndLine(dbg, source.id, 3);
assertTextContentOnLine(dbg, 3, "return plop;");
is(
dbg.selectors.getBreakpointCount(),
@ -198,7 +198,7 @@ add_task(async function runTest() {
const dbg = createDebuggerContext(gToolbox);
await waitForPaused(dbg);
const source = findSource(dbg, url);
await assertPausedAtSourceAndLine(dbg, source.id, 1);
assertPausedAtSourceAndLine(dbg, source.id, 1);
const thread = dbg.selectors.getThread(dbg.selectors.getCurrentThread());
is(thread.isTopLevel, false, "The current thread is not the top level one");
is(thread.targetType, "process", "The current thread is the tab one");

View File

@ -12,7 +12,6 @@ const {
} = require("resource://devtools/shared/indentation.js");
const { debounce } = require("resource://devtools/shared/debounce.js");
const nodeConstants = require("resource://devtools/shared/dom-node-constants.js");
const ENABLE_CODE_FOLDING = "devtools.editor.enableCodeFolding";
const KEYMAP_PREF = "devtools.editor.keymap";
@ -164,14 +163,13 @@ class Editor extends EventEmitter {
searchState = {
cursors: [],
currentCursorIndex: -1,
query: "",
query: null,
};
#abortController;
// The id for the current source in the editor (selected source). This
// is used to cache the scroll snapshot for tracking scroll positions.
#currentDocumentId = null;
#currentDocument = null;
#CodeMirror6;
#compartments;
#effects;
@ -708,7 +706,7 @@ class Editor extends EventEmitter {
// Track the scroll snapshot for the current document at the end of the scroll
this.#editorDOMEventHandlers.scroll = [
debounce(this.#cacheScrollSnapshot, 250),
debounce(this.cacheScrollSnapshot, 250),
];
const extensions = [
@ -1011,6 +1009,14 @@ class Editor extends EventEmitter {
}
#createEventHandlers() {
function posToLineColumn(pos, view) {
if (!pos) {
return { line: null, column: null };
}
const cursor = view.state.doc.lineAt(pos);
const column = pos - cursor.from;
return { line: cursor.number, column };
}
const eventHandlers = {};
for (const eventName in this.#editorDOMEventHandlers) {
const handlers = this.#editorDOMEventHandlers[eventName];
@ -1024,8 +1030,9 @@ class Editor extends EventEmitter {
// investigate further Bug 1890895.
event.target.ownerGlobal.setTimeout(() => {
const view = editor.viewState;
const cursorPos = this.#posToLineColumn(
view.state.selection.main.head
const cursorPos = posToLineColumn(
view.state.selection.main.head,
view
);
handler(event, view, cursorPos.line, cursorPos.column);
}, 0);
@ -1069,13 +1076,12 @@ class Editor extends EventEmitter {
});
}
#cacheScrollSnapshot = () => {
cacheScrollSnapshot = () => {
const cm = editors.get(this);
if (!this.#currentDocumentId) {
if (this.#currentDocumentId) {
return;
}
this.#scrollSnapshots.set(this.#currentDocumentId, cm.scrollSnapshot());
this.emitForTests("cm-editor-scrolled");
};
/**
@ -1141,9 +1147,7 @@ class Editor extends EventEmitter {
* @property {Function} marker.createLineElementNode
* This should return the DOM element which is used for the marker. The line number is passed as a parameter.
* This is optional.
* @property {Function} marker.getMarkerEqualityValue
* Custom equality function. The line and column will be passed as arguments when this is called.
* This should return a value used for an equality check. This is optional.
*/
setLineContentMarker(marker) {
const cm = editors.get(this);
@ -1186,20 +1190,11 @@ class Editor extends EventEmitter {
const cachedPositionContentMarkers = this.#posContentMarkers;
class NodeWidget extends WidgetType {
constructor({
line,
column,
markerId,
createElementNode,
getMarkerEqualityValue,
}) {
constructor(line, column, markerId, createElementNode) {
super();
this.line = line;
this.column = column;
this.markerId = markerId;
this.equalityValue = getMarkerEqualityValue
? getMarkerEqualityValue(line, column)
: {};
this.toDOM = () => createElementNode(line, column);
}
@ -1207,16 +1202,7 @@ class Editor extends EventEmitter {
return (
this.line == widget.line &&
this.column == widget.column &&
this.markerId == widget.markerId &&
this.#isCustomValueEqual(widget)
);
}
#isCustomValueEqual(widget) {
return Object.keys(this.equalityValue).every(
key =>
widget.equalityValue.hasOwnProperty(key) &&
widget.equalityValue[key] === this.equalityValue[key]
this.markerId == widget.markerId
);
}
}
@ -1275,13 +1261,12 @@ class Editor extends EventEmitter {
// Markers used:
// 1. column-breakpoint-marker
const nodeDecoration = Decoration.widget({
widget: new NodeWidget({
line: position.line,
column: position.column,
markerId: marker.id,
createElementNode: marker.createPositionElementNode,
getMarkerEqualityValue: marker.getMarkerEqualityValue,
}),
widget: new NodeWidget(
position.line,
position.column,
marker.id,
marker.createPositionElementNode
),
// Make sure the widget is rendered after the cursor
// see https://codemirror.net/docs/ref/#view.Decoration^widget^spec.side for details.
side: 1,
@ -2060,12 +2045,6 @@ class Editor extends EventEmitter {
getDoc() {
const cm = editors.get(this);
if (this.config.cm6) {
if (!this.#currentDocument) {
this.#currentDocument = { id: this.#currentDocumentId };
}
return this.#currentDocument;
}
return cm.getDoc();
}
@ -2088,47 +2067,24 @@ class Editor extends EventEmitter {
return this.wasmOffsetToLine(maybeOffset);
}
/**
* Gets details about the line
*
* @param {Number} lineOrOffset
* @returns {Object} line info object
*/
lineInfo(lineOrOffset) {
let line = this.toLineIfWasmOffset(lineOrOffset);
const line = this.toLineIfWasmOffset(lineOrOffset);
if (line == undefined) {
return null;
}
const cm = editors.get(this);
if (this.config.cm6) {
// cm6 lines are 1-based, while cm5 are 0-based
line = line + 1;
const el = this.getElementAtLine(line);
// Filter out SPAN which do not contain user-defined classes.
// Classes currently are "debug-expression" and "debug-expression-error"
const markedSpans = [...el.querySelectorAll("span")].filter(span =>
span.className.includes("debug-expression")
);
if (this.config.cm6) {
return {
text: cm.state.doc.lineAt(line)?.text,
// cm6 lines are 1-based, while cm5 are 0-based
text: cm.state.doc.lineAt(line + 1)?.text,
// TODO: Expose those, or see usage for those and do things differently
line: null,
handle: {
markedSpans: markedSpans
? markedSpans.map(span => {
const { column } = this.#posToLineColumn(cm.posAtDOM(span));
return {
marker: { className: span.className },
from: column,
};
})
: null,
},
handle: null,
gutterMarkers: null,
textClass: null,
bgClass: null,
wrapClass: el.className,
wrapClass: null,
widgets: null,
};
}
@ -2197,11 +2153,6 @@ class Editor extends EventEmitter {
if (documentId) {
this.#currentDocumentId = documentId;
// If there is no scroll snapshot explicitly cache the snapshot set as no scroll
// is triggered.
if (!scrollSnapshot) {
this.#cacheScrollSnapshot();
}
}
} else {
cm.setValue(value);
@ -2258,15 +2209,10 @@ class Editor extends EventEmitter {
* re-detect indentation if we should.
*/
resetIndentUnit() {
if (this.isDestroyed()) {
return;
}
const cm = editors.get(this);
const iterFn = (start, maxEnd, callback) => {
if (!this.config.cm6) {
if (this.isDestroyed()) {
return;
}
cm.eachLine(start, maxEnd, line => {
return callback(line.text);
});
@ -2638,6 +2584,15 @@ class Editor extends EventEmitter {
return cm.coordsChar({ left, top });
}
/**
* The reverse of getPositionFromCoords. Similarly, returns a {left, top}
* object that corresponds to the specified line and character number.
*/
getCoordsFromPosition({ line, ch }) {
const cm = editors.get(this);
return cm.charCoords({ line: ~~line, ch: ~~ch });
}
/**
* Returns true if there's something to undo and false otherwise.
*/
@ -2982,34 +2937,15 @@ class Editor extends EventEmitter {
});
}
/**
* Gets the element at the specified codemirror offset
* @param {Number} offset
* @return {Element|null}
*/
#getElementAtOffset(offset) {
const cm = editors.get(this);
const el = cm.domAtPos(offset).node;
if (!el) {
return null;
}
// Text nodes do not have offset* properties, so lets use its
// parent element;
if (el.nodeType == nodeConstants.TEXT_NODE) {
return el.parentElement;
}
return el;
}
/**
* This checks if the specified position (line/column) is within the current viewport
* bounds. it helps determine if scrolling should happen.
* @param {Object} cm - The codemirror instance
* @param {Number} line - The line in the source
* @param {Number} column - The column in the source
* @returns {Boolean}
*/
isPositionVisible(line, column) {
const cm = editors.get(this);
#isPositionVisible(cm, line, column) {
let inXView, inYView;
function withinBounds(x, min, max) {
@ -3017,11 +2953,8 @@ class Editor extends EventEmitter {
}
if (this.config.cm6) {
const pos = this.#positionToOffset(line, column);
if (pos == null) {
return false;
}
const coords = cm.coordsAtPos(pos);
const pos = this.#posToOffset(cm.state.doc, line, column);
const coords = pos && cm.coordsAtPos(pos);
if (!coords) {
return false;
}
@ -3061,37 +2994,19 @@ class Editor extends EventEmitter {
return inXView && inYView;
}
/**
* Determines the line and column values the map to the codemirror offset specified.
* Used only for CM6
* @param {Number} pos - Codemirror offset
* @returns {Object} - Line column related to the position
*/
#posToLineColumn(pos) {
const cm = editors.get(this);
if (!pos) {
return {
line: null,
column: null,
};
}
const line = cm.state.doc.lineAt(pos);
return {
line: line.number,
column: pos - line.from,
};
}
/**
* Converts line/col to CM6 offset position
* @param {Object} doc - the codemirror document
* @param {Number} line - The line in the source
* @param {Number} col - The column in the source
* @returns {Number}
*/
#positionToOffset(line, col = 0) {
const cm = editors.get(this);
#posToOffset(doc, line, col) {
if (!this.config.cm6) {
throw new Error("This function is only compatible with CM6");
}
try {
const offset = cm.state.doc.line(line);
const offset = doc.line(line);
return offset.from + col;
} catch (e) {
// Line likey does not exist in viewport yet
@ -3128,7 +3043,7 @@ class Editor extends EventEmitter {
const {
codemirrorView: { EditorView },
} = this.#CodeMirror6;
return cm.dispatch({
cm.dispatch({
effects: EditorView.scrollIntoView(position, {
x: "nearest",
y: "center",
@ -3142,18 +3057,15 @@ class Editor extends EventEmitter {
* @param {Number} column - The column in the source
*/
scrollTo(line, column) {
if (this.isDestroyed()) {
return;
}
const cm = editors.get(this);
if (this.config.cm6) {
const {
codemirrorView: { EditorView },
} = this.#CodeMirror6;
if (!this.isPositionVisible(line, column)) {
const offset = this.#positionToOffset(line, column);
if (offset == null) {
if (!this.#isPositionVisible(cm, line, column)) {
const offset = this.#posToOffset(cm.state.doc, line, column);
if (!offset) {
return;
}
cm.dispatch({
@ -3173,7 +3085,7 @@ class Editor extends EventEmitter {
const { top, left } = cm.charCoords({ line, ch: column }, "local");
if (!this.isPositionVisible(line, column)) {
if (!this.#isPositionVisible(cm, line, column)) {
const scroller = cm.getScrollerElement();
const centeredX = Math.max(left - scroller.offsetWidth / 2, 0);
const centeredY = Math.max(top - scroller.offsetHeight / 2, 0);
@ -3183,24 +3095,6 @@ class Editor extends EventEmitter {
}
}
// Used only in tests
setSelectionAt(start, end) {
const cm = editors.get(this);
if (this.config.cm6) {
const from = this.#positionToOffset(start.line, start.column);
const to = this.#positionToOffset(end.line, end.column);
if (from == null || to == null) {
return;
}
cm.dispatch({ selection: { anchor: from, head: to } });
} else {
cm.setSelection(
{ line: start.line - 1, ch: start.column },
{ line: end.line - 1, ch: end.column }
);
}
}
// Used only in tests
setCursorAt(line, column) {
const cm = editors.get(this);
@ -3237,72 +3131,6 @@ class Editor extends EventEmitter {
return !!cm.state.search;
}
// Used only in tests
getCoords(line, column = 0) {
const cm = editors.get(this);
if (this.config.cm6) {
const offset = this.#positionToOffset(line, column);
if (offset == null) {
return null;
}
return cm.coordsAtPos(offset);
}
// CodeMirror is 0-based while line and column arguments are 1-based.
// Pass "column=-1" when there is no column argument passed.
return cm.charCoords({ line: ~~line, ch: ~~column });
}
// Used only in tests
// Only used for CM6
getElementAtLine(line) {
const offset = this.#positionToOffset(line);
const el = this.#getElementAtOffset(offset);
return el.closest(".cm-line");
}
// Used only in tests
getSearchQuery() {
const cm = editors.get(this);
if (this.config.cm6) {
return this.searchState.query.toString();
}
return cm.state.search.query;
}
// Used only in tests
// Gets currently selected search term
getSearchSelection() {
const cm = editors.get(this);
if (this.config.cm6) {
const cursor =
this.searchState.cursors[this.searchState.currentCursorIndex];
if (!cursor) {
return { text: "", line: -1, column: -1 };
}
const cursorPosition = this.#posToLineColumn(cursor.to);
// The lines in CM6 are 1 based while CM5 is 0 based
return {
text: cursor.match[0],
line: cursorPosition.line - 1,
column: cursorPosition.column,
};
}
const cursor = cm.getCursor();
return {
text: cm.getSelection(),
line: cursor.line,
column: cursor.ch,
};
}
// Only used for CM6
getElementAtPos(line, column) {
const offset = this.#positionToOffset(line, column);
const el = this.#getElementAtOffset(offset);
return el;
}
// Used only in tests
getLineCount() {
const cm = editors.get(this);
@ -3344,7 +3172,7 @@ class Editor extends EventEmitter {
}
isDestroyed() {
return !this.config || !editors.get(this);
return !editors.get(this);
}
destroy() {
@ -3381,10 +3209,6 @@ class Editor extends EventEmitter {
cm.doc.cm = null;
}
// Destroy the CM6 view
if (cm?.destroy) {
cm.destroy();
}
this.emit("destroy");
}

View File

@ -35,8 +35,8 @@ add_task(async function () {
info("Add a logpoint with a valid expression");
await setLogPoint(dbg, 8, "`a is ${a}`");
await assertLogBreakpoint(dbg, 7);
await assertLogBreakpoint(dbg, 8);
await assertEditorLogpoint(dbg, 7, { hasLog: true });
await assertEditorLogpoint(dbg, 8, { hasLog: true });
info("Close the file in the debugger");
await closeTab(dbg, "test-location-debugger-link-logpoint-1.js");

View File

@ -637,13 +637,11 @@ async function checkClickOnNode(
if (logPointExpr !== undefined && logPointExpr !== "") {
const inputEl = dbg.panelWin.document.activeElement;
const isPanelFocused = isCm6Enabled
? inputEl.classList.contains("cm-content") &&
inputEl.closest(".conditional-breakpoint-panel.log-point")
: inputEl.tagName == "TEXTAREA";
ok(isPanelFocused, "The textarea of logpoint panel is focused");
is(
inputEl.tagName,
"TEXTAREA",
"The textarea of logpoint panel is focused"
);
const inputValue = inputEl.parentElement.parentElement.innerText.trim();
is(