gecko-dev/browser/base/content/test/general/browser_parsable_css.js
Patrick Brosset 432a34f1a4 Bug 985597 - Use the AnonymousContent Document API for the highlighters; r=miker r=Gijs
--HG--
rename : browser/themes/shared/devtools/highlighter.inc.css => browser/themes/shared/devtools/highlighter.css
2014-11-06 13:04:23 +01:00

128 lines
4.8 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/* This list allows pre-existing or 'unfixable' CSS issues to remain, while we
* detect newly occurring issues in shipping CSS. It is a list of objects
* specifying conditions under which an error should be ignored.
*
* Every property of the objects in it needs to consist of a regular expression
* matching the offending error. If an object has multiple regex criteria, they
* ALL need to match an error in order for that error not to cause a test
* failure. */
const kWhitelist = [
// Cleopatra is imported as-is, see bug 1004421.
{sourceName: /cleopatra.*(tree|ui)\.css/i},
// CodeMirror is imported as-is, see bug 1004423.
{sourceName: /codemirror\.css/i},
// PDFjs is futureproofing its pseudoselectors, and those rules are dropped.
{sourceName: /web\/viewer\.css/i,
errorMessage: /Unknown pseudo-class.*(fullscreen|selection)/i},
// Tracked in bug 1004428.
{sourceName: /aboutaccounts\/(main|normalize)\.css/i},
// TokBox SDK assets, see bug 1032469.
{sourceName: /loop\/.*sdk-content\/.*\.css$/i},
// Highlighter CSS uses chrome-only pseudo-class, see bug 985597.
{sourceName: /highlighter\.css/i,
errorMessage: /Unknown pseudo-class.*moz-native-anonymous/i}
];
let moduleLocation = gTestPath.replace(/\/[^\/]*$/i, "/parsingTestHelpers.jsm");
let {generateURIsFromDirTree} = Cu.import(moduleLocation, {});
/**
* Check if an error should be ignored due to matching one of the whitelist
* objects defined in kWhitelist
*
* @param aErrorObject the error to check
* @return true if the error should be ignored, false otherwise.
*/
function ignoredError(aErrorObject) {
for (let whitelistItem of kWhitelist) {
let matches = true;
for (let prop in whitelistItem) {
if (!whitelistItem[prop].test(aErrorObject[prop] || "")) {
matches = false;
break;
}
}
if (matches) {
return true;
}
}
return false;
}
add_task(function checkAllTheCSS() {
let appDir = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
// This asynchronously produces a list of URLs (sadly, mostly sync on our
// test infrastructure because it runs against jarfiles there, and
// our zipreader APIs are all sync)
let uris = yield generateURIsFromDirTree(appDir, ".css");
// Create a clean iframe to load all the files into:
let hiddenWin = Services.appShell.hiddenDOMWindow;
let iframe = hiddenWin.document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe");
hiddenWin.document.documentElement.appendChild(iframe);
let doc = iframe.contentWindow.document;
// Listen for errors caused by the CSS:
let errorListener = {
observe: function(aMessage) {
if (!aMessage || !(aMessage instanceof Ci.nsIScriptError)) {
return;
}
// Only care about CSS errors generated by our iframe:
if (aMessage.category.contains("CSS") && aMessage.innerWindowID === 0 && aMessage.outerWindowID === 0) {
// Check if this error is whitelisted in kWhitelist
if (!ignoredError(aMessage)) {
ok(false, "Got error message for " + aMessage.sourceName + ": " + aMessage.errorMessage);
errors++;
} else {
info("Ignored error for " + aMessage.sourceName + " because of filter.");
}
}
}
};
// We build a list of promises that get resolved when their respective
// files have loaded and produced no errors.
let allPromises = [];
let errors = 0;
// Register the error listener to keep track of errors.
Services.console.registerListener(errorListener);
for (let uri of uris) {
let linkEl = doc.createElement("link");
linkEl.setAttribute("rel", "stylesheet");
let promiseForThisSpec = Promise.defer();
let onLoad = (e) => {
promiseForThisSpec.resolve();
linkEl.removeEventListener("load", onLoad);
linkEl.removeEventListener("error", onError);
};
let onError = (e) => {
promiseForThisSpec.reject({error: e, href: linkEl.getAttribute("href")});
linkEl.removeEventListener("load", onLoad);
linkEl.removeEventListener("error", onError);
};
linkEl.addEventListener("load", onLoad);
linkEl.addEventListener("error", onError);
linkEl.setAttribute("type", "text/css");
linkEl.setAttribute("href", uri.spec);
allPromises.push(promiseForThisSpec.promise);
doc.head.appendChild(linkEl);
}
// Wait for all the files to have actually loaded:
yield Promise.all(allPromises);
// Count errors (the test output will list actual issues for us, as well
// as the ok(false) in the error listener)
is(errors, 0, "All the styles (" + allPromises.length + ") loaded without errors.");
// Clean up to avoid leaks:
Services.console.unregisterListener(errorListener);
iframe.remove();
doc.head.innerHTML = '';
doc = null;
iframe = null;
});