diff --git a/devtools/client/debugger/test/mochitest/browser.ini b/devtools/client/debugger/test/mochitest/browser.ini
index 1d6a97804f0d..d7fc4ce90f3e 100644
--- a/devtools/client/debugger/test/mochitest/browser.ini
+++ b/devtools/client/debugger/test/mochitest/browser.ini
@@ -104,6 +104,7 @@ skip-if = true # bug 1607636
[browser_dbg-keyboard-shortcuts.js]
skip-if = os == "linux" # bug 1351952
[browser_dbg-layout-changes.js]
+[browser_dbg-link-reload.js]
[browser_dbg-log-events.js]
[browser_dbg-log-point-mapping.js]
[browser_dbg-log-points.js]
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-link-reload.js b/devtools/client/debugger/test/mochitest/browser_dbg-link-reload.js
new file mode 100644
index 000000000000..415a298da120
--- /dev/null
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-link-reload.js
@@ -0,0 +1,67 @@
+/* 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 . */
+
+/**
+ * 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() {
+ // Disable bfcache for Fission for now.
+ // If Fission is disabled, the pref is no-op.
+ await SpecialPowers.pushPrefEnv({
+ set: [["fission.bfcacheInParent", false]],
+ });
+
+ 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;
+}
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-navigation.js b/devtools/client/debugger/test/mochitest/browser_dbg-navigation.js
index 69e9a3fccb37..b89b834c98b1 100644
--- a/devtools/client/debugger/test/mochitest/browser_dbg-navigation.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg-navigation.js
@@ -20,24 +20,24 @@ add_task(async function() {
selectors: { getSelectedSource, getIsPaused, getCurrentThread },
getState
} = dbg;
-
+
+ info("Pause in the first document");
invokeInTab("firstCall");
await waitForPaused(dbg);
- await waitForRequestsToSettle(dbg);
+ info("Navigate while being paused in the first document");
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 addBreakpoint(dbg, "simple1.js", 4);
invokeInTab("main");
await waitForPaused(dbg);
- await waitForLoadedSource(dbg, "simple1");
- toggleScopes(dbg);
-
- assertPausedLocation(dbg);
+ let source = findSource(dbg, "simple1.js");
+ assertPausedAtSourceAndLine(dbg, source.id, 4);
is(countSources(dbg), 5, "5 sources are loaded.");
await waitForRequestsToSettle(dbg);
- // this test is intermittent without this
let onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
await navigate(dbg, "doc-scripts.html", ...SOURCES);
await onBreakpoint
@@ -45,23 +45,20 @@ add_task(async function() {
ok(!getIsPaused(getCurrentThread()), "Is not paused");
await waitForRequestsToSettle(dbg);
- // this test is intermittent without this
onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
await navigate(dbg, "doc-scripts.html", ...SOURCES);
await onBreakpoint
is(countSources(dbg), 5, "5 sources are loaded.");
- // Test that the current select source persists across reloads
+ info("Test that the current selected source persists across reloads");
await selectSource(dbg, "long.js");
await waitForRequestsToSettle(dbg);
- // this test is intermittent without this
onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT");
await reload(dbg, "long.js");
await onBreakpoint
await waitForSelectedSource(dbg, "long.js");
- await waitForRequestsToSettle(dbg);
ok(getSelectedSource().url.includes("long.js"), "Selected source is long.js");
});
diff --git a/devtools/client/debugger/test/mochitest/examples/doc-reload-link.html b/devtools/client/debugger/test/mochitest/examples/doc-reload-link.html
new file mode 100644
index 000000000000..41c9ee9e5787
--- /dev/null
+++ b/devtools/client/debugger/test/mochitest/examples/doc-reload-link.html
@@ -0,0 +1,5 @@
+
+
+reload via link
diff --git a/devtools/client/debugger/test/mochitest/helpers.js b/devtools/client/debugger/test/mochitest/helpers.js
index 4397e76a6424..0fa7d22965f1 100644
--- a/devtools/client/debugger/test/mochitest/helpers.js
+++ b/devtools/client/debugger/test/mochitest/helpers.js
@@ -399,7 +399,7 @@ function assertPausedAtSourceAndLine(dbg, expectedSourceId, expectedLine) {
const frames = dbg.selectors.getCurrentThreadFrames();
ok(frames.length >= 1, "Got at least one frame");
const { sourceId, line } = frames[0].location;
- ok(sourceId == expectedSourceId, "Frame has correct source");
+ is(sourceId, expectedSourceId, "Frame has correct source");
ok(
line == expectedLine,
`Frame paused at ${line}, but expected ${expectedLine}`