mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-06-25 17:32:34 +00:00
141 lines
4.0 KiB
Python
141 lines
4.0 KiB
Python
from __future__ import annotations
|
|
|
|
import shutil
|
|
import urllib.parse
|
|
from pathlib import Path
|
|
from typing import Iterable
|
|
|
|
from dominate import document
|
|
from dominate.tags import a, i, img, span, table, td, th, tr
|
|
|
|
from ..common import UI_TESTS_DIR
|
|
|
|
_COLLAPSE_UNCHANGED_THRESHOLD = 10
|
|
_IMAGE_DIR = UI_TESTS_DIR / "images"
|
|
|
|
|
|
def set_image_dir(path: Path) -> None:
|
|
global _IMAGE_DIR
|
|
_IMAGE_DIR = path
|
|
|
|
|
|
def store_images(screens: Iterable[Path], hashes: Iterable[str]) -> None:
|
|
for screen, hash in zip(screens, hashes):
|
|
shutil.copy(screen, _IMAGE_DIR / f"{hash}.png")
|
|
|
|
|
|
def report_links(
|
|
tests: list[Path], reports_path: Path, actual_hashes: dict[str, str] | None = None
|
|
) -> None:
|
|
if actual_hashes is None:
|
|
actual_hashes = {}
|
|
|
|
if not tests:
|
|
i("None!")
|
|
return
|
|
with table(border=1):
|
|
with tr():
|
|
th("Link to report")
|
|
for test in sorted(tests):
|
|
with tr(data_actual_hash=actual_hashes.get(test.stem, "")):
|
|
urlsafe = urllib.parse.quote(test.name)
|
|
path = test.with_name(urlsafe).relative_to(reports_path)
|
|
td(a(test.name, href=path))
|
|
|
|
|
|
def write(fixture_test_path: Path, doc: document, filename: str) -> Path:
|
|
(fixture_test_path / filename).write_text(doc.render())
|
|
return fixture_test_path / filename
|
|
|
|
|
|
def image_column(hash: str | None, cur_dir: Path, img_id: str | None = None) -> None:
|
|
"""Put image into table as one cell."""
|
|
with td():
|
|
if hash:
|
|
image_link(hash, cur_dir, img_id=img_id)
|
|
else:
|
|
i("missing")
|
|
|
|
|
|
def diff_column() -> None:
|
|
"""Put diff image into table as one cell."""
|
|
with td(bgcolor="white"):
|
|
a("N/A")
|
|
|
|
|
|
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()
|
|
path_to = path_to.resolve()
|
|
if not cur_dir.is_dir():
|
|
cur_dir = cur_dir.parent
|
|
|
|
common = cur_dir
|
|
while common not in path_to.parents:
|
|
common = common.parent
|
|
ascent = len(cur_dir.parts) - len(common.parts)
|
|
relpath = path_to.relative_to(common)
|
|
components = [".."] * ascent + list(relpath.parts)
|
|
return "/".join(components)
|
|
|
|
|
|
def image_link(
|
|
hash: str, cur_dir: Path, title: str = "", img_id: str | None = None
|
|
) -> None:
|
|
"""Put image into table as one cell."""
|
|
path = _IMAGE_DIR / f"{hash}.png"
|
|
img(
|
|
id=img_id,
|
|
src=_relative_path(cur_dir, path),
|
|
title=title,
|
|
loading="lazy",
|
|
onload="imageLoaded(this)",
|
|
)
|
|
|
|
|
|
def diff_row(
|
|
left: str | None,
|
|
right: str | None,
|
|
cur_dir: Path,
|
|
bgcolor: str,
|
|
hidden: bool = False,
|
|
):
|
|
with tr(bgcolor=bgcolor, _class="hidden" if hidden else ""):
|
|
image_column(left, cur_dir)
|
|
image_column(right, cur_dir)
|
|
diff_column()
|
|
|
|
|
|
def collapsible_rows(rows, cur_dir):
|
|
collapse = len(rows) > 0
|
|
for left, right in rows:
|
|
diff_row(left, right, cur_dir, "white", collapse)
|
|
if collapse:
|
|
with tr(bgcolor="yellow"):
|
|
with td(colspan=3, _class="showLink"):
|
|
span(f"{len(rows)} hidden")
|
|
a("show all", href="#", onclick="return showAllHidden()")
|
|
|
|
|
|
def diff_table(diff: Iterable[tuple[str | None, str | None]], cur_dir: Path) -> None:
|
|
rows = list(diff)
|
|
has_diff = any(l != r for l, r in rows)
|
|
|
|
if (
|
|
not has_diff or len(rows) <= _COLLAPSE_UNCHANGED_THRESHOLD
|
|
): # show all without collapsing
|
|
for left, right in rows:
|
|
color = "red" if left != right else "white"
|
|
diff_row(left, right, cur_dir, color)
|
|
else:
|
|
unchanged_buffer = []
|
|
for left, right in rows:
|
|
is_diff = left != right
|
|
if not is_diff:
|
|
unchanged_buffer.append((left, right))
|
|
else:
|
|
collapsible_rows(unchanged_buffer, cur_dir)
|
|
unchanged_buffer.clear()
|
|
diff_row(left, right, cur_dir, "red")
|
|
collapsible_rows(unchanged_buffer, cur_dir)
|