The suggestions were sorted by the number of element matching the item, which could be confusing and get in the way of the user when they wanted to search for the least used version. We now sort the suggestions by "type" (id, class, tag, …), and then, within those groups, alphabetically. Differential Revision: https://phabricator.services.mozilla.com/D249768
181 lines
5.1 KiB
JavaScript
181 lines
5.1 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
const CSSCompleter = require("resource://devtools/client/shared/sourceeditor/css-autocompleter.js");
|
|
|
|
const CSS_URI =
|
|
"http://mochi.test:8888/browser/devtools/client/shared/sourceeditor" +
|
|
"/test/css_statemachine_testcases.css";
|
|
const TESTS_URI =
|
|
"http://mochi.test:8888/browser/devtools/client" +
|
|
"/shared/sourceeditor/test/css_autocompletion_tests.json";
|
|
|
|
const source = read(CSS_URI);
|
|
const { tests } = JSON.parse(read(TESTS_URI));
|
|
|
|
const TEST_URI =
|
|
"data:text/html;charset=UTF-8," +
|
|
encodeURIComponent(`
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>CSS State machine tests.</title>
|
|
<style>
|
|
#progress {
|
|
width: 500px; height: 30px;
|
|
border: 1px solid black;
|
|
position: relative
|
|
}
|
|
#progress div {
|
|
width: 0%; height: 100%;
|
|
background: green;
|
|
position: absolute;
|
|
z-index: -1; top: 0
|
|
}
|
|
#progress.failed div {
|
|
background: red !important;
|
|
}
|
|
#progress.failed:after {
|
|
content: 'Some tests failed';
|
|
color: white
|
|
}
|
|
#progress:before {
|
|
content: 'Running test ' attr(data-progress) ' of ${tests.length}';
|
|
color: white;
|
|
text-shadow: 0 0 2px darkgreen;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h2>State machine tests for CSS autocompleter.</h2><br>
|
|
<div id='progress' data-progress='0'>
|
|
<div></div>
|
|
</div>
|
|
<div id='devtools-menu' class='devtools-toolbarbutton'></div>
|
|
<div id='devtools-toolbarbutton' class='devtools-menulist'></div>
|
|
<div id='devtools-anotherone'></div>
|
|
<div id='devtools-yetagain'></div>
|
|
<div id='devtools-itjustgoeson'></div>
|
|
<div id='devtools-okstopitnow'></div>
|
|
<div class='hidden-labels-box devtools-toolbarbutton devtools-menulist'></div>
|
|
<div class='devtools-menulist'></div>
|
|
<div class='devtools-menulist'></div>",
|
|
<tabs class='devtools-toolbarbutton'><tab></tab><tab></tab><tab></tab></tabs><tabs></tabs>
|
|
<button class='category-name visible'></button>
|
|
<div class='devtools-toolbarbutton' label='true'>
|
|
<hbox class='toolbarbutton-menubutton-button'></hbox></div>
|
|
</body>
|
|
</html>
|
|
`);
|
|
|
|
let browser;
|
|
let index = 0;
|
|
let completer = null;
|
|
let inspector;
|
|
|
|
add_task(async function test() {
|
|
const tab = await addTab(TEST_URI);
|
|
browser = tab.linkedBrowser;
|
|
await runTests();
|
|
browser = null;
|
|
gBrowser.removeCurrentTab();
|
|
});
|
|
|
|
async function runTests() {
|
|
const target = await createAndAttachTargetForTab(gBrowser.selectedTab);
|
|
inspector = await target.getFront("inspector");
|
|
const walker = inspector.walker;
|
|
const cssPropertiesFront = await target.getFront("cssProperties");
|
|
completer = new CSSCompleter({
|
|
walker,
|
|
cssProperties: cssPropertiesFront.cssProperties,
|
|
});
|
|
await checkStateAndMoveOn();
|
|
await completer.walker.release();
|
|
await target.destroy();
|
|
inspector = null;
|
|
completer = null;
|
|
}
|
|
|
|
async function checkStateAndMoveOn() {
|
|
if (index == tests.length) {
|
|
return;
|
|
}
|
|
|
|
const [lineCh, baseExpectedSuggestions, prefSuggestions] = tests[index];
|
|
const [line, ch] = lineCh;
|
|
|
|
let expectedSuggestions;
|
|
if (prefSuggestions) {
|
|
const additional = [];
|
|
for (const [pref, property] of prefSuggestions) {
|
|
if (SpecialPowers.getBoolPref(pref)) {
|
|
additional.push(property);
|
|
}
|
|
}
|
|
expectedSuggestions = baseExpectedSuggestions.concat(additional);
|
|
expectedSuggestions.sort();
|
|
} else {
|
|
expectedSuggestions = baseExpectedSuggestions;
|
|
}
|
|
|
|
++index;
|
|
await SpecialPowers.spawn(
|
|
browser,
|
|
[[index, tests.length]],
|
|
function ([idx, len]) {
|
|
const progress = content.document.getElementById("progress");
|
|
const progressDiv = content.document.querySelector("#progress > div");
|
|
progress.dataset.progress = idx;
|
|
progressDiv.style.width = (100 * idx) / len + "%";
|
|
}
|
|
);
|
|
|
|
const actualSuggestions = await completer.complete(limit(source, lineCh), {
|
|
line,
|
|
ch,
|
|
});
|
|
await checkState(expectedSuggestions, actualSuggestions);
|
|
await checkStateAndMoveOn();
|
|
}
|
|
|
|
async function checkState(expected, actual) {
|
|
if (expected.length != actual.length) {
|
|
ok(
|
|
false,
|
|
"Number of suggestions did not match up for state " +
|
|
index +
|
|
". Expected: " +
|
|
expected.length +
|
|
", Actual: " +
|
|
actual.length
|
|
);
|
|
await SpecialPowers.spawn(browser, [], function () {
|
|
const progress = content.document.getElementById("progress");
|
|
progress.classList.add("failed");
|
|
});
|
|
return;
|
|
}
|
|
|
|
for (let i = 0; i < actual.length; i++) {
|
|
if (expected[i] != actual[i].label) {
|
|
ok(
|
|
false,
|
|
"Suggestion " +
|
|
i +
|
|
" of state " +
|
|
index +
|
|
" did not match up" +
|
|
". Expected: " +
|
|
expected[i] +
|
|
". Actual: " +
|
|
actual[i].label
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
ok(true, "Test " + index + " passed. ");
|
|
}
|