from __future__ import annotations from playwright.sync_api import expect, sync_playwright BASE_URL = "http://127.0.0.1:8000" def test_settings_reject_invalid_loan_amount_without_silent_zero_fallback() -> 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=10000) page.get_by_role("button", name="Get started").click() page.wait_for_url(f"{BASE_URL}/*", timeout=15000) workspace_url = page.url page.goto(f"{workspace_url}/settings", wait_until="domcontentloaded", timeout=30000) expect(page.locator("text=Settings").first).to_be_visible(timeout=15000) expect(page.locator("text=Last saved:").first).to_be_visible(timeout=15000) refresh_interval_input = page.get_by_label("Refresh interval (seconds)") refresh_interval_input.fill("7") expect(page.locator("text=Unsaved changes — Last saved:").first).to_be_visible(timeout=15000) refresh_interval_input.fill("5.5") refresh_interval_input.press("Tab") expect(page.locator("text=INVALID").first).to_be_visible(timeout=15000) expect(page.locator("text=Refresh interval must be a whole number of seconds").first).to_be_visible( timeout=15000 ) page.reload(wait_until="domcontentloaded", timeout=30000) expect(page.get_by_label("Refresh interval (seconds)")).to_have_value("5") expect(page.locator("text=Last saved:").first).to_be_visible(timeout=15000) loan_input = page.get_by_label("Loan amount ($)") loan_input.fill("") loan_input.press("Tab") expect(page.locator("text=INVALID").first).to_be_visible(timeout=15000) expect(page.locator("text=Loan amount must be zero or greater").first).to_be_visible(timeout=15000) expect(page.locator("text=Unsaved invalid changes — Last saved:").first).to_be_visible(timeout=15000) page.get_by_role("button", name="Save settings").click() expect(page.locator("text=Validation error: Loan amount must be zero or greater").first).to_be_visible( timeout=15000 ) settings_text = page.locator("body").inner_text(timeout=15000) assert "LTV=0.0%" not in settings_text assert "RuntimeError" not in settings_text assert "Server error" not in settings_text assert "Traceback" not in settings_text page.reload(wait_until="domcontentloaded", timeout=30000) expect(page.get_by_label("Loan amount ($)")).to_have_value("145000") expect(page.locator("text=Last saved:").first).to_be_visible(timeout=15000) browser.close()