from pathlib import Path def test_custom_ui_assets_exist(): root = Path(__file__).resolve().parents[1] assert (root / "web" / "index.html").exists() assert (root / "web" / "static" / "app.css").exists() assert (root / "web" / "static" / "app.js").exists() assert (root / "web" / "static" / "progress.js").exists() def test_app_registers_custom_routes(): root = Path(__file__).resolve().parents[1] content = (root / "app.py").read_text() assert "def register_custom_routes" in content assert '"/custom"' in content assert '"/api/progress/from-events"' in content assert '"/api/runs"' in content def test_custom_ui_contains_core_product_sections(): root = Path(__file__).resolve().parents[1] html = (root / "web" / "index.html").read_text() for text in [ "New Build", "Space Test", "Run Explorer", "Run storage", "Live job progress", "Run details", "Validation & metrics", "Latest events", ]: assert text in html def test_custom_ui_bridge_endpoints_are_registered(): root = Path(__file__).resolve().parents[1] content = (root / "app.py").read_text() for route in [ '"/api/me"', '"/api/bucket/status"', '"/api/bucket/create"', '"/api/build"', '"/api/validate"', '"/api/runs/{run_id}/progress"', ]: assert route in content assert "_oauth_context_from_request" in content def test_custom_ui_calls_real_bridge_endpoints(): root = Path(__file__).resolve().parents[1] js = (root / "web" / "static" / "app.js").read_text() for endpoint in ["/api/me", "/api/build", "/api/validate", "/api/bucket/status", "/api/bucket/create"]: assert endpoint in js assert "Custom UI shell is ready" not in js assert "functional Gradio controls" not in js def test_custom_ui_has_validate_form(): root = Path(__file__).resolve().parents[1] html = (root / "web" / "index.html").read_text() for element_id in ["validateSpace", "validateApi", "expectedOutput", "testArgs", "testKwargs", "launchValidate"]: assert element_id in html def test_custom_ui_has_run_detail_explorer(): root = Path(__file__).resolve().parents[1] html = (root / "web" / "index.html").read_text() for element_id in ["selectedRunId", "selectedModelId", "artifactList", "reportPreview", "runDetailStatus"]: assert element_id in html js = (root / "web" / "static" / "runs.js").read_text() assert "selectRun" in js assert "renderRunDetail" in js assert "/api/runs/" in js def test_custom_ui_renders_metrics_from_progress(): root = Path(__file__).resolve().parents[1] js = (root / "web" / "static" / "app.js").read_text() assert "function renderMetrics" in js assert "generation_smoke" in js assert "recommended_zerogpu_duration" in js def test_custom_ui_has_selected_run_actions_and_manual_hardware_panel(): root = Path(__file__).resolve().parents[1] html = (root / "web" / "index.html").read_text() for element_id in ["manualActionPanel", "manualOpenSettings", "manualGoValidate", "selectedValidateBtn", "selectedOpenSettings", "selectedBlockers"]: assert element_id in html app_js = (root / "web" / "static" / "app.js").read_text() assert "prepareValidationFromActiveRun" in app_js assert "renderManualAction" in app_js runs_js = (root / "web" / "static" / "runs.js").read_text() assert "renderSelectedLinks" in runs_js assert "renderBlockers" in runs_js def test_custom_ui_has_run_filters_and_resilient_polling(): root = Path(__file__).resolve().parents[1] html = (root / "web" / "index.html").read_text() js = (root / "web" / "static" / "app.js").read_text() runs_js = (root / "web" / "static" / "runs.js").read_text() css = (root / "web" / "static" / "app.css").read_text() for element_id in ["runFilters", "refreshRuns", "pollWarning"]: assert element_id in html assert "runStatusFilter" in js assert "localStorage.setItem('asf.activeRun'" in js assert "restoreActiveRun" in js assert "Progress polling failed" in js assert "renderRunsFromCache" in runs_js assert "state.runsCache" in runs_js assert ".run-row.selected" in css def test_custom_ui_has_oauth_status_panel_and_login_link(): root = Path(__file__).resolve().parents[1] html = (root / "web" / "index.html").read_text() js = (root / "web" / "static" / "app.js").read_text() app_py = (root / "app.py").read_text() assert "authPanel" in html assert "renderAuthWarnings" in js assert "/oauth/huggingface/login" in js assert '"/api/oauth/diagnostics"' in app_py assert "public_oauth_context" in app_py def test_custom_ui_v30_bucket_gate_and_zerogpu_toggle(): root = Path(__file__).resolve().parents[1] html = (root / "web" / "index.html").read_text() js = (root / "web" / "static" / "app.js").read_text() assert 'id="tryZeroGpu"' in html assert 'disabled /> Try ZeroGPU first' not in html assert 'id="launchBuild" disabled' in html assert 'buildGateText' in html assert 'effectivePreferredHardware' in js assert 'setBucketReady' in js assert 'Create or check your private run bucket before launching a build' in js def test_custom_ui_v30_css_has_overflow_and_duplicate_cleanup(): root = Path(__file__).resolve().parents[1] css = (root / "web" / "static" / "app.css").read_text() assert '.app-shell{min-height:100vh;max-width:1540px' in css assert '.top-tabs{display:flex' in css assert '.runs-table{border:1px solid var(--line);border-radius:14px;padding:0;overflow:hidden' in css assert 'font-family:ui-monospace' in css assert '.auth-panel,.operation-status{' in css def test_custom_ui_v31_feedback_and_loading_states(): root = Path(__file__).resolve().parents[1] html = (root / "web" / "index.html").read_text() js = (root / "web" / "static" / "app.js").read_text() css = (root / "web" / "static" / "app.css").read_text() api_js = (root / "web" / "static" / "api.js").read_text() progress_js = (root / "web" / "static" / "progress.js").read_text() assert "operationStatus" in html assert "lastPolled" in html assert "setOperation" in js assert "setBusy" in js assert "validateBuildForm" in js assert "validateValidationForm" in js assert "TERMINAL_STATUSES" in js assert "Run bucket is not ready" in Path(root / "app.py").read_text() assert ".operation-status" in css assert "parseApiError" in api_js assert "lastPolled" in progress_js def test_v33_root_custom_ui_not_iframe_preview(): root = Path(__file__).resolve().parents[1] app_py = (root / "app.py").read_text() readme = (root / "README.md").read_text() assert '@fastapi_app.get("/", response_class=HTMLResponse)' in app_py assert 'attach_huggingface_oauth(fastapi_app)' in app_py assert '