Bug 644412 - Export all data from Web Console to clipboard. r=nchevobbe
authorJefry Lagrange <jefry.reyes@gmail.com>
Mon, 14 Jan 2019 11:02:51 +0100
changeset 510879 9cc9822da7de89b2f24de19d85e1885fdb25a98c
parent 510878 b8baa741549c323261ff1dbfadcdf48c228acc80
child 510880 7ed5d740825007c2a3e04a749e7965de6874d2cb
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnchevobbe
bugs644412
milestone66.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 644412 - Export all data from Web Console to clipboard. r=nchevobbe
devtools/client/locales/en-US/webconsole.properties
devtools/client/webconsole/test/mochitest/browser.ini
devtools/client/webconsole/test/mochitest/browser_console_context_menu_entries.js
devtools/client/webconsole/test/mochitest/browser_webconsole_context_menu_export_console_output_clipboard.js
devtools/client/webconsole/utils/context-menu.js
--- a/devtools/client/locales/en-US/webconsole.properties
+++ b/devtools/client/locales/en-US/webconsole.properties
@@ -187,16 +187,21 @@ webconsole.menu.selectAll.label=Select a
 webconsole.menu.selectAll.accesskey=A
 
 # LOCALIZATION NOTE (webconsole.menu.openInSidebar.label)
 # Label used for a context-menu item displayed for object/variable logs. Clicking on it
 # opens the webconsole sidebar for the logged variable.
 webconsole.menu.openInSidebar.label=Open in sidebar
 webconsole.menu.openInSidebar.accesskey=V
 
+# LOCALIZATION NOTE (webconsole.menu.exportClipboard.label)
+# Label used for a context-menu item displayed on the output. Clicking on it
+# copies the entire output of the console to the clipboard.
+webconsole.menu.exportClipboard.label=Export visible messages to clipboard
+
 # LOCALIZATION NOTE (webconsole.menu.timeWarp.label)
 # Label used for a context-menu item displayed for any log. Clicking on it will
 # jump to the execution point where the log item was generated.
 webconsole.menu.timeWarp.label=Jump here
 
 # LOCALIZATION NOTE (webconsole.jumpButton.tooltip)
 # Label used for the tooltip on the "jump" button in the console. It's displayed when
 # the user recorded execution with WebReplay, is now paused in the debugger, and hover a
--- a/devtools/client/webconsole/test/mochitest/browser.ini
+++ b/devtools/client/webconsole/test/mochitest/browser.ini
@@ -278,16 +278,18 @@ skip-if = true # Bug 1405250
 [browser_webconsole_console_dir.js]
 [browser_webconsole_console_dir_uninspectable.js]
 [browser_webconsole_console_error_expand_object.js]
 [browser_webconsole_console_group.js]
 [browser_webconsole_console_logging_workers_api.js]
 skip-if = e10s # SharedWorkers console events are not received on the current process because they could run on any process.
 [browser_webconsole_console_table.js]
 [browser_webconsole_console_trace_duplicates.js]
+[browser_webconsole_context_menu_export_console_output_clipboard.js]
+subsuite = clipboard
 [browser_webconsole_context_menu_copy_entire_message.js]
 subsuite = clipboard
 skip-if = (os == 'linux' && bits == 32 && debug) # bug 1328915, disable linux32 debug devtools for timeouts
 [browser_webconsole_context_menu_copy_link_location.js]
 subsuite = clipboard
 skip-if = (os == 'linux' && bits == 32 && debug) || (os == 'linux') # bug 1328915, disable linux32 debug devtools for timeouts, bug 1473120
 [browser_webconsole_context_menu_copy_object.js]
 subsuite = clipboard
--- a/devtools/client/webconsole/test/mochitest/browser_console_context_menu_entries.js
+++ b/devtools/client/webconsole/test/mochitest/browser_console_context_menu_entries.js
@@ -39,16 +39,17 @@ async function performTests() {
 
   let expectedContextMenu = addPrefBasedEntries([
     "#console-menu-copy-url (a)",
     "#console-menu-open-url (T)",
     "#console-menu-store (S) [disabled]",
     "#console-menu-copy (C)",
     "#console-menu-copy-object (o) [disabled]",
     "#console-menu-select (A)",
+    "#console-menu-export-clipboard ()",
   ]);
   is(getSimplifiedContextMenu(menuPopup).join("\n"), expectedContextMenu.join("\n"),
     "The context menu has the expected entries for a network message");
 
   info("Logging a text message in the content window");
   const onLogMessage = waitForMessage(hud, "simple text message");
   ContentTask.spawn(gBrowser.selectedBrowser, null, () => {
     content.wrappedJSObject.console.log("simple text message");
@@ -58,16 +59,17 @@ async function performTests() {
   menuPopup = await openContextMenu(hud, logMessage.node);
   ok(menuPopup, "The context menu is displayed on a log message");
 
   expectedContextMenu = addPrefBasedEntries([
     "#console-menu-store (S) [disabled]",
     "#console-menu-copy (C)",
     "#console-menu-copy-object (o) [disabled]",
     "#console-menu-select (A)",
+    "#console-menu-export-clipboard ()",
   ]);
   is(getSimplifiedContextMenu(menuPopup).join("\n"), expectedContextMenu.join("\n"),
     "The context menu has the expected entries for a simple log message");
 
   menuPopup = await openContextMenu(hud, hud.jsterm.node || hud.jsterm.inputNode);
 
   expectedContextMenu = [
     "#editmenu-undo (editmenu-undo) [disabled]",
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_context_menu_export_console_output_clipboard.js
@@ -0,0 +1,69 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TEST_URI =
+`data:text/html;charset=utf-8,` +
+`<script>window.logStuff = function () {console.log("hello");};</script>`;
+const TEST_DATA = {
+  msg: "simple text message",
+  msg2: "second message test",
+};
+
+// Test the export visible messages to clipboard of the webconsole copies the expected
+// clipboard text for different log messages to find if everything is copied to clipboard.
+
+add_task(async function() {
+  const hud = await openNewTabAndConsole(TEST_URI);
+  hud.ui.clearOutput();
+
+  info("Call the log function defined in the test page");
+  await ContentTask.spawn(gBrowser.selectedBrowser, TEST_DATA, function(testData) {
+    content.wrappedJSObject.console.log(testData.msg);
+    content.wrappedJSObject.console.log(testData.msg2);
+    content.wrappedJSObject.console.log("object:", {a: 1},
+                                        "array:", ["b", "c"]);
+    content.wrappedJSObject.logStuff();
+  });
+
+  info("Test export to clipboard ");
+  await waitFor(() => findMessages(hud, "").length === 4);
+  const message = findMessage(hud, TEST_DATA.msg);
+  const clipboardText = await exportAllToClipboard(hud, message);
+  ok(true, "Clipboard text was found and saved");
+
+  const clipboardLines = clipboardText.split("\n");
+  info("Check if all messages where copied to clipboard");
+  is(clipboardLines[0].trim(), TEST_DATA.msg,
+    "found first text message in clipboard");
+  is(clipboardLines[1].trim(), TEST_DATA.msg2,
+    "found second text message in clipboard");
+  is(clipboardLines[2].trim(), 'object: Object { a: 1 } array: Array [ "b", "c" ]',
+    "found object and array in clipboard");
+  const CLEAN_URI = TEST_URI.replace("text/html;charset=utf-8,", "");
+  is(clipboardLines[3].trim(), `hello ${CLEAN_URI}:1:32`,
+    "found text from data uri");
+});
+
+/**
+ * Simple helper method to open the context menu on a given message, and click on the
+ * export visible messages to clipboard.
+ */
+async function exportAllToClipboard(hud, message) {
+  const menuPopup = await openContextMenu(hud, message);
+  const exportClipboard = menuPopup.querySelector("#console-menu-export-clipboard");
+  ok(exportClipboard, "copy menu item is enabled");
+
+  let clipboardText;
+  await waitForClipboardPromise(
+    () => exportClipboard.click(),
+    data => {
+      clipboardText = data;
+      return data;
+    }
+  );
+  return clipboardText;
+}
--- a/devtools/client/webconsole/utils/context-menu.js
+++ b/devtools/client/webconsole/utils/context-menu.js
@@ -165,16 +165,27 @@ function createContextMenu(hud, parentNo
     accesskey: l10n.getStr("webconsole.menu.selectAll.accesskey"),
     disabled: false,
     click: () => {
       const webconsoleOutput = parentNode.querySelector(".webconsole-output");
       selection.selectAllChildren(webconsoleOutput);
     },
   }));
 
+  // Export to clipboard
+  menu.append(new MenuItem({
+    id: "console-menu-export-clipboard",
+    label: l10n.getStr("webconsole.menu.exportClipboard.label"),
+    disabled: false,
+    click: () => {
+      const webconsoleOutput = parentNode.querySelector(".webconsole-output");
+      clipboardHelper.copyString(webconsoleOutput.textContent);
+    },
+  }));
+
   // Open object in sidebar.
   if (openSidebar) {
     menu.append(new MenuItem({
       id: "console-menu-open-sidebar",
       label: l10n.getStr("webconsole.menu.openInSidebar.label"),
       accesskey: l10n.getStr("webconsole.menu.openInSidebar.accesskey"),
       disabled: !rootActorId,
       click: () => openSidebar(message.messageId),