Allow tests to be ignored by specific browsers

This commit is contained in:
Niklas von Hertzen 2017-08-11 22:22:10 +08:00
parent af09280c38
commit 31a9f913ed
4 changed files with 264 additions and 206 deletions

View File

@ -7,10 +7,16 @@ const slash = require('slash');
const parseRefTest = require('./parse-reftest'); const parseRefTest = require('./parse-reftest');
const outputPath = 'tests/reftests.js'; const outputPath = 'tests/reftests.js';
const ignoredTests = [ const ignoredTests = fs
'/tests/reftests/background/radial-gradient.html', .readFileSync(path.resolve(__dirname, `../tests/reftests/ignore.txt`))
'/tests/reftests/text/chinese.html' .toString()
]; .split('\n')
.filter(l => l.length)
.reduce((acc, l) => {
const m = l.match(/^(\[(.+)\])?(.+)$/i);
acc[m[3]] = m[2] ? m[2].split(',') : [];
return acc;
}, {});
glob( glob(
'../tests/reftests/**/*.html', '../tests/reftests/**/*.html',
@ -27,8 +33,7 @@ glob(
const testList = files.reduce((acc, filename) => { const testList = files.reduce((acc, filename) => {
const refTestFilename = path.resolve(__dirname, filename.replace(/\.html$/, '.txt')); const refTestFilename = path.resolve(__dirname, filename.replace(/\.html$/, '.txt'));
const name = `/${slash(path.relative('../', filename))}`; const name = `/${slash(path.relative('../', filename))}`;
if (ignoredTests.indexOf(name) === -1) { if (!Array.isArray(ignoredTests[name]) || ignoredTests[name].length) {
console.log(name);
acc[name] = fs.existsSync(refTestFilename) acc[name] = fs.existsSync(refTestFilename)
? parseRefTest(fs.readFileSync(refTestFilename).toString()) ? parseRefTest(fs.readFileSync(refTestFilename).toString())
: null; : null;
@ -36,12 +41,11 @@ glob(
console.log(`IGNORED: ${name}`); console.log(`IGNORED: ${name}`);
} }
return acc; return acc;
}, {}); }, {});
fs.writeFileSync( fs.writeFileSync(
path.resolve(__dirname, `../${outputPath}`), path.resolve(__dirname, `../${outputPath}`),
`module.exports = ${JSON.stringify(testList, null, 4)};` `module.exports = ${JSON.stringify({testList, ignoredTests}, null, 4)};`
); );
console.log(`${outputPath} updated`); console.log(`${outputPath} updated`);

View File

@ -10,7 +10,7 @@ app.use('/', express.static(path.resolve(__dirname, '../')));
const listener = app.listen(0, () => { const listener = app.listen(0, () => {
async function run() { async function run() {
const chromeless = new Chromeless(); const chromeless = new Chromeless();
const tests = Object.keys(reftests); const tests = Object.keys(reftests.testList);
let i = 0; let i = 0;
while (tests[i]) { while (tests[i]) {
const filename = tests[i]; const filename = tests[i];

View File

@ -0,0 +1,5 @@
/tests/reftests/background/radial-gradient.html
/tests/reftests/text/chinese.html
[Edge]/tests/reftests/acid2.html
[Edge]/tests/reftests/pseudoelements.html
[Edge]/tests/reftests/text/multiple.html

View File

@ -1,8 +1,10 @@
import {expect} from 'chai'; import {expect} from 'chai';
import parseRefTest from '../scripts/parse-reftest'; import parseRefTest from '../scripts/parse-reftest';
import reftests from './reftests'; import reftests from './reftests';
import querystring from 'querystring';
const DOWNLOAD_REFTESTS = true; const DOWNLOAD_REFTESTS = true;
const query = querystring.parse(location.search.replace(/^\?/, ''));
const downloadResult = (filename, data) => { const downloadResult = (filename, data) => {
const downloadUrl = URL.createObjectURL(new Blob([data], {type: 'text/plain'})); const downloadUrl = URL.createObjectURL(new Blob([data], {type: 'text/plain'}));
@ -32,7 +34,7 @@ const assertPath = (result, expected, desc) => {
case 'Circle': case 'Circle':
expect(r.x).to.be.closeTo(e.x, 10, `${desc} Circle #${i + 1} x`); expect(r.x).to.be.closeTo(e.x, 10, `${desc} Circle #${i + 1} x`);
expect(r.y).to.be.closeTo(e.y, 10, `${desc} Circle #${i + 1} y`); expect(r.y).to.be.closeTo(e.y, 10, `${desc} Circle #${i + 1} y`);
expect(r.r).to.equal(e.r, `${desc} Circle #${i + 1} r`); expect(r.r).to.be.closeTo(e.r, 5, `${desc} Circle #${i + 1} r`);
break; break;
case 'Vector': case 'Vector':
expect(r.x).to.be.closeTo(e.x, 10, `${desc} vector #${i + 1} x`); expect(r.x).to.be.closeTo(e.x, 10, `${desc} vector #${i + 1} x`);
@ -67,223 +69,270 @@ const assertPath = (result, expected, desc) => {
); );
}); });
} else { } else {
Object.keys(reftests).forEach(url => { Object.keys(reftests.testList)
describe(url, function() { .filter(test => {
this.timeout(30000); return (
var windowWidth = 800; !Array.isArray(reftests.ignoredTests[test]) ||
var windowHeight = 600; reftests.ignoredTests[test].indexOf(query.browser) === -1
var testContainer = document.createElement('iframe'); );
var REFTEST = reftests[url]; })
testContainer.width = windowWidth; .forEach(url => {
testContainer.height = windowHeight; describe(url, function() {
testContainer.style.visibility = 'hidden'; this.timeout(30000);
testContainer.style.position = 'fixed'; const windowWidth = 800;
testContainer.style.left = '10000px'; const windowHeight = 600;
const testContainer = document.createElement('iframe');
const REFTEST = reftests.testList[url];
testContainer.width = windowWidth;
testContainer.height = windowHeight;
testContainer.style.visibility = 'hidden';
testContainer.style.position = 'fixed';
testContainer.style.left = '10000px';
before(done => { before(done => {
testContainer.onload = () => done(); testContainer.onload = () => done();
testContainer.src = url + '?selenium&run=false&reftest&' + Math.random(); testContainer.src = url + '?selenium&run=false&reftest&' + Math.random();
if (hasHistoryApi) { if (hasHistoryApi) {
// Chrome does not resolve relative background urls correctly inside of a nested iframe // Chrome does not resolve relative background urls correctly inside of a nested iframe
history.replaceState(null, '', url); history.replaceState(null, '', url);
} }
document.body.appendChild(testContainer); document.body.appendChild(testContainer);
}); });
after(() => { after(() => {
if (hasHistoryApi) { if (hasHistoryApi) {
history.replaceState(null, '', testRunnerUrl); history.replaceState(null, '', testRunnerUrl);
} }
document.body.removeChild(testContainer); document.body.removeChild(testContainer);
}); });
it('Should render untainted canvas', () => { it('Should render untainted canvas', () => {
return testContainer.contentWindow return testContainer.contentWindow
.html2canvas(testContainer.contentWindow.document.documentElement, { .html2canvas(testContainer.contentWindow.document.documentElement, {
removeContainer: true, removeContainer: true,
target: [ target: [
new testContainer.contentWindow.html2canvas.CanvasRenderer(), new testContainer.contentWindow.html2canvas.CanvasRenderer(),
new testContainer.contentWindow.RefTestRenderer() new testContainer.contentWindow.RefTestRenderer()
] ]
}) })
.then(([canvas, result]) => { .then(([canvas, result]) => {
try { try {
canvas canvas
.getContext('2d') .getContext('2d')
.getImageData(0, 0, canvas.width, canvas.height); .getImageData(0, 0, canvas.width, canvas.height);
} catch (e) { } catch (e) {
return Promise.reject('Canvas is tainted'); return Promise.reject('Canvas is tainted');
} }
const delta = 10; const delta = 10;
if (REFTEST) { if (REFTEST) {
const RESULTS = parseRefTest(result); const RESULTS = parseRefTest(result);
REFTEST.forEach(({action, line, ...args}, i) => { REFTEST.forEach(({action, line, ...args}, i) => {
const RESULT = RESULTS[i]; const RESULT = RESULTS[i];
expect(RESULT.action).to.equal(action, `Line ${line}`); expect(RESULT.action).to.equal(action, `Line ${line}`);
const desc = `Line ${line} ${action}`; const desc = `Line ${line} ${action}`;
switch (action) { switch (action) {
case 'Window': case 'Window':
expect(RESULT.width).to.equal( expect(RESULT.width).to.equal(
args.width, args.width,
`${desc} width` `${desc} width`
); );
expect(RESULT.height).to.be.closeTo( expect(RESULT.height).to.be.closeTo(
args.height, args.height,
delta, delta,
`${desc} height` `${desc} height`
); );
break; break;
case 'Rectangle': case 'Rectangle':
expect(RESULT.x).to.equal(args.x, `${desc} x`); expect(RESULT.x).to.equal(args.x, `${desc} x`);
expect(RESULT.y).to.equal(args.y, `${desc} y`); expect(RESULT.y).to.equal(args.y, `${desc} y`);
expect(RESULT.width).to.equal( expect(RESULT.width).to.equal(
args.width, args.width,
`${desc} width` `${desc} width`
); );
expect(RESULT.height).to.be.closeTo( expect(RESULT.height).to.be.closeTo(
args.height, args.height,
delta, delta,
`${desc} height` `${desc} height`
); );
break; break;
case 'Fill': case 'Fill':
expect(RESULT.color).to.equal( expect(RESULT.color).to.equal(
args.color, args.color,
`${desc} color` `${desc} color`
); );
break; break;
case 'Opacity': case 'Opacity':
expect(RESULT.opacity).to.equal( expect(RESULT.opacity).to.equal(
args.opacity, args.opacity,
`${desc} opacity` `${desc} opacity`
); );
break; break;
case 'Text': case 'Text':
expect(RESULT.font).to.equal(args.font, `${desc} font`); expect(RESULT.font).to.equal(
break; args.font,
`${desc} font`
);
break;
case 'T': case 'T':
expect(RESULT.x).to.be.closeTo(args.x, 10, `${desc} x`); expect(RESULT.x).to.be.closeTo(
expect(RESULT.y).to.be.closeTo(args.y, 10, `${desc} y`); args.x,
expect(RESULT.text).to.equal(args.text, `${desc} text`); 10,
break; `${desc} x`
);
expect(RESULT.y).to.be.closeTo(
args.y,
10,
`${desc} y`
);
expect(RESULT.text).to.equal(
args.text,
`${desc} text`
);
break;
case 'Transform': case 'Transform':
expect(RESULT.x).to.be.closeTo(args.x, 10, `${desc} x`); expect(RESULT.x).to.be.closeTo(
expect(RESULT.y).to.be.closeTo(args.y, 10, `${desc} y`); args.x,
expect(RESULT.matrix).to.equal( 10,
args.matrix, `${desc} x`
`${desc} matrix` );
); expect(RESULT.y).to.be.closeTo(
break; args.y,
10,
`${desc} y`
);
expect(RESULT.matrix).to.equal(
args.matrix,
`${desc} matrix`
);
break;
case 'Repeat': case 'Repeat':
expect(RESULT.x).to.be.closeTo(args.x, 10, `${desc} x`); expect(RESULT.x).to.be.closeTo(
expect(RESULT.y).to.be.closeTo(args.y, 10, `${desc} y`); args.x,
expect(RESULT.width).to.be.closeTo( 10,
args.width, `${desc} x`
3, );
`${desc} width` expect(RESULT.y).to.be.closeTo(
); args.y,
expect(RESULT.height).to.be.closeTo( 10,
args.height, `${desc} y`
3, );
`${desc} height` expect(RESULT.width).to.be.closeTo(
); args.width,
expect(RESULT.imageSrc).to.equal( 3,
args.imageSrc, `${desc} width`
`${desc} imageSrc` );
); expect(RESULT.height).to.be.closeTo(
assertPath(RESULT.path, args.path, desc); args.height,
break; 3,
`${desc} height`
);
expect(RESULT.imageSrc).to.equal(
args.imageSrc,
`${desc} imageSrc`
);
assertPath(RESULT.path, args.path, desc);
break;
case 'Gradient': case 'Gradient':
expect(RESULT.x).to.be.closeTo(args.x, 10, `${desc} x`); expect(RESULT.x).to.be.closeTo(
expect(RESULT.y).to.be.closeTo(args.y, 10, `${desc} y`); args.x,
expect(RESULT.x0).to.be.closeTo( 10,
args.x0, `${desc} x`
5, );
`${desc} x0` expect(RESULT.y).to.be.closeTo(
); args.y,
expect(RESULT.y0).to.be.closeTo( 10,
args.y0, `${desc} y`
5, );
`${desc} y0` expect(RESULT.x0).to.be.closeTo(
); args.x0,
expect(RESULT.x1).to.be.closeTo( 5,
args.x1, `${desc} x0`
5, );
`${desc} x1` expect(RESULT.y0).to.be.closeTo(
); args.y0,
expect(RESULT.y1).to.be.closeTo( 5,
args.y1, `${desc} y0`
5, );
`${desc} y1` expect(RESULT.x1).to.be.closeTo(
); args.x1,
expect(RESULT.stops).to.equal( 5,
args.stops, `${desc} x1`
`${desc} stops` );
); expect(RESULT.y1).to.be.closeTo(
expect(RESULT.width).to.equal( args.y1,
args.width, 5,
`${desc} width` `${desc} y1`
); );
expect(RESULT.height).to.equal( expect(RESULT.stops).to.equal(
args.height, args.stops,
`${desc} height` `${desc} stops`
); );
expect(RESULT.width).to.equal(
args.width,
`${desc} width`
);
expect(RESULT.height).to.equal(
args.height,
`${desc} height`
);
break; break;
case 'Draw image': case 'Draw image':
expect(RESULT.imageSrc).to.equal( expect(RESULT.imageSrc).to.equal(
args.imageSrc, args.imageSrc,
`${desc} stops` `${desc} stops`
); );
expect(RESULT.sx).to.equal(args.sx, `${desc} sx`); expect(RESULT.sx).to.equal(args.sx, `${desc} sx`);
expect(RESULT.sy).to.equal(args.sy, `${desc} sy`); expect(RESULT.sy).to.equal(args.sy, `${desc} sy`);
expect(RESULT.dx).to.equal(args.dx, `${desc} dx`); expect(RESULT.dx).to.equal(args.dx, `${desc} dx`);
expect(RESULT.dy).to.equal(args.dy, `${desc} dy`); expect(RESULT.dy).to.equal(args.dy, `${desc} dy`);
expect(RESULT.sw).to.equal(args.sw, `${desc} sw`); expect(RESULT.sw).to.equal(args.sw, `${desc} sw`);
expect(RESULT.sh).to.equal(args.sh, `${desc} sh`); expect(RESULT.sh).to.equal(args.sh, `${desc} sh`);
expect(RESULT.dw).to.equal(args.dw, `${desc} dw`); expect(RESULT.dw).to.equal(args.dw, `${desc} dw`);
expect(RESULT.dh).to.equal(args.dh, `${desc} dh`); expect(RESULT.dh).to.equal(args.dh, `${desc} dh`);
break; break;
case 'Clip': case 'Clip':
assertPath(RESULT.path, args.path, desc); assertPath(RESULT.path, args.path, desc);
break; break;
case 'Shape': case 'Shape':
expect(RESULT.color).to.equal( expect(RESULT.color).to.equal(
args.color, args.color,
`${desc} color` `${desc} color`
); );
assertPath(RESULT.path, args.path, desc); assertPath(RESULT.path, args.path, desc);
break; break;
default: default:
console.log(RESULT); console.log(RESULT);
throw new Error(`Unrecognized action ${action}`); throw new Error(`Unrecognized action ${action}`);
} }
}); });
} else if (DOWNLOAD_REFTESTS) { } else if (DOWNLOAD_REFTESTS) {
downloadResult( downloadResult(
url.slice(url.lastIndexOf('/') + 1).replace(/\.html$/i, '.txt'), url
result .slice(url.lastIndexOf('/') + 1)
); .replace(/\.html$/i, '.txt'),
} result
}); );
}
});
});
}); });
}); });
});
} }
})(); })();