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}`