diff options
Diffstat (limited to 'devtools/client/debugger/test/mochitest/integration-tests')
4 files changed, 464 insertions, 0 deletions
diff --git a/devtools/client/debugger/test/mochitest/integration-tests/1-reload-same-original.js b/devtools/client/debugger/test/mochitest/integration-tests/1-reload-same-original.js new file mode 100644 index 0000000000..3b6bc79226 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/integration-tests/1-reload-same-original.js @@ -0,0 +1,138 @@ +/* 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/>. */ + +/* import-globals-from ../head.js */ + +/** + * This first test will focus on original.js file whose content changes + * which affects the related generated file: bundle.js + * + * In the first reload, v2/original.js will only change with new lines being added + * before the line where we set a breakpoint. So that the breakpoint, if not + * automatically shifted, will now be against an empty line. + * + * In the second reload, v3/original.js will be trimmed, so that the line + * where we set a breakpoint against, has been removed. + */ + +"use strict"; + +addIntegrationTask(async function testReloadingStableOriginalSource( + testServer, + testUrl, + { isCompressed } +) { + info(" # Test reload a stable source whose content changes"); + const dbg = await initDebuggerWithAbsoluteURL(testUrl, "original.js"); + + info("Add initial breakpoint"); + await selectSource(dbg, "original.js"); + await addBreakpoint(dbg, "original.js", 6); + + info("Check that only one breakpoint is set"); + is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint exists"); + is( + dbg.client.getServerBreakpointsList().length, + 1, + "One breakpoint exists on the server" + ); + + info("Check that the breakpoint location info is correct"); + let breakpoint = dbg.selectors.getBreakpointsList(dbg)[0]; + is(breakpoint.location.line, 6); + if (isCompressed) { + is(breakpoint.generatedLocation.line, 1); + is(breakpoint.generatedLocation.column, 1056); + } else { + is(breakpoint.generatedLocation.line, 82); + } + + const expectedOriginalFileContentOnBreakpointLine = "await bar();"; + const expectedGeneratedFileContentOnBreakpointLine = "await bar();"; + + info("Check that the breakpoint is displayed on the correct line in the ui"); + await assertBreakpoint(dbg, 6); + + info("Check that breakpoint is on the first line within the function `foo`"); + assertTextContentOnLine(dbg, 6, expectedOriginalFileContentOnBreakpointLine); + + info( + "Check that the breakpoint is displayed in correct location in bundle.js (generated source)" + ); + await selectSource(dbg, "bundle.js"); + if (isCompressed) { + await assertBreakpoint(dbg, 1); + } else { + await assertBreakpoint(dbg, 82); + assertTextContentOnLine( + dbg, + 82, + expectedGeneratedFileContentOnBreakpointLine + ); + } + + await closeTab(dbg, "bundle.js"); + + // This reload changes the content of the original file + // which will cause the location of the breakpoint to change + info("Reload with a new version of the file"); + testServer.switchToNextVersion(); + await reload(dbg, "bundle.js", "original.js"); + await wait(1000); + + info( + "Check that no breakpoint is restore as original line 6 is no longer breakable" + ); + is(dbg.selectors.getBreakpointCount(), 0, "No breakpoint exists"); + + info("Invoke `foo` to trigger breakpoint"); + invokeInTab("foo"); + await wait(1000); + + // TODO: Intermittently pauses (especially when in compressed) + // Need to investigate + if (isPaused(dbg)) { + await resume(dbg); + } + assertNotPaused(dbg); + + await closeTab(dbg, "bundle.js"); + + info("Add a second breakpoint"); + await addBreakpoint(dbg, "original.js", 13); + + is(dbg.selectors.getBreakpointCount(dbg), 1, "The breakpoint exist"); + + info("Check that the original location of the new breakpoint is correct"); + breakpoint = dbg.selectors.getBreakpointsList(dbg)[0]; + is(breakpoint.location.line, 13); + if (isCompressed) { + is(breakpoint.generatedLocation.line, 1); + is(breakpoint.generatedLocation.column, 1089); + } else { + is(breakpoint.generatedLocation.line, 89); + } + + // This reload removes the content related to the lines in the original + // file where the breakpoints where set. + // NOTE: When we reload, the `foo` function no longer exists + // and the original.js file is now 3 lines long + info("Reload and observe no breakpoints"); + testServer.switchToNextVersion(); + await reload(dbg, "original.js"); + + // There will initially be zero breakpoints, but wait to make sure none are + // installed while syncing. + await wait(1000); + + assertNotPaused(dbg); + + is(dbg.selectors.getBreakpointCount(dbg), 0, "No breakpoints"); + // TODO: fails intermitently, look to fix + /*is( + dbg.client.getServerBreakpointsList().length, + 2, + "No breakpoint exists on the server" + );*/ +}); diff --git a/devtools/client/debugger/test/mochitest/integration-tests/2-reload-replaced-original.js b/devtools/client/debugger/test/mochitest/integration-tests/2-reload-replaced-original.js new file mode 100644 index 0000000000..a74b32776b --- /dev/null +++ b/devtools/client/debugger/test/mochitest/integration-tests/2-reload-replaced-original.js @@ -0,0 +1,126 @@ +/* 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/>. */ + +/* import-globals-from ../head.js */ + +/** + * This second test will focus on v1/removed-original.js which is an original source mapped file. + * This source is mapped to replaced-bundle.js. + * In the first reload (v2), this original source is removed and another original file: v2/new-original.js + * will replace the content of the removed-original.js in the replaced-bundle.js generated file. + * And finally, in the second reload (v3) everything is removed, both original and generated source. + * + * Note that great care is done to ensure that new-original replaces removed-original with the + * exact same breakable lines and columns. So that the breakpoint isn't simply removed + * because the location is no longer breakable. + */ + +"use strict"; + +addIntegrationTask(async function testReloadingRemovedOriginalSources( + testServer, + testUrl, + { isCompressed } +) { + info(" # Test reloading a source that is replaced and then removed"); + testServer.backToFirstVersion(); + + const dbg = await initDebuggerWithAbsoluteURL(testUrl, "removed-original.js"); + + info("Add initial breakpoint"); + await selectSource(dbg, "removed-original.js"); + await addBreakpoint(dbg, "removed-original.js", 4); + + // Assert the precise behavior of the breakpoint before reloading + invokeInTab("removedOriginal"); + await waitForPaused(dbg); + const replacedSource = findSource(dbg, "removed-original.js"); + assertPausedAtSourceAndLine(dbg, replacedSource.id, 4); + assertTextContentOnLine(dbg, 4, 'console.log("Removed original");'); + await assertBreakpoint(dbg, 4); + + is(dbg.selectors.getBreakpointCount(), 1, "One breakpoint exists"); + is( + dbg.client.getServerBreakpointsList().length, + 1, + "One breakpoint exists on the server" + ); + + let breakpoint = dbg.selectors.getBreakpointsList()[0]; + is(breakpoint.location.sourceUrl, replacedSource.url); + is(breakpoint.location.line, 4); + if (isCompressed) { + is(breakpoint.generatedLocation.line, 1); + is(breakpoint.generatedLocation.column, 992); + } else { + is(breakpoint.generatedLocation.line, 80); + } + + await resume(dbg); + + info( + "Reload, which should remove the original file and a add a new original file which will replace its content in the generated file" + ); + const syncBp = waitForDispatch(dbg.store, "SET_BREAKPOINT"); + testServer.switchToNextVersion(); + await reload(dbg, "new-original.js"); + await syncBp; + + // Assert the new breakpoint being created after reload + // For now, the current behavior of the debugger is that: + // the breakpoint is still hit based on the generated source/bundle file + // and the UI updates itself to mention the new original file. + await waitForPaused(dbg); + const newSource = findSource(dbg, "new-original.js"); + assertPausedAtSourceAndLine(dbg, newSource.id, 4); + assertTextContentOnLine(dbg, 4, 'console.log("New original");'); + await assertBreakpoint(dbg, 4); + + is(dbg.selectors.getBreakpointCount(), 1, "One breakpoint exists"); + is( + dbg.client.getServerBreakpointsList().length, + 1, + "One breakpoint exists on the server" + ); + + breakpoint = dbg.selectors.getBreakpointsList()[0]; + is(breakpoint.location.sourceUrl, newSource.url); + is(breakpoint.location.line, 4); + if (isCompressed) { + is(breakpoint.generatedLocation.line, 1); + is(breakpoint.generatedLocation.column, 992); + } else { + is(breakpoint.generatedLocation.line, 80); + } + + await resume(dbg); + + info( + "Reload a last time to remove both original and generated sources entirely" + ); + testServer.switchToNextVersion(); + await reload(dbg); + + // Let some time for breakpoint syncing to be buggy and recreated unexpected breakpoint + await wait(1000); + info("Assert that sources and breakpoints are gone and we aren't paused"); + ok( + !sourceExists(dbg, "removed-original.js"), + "removed-original is not present" + ); + ok(!sourceExists(dbg, "new-original.js"), "new-original is not present"); + ok( + !sourceExists(dbg, "replaced-bundle.js"), + "replaced-bundle is not present" + ); + assertNotPaused(dbg); + is(dbg.selectors.getBreakpointCount(), 0, "We no longer have any breakpoint"); + // The breakpoint for the removed source still exists, atm this difficult to fix + // as the frontend never loads the source. + is( + dbg.client.getServerBreakpointsList().length, + 1, + "One breakpoint still exists on the server" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/integration-tests/3-reload-changed-generated.js b/devtools/client/debugger/test/mochitest/integration-tests/3-reload-changed-generated.js new file mode 100644 index 0000000000..3f9aad7923 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/integration-tests/3-reload-changed-generated.js @@ -0,0 +1,171 @@ +/* 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/>. */ + +/* import-globals-from ../head.js */ + +/** + * This first test will focus on original-with-no-update.js file where the bundle-with-another-original.js file + * content changes because of another-original.js + */ + +"use strict"; + +addIntegrationTask(async function testReloadingChangedGeneratedSource( + testServer, + testUrl, + { isCompressed } +) { + info( + " # Test reload an original source whose generated source content changes" + ); + testServer.backToFirstVersion(); + const dbg = await initDebuggerWithAbsoluteURL( + testUrl, + "original-with-no-update.js" + ); + + info("Add initial breakpoint"); + await selectSource(dbg, "original-with-no-update.js"); + await addBreakpoint(dbg, "original-with-no-update.js", 6); + + info("Check that only one breakpoint is set"); + is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint exists"); + + info("Check that the breakpoint location info is correct"); + let breakpoint = dbg.selectors.getBreakpointsList(dbg)[0]; + is(breakpoint.location.line, 6); + if (isCompressed) { + is(breakpoint.generatedLocation.line, 1); + is(breakpoint.generatedLocation.column, 1062); + } else { + is(breakpoint.generatedLocation.line, 82); + } + + const expectedOriginalFileContentOnBreakpointLine = "await baabar();"; + const expectedGeneratedFileContentOnBreakpointLine = "await baabar();"; + + info("Check that the breakpoint is displayed on the correct line in the ui"); + await assertBreakpoint(dbg, 6); + + info("Check that breakpoint is on the first line within the function `foo`"); + assertTextContentOnLine(dbg, 6, expectedOriginalFileContentOnBreakpointLine); + + info( + "Check that the breakpoint is displayed in correct location in bundle-with-another-original.js (generated source)" + ); + await selectSource(dbg, "bundle-with-another-original.js"); + if (isCompressed) { + await assertBreakpoint(dbg, 1); + } else { + await assertBreakpoint(dbg, 82); + assertTextContentOnLine( + dbg, + 82, + expectedGeneratedFileContentOnBreakpointLine + ); + } + + await closeTab(dbg, "bundle-with-another-original.js"); + + // This reload changes the content of the generated file + // which will cause the location of the breakpoint to change + info("Reload with a new version of the file"); + const waitUntilNewBreakpointIsSet = waitForDispatch( + dbg.store, + "SET_BREAKPOINT" + ); + testServer.switchToNextVersion(); + await reload( + dbg, + "bundle-with-another-original.js", + "original-with-no-update.js" + ); + await waitUntilNewBreakpointIsSet; + + if (!isCompressed) { + await waitForPaused(dbg); + + // This is a bug where the server does not recieve updates to breakpoints + // 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"); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "another-original.js").id, + 5 + ); + await assertNoBreakpoint(dbg, 5); + assertTextContentOnLine(dbg, 5, "funcC();"); + + await selectSource(dbg, "bundle-with-another-original.js"); + + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "bundle-with-another-original.js").id, + 82 + ); + await assertNoBreakpoint(dbg, 82); + assertTextContentOnLine(dbg, 82, "funcC();"); + + await resume(dbg); + await waitForPaused(dbg); + + info( + "Check that the breakpoint is displayed and paused on the correct line" + ); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "original-with-no-update.js").id, + 6 + ); + } else { + // Assert that it does not pause in commpressed files + assertNotPaused(dbg); + } + await assertBreakpoint(dbg, 6); + + info( + "Check that though the breakpoint has moved, it is still on the first line within the function `foo`" + ); + assertTextContentOnLine(dbg, 6, expectedOriginalFileContentOnBreakpointLine); + + info( + "Check that the breakpoint is displayed in correct location in bundle-with-another-original.js (generated source)" + ); + 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. + getCM(dbg).scrollIntoView({ line: 103, ch: 0 }); + + if (isCompressed) { + await assertBreakpoint(dbg, 1); + } else { + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "bundle-with-another-original.js").id, + 103 + ); + await assertBreakpoint(dbg, 103); + assertTextContentOnLine( + dbg, + 103, + expectedGeneratedFileContentOnBreakpointLine + ); + } + + info("Check that only one breakpoint is still set"); + is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint exists"); + + info("Check that the original location has changed"); + breakpoint = dbg.selectors.getBreakpointsList(dbg)[0]; + is(breakpoint.location.line, 6); + if (isCompressed) { + is(breakpoint.generatedLocation.line, 1); + is(breakpoint.generatedLocation.column, 1132); + } else { + is(breakpoint.generatedLocation.line, 103); + } + + await closeTab(dbg, "bundle-with-another-original.js"); +}); diff --git a/devtools/client/debugger/test/mochitest/integration-tests/README.md b/devtools/client/debugger/test/mochitest/integration-tests/README.md new file mode 100644 index 0000000000..1816de0938 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/integration-tests/README.md @@ -0,0 +1,29 @@ +# Integration tests folder + +This folder contains all the sub tests ran by the integration tests. +The integration tests are in the parent folder and are named `browser_dbg-integration-*.js`. +Each time you execute one of the integration tests, all the sub tests implemented in this folder will be ran. +Sub tests will be ran in a precise order, this is why the module names are prefixed by a number. + +Sub tests are javascript files which have all typical test helpers available in their scope: +* devtools/client/shared/test/shared-head.js +* devtools/client/debugger/test/mochitest/shared-head.js + +They should call the `addIntegrationTask()` method to register a new sub test: +``` +addIntegrationTask(async function testMyNewIntegrationSubTest( + testServer, + testUrl, + { isCompressed } +) { + info("My new integration sub test"); + + // `testServer` is a reference to the fake http server returned by `createVersionizedHttpTestServer()`. + // This can be useful to better control the actual content delivered by the server. + + // `testUrl` is the URL of the test page the the debugger currently inspects. + + // The third argument is the environment object, that helps know which particular integration test currently runs. + // You may have different assertions based on the actual test that runs. +}); +``` |