from pathlib import Path ROOT = Path(__file__).resolve().parents[1] def test_active_run_prefill_requires_validation_result(): runs = (ROOT / "web" / "static" / "runs.js").read_text(encoding="utf-8") assert "function runHasValidationResult" in runs assert "const canPrefill=Boolean(targetSpace&&runHasValidationResult(detail,summary))" in runs assert "Space Test prefill becomes available after validation produced a result." in runs def test_delete_run_requires_finished_status(): runs = (ROOT / "web" / "static" / "runs.js").read_text(encoding="utf-8") assert "function runIsFinished" in runs assert "const canDelete=Boolean(runId&&runIsFinished(status))" in runs assert "after the Job is finished or cancelled" in runs def test_run_documents_do_not_use_backend_present_until_file_exists(): runs = (ROOT / "web" / "static" / "runs.js").read_text(encoding="utf-8") assert "const rawTrace=traceDocState('traces/raw',byId.get('pi_raw_trace'))" in runs assert "const redactedTrace=traceDocState('traces/redacted',byId.get('pi_redacted_trace'))" in runs assert "nonEmptyObject(detail.repair_decision)" in runs assert "nonEmptyObject(detail.blockage)" in runs def test_timeline_current_step_pulse_is_restored(): css = (ROOT / "web" / "static" / "app.css").read_text(encoding="utf-8") assert "@keyframes timeline-current-pulse" in css assert "animation: timeline-current-pulse" in css def test_run_stats_wording_is_user_friendly(): runs = (ROOT / "web" / "static" / "runs.js").read_text(encoding="utf-8") assert "Test response time" in runs assert "Typical " in runs assert "slowest recent" in runs assert "Things to review" in runs