"""Seam 1 page check: load a dashboard page with no backend, push contract envelopes through window.__pyMsg, and assert on what is visible. Page under test: set PAGE_CHECK_HTML to a generated dashboard.html. Without it, the no-AI template is filled with TEST_FILL. Every test runs in light, dark and narrow mode. The page sees a fake Qt bridge: each slot call lands in window.__calls as [slot, ...args]. """ import json import os import re from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] TEMPLATE = ROOT / "rpa-dashboard-no-ai" / "templates" / "dashboard.html" TEST_FILL = { "APP_NAME": "Test Bot", "APP_SUBTITLE": "Page check", "LOGO_SRC": "", "API_BASE": "", "STEPS_JSON": json.dumps(["Initializing", "Login", "Process items", "Completed"]), "REPORT_COLUMNS_JSON": json.dumps([{"key": "item", "label": "Item"}, {"key": "status", "label": "Status"}]), } FAKE_BRIDGE = """ window.__calls = []; window.qt = {webChannelTransport: {}}; window.QWebChannel = function (_transport, ready) { const pyBridge = new Proxy({}, {get: (_o, slot) => (...args) => { window.__calls.push([slot, ...args]); }}); ready({objects: {pyBridge}}); }; """ MODES = {"light": (1280, 820, False), "dark": (1280, 820, True), "narrow": (800, 900, False)} @pytest.fixture(scope="session") def page_url(tmp_path_factory): if os.environ.get("PAGE_CHECK_HTML"): return Path(os.environ["PAGE_CHECK_HTML"]).resolve().as_uri() html = re.sub(r"\{\{(\w+)\}\}", lambda m: TEST_FILL[m[1]], TEMPLATE.read_text(encoding="utf-8")) out = tmp_path_factory.mktemp("page") / "dashboard.html" out.write_text(html, encoding="utf-8") return out.as_uri() @pytest.fixture(params=list(MODES)) def page(request, browser, page_url): width, height, dark = MODES[request.param] ctx = browser.new_context(viewport={"width": width, "height": height}) ctx.add_init_script(FAKE_BRIDGE) pg = ctx.new_page() pg.set_default_timeout(5000) errors = [] pg.on("pageerror", lambda e: errors.append(e)) pg.goto(page_url) assert not errors, f"page script errors: {errors}" if dark: push_to(pg, "apply_dark", {"on": True}) yield pg ctx.close() def push_to(pg, event, data): pg.evaluate("([event, data]) => window.__pyMsg(JSON.stringify({event, data}))", [event, data]) @pytest.fixture def push(page): """push(event, data): send one contract envelope to the page, as the bot would.""" return lambda event, data: push_to(page, event, data)