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 '' in html assert "Pi 5" not in html assert '' in html preferred = html.split('id="preferredHardware"', 1)[1].split("", 1)[0] assert preferred.count("", 1)[0] assert '' 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")