mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 09:49:14 +00:00
Bug 988314 - Clean up and rewrite Inspector tests to use Task.jsm and generators. r=pbrosset
This commit is contained in:
parent
65aa288259
commit
ca224fd52d
@ -1,100 +1,54 @@
|
||||
/* 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";
|
||||
|
||||
function test()
|
||||
{
|
||||
ignoreAllUncaughtExceptions();
|
||||
// Test that the breadcrumbs widget content is correct.
|
||||
|
||||
let nodes = [
|
||||
{nodeId: "i1111", result: "i1 i11 i111 i1111"},
|
||||
{nodeId: "i22", result: "i2 i22 i221"},
|
||||
{nodeId: "i2111", result: "i2 i21 i211 i2111"},
|
||||
{nodeId: "i21", result: "i2 i21 i211 i2111"},
|
||||
{nodeId: "i22211", result: "i2 i22 i222 i2221 i22211"},
|
||||
{nodeId: "i22", result: "i2 i22 i222 i2221 i22211"},
|
||||
];
|
||||
const TEST_URI = TEST_URL_ROOT + "browser_inspector_breadcrumbs.html";
|
||||
const NODES = [
|
||||
{nodeId: "#i1111", result: "i1 i11 i111 i1111"},
|
||||
{nodeId: "#i22", result: "i2 i22 i221"},
|
||||
{nodeId: "#i2111", result: "i2 i21 i211 i2111"},
|
||||
{nodeId: "#i21", result: "i2 i21 i211 i2111"},
|
||||
{nodeId: "#i22211", result: "i2 i22 i222 i2221 i22211"},
|
||||
{nodeId: "#i22", result: "i2 i22 i222 i2221 i22211"},
|
||||
];
|
||||
|
||||
let doc;
|
||||
let nodes;
|
||||
let cursor;
|
||||
let inspector;
|
||||
let target;
|
||||
let panel;
|
||||
let container;
|
||||
let test = asyncTest(function*() {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URI);
|
||||
let container = inspector.panelDoc.getElementById("inspector-breadcrumbs");
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
doc = content.document;
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
for (let node of NODES) {
|
||||
info("Testing node " + node.nodeId);
|
||||
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_breadcrumbs.html";
|
||||
let documentNode = getNode(node.nodeId);
|
||||
|
||||
function setupTest()
|
||||
{
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
let node = doc.getElementById(nodes[i].nodeId);
|
||||
nodes[i].node = node;
|
||||
ok(nodes[i].node, "node " + nodes[i].nodeId + " found");
|
||||
}
|
||||
info("Selecting node and waiting for breadcrumbs to update");
|
||||
let breadcrumbsUpdated = inspector.once("breadcrumbs-updated");
|
||||
let nodeSelected = selectNode(documentNode, inspector);
|
||||
|
||||
openInspector(runTests);
|
||||
}
|
||||
yield Promise.all([breadcrumbsUpdated, nodeSelected]);
|
||||
|
||||
function runTests(aInspector)
|
||||
{
|
||||
inspector = aInspector;
|
||||
target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
panel = gDevTools.getToolbox(target).getPanel("inspector");
|
||||
container = panel.panelDoc.getElementById("inspector-breadcrumbs");
|
||||
cursor = 0;
|
||||
inspector.on("breadcrumbs-updated", nodeSelected);
|
||||
executeSoon(function() {
|
||||
inspector.selection.setNode(nodes[0].node);
|
||||
});
|
||||
}
|
||||
|
||||
function nodeSelected()
|
||||
{
|
||||
performTest();
|
||||
cursor++;
|
||||
|
||||
if (cursor >= nodes.length) {
|
||||
inspector.off("breadcrumbs-updated", nodeSelected);
|
||||
// breadcrumbs-updated is an event that is fired before the rest of the
|
||||
// inspector is updated, so there'll be hanging connections if we finish
|
||||
// up before waiting for everything to end.
|
||||
inspector.once("inspector-updated", finishUp);
|
||||
} else {
|
||||
let node = nodes[cursor].node;
|
||||
inspector.selection.setNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
function performTest()
|
||||
{
|
||||
let buttonsLabelIds = nodes[cursor].result.split(" ");
|
||||
info("Performing checks for node " + node.nodeId);
|
||||
let buttonsLabelIds = node.result.split(" ");
|
||||
|
||||
// html > body > …
|
||||
is(container.childNodes.length, buttonsLabelIds.length + 2, "Node " + cursor + ": Items count");
|
||||
is(container.childNodes.length, buttonsLabelIds.length + 2,
|
||||
"Node " + node.nodeId + ": Items count");
|
||||
|
||||
for (let i = 2; i < container.childNodes.length; i++) {
|
||||
let expectedId = "#" + buttonsLabelIds[i - 2];
|
||||
let button = container.childNodes[i];
|
||||
let labelId = button.querySelector(".breadcrumbs-widget-item-id");
|
||||
is(labelId.textContent, expectedId, "Node " + cursor + ": button " + i + " matches");
|
||||
is(labelId.textContent, expectedId,
|
||||
"Node #" + node.nodeId + ": button " + i + " matches");
|
||||
}
|
||||
|
||||
let checkedButton = container.querySelector("button[checked]");
|
||||
let labelId = checkedButton.querySelector(".breadcrumbs-widget-item-id");
|
||||
let id = inspector.selection.node.id;
|
||||
is(labelId.textContent, "#" + id, "Node " + cursor + ": selection matches");
|
||||
is(labelId.textContent, "#" + id,
|
||||
"Node #" + node.nodeId + ": selection matches");
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
doc = nodes = inspector = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,118 +1,82 @@
|
||||
/* 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";
|
||||
|
||||
function test()
|
||||
{
|
||||
let inspector, searchBox, state;
|
||||
let keypressStates = [3,4,8,18,19,20,21,22];
|
||||
// Test that searching for nodes in the search field actually selects those
|
||||
// nodes.
|
||||
|
||||
// The various states of the inspector: [key, id, isValid]
|
||||
// [
|
||||
// what key to press,
|
||||
// what id should be selected after the keypress,
|
||||
// is the searched text valid selector
|
||||
// ]
|
||||
let keyStates = [
|
||||
["d", "b1", false],
|
||||
["i", "b1", false],
|
||||
["v", "d1", true],
|
||||
["VK_DOWN", "d2", true],
|
||||
["VK_RETURN", "d1", true],
|
||||
[".", "d1", false],
|
||||
["c", "d1", false],
|
||||
["1", "d2", true],
|
||||
["VK_DOWN", "d2", true],
|
||||
["VK_BACK_SPACE", "d2", false],
|
||||
["VK_BACK_SPACE", "d2", false],
|
||||
["VK_BACK_SPACE", "d1", true],
|
||||
["VK_BACK_SPACE", "d1", false],
|
||||
["VK_BACK_SPACE", "d1", false],
|
||||
["VK_BACK_SPACE", "d1", true],
|
||||
[".", "d1", false],
|
||||
["c", "d1", false],
|
||||
["1", "d2", true],
|
||||
["VK_DOWN", "s2", true],
|
||||
["VK_DOWN", "p1", true],
|
||||
["VK_UP", "s2", true],
|
||||
["VK_UP", "d2", true],
|
||||
["VK_UP", "p1", true],
|
||||
["VK_BACK_SPACE", "p1", false],
|
||||
["2", "p3", true],
|
||||
["VK_BACK_SPACE", "p3", false],
|
||||
["VK_BACK_SPACE", "p3", false],
|
||||
["VK_BACK_SPACE", "p3", true],
|
||||
["r", "p3", false],
|
||||
];
|
||||
const TEST_URL = TEST_URL_ROOT + "browser_inspector_bug_650804_search.html";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
// Indexes of the keys in the KEY_STATES array that should listen to "keypress"
|
||||
// event instead of "command". These are keys that don't change the content of
|
||||
// the search field and thus don't trigger command event.
|
||||
const LISTEN_KEYPRESS = [3,4,8,18,19,20,21,22];
|
||||
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/" +
|
||||
"inspector/test/browser_inspector_bug_650804_search.html";
|
||||
// The various states of the inspector: [key, id, isValid]
|
||||
// [
|
||||
// what key to press,
|
||||
// what id should be selected after the keypress,
|
||||
// is the searched text valid selector
|
||||
// ]
|
||||
const KEY_STATES = [
|
||||
["d", "b1", false],
|
||||
["i", "b1", false],
|
||||
["v", "d1", true],
|
||||
["VK_DOWN", "d2", true], // keypress
|
||||
["VK_RETURN", "d1", true], //keypress
|
||||
[".", "d1", false],
|
||||
["c", "d1", false],
|
||||
["1", "d2", true],
|
||||
["VK_DOWN", "d2", true], // keypress
|
||||
["VK_BACK_SPACE", "d2", false],
|
||||
["VK_BACK_SPACE", "d2", false],
|
||||
["VK_BACK_SPACE", "d1", true],
|
||||
["VK_BACK_SPACE", "d1", false],
|
||||
["VK_BACK_SPACE", "d1", false],
|
||||
["VK_BACK_SPACE", "d1", true],
|
||||
[".", "d1", false],
|
||||
["c", "d1", false],
|
||||
["1", "d2", true],
|
||||
["VK_DOWN", "s2", true], // keypress
|
||||
["VK_DOWN", "p1", true], // kepress
|
||||
["VK_UP", "s2", true], // keypress
|
||||
["VK_UP", "d2", true], // keypress
|
||||
["VK_UP", "p1", true],
|
||||
["VK_BACK_SPACE", "p1", false],
|
||||
["2", "p3", true],
|
||||
["VK_BACK_SPACE", "p3", false],
|
||||
["VK_BACK_SPACE", "p3", false],
|
||||
["VK_BACK_SPACE", "p3", true],
|
||||
["r", "p3", false],
|
||||
];
|
||||
|
||||
function $(id) {
|
||||
if (id == null) return null;
|
||||
return content.document.getElementById(id);
|
||||
}
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
let { searchBox } = inspector;
|
||||
|
||||
function setupTest()
|
||||
{
|
||||
openInspector(startTest);
|
||||
}
|
||||
yield selectNode("#b1", inspector);
|
||||
yield focusSearchBoxUsingShortcut(inspector.panelWin);
|
||||
|
||||
function startTest(aInspector)
|
||||
{
|
||||
inspector = aInspector;
|
||||
inspector.selection.setNode($("b1"));
|
||||
let index = 0;
|
||||
for (let [ key, id, isValid ] of KEY_STATES) {
|
||||
let event = (LISTEN_KEYPRESS.indexOf(index) !== -1) ? "keypress" : "command";
|
||||
let eventHandled = once(searchBox, event, true);
|
||||
|
||||
searchBox =
|
||||
inspector.panelWin.document.getElementById("inspector-searchbox");
|
||||
|
||||
focusSearchBoxUsingShortcut(inspector.panelWin, function() {
|
||||
searchBox.addEventListener("command", checkState, true);
|
||||
searchBox.addEventListener("keypress", checkState, true);
|
||||
checkStateAndMoveOn(0);
|
||||
});
|
||||
}
|
||||
|
||||
function checkStateAndMoveOn(index) {
|
||||
if (index == keyStates.length) {
|
||||
finishUp();
|
||||
return;
|
||||
}
|
||||
|
||||
let [key, id, isValid] = keyStates[index];
|
||||
state = index;
|
||||
|
||||
info("pressing key " + key + " to get id " + id);
|
||||
info(index + ": Pressing key " + key + " to get id " + id);
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
}
|
||||
yield eventHandled;
|
||||
|
||||
function checkState(event) {
|
||||
if (event.type == "keypress" && keypressStates.indexOf(state) == -1) {
|
||||
return;
|
||||
}
|
||||
info("Got " + event + " event. Waiting for search query to complete");
|
||||
yield inspector.searchSuggestions._lastQuery;
|
||||
|
||||
inspector.searchSuggestions._lastQuery.then(() => {
|
||||
executeSoon(() => {
|
||||
let [key, id, isValid] = keyStates[state];
|
||||
info(inspector.selection.node.id + " is selected with text " +
|
||||
inspector.searchBox.value);
|
||||
is(inspector.selection.node, $(id),
|
||||
"Correct node is selected for state " + state);
|
||||
is(!searchBox.classList.contains("devtools-no-search-result"), isValid,
|
||||
"Correct searchbox result state for state " + state);
|
||||
checkStateAndMoveOn(state + 1);
|
||||
});
|
||||
});
|
||||
}
|
||||
info(inspector.selection.node.id + " is selected with text " +
|
||||
searchBox.value);
|
||||
is(inspector.selection.node, content.document.getElementById(id),
|
||||
"Correct node is selected for state " + index);
|
||||
is(!searchBox.classList.contains("devtools-no-search-result"), isValid,
|
||||
"Correct searchbox result state for state " + index);
|
||||
|
||||
function finishUp() {
|
||||
searchBox = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
index++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,44 +1,18 @@
|
||||
/* 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";
|
||||
|
||||
function test() {
|
||||
ignoreAllUncaughtExceptions();
|
||||
// A regression test for bug 665880 to make sure elements inside <object> can
|
||||
// be inspected without exceptions.
|
||||
|
||||
let doc;
|
||||
let objectNode;
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"<object><p>browser_inspector_inspect-object-element.js</p></object>";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(setupObjectInspectionTest, content);
|
||||
}, true);
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URI);
|
||||
let objectNode = getNode("object");
|
||||
ok(objectNode, "We have the object node");
|
||||
|
||||
content.location = "data:text/html,<object style='padding: 100px'><p>foobar</p></object>";
|
||||
|
||||
function setupObjectInspectionTest() {
|
||||
objectNode = doc.querySelector("object");
|
||||
ok(objectNode, "we have the object node");
|
||||
openInspector(runObjectInspectionTest);
|
||||
}
|
||||
|
||||
function runObjectInspectionTest(inspector) {
|
||||
inspector.once("inspector-updated", performTestComparison);
|
||||
inspector.selection.setNode(objectNode, "");
|
||||
}
|
||||
|
||||
function performTestComparison() {
|
||||
is(getActiveInspector().selection.node, objectNode, "selection matches node");
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
executeSoon(function() {
|
||||
gDevTools.closeToolbox(target);
|
||||
finishUp();
|
||||
});
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
doc = objectNode = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
yield selectNode(objectNode, inspector);
|
||||
});
|
||||
|
@ -1,92 +1,40 @@
|
||||
/* 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";
|
||||
|
||||
// Tests that the keybindings for highlighting different elements work as
|
||||
// intended.
|
||||
|
||||
function test()
|
||||
{
|
||||
let doc;
|
||||
let node;
|
||||
let inspector;
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"<html><head><title>Test for the highlighter keybindings</title></head>" +
|
||||
"<body><h1>Hello</h1><p><strong>Greetings, earthlings!</strong>" +
|
||||
" I come in peace.</p></body></html>";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
doc = content.document;
|
||||
waitForFocus(setupKeyBindingsTest, content);
|
||||
}, true);
|
||||
const TEST_DATA = [
|
||||
{ key: "VK_RIGHT", selectedNode: "h1" },
|
||||
{ key: "VK_DOWN", selectedNode: "p" },
|
||||
{ key: "VK_UP", selectedNode: "h1" },
|
||||
{ key: "VK_LEFT", selectedNode: "body" },
|
||||
];
|
||||
|
||||
content.location = "data:text/html,<html><head><title>Test for the " +
|
||||
"highlighter keybindings</title></head><body><h1>Hello" +
|
||||
"</h1><p><strong>Greetings, earthlings!</strong> I come" +
|
||||
" in peace.</body></html>";
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URI);
|
||||
is(inspector.selection.node, getNode("body"),
|
||||
"Body should be selected initially.");
|
||||
|
||||
function setupKeyBindingsTest()
|
||||
{
|
||||
openInspector(findAndHighlightNode);
|
||||
info("Focusing the currently active breadcrumb button");
|
||||
let bc = inspector.breadcrumbs;
|
||||
bc.nodeHierarchy[bc.currentIndex].button.focus();
|
||||
|
||||
for (let { key, selectedNode } of TEST_DATA) {
|
||||
info("Pressing " + key + " to select " + selectedNode);
|
||||
|
||||
let updated = inspector.once("inspector-updated");
|
||||
EventUtils.synthesizeKey(key, {});
|
||||
yield updated;
|
||||
|
||||
is(inspector.selection.node, getNode(selectedNode),
|
||||
selectedNode + " is selected.");
|
||||
}
|
||||
|
||||
function findAndHighlightNode(aInspector, aToolbox)
|
||||
{
|
||||
inspector = aInspector;
|
||||
|
||||
// Make sure the body element is selected initially.
|
||||
node = doc.querySelector("body");
|
||||
is(inspector.selection.node, node, "Body should be selected initially.");
|
||||
node = doc.querySelector("h1")
|
||||
inspector.once("inspector-updated", highlightHeaderNode);
|
||||
let bc = inspector.breadcrumbs;
|
||||
bc.nodeHierarchy[bc.currentIndex].button.focus();
|
||||
EventUtils.synthesizeKey("VK_RIGHT", {});
|
||||
}
|
||||
|
||||
function highlightHeaderNode()
|
||||
{
|
||||
is(inspector.selection.node, node, "selected h1 element");
|
||||
|
||||
executeSoon(function() {
|
||||
inspector.once("inspector-updated", highlightParagraphNode);
|
||||
// Test that moving to the next sibling works.
|
||||
node = doc.querySelector("p");
|
||||
EventUtils.synthesizeKey("VK_DOWN", { });
|
||||
});
|
||||
}
|
||||
|
||||
function highlightParagraphNode()
|
||||
{
|
||||
is(inspector.selection.node, node, "selected p element");
|
||||
|
||||
executeSoon(function() {
|
||||
inspector.once("inspector-updated", highlightHeaderNodeAgain);
|
||||
// Test that moving to the previous sibling works.
|
||||
node = doc.querySelector("h1");
|
||||
EventUtils.synthesizeKey("VK_UP", { });
|
||||
});
|
||||
}
|
||||
|
||||
function highlightHeaderNodeAgain()
|
||||
{
|
||||
is(inspector.selection.node, node, "selected h1 element");
|
||||
|
||||
executeSoon(function() {
|
||||
inspector.once("inspector-updated", highlightParentNode);
|
||||
// Test that moving to the parent works.
|
||||
node = doc.querySelector("body");
|
||||
EventUtils.synthesizeKey("VK_LEFT", { });
|
||||
});
|
||||
}
|
||||
|
||||
function highlightParentNode()
|
||||
{
|
||||
is(inspector.selection.node, node, "selected body element");
|
||||
finishUp();
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
doc = node = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,110 +1,70 @@
|
||||
/* 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";
|
||||
|
||||
function test()
|
||||
{
|
||||
let doc;
|
||||
let iframeNode, iframeBodyNode;
|
||||
let inspector;
|
||||
// Test that iframes are correctly highlighted.
|
||||
|
||||
let iframeSrc = "<style>" +
|
||||
"body {" +
|
||||
"margin:0;" +
|
||||
"height:100%;" +
|
||||
"background-color:red" +
|
||||
"}" +
|
||||
"</style>" +
|
||||
"<body></body>";
|
||||
let docSrc = "<style>" +
|
||||
"iframe {" +
|
||||
"height:200px;" +
|
||||
"border: 11px solid black;" +
|
||||
"padding: 13px;" +
|
||||
"}" +
|
||||
"body,iframe {" +
|
||||
"margin:0" +
|
||||
"}" +
|
||||
"</style>" +
|
||||
"<body>" +
|
||||
"<iframe src='data:text/html," + iframeSrc + "'></iframe>" +
|
||||
"</body>";
|
||||
const IFRAME_SRC = "<style>" +
|
||||
"body {" +
|
||||
"margin:0;" +
|
||||
"height:100%;" +
|
||||
"background-color:red" +
|
||||
"}" +
|
||||
"</style><body>hello from iframe</body>";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
doc = content.document;
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
const DOCUMENT_SRC = "<style>" +
|
||||
"iframe {" +
|
||||
"height:200px;" +
|
||||
"border: 11px solid black;" +
|
||||
"padding: 13px;" +
|
||||
"}" +
|
||||
"body,iframe {" +
|
||||
"margin:0" +
|
||||
"}" +
|
||||
"</style>" +
|
||||
"<body>" +
|
||||
"<iframe src='data:text/html," + IFRAME_SRC + "'></iframe>" +
|
||||
"</body>";
|
||||
|
||||
content.location = "data:text/html," + docSrc;
|
||||
const TEST_URI = "data:text/html;charset=utf-8," + DOCUMENT_SRC;
|
||||
|
||||
function setupTest()
|
||||
{
|
||||
iframeNode = doc.querySelector("iframe");
|
||||
iframeBodyNode = iframeNode.contentDocument.querySelector("body");
|
||||
ok(iframeNode, "we have the iframe node");
|
||||
ok(iframeBodyNode, "we have the body node");
|
||||
openInspector(aInspector => {
|
||||
inspector = aInspector;
|
||||
// Make sure the highlighter is shown so we can disable transitions
|
||||
inspector.toolbox.highlighter.showBoxModel(getNodeFront(doc.body)).then(() => {
|
||||
runTests();
|
||||
});
|
||||
});
|
||||
}
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector, toolbox } = yield openInspectorForURL(TEST_URI);
|
||||
let outerDocument = content.document;
|
||||
|
||||
function runTests()
|
||||
{
|
||||
inspector.toolbox.highlighterUtils.startPicker().then(() => {
|
||||
moveMouseOver(iframeNode, 1, 1, isTheIframeHighlighted);
|
||||
});
|
||||
}
|
||||
let iframeNode = getNode("iframe");
|
||||
let iframeBodyNode = getNode("body", { document: iframeNode.contentDocument });
|
||||
|
||||
function isTheIframeHighlighted()
|
||||
{
|
||||
let {p1, p2, p3, p4} = getBoxModelStatus().border.points;
|
||||
let {top, right, bottom, left} = iframeNode.getBoundingClientRect();
|
||||
info("Waiting for box mode to show.");
|
||||
yield toolbox.highlighter.showBoxModel(getNodeFront(outerDocument.body));
|
||||
|
||||
is(top, p1.y, "iframeRect.top === boxModelStatus.p1.y");
|
||||
is(top, p2.y, "iframeRect.top === boxModelStatus.p2.y");
|
||||
is(right, p2.x, "iframeRect.right === boxModelStatus.p2.x");
|
||||
is(right, p3.x, "iframeRect.right === boxModelStatus.p3.x");
|
||||
is(bottom, p3.y, "iframeRect.bottom === boxModelStatus.p3.y");
|
||||
is(bottom, p4.y, "iframeRect.bottom === boxModelStatus.p4.y");
|
||||
is(left, p1.x, "iframeRect.left === boxModelStatus.p1.x");
|
||||
is(left, p4.x, "iframeRect.left === boxModelStatus.p4.x");
|
||||
info("Waiting for element picker to become active.");
|
||||
yield toolbox.highlighterUtils.startPicker();
|
||||
|
||||
iframeNode.style.marginBottom = doc.defaultView.innerHeight + "px";
|
||||
doc.defaultView.scrollBy(0, 40);
|
||||
info("Moving mouse over iframe padding.");
|
||||
yield moveMouseOver(iframeNode, 1, 1);
|
||||
|
||||
moveMouseOver(iframeNode, 40, 40, isTheIframeContentHighlighted);
|
||||
}
|
||||
info("Performing checks");
|
||||
isNodeCorrectlyHighlighted(iframeNode);
|
||||
|
||||
function isTheIframeContentHighlighted()
|
||||
{
|
||||
is(getHighlitNode(), iframeBodyNode, "highlighter shows the right node");
|
||||
info("Scrolling the document");
|
||||
iframeNode.style.marginBottom = outerDocument.defaultView.innerHeight + "px";
|
||||
outerDocument.defaultView.scrollBy(0, 40);
|
||||
|
||||
let outlineRect = getSimpleBorderRect();
|
||||
is(outlineRect.height, 200, "highlighter height");
|
||||
info("Moving mouse over iframe body");
|
||||
yield moveMouseOver(iframeNode, 40, 40);
|
||||
|
||||
inspector.toolbox.highlighterUtils.stopPicker().then(() => {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.closeToolbox(target);
|
||||
finishUp();
|
||||
});
|
||||
}
|
||||
is(getHighlitNode(), iframeBodyNode, "highlighter shows the right node");
|
||||
isNodeCorrectlyHighlighted(iframeBodyNode);
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
doc = inspector = iframeNode = iframeBodyNode = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
info("Waiting for the element picker to deactivate.");
|
||||
yield inspector.toolbox.highlighterUtils.stopPicker();
|
||||
|
||||
function moveMouseOver(aElement, x, y, cb)
|
||||
{
|
||||
inspector.toolbox.once("picker-node-hovered", cb);
|
||||
function moveMouseOver(aElement, x, y) {
|
||||
info("Waiting for element " + aElement + " to be highlighted");
|
||||
EventUtils.synthesizeMouse(aElement, x, y, {type: "mousemove"},
|
||||
aElement.ownerDocument.defaultView);
|
||||
return inspector.toolbox.once("picker-node-hovered");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,77 +1,45 @@
|
||||
/* 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";
|
||||
|
||||
function test() {
|
||||
let iframe;
|
||||
let iframeLoads = 0;
|
||||
let checksAfterLoads = false;
|
||||
let inspector;
|
||||
// Test that the highlighter element picker still works through iframe
|
||||
// navigations.
|
||||
|
||||
function startTest() {
|
||||
openInspector(aInspector => {
|
||||
inspector = aInspector;
|
||||
runInspectorTests();
|
||||
});
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"<p>bug 699308 - test iframe navigation</p>" +
|
||||
"<iframe src='data:text/html;charset=utf-8,hello world'></iframe>";
|
||||
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector, toolbox } = yield openInspectorForURL(TEST_URI);
|
||||
let iframe = getNode("iframe");
|
||||
|
||||
info("Starting element picker.");
|
||||
yield toolbox.highlighterUtils.startPicker();
|
||||
|
||||
info("Waiting for highlighter to activate.");
|
||||
let highlighterShowing = toolbox.once("highlighter-ready");
|
||||
EventUtils.synthesizeMouse(content.document.body, 1, 1,
|
||||
{type: "mousemove"}, content);
|
||||
yield highlighterShowing;
|
||||
|
||||
ok(isHighlighting(), "Inspector is highlighting.");
|
||||
|
||||
yield reloadFrame();
|
||||
info("Frame reloaded. Reloading again.");
|
||||
|
||||
yield reloadFrame();
|
||||
info("Frame reloaded twice.");
|
||||
|
||||
ok(isHighlighting(), "Inspector is highlighting after iframe nav.");
|
||||
|
||||
info("Stopping element picker.");
|
||||
yield toolbox.highlighterUtils.stopPicker();
|
||||
|
||||
function reloadFrame() {
|
||||
info("Reloading frame.");
|
||||
let frameLoaded = once(iframe, "load");
|
||||
iframe.contentWindow.location.reload();
|
||||
return frameLoaded;
|
||||
}
|
||||
|
||||
function showHighlighter(cb) {
|
||||
inspector.toolbox.highlighterUtils.startPicker().then(() => {
|
||||
EventUtils.synthesizeMouse(content.document.body, 1, 1,
|
||||
{type: "mousemove"}, content);
|
||||
inspector.toolbox.once("highlighter-ready", cb);
|
||||
});
|
||||
}
|
||||
|
||||
function runInspectorTests() {
|
||||
iframe = content.document.querySelector("iframe");
|
||||
ok(iframe, "found the iframe element");
|
||||
|
||||
showHighlighter(() => {
|
||||
ok(isHighlighting(), "Inspector is highlighting");
|
||||
|
||||
iframe.addEventListener("load", onIframeLoad, false);
|
||||
executeSoon(() => {
|
||||
iframe.contentWindow.location = "javascript:location.reload()";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onIframeLoad() {
|
||||
if (++iframeLoads != 2) {
|
||||
executeSoon(function() {
|
||||
iframe.contentWindow.location = "javascript:location.reload()";
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
iframe.removeEventListener("load", onIframeLoad, false);
|
||||
info("Finished reloading iframe and inspector updated");
|
||||
|
||||
ok(isHighlighting(), "Inspector is highlighting after iframe nav");
|
||||
|
||||
checksAfterLoads = true;
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
is(iframeLoads, 2, "iframe loads");
|
||||
ok(checksAfterLoads, "the Inspector tests got the chance to run after iframe reloads");
|
||||
|
||||
inspector.toolbox.highlighterUtils.stopPicker().then(() => {
|
||||
iframe = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
executeSoon(finish);
|
||||
});
|
||||
}
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onBrowserLoad() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onBrowserLoad, true);
|
||||
waitForFocus(startTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8," +
|
||||
"<p>bug 699308 - test iframe navigation</p>" +
|
||||
"<iframe src='data:text/html;charset=utf-8,hello world'></iframe>";
|
||||
}
|
||||
});
|
||||
|
@ -1,52 +1,28 @@
|
||||
/* 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";
|
||||
|
||||
function test()
|
||||
{
|
||||
//ignoreAllUncaughtExceptions();
|
||||
// Test to ensure inspector handles deletion of selected node correctly.
|
||||
|
||||
let node, iframe, inspector;
|
||||
const TEST_URL = TEST_URL_ROOT + "browser_inspector_destroyselection.html";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
let iframe = getNode("iframe");
|
||||
let span = getNode("span", { document: iframe.contentDocument });
|
||||
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_destroyselection.html";
|
||||
yield selectNode(span, inspector);
|
||||
|
||||
function setupTest()
|
||||
{
|
||||
iframe = content.document.querySelector("iframe");
|
||||
node = iframe.contentDocument.querySelector("span");
|
||||
openInspector(runTests);
|
||||
}
|
||||
info("Removing selected <span> element.");
|
||||
let parentNode = span.parentNode;
|
||||
span.remove();
|
||||
|
||||
function runTests(aInspector)
|
||||
{
|
||||
inspector = aInspector;
|
||||
inspector.selection.setNode(node);
|
||||
inspector.once("inspector-updated", () => {
|
||||
let parentNode = node.parentNode;
|
||||
parentNode.removeChild(node);
|
||||
|
||||
let tmp = {};
|
||||
Cu.import("resource://gre/modules/devtools/LayoutHelpers.jsm", tmp);
|
||||
let lh = new tmp.LayoutHelpers(window.content);
|
||||
ok(!lh.isNodeConnected(node), "Node considered as disconnected.");
|
||||
|
||||
// Wait for the inspector to process the mutation
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, parentNode, "parent of selection got selected");
|
||||
finishUp();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function finishUp() {
|
||||
node = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
let lh = new LayoutHelpers(window.content);
|
||||
ok(!lh.isNodeConnected(span), "Node considered as disconnected.");
|
||||
|
||||
// Wait for the inspector to process the mutation
|
||||
yield inspector.once("inspector-updated");
|
||||
is(inspector.selection.node, parentNode,
|
||||
"Parent node of selected <span> got selected.");
|
||||
});
|
||||
|
@ -1,111 +1,157 @@
|
||||
/* 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";
|
||||
|
||||
function test()
|
||||
{
|
||||
let inspector, searchBox, state, popup;
|
||||
// Testing that searching for combining selectors using the inspector search
|
||||
// field produces correct suggestions.
|
||||
|
||||
// The various states of the inspector: [key, suggestions array]
|
||||
// [
|
||||
// what key to press,
|
||||
// suggestions array with count [
|
||||
// [suggestion1, count1], [suggestion2] ...
|
||||
// ] count can be left to represent 1
|
||||
// ]
|
||||
let keyStates = [
|
||||
["d", [["div", 4]]],
|
||||
["i", [["div", 4]]],
|
||||
["v", []],
|
||||
[" ", [["div div", 2], ["div span", 2]]],
|
||||
[">", [["div >div", 2], ["div >span", 2]]],
|
||||
["VK_BACK_SPACE", [["div div", 2], ["div span", 2]]],
|
||||
["+", [["div +span"]]],
|
||||
["VK_BACK_SPACE", [["div div", 2], ["div span", 2]]],
|
||||
["VK_BACK_SPACE", []],
|
||||
["VK_BACK_SPACE", [["div", 4]]],
|
||||
["VK_BACK_SPACE", [["div", 4]]],
|
||||
["VK_BACK_SPACE", []],
|
||||
["p", []],
|
||||
[" ", [["p strong"]]],
|
||||
["+", [["p +button"], ["p +p"]]],
|
||||
["b", [["p +button"]]],
|
||||
["u", [["p +button"]]],
|
||||
["t", [["p +button"]]],
|
||||
["t", [["p +button"]]],
|
||||
["o", [["p +button"]]],
|
||||
["n", []],
|
||||
["+", [["p +button+p"]]],
|
||||
];
|
||||
const TEST_URL = TEST_URL_ROOT + "browser_inspector_bug_831693_search_suggestions.html";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_bug_831693_search_suggestions.html";
|
||||
|
||||
function $(id) {
|
||||
if (id == null) return null;
|
||||
return content.document.getElementById(id);
|
||||
}
|
||||
|
||||
function setupTest()
|
||||
// An array of (key, suggestions) pairs where key is a key to press and
|
||||
// suggestions is an array of suggestions that should be shown in the popup.
|
||||
// Suggestion is an object with label of the entry and optional count
|
||||
// (defaults to 1)
|
||||
const TEST_DATA = [
|
||||
{
|
||||
openInspector(startTest);
|
||||
}
|
||||
|
||||
function startTest(aInspector)
|
||||
key: "d",
|
||||
suggestions: [{label: "div", count: 4}]
|
||||
},
|
||||
{
|
||||
inspector = aInspector;
|
||||
|
||||
searchBox =
|
||||
inspector.panelWin.document.getElementById("inspector-searchbox");
|
||||
popup = inspector.searchSuggestions.searchPopup;
|
||||
|
||||
focusSearchBoxUsingShortcut(inspector.panelWin, function() {
|
||||
searchBox.addEventListener("command", checkState, true);
|
||||
checkStateAndMoveOn(0);
|
||||
});
|
||||
key: "i",
|
||||
suggestions: [{label: "div", count: 4}]
|
||||
},
|
||||
{
|
||||
key: "v",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: " ",
|
||||
suggestions: [
|
||||
{label: "div div", count: 2},
|
||||
{label: "div span", count: 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: ">",
|
||||
suggestions: [
|
||||
{label: "div >div", count: 2},
|
||||
{label: "div >span", count: 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [
|
||||
{label: "div div", count: 2 },
|
||||
{label: "div span", count: 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "+",
|
||||
suggestions: [{label: "div +span"}]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [
|
||||
{label: "div div", count: 2 },
|
||||
{label: "div span", count: 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [{label: "div", count: 4}]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [{label: "div", count: 4}]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: "p",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: " ",
|
||||
suggestions: [{label: "p strong"}]
|
||||
},
|
||||
{
|
||||
key: "+",
|
||||
suggestions: [
|
||||
{label: "p +button" },
|
||||
{label: "p +p"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "b",
|
||||
suggestions: [{label: "p +button"}]
|
||||
},
|
||||
{
|
||||
key: "u",
|
||||
suggestions: [{label: "p +button"}]
|
||||
},
|
||||
{
|
||||
key: "t",
|
||||
suggestions: [{label: "p +button"}]
|
||||
},
|
||||
{
|
||||
key: "t",
|
||||
suggestions: [{label: "p +button"}]
|
||||
},
|
||||
{
|
||||
key: "o",
|
||||
suggestions: [{label: "p +button"}]
|
||||
},
|
||||
{
|
||||
key: "n",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: "+",
|
||||
suggestions: [{label: "p +button+p"}]
|
||||
}
|
||||
];
|
||||
|
||||
function checkStateAndMoveOn(index) {
|
||||
if (index == keyStates.length) {
|
||||
finishUp();
|
||||
return;
|
||||
}
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
let searchBox = inspector.searchBox;
|
||||
let popup = inspector.searchSuggestions.searchPopup;
|
||||
|
||||
let [key, suggestions] = keyStates[index];
|
||||
state = index;
|
||||
yield focusSearchBoxUsingShortcut(inspector.panelWin);
|
||||
|
||||
info("pressing key " + key + " to get suggestions " +
|
||||
JSON.stringify(suggestions));
|
||||
for (let { key, suggestions } of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + formatSuggestions(suggestions));
|
||||
|
||||
let command = once(searchBox, "command");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
}
|
||||
yield command;
|
||||
|
||||
function checkState(event) {
|
||||
inspector.searchSuggestions._lastQuery.then(() => {
|
||||
let [key, suggestions] = keyStates[state];
|
||||
let actualSuggestions = popup.getItems();
|
||||
is(popup.isOpen ? actualSuggestions.length: 0, suggestions.length,
|
||||
"There are expected number of suggestions at " + state + "th step.");
|
||||
actualSuggestions = actualSuggestions.reverse();
|
||||
for (let i = 0; i < suggestions.length; i++) {
|
||||
is(suggestions[i][0], actualSuggestions[i].label,
|
||||
"The suggestion at " + i + "th index for " + state +
|
||||
"th step is correct.")
|
||||
is(suggestions[i][1] || 1, actualSuggestions[i].count,
|
||||
"The count for suggestion at " + i + "th index for " + state +
|
||||
"th step is correct.")
|
||||
}
|
||||
checkStateAndMoveOn(state + 1);
|
||||
});
|
||||
}
|
||||
info("Waiting for search query to complete");
|
||||
yield inspector.searchSuggestions._lastQuery;
|
||||
|
||||
function finishUp() {
|
||||
searchBox = null;
|
||||
popup = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
info("Query completed. Performing checks for input '" + searchBox.value + "'");
|
||||
let actualSuggestions = popup.getItems().reverse();
|
||||
|
||||
is(popup.isOpen ? actualSuggestions.length: 0, suggestions.length,
|
||||
"There are expected number of suggestions.");
|
||||
|
||||
for (let i = 0; i < suggestions.length; i++) {
|
||||
is(suggestions[i].label, actualSuggestions[i].label,
|
||||
"The suggestion at " + i + "th index is correct.");
|
||||
is(suggestions[i].count || 1, actualSuggestions[i].count,
|
||||
"The count for suggestion at " + i + "th index is correct.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function formatSuggestions(suggestions) {
|
||||
return "[" + suggestions
|
||||
.map(s => "'" + s.label + "' (" + s.count || 1 + ")")
|
||||
.join(", ") + "]";
|
||||
}
|
||||
|
@ -1,112 +1,194 @@
|
||||
/* 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";
|
||||
|
||||
function test()
|
||||
{
|
||||
let inspector, searchBox, state, popup;
|
||||
// Testing that searching for elements using the inspector search field
|
||||
// produces correct suggestions.
|
||||
|
||||
// The various states of the inspector: [key, suggestions array]
|
||||
// [
|
||||
// what key to press,
|
||||
// suggestions array with count [
|
||||
// [suggestion1, count1], [suggestion2] ...
|
||||
// ] count can be left to represent 1
|
||||
// ]
|
||||
let keyStates = [
|
||||
["d", [["div", 2]]],
|
||||
["i", [["div", 2]]],
|
||||
["v", []],
|
||||
[".", [["div.c1"]]],
|
||||
["VK_BACK_SPACE", []],
|
||||
["#", [["div#d1"], ["div#d2"]]],
|
||||
["VK_BACK_SPACE", []],
|
||||
["VK_BACK_SPACE", [["div", 2]]],
|
||||
["VK_BACK_SPACE", [["div", 2]]],
|
||||
["VK_BACK_SPACE", []],
|
||||
[".", [[".c1", 3], [".c2"]]],
|
||||
["c", [[".c1", 3], [".c2"]]],
|
||||
["2", []],
|
||||
["VK_BACK_SPACE", [[".c1", 3], [".c2"]]],
|
||||
["1", []],
|
||||
["#", [["#d2"], ["#p1"], ["#s2"]]],
|
||||
["VK_BACK_SPACE", []],
|
||||
["VK_BACK_SPACE", [[".c1", 3], [".c2"]]],
|
||||
["VK_BACK_SPACE", [[".c1", 3], [".c2"]]],
|
||||
["VK_BACK_SPACE", []],
|
||||
["#", [["#b1"], ["#d1"], ["#d2"], ["#p1"], ["#p2"], ["#p3"], ["#s1"], ["#s2"]]],
|
||||
["p", [["#p1"], ["#p2"], ["#p3"]]],
|
||||
["VK_BACK_SPACE", [["#b1"], ["#d1"], ["#d2"], ["#p1"], ["#p2"], ["#p3"], ["#s1"], ["#s2"]]],
|
||||
["VK_BACK_SPACE", []],
|
||||
];
|
||||
const TEST_URL = TEST_URL_ROOT + "browser_inspector_bug_650804_search.html";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_bug_650804_search.html";
|
||||
|
||||
function $(id) {
|
||||
if (id == null) return null;
|
||||
return content.document.getElementById(id);
|
||||
}
|
||||
|
||||
function setupTest()
|
||||
// An array of (key, suggestions) pairs where key is a key to press and
|
||||
// suggestions is an array of suggestions that should be shown in the popup.
|
||||
// Suggestion is an object with label of the entry and optional count
|
||||
// (defaults to 1)
|
||||
let TEST_DATA = [
|
||||
{
|
||||
openInspector(startTest);
|
||||
}
|
||||
|
||||
function startTest(aInspector)
|
||||
key: "d",
|
||||
suggestions: [{label: "div", count: 2}]
|
||||
},
|
||||
{
|
||||
inspector = aInspector;
|
||||
searchBox =
|
||||
inspector.panelWin.document.getElementById("inspector-searchbox");
|
||||
popup = inspector.searchSuggestions.searchPopup;
|
||||
|
||||
focusSearchBoxUsingShortcut(inspector.panelWin, function() {
|
||||
searchBox.addEventListener("command", checkState, true);
|
||||
checkStateAndMoveOn(0);
|
||||
});
|
||||
key: "i",
|
||||
suggestions: [{label: "div", count: 2}]
|
||||
},
|
||||
{
|
||||
key: "v",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: ".",
|
||||
suggestions: [{label: "div.c1"}]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: "#",
|
||||
suggestions: [
|
||||
{label: "div#d1"},
|
||||
{label: "div#d2"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [{label: "div", count: 2}]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [{label: "div", count: 2}]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: ".",
|
||||
suggestions: [
|
||||
{label: ".c1", count: 3},
|
||||
{label: ".c2"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "c",
|
||||
suggestions: [
|
||||
{label: ".c1", count: 3},
|
||||
{label: ".c2"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "2",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [
|
||||
{label: ".c1", count: 3},
|
||||
{label: ".c2"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "1",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: "#",
|
||||
suggestions: [
|
||||
{label: "#d2"},
|
||||
{label: "#p1"},
|
||||
{label: "#s2"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [
|
||||
{label: ".c1", count: 3},
|
||||
{label: ".c2"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [
|
||||
{label: ".c1", count: 3},
|
||||
{label: ".c2"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
},
|
||||
{
|
||||
key: "#",
|
||||
suggestions: [
|
||||
{label: "#b1"},
|
||||
{label: "#d1"},
|
||||
{label: "#d2"},
|
||||
{label: "#p1"},
|
||||
{label: "#p2"},
|
||||
{label: "#p3"},
|
||||
{label: "#s1"},
|
||||
{label: "#s2"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "p",
|
||||
suggestions: [
|
||||
{label: "#p1"},
|
||||
{label: "#p2"},
|
||||
{label: "#p3"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: [
|
||||
{label: "#b1"},
|
||||
{label: "#d1"},
|
||||
{label: "#d2"},
|
||||
{label: "#p1"},
|
||||
{label: "#p2"},
|
||||
{label: "#p3"},
|
||||
{label: "#s1"},
|
||||
{label: "#s2"}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: "VK_BACK_SPACE",
|
||||
suggestions: []
|
||||
}
|
||||
];
|
||||
|
||||
function checkStateAndMoveOn(index) {
|
||||
if (index == keyStates.length) {
|
||||
finishUp();
|
||||
return;
|
||||
}
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
let searchBox = inspector.searchBox;
|
||||
let popup = inspector.searchSuggestions.searchPopup;
|
||||
|
||||
let [key, suggestions] = keyStates[index];
|
||||
state = index;
|
||||
yield focusSearchBoxUsingShortcut(inspector.panelWin);
|
||||
|
||||
info("pressing key " + key + " to get suggestions " +
|
||||
JSON.stringify(suggestions));
|
||||
for (let { key, suggestions } of TEST_DATA) {
|
||||
info("Pressing " + key + " to get " + formatSuggestions(suggestions));
|
||||
|
||||
let command = once(searchBox, "command");
|
||||
EventUtils.synthesizeKey(key, {}, inspector.panelWin);
|
||||
}
|
||||
yield command;
|
||||
|
||||
function checkState(event) {
|
||||
inspector.searchSuggestions._lastQuery.then(() => {
|
||||
let [key, suggestions] = keyStates[state];
|
||||
let actualSuggestions = popup.getItems();
|
||||
is(popup.isOpen ? actualSuggestions.length: 0, suggestions.length,
|
||||
"There are expected number of suggestions at " + state + "th step.");
|
||||
actualSuggestions = actualSuggestions.reverse();
|
||||
for (let i = 0; i < suggestions.length; i++) {
|
||||
is(suggestions[i][0], actualSuggestions[i].label,
|
||||
"The suggestion at " + i + "th index for " + state +
|
||||
"th step is correct.")
|
||||
is(suggestions[i][1] || 1, actualSuggestions[i].count,
|
||||
"The count for suggestion at " + i + "th index for " + state +
|
||||
"th step is correct.")
|
||||
}
|
||||
checkStateAndMoveOn(state + 1);
|
||||
});
|
||||
}
|
||||
info("Waiting for search query to complete");
|
||||
yield inspector.searchSuggestions._lastQuery;
|
||||
|
||||
function finishUp() {
|
||||
searchBox = null;
|
||||
popup = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
info("Query completed. Performing checks for input '" + searchBox.value + "'");
|
||||
let actualSuggestions = popup.getItems().reverse();
|
||||
|
||||
is(popup.isOpen ? actualSuggestions.length: 0, suggestions.length,
|
||||
"There are expected number of suggestions.");
|
||||
|
||||
for (let i = 0; i < suggestions.length; i++) {
|
||||
is(suggestions[i].label, actualSuggestions[i].label,
|
||||
"The suggestion at " + i + "th index is correct.");
|
||||
is(suggestions[i].count || 1, actualSuggestions[i].count,
|
||||
"The count for suggestion at " + i + "th index is correct.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function formatSuggestions(suggestions) {
|
||||
return "[" + suggestions
|
||||
.map(s => "'" + s.label + "' (" + s.count || 1 + ")")
|
||||
.join(", ") + "]";
|
||||
}
|
||||
|
@ -1,59 +1,29 @@
|
||||
/* 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/ */
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
let Toolbox = devtools.Toolbox;
|
||||
let TargetFactory = devtools.TargetFactory;
|
||||
// Testing that closing the inspector after navigating to a page doesn't fail.
|
||||
|
||||
function test() {
|
||||
const URL_1 = "data:text/plain;charset=UTF-8,abcde";
|
||||
const URL_2 = "data:text/plain;charset=UTF-8,12345";
|
||||
const URL_1 = "data:text/plain;charset=UTF-8,abcde";
|
||||
const URL_2 = "data:text/plain;charset=UTF-8,12345";
|
||||
|
||||
let target, toolbox;
|
||||
let test = asyncTest(function* () {
|
||||
let { toolbox } = yield openInspectorForURL(URL_1);
|
||||
|
||||
// open tab, load URL_1, and wait for load to finish
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let deferred = promise.defer();
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
function onTabLoad() {
|
||||
browser.removeEventListener("load", onTabLoad, true);
|
||||
deferred.resolve(null);
|
||||
info("Navigating to different URL.");
|
||||
let navigated = toolbox.target.once("navigate");
|
||||
content.location = URL_2;
|
||||
|
||||
info("Waiting for 'navigate' event from toolbox target.");
|
||||
yield navigated;
|
||||
|
||||
info("Destroying toolbox");
|
||||
try {
|
||||
yield toolbox.destroy();
|
||||
ok(true, "Toolbox destroyed");
|
||||
} catch (e) {
|
||||
ok(false, "An exception occured while destroying toolbox");
|
||||
console.error(e);
|
||||
}
|
||||
browser.addEventListener("load", onTabLoad, true);
|
||||
browser.loadURI(URL_1);
|
||||
|
||||
// open devtools panel
|
||||
deferred.promise
|
||||
.then(function () gDevTools.showToolbox(target, null, Toolbox.HostType.BOTTOM))
|
||||
.then(function (aToolbox) { toolbox = aToolbox; })
|
||||
|
||||
// select the inspector
|
||||
.then(function () toolbox.selectTool("inspector"))
|
||||
|
||||
// wait until inspector ready
|
||||
.then(function () {
|
||||
let deferred = promise.defer();
|
||||
toolbox.getPanel("inspector").once("inspector-updated", deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
|
||||
// navigate to URL_2
|
||||
.then(function () {
|
||||
let deferred = promise.defer();
|
||||
target.once("navigate", function () deferred.resolve());
|
||||
browser.loadURI(URL_2);
|
||||
return deferred.promise;
|
||||
})
|
||||
|
||||
// destroy the toolbox (and hence the inspector) before the load completes
|
||||
.then(function () toolbox.destroy())
|
||||
|
||||
// this (or any other) exception should not occur:
|
||||
// [JavaScript Error: "TypeError: self.selection is null" {file: "resource:///modules/devtools/InspectorPanel.jsm" line: 250}]
|
||||
|
||||
.then(function cleanUp() {
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -3,139 +3,94 @@
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
// Test that when nodes are being deleted in the page, the current selection
|
||||
// and therefore the markup view, css rule view, computed view, font view,
|
||||
// box model view, and breadcrumbs, reset accordingly to show the right node
|
||||
|
||||
const TEST_PAGE = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_bug_848731_reset_selection_on_delete.html";
|
||||
const TEST_PAGE = TEST_URL_ROOT +
|
||||
"browser_inspector_bug_848731_reset_selection_on_delete.html";
|
||||
|
||||
function test() {
|
||||
let inspector, toolbox;
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_PAGE);
|
||||
|
||||
// Create a tab, load test HTML, wait for load and start the tests
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(function() {
|
||||
openInspector((aInspector, aToolbox) => {
|
||||
inspector = aInspector;
|
||||
toolbox = aToolbox;
|
||||
startTests();
|
||||
});
|
||||
}, content);
|
||||
}, true);
|
||||
content.location = TEST_PAGE;
|
||||
yield testManuallyDeleteSelectedNode();
|
||||
yield testAutomaticallyDeleteSelectedNode();
|
||||
yield testDeleteSelectedNodeContainerFrame();
|
||||
|
||||
function startTests() {
|
||||
testManuallyDeleteSelectedNode();
|
||||
function* testManuallyDeleteSelectedNode() {
|
||||
info("Selecting a node, deleting it via context menu and checking that " +
|
||||
"its parent node is selected and breadcrumbs are updated.");
|
||||
|
||||
let div = getNode("#deleteManually");
|
||||
yield selectNode(div, inspector);
|
||||
|
||||
info("Getting the node container in the markup view.");
|
||||
let container = getContainerForRawNode(inspector.markup, div);
|
||||
|
||||
info("Simulating right-click on the markup view container.");
|
||||
EventUtils.synthesizeMouse(container.tagLine, 2, 2,
|
||||
{type: "contextmenu", button: 2}, inspector.panelWin);
|
||||
|
||||
info("Waiting for the context menu to open.");
|
||||
yield once(inspector.panelDoc.getElementById("inspectorPopupSet"), "popupshown");
|
||||
|
||||
info("Clicking 'Delete Node' in the context menu.");
|
||||
inspector.panelDoc.getElementById("node-menu-delete").click();
|
||||
|
||||
info("Waiting for inspector to update.");
|
||||
yield inspector.once("inspector-updated");
|
||||
|
||||
info("Inspector updated, performing checks.");
|
||||
let parent = getNode("#deleteChildren");
|
||||
assertNodeSelectedAndPanelsUpdated(parent, "ul#deleteChildren");
|
||||
}
|
||||
|
||||
function getContainerForRawNode(rawNode) {
|
||||
let front = inspector.markup.walker.frontForRawNode(rawNode);
|
||||
let container = inspector.markup.getContainer(front);
|
||||
return container;
|
||||
function* testAutomaticallyDeleteSelectedNode() {
|
||||
info("Selecting a node, deleting it via javascript and checking that " +
|
||||
"its parent node is selected and breadcrumbs are updated.");
|
||||
|
||||
let div = getNode("#deleteAutomatically");
|
||||
yield selectNode(div, inspector);
|
||||
|
||||
info("Deleting selected node via javascript.");
|
||||
div.remove();
|
||||
|
||||
info("Waiting for inspector to update.");
|
||||
yield inspector.once("inspector-updated");
|
||||
|
||||
info("Inspector updated, performing checks.");
|
||||
let parent = getNode("#deleteChildren");
|
||||
assertNodeSelectedAndPanelsUpdated(parent, "ul#deleteChildren");
|
||||
}
|
||||
|
||||
// 1 - select a node, right click, hit delete, verify that its parent is selected
|
||||
// and that all other tools are fine
|
||||
function testManuallyDeleteSelectedNode() {
|
||||
info("Deleting a node via the devtools contextual menu");
|
||||
function* testDeleteSelectedNodeContainerFrame() {
|
||||
info("Selecting a node inside iframe, deleting the iframe via javascript " +
|
||||
"and checking the parent node of the iframe is selected and " +
|
||||
"breadcrumbs are updated.");
|
||||
|
||||
// Select our div
|
||||
let div = content.document.getElementById("deleteManually");
|
||||
inspector.selection.setNode(div);
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, div, "Test node is selected");
|
||||
|
||||
// Get the node container in the markup view
|
||||
let container = getContainerForRawNode(div);
|
||||
|
||||
// Simulate right-click
|
||||
EventUtils.synthesizeMouse(container.tagLine, 2, 2,
|
||||
{type: "contextmenu", button: 2}, inspector.panelWin);
|
||||
|
||||
// And react to the popup shown event
|
||||
let contextMenu = inspector.panelDoc.getElementById("inspectorPopupSet");
|
||||
contextMenu.addEventListener("popupshown", function contextShown() {
|
||||
contextMenu.removeEventListener("popupshown", contextShown, false);
|
||||
|
||||
// Click on the delete sub-menu item
|
||||
inspector.panelDoc.getElementById("node-menu-delete").click();
|
||||
|
||||
// Once updated, make sure eveything is in place, and move on
|
||||
inspector.once("inspector-updated", () => {
|
||||
let parent = content.document.getElementById("deleteChildren");
|
||||
assertNodeSelectedAndPanelsUpdated(parent, "ul#deleteChildren");
|
||||
testAutomaticallyDeleteSelectedNode();
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}
|
||||
|
||||
// 2 - select a node, delete it via javascript, verify the same things as 1
|
||||
function testAutomaticallyDeleteSelectedNode() {
|
||||
info("Deleting a node via javascript");
|
||||
|
||||
// Select our second div
|
||||
let div = content.document.getElementById("deleteAutomatically");
|
||||
inspector.selection.setNode(div);
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, div, "Test node is selected");
|
||||
|
||||
// Now remove that div via javascript
|
||||
let parent = content.document.getElementById("deleteChildren");
|
||||
parent.removeChild(div);
|
||||
|
||||
// Once updated, make sure eveything is in place, and move on
|
||||
inspector.once("inspector-updated", () => {
|
||||
assertNodeSelectedAndPanelsUpdated(parent, "ul#deleteChildren");
|
||||
testDeleteSelectedNodeContainerFrame();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 3 - select a node inside an iframe, delete the iframe via javascript, verify that the default node is selected
|
||||
// and that all other tools are fine
|
||||
function testDeleteSelectedNodeContainerFrame() {
|
||||
info("Deleting an iframe via javascript");
|
||||
|
||||
// Select our third test element, inside the iframe
|
||||
let iframe = content.document.getElementById("deleteIframe");
|
||||
info("Selecting an element inside iframe.");
|
||||
let iframe = getNode("#deleteIframe");
|
||||
let div = iframe.contentDocument.getElementById("deleteInIframe");
|
||||
inspector.selection.setNode(div);
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, div, "Test node is selected");
|
||||
yield selectNode(div, inspector);
|
||||
|
||||
// Now remove that parent iframe via javascript
|
||||
let parent = content.document.body;
|
||||
parent.removeChild(iframe);
|
||||
info("Deleting selected node via javascript.");
|
||||
iframe.remove();
|
||||
|
||||
// Once updated, make sure eveything is in place, and move on
|
||||
inspector.once("inspector-updated", () => {
|
||||
assertNodeSelectedAndPanelsUpdated(parent, "body");
|
||||
endTests();
|
||||
});
|
||||
});
|
||||
}
|
||||
info("Waiting for inspector to update.");
|
||||
yield inspector.once("inspector-updated");
|
||||
|
||||
function endTests() {
|
||||
executeSoon(() => {
|
||||
toolbox.destroy();
|
||||
toolbox = inspector = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
info("Inspector updated, performing checks.");
|
||||
assertNodeSelectedAndPanelsUpdated(getNode("body"), "body");
|
||||
}
|
||||
|
||||
function assertNodeSelectedAndPanelsUpdated(node, crumbLabel) {
|
||||
// Right node selected?
|
||||
is(inspector.selection.nodeFront, getNodeFront(node),
|
||||
"The right node is selected");
|
||||
|
||||
// breadcrumbs updated?
|
||||
let breadcrumbs = inspector.panelDoc.getElementById("inspector-breadcrumbs");
|
||||
is(breadcrumbs.querySelector("button[checked=true]").textContent, crumbLabel,
|
||||
"The right breadcrumb is selected");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,77 +1,41 @@
|
||||
/* 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";
|
||||
|
||||
let Toolbox = devtools.Toolbox;
|
||||
let TargetFactory = devtools.TargetFactory;
|
||||
// Test that markup view handles page navigation correctly.
|
||||
|
||||
function test() {
|
||||
const URL_1 = "data:text/html;charset=UTF-8,<div id='one' style='color:red;'>ONE</div>";
|
||||
const URL_2 = "data:text/html;charset=UTF-8,<div id='two' style='color:green;'>TWO</div>";
|
||||
const SCHEMA = "data:text/html;charset=UTF-8,";
|
||||
const URL_1 = SCHEMA + "<div id='one' style='color:red;'>ONE</div>";
|
||||
const URL_2 = SCHEMA + "<div id='two' style='color:green;'>TWO</div>";
|
||||
|
||||
let toolbox, inspector;
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector, toolbox } = yield openInspectorForURL(URL_1);
|
||||
|
||||
// open tab, load URL_1, and wait for load to finish
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let deferred = promise.defer();
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
let firstNode = getNode("#one");
|
||||
|
||||
function onTabLoad() {
|
||||
browser.removeEventListener("load", onTabLoad, true);
|
||||
deferred.resolve(null);
|
||||
}
|
||||
browser.addEventListener("load", onTabLoad, true);
|
||||
browser.loadURI(URL_1);
|
||||
assertMarkupViewIsLoaded();
|
||||
yield selectNode(firstNode, inspector);
|
||||
|
||||
// open devtools panel
|
||||
deferred.promise.then(() => {
|
||||
return gDevTools.showToolbox(target, null, Toolbox.HostType.BOTTOM);
|
||||
}).then(aToolbox => {
|
||||
toolbox = aToolbox;
|
||||
}).then(() => {
|
||||
// select the inspector
|
||||
return toolbox.selectTool("inspector").then(i => {
|
||||
inspector = i;
|
||||
// Verify we are on page one
|
||||
let testNode = content.document.querySelector("#one");
|
||||
ok(testNode, "We have the test node on page 1");
|
||||
let willNavigate = toolbox.target.once("will-navigate");
|
||||
content.location = URL_2;
|
||||
|
||||
assertMarkupViewIsLoaded();
|
||||
});
|
||||
}).then(() => {
|
||||
// navigate to URL_2
|
||||
let deferred = promise.defer();
|
||||
info("Waiting for will-navigate");
|
||||
yield willNavigate;
|
||||
|
||||
// Listen to will-navigate to check if the view is empty
|
||||
target.on("will-navigate", () => {
|
||||
info("Navigation to page 2 has started, the inspector should be empty");
|
||||
assertMarkupViewIsEmpty();
|
||||
});
|
||||
inspector.once("new-root", () => {
|
||||
info("Navigation to page 2 was done, the inspector should be back up");
|
||||
info("Navigation to page 2 has started, the inspector should be empty");
|
||||
assertMarkupViewIsEmpty();
|
||||
|
||||
// Verify we are on page one
|
||||
let testNode = content.document.querySelector("#two");
|
||||
ok(testNode, "We have the test node on page 2");
|
||||
info("Waiting for new-root");
|
||||
yield inspector.once("new-root");
|
||||
|
||||
// On page 2 load, verify we have the right content
|
||||
assertMarkupViewIsLoaded();
|
||||
info("Checking that the page has node #two.");
|
||||
let secondNode = getNode("#two");
|
||||
|
||||
inspector.selection.setNode(content.document.querySelector("#two"));
|
||||
inspector.once("inspector-updated", () => {
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
info("Navigation to page 2 was done, the inspector should be back up");
|
||||
assertMarkupViewIsLoaded();
|
||||
|
||||
inspector.selection.setNode(content.document.querySelector("#one"));
|
||||
inspector.once("inspector-updated", () => {
|
||||
browser.loadURI(URL_2);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}).then(() => {
|
||||
endTests();
|
||||
});
|
||||
yield selectNode(secondNode, inspector);
|
||||
|
||||
function assertMarkupViewIsLoaded() {
|
||||
let markupViewBox = inspector.panelDoc.getElementById("markup-box");
|
||||
@ -82,10 +46,4 @@ function test() {
|
||||
let markupViewBox = inspector.panelDoc.getElementById("markup-box");
|
||||
is(markupViewBox.childNodes.length, 0, "The markup-view is unloaded");
|
||||
}
|
||||
|
||||
function endTests() {
|
||||
target = browser = tab = inspector = TargetFactory = Toolbox = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,55 +1,39 @@
|
||||
/* 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";
|
||||
|
||||
let doc;
|
||||
let toolbox;
|
||||
// Testing that clicking the pick button switches the toolbox to the inspector
|
||||
// panel.
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
doc = content.document;
|
||||
waitForFocus(startTests, content);
|
||||
}, true);
|
||||
const TEST_URI = "data:text/html;charset=UTF-8," +
|
||||
"<p>Switch to inspector on pick</p>";
|
||||
|
||||
content.location = "data:text/html,<p>Switch to inspector on pick</p>";
|
||||
let test = asyncTest(function* () {
|
||||
let tab = yield addTab(TEST_URI);
|
||||
let toolbox = yield openToolbox(tab);
|
||||
|
||||
yield startPickerAndAssertSwitchToInspector(toolbox);
|
||||
|
||||
info("Stoppping element picker.");
|
||||
yield toolbox.highlighterUtils.stopPicker();
|
||||
});
|
||||
|
||||
function openToolbox(tab) {
|
||||
info("Opening webconsole.");
|
||||
let target = TargetFactory.forTab(tab);
|
||||
return gDevTools.showToolbox(target, "webconsole");
|
||||
}
|
||||
|
||||
function startTests() {
|
||||
Task.spawn(function() {
|
||||
yield openToolbox();
|
||||
yield startPickerAndAssertSwitchToInspector();
|
||||
yield toolbox.highlighterUtils.stopPicker();
|
||||
|
||||
finishTests();
|
||||
}).then(null, Cu.reportError);
|
||||
}
|
||||
|
||||
function openToolbox() {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
return gDevTools.showToolbox(target, "webconsole").then(aToolbox => {
|
||||
toolbox = aToolbox;
|
||||
});
|
||||
}
|
||||
|
||||
function startPickerAndAssertSwitchToInspector() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
function* startPickerAndAssertSwitchToInspector(toolbox) {
|
||||
info("Clicking element picker button.");
|
||||
let pickButton = toolbox.doc.querySelector("#command-button-pick");
|
||||
pickButton.click();
|
||||
toolbox.once("inspector-selected", () => {
|
||||
is(toolbox.currentToolId, "inspector", "Switched to the inspector");
|
||||
toolbox.getCurrentPanel().once("inspector-updated", deferred.resolve);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
info("Waiting for inspector to be selected.");
|
||||
yield toolbox.once("inspector-selected");
|
||||
is(toolbox.currentToolId, "inspector", "Switched to the inspector");
|
||||
|
||||
function finishTests() {
|
||||
doc = toolbox = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
info("Waiting for inspector to update.");
|
||||
yield toolbox.getCurrentPanel().once("inspector-updated");
|
||||
}
|
||||
|
@ -3,113 +3,77 @@
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
// Test that hovering over the markup-view's containers doesn't always show the
|
||||
// highlighter, depending on the type of node hovered over.
|
||||
|
||||
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
const TEST_PAGE = TEST_URL_ROOT +
|
||||
"browser_inspector_bug_958456_highlight_comments.html";
|
||||
|
||||
const TEST_PAGE = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_bug_958456_highlight_comments.html";
|
||||
let inspector, markupView, doc;
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_PAGE);
|
||||
let markupView = inspector.markup;
|
||||
yield selectNode("p", inspector);
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
doc = content.document;
|
||||
info("Hovering over #id1 and waiting for highlighter to appear.");
|
||||
yield hoverElement("#id1");
|
||||
assertHighlighterShownOn("#id1");
|
||||
|
||||
waitForFocus(function() {
|
||||
openInspector((aInspector, aToolbox) => {
|
||||
inspector = aInspector;
|
||||
markupView = inspector.markup;
|
||||
startTests();
|
||||
});
|
||||
}, content);
|
||||
}, true);
|
||||
content.location = TEST_PAGE;
|
||||
}
|
||||
info("Hovering over comment node and ensuring highlighter doesn't appear.");
|
||||
yield hoverComment();
|
||||
assertHighlighterHidden();
|
||||
|
||||
function startTests() {
|
||||
Task.spawn(function() {
|
||||
yield prepareHighlighter();
|
||||
info("Hovering over #id1 again and waiting for highlighter to appear.");
|
||||
yield hoverElement("#id1");
|
||||
assertHighlighterShownOn("#id1");
|
||||
|
||||
// Highlighter should be shown on this element
|
||||
yield hoverElement("#id1");
|
||||
assertHighlighterShownOn("#id1");
|
||||
info("Hovering over #id2 and waiting for highlighter to appear.");
|
||||
yield hoverElement("#id2");
|
||||
assertHighlighterShownOn("#id2");
|
||||
|
||||
// But not over a comment
|
||||
yield hoverComment();
|
||||
assertHighlighterHidden();
|
||||
info("Hovering over <script> and ensuring highlighter doesn't appear.");
|
||||
yield hoverElement("script");
|
||||
assertHighlighterHidden();
|
||||
|
||||
// It should be shown again when coming back to the same element tough
|
||||
yield hoverElement("#id1");
|
||||
assertHighlighterShownOn("#id1");
|
||||
info("Hovering over #id3 and waiting for highlighter to appear.");
|
||||
yield hoverElement("#id3");
|
||||
assertHighlighterShownOn("#id3");
|
||||
|
||||
// Shown here too
|
||||
yield hoverElement("#id2");
|
||||
assertHighlighterShownOn("#id2");
|
||||
info("Hovering over hidden #id4 and ensuring highlighter doesn't appear.");
|
||||
yield hoverElement("#id4");
|
||||
assertHighlighterHidden();
|
||||
|
||||
// But not over a script tag
|
||||
yield hoverElement("script");
|
||||
assertHighlighterHidden();
|
||||
function hoverContainer(container) {
|
||||
let promise = inspector.toolbox.once("node-highlight");
|
||||
EventUtils.synthesizeMouse(container.tagLine, 2, 2, {type: "mousemove"},
|
||||
markupView.doc.defaultView);
|
||||
|
||||
// Shown here
|
||||
yield hoverElement("#id3");
|
||||
assertHighlighterShownOn("#id3");
|
||||
return promise;
|
||||
}
|
||||
|
||||
// But not over a hidden element
|
||||
yield hoverElement("#id4");
|
||||
assertHighlighterHidden();
|
||||
}).then(null, Cu.reportError).then(finishTest);
|
||||
}
|
||||
function hoverElement(selector) {
|
||||
info("Hovering node " + selector + " in the markup view");
|
||||
let container = getContainerForRawNode(markupView, getNode(selector));
|
||||
return hoverContainer(container);
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
doc = inspector = markupView = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function prepareHighlighter() {
|
||||
// Make sure the highlighter doesn't have transitions enabled
|
||||
let deferred = promise.defer();
|
||||
inspector.selection.setNode(doc.querySelector("p"), null);
|
||||
inspector.once("inspector-updated", () => {
|
||||
deferred.resolve();
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function hoverContainer(container) {
|
||||
let deferred = promise.defer();
|
||||
EventUtils.synthesizeMouse(container.tagLine, 2, 2, {type: "mousemove"},
|
||||
markupView.doc.defaultView);
|
||||
inspector.toolbox.once("node-highlight", deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function hoverElement(selector) {
|
||||
info("Hovering node " + selector + " in the markup view");
|
||||
let container = getContainerForRawNode(markupView, doc.querySelector(selector));
|
||||
return hoverContainer(container);
|
||||
}
|
||||
|
||||
function hoverComment() {
|
||||
info("Hovering the comment node in the markup view");
|
||||
for (let [node, container] of markupView._containers) {
|
||||
if (node.nodeType === Ci.nsIDOMNode.COMMENT_NODE) {
|
||||
return hoverContainer(container);
|
||||
function hoverComment() {
|
||||
info("Hovering the comment node in the markup view");
|
||||
for (let [node, container] of markupView._containers) {
|
||||
if (node.nodeType === Ci.nsIDOMNode.COMMENT_NODE) {
|
||||
return hoverContainer(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assertHighlighterShownOn(selector) {
|
||||
let node = doc.querySelector(selector);
|
||||
let highlightNode = getHighlitNode();
|
||||
is(node, highlightNode, "Highlighter is shown on the right node: " + selector);
|
||||
}
|
||||
function assertHighlighterShownOn(selector) {
|
||||
let node = getNode(selector);
|
||||
let highlightNode = getHighlitNode();
|
||||
is(node, highlightNode, "Highlighter is shown on the right node: " + selector);
|
||||
}
|
||||
|
||||
function assertHighlighterHidden() {
|
||||
ok(!isHighlighting(), "Highlighter is hidden");
|
||||
}
|
||||
function assertHighlighterHidden() {
|
||||
ok(!isHighlighting(), "Highlighter is hidden");
|
||||
}
|
||||
});
|
||||
|
@ -1,38 +1,27 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
// Test that the highlighter's picker should be stopped when a different tool is
|
||||
// Test that the highlighter's picker is stopped when a different tool is
|
||||
// selected
|
||||
|
||||
function test() {
|
||||
let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
const TEST_URI = "data:text/html;charset=UTF-8," +
|
||||
"testing the highlighter goes away on tool selection";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
content.location = "data:text/html,testing the highlighter goes away on tool selection";
|
||||
let test = asyncTest(function* () {
|
||||
let { toolbox } = yield openInspectorForURL(TEST_URI);
|
||||
let pickerStopped = toolbox.once("picker-stopped");
|
||||
|
||||
function setupTest() {
|
||||
openInspector((aInspector, toolbox) => {
|
||||
let pickerStopped = toolbox.once("picker-stopped");
|
||||
info("Starting the inspector picker");
|
||||
yield toolbox.highlighterUtils.startPicker();
|
||||
|
||||
Task.spawn(function() {
|
||||
info("Starting the inspector picker");
|
||||
yield toolbox.highlighterUtils.startPicker();
|
||||
info("Selecting another tool than the inspector in the toolbox");
|
||||
yield toolbox.selectNextTool();
|
||||
info("Waiting for the picker-stopped event to be fired")
|
||||
yield pickerStopped;
|
||||
ok(true, "picker-stopped event fired after switch tools, so picker is closed");
|
||||
}).then(null, ok.bind(null, false)).then(finishUp);
|
||||
});
|
||||
}
|
||||
info("Selecting another tool than the inspector in the toolbox");
|
||||
yield toolbox.selectNextTool();
|
||||
|
||||
function finishUp() {
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
info("Waiting for the picker-stopped event to be fired");
|
||||
yield pickerStopped;
|
||||
|
||||
ok(true, "picker-stopped event fired after switch tools; picker is closed");
|
||||
});
|
||||
|
@ -1,43 +1,30 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
// Test that the highlighter's picker should be stopped when the toolbox is
|
||||
// closed
|
||||
|
||||
function test() {
|
||||
let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"<p>testing the highlighter goes away on destroy</p>";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(runTest, content);
|
||||
}, true);
|
||||
content.location = "data:text/html,<p>testing the highlighter goes away on destroy</p>";
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector, toolbox } = yield openInspectorForURL(TEST_URI);
|
||||
let pickerStopped = toolbox.once("picker-stopped");
|
||||
|
||||
function runTest() {
|
||||
openInspector((inspector, toolbox) => {
|
||||
let pickerStopped = toolbox.once("picker-stopped");
|
||||
yield selectNode("p", inspector);
|
||||
|
||||
Task.spawn(function() {
|
||||
// Selecting a node and waiting for inspector-updated event gives the
|
||||
// inspector a chance to fully update its side-panels and therefore
|
||||
// avoids errors when removing the tab (due to ongoing requests)
|
||||
yield inspector.selection.setNode(content.document.querySelector("p"));
|
||||
yield inspector.once("inspector-updated");
|
||||
info("inspector displayed and ready, starting the picker");
|
||||
yield toolbox.highlighterUtils.startPicker();
|
||||
info("destroying the toolbox");
|
||||
yield toolbox.destroy();
|
||||
info("waiting for the picker-stopped event that should be fired when the toolbox is destroyed");
|
||||
yield pickerStopped;
|
||||
ok(true, "picker-stopped event fired after switch tools, so picker is closed");
|
||||
}).then(null, ok.bind(null, false)).then(finishUp);
|
||||
});
|
||||
}
|
||||
info("Inspector displayed and ready, starting the picker.");
|
||||
yield toolbox.highlighterUtils.startPicker();
|
||||
|
||||
function finishUp() {
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
info("Destroying the toolbox.");
|
||||
yield toolbox.destroy();
|
||||
|
||||
info("Waiting for the picker-stopped event that should be fired when the " +
|
||||
"toolbox is destroyed.");
|
||||
yield pickerStopped;
|
||||
|
||||
ok(true, "picker-stopped event fired after switch tools, so picker is closed.");
|
||||
});
|
||||
|
@ -1,13 +1,14 @@
|
||||
/* 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 that the inspect command works as it should
|
||||
// Testing that the gcli 'inspect' command works as it should.
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/inspector/" +
|
||||
"test/browser_inspector_cmd_inspect.html";
|
||||
const TEST_URI = TEST_URL_ROOT + "browser_inspector_cmd_inspect.html";
|
||||
|
||||
function test() {
|
||||
helpers.addTabWithToolbar(TEST_URI, function(options) {
|
||||
let test = asyncTest(function* () {
|
||||
return helpers.addTabWithToolbar(TEST_URI, function(options) {
|
||||
return helpers.audit(options, [
|
||||
{
|
||||
setup: "inspect",
|
||||
@ -128,6 +129,6 @@ function test() {
|
||||
status: 'VALID'
|
||||
},
|
||||
},
|
||||
]);
|
||||
}).then(finish);
|
||||
}
|
||||
]); // helpers.audit
|
||||
}); // helpers.addTabWithToolbar
|
||||
}); // asyncTest
|
||||
|
@ -12,24 +12,24 @@
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
iframe.remove();
|
||||
|
||||
yay.textContent = "before events";
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
iframe.remove();
|
||||
|
||||
yay.textContent = "DOMContentLoaded";
|
||||
});
|
||||
window.addEventListener("load", function() {
|
||||
var iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
iframe.remove();
|
||||
|
||||
yay.textContent = "load";
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -1,54 +1,40 @@
|
||||
/* Any copyright", " is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.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";
|
||||
|
||||
function test() {
|
||||
let contentTab, contentDoc, inspector;
|
||||
// Testing that the inspector doesn't go blank when navigating to a page that
|
||||
// deletes an iframe while loading.
|
||||
|
||||
// Create a tab
|
||||
contentTab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
const TEST_URL = TEST_URL_ROOT + "browser_inspector_dead_node_exception.html";
|
||||
|
||||
// Open the toolbox's inspector first
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||
inspector = toolbox.getCurrentPanel();
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector, toolbox } = yield openInspectorForURL("about:blank");
|
||||
|
||||
inspector.selection.setNode(content.document.querySelector("body"));
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node.tagName, "BODY", "Inspector displayed");
|
||||
yield selectNode("body", inspector);
|
||||
|
||||
// Then load our test page
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
contentDoc = content.document;
|
||||
let loaded = once(gBrowser.selectedBrowser, "load", true);
|
||||
content.location = TEST_URL;
|
||||
|
||||
// The content doc contains a script that creates an iframe and deletes
|
||||
// it immediately after. This is what used to make the inspector go
|
||||
// blank when navigating to that page.
|
||||
info("Waiting for test page to load.");
|
||||
yield loaded;
|
||||
|
||||
var iframe = contentDoc.createElement("iframe");
|
||||
contentDoc.body.appendChild(iframe);
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
// The content doc contains a script that creates an iframe and deletes
|
||||
// it immediately after. This is what used to make the inspector go
|
||||
// blank when navigating to that page.
|
||||
info("Creating and removing an iframe.");
|
||||
var iframe = content.document.createElement("iframe");
|
||||
content.document.body.appendChild(iframe);
|
||||
iframe.remove();
|
||||
|
||||
is(contentDoc.querySelector("iframe"), null, "Iframe has been removed");
|
||||
ok(!getNode("iframe", {expectNoMatch: true}), "Iframe has been removed.");
|
||||
|
||||
inspector.once("markuploaded", () => {
|
||||
// Assert that the markup-view is displayed and works
|
||||
is(contentDoc.querySelector("iframe"), null, "Iframe has been removed");
|
||||
is(contentDoc.getElementById("yay").textContent, "load", "Load event fired");
|
||||
info("Waiting for markup-view to load.");
|
||||
yield inspector.once("markuploaded");
|
||||
|
||||
inspector.selection.setNode(contentDoc.getElementById("yay"));
|
||||
inspector.once("inspector-updated", () => {
|
||||
ok(inspector.selection.node, "Inspector still displayed");
|
||||
// Assert that the markup-view is displayed and works
|
||||
ok(!getNode("iframe", {expectNoMatch: true}), "Iframe has been removed.");
|
||||
is(getNode("#yay").textContent, "load", "Load event fired.");
|
||||
|
||||
// Clean up and go
|
||||
contentTab, contentDoc, inspector = null;
|
||||
gBrowser.removeTab(contentTab);
|
||||
finish();
|
||||
});
|
||||
});
|
||||
}, true);
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/" +
|
||||
"inspector/test/browser_inspector_dead_node_exception.html";
|
||||
});
|
||||
});
|
||||
}
|
||||
yield selectNode("#yay", inspector);
|
||||
});
|
||||
|
@ -1,50 +1,26 @@
|
||||
/* 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";
|
||||
|
||||
function test()
|
||||
{
|
||||
let node, iframe, inspector;
|
||||
// Test to ensure inspector can handle destruction of selected node inside an
|
||||
// iframe.
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
const TEST_URL = TEST_URL_ROOT + "browser_inspector_destroyselection.html";
|
||||
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_destroyselection.html";
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
|
||||
function setupTest()
|
||||
{
|
||||
iframe = content.document.querySelector("iframe");
|
||||
node = iframe.contentDocument.querySelector("span");
|
||||
openInspector(runTests);
|
||||
}
|
||||
let iframe = getNode("iframe");
|
||||
let node = getNode("span", { document: iframe.contentDocument });
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
function runTests(aInspector)
|
||||
{
|
||||
inspector = aInspector;
|
||||
inspector.selection.setNode(node);
|
||||
info("Removing iframe.");
|
||||
iframe.remove();
|
||||
|
||||
inspector.once("inspector-updated", () => {
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
iframe = null;
|
||||
|
||||
let tmp = {};
|
||||
Cu.import("resource://gre/modules/devtools/LayoutHelpers.jsm", tmp);
|
||||
let lh = new tmp.LayoutHelpers(window.content);
|
||||
ok(!lh.isNodeConnected(node), "Node considered as disconnected.");
|
||||
ok(!inspector.selection.isConnected(), "Selection considered as disconnected");
|
||||
|
||||
inspector.once("inspector-updated", () => {
|
||||
finishUp();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
node = inspector = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
}
|
||||
let lh = new LayoutHelpers(window.content);
|
||||
ok(!lh.isNodeConnected(node), "Node considered as disconnected.");
|
||||
ok(!inspector.selection.isConnected(), "Selection considered as disconnected.");
|
||||
|
||||
yield inspector.once("inspector-updated");
|
||||
});
|
||||
|
@ -8,15 +8,10 @@
|
||||
|
||||
// Test that the highlighter is correctly displayed over a variety of elements
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "browser_inspector_highlighter.html";
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/inspector/" +
|
||||
"test/browser_inspector_highlighter.html";
|
||||
|
||||
info("Opening the document");
|
||||
yield addTab(TEST_URI);
|
||||
|
||||
info("Opening the inspector");
|
||||
let {toolbox, inspector} = yield openInspector();
|
||||
let { inspector } = yield openInspectorForURL(TEST_URI);
|
||||
|
||||
info("Selecting the simple, non-transformed DIV");
|
||||
let div = getNode("#simple-div");
|
||||
@ -43,7 +38,6 @@ let test = asyncTest(function*() {
|
||||
|
||||
testMouseOverWidthHeightZeroDiv(zeroWidthHeight);
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
function testSimpleDivHighlighted(div) {
|
||||
|
@ -3,109 +3,55 @@
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
let doc;
|
||||
let div1;
|
||||
let div2;
|
||||
let iframe1;
|
||||
let iframe2;
|
||||
let inspector;
|
||||
// Testing that moving the mouse over the document with the element picker
|
||||
// started highlights nodes
|
||||
|
||||
function createDocument() {
|
||||
doc.title = "Inspector iframe Tests";
|
||||
const NESTED_FRAME_SRC = "data:text/html;charset=utf-8," +
|
||||
"nested iframe<div>nested div</div>";
|
||||
|
||||
iframe1 = doc.createElement('iframe');
|
||||
const OUTER_FRAME_SRC = "data:text/html;charset=utf-8," +
|
||||
"little frame<div>little div</div>" +
|
||||
"<iframe src='" + NESTED_FRAME_SRC + "' />";
|
||||
|
||||
iframe1.addEventListener("load", function () {
|
||||
iframe1.removeEventListener("load", arguments.callee, false);
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"iframe tests for inspector" +
|
||||
"<iframe src=\"" + OUTER_FRAME_SRC + "\" />";
|
||||
|
||||
div1 = iframe1.contentDocument.createElement('div');
|
||||
div1.textContent = 'little div';
|
||||
iframe1.contentDocument.body.appendChild(div1);
|
||||
let test = asyncTest(function*() {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URI);
|
||||
let outerFrame = getNode("iframe");
|
||||
let outerFrameDiv = getNode("div", { document: outerFrame.contentDocument});
|
||||
let innerFrame = getNode("iframe", { document: outerFrame.contentDocument});
|
||||
let innerFrameDiv = getNode("div", { document: innerFrame.contentDocument});
|
||||
|
||||
iframe2 = iframe1.contentDocument.createElement('iframe');
|
||||
info("Waiting for element picker to activate.");
|
||||
yield inspector.toolbox.highlighterUtils.startPicker();
|
||||
|
||||
iframe2.addEventListener('load', function () {
|
||||
iframe2.removeEventListener("load", arguments.callee, false);
|
||||
info("Moving mouse over outerFrameDiv");
|
||||
yield moveMouseOver(outerFrameDiv);
|
||||
is(getHighlitNode(), outerFrameDiv, "outerFrameDiv is highlighted.");
|
||||
|
||||
div2 = iframe2.contentDocument.createElement('div');
|
||||
div2.textContent = 'nested div';
|
||||
iframe2.contentDocument.body.appendChild(div2);
|
||||
info("Moving mouse over innerFrameDiv");
|
||||
yield moveMouseOver(innerFrameDiv);
|
||||
is(getHighlitNode(), innerFrameDiv, "innerFrameDiv is highlighted.");
|
||||
|
||||
// Open the inspector, start the picker mode, and start the tests
|
||||
openInspector(aInspector => {
|
||||
inspector = aInspector;
|
||||
inspector.toolbox.highlighterUtils.startPicker().then(runTests);
|
||||
});
|
||||
}, false);
|
||||
info("Selecting root node");
|
||||
yield selectNode(content.document.documentElement, inspector);
|
||||
|
||||
iframe2.src = 'data:text/html,nested iframe';
|
||||
iframe1.contentDocument.body.appendChild(iframe2);
|
||||
}, false);
|
||||
info("Selecting an element from the nested iframe directly");
|
||||
yield selectNode(innerFrameDiv, inspector);
|
||||
|
||||
iframe1.src = 'data:text/html,little iframe';
|
||||
doc.body.appendChild(iframe1);
|
||||
}
|
||||
is(inspector.breadcrumbs.nodeHierarchy.length, 9, "Breadcrumbs have 9 items.");
|
||||
|
||||
function moveMouseOver(aElement, cb) {
|
||||
inspector.toolbox.once("picker-node-hovered", cb);
|
||||
EventUtils.synthesizeMouseAtCenter(aElement, {type: "mousemove"},
|
||||
aElement.ownerDocument.defaultView);
|
||||
}
|
||||
info("Waiting for element picker to deactivate.");
|
||||
yield inspector.toolbox.highlighterUtils.stopPicker();
|
||||
|
||||
function runTests() {
|
||||
testDiv1Highlighter();
|
||||
}
|
||||
|
||||
function testDiv1Highlighter() {
|
||||
moveMouseOver(div1, () => {
|
||||
is(getHighlitNode(), div1, "highlighter matches selection of div1");
|
||||
testDiv2Highlighter();
|
||||
});
|
||||
}
|
||||
|
||||
function testDiv2Highlighter() {
|
||||
moveMouseOver(div2, () => {
|
||||
is(getHighlitNode(), div2, "highlighter matches selection of div2");
|
||||
selectRoot();
|
||||
});
|
||||
}
|
||||
|
||||
function selectRoot() {
|
||||
// Select the root document element to clear the breadcrumbs.
|
||||
inspector.selection.setNode(doc.documentElement, null);
|
||||
inspector.once("inspector-updated", selectIframe);
|
||||
}
|
||||
|
||||
function selectIframe() {
|
||||
// Directly select an element in an iframe (without navigating to it
|
||||
// with mousemoves).
|
||||
inspector.selection.setNode(div2, null);
|
||||
inspector.once("inspector-updated", () => {
|
||||
let breadcrumbs = inspector.breadcrumbs;
|
||||
is(breadcrumbs.nodeHierarchy.length, 9, "Should have 9 items");
|
||||
finishUp();
|
||||
});
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
inspector.toolbox.highlighterUtils.stopPicker().then(() => {
|
||||
doc = div1 = div2 = iframe1 = iframe2 = inspector = null;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.closeToolbox(target);
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function test() {
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
gBrowser.selectedBrowser.focus();
|
||||
createDocument();
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,iframe tests for inspector";
|
||||
}
|
||||
function moveMouseOver(element) {
|
||||
info("Waiting for element " + element + " to be highlighted");
|
||||
EventUtils.synthesizeMouseAtCenter(element, {type: "mousemove"},
|
||||
element.ownerDocument.defaultView);
|
||||
return inspector.toolbox.once("picker-node-hovered");
|
||||
}
|
||||
});
|
||||
|
@ -3,138 +3,122 @@
|
||||
/* 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/. */
|
||||
let doc;
|
||||
let salutation;
|
||||
"use strict";
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = '<div id="first" style="{ margin: 10em; ' +
|
||||
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA}">\n' +
|
||||
'<h1>Some header text</h1>\n' +
|
||||
'<p id="salutation" style="{font-size: 12pt}">hi.</p>\n' +
|
||||
'<p id="body" style="{font-size: 12pt}">I am a test-case. This text exists ' +
|
||||
'solely to provide some things to test the inspector initialization.</p>\n' +
|
||||
'If you are reading this, you should go do something else instead. Maybe ' +
|
||||
'read a book. Or better yet, write some test-cases for another bit of code. ' +
|
||||
'<span style="{font-style: italic}">Inspector\'s!</span></p>\n' +
|
||||
'<p id="closing">end transmission</p>\n' +
|
||||
'</div>';
|
||||
doc.title = "Inspector Initialization Test";
|
||||
// Tests for different ways to initialize the inspector.
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||
startInspectorTests(toolbox);
|
||||
}).then(null, console.error);
|
||||
}
|
||||
const DOCUMENT_HTML = '<div id="first" style="{margin: 10em; font-size: 14pt;' +
|
||||
'font-family: helvetica, sans-serif; color: #AAA}">\n' +
|
||||
'<h1>Some header text</h1>\n' +
|
||||
'<p id="salutation" style="{font-size: 12pt}">hi.</p>\n' +
|
||||
'<p id="body" style="{font-size: 12pt}">I am a test-case. This text exists ' +
|
||||
'solely to provide some things to test the inspector initialization.</p>\n' +
|
||||
'If you are reading this, you should go do something else instead. Maybe ' +
|
||||
'read a book. Or better yet, write some test-cases for another bit of code. ' +
|
||||
'<span style="{font-style: italic}">Inspector\'s!</span></p>\n' +
|
||||
'<p id="closing">end transmission</p>\n' +
|
||||
'</div>';
|
||||
|
||||
function startInspectorTests(toolbox)
|
||||
{
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"browser_inspector_initialization.js";
|
||||
|
||||
let test = asyncTest(function* () {
|
||||
let tab = yield addTab(TEST_URI);
|
||||
content.document.body.innerHTML = DOCUMENT_HTML;
|
||||
content.document.title = "Inspector Initialization Test";
|
||||
|
||||
yield testToolboxInitialization(tab);
|
||||
yield testContextMenuInitialization();
|
||||
yield testContextMenuInspectorAlreadyOpen();
|
||||
});
|
||||
|
||||
function* testToolboxInitialization(tab) {
|
||||
let target = TargetFactory.forTab(tab);
|
||||
|
||||
info("Opening inspector with gDevTools.");
|
||||
let toolbox = yield gDevTools.showToolbox(target, "inspector");
|
||||
let inspector = toolbox.getCurrentPanel();
|
||||
|
||||
ok(true, "Inspector started, and notification received.");
|
||||
ok(inspector, "Inspector instance is accessible.");
|
||||
ok(inspector.isReady, "Inspector instance is ready.");
|
||||
is(inspector.target.tab, tab, "Valid target.");
|
||||
|
||||
ok(inspector, "Inspector instance is accessible");
|
||||
ok(inspector.isReady, "Inspector instance is ready");
|
||||
is(inspector.target.tab, gBrowser.selectedTab, "Valid target");
|
||||
let p = getNode("p");
|
||||
yield selectNode(p, inspector);
|
||||
testMarkupView(p, inspector);
|
||||
testBreadcrumbs(p, inspector);
|
||||
|
||||
let p = doc.querySelector("p");
|
||||
let span = getNode("span");
|
||||
span.scrollIntoView();
|
||||
|
||||
inspector.selection.setNode(p);
|
||||
inspector.once("inspector-updated", () => {
|
||||
testMarkupView(p);
|
||||
testBreadcrumbs(p);
|
||||
yield selectNode(span, inspector);
|
||||
testMarkupView(span, inspector);
|
||||
testBreadcrumbs(span, inspector);
|
||||
|
||||
let span = doc.querySelector("span");
|
||||
span.scrollIntoView();
|
||||
info("Destroying toolbox");
|
||||
let destroyed = toolbox.once("destroyed");
|
||||
toolbox.destroy();
|
||||
yield destroyed;
|
||||
|
||||
inspector.selection.setNode(span);
|
||||
inspector.once("inspector-updated", () => {
|
||||
testMarkupView(span);
|
||||
testBreadcrumbs(span);
|
||||
|
||||
toolbox.once("destroyed", function() {
|
||||
ok("true", "'destroyed' notification received.");
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
ok(!gDevTools.getToolbox(target), "Toolbox destroyed.");
|
||||
executeSoon(runContextMenuTest);
|
||||
});
|
||||
toolbox.destroy();
|
||||
});
|
||||
});
|
||||
ok("true", "'destroyed' notification received.");
|
||||
ok(!gDevTools.getToolbox(target), "Toolbox destroyed.");
|
||||
}
|
||||
|
||||
let callNo = 0;
|
||||
function testMarkupView(node)
|
||||
{
|
||||
let i = getActiveInspector();
|
||||
function* testContextMenuInitialization() {
|
||||
info("Opening inspector by clicking on 'Inspect Element' context menu item");
|
||||
let salutation = getNode("#salutation");
|
||||
|
||||
yield clickOnInspectMenuItem(salutation);
|
||||
|
||||
info("Checking inspector state.");
|
||||
testMarkupView(salutation);
|
||||
testBreadcrumbs(salutation);
|
||||
}
|
||||
|
||||
function* testContextMenuInspectorAlreadyOpen() {
|
||||
info("Changing node by clicking on 'Inspect Element' context menu item");
|
||||
|
||||
let inspector = getActiveInspector();
|
||||
ok(inspector, "Inspector is active");
|
||||
|
||||
let closing = getNode("#closing");
|
||||
yield clickOnInspectMenuItem(closing);
|
||||
|
||||
ok(true, "Inspector was updated when 'Inspect Element' was clicked.");
|
||||
testMarkupView(closing, inspector);
|
||||
testBreadcrumbs(closing, inspector);
|
||||
}
|
||||
|
||||
function testMarkupView(node, inspector) {
|
||||
inspector = inspector || getActiveInspector();
|
||||
try {
|
||||
is(i.markup._selectedContainer.node.rawNode(), node, "Right node is selected in the markup view");
|
||||
} catch(ex) { console.error(ex); }
|
||||
is(inspector.markup._selectedContainer.node.rawNode(), node,
|
||||
"Right node is selected in the markup view");
|
||||
} catch(ex) {
|
||||
ok(false, "Got exception while resolving selected node of markup view.");
|
||||
console.error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
function testBreadcrumbs(node)
|
||||
{
|
||||
let b = getActiveInspector().breadcrumbs;
|
||||
function testBreadcrumbs(node, inspector) {
|
||||
inspector = inspector || getActiveInspector();
|
||||
let b = inspector.breadcrumbs;
|
||||
let expectedText = b.prettyPrintNodeAsText(getNodeFront(node));
|
||||
let button = b.container.querySelector("button[checked=true]");
|
||||
ok(button, "A crumbs is checked=true");
|
||||
is(button.getAttribute("tooltiptext"), expectedText, "Crumb refers to the right node");
|
||||
}
|
||||
|
||||
function _clickOnInspectMenuItem(node) {
|
||||
function* clickOnInspectMenuItem(node) {
|
||||
info("Clicking on 'Inspect Element' context menu item of " + node);
|
||||
document.popupNode = node;
|
||||
var contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
|
||||
var contentAreaContextMenu = getNode("#contentAreaContextMenu", { document });
|
||||
var contextMenu = new nsContextMenu(contentAreaContextMenu);
|
||||
var {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
var deferred = promise.defer();
|
||||
contextMenu.inspectNode().then(() => {
|
||||
let i = getActiveInspector();
|
||||
i.once("inspector-updated", () => {
|
||||
deferred.resolve(undefined);
|
||||
});
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function runContextMenuTest()
|
||||
{
|
||||
salutation = doc.getElementById("salutation");
|
||||
_clickOnInspectMenuItem(salutation).then(testInitialNodeIsSelected);
|
||||
}
|
||||
info("Triggering inspect action.");
|
||||
yield contextMenu.inspectNode();
|
||||
|
||||
function testInitialNodeIsSelected() {
|
||||
testMarkupView(salutation);
|
||||
testBreadcrumbs(salutation);
|
||||
inspectNodesFromContextTestWhileOpen();
|
||||
}
|
||||
|
||||
function inspectNodesFromContextTestWhileOpen()
|
||||
{
|
||||
let closing = doc.getElementById("closing");
|
||||
getActiveInspector().selection.once("new-node", function() {
|
||||
ok(true, "Get selection's 'new-node' selection");
|
||||
executeSoon(function() {
|
||||
testMarkupView(closing);
|
||||
testBreadcrumbs(closing);
|
||||
getActiveInspector().once("inspector-updated", finishInspectorTests)
|
||||
}
|
||||
)});
|
||||
_clickOnInspectMenuItem(closing);
|
||||
}
|
||||
|
||||
function finishInspectorTests(subject, topic, aWinIdString)
|
||||
{
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,browser_inspector_initialization.js";
|
||||
info("Waiting for inspector to update.");
|
||||
yield getActiveInspector().once("inspector-updated");
|
||||
}
|
||||
|
@ -1,54 +1,33 @@
|
||||
/* 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";
|
||||
|
||||
function test() {
|
||||
let doc;
|
||||
let div;
|
||||
let inspector;
|
||||
// Test that highlighter handles geometry changes correctly.
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"browser_inspector_invalidate.js\n" +
|
||||
"<div style=\"width: 100px; height: 100px; background:yellow;\"></div>";
|
||||
|
||||
function createDocument() {
|
||||
div = doc.createElement("div");
|
||||
div.setAttribute("style", "width: 100px; height: 100px; background:yellow;");
|
||||
doc.body.appendChild(div);
|
||||
let test = asyncTest(function*() {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URI);
|
||||
let div = getNode("div");
|
||||
|
||||
openInspector(aInspector => {
|
||||
inspector = aInspector;
|
||||
inspector.toolbox.highlighter.showBoxModel(getNodeFront(div)).then(runTest);
|
||||
});
|
||||
}
|
||||
info("Waiting for highlighter to activate");
|
||||
yield inspector.toolbox.highlighter.showBoxModel(getNodeFront(div));
|
||||
|
||||
function runTest() {
|
||||
info("Checking that the highlighter has the right size");
|
||||
let rect = getSimpleBorderRect();
|
||||
is(rect.width, 100, "outline has the right width");
|
||||
let rect = getSimpleBorderRect();
|
||||
is(rect.width, 100, "Outline has the right width.");
|
||||
|
||||
waitForBoxModelUpdate().then(testRectWidth);
|
||||
info("Changing the test element's size");
|
||||
let boxModelUpdated = waitForBoxModelUpdate();
|
||||
div.style.width = "200px";
|
||||
|
||||
info("Changing the test element's size");
|
||||
div.style.width = "200px";
|
||||
}
|
||||
info("Waiting for the box model to update.");
|
||||
yield boxModelUpdated;
|
||||
|
||||
function testRectWidth() {
|
||||
info("Checking that the highlighter has the right size after update");
|
||||
let rect = getSimpleBorderRect();
|
||||
is(rect.width, 200, "outline updated");
|
||||
finishUp();
|
||||
}
|
||||
rect = getSimpleBorderRect();
|
||||
is(rect.width, 200, "Outline has the right width after update.");
|
||||
|
||||
function finishUp() {
|
||||
inspector.toolbox.highlighter.hideBoxModel().then(() => {
|
||||
doc = div = inspector = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,browser_inspector_invalidate.js";
|
||||
}
|
||||
info("Waiting for highlighter to hide");
|
||||
yield inspector.toolbox.highlighter.hideBoxModel();
|
||||
});
|
||||
|
@ -1,218 +1,210 @@
|
||||
/* 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
|
||||
|
||||
function test() {
|
||||
|
||||
let clipboard = require("sdk/clipboard");
|
||||
let doc;
|
||||
let inspector;
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
doc = content.document;
|
||||
waitForFocus(setupTest, content);
|
||||
}, true);
|
||||
|
||||
content.location = "http://mochi.test:8888/browser/browser/devtools/" +
|
||||
"inspector/test/browser_inspector_menu.html";
|
||||
|
||||
function setupTest() {
|
||||
openInspector(runTests);
|
||||
const TEST_URL = TEST_URL_ROOT + "browser_inspector_menu.html";
|
||||
const MENU_SENSITIVITY_TEST_DATA = [
|
||||
{
|
||||
desc: "doctype node",
|
||||
selector: null,
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
desc: "element node",
|
||||
selector: "p",
|
||||
disabled: false,
|
||||
}
|
||||
];
|
||||
|
||||
function runTests(aInspector) {
|
||||
inspector = aInspector;
|
||||
checkDocTypeMenuItems();
|
||||
}
|
||||
|
||||
function checkDocTypeMenuItems() {
|
||||
info("Checking context menu entries for doctype node");
|
||||
inspector.selection.setNode(doc.doctype);
|
||||
inspector.once("inspector-updated", () => {
|
||||
let docTypeNode = getMarkupTagNodeContaining("<!DOCTYPE html>");
|
||||
|
||||
// Right-click doctype tag
|
||||
contextMenuClick(docTypeNode);
|
||||
|
||||
checkDisabled("node-menu-copyinner");
|
||||
checkDisabled("node-menu-copyouter");
|
||||
checkDisabled("node-menu-copyuniqueselector");
|
||||
checkDisabled("node-menu-delete");
|
||||
checkDisabled("node-menu-pasteouterhtml");
|
||||
|
||||
for (let name of ["hover", "active", "focus"]) {
|
||||
checkDisabled("node-menu-pseudo-" + name);
|
||||
}
|
||||
|
||||
checkElementMenuItems();
|
||||
});
|
||||
}
|
||||
|
||||
function checkElementMenuItems() {
|
||||
info("Checking context menu entries for p tag");
|
||||
inspector.selection.setNode(doc.querySelector("p"));
|
||||
inspector.once("inspector-updated", () => {
|
||||
let tag = getMarkupTagNodeContaining("p");
|
||||
|
||||
// Right-click p tag
|
||||
contextMenuClick(tag);
|
||||
|
||||
checkEnabled("node-menu-copyinner");
|
||||
checkEnabled("node-menu-copyouter");
|
||||
checkEnabled("node-menu-copyuniqueselector");
|
||||
checkEnabled("node-menu-delete");
|
||||
|
||||
for (let name of ["hover", "active", "focus"]) {
|
||||
checkEnabled("node-menu-pseudo-" + name);
|
||||
}
|
||||
|
||||
checkElementPasteOuterHTMLMenuItemForText();
|
||||
});
|
||||
}
|
||||
|
||||
function checkPasteOuterHTMLMenuItem(data, type, check, next) {
|
||||
clipboard.set(data, type);
|
||||
inspector.selection.setNode(doc.querySelector("p"));
|
||||
inspector.once("inspector-updated", () => {
|
||||
contextMenuClick(getMarkupTagNodeContaining("p"));
|
||||
check("node-menu-pasteouterhtml");
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
function checkElementPasteOuterHTMLMenuItemForText() {
|
||||
checkPasteOuterHTMLMenuItem(
|
||||
"some text",
|
||||
undefined,
|
||||
checkEnabled,
|
||||
checkElementPasteOuterHTMLMenuItemForImage);
|
||||
}
|
||||
|
||||
function checkElementPasteOuterHTMLMenuItemForImage() {
|
||||
checkPasteOuterHTMLMenuItem(
|
||||
const PASTE_OUTER_HTML_TEST_DATA = [
|
||||
{
|
||||
desc: "some text",
|
||||
clipboardData: "some text",
|
||||
clipboardDataType: undefined,
|
||||
disabled: false
|
||||
},
|
||||
{
|
||||
desc: "base64 encoded image data uri",
|
||||
clipboardData:
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABC" +
|
||||
"AAAAAA6fptVAAAACklEQVQYV2P4DwABAQEAWk1v8QAAAABJRU5ErkJggg==",
|
||||
undefined,
|
||||
checkDisabled,
|
||||
checkElementPasteOuterHTMLMenuItemForHTML);
|
||||
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 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 = devtools.require("sdk/clipboard");
|
||||
registerCleanupFunction(() => {
|
||||
clipboard = null;
|
||||
});
|
||||
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
|
||||
yield testMenuItemSensitivity();
|
||||
yield testPasteOuterHTMLMenuItemSensitivity();
|
||||
yield testCopyMenuItems();
|
||||
yield testPasteOuterHTMLMenu();
|
||||
yield testDeleteNode();
|
||||
yield testDeleteRootNode();
|
||||
|
||||
function* testMenuItemSensitivity() {
|
||||
info("Testing sensitivity of menu items for different elements.");
|
||||
|
||||
const MENU_ITEMS = [
|
||||
"node-menu-copyinner",
|
||||
"node-menu-copyouter",
|
||||
"node-menu-copyuniqueselector",
|
||||
"node-menu-delete",
|
||||
"node-menu-pasteouterhtml",
|
||||
"node-menu-pseudo-hover",
|
||||
"node-menu-pseudo-active",
|
||||
"node-menu-pseudo-focus"
|
||||
];
|
||||
|
||||
// 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 node = getNode(selector) || content.document.doctype;
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
contextMenuClick(getContainerForRawNode(inspector.markup, node).tagLine);
|
||||
|
||||
for (let name of MENU_ITEMS) {
|
||||
checkMenuItem(name, disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkElementPasteOuterHTMLMenuItemForHTML() {
|
||||
checkPasteOuterHTMLMenuItem(
|
||||
"<p>some text</p>",
|
||||
"html",
|
||||
checkEnabled,
|
||||
checkElementPasteOuterHTMLMenuItemForEmptyString);
|
||||
function* testPasteOuterHTMLMenuItemSensitivity() {
|
||||
info("Checking 'Paste Outer HTML' menu item sensitivity for different types" +
|
||||
"of data");
|
||||
|
||||
let node = getNode("p");
|
||||
let markupTagLine = getContainerForRawNode(inspector.markup, node).tagLine;
|
||||
|
||||
for (let data of PASTE_OUTER_HTML_TEST_DATA) {
|
||||
let { desc, clipboardData, clipboardDataType, disabled } = data;
|
||||
info("Checking 'Paste Outer HTML' for " + desc);
|
||||
clipboard.set(clipboardData, clipboardDataType);
|
||||
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
contextMenuClick(markupTagLine);
|
||||
checkMenuItem("node-menu-pasteouterhtml", disabled);
|
||||
}
|
||||
}
|
||||
|
||||
function checkElementPasteOuterHTMLMenuItemForEmptyString() {
|
||||
checkPasteOuterHTMLMenuItem(
|
||||
"",
|
||||
undefined,
|
||||
checkDisabled,
|
||||
checkElementPasteOuterHTMLMenuItemForWhitespaceOnly);
|
||||
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 checkElementPasteOuterHTMLMenuItemForWhitespaceOnly() {
|
||||
checkPasteOuterHTMLMenuItem(
|
||||
" \n\n\t\n\n \n",
|
||||
undefined,
|
||||
checkDisabled,
|
||||
testCopyInnerMenu);
|
||||
}
|
||||
|
||||
function testCopyInnerMenu() {
|
||||
let copyInner = inspector.panelDoc.getElementById("node-menu-copyinner");
|
||||
ok(copyInner, "the popup menu has a copy inner html menu item");
|
||||
|
||||
waitForClipboard("This is some example text",
|
||||
function() { copyInner.doCommand(); },
|
||||
testCopyOuterMenu, testCopyOuterMenu);
|
||||
}
|
||||
|
||||
function testCopyOuterMenu() {
|
||||
let copyOuter = inspector.panelDoc.getElementById("node-menu-copyouter");
|
||||
ok(copyOuter, "the popup menu has a copy outer html menu item");
|
||||
|
||||
waitForClipboard("<p>This is some example text</p>",
|
||||
function() { copyOuter.doCommand(); },
|
||||
testCopyUniqueSelectorMenu, testCopyUniqueSelectorMenu);
|
||||
}
|
||||
|
||||
function testCopyUniqueSelectorMenu() {
|
||||
let copyUniqueSelector = inspector.panelDoc.getElementById("node-menu-copyuniqueselector");
|
||||
ok(copyUniqueSelector, "the popup menu has a copy unique selector menu item");
|
||||
|
||||
waitForClipboard("body > div:nth-child(1) > p:nth-child(2)",
|
||||
function() { copyUniqueSelector.doCommand(); },
|
||||
testPasteOuterHTMLMenu, testPasteOuterHTMLMenu);
|
||||
}
|
||||
|
||||
function testPasteOuterHTMLMenu() {
|
||||
function* testPasteOuterHTMLMenu() {
|
||||
info("Testing that 'Paste Outer HTML' menu item works.");
|
||||
clipboard.set("this was pasted");
|
||||
inspector.selection.setNode(doc.querySelector("h1"));
|
||||
inspector.once("inspector-updated", () => {
|
||||
contextMenuClick(getMarkupTagNodeContaining("h1"));
|
||||
let menu = inspector.panelDoc.getElementById("node-menu-pasteouterhtml");
|
||||
let event = document.createEvent("XULCommandEvent");
|
||||
event.initCommandEvent("command", true, true, window, 0, false, false,
|
||||
false, false, null);
|
||||
menu.dispatchEvent(event);
|
||||
inspector.selection.once("new-node", (event, oldNode, newNode) => {
|
||||
ok(doc.body.outerHTML.contains(clipboard.get()),
|
||||
"Clipboard content was pasted into the node's outer HTML.");
|
||||
ok(!doc.querySelector("h1"), "The original node was removed.");
|
||||
testDeleteNode();
|
||||
});
|
||||
});
|
||||
|
||||
let node = getNode("h1");
|
||||
yield selectNode(node, inspector);
|
||||
|
||||
contextMenuClick(getContainerForRawNode(inspector.markup, node).tagLine);
|
||||
|
||||
let menu = inspector.panelDoc.getElementById("node-menu-pasteouterhtml");
|
||||
dispatchCommandEvent(menu);
|
||||
|
||||
info("Waiting for inspector selection to update");
|
||||
yield inspector.selection.once("new-node");
|
||||
|
||||
ok(content.document.body.outerHTML.contains(clipboard.get()),
|
||||
"Clipboard content was pasted into the node's outer HTML.");
|
||||
ok(!getNode("h1", { expectNoMatch: true }), "The original node was removed.");
|
||||
}
|
||||
|
||||
function testDeleteNode() {
|
||||
function* testDeleteNode() {
|
||||
info("Testing 'Delete Node' menu item for normal elements.");
|
||||
let deleteNode = inspector.panelDoc.getElementById("node-menu-delete");
|
||||
ok(deleteNode, "the popup menu has a delete menu item");
|
||||
|
||||
inspector.once("inspector-updated", deleteTest);
|
||||
let updated = inspector.once("inspector-updated");
|
||||
|
||||
let commandEvent = document.createEvent("XULCommandEvent");
|
||||
commandEvent.initCommandEvent("command", true, true, window, 0, false, false,
|
||||
false, false, null);
|
||||
deleteNode.dispatchEvent(commandEvent);
|
||||
info("Triggering 'Delete Node' and waiting for inspector to update");
|
||||
dispatchCommandEvent(deleteNode);
|
||||
yield updated;
|
||||
|
||||
ok(!getNode("p", { expectNoMatch: true }), "Node deleted");
|
||||
}
|
||||
|
||||
function deleteTest() {
|
||||
let p = doc.querySelector("P");
|
||||
is(p, null, "node deleted");
|
||||
function* testDeleteRootNode() {
|
||||
info("Testing 'Delete Node' menu item does not delete root node.");
|
||||
yield selectNode(content.document.documentElement, inspector);
|
||||
|
||||
deleteRootNode();
|
||||
}
|
||||
let deleteNode = inspector.panelDoc.getElementById("node-menu-delete");
|
||||
dispatchCommandEvent(deleteNode);
|
||||
|
||||
function deleteRootNode() {
|
||||
inspector.selection.setNode(doc.documentElement);
|
||||
|
||||
inspector.once("inspector-updated", () => {
|
||||
let deleteNode = inspector.panelDoc.getElementById("node-menu-delete");
|
||||
let commandEvent = inspector.panelDoc.createEvent("XULCommandEvent");
|
||||
commandEvent.initCommandEvent("command", true, true, window, 0, false, false,
|
||||
false, false, null);
|
||||
deleteNode.dispatchEvent(commandEvent);
|
||||
executeSoon(isRootStillAlive);
|
||||
executeSoon(() => {
|
||||
ok(content.document.documentElement, "Document element still alive.");
|
||||
});
|
||||
}
|
||||
|
||||
function isRootStillAlive() {
|
||||
ok(doc.documentElement, "Document element still alive.");
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function getMarkupTagNodeContaining(text) {
|
||||
let tags = inspector._markupFrame.contentDocument.querySelectorAll("span");
|
||||
for (let tag of tags) {
|
||||
if (tag.textContent == text) {
|
||||
return tag;
|
||||
}
|
||||
function checkMenuItem(elementId, disabled) {
|
||||
if (disabled) {
|
||||
checkDisabled(elementId);
|
||||
} else {
|
||||
checkEnabled(elementId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,7 +220,16 @@ function test() {
|
||||
'"' + 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
|
||||
|
||||
@ -238,4 +239,4 @@ function test() {
|
||||
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -3,63 +3,41 @@
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
// Test that inspector updates when page is navigated.
|
||||
|
||||
function test() {
|
||||
let inspector, toolbox;
|
||||
const TEST_URL_FILE = "browser/browser/devtools/inspector/test/" +
|
||||
"browser_inspector_breadcrumbs.html";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(function() {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||
startInspectorTests(toolbox);
|
||||
}).then(null, console.error);
|
||||
}, content);
|
||||
}, true);
|
||||
const TEST_URL_1 = "http://test1.example.org/" + TEST_URL_FILE;
|
||||
const TEST_URL_2 = "http://test2.example.org/" + TEST_URL_FILE;
|
||||
|
||||
content.location = "http://test1.example.org/browser/browser/devtools/inspector/test/browser_inspector_breadcrumbs.html";
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL_1);
|
||||
let markuploaded = inspector.once("markuploaded");
|
||||
|
||||
function startInspectorTests(aToolbox)
|
||||
{
|
||||
toolbox = aToolbox;
|
||||
inspector = toolbox.getCurrentPanel();
|
||||
info("Inspector started");
|
||||
let node = content.document.querySelector("#i1");
|
||||
inspector.selection.setNode(node);
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, node, "Node selected.");
|
||||
inspector.once("markuploaded", onSecondLoad);
|
||||
content.location = "http://test2.example.org/browser/browser/devtools/inspector/test/browser_inspector_breadcrumbs.html";
|
||||
});
|
||||
}
|
||||
yield selectNode("#i1", inspector);
|
||||
|
||||
function onSecondLoad() {
|
||||
info("New page loaded");
|
||||
let node = content.document.querySelector("#i1");
|
||||
inspector.selection.setNode(node);
|
||||
info("Navigating to a different page.");
|
||||
content.location = TEST_URL_2;
|
||||
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, node, "Node re-selected.");
|
||||
inspector.once("markuploaded", onThirdLoad);
|
||||
content.history.go(-1);
|
||||
});
|
||||
}
|
||||
info("Waiting for markup view to load after navigation.");
|
||||
yield markuploaded;
|
||||
|
||||
function onThirdLoad() {
|
||||
info("Old page loaded");
|
||||
is(content.location.href, "http://test1.example.org/browser/browser/devtools/inspector/test/browser_inspector_breadcrumbs.html");
|
||||
let node = content.document.querySelector("#i1");
|
||||
inspector.selection.setNode(node);
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, node, "Node re-selected.");
|
||||
inspector.once("markuploaded", onThirdLoad);
|
||||
toolbox.destroy();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
ok(true, "New page loaded");
|
||||
yield selectNode("#i1", inspector);
|
||||
|
||||
markuploaded = inspector.once("markuploaded");
|
||||
|
||||
info("Going back in history");
|
||||
content.history.go(-1);
|
||||
|
||||
info("Waiting for markup view to load after going back in history.");
|
||||
yield markuploaded;
|
||||
|
||||
ok(true, "Old page loaded");
|
||||
is(content.location.href, TEST_URL_1, "URL is correct.");
|
||||
|
||||
yield selectNode("#i1", inspector);
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* 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 inspector has the correct pseudo-class locking menu items and
|
||||
@ -25,20 +25,12 @@ let test = asyncTest(function*() {
|
||||
yield openMenu(menu);
|
||||
|
||||
yield testMenuItems(div, menu, inspector);
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
function openMenu(menu) {
|
||||
let def = promise.defer();
|
||||
|
||||
menu.addEventListener("popupshowing", function onOpen() {
|
||||
menu.removeEventListener("popupshowing", onOpen, true);
|
||||
def.resolve();
|
||||
}, true);
|
||||
let promise = once(menu, "popupshowing", true);
|
||||
menu.openPopup();
|
||||
|
||||
return def.promise;
|
||||
return promise;
|
||||
}
|
||||
|
||||
function* testMenuItems(div,menu, inspector) {
|
||||
@ -49,7 +41,7 @@ function* testMenuItems(div,menu, inspector) {
|
||||
// Give the inspector panels a chance to update when the pseudoclass changes
|
||||
let onPseudo = inspector.selection.once("pseudoclass");
|
||||
let onRefresh = inspector.once("rule-view-refreshed");
|
||||
let onMutations = waitForMutation(inspector);
|
||||
let onMutations = inspector.walker.once("mutations");
|
||||
|
||||
menuitem.doCommand();
|
||||
|
||||
@ -61,9 +53,3 @@ function* testMenuItems(div,menu, inspector) {
|
||||
"pseudo-class lock has been applied");
|
||||
}
|
||||
}
|
||||
|
||||
function waitForMutation(inspector) {
|
||||
let def = promise.defer();
|
||||
inspector.walker.once("mutations", def.resolve);
|
||||
return def.promise;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
/* 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 locking the pseudoclass displays correctly in the ruleview
|
||||
|
||||
@ -18,8 +20,8 @@ const TEST_URL = 'data:text/html,' +
|
||||
|
||||
let test = asyncTest(function*() {
|
||||
info("Creating the test tab and opening the rule-view");
|
||||
yield addTab(TEST_URL);
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
let {toolbox, inspector} = yield openInspectorForURL(TEST_URL);
|
||||
let view = yield ensureRuleView(inspector);
|
||||
|
||||
info("Selecting the test node");
|
||||
yield selectNode("#div-1", inspector);
|
||||
@ -37,8 +39,6 @@ let test = asyncTest(function*() {
|
||||
info("Destroying the toolbox");
|
||||
yield toolbox.destroy();
|
||||
yield assertPseudoRemovedFromNode(getNode("#div-1"));
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ function* togglePseudoClass(inspector) {
|
||||
// Give the inspector panels a chance to update when the pseudoclass changes
|
||||
let onPseudo = inspector.selection.once("pseudoclass");
|
||||
let onRefresh = inspector.once("rule-view-refreshed");
|
||||
let onMutations = waitForMutation(inspector);
|
||||
let onMutations = inspector.walker.once("mutations");
|
||||
|
||||
yield inspector.togglePseudoClass(PSEUDO);
|
||||
|
||||
@ -57,12 +57,6 @@ function* togglePseudoClass(inspector) {
|
||||
yield onMutations;
|
||||
}
|
||||
|
||||
function waitForMutation(inspector) {
|
||||
let def = promise.defer();
|
||||
inspector.walker.once("mutations", def.resolve);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
function* testNavigate(inspector, ruleview) {
|
||||
yield selectNode("#parent-div", inspector);
|
||||
|
||||
@ -132,3 +126,15 @@ function* assertPseudoRemovedFromView(inspector, ruleview) {
|
||||
is(pseudoClassesBox.textContent, "", "pseudo-class removed from infobar selector");
|
||||
yield inspector.toolbox.highlighter.hideBoxModel();
|
||||
}
|
||||
|
||||
function* ensureRuleView(inspector) {
|
||||
if (!inspector.sidebar.getWindowForTab("ruleview")) {
|
||||
info("Waiting for ruleview initialization to complete.");
|
||||
yield inspector.sidebar.once("ruleview-ready");
|
||||
}
|
||||
|
||||
info("Selecting the ruleview sidebar");
|
||||
inspector.sidebar.select("ruleview");
|
||||
|
||||
return inspector.sidebar.getWindowForTab("ruleview")["ruleview"].view;
|
||||
}
|
||||
|
@ -3,51 +3,29 @@
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
// A test to ensure reloading a page doesn't break the inspector.
|
||||
|
||||
function test() {
|
||||
let inspector, toolbox;
|
||||
// Reload should reselect the currently selected markup view element.
|
||||
// This should work even when an element whose selector needs escaping
|
||||
// is selected (bug 1002280).
|
||||
const TEST_URI = "data:text/html,<p id='1'>p</p>";
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(function() {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||
startInspectorTests(toolbox);
|
||||
}).then(null, console.error);
|
||||
}, content);
|
||||
}, true);
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector, toolbox } = yield openInspectorForURL(TEST_URI);
|
||||
yield selectNode("p", inspector);
|
||||
|
||||
// Reload should reselect the currently selected markup view element.
|
||||
// This should work even when an element whose selector needs escaping
|
||||
// is selected (bug 100228).
|
||||
content.location = "data:text/html,<p id='1'>p</p>";
|
||||
let markupLoaded = inspector.once("markuploaded");
|
||||
|
||||
function startInspectorTests(aToolbox)
|
||||
{
|
||||
toolbox = aToolbox;
|
||||
inspector = toolbox.getCurrentPanel();
|
||||
info("Inspector started");
|
||||
let p = content.document.querySelector("p");
|
||||
inspector.selection.setNode(p);
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, p, "Node selected.");
|
||||
inspector.once("markuploaded", onReload);
|
||||
content.location.reload();
|
||||
});
|
||||
}
|
||||
info("Reloading page.");
|
||||
content.location.reload();
|
||||
|
||||
function onReload() {
|
||||
info("Page reloaded");
|
||||
let p = content.document.querySelector("p");
|
||||
inspector.selection.setNode(p);
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, p, "Node re-selected.");
|
||||
toolbox.destroy();
|
||||
toolbox = inspector = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
}
|
||||
info("Waiting for markupview to load after reload.");
|
||||
yield markupLoaded;
|
||||
|
||||
is(inspector.selection.node, getNode("p"), "<p> selected after reload.");
|
||||
|
||||
info("Selecting a node to see that inspector still works.");
|
||||
yield selectNode("body", inspector);
|
||||
});
|
||||
|
@ -3,74 +3,42 @@
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
let doc;
|
||||
let div;
|
||||
let iframe;
|
||||
let inspector;
|
||||
// Test that highlighted nodes can be scrolled.
|
||||
// TODO: This doesn't test anything useful. See b.m.o 1035661.
|
||||
const IFRAME_SRC = "data:text/html;charset=utf-8," +
|
||||
"<div style='height:500px; width:500px; border:1px solid gray;'>" +
|
||||
"big div" +
|
||||
"</div>";
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.title = "Inspector scrolling Tests";
|
||||
const TEST_URI = "data:text/html;charset=utf-8," +
|
||||
"<p>browser_inspector_scrolling.js</p>" +
|
||||
"<iframe src=\"" + IFRAME_SRC + "\" />";
|
||||
|
||||
iframe = doc.createElement("iframe");
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector, toolbox } = yield openInspectorForURL(TEST_URI);
|
||||
|
||||
iframe.addEventListener("load", function () {
|
||||
iframe.removeEventListener("load", arguments.callee, false);
|
||||
let iframe = getNode("iframe");
|
||||
let div = getNode("div", { document: iframe.contentDocument });
|
||||
|
||||
div = iframe.contentDocument.createElement("div");
|
||||
div.textContent = "big div";
|
||||
div.setAttribute("style", "height:500px; width:500px; border:1px solid gray;");
|
||||
iframe.contentDocument.body.appendChild(div);
|
||||
openInspector(inspectNode);
|
||||
}, false);
|
||||
info("Waiting for highlighter box model to appear.");
|
||||
yield toolbox.highlighter.showBoxModel(getNodeFront(div));
|
||||
|
||||
iframe.src = "data:text/html,foo bar";
|
||||
doc.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
function inspectNode(aInspector)
|
||||
{
|
||||
inspector = aInspector;
|
||||
|
||||
let highlighter = inspector.toolbox.highlighter;
|
||||
highlighter.showBoxModel(getNodeFront(div)).then(performScrollingTest);
|
||||
}
|
||||
|
||||
function performScrollingTest()
|
||||
{
|
||||
gBrowser.selectedBrowser.addEventListener("scroll", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("scroll", arguments.callee,
|
||||
false);
|
||||
let isRetina = devicePixelRatio === 2;
|
||||
is(iframe.contentDocument.body.scrollTop,
|
||||
isRetina ? 25 : 50, "inspected iframe scrolled");
|
||||
|
||||
finishUp();
|
||||
}, false);
|
||||
let scrolled = once(gBrowser.selectedBrowser, "scroll");
|
||||
|
||||
info("Scrolling iframe.");
|
||||
EventUtils.synthesizeWheel(div, 10, 10,
|
||||
{ deltaY: 50.0, deltaMode: WheelEvent.DOM_DELTA_PIXEL },
|
||||
iframe.contentWindow);
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
inspector = div = iframe = doc = null;
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.closeToolbox(target);
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
info("Waiting for scroll event");
|
||||
yield scrolled;
|
||||
|
||||
function test()
|
||||
{
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
let isRetina = devicePixelRatio === 2;
|
||||
is(iframe.contentDocument.body.scrollTop,
|
||||
isRetina ? 25 : 50, "inspected iframe scrolled");
|
||||
|
||||
content.location = "data:text/html,mouse scrolling test for inspector";
|
||||
}
|
||||
info("Hiding box model.");
|
||||
yield toolbox.highlighter.hideBoxModel();
|
||||
});
|
||||
|
@ -4,114 +4,84 @@
|
||||
* 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/. */
|
||||
|
||||
function test() {
|
||||
let inspector, toolbox;
|
||||
let page1 = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_select_last_selected.html";
|
||||
let page2 = "http://mochi.test:8888/browser/browser/devtools/inspector/test/browser_inspector_select_last_selected2.html";
|
||||
// Checks that the expected default node is selected after a page navigation or
|
||||
// a reload.
|
||||
let PAGE_1 = TEST_URL_ROOT + "browser_inspector_select_last_selected.html";
|
||||
let PAGE_2 = TEST_URL_ROOT + "browser_inspector_select_last_selected2.html";
|
||||
|
||||
// Create a tab, load test HTML, wait for load and start the tests
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
waitForFocus(function() {
|
||||
openInspector((aInspector, aToolbox) => {
|
||||
inspector = aInspector;
|
||||
toolbox = aToolbox;
|
||||
startTests();
|
||||
});
|
||||
}, content);
|
||||
}, true);
|
||||
content.location = page1;
|
||||
|
||||
function startTests() {
|
||||
testSameNodeSelectedOnPageReload();
|
||||
}
|
||||
|
||||
function endTests() {
|
||||
inspector.destroy();
|
||||
toolbox.destroy().then(() => {
|
||||
toolbox = inspector = page1 = page2 = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function loadPageAnd(page, callback) {
|
||||
inspector.once("new-root", () => {
|
||||
callback();
|
||||
});
|
||||
|
||||
if (page) {
|
||||
content.location = page;
|
||||
} else {
|
||||
content.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
function reloadAndReselect(id, callback) {
|
||||
let div = content.document.getElementById(id);
|
||||
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, div);
|
||||
|
||||
loadPageAnd(false, () => {
|
||||
is(inspector.selection.node.id, id, "Node re-selected after reload");
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
inspector.selection.setNode(div);
|
||||
}
|
||||
|
||||
// Test that nodes selected on the test page remain selected after reload
|
||||
function testSameNodeSelectedOnPageReload()
|
||||
// An array of test cases with following properties:
|
||||
// - url: URL to navigate to. If URL == content.location, reload instead.
|
||||
// - nodeToSelect: a selector for a node to select before navigation. If null,
|
||||
// whatever is selected stays selected.
|
||||
// - selectedNode: a selector for a node that is selected after navigation.
|
||||
let TEST_DATA = [
|
||||
{
|
||||
// Select a few nodes and check they are re-selected after reload of the same
|
||||
// page
|
||||
reloadAndReselect("id1", () => {
|
||||
reloadAndReselect("id2", () => {
|
||||
reloadAndReselect("id3", () => {
|
||||
reloadAndReselect("id4", testBodySelectedOnNavigate);
|
||||
});
|
||||
});
|
||||
});
|
||||
url: PAGE_1,
|
||||
nodeToSelect: "#id1",
|
||||
selectedNode: "#id1"
|
||||
},
|
||||
{
|
||||
url: PAGE_1,
|
||||
nodeToSelect: "#id2",
|
||||
selectedNode: "#id2"
|
||||
},
|
||||
{
|
||||
url: PAGE_1,
|
||||
nodeToSelect: "#id3",
|
||||
selectedNode: "#id3"
|
||||
},
|
||||
{
|
||||
url: PAGE_1,
|
||||
nodeToSelect: "#id4",
|
||||
selectedNode: "#id4"
|
||||
},
|
||||
{
|
||||
url: PAGE_2,
|
||||
nodeToSelect: null,
|
||||
selectedNode: "body"
|
||||
},
|
||||
{
|
||||
url: PAGE_1,
|
||||
nodeToSelect: "#id5",
|
||||
selectedNode: "body"
|
||||
},
|
||||
{
|
||||
url: PAGE_2,
|
||||
nodeToSelect: null,
|
||||
selectedNode: "body"
|
||||
}
|
||||
];
|
||||
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector } = yield openInspectorForURL(PAGE_1);
|
||||
|
||||
for (let { url, nodeToSelect, selectedNode } of TEST_DATA) {
|
||||
if (nodeToSelect) {
|
||||
info("Selecting node " + nodeToSelect + " before navigation.");
|
||||
yield selectNode(nodeToSelect, inspector);
|
||||
}
|
||||
|
||||
yield navigateToAndWaitForNewRoot(url);
|
||||
|
||||
info("Waiting for inspector to update after new-root event.");
|
||||
yield inspector.once("inspector-updated");
|
||||
|
||||
is(inspector.selection.node, getNode(selectedNode),
|
||||
selectedNode + " is selected after navigation.");
|
||||
}
|
||||
|
||||
// Test that since the previously selected node doesn't exist on the new page
|
||||
// the body is selected
|
||||
function testBodySelectedOnNavigate() {
|
||||
// Last node selected was id4, go to a different page and check body is
|
||||
// selected
|
||||
loadPageAnd(page2, () => {
|
||||
is(
|
||||
inspector.selection.node.tagName.toLowerCase(),
|
||||
"body",
|
||||
"Node not found, body selected"
|
||||
);
|
||||
testSameNodeSelectedOnNavigateAwayAndBack();
|
||||
});
|
||||
function navigateToAndWaitForNewRoot(url) {
|
||||
info("Navigating and waiting for new-root event after navigation.");
|
||||
let newRoot = inspector.once("new-root");
|
||||
|
||||
if (url == content.location) {
|
||||
info("Reloading page.");
|
||||
content.location.reload();
|
||||
} else {
|
||||
info("Navigating to " + url);
|
||||
content.location = url;
|
||||
}
|
||||
|
||||
return newRoot;
|
||||
}
|
||||
|
||||
// Test that the node selected on page 1 gets selected again after a navigation
|
||||
// is made to another page and back again
|
||||
function testSameNodeSelectedOnNavigateAwayAndBack() {
|
||||
// On page2, select id5
|
||||
let id = "id5";
|
||||
let div = content.document.getElementById(id);
|
||||
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node.id, id);
|
||||
|
||||
// go to page1 but do not select anything
|
||||
loadPageAnd(page1, () => {
|
||||
// go back to page2 and check id5 is still the current selection
|
||||
loadPageAnd(page2, () => {
|
||||
is(inspector.selection.node.id, id, "Node re-selected after navigation");
|
||||
endTests();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
inspector.selection.setNode(div);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,71 +1,34 @@
|
||||
/* 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";
|
||||
|
||||
let doc;
|
||||
let inspector;
|
||||
const TEST_URI = "data:text/html;charset=UTF-8," +
|
||||
"<h1>browser_inspector_sidebarstate.js</h1>";
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
doc.body.innerHTML = '<h1>Sidebar state test</h1>';
|
||||
doc.title = "Sidebar State Test";
|
||||
let test = asyncTest(function* () {
|
||||
let { inspector, toolbox } = yield openInspectorForURL(TEST_URI);
|
||||
|
||||
openInspector(function(panel) {
|
||||
inspector = panel;
|
||||
inspector.sidebar.select("ruleview");
|
||||
inspectorRuleViewOpened();
|
||||
});
|
||||
}
|
||||
info("Selecting ruleview.");
|
||||
inspector.sidebar.select("ruleview");
|
||||
|
||||
function inspectorRuleViewOpened()
|
||||
{
|
||||
is(inspector.sidebar.getCurrentTabID(), "ruleview", "Rule View is selected by default");
|
||||
is(inspector.sidebar.getCurrentTabID(), "ruleview",
|
||||
"Rule View is selected by default");
|
||||
|
||||
// Select the computed view and turn off the inspector.
|
||||
info("Selecting computed view.");
|
||||
inspector.sidebar.select("computedview");
|
||||
|
||||
gDevTools.once("toolbox-destroyed", inspectorClosed);
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.closeToolbox(target);
|
||||
}
|
||||
info("Closing inspector.");
|
||||
yield toolbox.destroy();
|
||||
|
||||
function inspectorClosed()
|
||||
{
|
||||
openInspector(function(panel) {
|
||||
inspector = panel;
|
||||
info("Re-opening inspector.");
|
||||
inspector = (yield openInspector()).inspector;
|
||||
|
||||
if (inspector.sidebar.getCurrentTabID()) {
|
||||
info("Default sidebar already selected.")
|
||||
testNewDefaultTab();
|
||||
} else {
|
||||
info("Default sidebar still to be selected, adding select listener.");
|
||||
inspector.sidebar.once("select", testNewDefaultTab);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!inspector.sidebar.getCurrentTabID()) {
|
||||
info("Default sidebar still to be selected, adding select listener.");
|
||||
yield inspector.sidebar.once("select");
|
||||
}
|
||||
|
||||
function testNewDefaultTab()
|
||||
{
|
||||
is(inspector.sidebar.getCurrentTabID(), "computedview", "Computed view is selected by default.");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
doc = inspector = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html;charset=utf-8,browser_inspector_sidebarstate.js";
|
||||
}
|
||||
is(inspector.sidebar.getCurrentTabID(), "computedview",
|
||||
"Computed view is selected by default.");
|
||||
});
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Ci = Components.interfaces;
|
||||
@ -13,8 +15,8 @@ const Cc = Components.classes;
|
||||
|
||||
//Services.prefs.setBoolPref("devtools.dump.emit", true);
|
||||
|
||||
const TEST_URL_ROOT = "http://example.com/browser/browser/devtools/inspector/test/";
|
||||
const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
|
||||
const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
|
||||
|
||||
// All test are asynchronous
|
||||
waitForExplicitFinish();
|
||||
@ -47,6 +49,22 @@ SimpleTest.registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.closeToolbox(target);
|
||||
|
||||
// Move the mouse outside inspector. If the test happened fake a mouse event
|
||||
// somewhere over inspector the pointer is considered to be there when the
|
||||
// next test begins. This might cause unexpected events to be emitted when
|
||||
// another test moves the mouse.
|
||||
EventUtils.synthesizeMouseAtPoint(1, 1, {type: "mousemove"}, window);
|
||||
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Define an async test based on a generator function
|
||||
*/
|
||||
@ -59,32 +77,59 @@ function asyncTest(generator) {
|
||||
* @param {String} url The url to be loaded in the new tab
|
||||
* @return a promise that resolves to the tab object when the url is loaded
|
||||
*/
|
||||
function addTab(url) {
|
||||
let def = promise.defer();
|
||||
|
||||
let addTab = Task.async(function* (url) {
|
||||
info("Adding a new tab with URL: '" + url + "'");
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
info("URL " + url + " loading complete into new test tab");
|
||||
waitForFocus(() => {
|
||||
def.resolve(tab);
|
||||
}, content);
|
||||
}, true);
|
||||
content.location = url;
|
||||
let loaded = once(gBrowser.selectedBrowser, "load", true);
|
||||
|
||||
return def.promise;
|
||||
}
|
||||
content.location = url;
|
||||
yield loaded;
|
||||
|
||||
info("URL '" + url + "' loading complete");
|
||||
|
||||
let def = promise.defer();
|
||||
let isBlank = url == "about:blank";
|
||||
waitForFocus(def.resolve, content, isBlank);
|
||||
|
||||
yield def.promise;
|
||||
|
||||
return tab;
|
||||
});
|
||||
|
||||
/**
|
||||
* Simple DOM node accesor function that takes either a node or a string css
|
||||
* selector as argument and returns the corresponding node
|
||||
* @param {String|DOMNode} nodeOrSelector
|
||||
* @param {Object} options
|
||||
* An object containing any of the following options:
|
||||
* - document: HTMLDocument that should be queried for the selector.
|
||||
* Default: content.document.
|
||||
* - expectNoMatch: If true and a node matches the given selector, a
|
||||
* failure is logged for an unexpected match.
|
||||
* If false and nothing matches the given selector, a
|
||||
* failure is logged for a missing match.
|
||||
* Default: false.
|
||||
* @return {DOMNode}
|
||||
*/
|
||||
function getNode(nodeOrSelector) {
|
||||
return typeof nodeOrSelector === "string" ?
|
||||
content.document.querySelector(nodeOrSelector) :
|
||||
nodeOrSelector;
|
||||
function getNode(nodeOrSelector, options = {}) {
|
||||
let document = options.document || content.document;
|
||||
let noMatches = !!options.expectNoMatch;
|
||||
|
||||
if (typeof nodeOrSelector === "string") {
|
||||
info("Looking for a node that matches selector " + nodeOrSelector);
|
||||
let node = document.querySelector(nodeOrSelector);
|
||||
if (noMatches) {
|
||||
ok(!node, "Selector " + nodeOrSelector + " didn't match any nodes.");
|
||||
}
|
||||
else {
|
||||
ok(node, "Selector " + nodeOrSelector + " matched a node.");
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
info("Looking for a node but selector was not a string.");
|
||||
return nodeOrSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,11 +147,25 @@ function getNode(nodeOrSelector) {
|
||||
function selectNode(nodeOrSelector, inspector, reason="test") {
|
||||
info("Selecting the node " + nodeOrSelector);
|
||||
let node = getNode(nodeOrSelector);
|
||||
let updated = inspector.once("inspector-updated");
|
||||
let updated = inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, node, "Correct node was selected");
|
||||
});
|
||||
inspector.selection.setNode(node, reason);
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the inspector in a tab with given URL.
|
||||
* @param {string} url The URL to open.
|
||||
* @return A promise that is resolved once the tab and inspector have loaded
|
||||
* with an object: { tab, toolbox, inspector }.
|
||||
*/
|
||||
let openInspectorForURL = Task.async(function* (url) {
|
||||
let tab = yield addTab(url);
|
||||
let { inspector, toolbox } = yield openInspector();
|
||||
return { tab, inspector, toolbox };
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible.
|
||||
* @param {Function} cb Optional callback, if you don't want to use the returned
|
||||
@ -169,61 +228,6 @@ function waitForToolboxFrameFocus(toolbox) {
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the sidebar that
|
||||
* corresponds to the given id selected
|
||||
* @return a promise that resolves when the inspector is ready and the sidebar
|
||||
* view is visible and ready
|
||||
*/
|
||||
let openInspectorSideBar = Task.async(function*(id) {
|
||||
let {toolbox, inspector} = yield openInspector();
|
||||
|
||||
if (!hasSideBarTab(inspector, id)) {
|
||||
info("Waiting for the " + id + " sidebar to be ready");
|
||||
yield inspector.sidebar.once(id + "-ready");
|
||||
}
|
||||
|
||||
info("Selecting the " + id + " sidebar");
|
||||
inspector.sidebar.select(id);
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector,
|
||||
view: inspector.sidebar.getWindowForTab(id)[id].view
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the computed-view
|
||||
* sidebar tab selected.
|
||||
* @return a promise that resolves when the inspector is ready and the computed
|
||||
* view is visible and ready
|
||||
*/
|
||||
function openComputedView() {
|
||||
return openInspectorSideBar("computedview");
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the rule-view
|
||||
* sidebar tab selected.
|
||||
* @return a promise that resolves when the inspector is ready and the rule
|
||||
* view is visible and ready
|
||||
*/
|
||||
function openRuleView() {
|
||||
return openInspectorSideBar("ruleview");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the inspector's sidebar corresponding to the given id already
|
||||
* exists
|
||||
* @param {InspectorPanel}
|
||||
* @param {String}
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function hasSideBarTab(inspector, id) {
|
||||
return !!inspector.sidebar.getWindowForTab(id);
|
||||
}
|
||||
|
||||
function getActiveInspector()
|
||||
{
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
@ -373,40 +377,8 @@ function getHighlitNode()
|
||||
}
|
||||
}
|
||||
|
||||
function computedView()
|
||||
{
|
||||
let sidebar = getActiveInspector().sidebar;
|
||||
let iframe = sidebar.tabbox.querySelector(".iframe-computedview");
|
||||
return iframe.contentWindow.computedView;
|
||||
}
|
||||
|
||||
function computedViewTree()
|
||||
{
|
||||
return computedView().view;
|
||||
}
|
||||
|
||||
function ruleView()
|
||||
{
|
||||
let sidebar = getActiveInspector().sidebar;
|
||||
let iframe = sidebar.tabbox.querySelector(".iframe-ruleview");
|
||||
return iframe.contentWindow.ruleView;
|
||||
}
|
||||
|
||||
function getComputedView() {
|
||||
let inspector = getActiveInspector();
|
||||
return inspector.sidebar.getWindowForTab("computedview").computedview.view;
|
||||
}
|
||||
|
||||
function waitForView(aName, aCallback) {
|
||||
let inspector = getActiveInspector();
|
||||
if (inspector.sidebar.getTab(aName)) {
|
||||
aCallback();
|
||||
} else {
|
||||
inspector.sidebar.once(aName + "-ready", aCallback);
|
||||
}
|
||||
}
|
||||
|
||||
function synthesizeKeyFromKeyTag(aKeyId) {
|
||||
function synthesizeKeyFromKeyTag(aKeyId, aDocument = null) {
|
||||
let document = aDocument || document;
|
||||
let key = document.getElementById(aKeyId);
|
||||
isnot(key, null, "Successfully retrieved the <key> node");
|
||||
|
||||
@ -432,53 +404,20 @@ function synthesizeKeyFromKeyTag(aKeyId) {
|
||||
EventUtils.synthesizeKey(name, modifiers);
|
||||
}
|
||||
|
||||
function focusSearchBoxUsingShortcut(panelWin, callback) {
|
||||
panelWin.focus();
|
||||
let key = panelWin.document.getElementById("nodeSearchKey");
|
||||
isnot(key, null, "Successfully retrieved the <key> node");
|
||||
|
||||
let modifiersAttr = key.getAttribute("modifiers");
|
||||
|
||||
let name = null;
|
||||
|
||||
if (key.getAttribute("keycode")) {
|
||||
name = key.getAttribute("keycode");
|
||||
} else if (key.getAttribute("key")) {
|
||||
name = key.getAttribute("key");
|
||||
}
|
||||
|
||||
isnot(name, null, "Successfully retrieved keycode/key");
|
||||
|
||||
let modifiers = {
|
||||
shiftKey: modifiersAttr.match("shift"),
|
||||
ctrlKey: modifiersAttr.match("ctrl"),
|
||||
altKey: modifiersAttr.match("alt"),
|
||||
metaKey: modifiersAttr.match("meta"),
|
||||
accelKey: modifiersAttr.match("accel")
|
||||
};
|
||||
|
||||
let focusSearchBoxUsingShortcut = Task.async(function* (panelWin, callback) {
|
||||
info("Focusing search box");
|
||||
let searchBox = panelWin.document.getElementById("inspector-searchbox");
|
||||
searchBox.addEventListener("focus", function onFocus() {
|
||||
searchBox.removeEventListener("focus", onFocus, false);
|
||||
callback && callback();
|
||||
}, false);
|
||||
EventUtils.synthesizeKey(name, modifiers);
|
||||
}
|
||||
let focused = once(searchBox, "focus");
|
||||
|
||||
function getComputedPropertyValue(aName)
|
||||
{
|
||||
let computedview = getComputedView();
|
||||
let props = computedview.styleDocument.querySelectorAll(".property-view");
|
||||
panelWin.focus();
|
||||
synthesizeKeyFromKeyTag("nodeSearchKey", panelWin.document);
|
||||
|
||||
for (let prop of props) {
|
||||
let name = prop.querySelector(".property-name");
|
||||
yield focused;
|
||||
|
||||
if (name.textContent === aName) {
|
||||
let value = prop.querySelector(".property-value");
|
||||
return value.textContent;
|
||||
}
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function isNodeCorrectlyHighlighted(node, prefix="") {
|
||||
let boxModel = getBoxModelStatus();
|
||||
@ -507,36 +446,33 @@ function getContainerForRawNode(markupView, rawNode)
|
||||
return container;
|
||||
}
|
||||
|
||||
SimpleTest.registerCleanupFunction(function () {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.closeToolbox(target);
|
||||
});
|
||||
|
||||
/**
|
||||
* Define an async test based on a generator function
|
||||
* Wait for eventName on target.
|
||||
* @param {Object} target An observable object that either supports on/off or
|
||||
* addEventListener/removeEventListener
|
||||
* @param {String} eventName
|
||||
* @param {Boolean} useCapture Optional, for addEventListener/removeEventListener
|
||||
* @return A promise that resolves when the event has been handled
|
||||
*/
|
||||
function asyncTest(generator) {
|
||||
return () => Task.spawn(generator).then(null, ok.bind(null, false)).then(finish);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new test tab in the browser and load the given url.
|
||||
* @param {String} url The url to be loaded in the new tab
|
||||
* @return a promise that resolves to the tab object when the url is loaded
|
||||
*/
|
||||
function addTab(url) {
|
||||
info("Adding a new tab with URL: '" + url + "'");
|
||||
let def = promise.defer();
|
||||
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onload() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||
info("URL '" + url + "' loading complete");
|
||||
waitForFocus(() => {
|
||||
def.resolve(tab);
|
||||
}, content);
|
||||
}, true);
|
||||
content.location = url;
|
||||
|
||||
return def.promise;
|
||||
function once(target, eventName, useCapture=false) {
|
||||
info("Waiting for event: '" + eventName + "' on " + target + ".");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
for (let [add, remove] of [
|
||||
["addEventListener", "removeEventListener"],
|
||||
["addListener", "removeListener"],
|
||||
["on", "off"]
|
||||
]) {
|
||||
if ((add in target) && (remove in target)) {
|
||||
target[add](eventName, function onEvent(...aArgs) {
|
||||
info("Got event: '" + eventName + "' on " + target + ".");
|
||||
target[remove](eventName, onEvent, useCapture);
|
||||
deferred.resolve.apply(deferred, aArgs);
|
||||
}, useCapture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user