From f0abfb84f135da3f3e0a75a936a5226fb587a17b Mon Sep 17 00:00:00 2001 From: Jason Laster Date: Mon, 13 Feb 2017 21:56:06 -0500 Subject: [PATCH] Add additional integration tests (#2017) --- src/test/integration/runner.js | 63 ++++++++++++- src/test/integration/tests.js | 4 +- src/test/integration/tests/call-stack.js | 84 +++++++++++++++++ .../integration/tests/debugger-buttons.js | 63 +++++++++++++ src/test/integration/tests/iframes.js | 33 +++++++ src/test/integration/tests/index.js | 12 ++- .../integration/tests/pause-exceptions.js | 54 +++++++++++ .../integration/tests/pretty-print-paused.js | 33 +++++++ src/test/integration/tests/scopes.js | 32 +++++++ .../integration/tests/sourcemaps-bogus.js | 31 +++++++ src/test/integration/tests/sourcemaps.js | 56 ++++++++++++ src/test/integration/tests/sourcemaps2.js | 39 ++++++++ src/test/integration/tests/sources.js | 90 +++++++++++++++++++ src/test/integration/utils/commands.js | 9 +- src/test/integration/utils/index.js | 10 ++- src/test/integration/utils/mocha.js | 5 ++ src/test/integration/utils/mochitest.js | 7 ++ src/test/integration/utils/shared.js | 8 +- src/test/integration/utils/wait.js | 3 +- src/test/mochitest/browser_dbg-call-stack.js | 67 +++----------- .../mochitest/browser_dbg-debugger-buttons.js | 58 ++---------- src/test/mochitest/browser_dbg-iframes.js | 30 ++----- .../mochitest/browser_dbg-pause-exceptions.js | 50 ++--------- .../browser_dbg-pretty-print-paused.js | 24 ++--- src/test/mochitest/browser_dbg-scopes.js | 22 ++--- .../mochitest/browser_dbg-sourcemaps-bogus.js | 24 ++--- src/test/mochitest/browser_dbg-sourcemaps.js | 46 ++-------- src/test/mochitest/browser_dbg-sourcemaps2.js | 30 ++----- src/test/mochitest/browser_dbg-sources.js | 64 ++----------- src/test/mochitest/examples/doc-sources.html | 11 ++- 30 files changed, 718 insertions(+), 344 deletions(-) create mode 100644 src/test/integration/tests/call-stack.js create mode 100644 src/test/integration/tests/debugger-buttons.js create mode 100644 src/test/integration/tests/iframes.js create mode 100644 src/test/integration/tests/pause-exceptions.js create mode 100644 src/test/integration/tests/pretty-print-paused.js create mode 100644 src/test/integration/tests/scopes.js create mode 100644 src/test/integration/tests/sourcemaps-bogus.js create mode 100644 src/test/integration/tests/sourcemaps.js create mode 100644 src/test/integration/tests/sourcemaps2.js create mode 100644 src/test/integration/tests/sources.js diff --git a/src/test/integration/runner.js b/src/test/integration/runner.js index 1c7fa1c7ca..6872eb9545 100644 --- a/src/test/integration/runner.js +++ b/src/test/integration/runner.js @@ -8,8 +8,18 @@ const { breaking, breakpointsCond, prettyPrint, + prettyPrintPaused, keyboardNavigation, - keyboardShortcuts + keyboardShortcuts, + callStack, + debuggerButtons, + iframes, + pauseOnExceptions, + scopes, + sources, + sourceMaps, + sourceMaps2, + sourceMapsBogus } = require("./tests/index") window.ok = function ok(expected) { @@ -57,6 +67,57 @@ describe("Tests", () => { xit("keyboard shortcuts", async function() { await keyboardShortcuts(ctx); }) + + xit("callStack", async function() { + await callStack(ctx); + }); + + it("debuggerButtons", async function() { + await debuggerButtons(ctx); + }); + + it("iframes", async function() { + await iframes(ctx); + }); + + // expected 17 to equal 15 + xit("pauseOnExceptions", async function() { + await pauseOnExceptions(ctx); + }); + + it("prettyPrint", async function() { + await prettyPrint(ctx); + }); + + // timed out + xit("prettyPrintPaused", async function() { + await prettyPrintPaused(ctx); + }); + + // timed out + xit("scopes", async function() { + await scopes(ctx); + }); + + // expected 0 to equal 2 + xit("sources", async function() { + await sources(ctx); + }); + + // timed out + xit("sourceMaps", async function() { + await sourceMaps(ctx); + }); + + it("sourceMaps2", async function() { + await sourceMaps2(ctx); + }); + + // expected 2 to equal 1 + xit("sourceMapsBogus", async function() { + await sourceMapsBogus(ctx); + }); + }); mocha.run(); diff --git a/src/test/integration/tests.js b/src/test/integration/tests.js index 1deb4fe3cb..9a4cc86b74 100644 --- a/src/test/integration/tests.js +++ b/src/test/integration/tests.js @@ -1,6 +1,7 @@ const tests = require("./tests/index") const { setupTestRunner } = require("./utils/mocha") +const utils = require("./utils") const { isDevelopment } = require("devtools-config"); if (isDevelopment()) { @@ -8,5 +9,6 @@ if (isDevelopment()) { } module.exports = Object.assign({}, tests, { - setupTestRunner + setupTestRunner, + utils }); diff --git a/src/test/integration/tests/call-stack.js b/src/test/integration/tests/call-stack.js new file mode 100644 index 0000000000..1159b99498 --- /dev/null +++ b/src/test/integration/tests/call-stack.js @@ -0,0 +1,84 @@ +const { + initDebugger, + assertPausedLocation, + waitForPaused, + invokeInTab, + clickElement, + findElement, + findAllElements, + reload +} = require("../utils") + + +// checks to see if the frame is selected and the title is correct +function isFrameSelected(dbg, index, title) { + const $frame = findElement(dbg, "frame", index); + const frame = dbg.selectors.getSelectedFrame(dbg.getState()); + + const elSelected = $frame.classList.contains("selected"); + const titleSelected = frame.displayName == title; + + return elSelected && titleSelected; +} + +function toggleButton(dbg) { + const callStackBody = findElement(dbg, "callStackBody"); + return callStackBody.querySelector(".show-more"); +} + +function toggleCallStack(dbg) { + return findElement(dbg, "callStackHeader").click(); +} + +async function test1(ctx) { + const { ok, is, info } = ctx; + + const dbg = await initDebugger("doc-script-switching.html"); + + toggleCallStack(dbg); + + const notPaused = findElement(dbg, "callStackBody").innerText; + is(notPaused, "Not Paused", "Not paused message is shown"); + + invokeInTab(dbg, "firstCall"); + await waitForPaused(dbg); + + ok(isFrameSelected(dbg, 1, "secondCall"), "the first frame is selected"); + + clickElement(dbg, "frame", 2); + ok(isFrameSelected(dbg, 2, "firstCall"), "the second frame is selected"); + + let button = toggleButton(dbg); + ok(!button, "toggle button shouldn't be there"); +} + +async function test2(ctx) { + const { ok, is, info } = ctx; + + const dbg = await initDebugger("doc-frames.html"); + + toggleCallStack(dbg); + + invokeInTab(dbg, "startRecursion"); + await waitForPaused(dbg); + + ok(isFrameSelected(dbg, 1, "recurseA"), "the first frame is selected"); + + // check to make sure that the toggle button isn't there + let button = toggleButton(dbg); + let frames = findAllElements(dbg, "frames"); + is(button.innerText, "Expand Rows", "toggle button should be expand"); + is(frames.length, 7, "There should be at most seven frames"); + + button.click(); + + button = toggleButton(dbg); + frames = findAllElements(dbg, "frames"); + is(button.innerText, "Collapse Rows", "toggle button should be collapse"); + is(frames.length, 22, "All of the frames should be shown"); +} + +module.exports = { + test1, + test2 +} diff --git a/src/test/integration/tests/debugger-buttons.js b/src/test/integration/tests/debugger-buttons.js new file mode 100644 index 0000000000..ac235af20f --- /dev/null +++ b/src/test/integration/tests/debugger-buttons.js @@ -0,0 +1,63 @@ +const { + initDebugger, + assertPausedLocation, + waitForPaused, + invokeInTab, + clickElement, + findElement, + reload +} = require("../utils") + +function clickStepOver(dbg) { + clickElement(dbg, "stepOver"); + return waitForPaused(dbg); +} + +function clickStepIn(dbg) { + clickElement(dbg, "stepIn"); + return waitForPaused(dbg); +} + +function clickStepOut(dbg) { + clickElement(dbg, "stepOut"); + return waitForPaused(dbg); +} + +/** + * Test debugger buttons + * 1. resume + * 2. stepOver + * 3. stepIn + * 4. stepOver to the end of a function + * 5. stepUp at the end of a function + */ +module.exports = async function(ctx) { + const { ok, is, info } = ctx; + + const dbg = await initDebugger("doc-debugger-statements.html"); + + await reload(dbg); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "debugger-statements.html", 8); + + // resume + clickElement(dbg, "resume"); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "debugger-statements.html", 12); + + // step over + await clickStepOver(dbg); + assertPausedLocation(dbg, ctx, "debugger-statements.html", 13); + + // step into + await clickStepIn(dbg); + assertPausedLocation(dbg, ctx, "debugger-statements.html", 18); + + // step over + await clickStepOver(dbg); + assertPausedLocation(dbg, ctx, "debugger-statements.html", 20); + + // step out + await clickStepOut(dbg); + assertPausedLocation(dbg, ctx, "debugger-statements.html", 20); +} diff --git a/src/test/integration/tests/iframes.js b/src/test/integration/tests/iframes.js new file mode 100644 index 0000000000..342e3016f8 --- /dev/null +++ b/src/test/integration/tests/iframes.js @@ -0,0 +1,33 @@ +const { + initDebugger, + assertPausedLocation, + reload, + resume, + waitForPaused +} = require("../utils"); + +/** + * Test debugging a page with iframes + * 1. pause in the main thread + * 2. pause in the iframe + */ +module.exports = async function(ctx) { + const { ok, is, info } = ctx; + + const dbg = await initDebugger("doc-iframes.html"); + + // test pausing in the main thread + await reload(dbg); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "iframes.html", 8); + + // test pausing in the iframe + await resume(dbg); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "debugger-statements.html", 8); + + // test pausing in the iframe + await resume(dbg); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "debugger-statements.html", 12); +} diff --git a/src/test/integration/tests/index.js b/src/test/integration/tests/index.js index 9279a24880..7c6634bcc6 100644 --- a/src/test/integration/tests/index.js +++ b/src/test/integration/tests/index.js @@ -2,7 +2,17 @@ module.exports = { asm: require("./asm"), breaking: require("./breaking"), breakpointsCond: require("./breakpoints-cond"), + callStack: require("./call-stack"), + debuggerButtons: require("./debugger-buttons"), keyboardNavigation: require("./keyboard-navigation"), keyboardShortcuts: require("./keyboard-shortcuts"), - prettyPrint: require("./pretty-print") + iframes: require("./iframes"), + pauseOnExceptions: require("./pause-exceptions"), + prettyPrint: require("./pretty-print"), + prettyPrintPaused: require("./pretty-print-paused"), + scopes: require("./scopes"), + sources: require("./sources"), + sourceMaps: require("./sourcemaps"), + sourceMaps2: require("./sourcemaps2"), + sourceMapsBogus: require("./sourcemaps-bogus") } diff --git a/src/test/integration/tests/pause-exceptions.js b/src/test/integration/tests/pause-exceptions.js new file mode 100644 index 0000000000..9182e84450 --- /dev/null +++ b/src/test/integration/tests/pause-exceptions.js @@ -0,0 +1,54 @@ +const { + initDebugger, + assertPausedLocation, + invokeInTab, + togglePauseOnExceptions, + waitForPaused, + isPaused, + resume +} = require("../utils"); + +function uncaughtException(dbg) { + return invokeInTab(dbg, "uncaughtException").catch(() => {}); +} + +function caughtException(dbg) { + return invokeInTab(dbg, "caughtException"); +} + +/* + Tests Pausing on exception + 1. skip an uncaught exception + 2. pause on an uncaught exception + 3. pause on a caught error + 4. skip a caught error +*/ +module.exports = async function(ctx) { const { ok, is, info } = ctx; + + const dbg = await initDebugger("doc-exceptions.html"); + + // test skipping an uncaught exception + await togglePauseOnExceptions(dbg, false, false); + await uncaughtException(dbg); + ok(!isPaused(dbg)); + + // Test pausing on an uncaught exception + await togglePauseOnExceptions(dbg, true, false); + uncaughtException(dbg); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "exceptions.js", 2); + await resume(dbg); + + // Test pausing on a caught Error + caughtException(dbg); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "exceptions.js", 15); + await resume(dbg); + + // Test skipping a caught error + await togglePauseOnExceptions(dbg, true, true); + caughtException(dbg); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "exceptions.js", 17); + await resume(dbg); +} diff --git a/src/test/integration/tests/pretty-print-paused.js b/src/test/integration/tests/pretty-print-paused.js new file mode 100644 index 0000000000..f640f2d1ba --- /dev/null +++ b/src/test/integration/tests/pretty-print-paused.js @@ -0,0 +1,33 @@ +const { + initDebugger, + assertPausedLocation, + selectSource, + addBreakpoint, + invokeInTab, + resume, + waitForPaused, + waitForDispatch, + clickElement +} = require("../utils"); + +// Tests pretty-printing a source that is currently paused. + +module.exports = async function(ctx) { + const { ok, is, info } = ctx; + + const dbg = await initDebugger("doc-minified.html"); + + await selectSource(dbg, "math.min.js"); + await addBreakpoint(dbg, "math.min.js", 2); + + invokeInTab(dbg, "arithmetic"); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "math.min.js", 2); + + clickElement(dbg, "prettyPrintButton"); + await waitForDispatch(dbg, "TOGGLE_PRETTY_PRINT"); + + assertPausedLocation(dbg, ctx, "math.min.js:formatted", 18); + + await resume(dbg); +} diff --git a/src/test/integration/tests/scopes.js b/src/test/integration/tests/scopes.js new file mode 100644 index 0000000000..28acc7d03d --- /dev/null +++ b/src/test/integration/tests/scopes.js @@ -0,0 +1,32 @@ +const { + initDebugger, + waitForPaused, + invokeInTab, + clickElement, + findElement +} = require("../utils") + +function toggleNode(dbg, index) { + clickElement(dbg, "scopeNode", index); +} + +function getLabel(dbg, index) { + return findElement(dbg, "scopeNode", index).innerText; +} + +function toggleScopes(dbg) { + return findElement(dbg, "scopesHeader").click(); +} + +module.exports = async function(ctx) { + const { ok, is, info } = ctx; + const dbg = await initDebugger("doc-script-switching.html"); + + toggleScopes(dbg); + + invokeInTab(dbg, "firstCall"); + await waitForPaused(dbg); + + is(getLabel(dbg, 1), "secondCall"); + is(getLabel(dbg, 2), ""); +} diff --git a/src/test/integration/tests/sourcemaps-bogus.js b/src/test/integration/tests/sourcemaps-bogus.js new file mode 100644 index 0000000000..e314265775 --- /dev/null +++ b/src/test/integration/tests/sourcemaps-bogus.js @@ -0,0 +1,31 @@ +const { + initDebugger, + assertPausedLocation, + selectSource, + addBreakpoint, + invokeInTab, + waitForPaused +} = require("../utils"); + +// Test that an error while loading a sourcemap does not break +// debugging. + +module.exports = async function(ctx) { + const { ok, is, info } = ctx; + + const dbg = await initDebugger("doc-sourcemap-bogus.html"); + const { selectors: { getSources }, getState } = dbg; + + await selectSource(dbg, "bogus-map.js"); + + // We should still be able to set breakpoints and pause in the + // generated source. + await addBreakpoint(dbg, "bogus-map.js", 4); + invokeInTab(dbg, "runCode"); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "bogus-map.js", 4); + + // Make sure that only the single generated source exists. The + // sourcemap failed to download. + is(getSources(getState()).size, 1, "Only 1 source exists"); +} diff --git a/src/test/integration/tests/sourcemaps.js b/src/test/integration/tests/sourcemaps.js new file mode 100644 index 0000000000..70b0ae65d6 --- /dev/null +++ b/src/test/integration/tests/sourcemaps.js @@ -0,0 +1,56 @@ +const { + initDebugger, + assertPausedLocation, + findSource, + waitForSources, + selectSource, + addBreakpoint, + stepIn, + stepOut, + stepOver, + invokeInTab, + waitForPaused +} = require("../utils"); + +// Tests loading sourcemapped sources, setting breakpoints, and +// stepping in them. + +module.exports = async function(ctx) { const { ok, is, info } = ctx; + + const dbg = await initDebugger("doc-sourcemaps.html"); + const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg; + + await waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js"); + ok(true, "Original sources exist"); + const entrySrc = findSource(dbg, "entry.js"); + + await selectSource(dbg, entrySrc); + ok(dbg.win.cm.getValue().includes("window.keepMeAlive"), + "Original source text loaded correctly"); + + // Test that breakpoint sliding is not attempted. The breakpoint + // should not move anywhere. + await addBreakpoint(dbg, entrySrc, 13); + is(getBreakpoints(getState()).size, 1, "One breakpoint exists"); + ok(getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }), + "Breakpoint has correct line"); + + // Test breaking on a breakpoint + await addBreakpoint(dbg, "entry.js", 15); + is(getBreakpoints(getState()).size, 2, "Two breakpoints exist"); + ok(getBreakpoint(getState(), { sourceId: entrySrc.id, line: 15 }), + "Breakpoint has correct line"); + + invokeInTab(dbg, "keepMeAlive"); + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, entrySrc, 15); + + await stepIn(dbg); + assertPausedLocation(dbg, ctx, "times2.js", 2); + await stepOver(dbg); + assertPausedLocation(dbg, ctx, "times2.js", 3); + + await stepOut(dbg); + await stepOut(dbg); + assertPausedLocation(dbg, ctx, "entry.js", 16); +} diff --git a/src/test/integration/tests/sourcemaps2.js b/src/test/integration/tests/sourcemaps2.js new file mode 100644 index 0000000000..76bf490cab --- /dev/null +++ b/src/test/integration/tests/sourcemaps2.js @@ -0,0 +1,39 @@ +const { + initDebugger, + assertPausedLocation, + findSource, + waitForSources, + selectSource, + addBreakpoint, + invokeInTab, + waitForPaused +} = require("../utils"); + +// Tests loading sourcemapped sources, setting breakpoints, and +// stepping in them. + +// This source map does not have source contents, so it's fetched separately + +module.exports = async function(ctx) { + const { ok, is, info } = ctx; + const dbg = await initDebugger("doc-sourcemaps2.html"); + const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg; + + await waitForSources(dbg, "main.js", "main.min.js"); + + ok(true, "Original sources exist"); + const mainSrc = findSource(dbg, "main.js"); + + await selectSource(dbg, mainSrc); + + // Test that breakpoint is not off by a line. + await addBreakpoint(dbg, mainSrc, 4); + is(getBreakpoints(getState()).size, 1, "One breakpoint exists"); + ok(getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4 }), + "Breakpoint has correct line"); + + invokeInTab(dbg, "logMessage"); + + await waitForPaused(dbg); + assertPausedLocation(dbg, ctx, "main.js", 4); +} diff --git a/src/test/integration/tests/sources.js b/src/test/integration/tests/sources.js new file mode 100644 index 0000000000..940a667fe4 --- /dev/null +++ b/src/test/integration/tests/sources.js @@ -0,0 +1,90 @@ +const { + initDebugger, + clickElement, + invokeInTab, + pressKey, + selectSource, + evalInTab, + findElement, + findAllElements, + findElementWithSelector, + waitForSources, + waitForDispatch, + waitUntil +} = require("../utils"); + +// Tests that the source tree works. + +async function waitForSourceCount(dbg, i) { + // We are forced to wait until the DOM nodes appear because the + // source tree batches its rendering. + await waitUntil(() => { + return findAllElements(dbg, "sourceNodes").length === i; + }); +} + +module.exports = async function(ctx) { + const { ok, is, info } = ctx; + + const dbg = await initDebugger("doc-sources.html"); + const { selectors: { getSelectedSource }, getState } = dbg; + + await waitForSources( + dbg, "simple1", "simple2", "nested-source", "long.js" + ); + + // Expand nodes and make sure more sources appear. + is(findAllElements(dbg, "sourceNodes").length, 2); + + clickElement(dbg, "sourceArrow", 2); + is(findAllElements(dbg, "sourceNodes").length, 7); + + clickElement(dbg, "sourceArrow", 3); + is(findAllElements(dbg, "sourceNodes").length, 8); + + // Select a source. + ok( + !findElementWithSelector(dbg, ".sources-list .focused"), + "Source is not focused" + ); + + const selected = waitForDispatch(dbg, "SELECT_SOURCE"); + clickElement(dbg, "sourceNode", 4); + await selected; + + ok( + findElementWithSelector(dbg, ".sources-list .focused"), + "Source is focused" + ); + + ok( + getSelectedSource(getState()).get("url").includes("nested-source.js"), + "The right source is selected" + ); + + // Make sure new sources appear in the list. + invokeInTab(dbg, "loadScript") + + await waitForSourceCount(dbg, 9); + + is( + findElement(dbg, "sourceNode", 7).textContent, + "math.min.js", + "The dynamic script exists" + ); + + // Make sure named eval sources appear in the list. + evalInTab( + dbg, + "window.evaledFunc = function() {} //# sourceURL=evaled.js" + ) + + await waitForSourceCount(dbg, 11); + debugger + + is( + findElement(dbg, "sourceNode", 2).textContent, + "evaled.js", + "The eval script exists" + ); +} diff --git a/src/test/integration/utils/commands.js b/src/test/integration/utils/commands.js index cc6d20534f..b15c1b8c9a 100644 --- a/src/test/integration/utils/commands.js +++ b/src/test/integration/utils/commands.js @@ -4,9 +4,13 @@ function info(msg) { console.log(`info: ${msg}\n`); } -const { invokeInTab, selectMenuItem, pressKey, type } = require("./mocha"); +const { + evalInTab, invokeInTab, selectMenuItem, pressKey, type +} = require("./mocha"); -const { selectors, findSource, getSelector, info } = require("./shared"); +const { + selectors, findSource, getSelector, info, isPaused +} = require("./shared"); const { waitForSources, waitForDispatch, @@ -207,6 +211,7 @@ module.exports = { clickElement, navigate, invokeInTab, + evalInTab, rightClickElement, selectMenuItem, type, diff --git a/src/test/integration/utils/index.js b/src/test/integration/utils/index.js index 8a1f312e74..798490bfc3 100644 --- a/src/test/integration/utils/index.js +++ b/src/test/integration/utils/index.js @@ -5,7 +5,8 @@ const { waitForSources, waitForElement, waitForTargetEvent, - waitForThreadEvents + waitForThreadEvents, + waitUntil } = require("./wait"); const { @@ -29,6 +30,7 @@ const { togglePauseOnExceptions, clickElement, navigate, + evalInTab, invokeInTab, rightClickElement, selectMenuItem, @@ -41,6 +43,7 @@ const { findElementWithSelector, findAllElements, findSource, + isPaused, getSelector } = require("./shared") @@ -52,6 +55,7 @@ module.exports = { findElementWithSelector, findAllElements, findSource, + isPaused, getSelector, selectSource, stepOver, @@ -64,6 +68,7 @@ module.exports = { removeBreakpoint, togglePauseOnExceptions, clickElement, + evalInTab, invokeInTab, rightClickElement, selectMenuItem, @@ -75,5 +80,6 @@ module.exports = { waitForSources, waitForElement, waitForTargetEvent, - waitForThreadEvents + waitForThreadEvents, + waitUntil } diff --git a/src/test/integration/utils/mocha.js b/src/test/integration/utils/mocha.js index 91bb663ff9..0d27cedf7b 100644 --- a/src/test/integration/utils/mocha.js +++ b/src/test/integration/utils/mocha.js @@ -40,6 +40,10 @@ async function invokeInTab(dbg, fnc) { return dbg.client.debuggeeCommand(`${fnc}()`); } +async function evalInTab(dbg, script) { + return dbg.client.debuggeeCommand(script); +} + function selectMenuItem(dbg, index) { const doc = dbg.win.document; @@ -137,6 +141,7 @@ function setupTestRunner() { module.exports = { invokeInTab, + evalInTab, selectMenuItem, type, pressKey, diff --git a/src/test/integration/utils/mochitest.js b/src/test/integration/utils/mochitest.js index 3657fc343f..26422231fa 100644 --- a/src/test/integration/utils/mochitest.js +++ b/src/test/integration/utils/mochitest.js @@ -39,6 +39,12 @@ function invokeInTab(dbg, fnc) { }); } +function evalInTab(dbg, script) { + ContentTask.spawn(gBrowser.selectedBrowser, script, function(script) { + content.eval(script); + }); +} + function selectMenuItem(dbg, index) { // the context menu is in the toolbox window const doc = dbg.toolbox.win.document; @@ -103,6 +109,7 @@ async function initDebugger(url, ...sources) { module.exports = { invokeInTab, + evalInTab, selectMenuItem, pressKey, type, diff --git a/src/test/integration/utils/shared.js b/src/test/integration/utils/shared.js index 49735f29e0..9ba90f4d45 100644 --- a/src/test/integration/utils/shared.js +++ b/src/test/integration/utils/shared.js @@ -21,7 +21,7 @@ const selectors = { toggleBreakpoints: ".breakpoints-toggle", prettyPrintButton: ".prettyPrint", sourceFooter: ".source-footer", - sourceNode: i => `.sources-list .tree-node:nth-child(${i})`, + sourceNode: i => `.sources-list .tree-node:nth-child(${i}) .node`, sourceNodes: ".sources-list .tree-node", sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`, }; @@ -73,6 +73,11 @@ function findSource(dbg, url) { return source.toJS(); } +function isPaused(dbg) { + const { selectors: { getPause }, getState } = dbg; + return !!getPause(getState()); +} + function info(msg) { const message = `INFO: ${msg}\n`; if (typeof dump == "function") { @@ -89,5 +94,6 @@ module.exports = { findSource, selectors, getSelector, + isPaused, info } diff --git a/src/test/integration/utils/wait.js b/src/test/integration/utils/wait.js index 3bd8a7de4e..a75cd46ed6 100644 --- a/src/test/integration/utils/wait.js +++ b/src/test/integration/utils/wait.js @@ -197,5 +197,6 @@ module.exports = { waitForSources, waitForElement, waitForTargetEvent, - waitForThreadEvents + waitForThreadEvents, + waitUntil } diff --git a/src/test/mochitest/browser_dbg-call-stack.js b/src/test/mochitest/browser_dbg-call-stack.js index 54a401eeb5..7fb6a8a5c5 100644 --- a/src/test/mochitest/browser_dbg-call-stack.js +++ b/src/test/mochitest/browser_dbg-call-stack.js @@ -1,62 +1,17 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -// checks to see if the frame is selected and the title is correct -function isFrameSelected(dbg, index, title) { - const $frame = findElement(dbg, "frame", index); - const frame = dbg.selectors.getSelectedFrame(dbg.getState()); - - const elSelected = $frame.classList.contains("selected"); - const titleSelected = frame.displayName == title; - - return elSelected && titleSelected; -} - -function toggleButton(dbg) { - const callStackBody = findElement(dbg, "callStackBody"); - return callStackBody.querySelector(".show-more"); -} - -add_task(function* () { - const dbg = yield initDebugger("doc-script-switching.html"); - - toggleCallStack(dbg); - - const notPaused = findElement(dbg, "callStackBody").innerText; - is(notPaused, "Not Paused", "Not paused message is shown"); - - invokeInTab("firstCall"); - yield waitForPaused(dbg); - - ok(isFrameSelected(dbg, 1, "secondCall"), "the first frame is selected"); - - clickElement(dbg, "frame", 2); - ok(isFrameSelected(dbg, 2, "firstCall"), "the second frame is selected"); - - let button = toggleButton(dbg); - ok(!button, "toggle button shouldn't be there"); +const { + callStack, + setupTestRunner +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield callStack.test1(this); }); -add_task(function* () { - const dbg = yield initDebugger("doc-frames.html"); - - toggleCallStack(dbg); - - invokeInTab("startRecursion"); - yield waitForPaused(dbg); - - ok(isFrameSelected(dbg, 1, "recurseA"), "the first frame is selected"); - - // check to make sure that the toggle button isn't there - let button = toggleButton(dbg); - let frames = findAllElements(dbg, "frames"); - is(button.innerText, "Expand Rows", "toggle button should be expand"); - is(frames.length, 7, "There should be at most seven frames"); - - button.click(); - - button = toggleButton(dbg); - frames = findAllElements(dbg, "frames"); - is(button.innerText, "Collapse Rows", "toggle button should be collapse"); - is(frames.length, 22, "All of the frames should be shown"); +add_task(function*() { + setupTestRunner(this); + yield callStack.test2(this); }); diff --git a/src/test/mochitest/browser_dbg-debugger-buttons.js b/src/test/mochitest/browser_dbg-debugger-buttons.js index 0094650bc2..b330dadd4a 100644 --- a/src/test/mochitest/browser_dbg-debugger-buttons.js +++ b/src/test/mochitest/browser_dbg-debugger-buttons.js @@ -1,54 +1,12 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -function clickStepOver(dbg) { - clickElement(dbg, "stepOver"); - return waitForPaused(dbg); -} - -function clickStepIn(dbg) { - clickElement(dbg, "stepIn"); - return waitForPaused(dbg); -} - -function clickStepOut(dbg) { - clickElement(dbg, "stepOut"); - return waitForPaused(dbg); -} - -/** - * Test debugger buttons - * 1. resume - * 2. stepOver - * 3. stepIn - * 4. stepOver to the end of a function - * 5. stepUp at the end of a function - */ -add_task(function* () { - const dbg = yield initDebugger("doc-debugger-statements.html"); - - yield reload(dbg); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "debugger-statements.html", 8); - - // resume - clickElement(dbg, "resume"); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "debugger-statements.html", 12); - - // step over - yield clickStepOver(dbg); - assertPausedLocation(dbg, "debugger-statements.html", 13); - - // step into - yield clickStepIn(dbg); - assertPausedLocation(dbg, "debugger-statements.html", 18); - - // step over - yield clickStepOver(dbg); - assertPausedLocation(dbg, "debugger-statements.html", 20); - - // step out - yield clickStepOut(dbg); - assertPausedLocation(dbg, "debugger-statements.html", 20); +const { + setupTestRunner, + debuggerButtons +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield debuggerButtons(this); }); diff --git a/src/test/mochitest/browser_dbg-iframes.js b/src/test/mochitest/browser_dbg-iframes.js index 9039da1bea..d431b292d7 100644 --- a/src/test/mochitest/browser_dbg-iframes.js +++ b/src/test/mochitest/browser_dbg-iframes.js @@ -1,26 +1,12 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -/** - * Test debugging a page with iframes - * 1. pause in the main thread - * 2. pause in the iframe - */ -add_task(function* () { - const dbg = yield initDebugger("doc-iframes.html"); - - // test pausing in the main thread - yield reload(dbg); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "iframes.html", 8); - - // test pausing in the iframe - yield resume(dbg); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "debugger-statements.html", 8); - - // test pausing in the iframe - yield resume(dbg); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "debugger-statements.html", 12); +const { + setupTestRunner, + iframes +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield iframes(this); }); diff --git a/src/test/mochitest/browser_dbg-pause-exceptions.js b/src/test/mochitest/browser_dbg-pause-exceptions.js index 133316b546..89d80ab9cf 100644 --- a/src/test/mochitest/browser_dbg-pause-exceptions.js +++ b/src/test/mochitest/browser_dbg-pause-exceptions.js @@ -1,46 +1,12 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -function uncaughtException() { - return invokeInTab("uncaughtException").catch(() => {}); -} - -function caughtException() { - return invokeInTab("caughtException"); -} - -/* - Tests Pausing on exception - 1. skip an uncaught exception - 2. pause on an uncaught exception - 3. pause on a caught error - 4. skip a caught error -*/ -add_task(function* () { - const dbg = yield initDebugger("doc-exceptions.html"); - - // test skipping an uncaught exception - yield togglePauseOnExceptions(dbg, false, false); - yield uncaughtException(); - ok(!isPaused(dbg)); - - // Test pausing on an uncaught exception - yield togglePauseOnExceptions(dbg, true, false); - uncaughtException(); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "exceptions.js", 2); - yield resume(dbg); - - // Test pausing on a caught Error - caughtException(); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "exceptions.js", 15); - yield resume(dbg); - - // Test skipping a caught error - yield togglePauseOnExceptions(dbg, true, true); - caughtException(); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "exceptions.js", 17); - yield resume(dbg); +const { + setupTestRunner, + pauseOnExceptions +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield pauseOnExceptions(this); }); diff --git a/src/test/mochitest/browser_dbg-pretty-print-paused.js b/src/test/mochitest/browser_dbg-pretty-print-paused.js index 73919e65e8..37cc1a79ed 100644 --- a/src/test/mochitest/browser_dbg-pretty-print-paused.js +++ b/src/test/mochitest/browser_dbg-pretty-print-paused.js @@ -3,20 +3,12 @@ // Tests pretty-printing a source that is currently paused. -add_task(function* () { - const dbg = yield initDebugger("doc-minified.html"); - - yield selectSource(dbg, "math.min.js"); - yield addBreakpoint(dbg, "math.min.js", 2); - - invokeInTab("arithmetic"); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "math.min.js", 2); - - clickElement(dbg, "prettyPrintButton"); - yield waitForDispatch(dbg, "TOGGLE_PRETTY_PRINT"); - - assertPausedLocation(dbg, "math.min.js:formatted", 18); - - yield resume(dbg); +const { + setupTestRunner, + prettyPrintPaused +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield prettyPrintPaused(this); }); diff --git a/src/test/mochitest/browser_dbg-scopes.js b/src/test/mochitest/browser_dbg-scopes.js index cc1037a2a2..02aa04a378 100644 --- a/src/test/mochitest/browser_dbg-scopes.js +++ b/src/test/mochitest/browser_dbg-scopes.js @@ -1,18 +1,12 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -function getLabel(dbg, index) { - return findElement(dbg, "scopeNode", index).innerText; -} - -add_task(function* () { - const dbg = yield initDebugger("doc-script-switching.html"); - - toggleScopes(dbg); - - invokeInTab("firstCall"); - yield waitForPaused(dbg); - - is(getLabel(dbg, 1), "secondCall"); - is(getLabel(dbg, 2), ""); +const { + setupTestRunner, + scopes +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield scopes(this); }); diff --git a/src/test/mochitest/browser_dbg-sourcemaps-bogus.js b/src/test/mochitest/browser_dbg-sourcemaps-bogus.js index e8c6070fc3..df5e6b4a86 100644 --- a/src/test/mochitest/browser_dbg-sourcemaps-bogus.js +++ b/src/test/mochitest/browser_dbg-sourcemaps-bogus.js @@ -4,20 +4,12 @@ // Test that an error while loading a sourcemap does not break // debugging. -add_task(function* () { - const dbg = yield initDebugger("doc-sourcemap-bogus.html"); - const { selectors: { getSources }, getState } = dbg; - - yield selectSource(dbg, "bogus-map.js"); - - // We should still be able to set breakpoints and pause in the - // generated source. - yield addBreakpoint(dbg, "bogus-map.js", 4); - invokeInTab("runCode"); - yield waitForPaused(dbg); - assertPausedLocation(dbg, "bogus-map.js", 4); - - // Make sure that only the single generated source exists. The - // sourcemap failed to download. - is(getSources(getState()).size, 1, "Only 1 source exists"); +const { + setupTestRunner, + sourceMapsBogus +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield sourceMapsBogus(this); }); diff --git a/src/test/mochitest/browser_dbg-sourcemaps.js b/src/test/mochitest/browser_dbg-sourcemaps.js index 30fd7b70c1..c199d6a0d3 100644 --- a/src/test/mochitest/browser_dbg-sourcemaps.js +++ b/src/test/mochitest/browser_dbg-sourcemaps.js @@ -3,42 +3,12 @@ // Tests loading sourcemapped sources, setting breakpoints, and // stepping in them. - -add_task(function* () { - const dbg = yield initDebugger("doc-sourcemaps.html"); - const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg; - - yield waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js"); - ok(true, "Original sources exist"); - const entrySrc = findSource(dbg, "entry.js"); - - yield selectSource(dbg, entrySrc); - ok(dbg.win.cm.getValue().includes("window.keepMeAlive"), - "Original source text loaded correctly"); - - // Test that breakpoint sliding is not attempted. The breakpoint - // should not move anywhere. - yield addBreakpoint(dbg, entrySrc, 13); - is(getBreakpoints(getState()).size, 1, "One breakpoint exists"); - ok(getBreakpoint(getState(), { sourceId: entrySrc.id, line: 13 }), - "Breakpoint has correct line"); - - // Test breaking on a breakpoint - yield addBreakpoint(dbg, "entry.js", 15); - is(getBreakpoints(getState()).size, 2, "Two breakpoints exist"); - ok(getBreakpoint(getState(), { sourceId: entrySrc.id, line: 15 }), - "Breakpoint has correct line"); - - invokeInTab("keepMeAlive"); - yield waitForPaused(dbg); - assertPausedLocation(dbg, entrySrc, 15); - - yield stepIn(dbg); - assertPausedLocation(dbg, "times2.js", 2); - yield stepOver(dbg); - assertPausedLocation(dbg, "times2.js", 3); - - yield stepOut(dbg); - yield stepOut(dbg); - assertPausedLocation(dbg, "entry.js", 16); +const { + setupTestRunner, + sourceMaps +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield sourceMaps(this); }); diff --git a/src/test/mochitest/browser_dbg-sourcemaps2.js b/src/test/mochitest/browser_dbg-sourcemaps2.js index 022f25fd6d..417d42dd7f 100644 --- a/src/test/mochitest/browser_dbg-sourcemaps2.js +++ b/src/test/mochitest/browser_dbg-sourcemaps2.js @@ -5,26 +5,12 @@ // stepping in them. // This source map does not have source contents, so it's fetched separately - -add_task(function* () { - const dbg = yield initDebugger("doc-sourcemaps2.html"); - const { selectors: { getBreakpoint, getBreakpoints }, getState } = dbg; - - yield waitForSources(dbg, "main.js", "main.min.js"); - - ok(true, "Original sources exist"); - const mainSrc = findSource(dbg, "main.js"); - - yield selectSource(dbg, mainSrc); - - // Test that breakpoint is not off by a line. - yield addBreakpoint(dbg, mainSrc, 4); - is(getBreakpoints(getState()).size, 1, "One breakpoint exists"); - ok(getBreakpoint(getState(), { sourceId: mainSrc.id, line: 4 }), - "Breakpoint has correct line"); - - invokeInTab("logMessage"); - - yield waitForPaused(dbg); - assertPausedLocation(dbg, "main.js", 4); +const { + setupTestRunner, + sourceMaps2 +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield sourceMaps2(this); }); diff --git a/src/test/mochitest/browser_dbg-sources.js b/src/test/mochitest/browser_dbg-sources.js index 39b6ed6c82..031e466af2 100644 --- a/src/test/mochitest/browser_dbg-sources.js +++ b/src/test/mochitest/browser_dbg-sources.js @@ -1,60 +1,12 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -// Tests that the source tree works. - -function* waitForSourceCount(dbg, i) { - // We are forced to wait until the DOM nodes appear because the - // source tree batches its rendering. - yield waitUntil(() => { - return findAllElements(dbg, "sourceNodes").length === i; - }); -} - -add_task(function* () { - const dbg = yield initDebugger("doc-sources.html"); - const { selectors: { getSelectedSource }, getState } = dbg; - - yield waitForSources(dbg, "simple1"); - - // Expand nodes and make sure more sources appear. - is(findAllElements(dbg, "sourceNodes").length, 2); - - clickElement(dbg, "sourceArrow", 2); - is(findAllElements(dbg, "sourceNodes").length, 7); - - clickElement(dbg, "sourceArrow", 3); - is(findAllElements(dbg, "sourceNodes").length, 8); - - // Select a source. - ok(!findElementWithSelector(dbg, ".sources-list .focused"), - "Source is not focused"); - const selected = waitForDispatch(dbg, "SELECT_SOURCE"); - clickElement(dbg, "sourceNode", 4); - yield selected; - ok(findElementWithSelector(dbg, ".sources-list .focused"), - "Source is focused"); - ok(getSelectedSource(getState()).get("url").includes("nested-source.js"), - "The right source is selected"); - - // Make sure new sources appear in the list. - ContentTask.spawn(gBrowser.selectedBrowser, null, function() { - const script = content.document.createElement("script"); - script.src = "math.min.js"; - content.document.body.appendChild(script); - }); - - yield waitForSourceCount(dbg, 9); - is(findElement(dbg, "sourceNode", 7).textContent, - "math.min.js", - "The dynamic script exists"); - - // Make sure named eval sources appear in the list. - ContentTask.spawn(gBrowser.selectedBrowser, null, function() { - content.eval("window.evaledFunc = function() {} //# sourceURL=evaled.js"); - }); - yield waitForSourceCount(dbg, 11); - is(findElement(dbg, "sourceNode", 2).textContent, - "evaled.js", - "The eval script exists"); +const { + setupTestRunner, + sources +} = require("devtools/client/debugger/new/integration-tests"); + +add_task(function*() { + setupTestRunner(this); + yield sources(this); }); diff --git a/src/test/mochitest/examples/doc-sources.html b/src/test/mochitest/examples/doc-sources.html index 14cc86701a..ce946994b3 100644 --- a/src/test/mochitest/examples/doc-sources.html +++ b/src/test/mochitest/examples/doc-sources.html @@ -6,18 +6,23 @@ Debugger test page - + + - -