blob: 504fdae4cc513efeba53c8a08d96558ccdac2bd4 [file] [log] [blame]
// Initial setup
//@{
var globalValue;
if (globalValue === undefined) {
globalValue = command in defaultValues ? defaultValues[command] : "";
}
var keyPrefix = globalValue == ""
? "manualtest-" + command + "-"
: "manualtest-" + command + "-" + globalValue + "-";
(function(){
var manualTests = tests[command]
.map(function(test) { return normalizeTest(command, test) })
.filter(function(test) { return test[1][1] == globalValue });
var relevantMultiTests = tests.multitest
.map(function(test) { return normalizeTest("multitest", test) })
.filter(function(test) {
// We only want multitests if there's exactly one occurrence of the
// command we're testing for, and the value is correct, and that's
// the last command we're testing. Some of these limitations could
// be removed in the future.
return test[test.length - 1][0] === command
&& test[test.length - 1][1] === globalValue;
});
tests = manualTests.concat(relevantMultiTests);
})();
//@}
function clearCachedResults() {
//@{
for (var key in localStorage) {
if (key.indexOf(keyPrefix) === 0) {
localStorage.removeItem(key);
}
}
}
//@}
var numManualTests = 0;
var currentTestIdx = null;
// Make sure styleWithCss is always reset to false at the start of a test run
// (I'm looking at you, Firefox)
try { document.execCommand("stylewithcss", false, "false") } catch(e) {}
function runTests() {
//@{
// We don't ask the user to hit a key on all tests, so make sure not to
// claim more tests are going to be run than actually are.
for (var i = 0; i < tests.length; i++) {
if (localStorage.getItem(keyPrefix + JSON.stringify(tests[i])) === null) {
numManualTests++;
}
}
currentTestIdx = 0;
var runTestsButton = document.querySelector("#tests input[type=button]");
runTestsButton.parentNode.removeChild(runTestsButton);
var addTestButton = document.querySelector("#tests input[type=button]");
var input = document.querySelector("#tests label input");
// This code actually focuses and clicks everything because for some
// reason, anything else doesn't work in IE9 . . .
input.value = JSON.stringify(tests[0]);
input.focus();
addTestButton.click();
}
//@}
function addTest() {
//@{
var tr = doSetup("#tests table", 0);
var input = document.querySelector("#tests label input");
var test = JSON.parse(input.value);
doInputCell(tr, test, test.length == 2 ? command : "multitest");
doSpecCell(tr, test, test.length == 2 ? command : "multitest");
if (localStorage.getItem(keyPrefix + JSON.stringify(test)) !== null) {
// Yay, I get to cheat. Remove the overlay div so the user doesn't
// keep hitting the key, in case it takes a while.
var browserCell = document.createElement("td");
tr.appendChild(browserCell);
browserCell.innerHTML = localStorage[keyPrefix + JSON.stringify(test)];
doBrowserCellButton(browserCell, test);
document.getElementById("overlay").style.display = "";
doSameCell(tr);
runNextTest(test);
} else {
doBrowserCell(tr, test, function() {
doSameCell(tr);
runNextTest();
});
}
}
//@}
function runNextTest() {
//@{
doTearDown();
var input = document.querySelector("#tests label input");
if (currentTestIdx === null
|| currentTestIdx + 1 >= tests.length) {
currentTestIdx = null;
document.getElementById("overlay").style.display = "";
input.value = "";
return;
}
currentTestIdx++;
input.value = JSON.stringify(tests[currentTestIdx]);
input.focus();
addTest();
}
//@}
function doBrowserCell(tr, test, callback) {
//@{
var browserCell = document.createElement("td");
tr.appendChild(browserCell);
try {
var points = setupCell(browserCell, test[0]);
var testDiv = browserCell.firstChild;
// Work around weird Firefox bug:
// https://bugzilla.mozilla.org/show_bug.cgi?id=649138
document.body.appendChild(testDiv);
testDiv.onkeyup = function() {
continueBrowserCell(test, testDiv, browserCell);
callback();
};
testDiv.contentEditable = "true";
testDiv.spellcheck = false;
if (currentTestIdx === null) {
document.getElementById("testcount").style.display = "none";
} else {
document.getElementById("testcount").style.display = "";
document.querySelector("#testcount > span").textContent = numManualTests;
numManualTests--;
}
document.getElementById("overlay").style.display = "block";
testDiv.focus();
setSelection(points[0], points[1], points[2], points[3]);
// Execute any extra commands beforehand, for multitests
for (var i = 1; i < test.length - 1; i++) {
document.execCommand(test[i][0], false, test[i][1]);
}
} catch (e) {
browserCellException(e, testDiv, browserCell);
callback();
}
}
//@}
function continueBrowserCell(test, testDiv, browserCell) {
//@{
try {
testDiv.contentEditable = "inherit";
testDiv.removeAttribute("spellcheck");
var compareDiv1 = testDiv.cloneNode(true);
if (getSelection().rangeCount) {
addBrackets(getSelection().getRangeAt(0));
}
browserCell.insertBefore(testDiv, browserCell.firstChild);
if (!browserCell.childNodes.length == 2) {
throw "The cell didn't have two children. Did something spill outside the test div?";
}
compareDiv1.normalize();
// Sigh, Gecko is crazy
var treeWalker = document.createTreeWalker(compareDiv1, NodeFilter.SHOW_ELEMENT, null, null);
while (treeWalker.nextNode()) {
var remove = [].filter.call(treeWalker.currentNode.attributes, function(attrib) {
return /^_moz_/.test(attrib.name) || attrib.value == "_moz";
});
for (var i = 0; i < remove.length; i++) {
treeWalker.currentNode.removeAttribute(remove[i].name);
}
}
var compareDiv2 = compareDiv1.cloneNode(false);
compareDiv2.innerHTML = compareDiv1.innerHTML;
if (!compareDiv1.isEqualNode(compareDiv2)
&& compareDiv1.innerHTML != compareDiv2.innerHTML) {
throw "DOM does not round-trip through serialization! "
+ compareDiv1.innerHTML + " vs. " + compareDiv2.innerHTML;
}
if (!compareDiv1.isEqualNode(compareDiv2)) {
throw "DOM does not round-trip through serialization (although innerHTML is the same)! "
+ compareDiv1.innerHTML;
}
browserCell.lastChild.textContent = browserCell.firstChild.innerHTML;
} catch (e) {
browserCellException(e, testDiv, browserCell);
}
localStorage[keyPrefix + JSON.stringify(test)] = browserCell.innerHTML;
doBrowserCellButton(browserCell, test);
}
//@}
function doBrowserCellButton(browserCell, test) {
//@{
var button = document.createElement("button");
browserCell.lastChild.appendChild(button);
button.textContent = "Redo browser output";
button.onclick = function() {
localStorage.removeItem(keyPrefix + JSON.stringify(test));
var tr = browserCell.parentNode;
while (browserCell.nextSibling) {
tr.removeChild(browserCell.nextSibling);
}
tr.removeChild(browserCell);
doBrowserCell(tr, test, function() {
doSameCell(tr);
doTearDown();
document.getElementById("overlay").style.display = "";
tr.scrollIntoView();
});
};
}
//@}
// vim: foldmarker=@{,@} foldmethod=marker