""" Source guards for frontend pitfalls that unit tests cannot catch. Native browser dialogs (window.confirm / alert / prompt) are silently suppressed in embedded and sandboxed browser contexts: confirm() returns false without ever showing a dialog, so any action gated behind it becomes a no-op with no error. This actually happened — the Dashboard delete button did nothing because of it. Use ConfirmDialog (components/ui.tsx) instead. """ from __future__ import annotations import re from pathlib import Path SRC = Path(__file__).resolve().parents[2] / "frontend" / "src" # `confirm(`, `alert(`, `prompt(` as bare calls or on window. _NATIVE_DIALOG = re.compile(r"(?:\bwindow\s*\.\s*)?\b(confirm|alert|prompt)\s*\(") _ALLOWED = {"ConfirmDialog"} # our own component, not the native dialog def _sources() -> list[Path]: return [p for p in SRC.rglob("*.ts*") if p.is_file()] def test_no_native_browser_dialogs(): offenders: list[str] = [] for path in _sources(): for i, line in enumerate(path.read_text().splitlines(), 1): stripped = line.strip() if stripped.startswith("//") or stripped.startswith("*"): continue m = _NATIVE_DIALOG.search(line) if m and not any(a in line for a in _ALLOWED): offenders.append(f"{path.relative_to(SRC)}:{i}: {stripped[:90]}") assert not offenders, ( "Native browser dialogs are suppressed in embedded contexts and silently " "cancel the action. Use instead:\n " + "\n ".join(offenders) ) def test_confirm_dialog_component_exists(): ui = (SRC / "components" / "ui.tsx").read_text() assert "export function ConfirmDialog" in ui def test_destructive_actions_use_confirm_dialog(): """Anything calling deleteSession must route through the in-app dialog.""" for path in _sources(): text = path.read_text() if "deleteSession" in text and "api.ts" not in path.name and "client.ts" not in path.name: assert "ConfirmDialog" in text, ( f"{path.relative_to(SRC)} deletes a closing without " )