Bug 1326937 - Adapt extensions inspect() calls to the new frontend. r=rpl,bgrins
The inspect command in extension was directly calling jsterm.inspectObject and doing so bypassed
the code we implemented for the command on the new frontend (i.e. no more variable view).
This patch modifies the jsterm inspectObject function so it can can do the expected behavior.
This implied changing an extension test that was waiting for the variable view to boot-up.
The test was modified to match the tests we already have for the inspect command on the new
console frontend.
MozReview-Commit-ID: 5CSYGP2YUdr
--- a/browser/components/extensions/test/browser/browser_ext_devtools_inspectedWindow_eval_bindings.js
+++ b/browser/components/extensions/test/browser/browser_ext_devtools_inspectedWindow_eval_bindings.js
@@ -118,25 +118,63 @@ add_task(async function test_devtools_in
info("Toolbox has been switched to the inspector as expected");
info("Test inspectedWindow.eval inspect() binding called for a JS object");
const splitPanelOpenedPromise = (async () => {
await toolbox.once("split-console");
let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
- const options = await new Promise(resolve => {
- jsterm.once("variablesview-open", (evt, view, options) => resolve(options));
+ // Wait for the message to appear on the console.
+ const messageNode = await new Promise(resolve => {
+ jsterm.hud.on("new-messages", function onThisMessage(e, messages) {
+ for (let m of messages) {
+ resolve(m.node);
+ jsterm.hud.off("new-messages", onThisMessage);
+ return;
+ }
+ });
});
- const objectType = options.objectActor.type;
- const objectPreviewProperties = options.objectActor.preview.ownProperties;
- is(objectType, "object", "The inspected object has the expected type");
- Assert.deepEqual(Object.keys(objectPreviewProperties), ["testkey"],
+ let objectInspectors = [...messageNode.querySelectorAll(".tree")];
+ is(objectInspectors.length, 1, "There is the expected number of object inspectors");
+
+ const [objectInspector] = objectInspectors;
+ const getObjectInspectorNodes = () => objectInspector.querySelectorAll(".node");
+ let objectInspectorNodes = getObjectInspectorNodes();
+
+ // The tree can be collapsed since the properties are fetched asynchronously.
+ if (objectInspectorNodes.length === 1) {
+ // If this is the case, we wait for the properties to be fetched and displayed.
+ await new Promise(resolve => {
+ const observer = new MutationObserver(mutations => {
+ resolve(mutations);
+ observer.disconnect();
+ });
+ observer.observe(objectInspector, {childList: true});
+ });
+ objectInspectorNodes = getObjectInspectorNodes();
+ }
+
+ // Checking the root node of the object inspector.
+ is(objectInspectorNodes[0].querySelector(".objectTitle").textContent, "Object",
+ "The inspected object has the expected type");
+
+ // Checking the leaves of the object inspector.
+ let propertiesNodes = [...objectInspector.querySelectorAll(".object-label")];
+ const properties = propertiesNodes.map(el => el.textContent);
+ Assert.deepEqual(properties, ["testkey", "__proto__"],
"The inspected object has the expected preview properties");
+
+ const testPropertyLabelNode = propertiesNodes.find(el => el.textContent === "testkey");
+ const testPropertyValueNode = testPropertyLabelNode
+ .closest(".node")
+ .querySelector(".objectBox");
+ is(testPropertyValueNode.textContent, '"testvalue"',
+ "The inspected object has the expected preview values");
})();
await gDevTools.closeToolbox(target);
await target.destroy();
await extension.unload();
--- a/devtools/client/webconsole/jsterm.js
+++ b/devtools/client/webconsole/jsterm.js
@@ -399,16 +399,26 @@ JSTerm.prototype = {
}
if (WebConsoleUtils.isActorGrip(result)) {
msg._objectActors.add(result.actor);
}
},
inspectObjectActor: function (objectActor) {
+ if (this.hud.NEW_CONSOLE_OUTPUT_ENABLED) {
+ this.hud.newConsoleOutput.dispatchMessageAdd({
+ helperResult: {
+ type: "inspectObject",
+ object: objectActor
+ }
+ }, true);
+ return this.hud.newConsoleOutput;
+ }
+
return this.openVariablesView({
objectActor,
label: VariablesView.getString(objectActor, {concise: true}),
});
},
/**
* Execute a string. Execution happens asynchronously in the content process.