Bug 1530133 Part 4 - Add logpoint tests.
authorBrian Hackett <bhackett1024@gmail.com>
Sat, 23 Feb 2019 16:19:59 -1000
changeset 462518 033697893400f17daeb0acacaf4916596b0d1471
parent 462517 0385531495c51233881ec821e3248a5a90c617f1
child 462519 8cccd561de71085f58db07f384ec9456be32c573
push id35654
push userncsoregi@mozilla.com
push dateWed, 06 Mar 2019 09:57:59 +0000
treeherdermozilla-central@3e0cf2f77f07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1530133
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1530133 Part 4 - Add logpoint tests.
devtools/client/debugger/new/test/mochitest/helpers.js
devtools/client/webreplay/mochitest/browser.ini
devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-01.js
devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-02.js
devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-03.js
devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-04.js
devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-05.js
devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-01.js
devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-02.js
devtools/client/webreplay/mochitest/browser_dbg_rr_logpoint-01.js
devtools/client/webreplay/mochitest/browser_dbg_rr_logpoint-02.js
devtools/client/webreplay/mochitest/browser_dbg_rr_record.js
devtools/client/webreplay/mochitest/browser_dbg_rr_recovery-01.js
devtools/client/webreplay/mochitest/browser_dbg_rr_replay-01.js
devtools/client/webreplay/mochitest/browser_dbg_rr_replay-02.js
devtools/client/webreplay/mochitest/browser_dbg_rr_replay-03.js
devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-01.js
devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-02.js
devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-03.js
devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-04.js
devtools/client/webreplay/mochitest/head.js
--- a/devtools/client/debugger/new/test/mochitest/helpers.js
+++ b/devtools/client/debugger/new/test/mochitest/helpers.js
@@ -737,30 +737,37 @@ async function navigate(dbg, url, ...sou
  * @memberof mochitest/actions
  * @param {Object} dbg
  * @param {String} source
  * @param {Number} line
  * @param {Number} col
  * @return {Promise}
  * @static
  */
-function addBreakpoint(dbg, source, line, column) {
+function addBreakpoint(dbg, source, line, column, options) {
   source = findSource(dbg, source);
   const sourceId = source.id;
-  dbg.actions.addBreakpoint({ sourceId, line, column });
+  dbg.actions.addBreakpoint({ sourceId, line, column }, options);
   return waitForDispatch(dbg, "ADD_BREAKPOINT");
 }
 
 function disableBreakpoint(dbg, source, line, column) {
   const location = { sourceId: source.id, sourceUrl: source.url, line, column };
   const bp = dbg.selectors.getBreakpointForLocation(dbg.getState(), location);
   dbg.actions.disableBreakpoint(bp);
   return waitForDispatch(dbg, "DISABLE_BREAKPOINT");
 }
 
+function setBreakpointOptions(dbg, source, line, column, options) {
+  source = findSource(dbg, source);
+  const sourceId = source.id;
+  dbg.actions.setBreakpointOptions({ sourceId, line, column }, options);
+  return waitForDispatch(dbg, "SET_BREAKPOINT_OPTIONS");
+}
+
 function findBreakpoint(dbg, url, line) {
   const {
     selectors: { getBreakpoint },
     getState
   } = dbg;
   const source = findSource(dbg, url);
   let column;
   if (
--- a/devtools/client/webreplay/mochitest/browser.ini
+++ b/devtools/client/webreplay/mochitest/browser.ini
@@ -1,23 +1,20 @@
 [DEFAULT]
 tags = devtools-webreplay
 subsuite = devtools-webreplay
 
-# 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
+  !/devtools/client/shared/test/shared-head.js
+  !/devtools/client/shared/test/telemetry-test-helpers.js
+  !/devtools/client/debugger/new/test/mochitest/helpers.js
+  !/devtools/client/debugger/new/test/mochitest/helpers/context.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]
@@ -31,8 +28,10 @@ support-files =
 [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]
+[browser_dbg_rr_logpoint-01.js]
+[browser_dbg_rr_logpoint-02.js]
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-01.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-01.js
@@ -1,18 +1,16 @@
 /* -*- 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 breakpoint functionality in web replay.
 add_task(async function() {
   const dbg = await attachRecordingDebugger(
     "doc_rr_basic.html",
     { waitForRecording: true }
   );
   const {threadClient, tab, toolbox} = dbg;
 
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-02.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-02.js
@@ -1,18 +1,16 @@
 /* -*- 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 unhandled divergence while evaluating at a breakpoint with Web Replay.
 add_task(async function() {
   const dbg = await attachRecordingDebugger("doc_rr_basic.html",
                                             { waitForRecording: true });
   const {threadClient, tab, toolbox} = dbg;
 
   const bp = await setBreakpoint(threadClient, "doc_rr_basic.html", 21);
   await rewindToLine(threadClient, 21);
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-03.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-03.js
@@ -1,18 +1,16 @@
 /* -*- 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 some issues when stepping around after hitting a breakpoint while recording.
 add_task(async function() {
   const dbg = await attachRecordingDebugger("doc_rr_continuous.html");
   const {threadClient, tab, toolbox} = dbg;
 
   await threadClient.interrupt();
   const bp1 = await setBreakpoint(threadClient, "doc_rr_continuous.html", 19);
   await resumeToLine(threadClient, 19);
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-04.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-04.js
@@ -1,18 +1,16 @@
 /* -*- 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 navigating back to earlier breakpoints while recording, then resuming
 // recording.
 add_task(async function() {
   const dbg = await attachRecordingDebugger("doc_rr_continuous.html");
   const {threadClient, tab, toolbox} = dbg;
 
   const bp = await setBreakpoint(threadClient, "doc_rr_continuous.html", 14);
   await resumeToLine(threadClient, 14);
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-05.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_breakpoints-05.js
@@ -1,18 +1,16 @@
 /* -*- 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 hitting breakpoints when rewinding past the point where the breakpoint
 // script was created.
 add_task(async function() {
   const dbg = await attachRecordingDebugger(
     "doc_rr_basic.html",
     { waitForRecording: true }
   );
 
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-01.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-01.js
@@ -1,18 +1,16 @@
 /* -*- 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_error.html",
     { waitForRecording: true }
   );
 
   const {tab, toolbox, threadClient} = dbg;
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-02.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_console_warp-02.js
@@ -1,18 +1,16 @@
 /* -*- 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;
new file mode 100644
--- /dev/null
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_logpoint-01.js
@@ -0,0 +1,46 @@
+/* -*- 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";
+
+// Test basic logpoint functionality in web replay. When logpoints are added,
+// new messages should appear in the correct order and allow time warping.
+add_task(async function() {
+  const dbg = await attachRecordingDebugger(
+    "doc_rr_basic.html",
+    { waitForRecording: true }
+  );
+
+  const {tab, toolbox, threadClient} = dbg;
+  const console = await getDebuggerSplitConsole(dbg);
+  const hud = console.hud;
+
+  const bp1 = await setBreakpoint(threadClient, "doc_rr_basic.html", 21,
+                                  { logValue: `"Logpoint Number " + number` });
+  const bp2 = await setBreakpoint(threadClient, "doc_rr_basic.html", 6,
+                                  { logValue: `"Logpoint Beginning"` });
+  const bp3 = await setBreakpoint(threadClient, "doc_rr_basic.html", 8,
+                                  { logValue: `"Logpoint Ending"` });
+
+  const messages = await waitForMessageCount(hud, "Logpoint", 12);
+  ok(messages[0].textContent.includes("Beginning"));
+  for (let i = 1; i <= 10; i++) {
+    ok(messages[i].textContent.includes("Number " + i));
+  }
+  ok(messages[11].textContent.includes("Ending"));
+
+  await warpToMessage(hud, dbg, "Number 5");
+  await threadClient.interrupt();
+
+  await checkEvaluateInTopFrame(threadClient, "number", 5);
+  await reverseStepOverToLine(threadClient, 20);
+
+  await threadClient.removeBreakpoint(bp1);
+  await threadClient.removeBreakpoint(bp2);
+  await threadClient.removeBreakpoint(bp3);
+  await toolbox.destroy();
+  await gBrowser.removeTab(tab);
+});
new file mode 100644
--- /dev/null
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_logpoint-02.js
@@ -0,0 +1,40 @@
+/* -*- 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";
+
+// Test that logpoints appear and disappear as expected as breakpoints are
+// modified. Also test that conditional logpoints work.
+add_task(async function() {
+  const dbg = await attachRecordingDebugger(
+    "doc_rr_basic.html",
+    { waitForRecording: true }
+  );
+
+  const {tab, toolbox} = dbg;
+  const console = await getDebuggerSplitConsole(dbg);
+  const hud = console.hud;
+
+  await addBreakpoint(dbg, "doc_rr_basic.html", 21, undefined,
+                      { logValue: `"Logpoint Number " + number` });
+  await addBreakpoint(dbg, "doc_rr_basic.html", 6, undefined,
+                      { logValue: `"Logpoint Beginning"` });
+  await addBreakpoint(dbg, "doc_rr_basic.html", 8, undefined,
+                      { logValue: `"Logpoint Ending"` });
+  await waitForMessageCount(hud, "Logpoint", 12);
+
+  await disableBreakpoint(dbg, findSource(dbg, "doc_rr_basic.html"), 6);
+  await waitForMessageCount(hud, "Logpoint", 11);
+
+  await setBreakpointOptions(dbg, "doc_rr_basic.html", 21, undefined,
+    { logValue: `"Logpoint Number " + number`, condition: `number % 2 == 0` });
+  await waitForMessageCount(hud, "Logpoint", 6);
+
+  await dbg.actions.removeAllBreakpoints();
+
+  await toolbox.destroy();
+  await gBrowser.removeTab(tab);
+});
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_record.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_record.js
@@ -1,18 +1,16 @@
 /* -*- 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 recording of a tab without any debugging.
 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");
 
   await gBrowser.removeTab(recordingTab);
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_recovery-01.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_recovery-01.js
@@ -1,18 +1,16 @@
 /* -*- 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 recovery of crashed child processes in web replay.
 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");
 
   const toolbox = await attachDebugger(tab), client = toolbox.threadClient;
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-01.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-01.js
@@ -1,18 +1,16 @@
 /* -*- 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
-
 // Basic test for saving a recording and then replaying it in a new tab.
 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");
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-02.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-02.js
@@ -1,18 +1,16 @@
 /* -*- 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 ending a recording at a breakpoint and then separately replaying to the end.
 add_task(async function() {
   waitForExplicitFinish();
 
   const recordingFile = newRecordingFile();
   const recordingTab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" });
   gBrowser.selectedTab = recordingTab;
   openTrustedLinkIn(EXAMPLE_URL + "doc_rr_continuous.html", "current");
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-03.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_replay-03.js
@@ -1,18 +1,16 @@
 /* -*- 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 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);
 
   const recordingFile = newRecordingFile();
   const recordingTab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" });
   gBrowser.selectedTab = recordingTab;
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-01.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-01.js
@@ -1,18 +1,16 @@
 /* -*- 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 step-over/back functionality in web replay.
 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");
 
   const toolbox = await attachDebugger(tab), client = toolbox.threadClient;
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-02.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-02.js
@@ -1,18 +1,16 @@
 /* -*- 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 fixes for some simple stepping bugs.
 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");
 
   const toolbox = await attachDebugger(tab), client = toolbox.threadClient;
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-03.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-03.js
@@ -1,18 +1,16 @@
 /* -*- 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 stepping back while recording, then resuming recording.
 add_task(async function() {
   const tab = BrowserTestUtils.addTab(gBrowser, null, { recordExecution: "*" });
   gBrowser.selectedTab = tab;
   openTrustedLinkIn(EXAMPLE_URL + "doc_rr_continuous.html", "current");
 
   const toolbox = await attachDebugger(tab), client = toolbox.threadClient;
   await client.interrupt();
--- a/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-04.js
+++ b/devtools/client/webreplay/mochitest/browser_dbg_rr_stepping-04.js
@@ -1,18 +1,16 @@
 /* -*- 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
-
 // Stepping past the beginning or end of a frame should act like a step-out.
 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");
 
   const toolbox = await attachDebugger(tab), client = toolbox.threadClient;
--- a/devtools/client/webreplay/mochitest/head.js
+++ b/devtools/client/webreplay/mochitest/head.js
@@ -40,22 +40,22 @@ async function attachRecordingDebugger(u
   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) {
+async function setBreakpoint(threadClient, expectedFile, lineno, options = {}) {
   const {sources} = await threadClient.getSources();
   ok(sources.length == 1, "Got one source");
   ok(RegExp(expectedFile).test(sources[0].url), "Source is " + expectedFile);
   const location = { sourceUrl: sources[0].url, line: lineno };
-  await threadClient.setBreakpoint(location, {});
+  await threadClient.setBreakpoint(location, options);
   return location;
 }
 
 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);
@@ -114,16 +114,26 @@ function findMessages(hud, text, selecto
 
   return elements;
 }
 
 function waitForMessages(hud, text, selector = ".message") {
   return waitUntilPredicate(() => findMessages(hud, text, selector));
 }
 
+async function waitForMessageCount(hud, text, length, selector = ".message") {
+  let messages;
+  await waitUntil(() => {
+    messages = findMessages(hud, text, selector);
+    return messages && messages.length == length;
+  });
+  ok(messages.length == length, "Found expected message count");
+  return messages;
+}
+
 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);