"""Test service s-expression page components.""" from __future__ import annotations import os from datetime import datetime from shared.sexp.jinja_bridge import render, load_service_components from shared.sexp.helpers import root_header_html, full_page # Load test-specific .sexpr components at import time load_service_components(os.path.dirname(os.path.dirname(__file__))) def _format_time(ts: float | None) -> str: """Format a unix timestamp for display.""" if not ts: return "never" return datetime.fromtimestamp(ts).strftime("%-d %b %Y, %H:%M:%S") def _test_rows_html(tests: list[dict]) -> str: """Render all test result rows.""" parts = [] for t in tests: parts.append(render( "test-row", nodeid=t["nodeid"], outcome=t["outcome"], duration=str(t["duration"]), longrepr=t.get("longrepr", ""), )) return "".join(parts) def _results_partial_html(result: dict | None, running: bool, csrf: str) -> str: """Render the results section (summary + table or running indicator).""" if running and not result: summary = render( "test-summary", status="running", passed="0", failed="0", errors="0", skipped="0", total="0", duration="...", last_run="in progress", running=True, csrf=csrf, ) return summary + render("test-running-indicator") if not result: summary = render( "test-summary", status=None, passed="0", failed="0", errors="0", skipped="0", total="0", duration="0", last_run="never", running=running, csrf=csrf, ) return summary + render("test-no-results") status = "running" if running else result["status"] summary = render( "test-summary", status=status, passed=str(result["passed"]), failed=str(result["failed"]), errors=str(result["errors"]), skipped=str(result.get("skipped", 0)), total=str(result["total"]), duration=str(result["duration"]), last_run=_format_time(result["finished_at"]) if not running else "in progress", running=running, csrf=csrf, ) if running: return summary + render("test-running-indicator") tests = result.get("tests", []) if not tests: return summary + render("test-no-results") has_failures = result["failed"] > 0 or result["errors"] > 0 rows = _test_rows_html(tests) table = render("test-results-table", rows_html=rows, has_failures=str(has_failures).lower()) return summary + table def _wrap_results_div(inner_html: str, running: bool) -> str: """Wrap results in a div with HTMX polling when running.""" attrs = 'id="test-results" class="space-y-6 p-4"' if running: attrs += ' hx-get="/results" hx-trigger="every 2s" hx-swap="outerHTML"' return f'