File size: 2,703 Bytes
9577cee 55b12be 9577cee 6e21858 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | from pathlib import Path
from src.progress import progress_from_events
def test_operation_status_is_fixed_floating_toast():
html = Path("web/index.html").read_text(encoding="utf-8")
css = Path("web/static/app.css").read_text(encoding="utf-8")
js = Path("web/static/app.js").read_text(encoding="utf-8")
assert 'id="toastLayer"' in html
assert "floating-toast" in html
assert ".toast-layer" in css
assert "position:fixed" in css
assert "operation-status floating-toast" in js
def test_new_build_defaults_are_correct():
html = Path("web/index.html").read_text(encoding="utf-8")
assert '<option value="Qwen/Qwen3-Coder-Next" selected>Qwen/Qwen3-Coder-Next</option>' in html
assert "Pi 5" not in html
assert '<option value="zero-a10g" selected>ZeroGPU</option>' in html
preferred = html.split('id="preferredHardware"', 1)[1].split("</select>", 1)[0]
assert preferred.count("<option") == 1
fallback = html.split('id="fallbackHardware"', 1)[1].split("</select>", 1)[0]
assert '<option value="a10g-large" selected>A10G Large</option>' in fallback
def test_progress_timeline_is_monotonic_and_does_not_go_backwards():
result = progress_from_events([
{"ts": "2026-06-02T10:00:00+00:00", "step": "bootstrap", "status": "started"},
{"ts": "2026-06-02T10:01:00+00:00", "step": "pi_run", "status": "running"},
{"ts": "2026-06-02T10:02:00+00:00", "step": "model_analysis", "status": "success"},
], state={"status": "running"})
assert result["current_step"] == "pi_run"
statuses = {item["step"]: item["status"] for item in result["timeline"]}
assert statuses["bootstrap"] == "done"
assert statuses["model_analysis"] == "done"
assert statuses["pi_run"] == "running"
def test_stopped_timeline_freezes_running_step_without_running_status():
result = progress_from_events([
{"ts": "2026-06-02T10:00:00+00:00", "step": "bootstrap", "status": "success"},
{"ts": "2026-06-02T10:01:00+00:00", "step": "pi_run", "status": "running"},
], state={"status": "cancelled"})
statuses = {item["step"]: item["status"] for item in result["timeline"]}
assert statuses["pi_run"] == "stopped"
assert result["status"] == "cancelled"
def test_frontend_timeline_supports_stopped_status():
js = Path("web/static/progress.js").read_text(encoding="utf-8")
css = Path("web/static/app.css").read_text(encoding="utf-8")
assert "status==='stopped'" in js
assert "status-stopped" in js
assert ".step.status-stopped .step-dot" in css
def test_app_version_v65():
assert '"version": "v81-robust-timeline-color-feedback"' in Path("app.py").read_text(encoding="utf-8")
|