78 lines
2.7 KiB
Python
Executable file
78 lines
2.7 KiB
Python
Executable file
from __future__ import annotations
|
|
|
|
from html.parser import HTMLParser
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
|
|
NODE = shutil.which("node")
|
|
APP_JS = Path("src/yolo_webui/static/app.js")
|
|
INDEX_HTML = Path("src/yolo_webui/static/index.html")
|
|
STYLE_CSS = Path("src/yolo_webui/static/style.css")
|
|
|
|
|
|
class _MarkupCollector(HTMLParser):
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.by_id: dict[str, dict[str, str | None]] = {}
|
|
self.options: dict[str, str] = {}
|
|
self._option_value: str | None = None
|
|
|
|
def handle_starttag(
|
|
self,
|
|
tag: str,
|
|
attrs: list[tuple[str, str | None]],
|
|
) -> None:
|
|
attributes = dict(attrs)
|
|
if element_id := attributes.get("id"):
|
|
self.by_id[element_id] = attributes
|
|
if tag == "option":
|
|
self._option_value = attributes.get("value")
|
|
|
|
def handle_data(self, data: str) -> None:
|
|
if self._option_value is not None:
|
|
self.options[self._option_value] = (
|
|
self.options.get(self._option_value, "") + data
|
|
).strip()
|
|
|
|
def handle_endtag(self, tag: str) -> None:
|
|
if tag == "option":
|
|
self._option_value = None
|
|
|
|
|
|
@pytest.mark.skipif(NODE is None, reason="Node.js is required for frontend checks")
|
|
def test_frontend_javascript_syntax() -> None:
|
|
subprocess.run([NODE, "--check", str(APP_JS)], check=True)
|
|
|
|
|
|
@pytest.mark.skipif(NODE is None, reason="Node.js is required for frontend checks")
|
|
def test_frontend_interactions_smoke() -> None:
|
|
subprocess.run([NODE, "tests/frontend_smoke.js"], check=True)
|
|
|
|
|
|
def test_export_controls_have_correct_formats_constraints_and_styles() -> None:
|
|
parser = _MarkupCollector()
|
|
parser.feed(INDEX_HTML.read_text(encoding="utf-8"))
|
|
|
|
assert parser.options["saved_model"].startswith("TensorFlow SavedModel")
|
|
assert parser.options["pb"] == "TensorFlow GraphDef (.pb)"
|
|
assert "triton" not in parser.options
|
|
assert parser.by_id["export-imgsz"]["min"] == "32"
|
|
assert parser.by_id["export-imgsz"]["max"] == "8192"
|
|
assert parser.by_id["export-imgsz"]["step"] == "1"
|
|
assert parser.by_id["export-batch"]["min"] == "1"
|
|
assert parser.by_id["export-batch"]["max"] == "1024"
|
|
assert parser.by_id["export-batch"]["step"] == "1"
|
|
assert parser.by_id["export-workspace"]["min"] == "1"
|
|
assert parser.by_id["export-workspace"]["max"] == "64"
|
|
assert parser.by_id["export-workspace"]["step"] == "0.5"
|
|
|
|
css = STYLE_CSS.read_text(encoding="utf-8")
|
|
assert "#export-config-pane" in css
|
|
assert "#export-run-pane" in css
|
|
assert "#export-log-container::-webkit-scrollbar" in css
|
|
assert "#export-status-card.status-exporting" in css
|
|
assert "#export-status-card.status-failed" in css
|