Files
vault-dash/tests/test_e2e_playwright.py
2026-03-24 19:36:37 +01:00

119 lines
6.6 KiB
Python

from __future__ import annotations
from pathlib import Path
from playwright.sync_api import expect, sync_playwright
BASE_URL = "http://127.0.0.1:8000"
ARTIFACTS = Path("tests/artifacts")
ARTIFACTS.mkdir(parents=True, exist_ok=True)
def test_homepage_and_options_page_render() -> 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).to_have_title("NiceGUI")
expect(page.locator("text=Vault Dashboard").first).to_be_visible(timeout=10000)
expect(page.locator("text=Overview").first).to_be_visible(timeout=10000)
expect(page.locator("text=Live quote source:").first).to_be_visible(timeout=15000)
expect(page.locator("text=Alert Status").first).to_be_visible(timeout=15000)
page.screenshot(path=str(ARTIFACTS / "overview.png"), full_page=True)
page.goto(f"{BASE_URL}/backtests", wait_until="networkidle", timeout=30000)
expect(page.locator("text=Backtests").first).to_be_visible(timeout=15000)
expect(page.locator("text=Scenario Form").first).to_be_visible(timeout=15000)
expect(page.locator("text=Scenario Summary").first).to_be_visible(timeout=15000)
expect(page.locator("text=Daily Results").first).to_be_visible(timeout=15000)
backtests_text = page.locator("body").inner_text(timeout=15000)
assert "Auto-derived entry spot: $100.00" in backtests_text
assert "RuntimeError" not in backtests_text
assert "Server error" not in backtests_text
assert "Traceback" not in backtests_text
page.screenshot(path=str(ARTIFACTS / "backtests.png"), full_page=True)
page.get_by_label("Template").click()
page.get_by_text("Protective Put 95%", exact=True).click()
page.get_by_role("button", name="Run backtest").click()
expect(page.locator("text=Scenario Summary").first).to_be_visible(timeout=15000)
expect(page.locator("text=Template: Protective Put 95%").first).to_be_visible(timeout=15000)
rerun_text = page.locator("body").inner_text(timeout=15000)
assert "Margin call days hedged" in rerun_text
assert "RuntimeError" not in rerun_text
assert "Server error" not in rerun_text
page.goto(f"{BASE_URL}/event-comparison", wait_until="networkidle", timeout=30000)
expect(page.locator("text=Event Comparison").first).to_be_visible(timeout=15000)
expect(page.locator("text=Comparison Form").first).to_be_visible(timeout=15000)
expect(page.locator("text=Ranked Results").first).to_be_visible(timeout=15000)
expect(page.locator("text=Scenario Metadata").first).to_be_visible(timeout=15000)
expect(page.locator("text=Portfolio Value Paths").first).to_be_visible(timeout=15000)
event_text = page.locator("body").inner_text(timeout=15000)
assert "GLD January 2024 Selloff" in event_text
assert "Protective Put ATM" in event_text
assert "Baseline series shows the unhedged collateral value path" in event_text
assert "Hedged margin call days" in event_text
assert "Templates compared" in event_text and "4" in event_text
assert "RuntimeError" not in event_text
assert "Server error" not in event_text
assert "Traceback" not in event_text
page.get_by_label("Event preset").click()
page.get_by_text("GLD January 2024 Drawdown", exact=True).click()
page.get_by_role("button", name="Run comparison").click()
expect(page.locator("text=GLD January 2024 Drawdown").first).to_be_visible(timeout=15000)
rerun_event_text = page.locator("body").inner_text(timeout=15000)
assert "Laddered Puts 33/33/33 ATM + 95% + 90%" in rerun_event_text
assert "Templates compared" in rerun_event_text and "3" in rerun_event_text
assert "RuntimeError" not in rerun_event_text
assert "Server error" not in rerun_event_text
page.screenshot(path=str(ARTIFACTS / "event-comparison.png"), full_page=True)
page.goto(f"{BASE_URL}/options", wait_until="domcontentloaded", timeout=30000)
expect(page.locator("text=Options Chain").first).to_be_visible(timeout=15000)
expect(page.locator("text=Filters").first).to_be_visible(timeout=15000)
body_text = page.locator("body").inner_text(timeout=15000)
assert "Server error" not in body_text
assert "RuntimeError" not in body_text
page.screenshot(path=str(ARTIFACTS / "options.png"), full_page=True)
page.goto(f"{BASE_URL}/settings", wait_until="domcontentloaded", timeout=30000)
expect(page.locator("text=Settings").first).to_be_visible(timeout=15000)
expect(page.locator("text=Collateral entry basis").first).to_be_visible(timeout=15000)
expect(page.locator("text=Entry price ($/oz)").first).to_be_visible(timeout=15000)
settings_text = page.locator("body").inner_text(timeout=15000)
assert "RuntimeError" not in settings_text
assert "Server error" not in settings_text
page.screenshot(path=str(ARTIFACTS / "settings.png"), full_page=True)
page.goto(f"{BASE_URL}/hedge", wait_until="domcontentloaded", timeout=30000)
expect(page.locator("text=Hedge Analysis").first).to_be_visible(timeout=15000)
expect(page.locator("text=Strategy selector").first).to_be_visible(timeout=15000)
expect(page.locator("text=Strategy Controls").first).to_be_visible(timeout=15000)
hedge_text = page.locator("body").inner_text(timeout=15000)
assert "Scenario Summary" in hedge_text
assert "RuntimeError" not in hedge_text
assert "Server error" not in hedge_text
slider = page.locator(".q-slider").first
slider_box = slider.bounding_box()
assert slider_box is not None
page.mouse.click(slider_box["x"] + slider_box["width"] * 0.1, slider_box["y"] + slider_box["height"] / 2)
expect(page.locator("text=Scenario move: -20%").first).to_be_visible(timeout=15000)
hedge_text = page.locator("body").inner_text(timeout=15000)
assert "Start value" in hedge_text
assert "Start price" in hedge_text
assert "Weight" in hedge_text
assert "$215,000" in hedge_text
assert "$215.00/oz" in hedge_text
assert "1,000 oz" in hedge_text
assert "Unhedged equity" in hedge_text
assert "Hedged equity" in hedge_text
assert "$27,000" in hedge_text
assert "$58,750" in hedge_text
page.screenshot(path=str(ARTIFACTS / "hedge.png"), full_page=True)
browser.close()