зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1035140
- Split browser_inspector_menu-0?.js into multiple tests. r=pbrosset
--HG-- rename : browser/devtools/inspector/test/browser_inspector_menu-02.js => browser/devtools/inspector/test/browser_inspector_menu-03-paste-items.js rename : browser/devtools/inspector/test/browser_inspector_menu-01.js => browser/devtools/inspector/test/browser_inspector_menu-04-other.js rename : browser/devtools/inspector/test/doc_inspector_menu-02.html => browser/devtools/inspector/test/doc_inspector_menu.html extra : rebase_source : 7d4fb3527bd0103859ce9aaee40974aa98b26ac5
This commit is contained in:
Родитель
02d6847dd7
Коммит
ffa08e1726
|
@ -808,7 +808,7 @@ InspectorPanel.prototype = {
|
|||
let jsterm = panel.hud.jsterm;
|
||||
|
||||
jsterm.execute("inspect($0)");
|
||||
jsterm.focusInput();
|
||||
jsterm.inputNode.focus();
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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: "<p>some text</p>",
|
||||
clipboardDataType: "html",
|
||||
selector: null,
|
||||
disabled: ITEMS_WITHOUT_SHOWDOMPROPS,
|
||||
},
|
||||
{
|
||||
desc: "element node HTML on the clipboard",
|
||||
clipboardData: "<p>some text</p>",
|
||||
clipboardDataType: "html",
|
||||
disabled: ["node-menu-copyimagedatauri"],
|
||||
selector: "#sensitivity",
|
||||
},
|
||||
{
|
||||
desc: "<html> element",
|
||||
clipboardData: "<p>some text</p>",
|
||||
clipboardDataType: "html",
|
||||
selector: "html",
|
||||
disabled: [
|
||||
"node-menu-copyimagedatauri",
|
||||
"node-menu-pastebefore",
|
||||
"node-menu-pasteafter",
|
||||
"node-menu-pastefirstchild",
|
||||
"node-menu-pastelastchild",
|
||||
],
|
||||
},
|
||||
{
|
||||
desc: "<body> with HTML on clipboard",
|
||||
clipboardData: "<p>some text</p>",
|
||||
clipboardDataType: "html",
|
||||
selector: "body",
|
||||
disabled: [
|
||||
"node-menu-copyimagedatauri",
|
||||
"node-menu-pastebefore",
|
||||
"node-menu-pasteafter",
|
||||
]
|
||||
},
|
||||
{
|
||||
desc: "<img> with HTML on clipboard",
|
||||
clipboardData: "<p>some text</p>",
|
||||
clipboardDataType: "html",
|
||||
selector: "img",
|
||||
disabled: []
|
||||
},
|
||||
{
|
||||
desc: "<head> with HTML on clipboard",
|
||||
clipboardData: "<p>some text</p>",
|
||||
clipboardDataType: "html",
|
||||
selector: "head",
|
||||
disabled: [
|
||||
"node-menu-copyimagedatauri",
|
||||
"node-menu-pastebefore",
|
||||
"node-menu-pasteafter",
|
||||
]
|
||||
},
|
||||
{
|
||||
desc: "<element> with text on clipboard",
|
||||
clipboardData: "some text",
|
||||
clipboardDataType: undefined,
|
||||
selector: "#paste-area",
|
||||
disabled: ["node-menu-copyimagedatauri"],
|
||||
},
|
||||
{
|
||||
desc: "<element> 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: "<element> with empty string on clipboard",
|
||||
clipboardData: "",
|
||||
clipboardDataType: undefined,
|
||||
selector: "#paste-area",
|
||||
disabled: PASTE_MENU_ITEMS.concat(["node-menu-copyimagedatauri"]),
|
||||
},
|
||||
{
|
||||
desc: "<element> 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);
|
||||
}
|
|
@ -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: "<p>This is some example text</p>",
|
||||
},
|
||||
{
|
||||
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);
|
||||
}
|
||||
});
|
|
@ -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: "<p data-id=\"copy\">Paragraph for testing copy</p>",
|
||||
},
|
||||
{
|
||||
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;
|
||||
}
|
||||
});
|
|
@ -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: "<p>some text</p>",
|
||||
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: "<span>5</span>",
|
||||
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("<p>test</p>", "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() === "1<span class=\"ref\">234</span>" +
|
||||
"<span>5</span>", "The Paste as Last Child / as First Child / Before " +
|
||||
"/ After worked as expected");
|
||||
yield undoChange(inspector);
|
||||
ok(adjacentNode.innerHTML.trim() === "1<span class=\"ref\">234</span>",
|
||||
"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}"`;
|
||||
}
|
||||
});
|
|
@ -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: "<span>5</span>",
|
||||
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() === "1<span class=\"ref\">234</span>" +
|
||||
"<span>5</span>", "The Paste as Last Child / as First Child / Before " +
|
||||
"/ After worked as expected");
|
||||
yield undoChange(inspector);
|
||||
ok(adjacentNode.innerHTML.trim() === "1<span class=\"ref\">234</span>",
|
||||
"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}"`;
|
||||
}
|
||||
});
|
|
@ -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);
|
||||
}
|
||||
});
|
|
@ -1,10 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>Inspector Tree Menu Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1>Inspector Tree Menu Test</h1>
|
||||
<p>This is some example text</p>
|
||||
</div>
|
||||
</body>
|
|
@ -16,6 +16,7 @@
|
|||
<p data-id="copy">Paragraph for testing copy</p>
|
||||
<p id="sensitivity">Paragraph for sensitivity</p>
|
||||
<p id="delete">This has to be deleted</p>
|
||||
<img id="copyimage" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==" />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче