"""Static frontend smoke tests (D3).""" from __future__ import annotations from collections.abc import AsyncIterator from pathlib import Path import pytest from httpx import ASGITransport, AsyncClient from my_deepagent.api.app import create_app from my_deepagent.config import load_config from my_deepagent.persistence.db import Database @pytest.fixture async def app_client(tmp_path: Path) -> AsyncIterator[AsyncClient]: db_url = f"sqlite+aiosqlite:///{tmp_path / 'api_static.sqlite3'}" cfg = load_config( workspace_root=tmp_path, data_dir=tmp_path / "data", database_url=db_url, ) db = Database(db_url) await db.init_schema() await db.dispose() app = create_app(cfg) transport = ASGITransport(app=app) async with app.router.lifespan_context(app): async with AsyncClient(transport=transport, base_url="http://test") as client: yield client @pytest.mark.asyncio async def test_root_serves_index_html(app_client: AsyncClient) -> None: r = await app_client.get("/") assert r.status_code == 200 assert r.headers["content-type"].startswith("text/html") body = r.text assert "my-deepagent ยท runs" in body assert 'data-page="index"' in body @pytest.mark.asyncio async def test_new_html_served(app_client: AsyncClient) -> None: r = await app_client.get("/new.html") assert r.status_code == 200 assert 'data-page="new"' in r.text @pytest.mark.asyncio async def test_run_html_served(app_client: AsyncClient) -> None: r = await app_client.get("/run.html") assert r.status_code == 200 assert 'data-page="run"' in r.text @pytest.mark.asyncio async def test_static_app_js_served(app_client: AsyncClient) -> None: r = await app_client.get("/static/app.js") assert r.status_code == 200 # Must be JS, not HTML assert ( "application/javascript" in r.headers["content-type"] or "text/javascript" in r.headers["content-type"] ) # XSS policy comment must be present (the hardcoded contract) assert "innerHTML" in r.text @pytest.mark.asyncio async def test_static_style_css_served(app_client: AsyncClient) -> None: r = await app_client.get("/static/style.css") assert r.status_code == 200 assert "text/css" in r.headers["content-type"]