Bug 1567849 - Use ad-hoc console front for calls to evaluateJSAsync with selectedObjectActor. r=jdescottes.
authorNicolas Chevobbe <nchevobbe@mozilla.com>
Wed, 04 Dec 2019 09:06:00 +0000
changeset 505283 0b459def3e0827d848f1ed2ecf703c6164113575
parent 505282 a1f1ebad7d9d3e4b03ae57b789727590cedf6d5c
child 505284 7f7d7683109ab33dafe5f0891892582a1432e8bc
push id36881
push userdvarga@mozilla.com
push dateWed, 04 Dec 2019 16:22:31 +0000
treeherdermozilla-central@13fb375eaf14 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1567849
milestone73.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 1567849 - Use ad-hoc console front for calls to evaluateJSAsync with selectedObjectActor. r=jdescottes. When the selectedObjectActor options is passed to the evaluateJSAsync command in the console, we now try to retrieve the corresponding console front to send the request to the correct target. This makes the "Copy Object" context menu entry works in the Browser Console on content objects. A test is added to ensure this works as expected. Differential Revision: https://phabricator.services.mozilla.com/D55258
devtools/client/webconsole/commands.js
devtools/client/webconsole/test/browser/browser.ini
devtools/client/webconsole/test/browser/browser_console_content_object_context_menu.js
--- a/devtools/client/webconsole/commands.js
+++ b/devtools/client/webconsole/commands.js
@@ -7,28 +7,36 @@
 class ConsoleCommands {
   constructor({ debuggerClient, proxy, threadFront, currentTarget }) {
     this.debuggerClient = debuggerClient;
     this.proxy = proxy;
     this.threadFront = threadFront;
     this.currentTarget = currentTarget;
   }
 
-  evaluateJSAsync(expression, options = {}) {
-    const { selectedNodeFront, webConsoleFront } = options;
+  async evaluateJSAsync(expression, options = {}) {
+    const { selectedNodeFront, webConsoleFront, selectedObjectActor } = options;
     let front = this.proxy.webConsoleFront;
 
     // Defer to the selected paused thread front
     if (webConsoleFront) {
       front = webConsoleFront;
     }
 
-    // Defer to the selected node's thread console front
-    if (selectedNodeFront) {
-      front = selectedNodeFront.targetFront.activeConsole;
+    // If there's a selectedObjectActor option, this means the user intend to do a
+    // given action on a specific object, so it should take precedence over selected
+    // node front.
+    if (selectedObjectActor) {
+      const objectFront = this.debuggerClient.getFrontByID(selectedObjectActor);
+      if (objectFront) {
+        front = await objectFront.targetFront.getFront("console");
+      }
+    } else if (selectedNodeFront) {
+      // Defer to the selected node's thread console front
+      front = await selectedNodeFront.targetFront.getFront("console");
       options.selectedNodeActor = selectedNodeFront.actorID;
     }
 
     return front.evaluateJSAsync(expression, options);
   }
 
   timeWarp(executionPoint) {
     return this.threadFront.timeWarp(executionPoint);
--- a/devtools/client/webconsole/test/browser/browser.ini
+++ b/devtools/client/webconsole/test/browser/browser.ini
@@ -174,16 +174,17 @@ support-files =
 [browser_console_cpow.js]
 skip-if = !e10s # This test is only valid in e10s
 [browser_console_clear_cache.js]
 [browser_console_clear_method.js]
 skip-if = true # Bug XXX # Bug 1437843
 [browser_console_consolejsm_output.js]
 [browser_console_content_getters.js]
 [browser_console_content_longstring.js]
+[browser_console_content_object_context_menu.js]
 [browser_console_content_object_in_sidebar.js]
 [browser_console_content_object.js]
 [browser_console_context_menu_entries.js]
 skip-if = os == "linux" # Bug 1440059, disabled for all build types
 [browser_console_dead_objects.js]
 [browser_console_devtools_loader_exception.js]
 [browser_console_error_source_click.js]
 [browser_console_filters.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/test/browser/browser_console_content_object_context_menu.js
@@ -0,0 +1,74 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Test that "Copy Object" on a the content message works in the browser console.
+
+"use strict";
+
+const TEST_URI = `data:text/html,<meta charset=utf8>console API calls<script>
+  console.log({
+    contentObject: "YAY!",
+    deep: ["hello", "world"]
+  });
+</script>`;
+
+add_task(async function() {
+  // Show the content messages
+  await pushPref("devtools.browserconsole.contentMessages", true);
+  // Enable Fission browser console to see the logged content object
+  await pushPref("devtools.browsertoolbox.fission", true);
+
+  await addTab(TEST_URI);
+
+  info("Open the Browser Console");
+  const hud = await BrowserConsoleManager.toggleBrowserConsole();
+
+  info("Wait until the content object is displayed");
+  const objectMessage = await waitFor(() =>
+    findMessage(hud, `Object { contentObject: "YAY!", deep: (2) […] }`)
+  );
+  ok(true, "Content object is displayed in the Browser Console");
+
+  info("Expand the object");
+  const oi = objectMessage.querySelector(".tree");
+  oi.querySelector(".arrow").click();
+  // The object inspector now looks like:
+  // ▼ {…}
+  // |  contentObject: "YAY!"
+  // |  ▶︎ deep: Array [ "hello", "world" ]
+  // |  ▶︎ <prototype>
+  await waitFor(() => oi.querySelectorAll(".node").length === 4);
+  ok(true, "The ObjectInspector was expanded");
+  oi.scrollIntoView();
+
+  info("Check that the object can be copied to clipboard");
+  await testCopyObject(
+    hud,
+    oi.querySelector(".objectBox-object"),
+    JSON.stringify({ contentObject: "YAY!", deep: ["hello", "world"] }, null, 2)
+  );
+
+  info("Check that inner object can be copied to clipboard");
+  await testCopyObject(
+    hud,
+    oi.querySelector(".objectBox-array"),
+    JSON.stringify(["hello", "world"], null, 2)
+  );
+
+  info("Close the browser console");
+  await BrowserConsoleManager.toggleBrowserConsole();
+});
+
+async function testCopyObject(hud, element, expected) {
+  info("Check `Copy object` is enabled");
+  const menuPopup = await openContextMenu(hud, element);
+  const copyObjectMenuItem = menuPopup.querySelector(
+    "#console-menu-copy-object"
+  );
+  ok(!copyObjectMenuItem.disabled, "`Copy object` is enabled");
+
+  info("Click on `Copy object`");
+  await waitForClipboardPromise(() => copyObjectMenuItem.click(), expected);
+  await hideContextMenu(hud);
+}