<!DOCTYPE HTML> <html> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id= --> <head> <meta charset="utf-8"> <title>Test for Bug </title> <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> <script type="application/javascript;version=1.8" src="inspector-helpers.js"></script> <script type="application/javascript;version=1.8"> const inspector = require("devtools/server/actors/inspector"); window.onload = function() { SimpleTest.waitForExplicitFinish(); runNextTest(); } var gInspectee = null; var gClient = null; var gWalker = null; var checkActorIDs = []; function assertOwnership() { assertOwnershipTrees(gWalker); } addTest(function setup() { let url = document.getElementById("inspectorContent").href; attachURL(url, function(err, client, tab, doc) { gInspectee = doc; let {InspectorFront} = require("devtools/shared/fronts/inspector"); let inspector = InspectorFront(client, tab); promiseDone(inspector.getWalker().then(walker => { ok(walker, "getWalker() should return an actor."); gClient = client; gWalker = walker; }).then(runNextTest)); }); }); addTest(function testWalkerRoot() { // Make sure that refetching the root document of the walker returns the same // actor as the getWalker returned. promiseDone(gWalker.document().then(root => { ok(root === gWalker.rootNode, "Re-fetching the document node should match the root document node."); checkActorIDs.push(root.actorID); assertOwnership(); }).then(runNextTest)); }); addTest(function testInnerHTML() { promiseDone(gWalker.documentElement().then(docElement => { return gWalker.innerHTML(docElement); }).then(longstring => { return longstring.string(); }).then(innerHTML => { ok(innerHTML === gInspectee.documentElement.innerHTML, "innerHTML should match"); }).then(runNextTest)); }); addTest(function testOuterHTML() { promiseDone(gWalker.documentElement().then(docElement => { return gWalker.outerHTML(docElement); }).then(longstring => { return longstring.string(); }).then(outerHTML => { ok(outerHTML === gInspectee.documentElement.outerHTML, "outerHTML should match"); }).then(runNextTest)); }); addTest(function testSetOuterHTMLNode() { let newHTML = "<p id=\"edit-html-done\">after edit</p>"; promiseDone(gWalker.querySelector(gWalker.rootNode, "#edit-html").then(node => { return gWalker.setOuterHTML(node, newHTML); }).then(() => { return gWalker.querySelector(gWalker.rootNode, "#edit-html-done"); }).then(node => { return gWalker.outerHTML(node); }).then(longstring => { return longstring.string(); }).then(outerHTML => { is(outerHTML, newHTML, "outerHTML has been updated"); }).then(() => { return gWalker.querySelector(gWalker.rootNode, "#edit-html"); }).then(node => { ok(!node, "The node with the old ID cannot be selected anymore"); }).then(runNextTest)); }); addTest(function testQuerySelector() { promiseDone(gWalker.querySelector(gWalker.rootNode, "#longlist").then(node => { is(node.getAttribute("data-test"), "exists", "should have found the right node"); assertOwnership(); }).then(() => { return gWalker.querySelector(gWalker.rootNode, "unknownqueryselector").then(node => { ok(!node, "Should not find a node here."); assertOwnership(); }); }).then(runNextTest)); }); addTest(function testQuerySelectors() { let nodeList = null; let firstNode = null; let nodeListID = null; promiseDone(gWalker.querySelectorAll(gWalker.rootNode, "#longlist div").then(list => { nodeList = list; is(nodeList.length, 26, "Expect 26 div children."); assertOwnership(); return nodeList.item(0); }).then(node => { firstNode = node; checkActorIDs.push(node.actorID); is(node.id, "a", "First child should be a"); assertOwnership(); return nodeList.items(); }).then(nodes => { is(nodes.length, 26, "Expect 26 nodes"); is(nodes[0], firstNode, "First node should be reused."); ok(nodes[0]._parent, "Parent node should be set."); ok(nodes[0]._next || nodes[0]._prev, "Siblings should be set."); ok(nodes[25]._next || nodes[25]._prev, "Siblings of " + nodes[25] + " should be set."); assertOwnership(); return nodeList.items(-1); }).then(nodes => { is(nodes.length, 1, "Expect 1 node") is(nodes[0].id, "z", "Expect it to be the last node."); checkActorIDs.push(nodes[0].actorID); // Save the node list ID so we can ensure it was destroyed. nodeListID = nodeList.actorID; assertOwnership(); return nodeList.release(); }).then(() => { ok(!nodeList.actorID, "Actor should have been destroyed."); assertOwnership(); return checkMissing(gClient, nodeListID); }).then(runNextTest)); }); // Helper to check the response of requests that return hasFirst/hasLast/nodes // node lists (like `children` and `siblings`) function nodeArrayChecker(first, last, ids) { return function(response) { is(response.hasFirst, first, "Should " + (first ? "" : "not ") + " have the first node."); is(response.hasLast, last, "Should " + (last ? "" : "not ") + " have the last node."); is(response.nodes.length, ids.length, "Should have " + ids.length + " children listed."); let responseIds = ''; for (node of response.nodes) { responseIds += node.id; } is(responseIds, ids, "Correct nodes were returned."); assertOwnership(); } } addTest(function testNoChildren() { promiseDone(gWalker.querySelector(gWalker.rootNode, "#empty").then(empty => { assertOwnership(); return gWalker.children(empty).then(nodeArrayChecker(true, true, "")); }).then(runNextTest)); }); addTest(function testLongListTraversal() { var longList; var allChildren; promiseDone(gWalker.querySelector(gWalker.rootNode, "#longlist").then(node => { longList = node; // First call with no options, expect all children. assertOwnership(); return gWalker.children(longList).then(response => { nodeArrayChecker(true, true, "abcdefghijklmnopqrstuvwxyz")(response); allChildren = response.nodes; assertOwnership(); }); }).then(() => { // maxNodes should limit us to the first 5 nodes. assertOwnership(); return gWalker.children(longList, { maxNodes: 5 }).then(nodeArrayChecker(true, false, 'abcde')); }).then(() => { assertOwnership(); // maxNodes with the second item centered should still give us the first 5 nodes. return gWalker.children(longList, { maxNodes: 5, center: allChildren[1] }).then( nodeArrayChecker(true, false, 'abcde') ); }).then(() => { // maxNodes with a center in the middle of the list should put that item in the middle let center = allChildren[13]; is(center.id, 'n', "Make sure I know how to count letters."); return gWalker.children(longList, { maxNodes: 5, center: center }).then( nodeArrayChecker(false, false, 'lmnop') ); }).then(() => { // maxNodes with the second-to-last item centered should give us the last 5 nodes. return gWalker.children(longList, { maxNodes: 5, center: allChildren[24] }).then( nodeArrayChecker(false, true, 'vwxyz') ); }).then(() => { // maxNodes with a start in the middle should start at that node and fetch 5 let start = allChildren[13]; is(start.id, 'n', "Make sure I know how to count letters.") return gWalker.children(longList, { maxNodes: 5, start: start }).then( nodeArrayChecker(false, false, 'nopqr') ); }).then(() => { // maxNodes near the end should only return what's left return gWalker.children(longList, { maxNodes: 5, start: allChildren[24] }).then( nodeArrayChecker(false, true, 'yz') ); }).then(runNextTest)); }); addTest(function testObjectNodeChildren() { promiseDone( gWalker.querySelector(gWalker.rootNode, "object") .then(object => gWalker.children(object)) .then(nodeArrayChecker(true, true, "1")) .then(runNextTest)); }); addTest(function testSiblings() { promiseDone(gWalker.querySelector(gWalker.rootNode, "#a").then(a => { return gWalker.siblings(a, { maxNodes: 5, center: a }).then(nodeArrayChecker(true, false, "abcde")); }).then(() => { return gWalker.siblings(gWalker.rootNode).then(response => { ok(response.hasFirst && response.hasLast, "Has first and last."); is(response.nodes.length, 1, "Has only the document element."); ok(response.nodes[0] === gWalker.rootNode, "Document element is its own sibling."); }); }).then(runNextTest)); }); addTest(function testNextSibling() { promiseDone(gWalker.querySelector(gWalker.rootNode, "#y").then(y => { is(y.id, "y", "Got the right node."); return gWalker.nextSibling(y); }).then(z => { is(z.id, "z", "nextSibling got the next node."); return gWalker.nextSibling(z); }).then(nothing => { is(nothing, null, "nextSibling on the last node returned null."); }).then(runNextTest)); }); addTest(function testPreviousSibling() { promiseDone(gWalker.querySelector(gWalker.rootNode, "#b").then(b => { is(b.id, "b", "Got the right node."); return gWalker.previousSibling(b); }).then(a => { is(a.id, "a", "nextSibling got the next node."); return gWalker.previousSibling(a); }).then(nothing => { is(nothing, null, "previousSibling on the first node returned null."); }).then(runNextTest)); }); addTest(function testFrameTraversal() { promiseDone(gWalker.querySelector(gWalker.rootNode, "#childFrame").then(childFrame => { return gWalker.children(childFrame); }).then(children => { let nodes = children.nodes; is(nodes.length, 1, "There should be only one child of the iframe"); is(nodes[0].nodeType, Node.DOCUMENT_NODE, "iframe child should be a document node"); return gWalker.querySelector(nodes[0], "#z"); }).then(childDocumentZ => { return gWalker.parents(childDocumentZ); }).then(parents => { // Expected set of parent tag names for this item: let expectedParents = ['DIV', 'BODY', 'HTML', '#document', 'IFRAME', 'BODY', 'HTML', '#document']; for (let parent of parents) { let expected = expectedParents.shift(); is(parent.nodeName, expected, "Got expected parent"); } }).then(runNextTest)); }); addTest(function testLongValue() { const testSummaryLength = 10; inspector.setValueSummaryLength(testSummaryLength); SimpleTest.registerCleanupFunction(function() { inspector.setValueSummaryLength(inspector.DEFAULT_VALUE_SUMMARY_LENGTH); }); let longstringText = gInspectee.getElementById("longstring").firstChild.nodeValue; promiseDone(gWalker.querySelector(gWalker.rootNode, "#longstring").then(node => { ok(!node.inlineTextChild, "Text is too long to be inlined"); // Now we need to get the text node child... return gWalker.children(node, { maxNodes: 1 }); }).then(children => { let textNode = children.nodes[0]; is(textNode.nodeType, Node.TEXT_NODE, "Value should be a text node"); return textNode; }).then(textNode => { return textNode.getNodeValue(); }).then(value => { return value.string(); }).then(valueStr => { is(valueStr, longstringText, "Full node value should match the string from the document."); }).then(runNextTest)); }); addTest(function testShortValue() { let shortstringText = gInspectee.getElementById("shortstring").firstChild.nodeValue; promiseDone(gWalker.querySelector(gWalker.rootNode, "#shortstring").then(node => { ok(!!node.inlineTextChild, "Text is short enough to be inlined"); // Now we need to get the text node child... return gWalker.children(node, { maxNodes: 1 }); }).then(children => { let textNode = children.nodes[0]; is(textNode.nodeType, Node.TEXT_NODE, "Value should be a text node"); return textNode; }).then(textNode => { return textNode.getNodeValue(); }).then(value => { return value.string(); }).then(valueStr => { is(valueStr, shortstringText, "Full node value should match the string from the document."); }).then(runNextTest)); }); addTest(function testReleaseWalker() { checkActorIDs.push(gWalker.actorID); promiseDone(gWalker.release().then(() => { let promises = Array.from(checkActorIDs, (id) => checkMissing(gClient, id)); return promise.all(promises) }).then(runNextTest)); }); addTest(function cleanup() { delete gWalker; delete gInspectee; delete gClient; runNextTest(); }); </script> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a> <a id="inspectorContent" target="_blank" href="inspector-traversal-data.html">Test Document</a> <p id="display"></p> <div id="content" style="display: none"> </div> <pre id="test"> </pre> </body> </html>