Ctrl K
ComunidadGuías…

tools/overlays_check.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
"""Every modal sheet is a real centered overlay — not an unstyled block in flow.

inbox, diff, board and broadcast are dialogs that open over the app. They each
need the overlay rule (`position: fixed`, a scrim, centred) that #settings and
#keys have. They once shipped without it and rendered as full-width unstyled
strips at the foot of the page — the board fell entirely below the fold — yet
the per-feature Playwright checks passed, because Playwright drives an element
by DOM ref no matter where it renders. This asserts the CSS itself, so that
class of "the button does nothing / breaks the UI" bug cannot come back unseen.

Needs the Playwright venv:

    ~/.cache/clique-visual/bin/python tools/overlays_check.py

Exit status is 0 on pass, 1 on fail.
"""

from __future__ import annotations

import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
import tools.visual_check as vc
from clique.auth import COOKIE_NAME, Auth

SHEETS = ("inbox", "diff", "board", "broadcast")


def main() -> int:
    from playwright.sync_api import sync_playwright

    panel = vc._own_panel()
    res: dict[str, object] = {}
    try:
        auth = Auth(vc.PASSWORD, vc.SANDBOX / "secret")
        vc._scratch_session()
        with sync_playwright() as play:
            browser = play.chromium.launch()
            ctx = browser.new_context(viewport={"width": 1400, "height": 900})
            ctx.add_init_script("try { localStorage.setItem('clique.gpu','0'); } catch (e) {}")
            ctx.add_cookies(
                [{"name": COOKIE_NAME, "value": auth.issue(), "domain": "127.0.0.1", "path": "/"}]
            )
            page = ctx.new_page()
            page.goto(vc.BASE, wait_until="networkidle")
            page.wait_for_timeout(800)
            probe = page.evaluate(
                """() => {
                  const out = {};
                  for (const id of %s) {
                    const el = document.getElementById(id);
                    if (!el) { out[id] = { missing: true }; continue; }
                    el.hidden = false;
                    const cs = getComputedStyle(el);
                    const sheet = el.querySelector('.sheet');
                    const sr = sheet ? sheet.getBoundingClientRect() : null;
                    out[id] = {
                      position: cs.position,
                      scrim: cs.backgroundColor,
                      centered: sr ? (sr.top > 0 && sr.bottom < window.innerHeight + 1) : false,
                    };
                    el.hidden = true;
                  }
                  return out;
                }"""
                % ("['" + "','".join(SHEETS) + "']")
            )
    finally:
        panel.terminate()

    for sid in SHEETS:
        info = probe.get(sid, {"missing": True})
        ok = (
            not info.get("missing")
            and info.get("position") == "fixed"
            and info.get("scrim") not in ("rgba(0, 0, 0, 0)", "transparent")
            and info.get("centered")
        )
        res[sid] = ok
        print(
            f"  {'ok  ' if ok else 'FAIL'} #{sid} is a fixed, scrimmed, on-screen overlay: {info}"
        )

    passed = all(res.values())
    print("overlays_check:", "PASS" if passed else "FAIL")
    return 0 if passed else 1


if __name__ == "__main__":
    sys.exit(main())