Backed out 4 changesets (bug 1814607, bug 1814608, bug 1809168) for causing devtools failures CLOSED TREE

Backed out changeset 8f7f098d9af0 (bug 1809168)
Backed out changeset aff754cf0b3f (bug 1814607)
Backed out changeset 2e41f4a14afd (bug 1814608)
Backed out changeset abc019424cec (bug 1814608)
This commit is contained in:
Noemi Erli 2023-02-25 07:42:13 +02:00
Родитель d521cb7246
Коммит 45aba48e02
36 изменённых файлов: 256 добавлений и 368 удалений

Просмотреть файл

@ -6,8 +6,7 @@ import { clearDocuments } from "../utils/editor";
import sourceQueue from "../utils/source-queue";
import { clearWasmStates } from "../utils/wasm";
import { getMainThread, getThreadContext } from "../selectors";
import { evaluateExpressions } from "../actions/expressions";
import { getMainThread } from "../selectors";
/**
* Redux actions for the navigation state
@ -45,11 +44,7 @@ export function willNavigate(event) {
* @static
*/
export function navigated() {
return async function({ getState, dispatch, panel }) {
// Update the watched expressions once the page is fully loaded
const threadcx = getThreadContext(getState());
await dispatch(evaluateExpressions(threadcx));
return async function({ dispatch, panel }) {
panel.emit("reloaded");
};
}

Просмотреть файл

@ -2,6 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
import {
getSourceActor,
getSourceActorBreakableLines,
} from "../selectors/source-actors";
import { memoizeableAction } from "../utils/memoizableAction";
import { PROMISE } from "./utils/middleware/promise";
export function insertSourceActors(sourceActors) {
return function({ dispatch }) {
dispatch({
@ -10,3 +17,21 @@ export function insertSourceActors(sourceActors) {
});
};
}
export const loadSourceActorBreakableLines = memoizeableAction(
"loadSourceActorBreakableLines",
{
createKey: args => args.sourceActorId,
getValue: ({ sourceActorId }, { getState }) =>
getSourceActorBreakableLines(getState(), sourceActorId),
action: async ({ sourceActorId }, { dispatch, getState, client }) => {
await dispatch({
type: "SET_SOURCE_ACTOR_BREAKABLE_LINES",
sourceActorId,
[PROMISE]: client.getSourceActorBreakableLines(
getSourceActor(getState(), sourceActorId)
),
});
},
}
);

Просмотреть файл

@ -3,11 +3,9 @@
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
import { isOriginalId } from "devtools/client/shared/source-map-loader/index";
import {
getBreakableLines,
getSourceActorBreakableLines,
} from "../../selectors";
import { getSourceActorsForSource, getBreakableLines } from "../../selectors";
import { setBreakpointPositions } from "../breakpoints/breakpointPositions";
import { loadSourceActorBreakableLines } from "../source-actors";
function calculateBreakableLines(positions) {
const lines = [];
@ -20,26 +18,16 @@ function calculateBreakableLines(positions) {
return lines;
}
/**
* Ensure that breakable lines for a given source are fetched.
*
* @param Object cx
* @param Object source
* @param Object sourceActor (optional)
* If one particular source actor is to be fetched.
* Otherwise the first available one will be picked,
* or all the source actors in case of HTML sources.
*/
export function setBreakableLines(cx, source, sourceActor) {
export function setBreakableLines(cx, sourceId) {
return async ({ getState, dispatch, client }) => {
let breakableLines;
if (isOriginalId(source.id)) {
if (isOriginalId(sourceId)) {
const positions = await dispatch(
setBreakpointPositions({ cx, sourceId: source.id })
setBreakpointPositions({ cx, sourceId })
);
breakableLines = calculateBreakableLines(positions);
const existingBreakableLines = getBreakableLines(getState(), source.id);
const existingBreakableLines = getBreakableLines(getState(), sourceId);
if (existingBreakableLines) {
breakableLines = [
...new Set([...existingBreakableLines, ...breakableLines]),
@ -49,21 +37,17 @@ export function setBreakableLines(cx, source, sourceActor) {
dispatch({
type: "SET_ORIGINAL_BREAKABLE_LINES",
cx,
sourceId: source.id,
sourceId,
breakableLines,
});
} else {
// Ignore re-fetching the breakable lines for source actor we already fetched
breakableLines = getSourceActorBreakableLines(getState(), sourceActor.id);
if (breakableLines) {
return;
}
breakableLines = await client.getSourceActorBreakableLines(sourceActor);
await dispatch({
type: "SET_SOURCE_ACTOR_BREAKABLE_LINES",
sourceActorId: sourceActor.id,
breakableLines,
});
const actors = getSourceActorsForSource(getState(), sourceId);
await Promise.all(
actors.map(({ id }) =>
dispatch(loadSourceActorBreakableLines({ sourceActorId: id, cx }))
)
);
}
};
}

Просмотреть файл

@ -4,6 +4,7 @@
import { PROMISE } from "../utils/middleware/promise";
import {
getSource,
getSourceTextContent,
getSettledSourceTextContent,
getGeneratedSource,
@ -21,7 +22,7 @@ import { isPretty } from "../../utils/source";
import { createLocation } from "../../utils/location";
import { memoizeableAction } from "../../utils/memoizableAction";
async function loadGeneratedSource(sourceActor, { client }) {
async function loadGeneratedSource(state, sourceActor, client) {
// If no source actor can be found then the text for the
// source cannot be loaded.
if (!sourceActor) {
@ -42,17 +43,20 @@ async function loadGeneratedSource(sourceActor, { client }) {
}
async function loadOriginalSource(
state,
source,
{ getState, client, sourceMapLoader, prettyPrintWorker }
client,
sourceMapLoader,
prettyPrintWorker
) {
if (isPretty(source)) {
const generatedSource = getGeneratedSource(getState(), source);
const generatedSource = getGeneratedSource(state, source);
if (!generatedSource) {
throw new Error("Unable to find minified original.");
}
const content = getSettledSourceTextContent(
getState(),
state,
createLocation({
sourceId: generatedSource.id,
})
@ -63,7 +67,7 @@ async function loadOriginalSource(
prettyPrintWorker,
generatedSource,
content,
getSourceActorsForSource(getState(), generatedSource.id)
getSourceActorsForSource(state, generatedSource.id)
);
}
@ -78,59 +82,82 @@ async function loadOriginalSource(
return result;
}
async function loadGeneratedSourceTextPromise(cx, sourceActor, thunkArgs) {
const { dispatch, getState } = thunkArgs;
async function loadGeneratedSourceTextPromise(
cx,
sourceActor,
{ dispatch, getState, client, parserWorker }
) {
const epoch = getSourcesEpoch(getState());
await dispatch({
type: "LOAD_GENERATED_SOURCE_TEXT",
sourceActorId: sourceActor.actor,
epoch,
[PROMISE]: loadGeneratedSource(sourceActor, thunkArgs),
[PROMISE]: loadGeneratedSource(getState(), sourceActor, client),
});
await onSourceTextContentAvailable(
await setParserAndBreakpointsTextContent(
cx,
sourceActor.sourceObject,
sourceActor,
thunkArgs
sourceActor.source,
sourceActor.actor,
{
state: getState(),
parserWorker,
dispatch,
}
);
}
async function loadOriginalSourceTextPromise(cx, source, thunkArgs) {
const { dispatch, getState } = thunkArgs;
async function loadOriginalSourceTextPromise(
cx,
source,
{
dispatch,
getState,
client,
sourceMapLoader,
parserWorker,
prettyPrintWorker,
}
) {
const epoch = getSourcesEpoch(getState());
await dispatch({
type: "LOAD_ORIGINAL_SOURCE_TEXT",
sourceId: source.id,
epoch,
[PROMISE]: loadOriginalSource(source, thunkArgs),
[PROMISE]: loadOriginalSource(
getState(),
source,
client,
sourceMapLoader,
prettyPrintWorker
),
});
await onSourceTextContentAvailable(cx, source, null, thunkArgs);
await setParserAndBreakpointsTextContent(cx, source.id, null, {
state: getState(),
parserWorker,
dispatch,
});
}
/**
* Function called everytime a new original or generated source gets its text content
* fetched from the server and registered in the reducer.
*
* @param {Object} cx
* @param {Object} source
* @param {Object} sourceActor (optional)
* If this is a generated source, we expect a precise source actor.
* @param {Object} thunkArgs
*/
async function onSourceTextContentAvailable(
async function setParserAndBreakpointsTextContent(
cx,
source,
sourceActor,
{ dispatch, getState, parserWorker }
sourceId,
sourceActorId,
{ dispatch, state, parserWorker }
) {
const source = getSource(state, sourceId);
if (!source) {
return;
}
const content = getSettledSourceTextContent(
getState(),
state,
createLocation({
sourceId: source.id,
sourceActorId: sourceActor?.id,
sourceActorId,
})
);
@ -143,7 +170,7 @@ async function onSourceTextContentAvailable(
);
// Update the text in any breakpoints for this source by re-adding them.
const breakpoints = getBreakpointsForSource(getState(), source.id);
const breakpoints = getBreakpointsForSource(state, source.id);
for (const { location, options, disabled } of breakpoints) {
await dispatch(addBreakpoint(cx, location, options, disabled));
}

Просмотреть файл

@ -16,11 +16,16 @@ import {
} from "../../client/firefox/create";
import { toggleBlackBox } from "./blackbox";
import { syncBreakpoint } from "../breakpoints";
import { createLocation } from "../../utils/location";
import { loadSourceText } from "./loadSourceText";
import { togglePrettyPrint } from "./prettyPrint";
import { selectLocation, setBreakableLines } from "../sources";
import { getRawSourceURL, isPrettyURL } from "../../utils/source";
import {
getRawSourceURL,
isPrettyURL,
isInlineScript,
} from "../../utils/source";
import {
getBlackBoxRanges,
getSource,
@ -30,6 +35,8 @@ import {
getPendingSelectedLocation,
getPendingBreakpointsForSource,
getContext,
getSourceTextContent,
getSourceActor,
} from "../../selectors";
import { prefs } from "../../utils/prefs";
@ -134,7 +141,7 @@ function checkSelectedSource(cx, sourceId) {
if (rawPendingUrl === source.url) {
if (isPrettyURL(pendingUrl)) {
const prettySource = await dispatch(togglePrettyPrint(cx, source.id));
dispatch(checkPendingBreakpoints(cx, prettySource, null));
dispatch(checkPendingBreakpoints(cx, prettySource.id, null));
return;
}
@ -150,8 +157,14 @@ function checkSelectedSource(cx, sourceId) {
};
}
function checkPendingBreakpoints(cx, source, sourceActor) {
function checkPendingBreakpoints(cx, sourceId, sourceActorId) {
return async ({ dispatch, getState }) => {
// source may have been modified by selectLocation
const source = getSource(getState(), sourceId);
if (!source) {
return;
}
const pendingBreakpoints = getPendingBreakpointsForSource(
getState(),
source
@ -161,13 +174,14 @@ function checkPendingBreakpoints(cx, source, sourceActor) {
return;
}
const sourceActor = getSourceActor(getState(), sourceActorId);
// load the source text if there is a pending breakpoint for it
await dispatch(loadSourceText(cx, source, sourceActor));
await dispatch(setBreakableLines(cx, source, sourceActor));
await dispatch(setBreakableLines(cx, source.id));
await Promise.all(
pendingBreakpoints.map(bp => {
return dispatch(syncBreakpoint(cx, source.id, bp));
return dispatch(syncBreakpoint(cx, sourceId, bp));
})
);
};
@ -240,7 +254,7 @@ export function newOriginalSources(originalSourcesInfo) {
await dispatch(checkNewSources(cx, sources));
for (const source of sources) {
dispatch(checkPendingBreakpoints(cx, source, null));
dispatch(checkPendingBreakpoints(cx, source.id, null));
}
return sources;
@ -301,6 +315,24 @@ export function newGeneratedSources(sourceResources) {
dispatch(addSources(cx, newSources));
dispatch(insertSourceActors(newSourceActors));
for (const newSourceActor of newSourceActors) {
const location = createLocation({
sourceId: newSourceActor.source.id,
sourceActorId: newSourceActor.actor,
});
// Fetch breakable lines for new HTML scripts
// when the HTML file has started loading
if (
isInlineScript(newSourceActor) &&
getSourceTextContent(getState(), location) != null
) {
dispatch(setBreakableLines(cx, newSourceActor.source)).catch(error => {
if (!(error instanceof ContextError)) {
throw error;
}
});
}
}
await dispatch(checkNewSources(cx, newSources));
(async () => {
@ -309,20 +341,8 @@ export function newGeneratedSources(sourceResources) {
// We would like to sync breakpoints after we are done
// loading source maps as sometimes generated and original
// files share the same paths.
for (const sourceActor of newSourceActors) {
// For HTML pages, we fetch all new incoming inline script,
// which will be related to one dedicated source actor.
// Whereas, for regular sources, if we have many source actors,
// this is for the same URL. And code expecting to have breakable lines
// will request breakable lines for that particular source actor.
if (sourceActor.sourceObject.isHTML) {
await dispatch(
setBreakableLines(cx, sourceActor.sourceObject, sourceActor)
);
}
dispatch(
checkPendingBreakpoints(cx, sourceActor.sourceObject, sourceActor)
);
for (const { source, actor } of newSourceActors) {
dispatch(checkPendingBreakpoints(cx, source, actor));
}
})();

Просмотреть файл

@ -184,7 +184,7 @@ export function selectLocation(cx, location, { keepContext = true } = {}) {
await dispatch(loadSourceText(cx, source, sourceActor));
await dispatch(setBreakableLines(cx, source, sourceActor));
await dispatch(setBreakableLines(cx, source.id));
const loadedSource = getSource(getState(), source.id);

Просмотреть файл

@ -177,15 +177,9 @@ function onDocumentEventAvailable(events) {
for (const event of events) {
// Only consider top level document, and ignore remote iframes top document
if (!event.targetFront.isTopLevel) continue;
// The browser toolbox debugger doesn't support the iframe dropdown.
// The debugger doesn't support the iframe dropdown.
// you will always see all the sources of all targets of your debugging context.
//
// But still allow it to clear the debugger when reloading the addon, or when
// switching between fallback document and other addon document.
if (
event.isFrameSwitching &&
!commands.descriptorFront.isWebExtensionDescriptor
) {
if (event.isFrameSwitching) {
continue;
}
if (event.name == "will-navigate") {

Просмотреть файл

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
import { asyncActionAsValue } from "../actions/utils/middleware/promise";
/**
* This reducer stores the list of all source actors as well their breakable lines.
*
@ -15,7 +17,8 @@ function initialSourceActorsState() {
// See create.js: `createSourceActor` for the shape of the source actor objects.
mutableSourceActors: new Map(),
// Map(Source Actor ID: string => Breakable lines: Array<Number>)
// Map(Source Actor ID: string => Breakable lines: object)
// Breakable lines object is of the form: { state: <"pending"|"fulfilled">, value: Array<Number> }
// The array is the list of all lines where breakpoints can be set
mutableBreakableLines: new Map(),
};
@ -83,6 +86,7 @@ function clearSourceActorMapURL(state, sourceActorId) {
}
function updateBreakableLines(state, action) {
const value = asyncActionAsValue(action);
const { sourceActorId } = action;
// Ignore breakable lines for source actors that aren't/no longer registered
@ -90,7 +94,7 @@ function updateBreakableLines(state, action) {
return state;
}
state.mutableBreakableLines.set(sourceActorId, action.breakableLines);
state.mutableBreakableLines.set(sourceActorId, value);
return {
...state,
};

Просмотреть файл

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
import { asSettled } from "../utils/async-value";
/**
* Tells if a given Source Actor is registered in the redux store
*
@ -59,7 +61,7 @@ export function getSourceActorsForThread(state, threadActorIDs) {
* List of all the breakable lines.
*/
export function getSourceActorBreakableLines(state, sourceActorId) {
return state.sourceActors.mutableBreakableLines.get(sourceActorId);
return asSettled(state.sourceActors.mutableBreakableLines.get(sourceActorId));
}
// Used by sources selectors
@ -90,11 +92,11 @@ export function getBreakableLinesForSourceActors(
const breakableLines = state.sourceActors.mutableBreakableLines.get(
sourceActorId
);
if (breakableLines) {
if (breakableLines && breakableLines.state == "fulfilled") {
if (isHTML) {
allBreakableLines.push(...breakableLines);
allBreakableLines.push(...breakableLines.value);
} else {
return breakableLines;
return breakableLines.value;
}
}
}

Просмотреть файл

@ -45,32 +45,21 @@ async function testSourcesOnNavigation() {
async function testDebuggerPauseStateOnNavigation() {
info("Test the debugger pause state when navigating using the BFCache");
info("Open debugger on the first page");
const dbg = await initDebugger("doc-bfcache1.html");
await addBreakpoint(dbg, "doc-bfcache1.html", 4);
info("Navigate to the second page");
await navigate(dbg, "doc-bfcache2.html");
await waitForSources(dbg, "doc-bfcache2.html");
info("Navigate back to the first page (which should resurect from bfcache)");
await goBack(`${EXAMPLE_URL}doc-bfcache1.html`);
await waitForSources(dbg, "doc-bfcache1.html");
// We paused when navigation back to bfcache1.html
// The previous navigation will prevent the page from completing its load.
// And we will do the same with this reload, which will pause page load
// and we will navigate forward and never complete the reload page load.
info("Reload the first page (which was in bfcache)");
await reloadWhenPausedBeforePageLoaded(dbg);
await reload(dbg);
await waitForPaused(dbg);
ok(dbg.toolbox.isHighlighted("jsdebugger"), "Debugger is highlighted");
info(
"Navigate forward to the second page (which should also coming from bfcache)"
);
await goForward(`${EXAMPLE_URL}doc-bfcache2.html`);
await waitUntil(() => !dbg.toolbox.isHighlighted("jsdebugger"));

Просмотреть файл

@ -63,7 +63,7 @@ add_task(async function testBlackBoxOnReload() {
// Lets reload without any blackboxing to make all necesary postions
// are hit.
const onReloaded = reload(dbg, file);
await reload(dbg, file);
await waitForPaused(dbg);
assertPausedAtSourceAndLine(dbg, source.id, 2);
@ -77,9 +77,6 @@ add_task(async function testBlackBoxOnReload() {
assertPausedAtSourceAndLine(dbg, source.id, 12);
await resumeAndWaitForPauseCounter(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
assertNotPaused(dbg);
info("Ignoring line 2");
@ -96,13 +93,11 @@ add_task(async function testBlackBoxOnReload() {
]);
await selectBlackBoxContextMenuItem(dbg, "blackbox-lines");
const onReloaded2 = reload(dbg, file);
await reload(dbg, file);
await waitForPaused(dbg);
assertPausedAtSourceAndLine(dbg, source.id, 12);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded2;
assertNotPaused(dbg);
});

Просмотреть файл

@ -18,7 +18,7 @@ add_task(async function() {
// reload.
await addBreakpoint(dbg, "doc-scripts.html", 21);
const onReloaded = reload(dbg, "doc-scripts.html");
await reload(dbg, "doc-scripts.html");
await waitForPaused(dbg);
@ -29,8 +29,6 @@ add_task(async function() {
assertPausedAtSourceAndLine(dbg, findSource(dbg, "doc-scripts.html").id, 21);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
info("Create an eval script that pauses itself.");
invokeInTab("doEval");

Просмотреть файл

@ -77,7 +77,7 @@ add_task(async function() {
await waitFor(() => findElement(dbg2, "codeMirror"));
info("Reload to check if we hit the breakpoint added in doc-scripts.html");
const onReloaded = reload(dbg2);
reload(dbg2);
await waitForDispatch(dbg2.store, "NAVIGATE");
await waitForSelectedSource(dbg2, "doc-scripts.html");
@ -86,7 +86,4 @@ add_task(async function() {
const scriptSource = dbg2.selectors.getSelectedSource();
assertPausedAtSourceAndLine(dbg2, scriptSource.id, 21);
await resume(dbg2);
info("Wait for reload to complete after resume");
await onReloaded;
});

Просмотреть файл

@ -105,7 +105,7 @@ add_task(async function testBreakpointInFunctionRelocation() {
info(
"Reload should change the source content to CONTENT 2 i.e 2 functions foo() and bar()"
);
const onReloaded = reload(dbg);
await reload(dbg);
await waitForPaused(dbg);
source = findSource(dbg, "script.js");
@ -130,8 +130,6 @@ add_task(async function testBreakpointInFunctionRelocation() {
);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
info(
"Reload should change the source content to CONTENT 3 i.e comments and 1 function bar()"

Просмотреть файл

@ -25,7 +25,7 @@ add_task(async function() {
await addBreakpointViaGutter(dbg, 1);
const onReloaded = reload(dbg);
await reload(dbg);
await waitForPaused(dbg);
info("Assert that the source is not long.js");
@ -60,9 +60,6 @@ add_task(async function() {
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
// remove breakpoints so they do not affect other
// tests.
await removeBreakpoint(dbg, source.id, 56);
@ -81,7 +78,7 @@ add_task(async function() {
await addBreakpointViaGutter(dbg, 22);
await addBreakpointViaGutter(dbg, 27);
const onReloaded = reload(dbg, "doc-scripts.html");
await reload(dbg, "doc-scripts.html");
await waitForPaused(dbg);
const source = findSource(dbg, "doc-scripts.html");
@ -109,9 +106,6 @@ add_task(async function() {
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
await removeBreakpoint(dbg, source.id, 22);
await removeBreakpoint(dbg, source.id, 27);

Просмотреть файл

@ -16,7 +16,7 @@
add_task(async function() {
const dbg = await initDebugger("doc-debugger-statements.html");
const onReloaded = reload(dbg, "doc-debugger-statements.html");
await reload(dbg, "doc-debugger-statements.html");
await waitForPaused(dbg);
assertPausedAtSourceAndLine(
dbg,
@ -64,11 +64,6 @@ add_task(async function() {
findSource(dbg, "doc-debugger-statements.html").id,
18
);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
});
function clickButton(dbg, button) {

Просмотреть файл

@ -9,8 +9,6 @@
"use strict";
const TEST_COM_URI = `${URL_ROOT_COM}examples/doc_dbg-fission-frame-sources.html`;
const TEST_ORG_IFRAME_URI = `${URL_ROOT_ORG_SSL}examples/doc_dbg-fission-frame-sources-frame.html`;
const DATA_URI = "data:text/html,<title>foo</title>";
add_task(async function() {
// Load a test page with a remote frame and wait for both sources to be visible.
@ -43,11 +41,11 @@ add_task(async function() {
"second thread displayed is the remote thread"
);
await addExpression(dbg, "document.location.href");
await addExpression(dbg, "document.location.host");
is(
getWatchExpressionValue(dbg, 1),
JSON.stringify(TEST_COM_URI),
`"example.com"`,
"expression is evaluated on the expected thread"
);
@ -63,7 +61,7 @@ add_task(async function() {
is(
getWatchExpressionValue(dbg, 1),
JSON.stringify(TEST_ORG_IFRAME_URI),
`"example.org"`,
"expression is evaluated on the remote origin thread"
);
@ -74,18 +72,19 @@ add_task(async function() {
is(
getWatchExpressionValue(dbg, 1),
JSON.stringify(TEST_COM_URI),
`"example.com"`,
"expression is evaluated on the main thread again"
);
// close the threads pane so following test don't have it open
threadsPaneEl.click();
await navigateToAbsoluteURL(dbg, DATA_URI);
await navigateToAbsoluteURL(dbg, "data:text/html,<title>foo</title>");
is(
// TOFIX: Bug 1809168 watch expressions aren't updated on navigation
todo_is(
getWatchExpressionValue(dbg, 1),
JSON.stringify(DATA_URI),
`""`,
"The location.host expression is updated after a navigaiton"
);

Просмотреть файл

@ -19,12 +19,12 @@ add_task(async function testBreakableLinesOverReloads() {
);
info("Assert breakable lines of the first html page load");
await assertBreakableLines(dbg, "index.html", 75, [
...getRange(16, 17),
21,
...getRange(24, 25),
30,
36,
await assertBreakableLines(dbg, "index.html", 73, [
[16, 17],
[21],
[23],
[28],
[34],
]);
info("Assert breakable lines of the first original source file, original.js");
@ -33,17 +33,17 @@ add_task(async function testBreakableLinesOverReloads() {
// and appends a few lines with a "WEBPACK FOOTER" comment
// All the appended lines are empty lines or comments, so none of them are breakable.
await assertBreakableLines(dbg, "original.js", 13, [
...getRange(1, 3),
...getRange(5, 8),
[1, 3],
[5, 8],
]);
info("Assert breakable lines of the simple first load of script.js");
await assertBreakableLines(dbg, "script.js", 3, [1, 3]);
await assertBreakableLines(dbg, "script.js", 3, [[1], [3]]);
info("Assert breakable lines of the first iframe page load");
await assertBreakableLines(dbg, "iframe.html", 30, [
...getRange(16, 17),
...getRange(22, 23),
[16, 17],
[22, 23],
]);
info(
@ -53,19 +53,15 @@ add_task(async function testBreakableLinesOverReloads() {
await reload(dbg, "index.html", "script.js", "original.js", "iframe.html");
info("Assert breakable lines of the more complex second load of script.js");
await assertBreakableLines(dbg, "script.js", 23, [2, ...getRange(13, 23)]);
await assertBreakableLines(dbg, "script.js", 23, [[2], [13, 23]]);
info("Assert breakable lines of the second html page load");
await assertBreakableLines(dbg, "index.html", 33, [25, 27]);
await assertBreakableLines(dbg, "index.html", 33, [[25], [27]]);
info("Assert breakable lines of the second orignal file");
// See first assertion about original.js,
// the size of original.js doesn't match the size of the test file
await assertBreakableLines(dbg, "original.js", 18, [
...getRange(1, 3),
...getRange(8, 11),
13,
]);
await assertBreakableLines(dbg, "original.js", 18, [[1, 3], [8, 11], [13]]);
await selectSource(dbg, "iframe.html");
// When EFT is disabled, iframe.html is a regular source and the right content is displayed
@ -80,8 +76,45 @@ add_task(async function testBreakableLinesOverReloads() {
info("Assert breakable lines of the second iframe page load");
await assertBreakableLines(dbg, "iframe.html", 27, [
...getRange(15, 17),
...getRange(21, 23),
[15, 17],
[21, 23],
]);
*/
});
function shouldLineBeBreakable(breakableLines, line) {
for (const range of breakableLines) {
if (range.length == 2) {
if (line >= range[0] && line <= range[1]) {
return true;
}
} else if (range.length == 1) {
if (line == range[0]) {
return true;
}
} else {
ok(
false,
"Ranges of breakable lines should only be made of arrays, with one item for single lines, or two items for subsequent breakable lines"
);
}
}
return false;
}
async function assertBreakableLines(dbg, file, numberOfLines, breakableLines) {
await selectSource(dbg, file);
is(
getCM(dbg).lineCount(),
numberOfLines,
`We show the expected number of lines in CodeMirror for ${file}`
);
for (let line = 1; line <= numberOfLines; line++) {
assertLineIsBreakable(
dbg,
file,
line,
shouldLineBeBreakable(breakableLines, line)
);
}
}

Просмотреть файл

@ -30,14 +30,13 @@ add_task(async function testBreakableLinesOverReloads() {
);
info("Assert breakable lines of the first html page load");
await assertBreakablePositions(dbg, "index.html", 75, [
await assertBreakablePositions(dbg, "index.html", 73, [
{ line: 16, columns: [6, 14] },
{ line: 17, columns: [] },
{ line: 21, columns: [12, 20, 48] },
{ line: 24, columns: [12, 20] },
{ line: 25, columns: [] },
{ line: 30, columns: [] },
{ line: 36, columns: [] },
{ line: 21, columns: [6, 14] },
{ line: 23, columns: [] },
{ line: 28, columns: [] },
{ line: 34, columns: [] },
]);
info("Assert breakable lines of the first original source file, original.js");

Просмотреть файл

@ -98,15 +98,15 @@ add_task(async function testSourceTreeNamesForWebExtensions() {
!lastThreadLabel,
"We should only have content process threads first after the main thread"
);
const pid = parseInt(label.match(/pid (\d+)\)/)[1], 10);
const pid = label.match(/pid (\d+)\)/)[1];
ok(
pid >= lastPID,
pid > lastPID,
`The content process threads are sorted by incremental PID ${pid} > ${lastPID}`
);
lastPID = pid;
} else {
ok(
label.localeCompare(lastThreadLabel) >= 0,
label.localeCompare(lastThreadLabel) > 0,
`Worker thread labels are sorted alphabeticaly: ${label} vs ${lastThreadLabel}`
);
lastThreadLabel = label;

Просмотреть файл

@ -24,7 +24,7 @@ add_task(async function() {
const onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
info("Reload the page to hit the breakpoint on load");
const onReloaded = reload(dbg);
await reload(dbg);
await onBreakpoint;
await waitForSelectedSource(dbg, "simple2.js");
@ -43,8 +43,5 @@ add_task(async function() {
await dbg.actions.stepIn(getThreadContext(dbg));
assertNotPaused(dbg, "Stepping in two times resumes");
info("Wait for reload to complete after resume");
await onReloaded;
await dbg.toolbox.closeToolbox();
});

Просмотреть файл

@ -14,7 +14,7 @@ add_task(async function() {
info("Test pause on exceptions ignoring caught exceptions");
await togglePauseOnExceptions(dbg, true, false);
let onReloaded = reload(dbg);
await reload(dbg);
await waitForPaused(dbg);
assertPausedAtSourceAndLine(
@ -24,13 +24,11 @@ add_task(async function() {
);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
info("Test pause on exceptions including caught exceptions");
await togglePauseOnExceptions(dbg, true, true);
onReloaded = reload(dbg);
await reload(dbg);
await waitForPaused(dbg);
assertPausedAtSourceAndLine(
@ -49,6 +47,4 @@ add_task(async function() {
);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
});

Просмотреть файл

@ -18,7 +18,7 @@ add_task(async function() {
const dbg = await initDebugger("doc-iframes.html");
// test pausing in the main thread
const onReloaded = reload(dbg);
await reload(dbg);
await waitForPaused(dbg);
await waitForLoadedSource(dbg, "doc-iframes.html");
assertPausedAtSourceAndLine(dbg, findSource(dbg, "doc-iframes.html").id, 11);
@ -53,8 +53,5 @@ add_task(async function() {
await waitForResumed(dbg);
await waitFor(() => !dbg.toolbox.isHighlighted("jsdebugger"));
ok(true, "Debugger is no longer highlighted when resumed");
info("Wait for reload to complete after resume");
await onReloaded;
}
});

Просмотреть файл

@ -6,35 +6,11 @@
"use strict";
const TEST_PAGE = "doc-inline-script-offset.html";
add_task(async function() {
const dbg = await initDebugger(TEST_PAGE);
await selectSource(dbg, TEST_PAGE);
// Ensure that breakable lines are correct when loading against an already loaded page
await assertBreakableLines(dbg, TEST_PAGE, 16, [
...getRange(3, 5),
...getRange(11, 13),
15,
]);
await reload(dbg, TEST_PAGE);
// Also verify they are fine after reload
await assertBreakableLines(dbg, TEST_PAGE, 16, [
...getRange(3, 5),
...getRange(11, 13),
15,
]);
await addBreakpoint(dbg, "doc-inline-script-offset.html", 15, 66);
const onReloaded = reload(dbg);
const dbg = await initDebugger("doc-inline-script-offset.html");
await selectSource(dbg, "doc-inline-script-offset.html");
await addBreakpoint(dbg, "doc-inline-script-offset.html", 6, 66);
await reload(dbg);
await waitForPaused(dbg);
ok(true, "paused after reloading at column breakpoint");
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
});

Просмотреть файл

@ -11,7 +11,7 @@
add_task(async function() {
const dbg = await initDebugger("doc-debugger-statements.html");
const onReloaded = reload(dbg);
await reload(dbg);
await waitForPaused(dbg);
await waitForLoadedSource(dbg, "doc-debugger-statements.html");
const source = findSource(dbg, "doc-debugger-statements.html");
@ -31,10 +31,6 @@ add_task(async function() {
await pressStepOver(dbg);
assertPausedAtSourceAndLine(dbg, source.id, 18);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
});
function pressResume(dbg) {

Просмотреть файл

@ -13,7 +13,7 @@ add_task(async function() {
);
info("Reload the page to hit the debugger statement while loading");
const onReloaded = reload(dbg);
reload(dbg);
await waitForPaused(dbg);
ok(true, "We're paused");
@ -42,7 +42,4 @@ add_task(async function() {
});
ok(true, "The overlay is now hidden");
info("Wait for reload to complete after resume");
await onReloaded;
});

Просмотреть файл

@ -30,7 +30,7 @@ add_task(async function() {
await disableBreakpoint(dbg, entrySrc, 15, 0);
// Test reloading the debugger
const onReloaded = reload(dbg, "opts.js");
await reload(dbg, "opts.js");
await waitForDispatch(dbg.store, "LOAD_ORIGINAL_SOURCE_TEXT");
await waitForPaused(dbg);
@ -50,10 +50,6 @@ add_task(async function() {
"Breakpoint is on the correct line and is disabled"
);
await assertBreakpoint(dbg, 15);
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
});
async function waitForBreakpointCount(dbg, count) {

Просмотреть файл

@ -44,7 +44,7 @@ add_task(async function() {
await checkWorkerThreads(dbg, 1);
// The test page will immediately fetch from the service worker if registered.
const onReloaded = reload(dbg);
await reload(dbg);
await waitForSource(dbg, "service-worker.sjs");
const workerSource = findSource(dbg, "service-worker.sjs");
@ -56,9 +56,6 @@ add_task(async function() {
await resume(dbg);
await dbg.actions.removeAllBreakpoints(getContext(dbg));
info("Wait for reload to complete after resume");
await onReloaded;
invokeInTab("unregisterWorker");
await checkWorkerThreads(dbg, 0);

Просмотреть файл

@ -3,13 +3,4 @@ function f() {
return { g: () => {} };
}
</script>
<!-- evaluate the same long script to slow down the page load and more easily cause race condition in inline script code -->
<script src="long.js"></script><script src="long.js"></script><script src="long.js"></script><script src="long.js"></script>
<script>
function j() {
return 42;
}
</script>
<span>Here is some random stuff</span><script>function z() { this.f().g() } z();</script>

Просмотреть файл

@ -17,11 +17,9 @@
</script>
<!-- A second inline script, that helps cover bugs when having two distinct inline scripts -->
<!-- And also covers inline script with column indexes being offseted by the HTML content -->
<script>console.log("second inline script");</script>
<script>
console.log("second in line script");
<!-- Covers column index being shifted only for the first line and normal for the subsequent ones -->
<script>console.log("third inline script");
eval(`
function nameLessEval() {
console.log("name-less-eval");

Просмотреть файл

@ -17,11 +17,9 @@
</script>
<!-- A second inline script, that helps cover bugs when having two distinct inline scripts -->
<!-- And also covers inline script with column indexes being offseted by the HTML content -->
<script>console.log("second inline script");</script>
<script>
console.log("second in line script");
<!-- Covers column index being shifted only for the first line and normal for the subsequent ones -->
<script>console.log("third inline script");
eval(`
function nameLessEval() {
console.log("name-less-eval");

Просмотреть файл

@ -200,47 +200,3 @@ async function assertSourceTreeNode(dbg, text) {
});
ok(!!node, `Source tree node with text "${text}" exists`);
}
/**
* Assert precisely the list of all breakable line for a given source
*
* @param {Object} dbg
* @param {Object|String} file
* The source name or source object to review
* @param {Number} numberOfLines
* The expected number of lines for this source.
* @param {Array<Number>} breakableLines
* This list of all breakable line numbers
*/
async function assertBreakableLines(
dbg,
source,
numberOfLines,
breakableLines
) {
await selectSource(dbg, source);
is(
getCM(dbg).lineCount(),
numberOfLines,
`We show the expected number of lines in CodeMirror for ${source}`
);
for (let line = 1; line <= numberOfLines; line++) {
assertLineIsBreakable(dbg, source, line, breakableLines.includes(line));
}
}
/**
* Helper alongside assertBreakable lines to ease defining list of breakable lines.
*
* @param {Number} start
* @param {Number} end
* @return {Array<Number>}
* Returns an array of decimal numbers starting from `start` and ending with `end`.
*/
function getRange(start, end) {
const range = [];
for (let i = start; i <= end; i++) {
range.push(i);
}
return range;
}

Просмотреть файл

@ -64,7 +64,7 @@ addIntegrationTask(async function testReloadingRemovedOriginalSources(
);
const syncBp = waitForDispatch(dbg.store, "SET_BREAKPOINT");
testServer.switchToNextVersion();
const onReloaded = reload(dbg, "new-original.js");
await reload(dbg, "new-original.js");
await syncBp;
// Assert the new breakpoint being created after reload
@ -95,8 +95,6 @@ addIntegrationTask(async function testReloadingRemovedOriginalSources(
}
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
info(
"Reload a last time to remove both original and generated sources entirely"

Просмотреть файл

@ -76,7 +76,7 @@ addIntegrationTask(async function testReloadingChangedGeneratedSource(
"SET_BREAKPOINT"
);
testServer.switchToNextVersion();
const onReloaded = reload(
await reload(
dbg,
"bundle-with-another-original.js",
"original-with-no-update.js"
@ -120,7 +120,6 @@ addIntegrationTask(async function testReloadingChangedGeneratedSource(
6
);
} else {
await onReloaded;
// Assert that it does not pause in commpressed files
assertNotPaused(dbg);
}
@ -168,10 +167,5 @@ addIntegrationTask(async function testReloadingChangedGeneratedSource(
is(breakpoint.generatedLocation.line, 103);
}
if (!isCompressed) {
await resume(dbg);
info("Wait for reload to complete after resume");
await onReloaded;
}
await closeTab(dbg, "bundle-with-another-original.js");
});

Просмотреть файл

@ -201,8 +201,6 @@ function waitForSelectedSource(dbg, sourceOrUrl) {
getSelectedSourceTextContent,
getSymbols,
getBreakableLines,
getSourceActorsForSource,
getSourceActorBreakableLines,
} = dbg.selectors;
return waitForState(
@ -226,23 +224,7 @@ function waitForSelectedSource(dbg, sourceOrUrl) {
}
}
// Wait for symbols/AST to be parsed
if (!getSymbols(source)) {
return false;
}
// Finaly wait for breakable lines to be set
if (source.isHTML) {
// For HTML sources we need to wait for each source actor to be processed.
// getBreakableLines will return the aggregation without being able to know
// if that's complete, with all the source actors.
const sourceActors = getSourceActorsForSource(source.id);
const allSourceActorsProcessed = sourceActors.every(
sourceActor => !!getSourceActorBreakableLines(sourceActor.id)
);
return allSourceActorsProcessed;
}
return getBreakableLines(source.id);
return getSymbols(source) && getBreakableLines(source.id);
},
"selected source"
);
@ -856,35 +838,8 @@ function deleteExpression(dbg, input) {
* @static
*/
async function reload(dbg, ...sources) {
await reloadBrowser();
return waitForSources(dbg, ...sources);
}
// Only use this method when the page is paused by the debugger
// during page load and we navigate away without resuming.
//
// In this particular scenario, the page will never be "loaded".
// i.e. emit DOCUMENT_EVENT's dom-complete
// And consequently, debugger panel won't emit "reloaded" event.
async function reloadWhenPausedBeforePageLoaded(dbg, ...sources) {
// But we can at least listen for the next DOCUMENT_EVENT's dom-loading,
// which should be fired even if the page is pause the earliest.
const { resourceCommand } = dbg.commands;
const {
onResource: onTopLevelDomLoading,
} = await resourceCommand.waitForNextResource(
resourceCommand.TYPES.DOCUMENT_EVENT,
{
ignoreExistingResources: true,
predicate: resource =>
resource.targetFront.isTopLevel && resource.name === "dom-loading",
}
);
gBrowser.reloadTab(gBrowser.selectedTab);
info("Wait for DOCUMENT_EVENT dom-loading after reload");
await onTopLevelDomLoading;
// We aren't waiting for load as the page may not load because of a breakpoint
await reloadBrowser({ waitForLoad: false });
return waitForSources(dbg, ...sources);
}

Просмотреть файл

@ -785,9 +785,7 @@ function _watchForPanelReload(toolbox, toolId) {
info("Waiting for inspector updates after page reload");
await onReloaded;
};
} else if (
["netmonitor", "accessibility", "webconsole", "jsdebugger"].includes(toolId)
) {
} else if (["netmonitor", "accessibility", "webconsole"].includes(toolId)) {
const onReloaded = panel.once("reloaded");
return async function() {
info(`Waiting for ${toolId} updates after page reload`);