Bug 1576318 Part 5 - Add tests that we can preview assorted objects while replaying, and pause the debugger without making debugger requests, r=loganfsmyth.

Depends on D43321

Differential Revision: https://phabricator.services.mozilla.com/D43322

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Brian Hackett 2019-08-30 17:13:34 +00:00
parent ad74710129
commit 44d14c3f29
3 changed files with 135 additions and 5 deletions

View File

@ -19,20 +19,54 @@ Services.scriptloader.loadSubScript(
BrowserTest
);
async function checkMessageObjectContents(msg, expected, expandList = []) {
const oi = msg.querySelector(".tree");
const node = oi.querySelector(".tree-node");
BrowserTest.expandObjectInspectorNode(node);
for (const label of expandList) {
const labelNode = await waitFor(() =>
BrowserTest.findObjectInspectorNode(oi, label)
);
BrowserTest.expandObjectInspectorNode(labelNode);
}
const properties = await waitFor(() => {
const nodes = BrowserTest.getObjectInspectorNodes(oi);
if (nodes && nodes.length > 1) {
return [...nodes].map(n => n.textContent);
}
return null;
});
expected.forEach(s => {
ok(properties.find(v => v.includes(s)), `Object contents include "${s}"`);
});
}
// Test evaluating various expressions in the console after time warping.
add_task(async function() {
const dbg = await attachRecordingDebugger("doc_rr_error.html", {
const dbg = await attachRecordingDebugger("doc_rr_objects.html", {
waitForRecording: true,
});
const { toolbox } = dbg;
const { threadFront, toolbox } = dbg;
const console = await toolbox.selectTool("webconsole");
const hud = console.hud;
await warpToMessage(hud, dbg, "Number 5");
await warpToMessage(hud, dbg, "Done");
const requests = await threadFront.debuggerRequests();
requests.forEach(({ request, stack }) => {
if (request.type != "pauseData") {
dump(`Unexpected debugger request stack:\n${stack}\n`);
ok(false, `Unexpected debugger request while paused: ${request.type}`);
}
});
BrowserTest.execute(hud, "Error('helo')");
await waitFor(() => findMessage(hud, "helo"));
await waitForMessage(hud, "helo");
BrowserTest.execute(
hud,
@ -45,5 +79,58 @@ f();
);
await BrowserTest.checkMessageStack(hud, "Error: there", [3, 5]);
let msg;
BrowserTest.execute(hud, "Array(1, 2, 3)");
msg = await waitForMessage(hud, "Array(3) [ 1, 2, 3 ]");
await checkMessageObjectContents(msg, ["0: 1", "1: 2", "2: 3", "length: 3"]);
BrowserTest.execute(hud, "new Uint8Array([1, 2, 3, 4])");
msg = await waitForMessage(hud, "Uint8Array(4) [ 1, 2, 3, 4 ]");
await checkMessageObjectContents(msg, [
"0: 1",
"1: 2",
"2: 3",
"3: 4",
"byteLength: 4",
"byteOffset: 0",
]);
BrowserTest.execute(hud, `RegExp("abc", "g")`);
msg = await waitForMessage(hud, "/abc/g");
await checkMessageObjectContents(msg, ["global: true", `source: "abc"`]);
BrowserTest.execute(hud, "new Set([1, 2, 3])");
msg = await waitForMessage(hud, "Set(3) [ 1, 2, 3 ]");
await checkMessageObjectContents(
msg,
["0: 1", "1: 2", "2: 3", "size: 3"],
["<entries>"]
);
BrowserTest.execute(hud, "new Map([[1, {a:1}], [2, {b:2}]])");
msg = await waitForMessage(hud, "Map { 1 → {…}, 2 → {…} }");
await checkMessageObjectContents(
msg,
["0: 1 → Object { … }", "1: 2 → Object { … }", "size: 2"],
["<entries>"]
);
BrowserTest.execute(hud, "new WeakSet([{a:1}, {b:2}])");
msg = await waitForMessage(hud, "WeakSet [ {…}, {…} ]");
await checkMessageObjectContents(
msg,
["0: Object { … }", "1: Object { … }"],
["<entries>"]
);
BrowserTest.execute(hud, "new WeakMap([[{a:1},{b:1}], [{a:2},{b:2}]])");
msg = await waitForMessage(hud, "WeakMap { {…} → {…}, {…} → {…} }");
await checkMessageObjectContents(
msg,
["0: Object { … } → Object { … }", "1: Object { … } → Object { … }"],
["<entries>"]
);
await shutdownDebugger(dbg);
});

View File

@ -0,0 +1,38 @@
<div id="foo">BAR</div>
<script>
const cpmm = SpecialPowers.Services.cpmm;
function recordingFinished() {
cpmm.sendAsyncMessage("RecordingFinished");
}
function foo() {
// Create various objects which the debugger must be able to show in the scopes
// pane using only the pause data, i.e. without additional debugger requests.
// Not performing debugger requests allows the debugger to finish updating the
// UI using cached pause data, and without any replaying process actually being
// at the point where we are pausing.
var a = Array();
var b = new Uint8Array(20);
var c = new Set([{a:0},{b:1}]);
var d = new Map([[{a:0},{b:1}]]);
var e = new WeakSet();
var f = new WeakMap();
var g = { a:0 };
for (let i = 0; i < 20; i++) {
a.push(i);
b[i] = i;
c.add(i);
d.set(i, i + 1);
e.add({ i });
f.set({ i }, { j: i + 1 });
g[`a${i}`] = i;
}
var h = /abc/gi;
var i = new Date();
var j = RangeError();
var k = document.getElementById("foo");
console.log("Done");
window.setTimeout(recordingFinished);
}
foo();
</script>

View File

@ -111,7 +111,8 @@ function newRecordingFile() {
}
function findMessage(hud, text, selector = ".message") {
return findMessages(hud, text, selector)[0];
const messages = findMessages(hud, text, selector);
return messages ? messages[0] : null;
}
function findMessages(hud, text, selector = ".message") {
@ -127,6 +128,10 @@ function findMessages(hud, text, selector = ".message") {
return elements;
}
function waitForMessage(hud, text, selector = ".message") {
return waitUntilPredicate(() => findMessage(hud, text, selector));
}
function waitForMessages(hud, text, selector = ".message") {
return waitUntilPredicate(() => findMessages(hud, text, selector));
}