bug 1034601 - Enable devtools/markupview tests with e10s; r=bgrins

This commit is contained in:
Patrick Brosset 2014-07-16 22:17:30 +02:00
Родитель 2373e5e978
Коммит 7fda3ce229
29 изменённых файлов: 427 добавлений и 349 удалений

Просмотреть файл

@ -596,8 +596,8 @@ HTMLBreadcrumbs.prototype = {
if (this.currentIndex == this.nodeHierarchy.length - 1) {
let node = this.nodeHierarchy[this.currentIndex].node;
return this.getInterestingFirstNode(node).then(child => {
// If the node has a child
if (child) {
// If the node has a child and we've not been destroyed in the meantime
if (child && !this.isDestroyed) {
// Show this child
this.expand(child);
}

Просмотреть файл

@ -1,5 +1,4 @@
[DEFAULT]
skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
subsuite = devtools
support-files =
doc_markup_edit.html
@ -19,8 +18,11 @@ support-files =
[browser_markupview_copy_image_data.js]
[browser_markupview_css_completion_style_attribute.js]
[browser_markupview_highlight_hover_01.js]
skip-if = e10s # Bug 985597 - The XUL-based highlighter isn't e10s compatible
[browser_markupview_highlight_hover_02.js]
skip-if = e10s # Bug 985597 - The XUL-based highlighter isn't e10s compatible
[browser_markupview_highlight_hover_03.js]
skip-if = e10s # Bug 985597 - The XUL-based highlighter isn't e10s compatible
[browser_markupview_html_edit_01.js]
[browser_markupview_html_edit_02.js]
[browser_markupview_html_edit_03.js]
@ -32,10 +34,12 @@ support-files =
[browser_markupview_node_not_displayed_02.js]
[browser_markupview_pagesize_01.js]
[browser_markupview_pagesize_02.js]
skip-if = e10s # Bug 1036409 - The last selected node isn't reselected
[browser_markupview_search_01.js]
[browser_markupview_tag_edit_01.js]
[browser_markupview_tag_edit_02.js]
[browser_markupview_tag_edit_03.js]
skip-if = e10s # Bug 1036421 - Tag editing isn't remote-safe
[browser_markupview_tag_edit_04.js]
[browser_markupview_tag_edit_05.js]
[browser_markupview_tag_edit_06.js]

Просмотреть файл

@ -69,15 +69,16 @@ let test = asyncTest(function*() {
yield inspector.markup.expandAll();
let node = getContainerForRawNode("#node14", inspector).editor;
let attr = node.newAttr;
let nodeFront = yield getNodeFront("#node14", inspector);
let container = getContainerForNodeFront(nodeFront, inspector);
let attr = container.editor.newAttr;
attr.focus();
EventUtils.sendKey("return", inspector.panelWin);
let editor = inplaceEditor(attr);
for (let i = 0; i < TEST_DATA.length; i ++) {
yield enterData(i, editor, inspector);
checkData(i, editor, inspector);
yield checkData(i, editor, inspector);
}
while (inspector.markup.undo.canUndo()) {
@ -122,7 +123,7 @@ function enterData(index, editor, inspector) {
return def.promise;
}
function checkData(index, editor, inspector) {
function* checkData(index, editor, inspector) {
let [key, completion, selStart, selEnd, popupOpen] = TEST_DATA[index];
info("Test data " + index + " entered. Checking state.");
@ -137,7 +138,8 @@ function checkData(index, editor, inspector) {
"Popup is closed");
}
} else {
let editor = getContainerForRawNode("#node14", inspector).editor;
let nodeFront = yield getNodeFront("#node14", inspector);
let editor = getContainerForNodeFront(nodeFront, inspector).editor;
let attr = editor.attrs["style"].querySelector(".editable");
is(attr.textContent, completion, "Correct value is persisted after pressing Enter");
}

Просмотреть файл

@ -13,11 +13,11 @@ let test = asyncTest(function*() {
let p = getNode("p");
info("hovering over the <p> line in the markup-view");
yield hoverContainer(p, inspector);
yield hoverContainer("p", inspector);
ok(isHighlighterVisible(), "the highlighter is still visible");
info("selecting the <p> line by clicking in the markup-view");
yield clickContainer(p, inspector);
yield clickContainer("p", inspector);
p.textContent = "wait for it ....";
info("wait and see if the highlighter stays visible even after the node was selected");

Просмотреть файл

@ -29,13 +29,14 @@ let test = asyncTest(function*() {
return promise.resolve();
};
function isHighlighting(node, desc) {
is(highlightedNode, getContainerForRawNode(node, inspector).node, desc);
function* isHighlighting(selector, desc) {
let nodeFront = yield getNodeFront(selector, inspector);
is(highlightedNode, nodeFront, desc);
}
info("Hover over <p#one> line in the markup-view");
yield hoverContainer("#one", inspector);
isHighlighting(getNode("#one"), "<p#one> is highlighted");
yield isHighlighting("#one", "<p#one> is highlighted");
info("Navigate to <p#two> with the keyboard");
let onUpdated = inspector.once("inspector-updated");
@ -44,11 +45,11 @@ let test = asyncTest(function*() {
let onUpdated = inspector.once("inspector-updated");
EventUtils.synthesizeKey("VK_DOWN", {});
yield onUpdated;
isHighlighting(getNode("#two"), "<p#two> is highlighted");
yield isHighlighting("#two", "<p#two> is highlighted");
info("Navigate back to <p#one> with the keyboard");
let onUpdated = inspector.once("inspector-updated");
EventUtils.synthesizeKey("VK_UP", {});
yield onUpdated;
isHighlighting(getNode("#one"), "<p#one> is highlighted again");
yield isHighlighting("#one", "<p#one> is highlighted again");
});

Просмотреть файл

@ -13,7 +13,7 @@ const TEST_DATA = [
selector: "#one",
oldHTML: '<div id="one">First <em>Div</em></div>',
newHTML: '<div id="one">First Div</div>',
validate: function(pageNode, selectedNode) {
validate: function*(pageNode, pageNodeFront, selectedNodeFront) {
is(pageNode.textContent, "First Div", "New div has expected text content");
ok(!getNode("#one em"), "No em remaining")
}
@ -32,8 +32,8 @@ const TEST_DATA = [
selector: "#addedAttribute",
oldHTML: '<div id="addedAttribute">addedAttribute</div>',
newHTML: '<div id="addedAttribute" class="important" disabled checked>addedAttribute</div>',
validate: function(pageNode, selectedNode) {
is(pageNode, selectedNode, "Original element is selected");
validate: function*(pageNode, pageNodeFront, selectedNodeFront) {
is(pageNodeFront, selectedNodeFront, "Original element is selected");
is(pageNode.outerHTML, '<div id="addedAttribute" class="important" disabled="" checked="">addedAttribute</div>',
"Attributes have been added");
}
@ -49,14 +49,15 @@ const TEST_DATA = [
newHTML: '<div id="siblings-before-sibling">before sibling</div>' +
'<div id="siblings">siblings (updated)</div>' +
'<div id="siblings-after-sibling">after sibling</div>',
validate: function(pageNode, selectedNode) {
let beforeSiblingNode = getNode("#siblings-before-sibling");
let afterSiblingNode = getNode("#siblings-after-sibling");
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
let beforeSibling = getNode("#siblings-before-sibling");
let beforeSiblingFront = yield getNodeFront("#siblings-before-sibling", inspector);
let afterSibling = getNode("#siblings-after-sibling");
is(beforeSiblingNode, selectedNode, "Sibling has been selected");
is(beforeSiblingFront, selectedNodeFront, "Sibling has been selected");
is(pageNode.textContent, "siblings (updated)", "New div has expected text content");
is(beforeSiblingNode.textContent, "before sibling", "Sibling has been inserted");
is(afterSiblingNode.textContent, "after sibling", "Sibling has been inserted");
is(beforeSibling.textContent, "before sibling", "Sibling has been inserted");
is(afterSibling.textContent, "after sibling", "Sibling has been inserted");
}
}
];

Просмотреть файл

@ -13,8 +13,8 @@ const TEST_DATA = [
selector: "#badMarkup1",
oldHTML: '<div id="badMarkup1">badMarkup1</div>',
newHTML: '<div id="badMarkup1">badMarkup1</div> hanging</div>',
validate: function(pageNode, selectedNode) {
is(pageNode, selectedNode, "Original element is selected");
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
is(pageNodeFront, selectedNodeFront, "Original element is selected");
let textNode = pageNode.nextSibling;
@ -26,8 +26,8 @@ const TEST_DATA = [
selector: "#badMarkup2",
oldHTML: '<div id="badMarkup2">badMarkup2</div>',
newHTML: '<div id="badMarkup2">badMarkup2</div> hanging<div></div></div></div></body>',
validate: function(pageNode, selectedNode) {
is(pageNode, selectedNode, "Original element is selected");
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
is(pageNodeFront, selectedNodeFront, "Original element is selected");
let textNode = pageNode.nextSibling;
@ -39,8 +39,8 @@ const TEST_DATA = [
selector: "#badMarkup3",
oldHTML: '<div id="badMarkup3">badMarkup3</div>',
newHTML: '<div id="badMarkup3">badMarkup3 <em>Emphasized <strong> and strong</div>',
validate: function(pageNode, selectedNode) {
is(pageNode, selectedNode, "Original element is selected");
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
is(pageNodeFront, selectedNodeFront, "Original element is selected");
let em = getNode("#badMarkup3 em");
let strong = getNode("#badMarkup3 strong");
@ -53,8 +53,8 @@ const TEST_DATA = [
selector: "#badMarkup4",
oldHTML: '<div id="badMarkup4">badMarkup4</div>',
newHTML: '<div id="badMarkup4">badMarkup4</p>',
validate: function(pageNode, selectedNode) {
is(pageNode, selectedNode, "Original element is selected");
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
is(pageNodeFront, selectedNodeFront, "Original element is selected");
let div = getNode("#badMarkup4");
let p = getNode("#badMarkup4 p");
@ -69,8 +69,8 @@ const TEST_DATA = [
selector: "#badMarkup5",
oldHTML: '<p id="badMarkup5">badMarkup5</p>',
newHTML: '<p id="badMarkup5">badMarkup5 <div>with a nested div</div></p>',
validate: function(pageNode, selectedNode) {
is(pageNode, selectedNode, "Original element is selected");
validate: function*(pageNode, pageNodeFront, selectedNodeFront, inspector) {
is(pageNodeFront, selectedNodeFront, "Original element is selected");
let p = getNode("#badMarkup5");
let nodiv = getNode("#badMarkup5 div");

Просмотреть файл

@ -46,7 +46,7 @@ function testEscapeCancels(inspector) {
let def = promise.defer();
let node = getNode(SELECTOR);
selectNode(node, inspector).then(() => {
selectNode(SELECTOR, inspector).then(() => {
inspector.markup.htmlEditor.on("popupshown", function onPopupShown() {
inspector.markup.htmlEditor.off("popupshown", onPopupShown);
@ -101,80 +101,82 @@ function testF2Commits(inspector) {
return def.promise;
}
function testBody(inspector) {
function* testBody(inspector) {
let body = getNode("body");
let bodyHTML = '<body id="updated"><p></p></body>';
let bodyFront = inspector.markup.walker.frontForRawNode(body);
let bodyFront = yield getNodeFront("body", inspector);
let doc = content.document;
let mutated = inspector.once("markupmutation");
inspector.markup.updateNodeOuterHTML(bodyFront, bodyHTML, body.outerHTML);
return mutated.then(mutations => {
is(getNode("body").outerHTML, bodyHTML, "<body> HTML has been updated");
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
return inspector.once("inspector-updated");
});
let mutations = yield mutated;
is(getNode("body").outerHTML, bodyHTML, "<body> HTML has been updated");
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
yield inspector.once("inspector-updated");
}
function testHead(inspector) {
function* testHead(inspector) {
let head = getNode("head");
let headHTML = '<head id="updated"><title>New Title</title><script>window.foo="bar";</script></head>';
let headFront = inspector.markup.walker.frontForRawNode(head);
let headFront = yield getNodeFront("head", inspector);
let doc = content.document;
let mutated = inspector.once("markupmutation");
inspector.markup.updateNodeOuterHTML(headFront, headHTML, head.outerHTML);
return mutated.then(mutations => {
is(doc.title, "New Title", "New title has been added");
is(doc.defaultView.foo, undefined, "Script has not been executed");
is(doc.querySelector("head").outerHTML, headHTML, "<head> HTML has been updated");
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
return inspector.once("inspector-updated");
});
let mutations = yield mutated;
is(doc.title, "New Title", "New title has been added");
is(doc.defaultView.foo, undefined, "Script has not been executed");
is(doc.querySelector("head").outerHTML, headHTML, "<head> HTML has been updated");
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
yield inspector.once("inspector-updated");
}
function testDocumentElement(inspector) {
function* testDocumentElement(inspector) {
let doc = content.document;
let docElement = doc.documentElement;
let docElementHTML = '<html id="updated" foo="bar"><head><title>Updated from document element</title><script>window.foo="bar";</script></head><body><p>Hello</p></body></html>';
let docElementFront = inspector.markup.walker.frontForRawNode(docElement);
let docElementFront = yield inspector.markup.walker.documentElement();
let mutated = inspector.once("markupmutation");
inspector.markup.updateNodeOuterHTML(docElementFront, docElementHTML, docElement.outerHTML);
return mutated.then(mutations => {
is(doc.title, "Updated from document element", "New title has been added");
is(doc.defaultView.foo, undefined, "Script has not been executed");
is(doc.documentElement.id, "updated", "<html> ID has been updated");
is(doc.documentElement.className, "", "<html> class has been updated");
is(doc.documentElement.getAttribute("foo"), "bar", "<html> attribute has been updated");
is(doc.documentElement.outerHTML, docElementHTML, "<html> HTML has been updated");
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
is(doc.body.textContent, "Hello", "document.body.textContent has been updated");
});
let mutations = yield mutated;
is(doc.title, "Updated from document element", "New title has been added");
is(doc.defaultView.foo, undefined, "Script has not been executed");
is(doc.documentElement.id, "updated", "<html> ID has been updated");
is(doc.documentElement.className, "", "<html> class has been updated");
is(doc.documentElement.getAttribute("foo"), "bar", "<html> attribute has been updated");
is(doc.documentElement.outerHTML, docElementHTML, "<html> HTML has been updated");
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
is(doc.body.textContent, "Hello", "document.body.textContent has been updated");
}
function testDocumentElement2(inspector) {
function* testDocumentElement2(inspector) {
let doc = content.document;
let docElement = doc.documentElement;
let docElementHTML = '<html class="updated" id="somethingelse"><head><title>Updated again from document element</title><script>window.foo="bar";</script></head><body><p>Hello again</p></body></html>';
let docElementFront = inspector.markup.walker.frontForRawNode(docElement);
let docElementFront = yield inspector.markup.walker.documentElement();
let mutated = inspector.once("markupmutation");
inspector.markup.updateNodeOuterHTML(docElementFront, docElementHTML, docElement.outerHTML);
return mutated.then(mutations => {
is(doc.title, "Updated again from document element", "New title has been added");
is(doc.defaultView.foo, undefined, "Script has not been executed");
is(doc.documentElement.id, "somethingelse", "<html> ID has been updated");
is(doc.documentElement.className, "updated", "<html> class has been updated");
is(doc.documentElement.getAttribute("foo"), null, "<html> attribute has been removed");
is(doc.documentElement.outerHTML, docElementHTML, "<html> HTML has been updated");
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
is(doc.body.textContent, "Hello again", "document.body.textContent has been updated");
});
let mutations = yield mutated;
is(doc.title, "Updated again from document element", "New title has been added");
is(doc.defaultView.foo, undefined, "Script has not been executed");
is(doc.documentElement.id, "somethingelse", "<html> ID has been updated");
is(doc.documentElement.className, "updated", "<html> class has been updated");
is(doc.documentElement.getAttribute("foo"), null, "<html> attribute has been removed");
is(doc.documentElement.outerHTML, docElementHTML, "<html> HTML has been updated");
is(doc.querySelectorAll("head").length, 1, "no extra <head>s have been added");
is(doc.querySelectorAll("body").length, 1, "no extra <body>s have been added");
is(doc.body.textContent, "Hello again", "document.body.textContent has been updated");
}

Просмотреть файл

@ -32,7 +32,7 @@ let test = asyncTest(function*() {
yield selectNode("img", inspector);
for (let testNode of TEST_NODES) {
let target = getImageTooltipTarget(testNode, inspector);
let target = yield getImageTooltipTarget(testNode, inspector);
yield assertTooltipShownOn(target, inspector);
checkImageTooltip(testNode, inspector);
}
@ -55,11 +55,11 @@ function createPage() {
context.fill();
}
function getImageTooltipTarget({selector}, inspector) {
let node = getNode(selector);
let isImg = node.tagName.toLowerCase() === "img";
function* getImageTooltipTarget({selector}, inspector) {
let nodeFront = yield getNodeFront(selector, inspector);
let isImg = nodeFront.tagName.toLowerCase() === "img";
let container = getContainerForRawNode(node, inspector);
let container = getContainerForNodeFront(nodeFront, inspector);
let target = container.editor.tag;
if (isImg) {
@ -68,12 +68,10 @@ function getImageTooltipTarget({selector}, inspector) {
return target;
}
function assertTooltipShownOn(element, {markup}) {
return Task.spawn(function*() {
info("Is the element a valid hover target");
let isValid = yield markup.tooltip.isValidHoverTarget(element);
ok(isValid, "The element is a valid hover target for the image tooltip");
});
function* assertTooltipShownOn(element, {markup}) {
info("Is the element a valid hover target");
let isValid = yield markup.tooltip.isValidHoverTarget(element);
ok(isValid, "The element is a valid hover target for the image tooltip");
}
function checkImageTooltip({selector, size}, {markup}) {

Просмотреть файл

@ -5,20 +5,25 @@
"use strict";
// Tests that various mutations to the dom update the markup view correctly.
// The test for comparing the markup view to the real dom is a bit weird:
// - Select the text in the markup view
// - Parse that as innerHTML in a document we've created for the purpose.
// - Remove extraneous whitespace in that tree
// - Compare it to the real dom with isEqualNode.
const TEST_URL = TEST_URL_ROOT + "doc_markup_mutation.html";
// All the mutation types we want to test.
// Mutation tests. Each entry in the array has the following properties:
// - desc: for logging only
// - test: a function supposed to mutate the DOM
// - check: a function supposed to test that the mutation was handled
const TEST_DATA = [
{
desc: "Adding an attribute",
test: () => {
let node1 = getNode("#node1");
node1.setAttribute("newattr", "newattrval");
},
check: function*(inspector) {
let {editor} = yield getContainerForSelector("#node1", inspector);
ok([...editor.attrList.querySelectorAll(".attreditor")].some(attr => {
return attr.textContent.trim() === "newattr=\"newattrval\"";
}), "newattr attribute found");
}
},
{
@ -26,6 +31,15 @@ const TEST_DATA = [
test: () => {
let node1 = getNode("#node1");
node1.removeAttribute("newattr");
},
check: function*(inspector) {
// The markup-view is a little weird in that it doesn't remove the
// attribute but only hides it with display:none
let {editor} = yield getContainerForSelector("#node1", inspector);
ok([...editor.attrList.querySelectorAll(".attreditor")].some(attr => {
return attr.textContent.trim() === "newattr=\"newattrval\"" &&
attr.style.display === "none";
}), "newattr attribute removed");
}
},
{
@ -33,6 +47,11 @@ const TEST_DATA = [
test: () => {
let node1 = getNode("#node1");
node1.textContent = "newtext";
},
check: function*(inspector) {
let {children} = yield getContainerForSelector("#node1", inspector);
is(children.querySelector(".text").textContent.trim(), "newtext",
"The new textcontent was updated");
}
},
{
@ -40,6 +59,17 @@ const TEST_DATA = [
test: () => {
let node2 = getNode("#node2");
node2.innerHTML = "<div><span>foo</span></div>";
},
check: function*(inspector) {
let container = yield getContainerForSelector("#node2", inspector);
let openTags = container.children.querySelectorAll(".open .tag");
is(openTags.length, 2, "There are 2 tags in node2");
is(openTags[0].textContent.trim(), "div", "The first tag is a div");
is(openTags[1].textContent.trim(), "span", "The second tag is a span");
is(container.children.querySelector(".text").textContent.trim(), "foo",
"The span's textcontent is correct");
}
},
{
@ -49,14 +79,27 @@ const TEST_DATA = [
while (node4.firstChild) {
node4.removeChild(node4.firstChild);
}
},
check: function*(inspector) {
let {children} = yield getContainerForSelector("#node4", inspector);
is(children.innerHTML, "", "Children have been removed");
}
},
{
desc: "Appending a child to a different parent",
test: () => {
let node17 = getNode("#node17");
let node1 = getNode("#node2");
node1.appendChild(node17);
let node2 = getNode("#node2");
node2.appendChild(node17);
},
check: function*(inspector) {
let {children} = yield getContainerForSelector("#node16", inspector);
is(children.innerHTML, "", "Node17 has been removed from its node16 parent");
let container = yield getContainerForSelector("#node2", inspector);
let openTags = container.children.querySelectorAll(".open .tag");
is(openTags.length, 3, "There are now 3 tags in node2");
is(openTags[2].textContent.trim(), "p", "The third tag is node17");
}
},
{
@ -82,73 +125,46 @@ const TEST_DATA = [
node1.appendChild(node20);
node20.appendChild(node18);
},
check: function*(inspector) {
let {children} = yield getContainerForSelector("#node1", inspector);
is(children.childNodes.length, 2,
"Node1 now has 2 children (textnode and node20)");
let node20 = children.childNodes[1];
let node20Children = node20.querySelector(".children")
is(node20Children.childNodes.length, 2, "Node20 has 2 children (21 and 18)");
let node21 = node20Children.childNodes[0];
is(node21.querySelector(".children").textContent.trim(), "line21",
"Node21 only has a text node child");
let node18 = node20Children.childNodes[1];
is(node18.querySelector(".open .attreditor .attr-value").textContent.trim(),
"node18", "Node20's second child is indeed node18");
}
}
];
let test = asyncTest(function*() {
info("Creating the helper tab for parsing");
let parseTab = yield addTab("data:text/html,<html></html>");
let parseDoc = content.document;
info("Creating the test tab");
let contentTab = yield addTab(TEST_URL);
let doc = content.document;
// Strip whitespace in the document for easier comparison
stripWhitespace(doc.documentElement);
let {inspector} = yield openInspector();
let markup = inspector.markup;
let {toolbox, inspector} = yield addTab(TEST_URL).then(openInspector);
info("Expanding all markup-view nodes");
yield markup.expandAll();
yield inspector.markup.expandAll();
for (let step of TEST_DATA) {
info("Starting test: " + step.desc);
for (let {desc, test, check} of TEST_DATA) {
info("Starting test: " + desc);
info("Executing the test markup mutation, listening for inspector-updated before moving on");
let updated = inspector.once("inspector-updated");
step.test();
yield updated;
info("Executing the test markup mutation");
let onUpdated = inspector.once("inspector-updated");
let onMutation = inspector.once("markupmutation");
test();
yield onUpdated.then(onMutation);
info("Expanding all markup-view nodes to make sure new nodes are imported");
yield markup.expandAll();
yield inspector.markup.expandAll();
info("Comparing the markup-view markup with the content document");
compareMarkup(parseDoc, inspector);
info("Checking the markup-view content");
yield check(inspector);
}
});
function stripWhitespace(node) {
node.normalize();
let iter = node.ownerDocument.createNodeIterator(node,
NodeFilter.SHOW_TEXT + NodeFilter.SHOW_COMMENT, null);
while ((node = iter.nextNode())) {
node.nodeValue = node.nodeValue.replace(/\s+/g, '');
if (node.nodeType == Node.TEXT_NODE &&
!/[^\s]/.exec(node.nodeValue)) {
node.parentNode.removeChild(node);
}
}
}
function compareMarkup(parseDoc, inspector) {
// Grab the text from the markup panel...
let markupContainerEl = getContainerForRawNode("body", inspector).elt;
let sel = markupContainerEl.ownerDocument.defaultView.getSelection();
sel.selectAllChildren(markupContainerEl);
// Parse it
let parseNode = parseDoc.querySelector("body");
parseNode.outerHTML = sel;
parseNode = parseDoc.querySelector("body");
// Pull whitespace out of text and comment nodes, there will
// be minor unimportant differences.
stripWhitespace(parseNode);
// console.log(contentNode.innerHTML, parseNode.innerHTML);
ok(getNode("body").isEqualNode(parseNode),
"Markup panel matches what's in the content document.");
}

Просмотреть файл

@ -8,11 +8,14 @@
// corresponding DOM nodes mutate
const TEST_URL = TEST_URL_ROOT + "doc_markup_flashing.html";
// The test data contains a list of mutations to test.
// Each item is an object:
// - desc: a description of the test step, for better logging
// - mutate: a function that should make changes to the content DOM
// - shouldFlash: a function that returns the element that should be the one flashing
// - flashedNode: [optional] the css selector of the node that is expected to
// flash in the markup-view as a result of the mutation.
// If missing, the rootNode (".list") will be expected to flash
const TEST_DATA = [{
desc: "Adding a new node should flash the new node",
mutate: (doc, rootNode) => {
@ -20,37 +23,33 @@ const TEST_DATA = [{
newLi.textContent = "new list item";
rootNode.appendChild(newLi);
},
shouldFlash: rootNode => rootNode.lastElementChild
flashedNode: ".list li:nth-child(3)"
}, {
desc: "Removing a node should flash its parent",
mutate: (doc, rootNode) => {
rootNode.removeChild(rootNode.lastElementChild);
},
shouldFlash: rootNode => rootNode
}
}, {
desc: "Re-appending an existing node should only flash this node",
mutate: (doc, rootNode) => {
rootNode.appendChild(rootNode.firstElementChild);
},
shouldFlash: rootNode => rootNode.lastElementChild
flashedNode: ".list .item:last-child"
}, {
desc: "Adding an attribute should flash the node",
mutate: (doc, rootNode) => {
rootNode.setAttribute("name-" + Date.now(), "value-" + Date.now());
},
shouldFlash: rootNode => rootNode
}
}, {
desc: "Editing an attribute should flash the node",
mutate: (doc, rootNode) => {
rootNode.setAttribute("class", "list value-" + Date.now());
},
shouldFlash: rootNode => rootNode
}
}, {
desc: "Removing an attribute should flash the node",
mutate: (doc, rootNode) => {
rootNode.removeAttribute("class");
},
shouldFlash: rootNode => rootNode
}
}];
let test = asyncTest(function*() {
@ -58,11 +57,12 @@ let test = asyncTest(function*() {
info("Getting the <ul.list> root node to test mutations on");
let rootNode = getNode(".list");
let rootNodeFront = yield getNodeFront(".list", inspector);
info("Selecting the last element of the root node before starting");
yield selectNode(rootNode.lastElementChild, inspector);
yield selectNode(".list .item:nth-child(2)", inspector);
for (let {mutate, shouldFlash, desc} of TEST_DATA) {
for (let {mutate, flashedNode, desc} of TEST_DATA) {
info("Starting test: " + desc);
info("Mutating the DOM and listening for markupmutation event");
@ -72,20 +72,20 @@ let test = asyncTest(function*() {
yield mutated;
info("Asserting that the correct markup-container is flashing");
assertNodeFlashing(shouldFlash(rootNode), inspector);
let flashingNodeFront = rootNodeFront;
if (flashedNode) {
flashingNodeFront = yield getNodeFront(flashedNode, inspector);
}
yield assertNodeFlashing(flashingNodeFront, inspector);
// Making sure the inspector has finished updating before moving on
yield updated;
}
});
function assertNodeFlashing(node, inspector) {
let container = getContainerForRawNode(node, inspector);
if (!container) {
ok(false, "Node not found");
} else {
ok(container.tagState.classList.contains("theme-bg-contrast"),
"Node is flashing");
}
function* assertNodeFlashing(nodeFront, inspector) {
let container = getContainerForNodeFront(nodeFront, inspector);
ok(container, "Markup container for node found");
ok(container.tagState.classList.contains("theme-bg-contrast"),
"Markup container for node is flashing");
}

Просмотреть файл

@ -114,7 +114,7 @@ function pressKey(key) {
}
function checkSelectedNode(key, className, inspector) {
let node = inspector.selection.node;
let node = inspector.selection.nodeFront;
if (className == "*comment*") {
is(node.nodeType, Node.COMMENT_NODE, "Found a comment after pressing " + key);

Просмотреть файл

@ -26,7 +26,8 @@ let test = asyncTest(function*() {
for (let {selector, isDisplayed} of TEST_DATA) {
info("Getting node " + selector);
let container = getContainerForRawNode(selector, inspector);
let nodeFront = yield getNodeFront(selector, inspector);
let container = getContainerForNodeFront(nodeFront, inspector);
is(!container.elt.classList.contains("not-displayed"), isDisplayed,
"The container for " + selector + " is marked as displayed " + isDisplayed);
}

Просмотреть файл

@ -98,35 +98,33 @@ let test = asyncTest(function*() {
}
});
function runTestData(inspector, {selector, before, changeStyle, after}) {
let def = promise.defer();
function* runTestData(inspector, {selector, before, changeStyle, after}) {
info("Getting the " + selector + " test node");
let container = getContainerForRawNode(selector, inspector);
let nodeFront = yield getNodeFront(selector, inspector);
let container = getContainerForNodeFront(nodeFront, inspector);
is(!container.elt.classList.contains("not-displayed"), before,
"The container is marked as " + (before ? "shown" : "hidden"));
info("Listening for the display-change event");
inspector.markup.walker.once("display-change", nodes => {
info("Verifying that the list of changed nodes include our container");
ok(nodes.length, "The display-change event was received with a nodes");
let foundContainer = false;
for (let node of nodes) {
if (inspector.markup.getContainer(node) === container) {
foundContainer = true;
break;
}
}
ok(foundContainer, "Container is part of the list of changed nodes");
is(!container.elt.classList.contains("not-displayed"), after,
"The container is marked as " + (after ? "shown" : "hidden"));
def.resolve();
});
let onDisplayChanged = promise.defer();
inspector.markup.walker.once("display-change", onDisplayChanged.resolve);
info("Making style changes");
changeStyle(content.document, getNode(selector));
let nodes = yield onDisplayChanged.promise;
return def.promise;
info("Verifying that the list of changed nodes include our container");
ok(nodes.length, "The display-change event was received with a nodes");
let foundContainer = false;
for (let node of nodes) {
if (getContainerForNodeFront(node, inspector) === container) {
foundContainer = true;
break;
}
}
ok(foundContainer, "Container is part of the list of changed nodes");
is(!container.elt.classList.contains("not-displayed"), after,
"The container is marked as " + (after ? "shown" : "hidden"));
}

Просмотреть файл

@ -45,23 +45,23 @@ let test = asyncTest(function*() {
info("Start test: " + step.desc);
if (step.forceReload) {
forceReload(inspector);
yield forceReload(inspector);
}
info("Selecting the node that corresponds to " + step.selector);
yield selectNode(step.selector, inspector);
info("Checking that the right nodes are shwon");
assertChildren(step.expected, inspector);
yield assertChildren(step.expected, inspector);
}
info("Checking that clicking the more button loads everything");
clickShowMoreNodes(inspector);
yield clickShowMoreNodes(inspector);
yield inspector.markup._waitForChildren();
assertChildren("abcdefghijklmnopqrstuvwxyz", inspector);
yield assertChildren("abcdefghijklmnopqrstuvwxyz", inspector);
});
function assertChildren(expected, inspector) {
let container = getContainerForRawNode("body", inspector);
function* assertChildren(expected, inspector) {
let container = yield getContainerForSelector("body", inspector);
let found = "";
for (let child of container.children.children) {
if (child.classList.contains("more-nodes")) {
@ -73,13 +73,13 @@ function assertChildren(expected, inspector) {
is(found, expected, "Got the expected children.");
}
function forceReload(inspector) {
let container = getContainerForRawNode("body", inspector);
function* forceReload(inspector) {
let container = yield getContainerForSelector("body", inspector);
container.childrenDirty = true;
}
function clickShowMoreNodes(inspector) {
let container = getContainerForRawNode("body", inspector);
function* clickShowMoreNodes(inspector) {
let container = yield getContainerForSelector("body", inspector);
let button = container.elt.querySelector("button");
let win = button.ownerDocument.defaultView;
EventUtils.sendMouseEvent({type: "click"}, button, win);

Просмотреть файл

@ -25,22 +25,21 @@ let test = asyncTest(function*() {
info("Click on the 'show all nodes' button in the UL's list of children");
yield showAllNodes(inspector);
assertAllNodesAreVisible(inspector);
yield assertAllNodesAreVisible(inspector);
});
function showAllNodes(inspector) {
let container = getContainerForRawNode("ul", inspector);
function* showAllNodes(inspector) {
let container = yield getContainerForSelector("ul", inspector);
let button = container.elt.querySelector("button");
ok(button, "All nodes button is here");
let win = button.ownerDocument.defaultView;
EventUtils.sendMouseEvent({type: "click"}, button, win);
return inspector.markup._waitForChildren();
yield inspector.markup._waitForChildren();
}
function assertAllNodesAreVisible(inspector) {
let ul = getNode("ul");
let container = getContainerForRawNode(ul, inspector);
function* assertAllNodesAreVisible(inspector) {
let container = yield getContainerForSelector("ul", inspector);
ok(!container.elt.querySelector("button"), "All nodes button isn't here anymore");
is(container.children.childNodes.length, ul.children.length);
is(container.children.childNodes.length, getNode("ul").children.length);
}

Просмотреть файл

@ -13,8 +13,8 @@ const TEST_URL = TEST_URL_ROOT + "doc_markup_search.html";
let test = asyncTest(function*() {
let {inspector, toolbox} = yield addTab(TEST_URL).then(openInspector);
ok(!getContainerForRawNode("em", inspector),
"The <em> tag isn't present yet in the markup-view");
let container = yield getContainerForSelector("em", inspector);
ok(!container, "The <em> tag isn't present yet in the markup-view");
// Searching for the innermost element first makes sure that the inspector
// back-end is able to attach the resulting node to the tree it knows at the
@ -25,9 +25,11 @@ let test = asyncTest(function*() {
searchUsingSelectorSearch("em", inspector);
yield updated;
ok(getContainerForRawNode("em", inspector),
"The <em> tag is now imported in the markup-view");
is(inspector.selection.node, getNode("em"),
container = yield getContainerForSelector("em", inspector);
ok(container, "The <em> tag is now imported in the markup-view");
let nodeFront = yield getNodeFront("em", inspector);
is(inspector.selection.nodeFront, nodeFront,
"The <em> tag is the currently selected node");
info("searching for other nodes too");
@ -35,7 +37,9 @@ let test = asyncTest(function*() {
let updated = inspector.once("inspector-updated");
searchUsingSelectorSearch(node, inspector);
yield updated;
is(inspector.selection.node, getNode(node),
nodeFront = yield getNodeFront(node, inspector);
is(inspector.selection.nodeFront, nodeFront,
"The <" + node + "> tag is the currently selected node");
}
});

Просмотреть файл

@ -13,16 +13,15 @@ let test = asyncTest(function*() {
let {toolbox, inspector} = yield addTab(TEST_URL).then(openInspector);
info("Selecting the test node");
let node = content.document.getElementById("test-div");
yield selectNode(node, inspector);
yield selectNode("#test-div", inspector);
info("Verify attributes, only ID should be there for now");
assertAttributes(node, {
assertAttributes("#test-div", {
id: "test-div"
});
info("Focus the ID attribute and change its content");
let editor = getContainerForRawNode(node, inspector).editor;
let {editor} = yield getContainerForSelector("#test-div", inspector);
let attr = editor.attrs["id"].querySelector(".editable");
let mutated = inspector.once("markupmutation");
setEditableFieldValue(attr,
@ -30,7 +29,7 @@ let test = asyncTest(function*() {
yield mutated;
info("Verify attributes, should have ID, class and style");
assertAttributes(node, {
assertAttributes("#test-div", {
id: "test-div",
class: "newclass",
style: "color:green"
@ -38,7 +37,7 @@ let test = asyncTest(function*() {
info("Trying to undo the change");
yield undoChange(inspector);
assertAttributes(node, {
assertAttributes("#test-div", {
id: "test-div"
});

Просмотреть файл

@ -14,11 +14,11 @@ let test = asyncTest(function*() {
yield inspector.markup.expandAll();
info("Selecting the test node");
let node = content.document.getElementById("retag-me");
let node = content.document.querySelector("#retag-me");
let child = content.document.querySelector("#retag-me-2");
yield selectNode(node, inspector);
yield selectNode("#retag-me", inspector);
let container = getContainerForRawNode(node, inspector);
let container = yield getContainerForSelector("#retag-me", inspector);
is(node.tagName, "DIV", "We've got #retag-me element, it's a DIV");
ok(container.expanded, "It is expanded");
is(child.parentNode, node, "Child #retag-me-2 is inside #retag-me");
@ -30,8 +30,8 @@ let test = asyncTest(function*() {
yield mutated;
info("Checking that the tagname change was done");
let node = content.document.getElementById("retag-me");
let container = getContainerForRawNode(node, inspector);
let node = content.document.querySelector("#retag-me");
let container = yield getContainerForSelector("#retag-me", inspector);
is(node.tagName, "P", "We've got #retag-me, it should now be a P");
ok(container.expanded, "It is still expanded");
ok(container.selected, "It is still selected");

Просмотреть файл

@ -12,8 +12,8 @@ let test = asyncTest(function*() {
let {toolbox, inspector} = yield addTab(TEST_URL).then(openInspector);
info("Selecting the test node by clicking on it to make sure it receives focus");
let node = content.document.getElementById("delete-me");
yield clickContainer(node, inspector);
let node = content.document.querySelector("#delete-me");
yield clickContainer("#delete-me", inspector);
info("Deleting the element with the keyboard");
let mutated = inspector.once("markupmutation");
@ -21,10 +21,10 @@ let test = asyncTest(function*() {
yield mutated;
info("Checking that it's gone, baby gone!");
ok(!content.document.getElementById("delete-me"), "The test node does not exist");
ok(!content.document.querySelector("#delete-me"), "The test node does not exist");
yield undoChange(inspector);
ok(content.document.getElementById("delete-me"), "The test node is back!");
ok(content.document.querySelector("#delete-me"), "The test node is back!");
yield inspector.once("inspector-updated");
});

Просмотреть файл

@ -36,7 +36,7 @@ function* testCollapsedLongAttribute(inspector) {
"data-long": LONG_ATTRIBUTE
});
let editor = getContainerForRawNode("#node24", inspector).editor;
let {editor} = yield getContainerForSelector("#node24", inspector);
let attr = editor.attrs["data-long"].querySelector(".editable");
// Check to make sure it has expanded after focus
@ -69,7 +69,7 @@ function* testModifyInlineStyleWithQuotes(inspector) {
});
let onMutated = inspector.once("markupmutation");
let editor = getContainerForRawNode("#node26", inspector).editor;
let {editor} = yield getContainerForSelector("#node26", inspector);
let attr = editor.attrs["style"].querySelector(".editable");
attr.focus();
@ -105,7 +105,7 @@ function* testEditingAttributeWithMixedQuotes(inspector) {
});
let onMutated = inspector.once("markupmutation");
let editor = getContainerForRawNode("#node27", inspector).editor;
let {editor} = yield getContainerForSelector("#node27", inspector);
let attr = editor.attrs["class"].querySelector(".editable");
attr.focus();

Просмотреть файл

@ -13,6 +13,7 @@ let test = asyncTest(function*() {
info("Expanding all nodes");
yield inspector.markup.expandAll();
yield waitForMultipleChildrenUpdates(inspector);
let node = getNode(".node6").firstChild;
is(node.nodeValue, "line6", "The test node's text content is correct");
@ -21,8 +22,8 @@ let test = asyncTest(function*() {
info("Listening to the markupmutation event");
let onMutated = inspector.once("markupmutation");
let editor = getContainerForRawNode(node, inspector).editor;
let field = editor.elt.querySelector("pre");
let container = yield getContainerForSelector(".node6", inspector);
let field = container.elt.querySelector("pre");
setEditableFieldValue(field, "New text", inspector);
yield onMutated;
@ -30,3 +31,15 @@ let test = asyncTest(function*() {
yield inspector.once("inspector-updated");
});
// The expand all operation of the markup-view calls itself recursively and
// there's not one event we can wait for to know when it's done
function* waitForMultipleChildrenUpdates(inspector) {
// As long as child updates are queued up while we wait for an update already
// wait again
if (inspector.markup._queuedChildUpdates &&
inspector.markup._queuedChildUpdates.size) {
yield waitForChildrenUpdated(inspector);
return yield waitForMultipleChildrenUpdates(inspector);
}
}

Просмотреть файл

@ -12,7 +12,7 @@ let test = asyncTest(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
info("Getting the container for the UL parent element");
let container = getContainerForRawNode("ul", inspector);
let container = yield getContainerForSelector("ul", inspector);
info("Clicking on the UL parent expander, and waiting for children");
let onChildren = waitForChildrenUpdated(inspector);
@ -23,9 +23,10 @@ let test = asyncTest(function*() {
yield onUpdated;
info("Checking that child LI elements have been created");
for (let li of content.document.querySelectorAll("li")) {
ok(getContainerForRawNode(li, inspector),
"A container for the child LI element was created");
for (let i = 0; i < content.document.querySelectorAll("li").length; i ++) {
let liContainer = yield getContainerForSelector(
"li:nth-child(" + (i + 1) + ")", inspector);
ok(liContainer, "A container for the child LI element was created");
}
ok(container.expanded, "Parent UL container is expanded");
@ -36,8 +37,9 @@ let test = asyncTest(function*() {
inspector.markup.doc.defaultView);
info("Checking that child LI elements have been hidden");
for (let li of content.document.querySelectorAll("li")) {
let liContainer = getContainerForRawNode(li, inspector);
for (let i = 0; i < content.document.querySelectorAll("li").length; i ++) {
let liContainer = yield getContainerForSelector(
"li:nth-child(" + (i + 1) + ")", inspector);
is(liContainer.elt.getClientRects().length, 0,
"The container for the child LI element was hidden");
}

Просмотреть файл

@ -12,7 +12,7 @@ let test = asyncTest(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
info("Getting the container for the UL parent element");
let container = getContainerForRawNode("ul", inspector);
let container = yield getContainerForSelector("ul", inspector);
info("Dbl-clicking on the UL parent expander, and waiting for children");
let onChildren = waitForChildrenUpdated(inspector);
@ -23,9 +23,10 @@ let test = asyncTest(function*() {
yield onUpdated;
info("Checking that child LI elements have been created");
for (let li of content.document.querySelectorAll("li")) {
ok(getContainerForRawNode(li, inspector),
"A container for the child LI element was created");
for (let i = 0; i < content.document.querySelectorAll("li").length; i ++) {
let liContainer = yield getContainerForSelector(
"li:nth-child(" + (i + 1) + ")", inspector);
ok(liContainer, "A container for the child LI element was created");
}
ok(container.expanded, "Parent UL container is expanded");
@ -36,8 +37,9 @@ let test = asyncTest(function*() {
inspector.markup.doc.defaultView);
info("Checking that child LI elements have been hidden");
for (let li of content.document.querySelectorAll("li")) {
let liContainer = getContainerForRawNode(li, inspector);
for (let i = 0; i < content.document.querySelectorAll("li").length; i ++) {
let liContainer = yield getContainerForSelector(
"li:nth-child(" + (i + 1) + ")", inspector);
is(liContainer.elt.getClientRects().length, 0,
"The container for the child LI element was hidden");
}

Просмотреть файл

@ -13,7 +13,7 @@ let test = asyncTest(function*() {
let {inspector} = yield addTab(TEST_URL).then(openInspector);
info("Getting the container for the UL parent element");
let container = getContainerForRawNode("ul", inspector);
let container = yield getContainerForSelector("ul", inspector);
info("Alt-clicking on the UL parent expander, and waiting for children");
let onUpdated = inspector.once("inspector-updated");
@ -23,11 +23,14 @@ let test = asyncTest(function*() {
yield waitForMultipleChildrenUpdates(inspector);
info("Checking that all nodes exist and are expanded");
for (let node of content.document.querySelectorAll("ul, li, span, em")) {
let nodeContainer = getContainerForRawNode(node, inspector);
ok(nodeContainer, "Container for node " + node.tagName + " exists");
let nodeList = yield inspector.walker.querySelectorAll(
inspector.walker.rootNode, "ul, li, span, em");
let nodeFronts = yield nodeList.items();
for (let nodeFront of nodeFronts) {
let nodeContainer = getContainerForNodeFront(nodeFront, inspector);
ok(nodeContainer, "Container for node " + nodeFront.tagName + " exists");
ok(nodeContainer.expanded,
"Container for node " + node.tagName + " is expanded");
"Container for node " + nodeFront.tagName + " is expanded");
}
});
@ -41,4 +44,4 @@ function* waitForMultipleChildrenUpdates(inspector) {
yield waitForChildrenUpdated(inspector);
return yield waitForMultipleChildrenUpdates(inspector);
}
}
}

Просмотреть файл

@ -28,19 +28,17 @@ registerCleanupFunction(() => {
});
// Auto close the toolbox and close the test tabs when the test ends
registerCleanupFunction(() => {
try {
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.closeToolbox(target);
} catch (ex) {
dump(ex);
}
registerCleanupFunction(function*() {
let target = TargetFactory.forTab(gBrowser.selectedTab);
yield gDevTools.closeToolbox(target);
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
});
const TEST_URL_ROOT = "http://mochi.test:8888/browser/browser/devtools/markupview/test/";
const CHROME_BASE = "chrome://mochitests/content/browser/browser/devtools/markupview/test/";
/**
* Define an async test based on a generator function
@ -58,15 +56,19 @@ 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);
// Bug 921935 should bring waitForFocus() support to e10s, which would
// probably cover the case of the test losing focus when the page is loading.
// For now, we just make sure the window is focused.
window.focus();
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
let linkedBrowser = tab.linkedBrowser;
linkedBrowser.addEventListener("load", function onload() {
linkedBrowser.removeEventListener("load", onload, true);
info("URL '" + url + "' loading complete");
waitForFocus(() => {
def.resolve(tab);
}, content);
def.resolve(tab);
}, true);
content.location = url;
return def.promise;
}
@ -124,7 +126,8 @@ function openInspector() {
* 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
* @return {DOMNode}
* @return {DOMNode|CPOW} Note that in e10s mode a CPOW object is returned which
* doesn't implement *all* of the DOMNode's properties
*/
function getNode(nodeOrSelector) {
info("Getting the node for '" + nodeOrSelector + "'");
@ -133,6 +136,17 @@ function getNode(nodeOrSelector) {
nodeOrSelector;
}
/**
* Get the NodeFront for a given css selector, via the protocol
* @param {String} selector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return {Promise} Resolves to the NodeFront instance
*/
function getNodeFront(selector, {walker}) {
return walker.querySelector(walker.rootNode, selector);
}
/**
* Highlight a node and set the inspector's current selection to the node or
* the first match of the given css selector.
@ -149,46 +163,54 @@ function selectAndHighlightNode(nodeOrSelector, inspector) {
let updated = inspector.toolbox.once("highlighter-ready");
inspector.selection.setNode(node, "test-highlight");
return updated;
}
/**
* Set the inspector's current selection to a node or to the first match of the
* given css selector.
* @param {String|DOMNode} nodeOrSelector
* @param {InspectorPanel} inspector
* The instance of InspectorPanel currently loaded in the toolbox
* @param {String} reason
* Defaults to "test" which instructs the inspector not to highlight the
* node upon selection
* @return a promise that resolves when the inspector is updated with the new
* node
* Set the inspector's current selection to the first match of the given css
* selector
* @param {String} selector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @param {String} reason Defaults to "test" which instructs the inspector not
* to highlight the node upon selection
* @return {Promise} Resolves when the inspector is updated with the new node
*/
function selectNode(nodeOrSelector, inspector, reason="test") {
info("Selecting the node " + nodeOrSelector);
let node = getNode(nodeOrSelector);
let selectNode = Task.async(function*(selector, inspector, reason="test") {
info("Selecting the node for '" + selector + "'");
let nodeFront = yield getNodeFront(selector, inspector);
let updated = inspector.once("inspector-updated");
inspector.selection.setNode(node, reason);
return updated;
}
inspector.selection.setNodeFront(nodeFront, reason);
yield updated;
});
/**
* Get the MarkupContainer object instance that corresponds to the given
* HTML node
* @param {DOMNode|String} nodeOrSelector The DOM node for which the
* container is required
* NodeFront
* @param {NodeFront} nodeFront
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return {MarkupContainer}
*/
function getContainerForRawNode(nodeOrSelector, {markup}) {
let front = markup.walker.frontForRawNode(getNode(nodeOrSelector));
let container = markup.getContainer(front);
info("Markup-container object for " + nodeOrSelector + " " + container);
return container;
function getContainerForNodeFront(nodeFront, {markup}) {
return markup.getContainer(nodeFront);
}
/**
* Get the MarkupContainer object instance that corresponds to the given
* selector
* @param {String} selector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return {MarkupContainer}
*/
let getContainerForSelector = Task.async(function*(selector, inspector) {
info("Getting the markup-container for node " + selector);
let nodeFront = yield getNodeFront(selector, inspector);
let container = getContainerForNodeFront(nodeFront, inspector);
info("Found markup-container " + container);
return container;
});
/**
* Using the markupview's _waitForChildren function, wait for all queued
* children updates to be handled.
@ -208,38 +230,46 @@ function waitForChildrenUpdated({markup}) {
/**
* Simulate a mouse-over on the markup-container (a line in the markup-view)
* that corresponds to the node or selector passed.
* @param {String|DOMNode} nodeOrSelector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently loaded in the toolbox
* @return a promise that resolves when the container is hovered and the higlighter
* that corresponds to the selector passed.
* @param {String} selector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return {Promise} Resolves when the container is hovered and the higlighter
* is shown on the corresponding node
*/
function hoverContainer(nodeOrSelector, inspector) {
info("Hovering over the markup-container for node " + nodeOrSelector);
let hoverContainer = Task.async(function*(selector, inspector) {
info("Hovering over the markup-container for node " + selector);
let nodeFront = yield getNodeFront(selector, inspector);
let container = getContainerForNodeFront(nodeFront, inspector);
let highlit = inspector.toolbox.once("node-highlight");
let container = getContainerForRawNode(getNode(nodeOrSelector), inspector);
EventUtils.synthesizeMouseAtCenter(container.tagLine, {type: "mousemove"},
inspector.markup.doc.defaultView);
return highlit;
}
});
/**
* Simulate a click on the markup-container (a line in the markup-view)
* that corresponds to the node or selector passed.
* @param {String|DOMNode} nodeOrSelector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently loaded in the toolbox
* @return a promise that resolves when the node has been selected.
* that corresponds to the selector passed.
* @param {String} selector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return {Promise} Resolves when the node has been selected.
*/
function clickContainer(nodeOrSelector, inspector) {
info("Clicking on the markup-container for node " + nodeOrSelector);
let clickContainer = Task.async(function*(selector, inspector) {
info("Clicking on the markup-container for node " + selector);
let nodeFront = yield getNodeFront(selector, inspector);
let container = getContainerForNodeFront(nodeFront, inspector);
let updated = inspector.once("inspector-updated");
let container = getContainerForRawNode(getNode(nodeOrSelector), inspector);
EventUtils.synthesizeMouseAtCenter(container.tagLine, {type: "mousedown"},
inspector.markup.doc.defaultView);
EventUtils.synthesizeMouseAtCenter(container.tagLine, {type: "mouseup"},
inspector.markup.doc.defaultView);
return updated;
}
});
/**
* Checks if the highlighter is visible currently
@ -288,39 +318,39 @@ function setEditableFieldValue(field, value, inspector) {
}
/**
* Focus the new-attribute inplace-editor field of the nodeOrSelector's markup
* container, and enters the given text, then wait for it to be applied and the
* for the node to mutates (when new attribute(s) is(are) created)
* @param {DOMNode|String} nodeOrSelector The node or node selector to edit.
* Focus the new-attribute inplace-editor field of a node's markup container
* and enters the given text, then wait for it to be applied and the for the
* node to mutates (when new attribute(s) is(are) created)
* @param {String} selector The selector for the node to edit.
* @param {String} text The new attribute text to be entered (e.g. "id='test'")
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return a promise that resolves when the node has mutated
*/
function addNewAttributes(nodeOrSelector, text, inspector) {
info("Entering text '" + text + "' in node '" + nodeOrSelector + "''s new attribute field");
let addNewAttributes = Task.async(function*(selector, text, inspector) {
info("Entering text '" + text + "' in node '" + selector + "''s new attribute field");
let container = getContainerForRawNode(nodeOrSelector, inspector);
ok(container, "The container for '" + nodeOrSelector + "' was found");
let container = yield getContainerForSelector(selector, inspector);
ok(container, "The container for '" + selector + "' was found");
info("Listening for the markupmutation event");
let nodeMutated = inspector.once("markupmutation");
setEditableFieldValue(container.editor.newAttr, text, inspector);
return nodeMutated;
}
yield nodeMutated;
});
/**
* Checks that a node has the given attributes
*
* @param {DOMNode|String} nodeOrSelector The node or node selector to check.
* @param {String} selector The node or node selector to check.
* @param {Object} attrs An object containing the attributes to check.
* e.g. {id: "id1", class: "someclass"}
*
* Note that node.getAttribute() returns attribute values provided by the HTML
* parser. The parser only provides unescaped entities so &amp; will return &.
*/
function assertAttributes(nodeOrSelector, attrs) {
let node = getNode(nodeOrSelector);
function assertAttributes(selector, attrs) {
let node = getNode(selector);
is(node.attributes.length, Object.keys(attrs).length,
"Node has the correct number of attributes.");

Просмотреть файл

@ -21,11 +21,10 @@ function runAddAttributesTests(tests, nodeOrSelector, inspector) {
info("Running " + tests.length + " add-attributes tests");
return Task.spawn(function*() {
info("Selecting the test node");
let div = getNode("div");
yield selectNode(div, inspector);
yield selectNode("div", inspector);
for (let test of tests) {
yield runAddAttributesTest(test, div, inspector);
yield runAddAttributesTest(test, "div", inspector);
}
yield inspector.once("inspector-updated");
@ -48,22 +47,22 @@ function runAddAttributesTests(tests, nodeOrSelector, inspector) {
* - {DOMNode} The element being tested
* - {MarkupContainer} The corresponding container in the markup-view
* - {InspectorPanel} The instance of the InspectorPanel opened
* @param {DOMNode|String} nodeOrSelector The node or node selector
* corresponding to the test element
* @param {String} selector The node selector corresponding to the test element
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* opened
*/
function* runAddAttributesTest(test, nodeOrSelector, inspector) {
let element = getNode(nodeOrSelector);
function* runAddAttributesTest(test, selector, inspector) {
let element = getNode(selector);
info("Starting add-attribute test: " + test.desc);
yield addNewAttributes(element, test.text, inspector);
yield addNewAttributes(selector, test.text, inspector);
info("Assert that the attribute(s) has/have been applied correctly");
assertAttributes(element, test.expectedAttributes);
if (test.validate) {
test.validate(element, getContainerForRawNode(element, inspector), inspector);
let container = yield getContainerForSelector(selector, inspector);
test.validate(element, container, inspector);
}
info("Undo the change");
@ -128,7 +127,7 @@ function* runEditAttributesTest(test, inspector) {
info("Editing attribute " + test.name + " with value " + test.value);
let container = getContainerForRawNode(test.node, inspector);
let container = yield getContainerForSelector(test.node, inspector);
ok(container && container.editor, "The markup-container for " + test.node +
" was found");

Просмотреть файл

@ -42,6 +42,8 @@ function* runEditOuterHTMLTest(test, inspector) {
yield selectNode(test.selector, inspector);
let oldNodeFront = inspector.selection.nodeFront;
let onUpdated = inspector.once("inspector-updated");
info("Listening for the markupmutation event");
// This event fires once the outerHTML is set, with a target as the parent node and a type of "childList".
let mutated = inspector.once("markupmutation");
@ -60,22 +62,22 @@ function* runEditOuterHTMLTest(test, inspector) {
is(mutation.target, nodeFront, "Parent node is selected immediately after setting outerHTML");
// Wait for node to be reselected after outerHTML has been set
yield inspector.selection.once("new-node");
yield inspector.selection.once("new-node-front");
// Typically selectedNode will === pageNode, but if a new element has been injected in front
// of it, this will not be the case. If this happens.
let selectedNode = inspector.selection.node;
let nodeFront = inspector.selection.nodeFront;
let selectedNodeFront = inspector.selection.nodeFront;
let pageNodeFront = yield inspector.walker.querySelector(inspector.walker.rootNode, test.selector);
let pageNode = getNode(test.selector);
if (test.validate) {
test.validate(pageNode, selectedNode);
yield test.validate(pageNode, pageNodeFront, selectedNodeFront, inspector);
} else {
is(pageNode, selectedNode, "Original node (grabbed by selector) is selected");
is(pageNodeFront, selectedNodeFront, "Original node (grabbed by selector) is selected");
is(pageNode.outerHTML, test.newHTML, "Outer HTML has been updated");
}
// Wait for the inspector to be fully updated to avoid causing errors by
// abruptly closing hanging requests when the test ends
yield inspector.once("inspector-updated");
yield onUpdated;
}

Просмотреть файл

@ -94,8 +94,10 @@ let HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
destroy: function() {
protocol.Actor.prototype.destroy.call(this);
if (this._boxModelHighlighter) {
this._boxModelHighlighter.off("ready", this._highlighterReady);
this._boxModelHighlighter.off("hide", this._highlighterHidden);
if (supportXULBasedHighlighter(this._tabActor)) {
this._boxModelHighlighter.off("ready", this._highlighterReady);
this._boxModelHighlighter.off("hide", this._highlighterHidden);
}
this._boxModelHighlighter.destroy();
this._boxModelHighlighter = null;
}