Bug 1403130 - Support result as value grip on WebExtension InspectorWindow actor eval method.
MozReview-Commit-ID: Efxhsm4bApu
--- a/devtools/server/actors/webextension-inspected-window.js
+++ b/devtools/server/actors/webextension-inspected-window.js
@@ -496,16 +496,40 @@ var WebExtensionInspectedWindowActor = p
// TODO(rpl): can the result of executeInGlobalWithBinding be null or
// undefined? (which means that it is not a return, a yield or a throw).
console.error("Unexpected empty inspectedWindow.eval result for",
`${callerInfo.url}:${callerInfo.lineNumber}`);
}
if (evalResult) {
try {
+ // Return the evalResult as a grip (used by the WebExtensions
+ // devtools inspector's sidebar.setExpression API method).
+ if (options.evalResultAsGrip) {
+ if (!options.toolboxConsoleActorID) {
+ return {
+ exceptionInfo: {
+ isError: true,
+ code: "E_PROTOCOLERROR",
+ description: "Inspector protocol error: %s - %s",
+ details: [
+ "Unexpected invalid sidebar panel expression request",
+ "missing toolboxConsoleActorID",
+ ],
+ },
+ };
+ }
+
+ let consoleActor = DebuggerServer.searchAllConnectionsForActor(
+ options.toolboxConsoleActorID
+ );
+
+ return {valueGrip: consoleActor.createValueGrip(evalResult)};
+ }
+
if (evalResult && typeof evalResult === "object") {
evalResult = evalResult.unsafeDereference();
}
evalResult = JSON.parse(JSON.stringify(evalResult));
} catch (err) {
// The evaluation result cannot be sent over the RDP Protocol,
// report it as with the same data format used in the corresponding
// chrome API method.
--- a/devtools/server/tests/browser/browser_webextension_inspected_window.js
+++ b/devtools/server/tests/browser/browser_webextension_inspected_window.js
@@ -94,16 +94,53 @@ add_task(function* test_successfull_insp
is(result.value.href, MAIN_DOMAIN,
"Got the expected window.location.href property value");
is(result.value.protocol, "http:",
"Got the expected window.location.protocol property value");
yield teardown({client});
});
+add_task(function* test_successfull_inspectedWindowEval_resultAsGrip() {
+ const {client, inspectedWindowFront, form} = yield setup(MAIN_DOMAIN);
+ let result = yield inspectedWindowFront.eval(FAKE_CALLER_INFO, "window", {
+ evalResultAsGrip: true,
+ toolboxConsoleActorID: form.consoleActor
+ });
+
+ ok(result.valueGrip, "Got a result from inspectedWindow eval");
+ ok(result.valueGrip.actor, "Got a object actor as expected");
+ is(result.valueGrip.type, "object", "Got a value grip of type object");
+ is(result.valueGrip.class, "Window", "Got a value grip which is instanceof Location");
+
+ // Test invalid evalResultAsGrip request.
+ result = yield inspectedWindowFront.eval(
+ FAKE_CALLER_INFO, "window", {evalResultAsGrip: true}
+ );
+
+ ok(!result.value && !result.valueGrip,
+ "Got a null result from the invalid inspectedWindow eval call");
+ ok(result.exceptionInfo.isError, "Got an API Error result from inspectedWindow eval");
+ ok(!result.exceptionInfo.isException, "An error isException is false as expected");
+ is(result.exceptionInfo.code, "E_PROTOCOLERROR",
+ "Got the expected 'code' property in the error result");
+ is(result.exceptionInfo.description, "Inspector protocol error: %s - %s",
+ "Got the expected 'description' property in the error result");
+ is(result.exceptionInfo.details.length, 2,
+ "The 'details' array property should contains 1 element");
+ is(result.exceptionInfo.details[0],
+ "Unexpected invalid sidebar panel expression request",
+ "Got the expected content in the error results's details");
+ is(result.exceptionInfo.details[1],
+ "missing toolboxConsoleActorID",
+ "Got the expected content in the error results's details");
+
+ yield teardown({client});
+});
+
add_task(function* test_error_inspectedWindowEval_result() {
const {client, inspectedWindowFront} = yield setup(MAIN_DOMAIN);
const result = yield inspectedWindowFront.eval(FAKE_CALLER_INFO, "window", {});
ok(!result.value, "Got a null result from inspectedWindow eval");
ok(result.exceptionInfo.isError, "Got an API Error result from inspectedWindow eval");
ok(!result.exceptionInfo.isException, "An error isException is false as expected");
is(result.exceptionInfo.code, "E_PROTOCOLERROR",
--- a/devtools/shared/specs/webextension-inspected-window.js
+++ b/devtools/shared/specs/webextension-inspected-window.js
@@ -32,16 +32,20 @@ types.addDictType("webExtensionCallerInf
/**
* RDP type related to the inspectedWindow.eval method request.
*/
types.addDictType("webExtensionEvalOptions", {
frameURL: "nullable:string",
contextSecurityOrigin: "nullable:string",
useContentScriptContext: "nullable:boolean",
+ // Return the evalResult as a grip (used by the WebExtensions
+ // devtools inspector's sidebar.setExpression API method).
+ evalResultAsGrip: "nullable:boolean",
+
// The actor ID of the node selected in the inspector if any,
// used to provide the '$0' binding.
toolboxSelectedNodeActorID: "nullable:string",
// The actor ID of the console actor,
// used to provide the 'inspect' binding.
toolboxConsoleActorID: "nullable:string",
});
@@ -68,16 +72,17 @@ types.addDictType("webExtensionEvalExcep
/**
* RDP type related to the inspectedWindow.eval method result.
*/
types.addDictType("webExtensionEvalResult", {
// The following properties are set if the evaluation has been
// completed successfully.
value: "nullable:json",
+ valueGrip: "nullable:json",
// The following properties are set if the evalutation has been
// completed with errors.
exceptionInfo: "nullable:webExtensionEvalExceptionInfo",
});
/**
* RDP type related to the inspectedWindow.reload method request.
*/