feat(tests): show screenshot diff

[no changelog]
pull/3572/head
cepetr 3 months ago committed by cepetr
parent 5f016a896a
commit fab70c7dba

@ -56,6 +56,12 @@ def image_column(hash: str | None, cur_dir: Path, img_id: str | None = None) ->
i("missing")
def diff_column() -> None:
"""Put diff image into table as one cell."""
with td(bgcolor="white"):
a("Click to show")
def _relative_path(cur_dir: Path, path_to: Path) -> str:
"""Find best relative path to refer to path_to from cur_dir."""
cur_dir = cur_dir.resolve()
@ -91,6 +97,7 @@ def diff_table(diff: Iterable[tuple[str | None, str | None]], cur_dir: Path) ->
background = "white"
else:
background = "red"
with tr(bgcolor=background):
with tr(bgcolor=background, onclick="createDiff(this)"):
image_column(left, cur_dir)
image_column(right, cur_dir)
diff_column()

@ -69,6 +69,12 @@ tr.bad a:visited {
width: 256px;
}
.model-TR canvas {
image-rendering: pixelated;
width: 256px;
}
/* GIF styling */
/* Style the input field */

@ -162,5 +162,67 @@ function onLoad() {
}
}
var module = {};
function getImageData(image) {
// Get original image size
const width = image.naturalWidth;
const height = image.naturalHeight;
// Create 2D canvas
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
let context = canvas.getContext("2d");
// Draw the image
context.drawImage(image, 0, 0);
// Return image raw data
return context.getImageData(0, 0, width, height);
}
function createTableDiff(table) {
// Process all rows in the table\
// (if the row doesn't contain two images, it's skipped)
table.querySelectorAll("tr").forEach((row) => {
createRowDiff(row);
});
}
function createRowDiff(row) {
// Find an element with recorded image
recImg = row.querySelector("td:nth-child(1) > img");
// Find an element with the current image
curImg = row.querySelector("td:nth-child(2) > img");
// Skip if we haven't found two images
if (recImg == null || curImg == null) {
return;
}
// Get images's raw data
recData = getImageData(recImg);
curData = getImageData(curImg);
const width = recImg.naturalWidth;
const height = recImg.naturalHeight;
// Create canvas for diff result
let difImg = document.createElement('canvas')
difImg.width = width;
difImg.height = height;
let difCtx = difImg.getContext("2d")
// Process differences
const difData = difCtx.createImageData(width, height);
options = {threshold: 0.0, includeAA: true};
pixelmatch(recData.data, curData.data, difData.data, width, height, options);
difCtx.putImageData(difData, 0, 0);
// Put the result into the 3rd column
row.querySelector("td:nth-child(3)").replaceChildren(difImg)
}
window.onload = onLoad

@ -7,7 +7,22 @@ from pathlib import Path
import dominate
import dominate.tags as t
from dominate.tags import a, div, h1, h2, hr, i, p, span, strong, table, td, th, tr
from dominate.tags import (
a,
div,
h1,
h2,
hr,
i,
p,
script,
span,
strong,
table,
td,
th,
tr,
)
from dominate.util import text
from ..common import FixturesType, TestCase, TestResult
@ -338,7 +353,13 @@ def failed(result: TestResult) -> Path:
doc = document(
title=result.test.id, actual_hash=result.actual_hash, model=result.test.model
)
with doc.head:
script(
type="text/javascript", src="https://cdn.jsdelivr.net/npm/pixelmatch@5.3.0"
)
with doc:
_header(result.test.id, result.expected_hash, result.actual_hash)
with div(id="markbox", _class="script-hidden"):
@ -353,10 +374,11 @@ def failed(result: TestResult) -> Path:
strong("WARNING:")
text(" failed to download recorded fixtures. Is this a new test case?")
with table(border=1, width=600):
with table(border=1, width=600, onclick="createTableDiff(this)"):
with tr():
th("Expected")
th("Actual")
th("Diff")
html.diff_table(result.diff_lines(), TESTREPORT_PATH / "failed")

Loading…
Cancel
Save