You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/tests/ui_tests/report.py

154 lines
4.3 KiB

import base64
import filecmp
import shutil
from datetime import datetime
from distutils.dir_util import copy_tree
from itertools import zip_longest
from pathlib import Path
import dominate
from dominate.tags import a, div, h1, h2, hr, i, img, p, table, td, th, tr
from . import download
REPORTS_PATH = Path(__file__).parent.resolve() / "reports"
def _image(src):
with td():
if src:
# open image file
image = src.read_bytes()
# encode image as base64
image = base64.b64encode(image)
# convert output to str
image = image.decode()
# img(src=src.relative_to(fixture_test_path))
img(src="data:image/png;base64, " + image)
else:
i("missing")
def _header(test_name, expected_hash, actual_hash):
h1(test_name)
with div():
if actual_hash == expected_hash:
p(
"This test succeeded on UI comparison.",
style="color: green; font-weight: bold;",
)
else:
p(
"This test failed on UI comparison.",
style="color: red; font-weight: bold;",
)
p("Expected: ", expected_hash)
p("Actual: ", actual_hash)
hr()
def _write(fixture_test_path, doc, filename):
(fixture_test_path / filename).write_text(doc.render())
return fixture_test_path / filename
def _report_links(tests):
if not tests:
i("None!")
return
with table(border=1):
with tr():
th("Link to report")
for test in sorted(tests):
with tr():
path = test.relative_to(REPORTS_PATH)
td(a(test.name, href=path))
def clear_dir():
# delete and create the reports dir to clear previous entries
shutil.rmtree(REPORTS_PATH, ignore_errors=True)
REPORTS_PATH.mkdir()
(REPORTS_PATH / "failed").mkdir()
(REPORTS_PATH / "passed").mkdir()
def index():
passed_tests = list((REPORTS_PATH / "passed").iterdir())
failed_tests = list((REPORTS_PATH / "failed").iterdir())
title = "UI Test report " + datetime.now().strftime("%Y-%m-%d %H:%M:%S")
doc = dominate.document(title=title)
with doc:
h1("UI Test report")
if not failed_tests:
p("All tests succeeded!", style="color: green; font-weight: bold;")
else:
p("Some tests failed!", style="color: red; font-weight: bold;")
hr()
h2("Failed", style="color: red;")
_report_links(failed_tests)
h2("Passed", style="color: green;")
_report_links(passed_tests)
return _write(REPORTS_PATH, doc, "index.html")
def failed(fixture_test_path, test_name, actual_hash, expected_hash):
doc = dominate.document(title=test_name)
recorded_path = fixture_test_path / "recorded"
actual_path = fixture_test_path / "actual"
if not recorded_path.exists():
recorded_path.mkdir()
download.fetch_recorded(expected_hash, recorded_path)
recorded_screens = sorted(recorded_path.iterdir())
actual_screens = sorted(actual_path.iterdir())
if not recorded_screens:
return
with doc:
_header(test_name, expected_hash, actual_hash)
with table(border=1, width=600):
with tr():
th("Expected")
th("Actual")
for recorded, actual in zip_longest(recorded_screens, actual_screens):
if recorded and actual and filecmp.cmp(actual, recorded):
background = "white"
else:
background = "red"
with tr(bgcolor=background):
_image(recorded)
_image(actual)
return _write(REPORTS_PATH / "failed", doc, test_name + ".html")
def passed(fixture_test_path, test_name, actual_hash):
copy_tree(str(fixture_test_path / "actual"), str(fixture_test_path / "recorded"))
doc = dominate.document(title=test_name)
actual_path = fixture_test_path / "actual"
actual_screens = sorted(actual_path.iterdir())
with doc:
_header(test_name, actual_hash, actual_hash)
with table(border=1):
with tr():
th("Recorded")
for screen in actual_screens:
with tr():
_image(screen)
return _write(REPORTS_PATH / "passed", doc, test_name + ".html")