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=Create a private workspace URL").first).to_be_visible(timeout=10000) page.get_by_role("button", name="Get started").click() page.wait_for_url(f"{BASE_URL}/*", timeout=15000) workspace_url = page.url workspace_id = workspace_url.removeprefix(f"{BASE_URL}/") assert workspace_id cookies = page.context.cookies() workspace_cookie = next(cookie for cookie in cookies if cookie["name"] == "workspace_id") assert workspace_cookie["value"] == workspace_id 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(BASE_URL, wait_until="domcontentloaded", timeout=30000) page.wait_for_url(workspace_url, timeout=15000) expect(page.locator("text=Alert Status").first).to_be_visible(timeout=15000) page.goto(f"{workspace_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"{workspace_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"{workspace_url}/settings", wait_until="domcontentloaded", timeout=30000) assert page.url.endswith("/settings") 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) page.get_by_label("Collateral entry basis").click() page.get_by_text("Gold weight + entry price", exact=True).click() page.get_by_label("Entry price ($/oz)").fill("4400") page.get_by_label("Gold weight (oz)").fill("220") page.get_by_label("Loan amount ($)").fill("222000") page.get_by_label("Margin call LTV threshold").fill("0.8") budget_input = page.get_by_label("Monthly hedge budget ($)") budget_input.fill("12345") page.get_by_role("button", name="Save settings").click() expect(page.locator("text=Settings saved successfully").first).to_be_visible(timeout=15000) page.reload(wait_until="domcontentloaded", timeout=30000) expect(page.get_by_label("Monthly hedge budget ($)")).to_have_value("12345") expect(page.get_by_label("Entry price ($/oz)")).to_have_value("4400") expect(page.get_by_label("Loan amount ($)")).to_have_value("222000") expect(page.get_by_label("Margin call LTV threshold")).to_have_value("0.8") 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"{workspace_url}/backtests", wait_until="networkidle", timeout=30000) expect(page.get_by_label("Underlying units")).to_have_value("9680") expect(page.get_by_label("Loan amount")).to_have_value("222000") expect(page.get_by_label("Margin call LTV")).to_have_value("0.8") backtests_workspace_text = page.locator("body").inner_text(timeout=15000) assert "Scenario Summary" in backtests_workspace_text assert "$968,000" in backtests_workspace_text page.goto(f"{workspace_url}/event-comparison", wait_until="networkidle", timeout=30000) expect(page.get_by_label("Underlying units")).to_have_value("9680") expect(page.get_by_label("Loan amount")).to_have_value("222000") expect(page.get_by_label("Margin call LTV")).to_have_value("0.8") event_workspace_text = page.locator("body").inner_text(timeout=15000) assert "$222,000" in event_workspace_text assert "9,680" in event_workspace_text assert "80.0%" in event_workspace_text page.goto(workspace_url, wait_until="domcontentloaded", timeout=30000) overview_text = page.locator("body").inner_text(timeout=15000) assert "Hedge Analysis" in overview_text assert "Options Chain" in overview_text assert "Backtests" in overview_text assert "Event Comparison" in overview_text assert "Live quote source:" in overview_text assert "GLD share quote converted to ozt-equivalent spot" in overview_text assert "configured entry price fallback" not in overview_text assert "Collateral Spot Price" in overview_text assert "$1,261.36" in overview_text assert "$968,000" in overview_text assert "$222,000" in overview_text expect(page.get_by_role("link", name="Hedge Analysis")).to_have_attribute("href", f"/{workspace_id}/hedge") expect(page.get_by_role("link", name="Backtests")).to_have_attribute("href", f"/{workspace_id}/backtests") expect(page.get_by_role("link", name="Event Comparison")).to_have_attribute( "href", f"/{workspace_id}/event-comparison" ) second_context = browser.new_context(viewport={"width": 1440, "height": 1000}) second_page = second_context.new_page() second_page.goto(BASE_URL, wait_until="domcontentloaded", timeout=30000) expect(second_page.locator("text=Create a private workspace URL").first).to_be_visible(timeout=10000) second_page.get_by_role("button", name="Get started").click() second_page.wait_for_url(f"{BASE_URL}/*", timeout=15000) second_workspace_url = second_page.url assert second_workspace_url != workspace_url second_page.goto(f"{second_workspace_url}/settings", wait_until="domcontentloaded", timeout=30000) settings_loaded = False for _ in range(3): try: expect(second_page).to_have_url(f"{second_workspace_url}/settings") expect(second_page.locator("text=Settings").first).to_be_visible(timeout=15000) expect(second_page.get_by_label("Monthly hedge budget ($)")).to_have_value("8000", timeout=15000) settings_loaded = True break except AssertionError: second_page.reload(wait_until="domcontentloaded", timeout=30000) assert settings_loaded second_page.close() second_context.close() page.goto(f"{workspace_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 "Loan amount" in hedge_text assert "Monthly hedge budget" in hedge_text assert "$4,400.00/oz" not in hedge_text assert "220 oz" in hedge_text assert "$222,000" in hedge_text assert "80.0%" in hedge_text assert "$12,345" in hedge_text assert "converted collateral spot" in hedge_text assert "Start value" in hedge_text assert "Start price" in hedge_text assert "Scenario spot" in hedge_text assert "Unhedged equity" in hedge_text assert "Hedged equity" in hedge_text page.screenshot(path=str(ARTIFACTS / "hedge.png"), full_page=True) page.goto(f"{workspace_url}/hedge", wait_until="domcontentloaded", timeout=30000) hedge_spot_text = page.locator("body").inner_text(timeout=15000) assert "converted collateral spot" in hedge_spot_text or "configured entry price" in hedge_spot_text browser.close()