diff --git a/browser/devtools/inspector/inspector-panel.js b/browser/devtools/inspector/inspector-panel.js index 04aa83af526f..c396042a3240 100644 --- a/browser/devtools/inspector/inspector-panel.js +++ b/browser/devtools/inspector/inspector-panel.js @@ -808,7 +808,7 @@ InspectorPanel.prototype = { let jsterm = panel.hud.jsterm; jsterm.execute("inspect($0)"); - jsterm.focusInput(); + jsterm.inputNode.focus(); }); }, diff --git a/browser/devtools/inspector/test/browser.ini b/browser/devtools/inspector/test/browser.ini index 9f144a0964af..45e51888e575 100644 --- a/browser/devtools/inspector/test/browser.ini +++ b/browser/devtools/inspector/test/browser.ini @@ -17,8 +17,7 @@ support-files = doc_inspector_highlighter_rect_iframe.html doc_inspector_infobar_01.html doc_inspector_infobar_02.html - doc_inspector_menu-01.html - doc_inspector_menu-02.html + doc_inspector_menu.html doc_inspector_remove-iframe-during-load.html doc_inspector_search.html doc_inspector_search-suggestions.html @@ -67,8 +66,10 @@ skip-if = e10s # GCLI isn't e10s compatible. See bug 1128988. [browser_inspector_inspect-object-element.js] [browser_inspector_invalidate.js] [browser_inspector_keyboard-shortcuts.js] -[browser_inspector_menu-01.js] -[browser_inspector_menu-02.js] +[browser_inspector_menu-01-sensitivity.js] +[browser_inspector_menu-02-copy-items.js] +[browser_inspector_menu-03-paste-items.js] +[browser_inspector_menu-04-other.js] [browser_inspector_navigation.js] [browser_inspector_picker-stop-on-destroy.js] [browser_inspector_picker-stop-on-tool-change.js] diff --git a/browser/devtools/inspector/test/browser_inspector_menu-01-sensitivity.js b/browser/devtools/inspector/test/browser_inspector_menu-01-sensitivity.js new file mode 100644 index 000000000000..8781765c8254 --- /dev/null +++ b/browser/devtools/inspector/test/browser_inspector_menu-01-sensitivity.js @@ -0,0 +1,202 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test that context menu items are enabled / disabled correctly. + +const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu.html"; + +const PASTE_MENU_ITEMS = [ + "node-menu-pasteinnerhtml", + "node-menu-pasteouterhtml", + "node-menu-pastebefore", + "node-menu-pasteafter", + "node-menu-pastefirstchild", + "node-menu-pastelastchild", +]; + +const ALL_MENU_ITEMS = [ + "node-menu-edithtml", + "node-menu-copyinner", + "node-menu-copyouter", + "node-menu-copyuniqueselector", + "node-menu-copyimagedatauri", + "node-menu-showdomproperties", + "node-menu-delete", + "node-menu-pseudo-hover", + "node-menu-pseudo-active", + "node-menu-pseudo-focus" +].concat(PASTE_MENU_ITEMS); + +const ITEMS_WITHOUT_SHOWDOMPROPS = + ALL_MENU_ITEMS.filter(item => item != "node-menu-showdomproperties"); + +const TEST_CASES = [ + { + desc: "doctype node with empty clipboard", + selector: null, + disabled: ITEMS_WITHOUT_SHOWDOMPROPS, + }, + { + desc: "doctype node with html on clipboard", + clipboardData: "

some text

", + clipboardDataType: "html", + selector: null, + disabled: ITEMS_WITHOUT_SHOWDOMPROPS, + }, + { + desc: "element node HTML on the clipboard", + clipboardData: "

some text

", + clipboardDataType: "html", + disabled: ["node-menu-copyimagedatauri"], + selector: "#sensitivity", + }, + { + desc: " element", + clipboardData: "

some text

", + clipboardDataType: "html", + selector: "html", + disabled: [ + "node-menu-copyimagedatauri", + "node-menu-pastebefore", + "node-menu-pasteafter", + "node-menu-pastefirstchild", + "node-menu-pastelastchild", + ], + }, + { + desc: " with HTML on clipboard", + clipboardData: "

some text

", + clipboardDataType: "html", + selector: "body", + disabled: [ + "node-menu-copyimagedatauri", + "node-menu-pastebefore", + "node-menu-pasteafter", + ] + }, + { + desc: " with HTML on clipboard", + clipboardData: "

some text

", + clipboardDataType: "html", + selector: "img", + disabled: [] + }, + { + desc: " with HTML on clipboard", + clipboardData: "

some text

", + clipboardDataType: "html", + selector: "head", + disabled: [ + "node-menu-copyimagedatauri", + "node-menu-pastebefore", + "node-menu-pasteafter", + ] + }, + { + desc: " with text on clipboard", + clipboardData: "some text", + clipboardDataType: undefined, + selector: "#paste-area", + disabled: ["node-menu-copyimagedatauri"], + }, + { + desc: " with base64 encoded image data uri on clipboard", + clipboardData: + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABC" + + "AAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==", + clipboardDataType: undefined, + selector: "#paste-area", + disabled: PASTE_MENU_ITEMS.concat(["node-menu-copyimagedatauri"]), + }, + { + desc: " with empty string on clipboard", + clipboardData: "", + clipboardDataType: undefined, + selector: "#paste-area", + disabled: PASTE_MENU_ITEMS.concat(["node-menu-copyimagedatauri"]), + }, + { + desc: " with whitespace only on clipboard", + clipboardData: " \n\n\t\n\n \n", + clipboardDataType: undefined, + selector: "#paste-area", + disabled: PASTE_MENU_ITEMS.concat(["node-menu-copyimagedatauri"]), + }, +]; + +let clipboard = require("sdk/clipboard"); +registerCleanupFunction(() => { + clipboard = null; +}); + +add_task(function *() { + let { inspector } = yield openInspectorForURL(TEST_URL); + for (let test of TEST_CASES) { + let { desc, disabled, selector } = test; + + info(`Test ${desc}`); + setupClipboard(test.clipboardData, test.clipboardDataType); + + let front = yield getNodeFrontForSelector(selector, inspector); + + info("Selecting the specified node."); + yield selectNode(front, inspector); + + info("Simulating context menu click on the selected node container."); + contextMenuClick(getContainerForNodeFront(front, inspector).tagLine); + + for (let menuitem of ALL_MENU_ITEMS) { + let elt = inspector.panelDoc.getElementById(menuitem); + let shouldBeDisabled = disabled.indexOf(menuitem) !== -1; + let isDisabled = elt.hasAttribute("disabled"); + + is(isDisabled, shouldBeDisabled, + `#${menuitem} should be ${shouldBeDisabled ? "disabled" : "enabled"} `); + } + } +}); + +/** + * A helper that fetches a front for a node that matches the given selector or + * doctype node if the selector is falsy. + */ +function* getNodeFrontForSelector(selector, inspector) { + if (selector) { + info("Retrieving front for selector " + selector); + return getNodeFront(selector, inspector); + } else { + info("Retrieving front for doctype node"); + let {nodes} = yield inspector.walker.children(inspector.walker.rootNode); + return nodes[0]; + } +} + +/** + * A helper that populates the clipboard with data of given type. Clears the + * clipboard if data is falsy. + */ +function setupClipboard(data, type) { + if (data) { + info("Populating clipboard with " + type + " data."); + clipboard.set(data, type); + } else { + info("Clearing clipboard."); + clipboard.set("", "text"); + } +} + +/** + * A helper that simulates a contextmenu event on the given chrome DOM element. + */ +function contextMenuClick(element) { + let evt = element.ownerDocument.createEvent('MouseEvents'); + let button = 2; // right click + + evt.initMouseEvent('contextmenu', true, true, + element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, + false, false, false, button, null); + + element.dispatchEvent(evt); +} diff --git a/browser/devtools/inspector/test/browser_inspector_menu-01.js b/browser/devtools/inspector/test/browser_inspector_menu-01.js deleted file mode 100644 index f5710e0c5710..000000000000 --- a/browser/devtools/inspector/test/browser_inspector_menu-01.js +++ /dev/null @@ -1,201 +0,0 @@ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. -http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -/////////////////// -// -// Whitelisting this test. -// As part of bug 1077403, the leaking uncaught rejection should be fixed. -// -thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: jsterm.focusInput is not a function"); - -// Test context menu functionality: -// 1) menu items are disabled/enabled depending on the clicked node -// 2) actions triggered by the items work correctly - -const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu-01.html"; -const MENU_SENSITIVITY_TEST_DATA = [ - { - desc: "doctype node", - selector: null, - disabled: true, - }, - { - desc: "element node", - selector: "p", - disabled: false, - } -]; - -const COPY_ITEMS_TEST_DATA = [ - { - desc: "copy inner html", - id: "node-menu-copyinner", - text: "This is some example text", - }, - { - desc: "copy outer html", - id: "node-menu-copyouter", - text: "

This is some example text

", - }, - { - desc: "copy unique selector", - id: "node-menu-copyuniqueselector", - text: "body > div:nth-child(1) > p:nth-child(2)", - }, -]; - -let clipboard = require("sdk/clipboard"); -registerCleanupFunction(() => { - clipboard = null; -}); - -add_task(function* () { - let { inspector, toolbox } = yield openInspectorForURL(TEST_URL); - - yield testMenuItemSensitivity(); - yield testCopyMenuItems(); - yield testShowDOMProperties(); - yield testDeleteNode(); - yield testDeleteRootNode(); - - function* testMenuItemSensitivity() { - info("Testing sensitivity of menu items for different elements."); - - // The sensibility for paste options are described in browser_inspector_menu-02.js - const MENU_ITEMS = [ - "node-menu-copyinner", - "node-menu-copyouter", - "node-menu-copyuniqueselector", - "node-menu-delete", - "node-menu-pseudo-hover", - "node-menu-pseudo-active", - "node-menu-pseudo-focus" - ]; - - for (let {desc, selector, disabled} of MENU_SENSITIVITY_TEST_DATA) { - info("Testing context menu entries for " + desc); - - let front; - if (selector) { - front = yield getNodeFront(selector, inspector); - } else { - // Select the docType if no selector is provided - let {nodes} = yield inspector.walker.children(inspector.walker.rootNode); - front = nodes[0]; - } - yield selectNode(front, inspector); - - contextMenuClick(getContainerForNodeFront(front, inspector).tagLine); - - for (let name of MENU_ITEMS) { - checkMenuItem(name, disabled); - } - } - } - - function* testCopyMenuItems() { - info("Testing various copy actions of context menu."); - for (let {desc, id, text} of COPY_ITEMS_TEST_DATA) { - info("Testing " + desc); - - let item = inspector.panelDoc.getElementById(id); - ok(item, "The popup has a " + desc + " menu item."); - - let deferred = promise.defer(); - waitForClipboard(text, () => item.doCommand(), - deferred.resolve, deferred.reject); - yield deferred.promise; - } - } - - function* testShowDOMProperties() { - info("Testing 'Show DOM Properties' menu item."); - let showDOMPropertiesNode = inspector.panelDoc.getElementById("node-menu-showdomproperties"); - ok(showDOMPropertiesNode, "the popup menu has a show dom properties item"); - - let consoleOpened = toolbox.once("webconsole-ready"); - - info("Triggering 'Show DOM Properties' and waiting for inspector open"); - dispatchCommandEvent(showDOMPropertiesNode); - yield consoleOpened; - - let webconsoleUI = toolbox.getPanel("webconsole").hud.ui; - let messagesAdded = webconsoleUI.once("new-messages"); - yield messagesAdded; - - info("Checking if 'inspect($0)' was evaluated"); - ok(webconsoleUI.jsterm.history[0] === 'inspect($0)'); - - yield toolbox.toggleSplitConsole(); - } - - function* testDeleteNode() { - info("Testing 'Delete Node' menu item for normal elements."); - - yield selectNode("p", inspector); - let deleteNode = inspector.panelDoc.getElementById("node-menu-delete"); - ok(deleteNode, "the popup menu has a delete menu item"); - - let updated = inspector.once("inspector-updated"); - - info("Triggering 'Delete Node' and waiting for inspector to update"); - dispatchCommandEvent(deleteNode); - yield updated; - - ok(!getNode("p", { expectNoMatch: true }), "Node deleted"); - } - - function* testDeleteRootNode() { - info("Testing 'Delete Node' menu item does not delete root node."); - yield selectNode(inspector.walker.rootNode, inspector); - - let deleteNode = inspector.panelDoc.getElementById("node-menu-delete"); - dispatchCommandEvent(deleteNode); - - executeSoon(() => { - ok(content.document.documentElement, "Document element still alive."); - }); - } - - function checkMenuItem(elementId, disabled) { - if (disabled) { - checkDisabled(elementId); - } else { - checkEnabled(elementId); - } - } - - function checkEnabled(elementId) { - let elt = inspector.panelDoc.getElementById(elementId); - ok(!elt.hasAttribute("disabled"), - '"' + elt.label + '" context menu option is not disabled'); - } - - function checkDisabled(elementId) { - let elt = inspector.panelDoc.getElementById(elementId); - ok(elt.hasAttribute("disabled"), - '"' + elt.label + '" context menu option is disabled'); - } - - function dispatchCommandEvent(node) { - info("Dispatching command event on " + node); - let commandEvent = document.createEvent("XULCommandEvent"); - commandEvent.initCommandEvent("command", true, true, window, 0, false, false, - false, false, null); - node.dispatchEvent(commandEvent); - } - - function contextMenuClick(element) { - info("Simulating contextmenu event on " + element); - let evt = element.ownerDocument.createEvent('MouseEvents'); - let button = 2; // right click - - evt.initMouseEvent('contextmenu', true, true, - element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, - false, false, false, button, null); - - element.dispatchEvent(evt); - } -}); diff --git a/browser/devtools/inspector/test/browser_inspector_menu-02-copy-items.js b/browser/devtools/inspector/test/browser_inspector_menu-02-copy-items.js new file mode 100644 index 000000000000..3f8ab24cefc3 --- /dev/null +++ b/browser/devtools/inspector/test/browser_inspector_menu-02-copy-items.js @@ -0,0 +1,51 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test that the various copy items in the context menu works correctly. + +const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu.html"; +const COPY_ITEMS_TEST_DATA = [ + { + desc: "copy inner html", + id: "node-menu-copyinner", + selector: "[data-id=\"copy\"]", + text: "Paragraph for testing copy", + }, + { + desc: "copy outer html", + id: "node-menu-copyouter", + selector: "[data-id=\"copy\"]", + text: "

Paragraph for testing copy

", + }, + { + desc: "copy unique selector", + id: "node-menu-copyuniqueselector", + selector: "[data-id=\"copy\"]", + text: "body > div:nth-child(1) > p:nth-child(2)", + }, + { + desc: "copy image data uri", + id: "node-menu-copyimagedatauri", + selector: "#copyimage", + text: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABC" + + "AAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==", + }, +]; + +add_task(function *() { + let { inspector } = yield openInspectorForURL(TEST_URL); + for (let {desc, id, selector, text} of COPY_ITEMS_TEST_DATA) { + info("Testing " + desc); + yield selectNode(selector, inspector); + + let item = inspector.panelDoc.getElementById(id); + ok(item, "The popup has a " + desc + " menu item."); + + let deferred = promise.defer(); + waitForClipboard(text, () => item.doCommand(), + deferred.resolve, deferred.reject); + yield deferred.promise; + } +}); diff --git a/browser/devtools/inspector/test/browser_inspector_menu-02.js b/browser/devtools/inspector/test/browser_inspector_menu-02.js deleted file mode 100644 index 32d955d19f73..000000000000 --- a/browser/devtools/inspector/test/browser_inspector_menu-02.js +++ /dev/null @@ -1,326 +0,0 @@ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. -http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; - -// Test context menu functionality: -// 1) menu items are disabled/enabled depending on the clicked node -// 2) actions triggered by the items work correctly - -/////////////////// -// -// Whitelisting this test. -// As part of bug 1077403, the leaking uncaught rejection should be fixed. -// -thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: jsterm.focusInput is not a function"); - -const MENU_SENSITIVITY_TEST_DATA = [ - { - desc: "doctype node", - selector: null, - disabled: true, - }, - { - desc: "element node", - selector: "#sensitivity", - disabled: false, - }, - { - desc: "document element", - selector: "html", - disabled: { - "node-menu-pastebefore": true, - "node-menu-pasteafter": true, - "node-menu-pastefirstchild": true, - "node-menu-pastelastchild": true, - } - }, - { - desc: "body", - selector: "body", - disabled: { - "node-menu-pastebefore": true, - "node-menu-pasteafter": true, - } - }, - { - desc: "head", - selector: "head", - disabled: { - "node-menu-pastebefore": true, - "node-menu-pasteafter": true, - } - } -]; - -const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu-02.html"; - -const PASTE_HTML_TEST_SENSITIVITY_DATA = [ - { - desc: "some text", - clipboardData: "some text", - clipboardDataType: undefined, - disabled: false - }, - { - desc: "base64 encoded image data uri", - clipboardData: - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABC" + - "AAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==", - clipboardDataType: undefined, - disabled: true - }, - { - desc: "html", - clipboardData: "

some text

", - clipboardDataType: "html", - disabled: false - }, - { - desc: "empty string", - clipboardData: "", - clipboardDataType: undefined, - disabled: true - }, - { - desc: "whitespace only", - clipboardData: " \n\n\t\n\n \n", - clipboardDataType: undefined, - disabled: true - }, -]; - -const PASTE_ADJACENT_HTML_DATA = [ - { - desc: "As First Child", - clipboardData: "2", - menuId: "node-menu-pastefirstchild", - }, - { - desc: "As Last Child", - clipboardData: "4", - menuId: "node-menu-pastelastchild", - }, - { - desc: "Before", - clipboardData: "1", - menuId: "node-menu-pastebefore", - }, - { - desc: "After", - clipboardData: "5", - menuId: "node-menu-pasteafter", - }, -]; - - -let clipboard = require("sdk/clipboard"); -registerCleanupFunction(() => { - clipboard = null; -}); - -add_task(function* () { - let { inspector, toolbox } = yield openInspectorForURL(TEST_URL); - - yield testMenuItemSensitivity(); - yield testPasteHTMLMenuItemsSensitivity(); - yield testPasteOuterHTMLMenu(); - yield testPasteInnerHTMLMenu(); - yield testPasteAdjacentHTMLMenu(); - - function* testMenuItemSensitivity() { - info("Testing sensitivity of menu items for different elements."); - - const MENU_ITEMS = [ - "node-menu-pasteinnerhtml", - "node-menu-pasteouterhtml", - "node-menu-pastebefore", - "node-menu-pasteafter", - "node-menu-pastefirstchild", - "node-menu-pastelastchild", - ]; - - // To ensure clipboard contains something to paste. - clipboard.set("

test

", "html"); - - for (let {desc, selector, disabled} of MENU_SENSITIVITY_TEST_DATA) { - info("Testing context menu entries for " + desc); - - let front; - if (selector) { - front = yield getNodeFront(selector, inspector); - } else { - // Select the docType if no selector is provided - let {nodes} = yield inspector.walker.children(inspector.walker.rootNode); - front = nodes[0]; - } - yield selectNode(front, inspector); - - contextMenuClick(getContainerForNodeFront(front, inspector).tagLine); - - for (let name of MENU_ITEMS) { - let disabledForMenu = typeof disabled === "object" ? - disabled[name] : disabled; - info(`${name} should be ${disabledForMenu ? "disabled" : "enabled"} ` + - `for ${desc}`); - checkMenuItem(name, disabledForMenu); - } - } - } - - function* testPasteHTMLMenuItemsSensitivity() { - let menus = [ - "node-menu-pasteinnerhtml", - "node-menu-pasteouterhtml", - "node-menu-pastebefore", - "node-menu-pasteafter", - "node-menu-pastefirstchild", - "node-menu-pastelastchild", - ]; - - info("Checking Paste menu items sensitivity for different types" + - "of data"); - - let nodeFront = yield getNodeFront("#paste-area", inspector); - let markupTagLine = getContainerForNodeFront(nodeFront, inspector).tagLine; - - for (let menuId of menus) { - for (let data of PASTE_HTML_TEST_SENSITIVITY_DATA) { - let { desc, clipboardData, clipboardDataType, disabled } = data; - let menuLabel = getLabelFor("#" + menuId); - info(`Checking ${menuLabel} for ${desc}`); - clipboard.set(clipboardData, clipboardDataType); - - yield selectNode(nodeFront, inspector); - - contextMenuClick(markupTagLine); - checkMenuItem(menuId, disabled); - } - } - } - - function* testPasteOuterHTMLMenu() { - info("Testing that 'Paste Outer HTML' menu item works."); - clipboard.set("this was pasted (outerHTML)"); - let outerHTMLSelector = "#paste-area h1"; - - let nodeFront = yield getNodeFront(outerHTMLSelector, inspector); - yield selectNode(nodeFront, inspector); - - contextMenuClick(getContainerForNodeFront(nodeFront, inspector).tagLine); - - let onNodeReselected = inspector.markup.once("reselectedonremoved"); - let menu = inspector.panelDoc.getElementById("node-menu-pasteouterhtml"); - dispatchCommandEvent(menu); - - info("Waiting for inspector selection to update"); - yield onNodeReselected; - - ok(content.document.body.outerHTML.contains(clipboard.get()), - "Clipboard content was pasted into the node's outer HTML."); - ok(!getNode(outerHTMLSelector, { expectNoMatch: true }), - "The original node was removed."); - } - - function* testPasteInnerHTMLMenu() { - info("Testing that 'Paste Inner HTML' menu item works."); - clipboard.set("this was pasted (innerHTML)"); - let innerHTMLSelector = "#paste-area .inner"; - let getInnerHTML = () => content.document.querySelector(innerHTMLSelector).innerHTML; - let origInnerHTML = getInnerHTML(); - - let nodeFront = yield getNodeFront(innerHTMLSelector, inspector); - yield selectNode(nodeFront, inspector); - - contextMenuClick(getContainerForNodeFront(nodeFront, inspector).tagLine); - - let onMutation = inspector.once("markupmutation"); - let menu = inspector.panelDoc.getElementById("node-menu-pasteinnerhtml"); - dispatchCommandEvent(menu); - - info("Waiting for mutation to occur"); - yield onMutation; - - ok(getInnerHTML() === clipboard.get(), - "Clipboard content was pasted into the node's inner HTML."); - ok(getNode(innerHTMLSelector), "The original node has been preserved."); - yield undoChange(inspector); - ok(getInnerHTML() === origInnerHTML, "Previous innerHTML has been " + - "restored after undo"); - } - - function* testPasteAdjacentHTMLMenu() { - let refSelector = "#paste-area .adjacent .ref"; - let adjacentNode = content.document.querySelector(refSelector).parentNode; - let nodeFront = yield getNodeFront(refSelector, inspector); - yield selectNode(nodeFront, inspector); - let markupTagLine = getContainerForNodeFront(nodeFront, inspector).tagLine; - - for (let { desc, clipboardData, menuId } of PASTE_ADJACENT_HTML_DATA) { - let menu = inspector.panelDoc.getElementById(menuId); - info(`Testing ${getLabelFor(menu)} for ${clipboardData}`); - clipboard.set(clipboardData); - - contextMenuClick(markupTagLine); - let onMutation = inspector.once("markupmutation"); - dispatchCommandEvent(menu); - - info("Waiting for mutation to occur"); - yield onMutation; - } - - ok(adjacentNode.innerHTML.trim() === "1234" + - "5", "The Paste as Last Child / as First Child / Before " + - "/ After worked as expected"); - yield undoChange(inspector); - ok(adjacentNode.innerHTML.trim() === "1234", - "Undo works for paste adjacent HTML"); - } - - function checkMenuItem(elementId, disabled) { - if (disabled) { - checkDisabled(elementId); - } else { - checkEnabled(elementId); - } - } - - function checkEnabled(elementId) { - let elt = inspector.panelDoc.getElementById(elementId); - ok(!elt.hasAttribute("disabled"), - '"' + elt.label + '" context menu option is not disabled'); - } - - function checkDisabled(elementId) { - let elt = inspector.panelDoc.getElementById(elementId); - ok(elt.hasAttribute("disabled"), - '"' + elt.label + '" context menu option is disabled'); - } - - function dispatchCommandEvent(node) { - info("Dispatching command event on " + node); - let commandEvent = document.createEvent("XULCommandEvent"); - commandEvent.initCommandEvent("command", true, true, window, 0, false, false, - false, false, null); - node.dispatchEvent(commandEvent); - } - - function contextMenuClick(element) { - info("Simulating contextmenu event on " + element); - let evt = element.ownerDocument.createEvent('MouseEvents'); - let button = 2; // right click - - evt.initMouseEvent('contextmenu', true, true, - element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, - false, false, false, button, null); - - element.dispatchEvent(evt); - } - - function getLabelFor(elt) { - if (typeof elt === "string") - elt = inspector.panelDoc.querySelector(elt); - let isInPasteSubMenu = elt.matches("#node-menu-paste-extra-submenu *"); - return `"${isInPasteSubMenu ? "Paste > " : ""}${elt.label}"`; - } -}); diff --git a/browser/devtools/inspector/test/browser_inspector_menu-03-paste-items.js b/browser/devtools/inspector/test/browser_inspector_menu-03-paste-items.js new file mode 100644 index 000000000000..78c1004e1b1f --- /dev/null +++ b/browser/devtools/inspector/test/browser_inspector_menu-03-paste-items.js @@ -0,0 +1,150 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Test that different paste items work in the context menu + + +const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu.html"; +const PASTE_ADJACENT_HTML_DATA = [ + { + desc: "As First Child", + clipboardData: "2", + menuId: "node-menu-pastefirstchild", + }, + { + desc: "As Last Child", + clipboardData: "4", + menuId: "node-menu-pastelastchild", + }, + { + desc: "Before", + clipboardData: "1", + menuId: "node-menu-pastebefore", + }, + { + desc: "After", + clipboardData: "5", + menuId: "node-menu-pasteafter", + }, +]; + + +let clipboard = require("sdk/clipboard"); +registerCleanupFunction(() => { + clipboard = null; +}); + +add_task(function* () { + let { inspector } = yield openInspectorForURL(TEST_URL); + + yield testPasteOuterHTMLMenu(); + yield testPasteInnerHTMLMenu(); + yield testPasteAdjacentHTMLMenu(); + + function* testPasteOuterHTMLMenu() { + info("Testing that 'Paste Outer HTML' menu item works."); + clipboard.set("this was pasted (outerHTML)"); + let outerHTMLSelector = "#paste-area h1"; + + let nodeFront = yield getNodeFront(outerHTMLSelector, inspector); + yield selectNode(nodeFront, inspector); + + contextMenuClick(getContainerForNodeFront(nodeFront, inspector).tagLine); + + let onNodeReselected = inspector.markup.once("reselectedonremoved"); + let menu = inspector.panelDoc.getElementById("node-menu-pasteouterhtml"); + dispatchCommandEvent(menu); + + info("Waiting for inspector selection to update"); + yield onNodeReselected; + + ok(content.document.body.outerHTML.contains(clipboard.get()), + "Clipboard content was pasted into the node's outer HTML."); + ok(!getNode(outerHTMLSelector, { expectNoMatch: true }), + "The original node was removed."); + } + + function* testPasteInnerHTMLMenu() { + info("Testing that 'Paste Inner HTML' menu item works."); + clipboard.set("this was pasted (innerHTML)"); + let innerHTMLSelector = "#paste-area .inner"; + let getInnerHTML = () => content.document.querySelector(innerHTMLSelector).innerHTML; + let origInnerHTML = getInnerHTML(); + + let nodeFront = yield getNodeFront(innerHTMLSelector, inspector); + yield selectNode(nodeFront, inspector); + + contextMenuClick(getContainerForNodeFront(nodeFront, inspector).tagLine); + + let onMutation = inspector.once("markupmutation"); + let menu = inspector.panelDoc.getElementById("node-menu-pasteinnerhtml"); + dispatchCommandEvent(menu); + + info("Waiting for mutation to occur"); + yield onMutation; + + ok(getInnerHTML() === clipboard.get(), + "Clipboard content was pasted into the node's inner HTML."); + ok(getNode(innerHTMLSelector), "The original node has been preserved."); + yield undoChange(inspector); + ok(getInnerHTML() === origInnerHTML, "Previous innerHTML has been " + + "restored after undo"); + } + + function* testPasteAdjacentHTMLMenu() { + let refSelector = "#paste-area .adjacent .ref"; + let adjacentNode = content.document.querySelector(refSelector).parentNode; + let nodeFront = yield getNodeFront(refSelector, inspector); + yield selectNode(nodeFront, inspector); + let markupTagLine = getContainerForNodeFront(nodeFront, inspector).tagLine; + + for (let { clipboardData, menuId } of PASTE_ADJACENT_HTML_DATA) { + let menu = inspector.panelDoc.getElementById(menuId); + info(`Testing ${getLabelFor(menu)} for ${clipboardData}`); + clipboard.set(clipboardData); + + contextMenuClick(markupTagLine); + let onMutation = inspector.once("markupmutation"); + dispatchCommandEvent(menu); + + info("Waiting for mutation to occur"); + yield onMutation; + } + + ok(adjacentNode.innerHTML.trim() === "1234" + + "5", "The Paste as Last Child / as First Child / Before " + + "/ After worked as expected"); + yield undoChange(inspector); + ok(adjacentNode.innerHTML.trim() === "1234", + "Undo works for paste adjacent HTML"); + } + + function dispatchCommandEvent(node) { + info("Dispatching command event on " + node); + let commandEvent = document.createEvent("XULCommandEvent"); + commandEvent.initCommandEvent("command", true, true, window, 0, false, false, + false, false, null); + node.dispatchEvent(commandEvent); + } + + function contextMenuClick(element) { + info("Simulating contextmenu event on " + element); + let evt = element.ownerDocument.createEvent('MouseEvents'); + let button = 2; // right click + + evt.initMouseEvent('contextmenu', true, true, + element.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, + false, false, false, button, null); + + element.dispatchEvent(evt); + } + + function getLabelFor(elt) { + if (typeof elt === "string") + elt = inspector.panelDoc.querySelector(elt); + let isInPasteSubMenu = elt.matches("#node-menu-paste-extra-submenu *"); + return `"${isInPasteSubMenu ? "Paste > " : ""}${elt.label}"`; + } +}); diff --git a/browser/devtools/inspector/test/browser_inspector_menu-04-other.js b/browser/devtools/inspector/test/browser_inspector_menu-04-other.js new file mode 100644 index 000000000000..1f54aa7615ee --- /dev/null +++ b/browser/devtools/inspector/test/browser_inspector_menu-04-other.js @@ -0,0 +1,73 @@ +/* vim: set ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. +http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +// Tests for menuitem functionality that doesn't fit into any specific category + +const TEST_URL = TEST_URL_ROOT + "doc_inspector_menu.html"; + +add_task(function* () { + let { inspector, toolbox } = yield openInspectorForURL(TEST_URL); + + yield testShowDOMProperties(); + yield testDeleteNode(); + yield testDeleteRootNode(); + + function* testShowDOMProperties() { + info("Testing 'Show DOM Properties' menu item."); + let showDOMPropertiesNode = inspector.panelDoc.getElementById("node-menu-showdomproperties"); + ok(showDOMPropertiesNode, "the popup menu has a show dom properties item"); + + let consoleOpened = toolbox.once("webconsole-ready"); + + info("Triggering 'Show DOM Properties' and waiting for inspector open"); + dispatchCommandEvent(showDOMPropertiesNode); + yield consoleOpened; + + let webconsoleUI = toolbox.getPanel("webconsole").hud.ui; + let messagesAdded = webconsoleUI.once("new-messages"); + yield messagesAdded; + + info("Checking if 'inspect($0)' was evaluated"); + ok(webconsoleUI.jsterm.history[0] === 'inspect($0)'); + + yield toolbox.toggleSplitConsole(); + } + + function* testDeleteNode() { + info("Testing 'Delete Node' menu item for normal elements."); + + yield selectNode("#delete", inspector); + let deleteNode = inspector.panelDoc.getElementById("node-menu-delete"); + ok(deleteNode, "the popup menu has a delete menu item"); + + let updated = inspector.once("inspector-updated"); + + info("Triggering 'Delete Node' and waiting for inspector to update"); + dispatchCommandEvent(deleteNode); + yield updated; + + ok(!getNode("#delete", { expectNoMatch: true }), "Node deleted"); + } + + function* testDeleteRootNode() { + info("Testing 'Delete Node' menu item does not delete root node."); + yield selectNode("html", inspector); + + let deleteNode = inspector.panelDoc.getElementById("node-menu-delete"); + dispatchCommandEvent(deleteNode); + + executeSoon(() => { + ok(content.document.documentElement, "Document element still alive."); + }); + } + + function dispatchCommandEvent(node) { + info("Dispatching command event on " + node); + let commandEvent = document.createEvent("XULCommandEvent"); + commandEvent.initCommandEvent("command", true, true, window, 0, false, false, + false, false, null); + node.dispatchEvent(commandEvent); + } +}); diff --git a/browser/devtools/inspector/test/doc_inspector_menu-01.html b/browser/devtools/inspector/test/doc_inspector_menu-01.html deleted file mode 100644 index 52c94923becc..000000000000 --- a/browser/devtools/inspector/test/doc_inspector_menu-01.html +++ /dev/null @@ -1,10 +0,0 @@ - - - Inspector Tree Menu Test - - -
-

Inspector Tree Menu Test

-

This is some example text

-
- diff --git a/browser/devtools/inspector/test/doc_inspector_menu-02.html b/browser/devtools/inspector/test/doc_inspector_menu.html similarity index 77% rename from browser/devtools/inspector/test/doc_inspector_menu-02.html rename to browser/devtools/inspector/test/doc_inspector_menu.html index c5f0249677fd..13dbed3131f4 100644 --- a/browser/devtools/inspector/test/doc_inspector_menu-02.html +++ b/browser/devtools/inspector/test/doc_inspector_menu.html @@ -16,6 +16,7 @@

Paragraph for testing copy

Paragraph for sensitivity

This has to be deleted

+