from __future__ import annotations from pathlib import Path from playwright.sync_api import expect, sync_playwright BASE_URL = "http://127.0.0.1:8100" ARTIFACTS = Path("tests/artifacts") ARTIFACTS.mkdir(parents=True, exist_ok=True) def test_overview_shows_ltv_history_and_exports_csv() -> None: with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page(viewport={"width": 1440, "height": 1000}) page.goto(BASE_URL, wait_until="domcontentloaded", timeout=30000) expect(page.locator("text=Create a private workspace URL").first).to_be_visible(timeout=15000) page.get_by_role("button", name="Get started").click() page.wait_for_url(f"{BASE_URL}/*", timeout=15000) expect(page.locator("text=Overview").first).to_be_visible(timeout=15000) expect(page.locator("text=Historical LTV").first).to_be_visible(timeout=15000) expect(page.locator("text=7 Day").first).to_be_visible(timeout=15000) expect(page.locator("text=30 Day").first).to_be_visible(timeout=15000) expect(page.locator("text=90 Day").first).to_be_visible(timeout=15000) expect(page.get_by_role("button", name="Export CSV")).to_be_visible(timeout=15000) series_names = page.evaluate( """ async () => { const importMap = JSON.parse(document.querySelector('script[type="importmap"]').textContent).imports; const mod = await import(importMap['nicegui-echart']); const chart = mod.echarts.getInstanceByDom(document.querySelector('.nicegui-echart')); return chart ? chart.getOption().series.map(series => series.name) : []; } """ ) assert series_names == ["LTV", "Margin threshold"] with page.expect_download() as download_info: page.get_by_role("button", name="Export CSV").click() download = download_info.value assert download.suggested_filename.endswith("-ltv-history.csv") download_path = ARTIFACTS / "ltv-history-export.csv" download.save_as(str(download_path)) csv_content = download_path.read_text() assert ( "snapshot_date,captured_at,ltv_ratio_pct,margin_threshold_pct,loan_amount_usd,collateral_value_usd,spot_price_usd_per_ozt,source" in csv_content ) body = page.locator("body").inner_text(timeout=15000) assert "RuntimeError" not in body assert "Server error" not in body assert "Traceback" not in body page.screenshot(path=str(ARTIFACTS / "overview-ltv-history.png"), full_page=True) browser.close()