Bug 1500158 - Implement marionette support for fuzzy reftests, r=ato

This adds an extra field to the reftest comaprisons to hold the
minumum/maximum allowed differences per pixel channel and the
minumum/maximum number of pixels that may differ.

Differential Revision: https://phabricator.services.mozilla.com/D9129

--HG--
extra : moz-landing-system : lando
This commit is contained in:
James Graham 2018-11-08 17:04:55 +00:00
Родитель 22809b0ee5
Коммит 9bf3c6a089
1 изменённых файлов: 28 добавлений и 14 удалений

Просмотреть файл

@ -237,19 +237,19 @@ max-width: ${REFTEST_WIDTH}px; max-height: ${REFTEST_HEIGHT}px`;
let stack = []; let stack = [];
for (let i = references.length - 1; i >= 0; i--) { for (let i = references.length - 1; i >= 0; i--) {
let item = references[i]; let item = references[i];
stack.push([testUrl, item[0], item[1], item[2]]); stack.push([testUrl, ...item]);
} }
let done = false; let done = false;
while (stack.length && !done) { while (stack.length && !done) {
let [lhsUrl, rhsUrl, references, relation] = stack.pop(); let [lhsUrl, rhsUrl, references, relation, extras = {}] = stack.pop();
result.message += `Testing ${lhsUrl} ${relation} ${rhsUrl}\n`; result.message += `Testing ${lhsUrl} ${relation} ${rhsUrl}\n`;
let comparison; let comparison;
try { try {
comparison = await this.compareUrls( comparison = await this.compareUrls(
win, lhsUrl, rhsUrl, relation, timeout); win, lhsUrl, rhsUrl, relation, timeout, extras);
} catch (e) { } catch (e) {
comparison = {lhs: null, rhs: null, passed: false, error: e}; comparison = {lhs: null, rhs: null, passed: false, error: e};
} }
@ -318,7 +318,7 @@ max-width: ${REFTEST_WIDTH}px; max-height: ${REFTEST_HEIGHT}px`;
return result; return result;
} }
async compareUrls(win, lhsUrl, rhsUrl, relation, timeout) { async compareUrls(win, lhsUrl, rhsUrl, relation, timeout, extras) {
logger.info(`Testing ${lhsUrl} ${relation} ${rhsUrl}`); logger.info(`Testing ${lhsUrl} ${relation} ${rhsUrl}`);
// Take the reference screenshot first so that if we pause // Take the reference screenshot first so that if we pause
@ -326,44 +326,58 @@ max-width: ${REFTEST_WIDTH}px; max-height: ${REFTEST_HEIGHT}px`;
let rhs = await this.screenshot(win, rhsUrl, timeout); let rhs = await this.screenshot(win, rhsUrl, timeout);
let lhs = await this.screenshot(win, lhsUrl, timeout); let lhs = await this.screenshot(win, lhsUrl, timeout);
let maxDifferences = {};
logger.debug(`lhs canvas size ${lhs.canvas.width}x${lhs.canvas.height}`); logger.debug(`lhs canvas size ${lhs.canvas.width}x${lhs.canvas.height}`);
logger.debug(`rhs canvas size ${rhs.canvas.width}x${rhs.canvas.height}`); logger.debug(`rhs canvas size ${rhs.canvas.width}x${rhs.canvas.height}`);
let error = null;
let passed; let passed;
let error = null;
let pixelsDifferent = null;
let maxDifferences = {};
let differences;
try { try {
differences = this.windowUtils.compareCanvases( pixelsDifferent = this.windowUtils.compareCanvases(
lhs.canvas, rhs.canvas, maxDifferences); lhs.canvas, rhs.canvas, maxDifferences);
} catch (e) { } catch (e) {
differences = null;
passed = false; passed = false;
error = e; error = e;
} }
if (error === null) { if (error === null) {
passed = this.isAcceptableDifference(
maxDifferences.value, pixelsDifferent, extras.fuzzy);
switch (relation) { switch (relation) {
case "==": case "==":
passed = differences === 0;
if (!passed) { if (!passed) {
logger.info(`Found ${differences} pixels different, ` + logger.info(`Found ${pixelsDifferent} pixels different, ` +
`maximum difference per channel ${maxDifferences.value}`); `maximum difference per channel ${maxDifferences.value}`);
} }
break; break;
case "!=": case "!=":
passed = differences !== 0; passed = !passed;
break; break;
default: default:
throw new InvalidArgumentError("Reftest operator should be '==' or '!='"); throw new InvalidArgumentError("Reftest operator should be '==' or '!='");
} }
} }
return {lhs, rhs, passed, error}; return {lhs, rhs, passed, error};
} }
isAcceptableDifference(maxDifference, pixelsDifferent, allowed) {
if (!allowed) {
logger.info(`No differences allowed`);
return pixelsDifferent === 0;
}
let [allowedDiff, allowedPixels] = allowed;
logger.info(`Allowed ${allowedPixels.join("-")} pixels different, ` +
`maximum difference per channel ${allowedDiff.join("-")}`);
return ((maxDifference >= allowedDiff[0] &&
maxDifference <= allowedDiff[1]) &&
(pixelsDifferent >= allowedPixels[0] ||
pixelsDifferent <= allowedPixels[1]));
}
async screenshot(win, url, timeout) { async screenshot(win, url, timeout) {
win.innerWidth = REFTEST_WIDTH; win.innerWidth = REFTEST_WIDTH;
win.innerHeight = REFTEST_HEIGHT; win.innerHeight = REFTEST_HEIGHT;