зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1712557) for failures on browser_dbg-link-reload.js. CLOSED TREE
Backed out changeset 853833eded4d (bug 1712557) Backed out changeset d7c5b966a457 (bug 1712557) Backed out changeset 3bab93803617 (bug 1712557)
This commit is contained in:
Родитель
9869f145e1
Коммит
cee413b886
|
@ -104,7 +104,6 @@ skip-if = true # bug 1607636
|
||||||
[browser_dbg-keyboard-shortcuts.js]
|
[browser_dbg-keyboard-shortcuts.js]
|
||||||
skip-if = os == "linux" # bug 1351952
|
skip-if = os == "linux" # bug 1351952
|
||||||
[browser_dbg-layout-changes.js]
|
[browser_dbg-layout-changes.js]
|
||||||
[browser_dbg-link-reload.js]
|
|
||||||
[browser_dbg-log-events.js]
|
[browser_dbg-log-events.js]
|
||||||
[browser_dbg-log-point-mapping.js]
|
[browser_dbg-log-point-mapping.js]
|
||||||
[browser_dbg-log-points.js]
|
[browser_dbg-log-points.js]
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* 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/>. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test reload via an href link, which refers to the same document.
|
|
||||||
* It seems to cause different codepath compared to F5.
|
|
||||||
*/
|
|
||||||
add_task(async function() {
|
|
||||||
const dbg = await initDebugger("doc-reload-link.html");
|
|
||||||
const {
|
|
||||||
selectors: { getSelectedSource, getIsPaused, getCurrentThread },
|
|
||||||
getState
|
|
||||||
} = dbg;
|
|
||||||
|
|
||||||
info("Add a breakpoint that will be hit on reload");
|
|
||||||
await addBreakpoint(dbg, "doc-reload-link.html", 3);
|
|
||||||
|
|
||||||
for(let i = 0; i < 5; i++) {
|
|
||||||
let onReloaded = waitForReload(dbg.commands);
|
|
||||||
|
|
||||||
info("Reload via a link, this causes special race condition different from F5");
|
|
||||||
await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () {
|
|
||||||
const reloadLink = content.document.querySelector("a");
|
|
||||||
reloadLink.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
info("Wait for paused\n");
|
|
||||||
await waitForPaused(dbg);
|
|
||||||
|
|
||||||
info("Check paused location\n");
|
|
||||||
let source = findSource(dbg, "doc-reload-link.html");
|
|
||||||
assertPausedAtSourceAndLine(dbg, source.id, 3);
|
|
||||||
|
|
||||||
await resume(dbg);
|
|
||||||
|
|
||||||
info("Wait for completion of the page load");
|
|
||||||
// This help ensure that the page loaded correctly and prevent pending request at teardown
|
|
||||||
await onReloaded;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function waitForReload(commands) {
|
|
||||||
let resolve;
|
|
||||||
const onReloaded = new Promise(r => (resolve = r));
|
|
||||||
const { resourceCommand } = commands;
|
|
||||||
const { DOCUMENT_EVENT } = resourceCommand.TYPES;
|
|
||||||
const onAvailable = resources => {
|
|
||||||
if (resources.find(resource => resource.name == "dom-complete")) {
|
|
||||||
resourceCommand.unwatchResources([DOCUMENT_EVENT], { onAvailable });
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Wait for watchResources completion before reloading, otherwise we might miss the dom-complete event
|
|
||||||
// if watchResources is still pending while the reload already started and finished loading the document early.
|
|
||||||
await resourceCommand.watchResources([DOCUMENT_EVENT], {
|
|
||||||
onAvailable,
|
|
||||||
ignoreExistingResources: true,
|
|
||||||
});
|
|
||||||
return onReloaded;
|
|
||||||
}
|
|
|
@ -21,23 +21,23 @@ add_task(async function() {
|
||||||
getState
|
getState
|
||||||
} = dbg;
|
} = dbg;
|
||||||
|
|
||||||
info("Pause in the first document");
|
|
||||||
invokeInTab("firstCall");
|
invokeInTab("firstCall");
|
||||||
await waitForPaused(dbg);
|
await waitForPaused(dbg);
|
||||||
|
|
||||||
info("Navigate while being paused in the first document");
|
await waitForRequestsToSettle(dbg);
|
||||||
await navigate(dbg, "doc-scripts.html", "simple1.js");
|
await navigate(dbg, "doc-scripts.html", "simple1.js");
|
||||||
|
|
||||||
info("Set a breakpoint on the second document and pause on it");
|
|
||||||
await selectSource(dbg, "simple1");
|
await selectSource(dbg, "simple1");
|
||||||
await addBreakpoint(dbg, "simple1.js", 4);
|
await addBreakpoint(dbg, "simple1.js", 4);
|
||||||
invokeInTab("main");
|
invokeInTab("main");
|
||||||
await waitForPaused(dbg);
|
await waitForPaused(dbg);
|
||||||
let source = findSource(dbg, "simple1.js");
|
await waitForLoadedSource(dbg, "simple1");
|
||||||
assertPausedAtSourceAndLine(dbg, source.id, 4);
|
toggleScopes(dbg);
|
||||||
|
|
||||||
|
assertPausedLocation(dbg);
|
||||||
is(countSources(dbg), 5, "5 sources are loaded.");
|
is(countSources(dbg), 5, "5 sources are loaded.");
|
||||||
|
|
||||||
await waitForRequestsToSettle(dbg);
|
await waitForRequestsToSettle(dbg);
|
||||||
|
// this test is intermittent without this
|
||||||
let onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
let onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||||
await navigate(dbg, "doc-scripts.html", ...SOURCES);
|
await navigate(dbg, "doc-scripts.html", ...SOURCES);
|
||||||
await onBreakpoint
|
await onBreakpoint
|
||||||
|
@ -45,20 +45,23 @@ add_task(async function() {
|
||||||
ok(!getIsPaused(getCurrentThread()), "Is not paused");
|
ok(!getIsPaused(getCurrentThread()), "Is not paused");
|
||||||
|
|
||||||
await waitForRequestsToSettle(dbg);
|
await waitForRequestsToSettle(dbg);
|
||||||
|
// this test is intermittent without this
|
||||||
onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||||
await navigate(dbg, "doc-scripts.html", ...SOURCES);
|
await navigate(dbg, "doc-scripts.html", ...SOURCES);
|
||||||
await onBreakpoint
|
await onBreakpoint
|
||||||
is(countSources(dbg), 5, "5 sources are loaded.");
|
is(countSources(dbg), 5, "5 sources are loaded.");
|
||||||
|
|
||||||
info("Test that the current selected source persists across reloads");
|
// Test that the current select source persists across reloads
|
||||||
await selectSource(dbg, "long.js");
|
await selectSource(dbg, "long.js");
|
||||||
|
|
||||||
await waitForRequestsToSettle(dbg);
|
await waitForRequestsToSettle(dbg);
|
||||||
|
// this test is intermittent without this
|
||||||
onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
|
||||||
await reload(dbg, "long.js");
|
await reload(dbg, "long.js");
|
||||||
await onBreakpoint
|
await onBreakpoint
|
||||||
await waitForSelectedSource(dbg, "long.js");
|
await waitForSelectedSource(dbg, "long.js");
|
||||||
|
|
||||||
|
await waitForRequestsToSettle(dbg);
|
||||||
ok(getSelectedSource().url.includes("long.js"), "Selected source is long.js");
|
ok(getSelectedSource().url.includes("long.js"), "Selected source is long.js");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<meta charset="UTF-8">
|
|
||||||
<script>
|
|
||||||
dump("dump\n");
|
|
||||||
</script>
|
|
||||||
<a href="doc-reload-link.html">reload via link</a>
|
|
|
@ -399,7 +399,7 @@ function assertPausedAtSourceAndLine(dbg, expectedSourceId, expectedLine) {
|
||||||
const frames = dbg.selectors.getCurrentThreadFrames();
|
const frames = dbg.selectors.getCurrentThreadFrames();
|
||||||
ok(frames.length >= 1, "Got at least one frame");
|
ok(frames.length >= 1, "Got at least one frame");
|
||||||
const { sourceId, line } = frames[0].location;
|
const { sourceId, line } = frames[0].location;
|
||||||
is(sourceId, expectedSourceId, "Frame has correct source");
|
ok(sourceId == expectedSourceId, "Frame has correct source");
|
||||||
ok(
|
ok(
|
||||||
line == expectedLine,
|
line == expectedLine,
|
||||||
`Frame paused at ${line}, but expected ${expectedLine}`
|
`Frame paused at ${line}, but expected ${expectedLine}`
|
||||||
|
|
|
@ -1462,16 +1462,9 @@ const browsingContextTargetPrototype = {
|
||||||
this._updateChildDocShells();
|
this._updateChildDocShells();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this follows WindowGlobal lifecycle, a new Target actor will be spawn for the top level
|
|
||||||
// target document. Only notify about in-process iframes.
|
|
||||||
// Note that OOP iframes won't emit window-ready and will also have their dedicated target.
|
|
||||||
if (this.followWindowGlobalLifeCycle && isTopLevel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.emit("window-ready", {
|
this.emit("window-ready", {
|
||||||
window,
|
window: window,
|
||||||
isTopLevel,
|
isTopLevel: isTopLevel,
|
||||||
isBFCache,
|
isBFCache,
|
||||||
id: getWindowID(window),
|
id: getWindowID(window),
|
||||||
isFrameSwitching,
|
isFrameSwitching,
|
||||||
|
@ -1479,20 +1472,11 @@ const browsingContextTargetPrototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
_windowDestroyed(window, id = null, isFrozen = false) {
|
_windowDestroyed(window, id = null, isFrozen = false) {
|
||||||
const isTopLevel = window == this.window;
|
|
||||||
|
|
||||||
// If this follows WindowGlobal lifecycle, this target will be destroyed, alongside its top level document.
|
|
||||||
// Only notify about in-process iframes.
|
|
||||||
// Note that OOP iframes won't emit window-ready and will also have their dedicated target.
|
|
||||||
if (this.followWindowGlobalLifeCycle && isTopLevel) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.emit("window-destroyed", {
|
this.emit("window-destroyed", {
|
||||||
window,
|
window: window,
|
||||||
isTopLevel,
|
isTopLevel: window == this.window,
|
||||||
id: id || getWindowID(window),
|
id: id || getWindowID(window),
|
||||||
isFrozen,
|
isFrozen: isFrozen,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -60,11 +60,7 @@ DocumentEventsListener.prototype = {
|
||||||
// Listen to window-ready and then fake one in order to notify about dom-loading for the existing document
|
// Listen to window-ready and then fake one in order to notify about dom-loading for the existing document
|
||||||
EventEmitter.on(this.targetActor, "window-ready", this.onWindowReady);
|
EventEmitter.on(this.targetActor, "window-ready", this.onWindowReady);
|
||||||
// If the target actor isn't attached yet, attach it so that it starts emitting window-ready event
|
// If the target actor isn't attached yet, attach it so that it starts emitting window-ready event
|
||||||
// Only do that if this isn't a JSWindowActor based target as this won't emit window-ready anyway.
|
if (!this.targetActor.attached) {
|
||||||
if (
|
|
||||||
!this.targetActor.attached &&
|
|
||||||
!this.targetActor.followWindowGlobalLifeCycle
|
|
||||||
) {
|
|
||||||
// The target actor will emit a window-ready in the next event loop
|
// The target actor will emit a window-ready in the next event loop
|
||||||
// for the top level document (and any existing iframe document)
|
// for the top level document (and any existing iframe document)
|
||||||
this.targetActor.attach();
|
this.targetActor.attach();
|
||||||
|
|
|
@ -245,21 +245,6 @@ class DevToolsFrameChild extends JSWindowActorChild {
|
||||||
actor: targetActor,
|
actor: targetActor,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Immediately queue a message for the parent process,
|
|
||||||
// in order to ensure that the JSWindowActorTransport is instantiated
|
|
||||||
// before any packet is sent from the content process.
|
|
||||||
// As the order of messages is guaranteed to be delivered in the order they
|
|
||||||
// were queued, we don't have to wait for anything around this sendAsyncMessage call.
|
|
||||||
// In theory, the FrameTargetActor may emit events in its constructor.
|
|
||||||
// If it does, such RDP packets may be lost.
|
|
||||||
// The important point here is to send this message before processing the watchedData,
|
|
||||||
// which will start the Watcher and start emitting resources on the target actor.
|
|
||||||
this.sendAsyncMessage("DevToolsFrameChild:connectFromContent", {
|
|
||||||
watcherActorID,
|
|
||||||
forwardingPrefix,
|
|
||||||
actor: targetActor.form(),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Pass initialization data to the target actor
|
// Pass initialization data to the target actor
|
||||||
for (const type in watchedData) {
|
for (const type in watchedData) {
|
||||||
// `watchedData` will also contain `browserId` and `watcherTraits`,
|
// `watchedData` will also contain `browserId` and `watcherTraits`,
|
||||||
|
@ -270,6 +255,21 @@ class DevToolsFrameChild extends JSWindowActorChild {
|
||||||
}
|
}
|
||||||
targetActor.addWatcherDataEntry(type, entries);
|
targetActor.addWatcherDataEntry(type, entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Immediately queue a message for the parent process,
|
||||||
|
// in order to ensure that the JSWindowActorTransport is instantiated
|
||||||
|
// before any packet is sent from the content process.
|
||||||
|
// As the order of messages is quaranteed to be delivered in the order they
|
||||||
|
// were queued, we don't have to wait for anything around this sendAsyncMessage call.
|
||||||
|
// In theory, the FrameTargetActor may emit events in its constructor.
|
||||||
|
// If it does, such RDP packets may be lost. But in practice, no events
|
||||||
|
// are emitted during its construction. Instead the frontend will start
|
||||||
|
// the communication first.
|
||||||
|
this.sendAsyncMessage("DevToolsFrameChild:connectFromContent", {
|
||||||
|
watcherActorID,
|
||||||
|
forwardingPrefix,
|
||||||
|
actor: targetActor.form(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_destroyTargetActor(watcherActorID) {
|
_destroyTargetActor(watcherActorID) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче