diff --git a/.eslintignore b/.eslintignore index 35dfd77cb57a..e7999a5eafee 100644 --- a/.eslintignore +++ b/.eslintignore @@ -106,6 +106,7 @@ devtools/client/shared/webpack/shims/test/test_clipboard.html devtools/shared/qrcode/tests/mochitest/test_decode.html devtools/shared/tests/mochitest/*.html devtools/shared/webconsole/test/test_*.html +devtools/client/webreplay/mochitest/examples/*.html # Soon to be removed, the new/ directory is explicitly excluded below due to # also being an imported repository. diff --git a/devtools/client/debugger/new/test/mochitest/browser.ini b/devtools/client/debugger/new/test/mochitest/browser.ini index 497d58d9ab09..a28bb68efefc 100644 --- a/devtools/client/debugger/new/test/mochitest/browser.ini +++ b/devtools/client/debugger/new/test/mochitest/browser.ini @@ -656,11 +656,6 @@ support-files = examples/simple-worker.js examples/doc-event-handler.html examples/doc-eval-throw.html - examples/doc_rr_basic.html - examples/doc_rr_continuous.html - examples/doc_rr_logs.html - examples/doc_rr_recovery.html - examples/doc_rr_error.html [browser_dbg-asm.js] [browser_dbg-async-stepping.js] @@ -775,36 +770,3 @@ skip-if = true [browser_dbg-windowless-workers.js] [browser_dbg-event-handler.js] [browser_dbg-eval-throw.js] -[browser_dbg_rr_breakpoints-01.js] -skip-if = true # bug 1513057 os != "mac" || debug || !nightly_build -[browser_dbg_rr_breakpoints-02.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_breakpoints-03.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_breakpoints-04.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_breakpoints-05.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_record.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_stepping-01.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_stepping-02.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_stepping-03.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_stepping-04.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_recovery-01.js] -skip-if = true # See bug 1481009 -[browser_dbg_rr_replay-01.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_replay-02.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_replay-03.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_console_warp-01.js] -skip-if = true # os != "mac" || debug || !nightly_build -[browser_dbg_rr_console_warp-02.js] -skip-if = true # os != "mac" || debug || !nightly_build - diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg-console.js b/devtools/client/debugger/new/test/mochitest/browser_dbg-console.js index 965b36b84d55..cc5d2acd52f7 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg-console.js +++ b/devtools/client/debugger/new/test/mochitest/browser_dbg-console.js @@ -5,7 +5,7 @@ add_task(async function() { await selectSource(dbg, "switching-01"); // open the console - await getSplitConsole(dbg); + await getDebuggerSplitConsole(dbg); ok(dbg.toolbox.splitConsole, "Split console is shown."); // close the console diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_console_warp-02.js b/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_console_warp-02.js deleted file mode 100644 index 6502156c75b4..000000000000 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_console_warp-02.js +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - - -// This functionality was copied from devtools/client/webconsole/test/mochitest/head.js, -// since this test straddles both the web console and the debugger. I couldn't -// figure out how to load that script directly here. -function waitForThreadEvents(threadClient, eventName) { - info(`Waiting for thread event '${eventName}' to fire.`); - - return new Promise(function(resolve, reject) { - threadClient.addListener(eventName, function onEvent(eventName, ...args) { - info(`Thread event '${eventName}' fired.`); - threadClient.removeListener(eventName, onEvent); - resolve.apply(resolve, args); - }); - }); -} - - -// Test basic console time warping functionality in web replay. -async function test() { - waitForExplicitFinish(); - - const dbg = await attachRecordingDebugger( - "doc_rr_logs.html", - { waitForRecording: true } - ); - - const {tab, toolbox, threadClient} = dbg; - const console = await getSplitConsole(dbg); - const hud = console.hud; - - let message = await warpToMessage(hud, threadClient, "number: 1"); - ok(!message.classList.contains("paused-before"), "paused before message is not shown"); - - await stepOverToLine(threadClient, 18); - await reverseStepOverToLine(threadClient, 17); - - message = findMessage(hud, "number: 1") - ok(message.classList.contains("paused-before"), "paused before message is shown"); - - await toolbox.destroy(); - await gBrowser.removeTab(tab); - finish(); -} diff --git a/devtools/client/debugger/new/test/mochitest/head.js b/devtools/client/debugger/new/test/mochitest/head.js index 7b694374d9db..4ea3838d6668 100644 --- a/devtools/client/debugger/new/test/mochitest/head.js +++ b/devtools/client/debugger/new/test/mochitest/head.js @@ -47,16 +47,6 @@ const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/new/test/mochitest/examples/"; -async function waitUntilPredicate(predicate) { - let result; - await waitUntil(() => { - result = predicate(); - return result; - }) - - return result; -} - // NOTE: still experimental, the screenshots might not be exactly correct async function takeScreenshot(dbg) { let canvas = dbg.win.document.createElementNS( @@ -70,193 +60,3 @@ async function takeScreenshot(dbg) { await waitForTime(1000); dump(`[SCREENSHOT] ${canvas.toDataURL()}\n`); } - -// Attach a debugger to a tab, returning a promise that resolves with the -// debugger's toolbox. -async function attachDebugger(tab) { - let target = await TargetFactory.forTab(tab); - let toolbox = await gDevTools.showToolbox(target, "jsdebugger"); - return toolbox; -} - -async function attachRecordingDebugger(url, { waitForRecording } = { waitForRecording: false }) { - let tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); - gBrowser.selectedTab = tab; - openTrustedLinkIn(EXAMPLE_URL + url, "current"); - - if (waitForRecording) { - await once(Services.ppmm, "RecordingFinished"); - } - const toolbox = await attachDebugger(tab); - const dbg = createDebuggerContext(toolbox) - const threadClient = dbg.toolbox.threadClient; - - await threadClient.interrupt(); - return {...dbg, tab, threadClient}; -} - - -// Return a promise with a reference to jsterm, opening the split -// console if necessary. This cleans up the split console pref so -// it won't pollute other tests. -async function getSplitConsole(dbg) { - const { toolbox, win } = dbg; - - if (!win) { - win = toolbox.win; - } - - if (!toolbox.splitConsole) { - pressKey(dbg, "Escape"); - } - - await toolbox.openSplitConsole(); - return toolbox.getPanel("webconsole"); -} - - -// Return a promise that resolves when a breakpoint has been set. -async function setBreakpoint(threadClient, expectedFile, lineno) { - let {sources} = await threadClient.getSources(); - ok(sources.length == 1, "Got one source"); - ok(RegExp(expectedFile).test(sources[0].url), "Source is " + expectedFile); - let sourceClient = threadClient.source(sources[0]); - await sourceClient.setBreakpoint({ line: lineno }); -} - -function resumeThenPauseAtLineFunctionFactory(method) { - return async function(threadClient, lineno) { - threadClient[method](); - await threadClient.addOneTimeListener("paused", async function(event, packet) { - let {frames} = await threadClient.getFrames(0, 1); - let frameLine = frames[0] ? frames[0].where.line : undefined; - ok(frameLine == lineno, "Paused at line " + frameLine + " expected " + lineno); - }); - }; -} - -// Define various methods that resume a thread in a specific way and ensure it -// pauses at a specified line. -var rewindToLine = resumeThenPauseAtLineFunctionFactory("rewind"); -var resumeToLine = resumeThenPauseAtLineFunctionFactory("resume"); -var reverseStepOverToLine = resumeThenPauseAtLineFunctionFactory("reverseStepOver"); -var stepOverToLine = resumeThenPauseAtLineFunctionFactory("stepOver"); -var reverseStepInToLine = resumeThenPauseAtLineFunctionFactory("reverseStepIn"); -var stepInToLine = resumeThenPauseAtLineFunctionFactory("stepIn"); -var reverseStepOutToLine = resumeThenPauseAtLineFunctionFactory("reverseStepOut"); -var stepOutToLine = resumeThenPauseAtLineFunctionFactory("stepOut"); - -// Return a promise that resolves with the result of a thread evaluating a -// string in the topmost frame. -async function evaluateInTopFrame(threadClient, text) { - let {frames} = await threadClient.getFrames(0, 1); - ok(frames.length == 1, "Got one frame"); - let response = await threadClient.eval(frames[0].actor, text); - ok(response.type == "resumed", "Got resume response from eval"); - let rval; - await threadClient.addOneTimeListener("paused", function(event, packet) { - ok(packet.type == "paused" && - packet.why.type == "clientEvaluated" && - "return" in packet.why.frameFinished, "Eval returned a value"); - rval = packet.why.frameFinished["return"]; - }); - return (rval.type == "undefined") ? undefined : rval; -} - -// Return a promise that resolves when a thread evaluates a string in the -// topmost frame, ensuring the result matches the expected value. -async function checkEvaluateInTopFrame(threadClient, text, expected) { - let rval = await evaluateInTopFrame(threadClient, text); - ok(rval == expected, "Eval returned " + expected); -} - -// Return a promise that resolves when a thread evaluates a string in the -// topmost frame, with the result throwing an exception. -async function checkEvaluateInTopFrameThrows(threadClient, text) { - let {frames} = await threadClient.getFrames(0, 1); - ok(frames.length == 1, "Got one frame"); - let response = await threadClient.eval(frames[0].actor, text); - ok(response.type == "resumed", "Got resume response from eval"); - await threadClient.addOneTimeListener("paused", function(event, packet) { - ok(packet.type == "paused" && - packet.why.type == "clientEvaluated" && - "throw" in packet.why.frameFinished, "Eval threw an exception"); - }); -} - -// Return a pathname that can be used for a new recording file. -function newRecordingFile() { - ChromeUtils.import("resource://gre/modules/osfile.jsm", this); - return OS.Path.join(OS.Constants.Path.tmpDir, - "MochitestRecording" + Math.round(Math.random() * 1000000000)); -} - - -async function warpToMessage(hud, threadClient, text) { - let messages = await waitForMessages(hud, text); - ok(messages.length == 1, "Found one message"); - let message = messages.pop(); - - let menuPopup = await openConsoleContextMenu(hud, message); - console.log(`.>> menu`, menuPopup); - - - let timeWarpItem = menuPopup.querySelector("#console-menu-time-warp"); - ok(timeWarpItem, "Time warp menu item is available"); - - timeWarpItem.click(); - - await Promise.all([ - hideConsoleContextMenu(hud), - once(Services.ppmm, "TimeWarpFinished"), - waitForThreadEvents(threadClient, 'paused') - ]); - - messages = findMessages(hud, "", ".paused"); - ok(messages.length == 1, "Found one paused message"); - - return message; -} - - -function findMessage(hud, text, selector = ".message") { - return findMessages(hud, text, selector)[0] -} - -function findMessages(hud, text, selector = ".message") { - const messages = hud.ui.outputNode.querySelectorAll(selector); - const elements = Array.prototype.filter.call( - messages, - (el) => el.textContent.includes(text) - ); - - if (elements.length == 0) { - return null; - } - - return elements; -} - -function waitForMessages(hud, text, selector = ".message") { - return waitUntilPredicate(() => findMessages(hud, text, selector)) -} - -async function openConsoleContextMenu(hud, element) { - const onConsoleMenuOpened = hud.ui.consoleOutput.once("menu-open"); - synthesizeContextMenuEvent(element); - await onConsoleMenuOpened; - const doc = hud.ui.consoleOutput.owner.chromeWindow.document; - return doc.getElementById("webconsole-menu"); -} - -function hideConsoleContextMenu(hud) { - const doc = hud.ui.consoleOutput.owner.chromeWindow.document; - const popup = doc.getElementById("webconsole-menu"); - if (!popup) { - return Promise.resolve(); - } - - const onPopupHidden = once(popup, "popuphidden"); - popup.hidePopup(); - return onPopupHidden; -} diff --git a/devtools/client/debugger/new/test/mochitest/helpers.js b/devtools/client/debugger/new/test/mochitest/helpers.js index 412552adbea5..d50820ccb66f 100644 --- a/devtools/client/debugger/new/test/mochitest/helpers.js +++ b/devtools/client/debugger/new/test/mochitest/helpers.js @@ -1462,3 +1462,75 @@ async function editExpression(dbg, input) { pressKey(dbg, "Enter"); await evaluated; } + +async function waitUntilPredicate(predicate) { + let result; + await waitUntil(() => { + result = predicate(); + return result; + }) + + return result; +} + +// Return a promise with a reference to jsterm, opening the split +// console if necessary. This cleans up the split console pref so +// it won't pollute other tests. +async function getDebuggerSplitConsole(dbg) { + const { toolbox, win } = dbg; + + if (!win) { + win = toolbox.win; + } + + if (!toolbox.splitConsole) { + pressKey(dbg, "Escape"); + } + + await toolbox.openSplitConsole(); + return toolbox.getPanel("webconsole"); +} + +async function openConsoleContextMenu(hud, element) { + const onConsoleMenuOpened = hud.ui.consoleOutput.once("menu-open"); + synthesizeContextMenuEvent(element); + await onConsoleMenuOpened; + const doc = hud.ui.consoleOutput.owner.chromeWindow.document; + return doc.getElementById("webconsole-menu"); +} + +function hideConsoleContextMenu(hud) { + const doc = hud.ui.consoleOutput.owner.chromeWindow.document; + const popup = doc.getElementById("webconsole-menu"); + if (!popup) { + return Promise.resolve(); + } + + const onPopupHidden = once(popup, "popuphidden"); + popup.hidePopup(); + return onPopupHidden; +} + +// Return a promise that resolves with the result of a thread evaluating a +// string in the topmost frame. +async function evaluateInTopFrame(threadClient, text) { + const {frames} = await threadClient.getFrames(0, 1); + ok(frames.length == 1, "Got one frame"); + const response = await threadClient.eval(frames[0].actor, text); + ok(response.type == "resumed", "Got resume response from eval"); + let rval; + await threadClient.addOneTimeListener("paused", function(event, packet) { + ok(packet.type == "paused" && + packet.why.type == "clientEvaluated" && + "return" in packet.why.frameFinished, "Eval returned a value"); + rval = packet.why.frameFinished.return; + }); + return (rval.type == "undefined") ? undefined : rval; +} + +// Return a promise that resolves when a thread evaluates a string in the +// topmost frame, ensuring the result matches the expected value. +async function checkEvaluateInTopFrame(threadClient, text, expected) { + const rval = await evaluateInTopFrame(threadClient, text); + ok(rval == expected, "Eval returned " + expected); +} diff --git a/devtools/client/webreplay/mochitest/browser.ini b/devtools/client/webreplay/mochitest/browser.ini new file mode 100644 index 000000000000..92e99ea8e16f --- /dev/null +++ b/devtools/client/webreplay/mochitest/browser.ini @@ -0,0 +1,38 @@ +[DEFAULT] +tags = devtools +subsuite = devtools + +# Feel free to set this to true if an impending change breaks Web Replay and +# fixing it would be annoying or difficult. This will avoid running all tests +# that use Web Replay; we don't want this experimental feature to impede +# development in the rest of Gecko. +# +# Please file a bug against the 'Core > Web Replay' component if you do so, +# so that the problem can be fixed and tests reenabled. +skip-if = os != "mac" || debug || !nightly_build + +support-files = + head.js + examples/doc_rr_basic.html + examples/doc_rr_continuous.html + examples/doc_rr_logs.html + examples/doc_rr_recovery.html + examples/doc_rr_error.html + +[browser_dbg_rr_breakpoints-01.js] +[browser_dbg_rr_breakpoints-02.js] +[browser_dbg_rr_breakpoints-03.js] +[browser_dbg_rr_breakpoints-04.js] +[browser_dbg_rr_breakpoints-05.js] +[browser_dbg_rr_record.js] +[browser_dbg_rr_stepping-01.js] +[browser_dbg_rr_stepping-02.js] +[browser_dbg_rr_stepping-03.js] +[browser_dbg_rr_stepping-04.js] +[browser_dbg_rr_recovery-01.js] +skip-if = true # See bug 1481009 +[browser_dbg_rr_replay-01.js] +[browser_dbg_rr_replay-02.js] +[browser_dbg_rr_replay-03.js] +[browser_dbg_rr_console_warp-01.js] +[browser_dbg_rr_console_warp-02.js] diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-01.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-01.js similarity index 92% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-01.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-01.js index d734dff0e8af..cb908c88211c 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-01.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-01.js @@ -2,11 +2,14 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test basic breakpoint functionality in web replay. -async function test() { - waitForExplicitFinish(); - +add_task(async function() { const dbg = await attachRecordingDebugger( "doc_rr_basic.html", { waitForRecording: true } @@ -38,5 +41,4 @@ async function test() { await toolbox.closeToolbox(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-02.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-02.js similarity index 82% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-02.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-02.js index 96f80555784e..f753cf75a081 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-02.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-02.js @@ -2,12 +2,16 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test unhandled divergence while evaluating at a breakpoint with Web Replay. -async function test() { - waitForExplicitFinish(); - - const dbg = await attachRecordingDebugger("doc_rr_basic.html", { waitForRecording: true }); +add_task(async function() { + const dbg = await attachRecordingDebugger("doc_rr_basic.html", + { waitForRecording: true }); const {threadClient, tab, toolbox} = dbg; await setBreakpoint(threadClient, "doc_rr_basic.html", 21); @@ -21,5 +25,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-03.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-03.js similarity index 77% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-03.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-03.js index 9209fef2295f..ba7786c86c8a 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-03.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-03.js @@ -2,11 +2,14 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test some issues when stepping around after hitting a breakpoint while recording. -async function test() { - waitForExplicitFinish(); - +add_task(async function() { const dbg = await attachRecordingDebugger("doc_rr_continuous.html"); const {threadClient, tab, toolbox} = dbg; @@ -14,7 +17,9 @@ async function test() { await setBreakpoint(threadClient, "doc_rr_continuous.html", 19); await resumeToLine(threadClient, 19); await reverseStepOverToLine(threadClient, 18); - await checkEvaluateInTopFrame(threadClient, "SpecialPowers.Cu.recordReplayDirective(/* AlwaysTakeTemporarySnapshots */ 3)", undefined); + await checkEvaluateInTopFrame(threadClient, + "SpecialPowers.Cu.recordReplayDirective(/* AlwaysTakeTemporarySnapshots */ 3)", + undefined); await stepInToLine(threadClient, 22); await setBreakpoint(threadClient, "doc_rr_continuous.html", 24); await resumeToLine(threadClient, 24); @@ -23,5 +28,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-04.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-04.js similarity index 86% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-04.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-04.js index 2a5626f97ae2..50996d653cc6 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-04.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-04.js @@ -2,18 +2,21 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test navigating back to earlier breakpoints while recording, then resuming // recording. -async function test() { - waitForExplicitFinish(); - +add_task(async function() { const dbg = await attachRecordingDebugger("doc_rr_continuous.html"); const {threadClient, tab, toolbox} = dbg; await setBreakpoint(threadClient, "doc_rr_continuous.html", 14); await resumeToLine(threadClient, 14); - let value = await evaluateInTopFrame(threadClient, "number"); + const value = await evaluateInTopFrame(threadClient, "number"); await resumeToLine(threadClient, 14); await checkEvaluateInTopFrame(threadClient, "number", value + 1); await rewindToLine(threadClient, 14); @@ -29,5 +32,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-05.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-05.js similarity index 84% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-05.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-05.js index 09640a1af8c6..8e14957b73af 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_breakpoints-05.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-05.js @@ -2,14 +2,17 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test hitting breakpoints when rewinding past the point where the breakpoint // script was created. -async function test() { - waitForExplicitFinish(); - +add_task(async function() { const dbg = await attachRecordingDebugger( - "doc_rr_basic.html", + "doc_rr_basic.html", { waitForRecording: true } ); @@ -26,5 +29,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_console_warp-01.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-01.js similarity index 57% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_console_warp-01.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-01.js index 2dbce382cfe0..fd3452b90303 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_console_warp-01.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-01.js @@ -2,37 +2,24 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ -// This functionality was copied from devtools/client/webconsole/test/mochitest/head.js, -// since this test straddles both the web console and the debugger. I couldn't -// figure out how to load that script directly here. -function waitForThreadEvents(threadClient, eventName) { - info(`Waiting for thread event '${eventName}' to fire.`); - - return new Promise(function(resolve, reject) { - threadClient.addListener(eventName, function onEvent(eventName, ...args) { - info(`Thread event '${eventName}' fired.`); - threadClient.removeListener(eventName, onEvent); - resolve.apply(resolve, args); - }); - }); -} +"use strict"; +// To disable all Web Replay tests, see browser.ini // Test basic console time warping functionality in web replay. -async function test() { - waitForExplicitFinish(); - +add_task(async function() { const dbg = await attachRecordingDebugger( - "doc_rr_error.html", + "doc_rr_error.html", { waitForRecording: true } ); const {tab, toolbox, threadClient} = dbg; - const console = await getSplitConsole(dbg); + const console = await getDebuggerSplitConsole(dbg); const hud = console.hud; - await warpToMessage(hud, threadClient, "Number 5"); + await warpToMessage(hud, dbg, "Number 5"); await threadClient.interrupt(); await checkEvaluateInTopFrame(threadClient, "number", 5); @@ -49,5 +36,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-02.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-02.js new file mode 100644 index 000000000000..2f52a5ce3293 --- /dev/null +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-02.js @@ -0,0 +1,33 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini + +// Test basic console time warping functionality in web replay. +add_task(async function() { + const dbg = await attachRecordingDebugger( + "doc_rr_logs.html", + { waitForRecording: true } + ); + + const {tab, toolbox, threadClient} = dbg; + const console = await getDebuggerSplitConsole(dbg); + const hud = console.hud; + + let message = await warpToMessage(hud, dbg, "number: 1"); + ok(!message.classList.contains("paused-before"), "paused before message is not shown"); + + await stepOverToLine(threadClient, 18); + await reverseStepOverToLine(threadClient, 17); + + message = findMessage(hud, "number: 1"); + ok(message.classList.contains("paused-before"), "paused before message is shown"); + + await toolbox.destroy(); + await gBrowser.removeTab(tab); +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_record.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_record.js similarity index 69% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_record.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_record.js index dd6042cc69b1..4f3358419172 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_record.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_record.js @@ -2,12 +2,15 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test basic recording of a tab without any debugging. -async function test() { - waitForExplicitFinish(); - - var recordingTab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); +add_task(async function() { + const recordingTab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); gBrowser.selectedTab = recordingTab; openTrustedLinkIn(EXAMPLE_URL + "doc_rr_basic.html", "current"); await once(Services.ppmm, "RecordingFinished"); @@ -15,5 +18,4 @@ async function test() { await gBrowser.removeTab(recordingTab); ok(true, "Finished"); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_recovery-01.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_recovery-01.js similarity index 53% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_recovery-01.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_recovery-01.js index b2b6bf82a5c9..8d2c751c72f7 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_recovery-01.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_recovery-01.js @@ -2,27 +2,32 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test basic recovery of crashed child processes in web replay. -async function test() { - waitForExplicitFinish(); - - let tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); +add_task(async function() { + const tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); gBrowser.selectedTab = tab; openTrustedLinkIn(EXAMPLE_URL + "doc_rr_recovery.html", "current"); await once(Services.ppmm, "RecordingFinished"); - let toolbox = await attachDebugger(tab), client = toolbox.threadClient; + const toolbox = await attachDebugger(tab), client = toolbox.threadClient; await client.interrupt(); await setBreakpoint(client, "doc_rr_recovery.html", 21); await rewindToLine(client, 21); - await checkEvaluateInTopFrame(client, "SpecialPowers.Cu.recordReplayDirective(/* CrashSoon */ 1)", undefined); + await checkEvaluateInTopFrame(client, + "SpecialPowers.Cu.recordReplayDirective(/* CrashSoon */ 1)", + undefined); await stepOverToLine(client, 22); await stepOverToLine(client, 23); - await checkEvaluateInTopFrame(client, "SpecialPowers.Cu.recordReplayDirective(/* CrashSoon */ 1); " + - "SpecialPowers.Cu.recordReplayDirective(/* MaybeCrash */ 2)", undefined); - + await checkEvaluateInTopFrame(client, + "SpecialPowers.Cu.recordReplayDirective(/* CrashSoon */ 1); " + + "SpecialPowers.Cu.recordReplayDirective(/* MaybeCrash */ 2)", + undefined); await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_replay-01.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-01.js similarity index 65% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_replay-01.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_replay-01.js index 3f9eec2a81b1..d864f188d3ea 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_replay-01.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-01.js @@ -2,27 +2,32 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Basic test for saving a recording and then replaying it in a new tab. -async function test() { - waitForExplicitFinish(); - - let recordingFile = newRecordingFile(); - let recordingTab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); +add_task(async function() { + const recordingFile = newRecordingFile(); + const recordingTab = BrowserTestUtils.addTab(gBrowser, null, + { recordExecution: "*" }); gBrowser.selectedTab = recordingTab; openTrustedLinkIn(EXAMPLE_URL + "doc_rr_basic.html", "current"); await once(Services.ppmm, "RecordingFinished"); - let tabParent = recordingTab.linkedBrowser.frameLoader.tabParent; + const tabParent = recordingTab.linkedBrowser.frameLoader.tabParent; ok(tabParent, "Found recording tab parent"); ok(tabParent.saveRecording(recordingFile), "Saved recording"); await once(Services.ppmm, "SaveRecordingFinished"); - let replayingTab = BrowserTestUtils.addTab(gBrowser, null, { replayExecution: recordingFile }); + const replayingTab = BrowserTestUtils.addTab(gBrowser, null, + { replayExecution: recordingFile }); gBrowser.selectedTab = replayingTab; await once(Services.ppmm, "HitRecordingEndpoint"); - let toolbox = await attachDebugger(replayingTab), client = toolbox.threadClient; + const toolbox = await attachDebugger(replayingTab), client = toolbox.threadClient; await client.interrupt(); await setBreakpoint(client, "doc_rr_basic.html", 21); await rewindToLine(client, 21); @@ -35,5 +40,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(recordingTab); await gBrowser.removeTab(replayingTab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_replay-02.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-02.js similarity index 74% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_replay-02.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_replay-02.js index 57edaa8aa728..a529ca119d8a 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_replay-02.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-02.js @@ -2,13 +2,18 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test ending a recording at a breakpoint and then separately replaying to the end. -async function test() { +add_task(async function() { waitForExplicitFinish(); - let recordingFile = newRecordingFile(); - let recordingTab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); + const recordingFile = newRecordingFile(); + const recordingTab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); gBrowser.selectedTab = recordingTab; openTrustedLinkIn(EXAMPLE_URL + "doc_rr_continuous.html", "current"); @@ -18,9 +23,9 @@ async function test() { await resumeToLine(client, 14); await resumeToLine(client, 14); await reverseStepOverToLine(client, 13); - let lastNumberValue = await evaluateInTopFrame(client, "number"); + const lastNumberValue = await evaluateInTopFrame(client, "number"); - let tabParent = recordingTab.linkedBrowser.frameLoader.tabParent; + const tabParent = recordingTab.linkedBrowser.frameLoader.tabParent; ok(tabParent, "Found recording tab parent"); ok(tabParent.saveRecording(recordingFile), "Saved recording"); await once(Services.ppmm, "SaveRecordingFinished"); @@ -28,7 +33,8 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(recordingTab); - let replayingTab = BrowserTestUtils.addTab(gBrowser, null, { replayExecution: recordingFile }); + const replayingTab = BrowserTestUtils.addTab(gBrowser, null, + { replayExecution: recordingFile }); gBrowser.selectedTab = replayingTab; await once(Services.ppmm, "HitRecordingEndpoint"); @@ -45,5 +51,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(replayingTab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_replay-03.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-03.js similarity index 63% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_replay-03.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_replay-03.js index a004ff61af4b..f0311420c195 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_replay-03.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-03.js @@ -2,25 +2,30 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ -// Test for saving a recording and then replaying it in a new tab, with rewinding disabled. -async function test() { - waitForExplicitFinish(); +"use strict"; +// To disable all Web Replay tests, see browser.ini + +// Test for saving a recording and then replaying it in a new tab, +// with rewinding disabled. +add_task(async function() { await pushPref("devtools.recordreplay.enableRewinding", false); - let recordingFile = newRecordingFile(); - let recordingTab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); + const recordingFile = newRecordingFile(); + const recordingTab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); gBrowser.selectedTab = recordingTab; openTrustedLinkIn(EXAMPLE_URL + "doc_rr_basic.html", "current"); await once(Services.ppmm, "RecordingFinished"); - let tabParent = recordingTab.linkedBrowser.frameLoader.tabParent; + const tabParent = recordingTab.linkedBrowser.frameLoader.tabParent; ok(tabParent, "Found recording tab parent"); ok(tabParent.saveRecording(recordingFile), "Saved recording"); await once(Services.ppmm, "SaveRecordingFinished"); - let replayingTab = BrowserTestUtils.addTab(gBrowser, null, { replayExecution: recordingFile }); + const replayingTab = BrowserTestUtils.addTab(gBrowser, null, + { replayExecution: recordingFile }); gBrowser.selectedTab = replayingTab; await once(Services.ppmm, "HitRecordingEndpoint"); @@ -28,5 +33,4 @@ async function test() { await gBrowser.removeTab(recordingTab); await gBrowser.removeTab(replayingTab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-01.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-01.js similarity index 76% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-01.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-01.js index fb4dc2083ba9..105b4f2e8bc9 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-01.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-01.js @@ -2,17 +2,20 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test basic step-over/back functionality in web replay. -async function test() { - waitForExplicitFinish(); - - let tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); +add_task(async function() { + const tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); gBrowser.selectedTab = tab; openTrustedLinkIn(EXAMPLE_URL + "doc_rr_basic.html", "current"); await once(Services.ppmm, "RecordingFinished"); - let toolbox = await attachDebugger(tab), client = toolbox.threadClient; + const toolbox = await attachDebugger(tab), client = toolbox.threadClient; await client.interrupt(); await setBreakpoint(client, "doc_rr_basic.html", 21); await rewindToLine(client, 21); @@ -25,5 +28,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-02.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-02.js similarity index 75% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-02.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-02.js index a16cac6b5ef3..9c32b8a6112f 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-02.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-02.js @@ -2,17 +2,20 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test fixes for some simple stepping bugs. -async function test() { - waitForExplicitFinish(); - - let tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); +add_task(async function() { + const tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); gBrowser.selectedTab = tab; openTrustedLinkIn(EXAMPLE_URL + "doc_rr_basic.html", "current"); await once(Services.ppmm, "RecordingFinished"); - let toolbox = await attachDebugger(tab), client = toolbox.threadClient; + const toolbox = await attachDebugger(tab), client = toolbox.threadClient; await client.interrupt(); await setBreakpoint(client, "doc_rr_basic.html", 22); await rewindToLine(client, 22); @@ -26,5 +29,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-03.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-03.js similarity index 69% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-03.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-03.js index 2bc1c1de0dae..8fed55cd67df 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-03.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-03.js @@ -2,20 +2,23 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Test stepping back while recording, then resuming recording. -async function test() { - waitForExplicitFinish(); - - let tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); +add_task(async function() { + const tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); gBrowser.selectedTab = tab; openTrustedLinkIn(EXAMPLE_URL + "doc_rr_continuous.html", "current"); - let toolbox = await attachDebugger(tab), client = toolbox.threadClient; + const toolbox = await attachDebugger(tab), client = toolbox.threadClient; await client.interrupt(); await setBreakpoint(client, "doc_rr_continuous.html", 13); await resumeToLine(client, 13); - let value = await evaluateInTopFrame(client, "number"); + const value = await evaluateInTopFrame(client, "number"); await reverseStepOverToLine(client, 12); await checkEvaluateInTopFrame(client, "number", value - 1); await resumeToLine(client, 13); @@ -24,5 +27,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-04.js b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-04.js similarity index 82% rename from devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-04.js rename to devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-04.js index b5173fd099a2..6c209dc388af 100644 --- a/devtools/client/debugger/new/test/mochitest/browser_dbg_rr_stepping-04.js +++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-04.js @@ -2,17 +2,20 @@ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +// To disable all Web Replay tests, see browser.ini // Stepping past the beginning or end of a frame should act like a step-out. -async function test() { - waitForExplicitFinish(); - - let tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); +add_task(async function() { + const tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); gBrowser.selectedTab = tab; openTrustedLinkIn(EXAMPLE_URL + "doc_rr_basic.html", "current"); await once(Services.ppmm, "RecordingFinished"); - let toolbox = await attachDebugger(tab), client = toolbox.threadClient; + const toolbox = await attachDebugger(tab), client = toolbox.threadClient; await client.interrupt(); await setBreakpoint(client, "doc_rr_basic.html", 21); await rewindToLine(client, 21); @@ -38,5 +41,4 @@ async function test() { await toolbox.destroy(); await gBrowser.removeTab(tab); - finish(); -} +}); diff --git a/devtools/client/debugger/new/test/mochitest/examples/doc_rr_basic.html b/devtools/client/webreplay/mochitest/examples/doc_rr_basic.html similarity index 100% rename from devtools/client/debugger/new/test/mochitest/examples/doc_rr_basic.html rename to devtools/client/webreplay/mochitest/examples/doc_rr_basic.html diff --git a/devtools/client/debugger/new/test/mochitest/examples/doc_rr_continuous.html b/devtools/client/webreplay/mochitest/examples/doc_rr_continuous.html similarity index 100% rename from devtools/client/debugger/new/test/mochitest/examples/doc_rr_continuous.html rename to devtools/client/webreplay/mochitest/examples/doc_rr_continuous.html diff --git a/devtools/client/debugger/new/test/mochitest/examples/doc_rr_error.html b/devtools/client/webreplay/mochitest/examples/doc_rr_error.html similarity index 100% rename from devtools/client/debugger/new/test/mochitest/examples/doc_rr_error.html rename to devtools/client/webreplay/mochitest/examples/doc_rr_error.html diff --git a/devtools/client/debugger/new/test/mochitest/examples/doc_rr_logs.html b/devtools/client/webreplay/mochitest/examples/doc_rr_logs.html similarity index 100% rename from devtools/client/debugger/new/test/mochitest/examples/doc_rr_logs.html rename to devtools/client/webreplay/mochitest/examples/doc_rr_logs.html diff --git a/devtools/client/debugger/new/test/mochitest/examples/doc_rr_recovery.html b/devtools/client/webreplay/mochitest/examples/doc_rr_recovery.html similarity index 100% rename from devtools/client/debugger/new/test/mochitest/examples/doc_rr_recovery.html rename to devtools/client/webreplay/mochitest/examples/doc_rr_recovery.html diff --git a/devtools/client/webreplay/mochitest/head.js b/devtools/client/webreplay/mochitest/head.js new file mode 100644 index 000000000000..d7fe650ce90d --- /dev/null +++ b/devtools/client/webreplay/mochitest/head.js @@ -0,0 +1,144 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +/* eslint-disable no-undef */ + +"use strict"; + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js", + this +); + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/debugger/new/test/mochitest/helpers.js", + this +); + +const EXAMPLE_URL = + "http://example.com/browser/devtools/client/webreplay/mochitest/examples/"; + +// Attach a debugger to a tab, returning a promise that resolves with the +// debugger's toolbox. +async function attachDebugger(tab) { + const target = await TargetFactory.forTab(tab); + const toolbox = await gDevTools.showToolbox(target, "jsdebugger"); + return toolbox; +} + +async function attachRecordingDebugger(url, + { waitForRecording } = { waitForRecording: false }) { + const tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" }); + gBrowser.selectedTab = tab; + openTrustedLinkIn(EXAMPLE_URL + url, "current"); + + if (waitForRecording) { + await once(Services.ppmm, "RecordingFinished"); + } + const toolbox = await attachDebugger(tab); + const dbg = createDebuggerContext(toolbox); + const threadClient = dbg.toolbox.threadClient; + + await threadClient.interrupt(); + return {...dbg, tab, threadClient}; +} + +// Return a promise that resolves when a breakpoint has been set. +async function setBreakpoint(threadClient, expectedFile, lineno) { + const {sources} = await threadClient.getSources(); + ok(sources.length == 1, "Got one source"); + ok(RegExp(expectedFile).test(sources[0].url), "Source is " + expectedFile); + const sourceClient = threadClient.source(sources[0]); + await sourceClient.setBreakpoint({ line: lineno }); +} + +function resumeThenPauseAtLineFunctionFactory(method) { + return async function(threadClient, lineno) { + threadClient[method](); + await threadClient.addOneTimeListener("paused", async function(event, packet) { + const {frames} = await threadClient.getFrames(0, 1); + const frameLine = frames[0] ? frames[0].where.line : undefined; + ok(frameLine == lineno, "Paused at line " + frameLine + " expected " + lineno); + }); + }; +} + +// Define various methods that resume a thread in a specific way and ensure it +// pauses at a specified line. +var rewindToLine = resumeThenPauseAtLineFunctionFactory("rewind"); +var resumeToLine = resumeThenPauseAtLineFunctionFactory("resume"); +var reverseStepOverToLine = resumeThenPauseAtLineFunctionFactory("reverseStepOver"); +var stepOverToLine = resumeThenPauseAtLineFunctionFactory("stepOver"); +var reverseStepInToLine = resumeThenPauseAtLineFunctionFactory("reverseStepIn"); +var stepInToLine = resumeThenPauseAtLineFunctionFactory("stepIn"); +var reverseStepOutToLine = resumeThenPauseAtLineFunctionFactory("reverseStepOut"); +var stepOutToLine = resumeThenPauseAtLineFunctionFactory("stepOut"); + +// Return a promise that resolves when a thread evaluates a string in the +// topmost frame, with the result throwing an exception. +async function checkEvaluateInTopFrameThrows(threadClient, text) { + const {frames} = await threadClient.getFrames(0, 1); + ok(frames.length == 1, "Got one frame"); + const response = await threadClient.eval(frames[0].actor, text); + ok(response.type == "resumed", "Got resume response from eval"); + await threadClient.addOneTimeListener("paused", function(event, packet) { + ok(packet.type == "paused" && + packet.why.type == "clientEvaluated" && + "throw" in packet.why.frameFinished, "Eval threw an exception"); + }); +} + +// Return a pathname that can be used for a new recording file. +function newRecordingFile() { + ChromeUtils.import("resource://gre/modules/osfile.jsm", this); + return OS.Path.join(OS.Constants.Path.tmpDir, + "MochitestRecording" + Math.round(Math.random() * 1000000000)); +} + +function findMessage(hud, text, selector = ".message") { + return findMessages(hud, text, selector)[0]; +} + +function findMessages(hud, text, selector = ".message") { + const messages = hud.ui.outputNode.querySelectorAll(selector); + const elements = Array.prototype.filter.call( + messages, + (el) => el.textContent.includes(text) + ); + + if (elements.length == 0) { + return null; + } + + return elements; +} + +function waitForMessages(hud, text, selector = ".message") { + return waitUntilPredicate(() => findMessages(hud, text, selector)); +} + +async function warpToMessage(hud, threadClient, text) { + let messages = await waitForMessages(hud, text); + ok(messages.length == 1, "Found one message"); + const message = messages.pop(); + + const menuPopup = await openConsoleContextMenu(hud, message); + console.log(`.>> menu`, menuPopup); + + const timeWarpItem = menuPopup.querySelector("#console-menu-time-warp"); + ok(timeWarpItem, "Time warp menu item is available"); + + timeWarpItem.click(); + + await Promise.all([ + hideConsoleContextMenu(hud), + once(Services.ppmm, "TimeWarpFinished"), + waitForThreadEvents(threadClient, "paused"), + ]); + + messages = findMessages(hud, "", ".paused"); + ok(messages.length == 1, "Found one paused message"); + + return message; +} diff --git a/devtools/client/webreplay/moz.build b/devtools/client/webreplay/moz.build index 5560adb742f0..b176495deef8 100644 --- a/devtools/client/webreplay/moz.build +++ b/devtools/client/webreplay/moz.build @@ -14,3 +14,5 @@ DevToolsModules( with Files('**'): BUG_COMPONENT = ('Core', 'Web Replay') + +BROWSER_CHROME_MANIFESTS += [ 'mochitest/browser.ini' ]