371967f791
By using npm ci, we can make sure the versions of the helper libraries (e.g. Karma, Jasmine) we are testing with locally is the same as the versions we are using in the continuous integration system. The copying is needed because our docker recipe forces us to run as not root, and this was causing some issues. As a result, I changed the canvaskit test/perf to not re-use the same file as pathkit does so copying was easier and the dependencies between the two modules is broken. Bug: skia:11077 Change-Id: Ib05890d666d3507d4f724a4ae298484629c7932a Reviewed-on: https://skia-review.googlesource.com/c/skia/+/343503 Reviewed-by: Kevin Lubick <kjlubick@google.com>
130 lines
4.5 KiB
JavaScript
130 lines
4.5 KiB
JavaScript
const REPORT_URL = 'http://localhost:8081/report_gold_data'
|
|
// Set this to enforce that the gold server must be up.
|
|
// Typically used for debugging.
|
|
const fail_on_no_gold = false;
|
|
|
|
function reportCanvas(canvas, testname, outputType='canvas') {
|
|
let b64 = canvas.toDataURL('image/png');
|
|
return _report(b64, outputType, testname);
|
|
}
|
|
|
|
function reportSVG(svg, testname) {
|
|
// This converts an SVG to a base64 encoded PNG. It basically creates an
|
|
// <img> element that takes the inlined SVG and draws it on a canvas.
|
|
// The trick is we have to wait until the image is loaded, thus the Promise
|
|
// wrapping below.
|
|
let svgStr = svg.outerHTML;
|
|
let tempImg = document.createElement('img');
|
|
|
|
let tempCanvas = document.createElement('canvas');
|
|
let canvasCtx = tempCanvas.getContext('2d');
|
|
setCanvasSize(canvasCtx, svg.getAttribute('width'), svg.getAttribute('height'));
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
tempImg.onload = () => {
|
|
canvasCtx.drawImage(tempImg, 0, 0);
|
|
let b64 = tempCanvas.toDataURL('image/png');
|
|
_report(b64, 'svg', testname).then(() => {
|
|
resolve();
|
|
}).catch((e) => reject(e));
|
|
};
|
|
tempImg.setAttribute('src', 'data:image/svg+xml;,' + svgStr);
|
|
});
|
|
}
|
|
|
|
// For tests that just do a simple path and return it as a string, wrap it in
|
|
// a proper svg and send it off. Supports fill (nofill means just stroke it).
|
|
// This uses the "standard" size of 600x600.
|
|
function reportSVGString(svgstr, testname, fillRule='nofill') {
|
|
let newPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
newPath.setAttribute('stroke', 'black');
|
|
if (fillRule !== 'nofill') {
|
|
newPath.setAttribute('fill', 'orange');
|
|
newPath.setAttribute('fill-rule', fillRule);
|
|
} else {
|
|
newPath.setAttribute('fill', 'rgba(255,255,255,0.0)');
|
|
}
|
|
newPath.setAttribute('d', svgstr);
|
|
let newSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
newSVG.appendChild(newPath);
|
|
// helps with the conversion to PNG.
|
|
newSVG.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
|
|
newSVG.setAttribute('width', 600);
|
|
newSVG.setAttribute('height', 600);
|
|
return reportSVG(newSVG, testname);
|
|
}
|
|
|
|
// Reports a canvas and then an SVG of this path. Puts it on a standard size canvas.
|
|
function reportPath(path, testname, done) {
|
|
let canvas = document.createElement('canvas');
|
|
let canvasCtx = canvas.getContext('2d');
|
|
// Set canvas size and make it a bit bigger to zoom in on the lines
|
|
standardizedCanvasSize(canvasCtx);
|
|
canvasCtx.stroke(path.toPath2D());
|
|
|
|
let svgStr = path.toSVGString();
|
|
|
|
return reportCanvas(canvas, testname).then(() => {
|
|
reportSVGString(svgStr, testname).then(() => {
|
|
done();
|
|
}).catch(reportError(done));
|
|
}).catch(reportError(done));
|
|
}
|
|
|
|
// data is a base64 encoded png, outputType is the value that goes with the
|
|
// key 'config' when reporting.
|
|
function _report(data, outputType, testname) {
|
|
return fetch(REPORT_URL, {
|
|
method: 'POST',
|
|
mode: 'no-cors',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
'output_type': outputType,
|
|
'data': data,
|
|
'test_name': testname,
|
|
})
|
|
}).then(() => console.log(`Successfully reported ${testname} to gold aggregator`));
|
|
}
|
|
|
|
function reportError(done) {
|
|
return (e) => {
|
|
console.log("Error with fetching. Likely could not connect to aggregator server", e.message);
|
|
if (fail_on_no_gold) {
|
|
expect(e).toBeUndefined();
|
|
}
|
|
done();
|
|
};
|
|
}
|
|
|
|
function setCanvasSize(ctx, width, height) {
|
|
ctx.canvas.width = width;
|
|
ctx.canvas.height = height;
|
|
}
|
|
|
|
function standardizedCanvasSize(ctx) {
|
|
setCanvasSize(ctx, 600, 600);
|
|
}
|
|
|
|
// A wrapper to catch and print a stacktrace to the logs.
|
|
// Exceptions normally shows up in the browser console,
|
|
// but not in the logs that appear on the bots AND a thrown
|
|
// exception will normally cause a test to time out.
|
|
// This wrapper mitigates both those pain points.
|
|
function catchException(done, fn) {
|
|
return () => {
|
|
try {
|
|
fn()
|
|
} catch (e) {
|
|
console.log('Failed with the following error', e);
|
|
expect(e).toBeFalsy();
|
|
debugger;
|
|
done();
|
|
}
|
|
// We don't call done with finally because
|
|
// that would make the break the asynchronous nature
|
|
// of fn().
|
|
}
|
|
}
|