mirror of
https://github.com/classilla/tenfourfox.git
synced 2025-01-23 18:32:20 +00:00
301 lines
9.7 KiB
HTML
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>
|