Bug 1403130 - Support result as value grip on WebExtension InspectorWindow actor eval method. draft
authorLuca Greco <lgreco@mozilla.com>
Wed, 11 Oct 2017 15:06:27 +0200
changeset 748479 0dcc8b1903b1ba060a8e16b1bf73432e575d80b2
parent 719102 c4e4613dbe32bb218957a140e5d0bd4fe7d1e98c
child 748480 21c769b58b0ca6bbae9bfc894dbe520e6ac66453
child 748787 83e975ea1db1f255ec6df8e6a807f0d9fded67b0
child 748822 480508af10e7a7cb2d53412be01a792e577d30ec
push id97184
push userluca.greco@alcacoop.it
push dateMon, 29 Jan 2018 22:01:37 +0000
bugs1403130
milestone59.0a1
Bug 1403130 - Support result as value grip on WebExtension InspectorWindow actor eval method. MozReview-Commit-ID: Efxhsm4bApu
devtools/server/actors/webextension-inspected-window.js
devtools/server/tests/browser/browser_webextension_inspected_window.js
devtools/shared/specs/webextension-inspected-window.js
--- 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.
  */