diff --git a/scripts/create-reftest-list.js b/scripts/create-reftest-list.js index 0e4a487..308ab64 100644 --- a/scripts/create-reftest-list.js +++ b/scripts/create-reftest-list.js @@ -7,10 +7,16 @@ const slash = require('slash'); const parseRefTest = require('./parse-reftest'); const outputPath = 'tests/reftests.js'; -const ignoredTests = [ - '/tests/reftests/background/radial-gradient.html', - '/tests/reftests/text/chinese.html' -]; +const ignoredTests = fs + .readFileSync(path.resolve(__dirname, `../tests/reftests/ignore.txt`)) + .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( '../tests/reftests/**/*.html', @@ -27,8 +33,7 @@ glob( const testList = files.reduce((acc, filename) => { const refTestFilename = path.resolve(__dirname, filename.replace(/\.html$/, '.txt')); const name = `/${slash(path.relative('../', filename))}`; - if (ignoredTests.indexOf(name) === -1) { - console.log(name); + if (!Array.isArray(ignoredTests[name]) || ignoredTests[name].length) { acc[name] = fs.existsSync(refTestFilename) ? parseRefTest(fs.readFileSync(refTestFilename).toString()) : null; @@ -36,12 +41,11 @@ glob( console.log(`IGNORED: ${name}`); } - return acc; }, {}); fs.writeFileSync( path.resolve(__dirname, `../${outputPath}`), - `module.exports = ${JSON.stringify(testList, null, 4)};` + `module.exports = ${JSON.stringify({testList, ignoredTests}, null, 4)};` ); console.log(`${outputPath} updated`); diff --git a/scripts/create-reftests.js b/scripts/create-reftests.js index 9d38f8b..168529a 100644 --- a/scripts/create-reftests.js +++ b/scripts/create-reftests.js @@ -10,7 +10,7 @@ app.use('/', express.static(path.resolve(__dirname, '../'))); const listener = app.listen(0, () => { async function run() { const chromeless = new Chromeless(); - const tests = Object.keys(reftests); + const tests = Object.keys(reftests.testList); let i = 0; while (tests[i]) { const filename = tests[i]; diff --git a/tests/reftests/ignore.txt b/tests/reftests/ignore.txt new file mode 100644 index 0000000..f037e33 --- /dev/null +++ b/tests/reftests/ignore.txt @@ -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 diff --git a/tests/testrunner.js b/tests/testrunner.js index 64f3ec6..ffa9539 100644 --- a/tests/testrunner.js +++ b/tests/testrunner.js @@ -1,8 +1,10 @@ import {expect} from 'chai'; import parseRefTest from '../scripts/parse-reftest'; import reftests from './reftests'; +import querystring from 'querystring'; const DOWNLOAD_REFTESTS = true; +const query = querystring.parse(location.search.replace(/^\?/, '')); const downloadResult = (filename, data) => { const downloadUrl = URL.createObjectURL(new Blob([data], {type: 'text/plain'})); @@ -32,7 +34,7 @@ const assertPath = (result, expected, desc) => { case 'Circle': 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.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; case 'Vector': expect(r.x).to.be.closeTo(e.x, 10, `${desc} vector #${i + 1} x`); @@ -67,223 +69,270 @@ const assertPath = (result, expected, desc) => { ); }); } else { - Object.keys(reftests).forEach(url => { - describe(url, function() { - this.timeout(30000); - var windowWidth = 800; - var windowHeight = 600; - var testContainer = document.createElement('iframe'); - var REFTEST = reftests[url]; - testContainer.width = windowWidth; - testContainer.height = windowHeight; - testContainer.style.visibility = 'hidden'; - testContainer.style.position = 'fixed'; - testContainer.style.left = '10000px'; + Object.keys(reftests.testList) + .filter(test => { + return ( + !Array.isArray(reftests.ignoredTests[test]) || + reftests.ignoredTests[test].indexOf(query.browser) === -1 + ); + }) + .forEach(url => { + describe(url, function() { + this.timeout(30000); + const windowWidth = 800; + 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 => { - testContainer.onload = () => done(); + before(done => { + testContainer.onload = () => done(); - testContainer.src = url + '?selenium&run=false&reftest&' + Math.random(); - if (hasHistoryApi) { - // Chrome does not resolve relative background urls correctly inside of a nested iframe - history.replaceState(null, '', url); - } + testContainer.src = url + '?selenium&run=false&reftest&' + Math.random(); + if (hasHistoryApi) { + // Chrome does not resolve relative background urls correctly inside of a nested iframe + history.replaceState(null, '', url); + } - document.body.appendChild(testContainer); - }); - after(() => { - if (hasHistoryApi) { - history.replaceState(null, '', testRunnerUrl); - } - document.body.removeChild(testContainer); - }); - it('Should render untainted canvas', () => { - return testContainer.contentWindow - .html2canvas(testContainer.contentWindow.document.documentElement, { - removeContainer: true, - target: [ - new testContainer.contentWindow.html2canvas.CanvasRenderer(), - new testContainer.contentWindow.RefTestRenderer() - ] - }) - .then(([canvas, result]) => { - try { - canvas - .getContext('2d') - .getImageData(0, 0, canvas.width, canvas.height); - } catch (e) { - return Promise.reject('Canvas is tainted'); - } + document.body.appendChild(testContainer); + }); + after(() => { + if (hasHistoryApi) { + history.replaceState(null, '', testRunnerUrl); + } + document.body.removeChild(testContainer); + }); + it('Should render untainted canvas', () => { + return testContainer.contentWindow + .html2canvas(testContainer.contentWindow.document.documentElement, { + removeContainer: true, + target: [ + new testContainer.contentWindow.html2canvas.CanvasRenderer(), + new testContainer.contentWindow.RefTestRenderer() + ] + }) + .then(([canvas, result]) => { + try { + canvas + .getContext('2d') + .getImageData(0, 0, canvas.width, canvas.height); + } catch (e) { + return Promise.reject('Canvas is tainted'); + } - const delta = 10; + const delta = 10; - if (REFTEST) { - const RESULTS = parseRefTest(result); - REFTEST.forEach(({action, line, ...args}, i) => { - const RESULT = RESULTS[i]; - expect(RESULT.action).to.equal(action, `Line ${line}`); + if (REFTEST) { + const RESULTS = parseRefTest(result); + REFTEST.forEach(({action, line, ...args}, i) => { + const RESULT = RESULTS[i]; + expect(RESULT.action).to.equal(action, `Line ${line}`); - const desc = `Line ${line} ${action}`; + const desc = `Line ${line} ${action}`; - switch (action) { - case 'Window': - expect(RESULT.width).to.equal( - args.width, - `${desc} width` - ); - expect(RESULT.height).to.be.closeTo( - args.height, - delta, - `${desc} height` - ); - break; + switch (action) { + case 'Window': + expect(RESULT.width).to.equal( + args.width, + `${desc} width` + ); + expect(RESULT.height).to.be.closeTo( + args.height, + delta, + `${desc} height` + ); + break; - case 'Rectangle': - expect(RESULT.x).to.equal(args.x, `${desc} x`); - expect(RESULT.y).to.equal(args.y, `${desc} y`); - expect(RESULT.width).to.equal( - args.width, - `${desc} width` - ); - expect(RESULT.height).to.be.closeTo( - args.height, - delta, - `${desc} height` - ); - break; + case 'Rectangle': + expect(RESULT.x).to.equal(args.x, `${desc} x`); + expect(RESULT.y).to.equal(args.y, `${desc} y`); + expect(RESULT.width).to.equal( + args.width, + `${desc} width` + ); + expect(RESULT.height).to.be.closeTo( + args.height, + delta, + `${desc} height` + ); + break; - case 'Fill': - expect(RESULT.color).to.equal( - args.color, - `${desc} color` - ); - break; + case 'Fill': + expect(RESULT.color).to.equal( + args.color, + `${desc} color` + ); + break; - case 'Opacity': - expect(RESULT.opacity).to.equal( - args.opacity, - `${desc} opacity` - ); - break; + case 'Opacity': + expect(RESULT.opacity).to.equal( + args.opacity, + `${desc} opacity` + ); + break; - case 'Text': - expect(RESULT.font).to.equal(args.font, `${desc} font`); - break; + case 'Text': + expect(RESULT.font).to.equal( + args.font, + `${desc} font` + ); + break; - case 'T': - expect(RESULT.x).to.be.closeTo(args.x, 10, `${desc} x`); - expect(RESULT.y).to.be.closeTo(args.y, 10, `${desc} y`); - expect(RESULT.text).to.equal(args.text, `${desc} text`); - break; + case 'T': + expect(RESULT.x).to.be.closeTo( + args.x, + 10, + `${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': - expect(RESULT.x).to.be.closeTo(args.x, 10, `${desc} x`); - expect(RESULT.y).to.be.closeTo(args.y, 10, `${desc} y`); - expect(RESULT.matrix).to.equal( - args.matrix, - `${desc} matrix` - ); - break; + case 'Transform': + expect(RESULT.x).to.be.closeTo( + args.x, + 10, + `${desc} x` + ); + expect(RESULT.y).to.be.closeTo( + args.y, + 10, + `${desc} y` + ); + expect(RESULT.matrix).to.equal( + args.matrix, + `${desc} matrix` + ); + break; - case 'Repeat': - expect(RESULT.x).to.be.closeTo(args.x, 10, `${desc} x`); - expect(RESULT.y).to.be.closeTo(args.y, 10, `${desc} y`); - expect(RESULT.width).to.be.closeTo( - args.width, - 3, - `${desc} width` - ); - expect(RESULT.height).to.be.closeTo( - args.height, - 3, - `${desc} height` - ); - expect(RESULT.imageSrc).to.equal( - args.imageSrc, - `${desc} imageSrc` - ); - assertPath(RESULT.path, args.path, desc); - break; + case 'Repeat': + expect(RESULT.x).to.be.closeTo( + args.x, + 10, + `${desc} x` + ); + expect(RESULT.y).to.be.closeTo( + args.y, + 10, + `${desc} y` + ); + expect(RESULT.width).to.be.closeTo( + args.width, + 3, + `${desc} width` + ); + expect(RESULT.height).to.be.closeTo( + args.height, + 3, + `${desc} height` + ); + expect(RESULT.imageSrc).to.equal( + args.imageSrc, + `${desc} imageSrc` + ); + assertPath(RESULT.path, args.path, desc); + break; - case 'Gradient': - expect(RESULT.x).to.be.closeTo(args.x, 10, `${desc} x`); - expect(RESULT.y).to.be.closeTo(args.y, 10, `${desc} y`); - expect(RESULT.x0).to.be.closeTo( - args.x0, - 5, - `${desc} x0` - ); - expect(RESULT.y0).to.be.closeTo( - args.y0, - 5, - `${desc} y0` - ); - expect(RESULT.x1).to.be.closeTo( - args.x1, - 5, - `${desc} x1` - ); - expect(RESULT.y1).to.be.closeTo( - args.y1, - 5, - `${desc} y1` - ); - expect(RESULT.stops).to.equal( - args.stops, - `${desc} stops` - ); - expect(RESULT.width).to.equal( - args.width, - `${desc} width` - ); - expect(RESULT.height).to.equal( - args.height, - `${desc} height` - ); + case 'Gradient': + expect(RESULT.x).to.be.closeTo( + args.x, + 10, + `${desc} x` + ); + expect(RESULT.y).to.be.closeTo( + args.y, + 10, + `${desc} y` + ); + expect(RESULT.x0).to.be.closeTo( + args.x0, + 5, + `${desc} x0` + ); + expect(RESULT.y0).to.be.closeTo( + args.y0, + 5, + `${desc} y0` + ); + expect(RESULT.x1).to.be.closeTo( + args.x1, + 5, + `${desc} x1` + ); + expect(RESULT.y1).to.be.closeTo( + args.y1, + 5, + `${desc} y1` + ); + expect(RESULT.stops).to.equal( + args.stops, + `${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': - expect(RESULT.imageSrc).to.equal( - args.imageSrc, - `${desc} stops` - ); - expect(RESULT.sx).to.equal(args.sx, `${desc} sx`); - expect(RESULT.sy).to.equal(args.sy, `${desc} sy`); - expect(RESULT.dx).to.equal(args.dx, `${desc} dx`); - expect(RESULT.dy).to.equal(args.dy, `${desc} dy`); - expect(RESULT.sw).to.equal(args.sw, `${desc} sw`); - expect(RESULT.sh).to.equal(args.sh, `${desc} sh`); - expect(RESULT.dw).to.equal(args.dw, `${desc} dw`); - expect(RESULT.dh).to.equal(args.dh, `${desc} dh`); - break; + case 'Draw image': + expect(RESULT.imageSrc).to.equal( + args.imageSrc, + `${desc} stops` + ); + expect(RESULT.sx).to.equal(args.sx, `${desc} sx`); + expect(RESULT.sy).to.equal(args.sy, `${desc} sy`); + expect(RESULT.dx).to.equal(args.dx, `${desc} dx`); + expect(RESULT.dy).to.equal(args.dy, `${desc} dy`); + expect(RESULT.sw).to.equal(args.sw, `${desc} sw`); + expect(RESULT.sh).to.equal(args.sh, `${desc} sh`); + expect(RESULT.dw).to.equal(args.dw, `${desc} dw`); + expect(RESULT.dh).to.equal(args.dh, `${desc} dh`); + break; - case 'Clip': - assertPath(RESULT.path, args.path, desc); - break; + case 'Clip': + assertPath(RESULT.path, args.path, desc); + break; - case 'Shape': - expect(RESULT.color).to.equal( - args.color, - `${desc} color` - ); - assertPath(RESULT.path, args.path, desc); - break; + case 'Shape': + expect(RESULT.color).to.equal( + args.color, + `${desc} color` + ); + assertPath(RESULT.path, args.path, desc); + break; - default: - console.log(RESULT); - throw new Error(`Unrecognized action ${action}`); - } - }); - } else if (DOWNLOAD_REFTESTS) { - downloadResult( - url.slice(url.lastIndexOf('/') + 1).replace(/\.html$/i, '.txt'), - result - ); - } - }); + default: + console.log(RESULT); + throw new Error(`Unrecognized action ${action}`); + } + }); + } else if (DOWNLOAD_REFTESTS) { + downloadResult( + url + .slice(url.lastIndexOf('/') + 1) + .replace(/\.html$/i, '.txt'), + result + ); + } + }); + }); }); }); - }); } })();