tenfourfox/devtools/server/tests/mochitest/test_inspector-search.html
Cameron Kaiser c9b2922b70 hello FPR
2017-04-19 00:56:45 -07:00

301 lines
9.7 KiB
HTML

<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=835896
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 835896</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">
window.onload = function() {
const Cu = Components.utils;
Cu.import("resource://gre/modules/devtools/Loader.jsm");
const {Promise: promise} =
Cu.import("resource://gre/modules/Promise.jsm", {});
const {InspectorFront} =
devtools.require("devtools/server/actors/inspector");
const {WalkerSearch, WalkerIndex} =
devtools.require("devtools/server/actors/utils/walker-search");
const {console} =
Cu.import("resource://gre/modules/devtools/shared/Console.jsm", {});
SimpleTest.waitForExplicitFinish();
let walkerActor = null;
let walkerSearch = null;
let inspectee = null;
let inspector = null;
// WalkerSearch specific tests. This is to make sure search results are
// coming back as expected.
// See also test_inspector-search-front.html.
addAsyncTest(function* setup() {
info ("Setting up inspector and walker actors.");
let url = document.getElementById("inspectorContent").href;
yield new Promise(resolve => {
attachURL(url, function(err, client, tab, doc) {
inspectee = doc;
inspector = InspectorFront(client, tab);
resolve();
});
});
let walkerFront = yield inspector.getWalker();
ok(walkerFront, "getWalker() should return an actor.");
let serverConnection = walkerFront.conn._transport._serverConnection;
walkerActor = serverConnection.getActor(walkerFront.actorID);
ok(walkerActor,
"Got a reference to the walker actor (" + walkerFront.actorID + ")");
walkerSearch = walkerActor.walkerSearch;
runNextTest();
});
addAsyncTest(function* testIndexExists() {
info ("Testing basic index APIs exist.");
let index = new WalkerIndex(walkerActor);
ok(index.data.size > 0, "public index is filled after getting");
index.clearIndex();
ok(!index._data, "private index is empty after clearing");
ok(index.data.size > 0, "public index is filled after getting");
index.destroy();
runNextTest();
});
addAsyncTest(function* testSearchExists() {
info ("Testing basic search APIs exist.");
ok(walkerSearch, "walker search exists on the WalkerActor");
ok(walkerSearch.search, "walker search has `search` method");
ok(walkerSearch.index, "walker search has `index` property");
is(walkerSearch.walker, walkerActor, "referencing the correct WalkerActor");
let search = new WalkerSearch(walkerActor);
ok(search, "a new search instance can be created");
ok(search.search, "new search instance has `search` method");
ok(search.index, "new search instance has `index` property");
isnot(search, walkerSearch, "new search instance differs from the WalkerActor's");
search.destroy();
runNextTest();
});
addAsyncTest(function* testEmptySearch() {
info ("Testing search with an empty query.");
results = walkerSearch.search("");
is(results.length, 0, "No results when searching for ''");
results = walkerSearch.search(null);
is(results.length, 0, "No results when searching for null");
results = walkerSearch.search(undefined);
is(results.length, 0, "No results when searching for undefined");
results = walkerSearch.search(10);
is(results.length, 0, "No results when searching for 10");
runNextTest();
});
addAsyncTest(function* testBasicSearchData() {
let testData = [
{
desc: "Search for tag with one result.",
search: "body",
expected: [
{node: inspectee.body, type: "tag"}
]
},
{
desc: "Search for tag with multiple results",
search: "h2",
expected: [
{node: inspectee.querySelectorAll("h2")[0], type: "tag"},
{node: inspectee.querySelectorAll("h2")[1], type: "tag"},
{node: inspectee.querySelectorAll("h2")[2], type: "tag"},
]
},
{
desc: "Search for selector with multiple results",
search: "body > h2",
expected: [
{node: inspectee.querySelectorAll("h2")[0], type: "selector"},
{node: inspectee.querySelectorAll("h2")[1], type: "selector"},
{node: inspectee.querySelectorAll("h2")[2], type: "selector"},
]
},
{
desc: "Search for selector with multiple results",
search: ":root h2",
expected: [
{node: inspectee.querySelectorAll("h2")[0], type: "selector"},
{node: inspectee.querySelectorAll("h2")[1], type: "selector"},
{node: inspectee.querySelectorAll("h2")[2], type: "selector"},
]
},
{
desc: "Search for selector with multiple results",
search: "* h2",
expected: [
{node: inspectee.querySelectorAll("h2")[0], type: "selector"},
{node: inspectee.querySelectorAll("h2")[1], type: "selector"},
{node: inspectee.querySelectorAll("h2")[2], type: "selector"},
]
},
{
desc: "Search with multiple matches in a single tag expecting a single result",
search: "💩",
expected: [
{node: inspectee.getElementById("💩"), type: "attributeName"}
]
},
{
desc: "Search that has tag and text results",
search: "h1",
expected: [
{node: inspectee.querySelector("h1"), type: "tag"},
{node: inspectee.querySelector("h1 + p").childNodes[0], type: "text"},
{node: inspectee.querySelector("h1 + p > strong").childNodes[0], type: "text"},
]
},
]
for (let {desc, search, expected} of testData) {
info("Running test: " + desc);
let results = walkerSearch.search(search);
isDeeply(results, expected,
"Search returns correct results with '" + search + "'");
}
runNextTest();
});
addAsyncTest(function* testPseudoElements() {
info ("Testing ::before and ::after element matching");
let beforeElt = new _documentWalker(inspectee.querySelector("#pseudo"),
inspectee.defaultView).firstChild();
let afterElt = new _documentWalker(inspectee.querySelector("#pseudo"),
inspectee.defaultView).lastChild();
let styleText = inspectee.querySelector("style").childNodes[0];
// ::before
let results = walkerSearch.search("::before");
isDeeply(results, [ {node: beforeElt, type: "tag"} ],
"Tag search works for pseudo element");
results = walkerSearch.search("_moz_generated_content_before");
is(results.length, 0, "No results for anon tag name");
results = walkerSearch.search("before element");
isDeeply(results, [
{node: styleText, type: "text"},
{node: beforeElt, type: "text"}
], "Text search works for pseudo element");
// ::after
results = walkerSearch.search("::after");
isDeeply(results, [ {node: afterElt, type: "tag"} ],
"Tag search works for pseudo element");
results = walkerSearch.search("_moz_generated_content_after");
is(results.length, 0, "No results for anon tag name");
results = walkerSearch.search("after element");
isDeeply(results, [
{node: styleText, type: "text"},
{node: afterElt, type: "text"}
], "Text search works for pseudo element");
runNextTest();
});
addAsyncTest(function* testSearchMutationChangeResults() {
info ("Testing search before and after a mutation.");
let expected = [
{node: inspectee.querySelectorAll("h3")[0], type: "tag"},
{node: inspectee.querySelectorAll("h3")[1], type: "tag"},
{node: inspectee.querySelectorAll("h3")[2], type: "tag"},
];
let results = walkerSearch.search("h3");
isDeeply(results, expected, "Search works with tag results");
yield mutateDocumentAndWaitForMutation(() => {
expected[0].node.remove();
});
results = walkerSearch.search("h3");
isDeeply(results, [
expected[1],
expected[2]
], "Results are updated after removal");
yield new Promise(resolve => {
info("Waiting for a mutation to happen");
let observer = new inspectee.defaultView.MutationObserver(() => {
resolve();
});
observer.observe(inspectee, {attributes: true, subtree: true});
inspectee.body.setAttribute("h3", "true");
});
results = walkerSearch.search("h3");
isDeeply(results, [
{node: inspectee.body, type: "attributeName"},
expected[1],
expected[2]
], "Results are updated after addition");
yield new Promise(resolve => {
info("Waiting for a mutation to happen");
let observer = new inspectee.defaultView.MutationObserver(() => {
resolve();
});
observer.observe(inspectee, {attributes: true, childList: true, subtree: true});
inspectee.body.removeAttribute("h3");
expected[1].node.remove();
expected[2].node.remove();
});
results = walkerSearch.search("h3");
is(results.length, 0, "Results are updated after removal");
runNextTest();
});
runNextTest();
function mutateDocumentAndWaitForMutation(mutationFn) {
return new Promise(resolve => {
info("Listening to markup mutation on the inspectee");
let observer = new inspectee.defaultView.MutationObserver(resolve);
observer.observe(inspectee, {childList: true, subtree: true});
mutationFn();
});
}
};
</script>
</head>
<body>
<a id="inspectorContent" target="_blank" href="inspector-search-data.html">Test Document</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>