Ctrl K
ComunidadGuías…

tools/windows_check.py

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

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
"""Two browser windows: open clean, hand sessions across, collect on close.

Same-origin windows talk over a BroadcastChannel (no server), so a session's tab
can move between windows — one monitor to the next. This drives two real pages
in one browser (which is what shares the channel) and checks the whole handoff:

- a first window restores the shared workspace; a *second* window opens CLEAN,
  so a second screen is a fresh desk, not a copy of the first;
- presence, the window-number chip, and the "Move to … window" menu item;
- a move opens the session in the target and closes it in the source;
- closing a window collects its tabs into the remaining (primary) window.

Needs the Playwright venv:

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

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

from __future__ import annotations

import sys
import time
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


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")
        alpha = vc._api("/api/sessions", "POST", {"cli": "shell", "cwd": "/tmp", "name": "alpha"})[
            "id"
        ]
        vc._api("/api/sessions", "POST", {"cli": "shell", "cwd": "/tmp", "name": "bravo"})
        # Seed the shared workspace with one tab, as a prior single window would.
        vc._api("/api/settings", "PATCH", {"open_tabs": [alpha], "active_tab": alpha})

        with sync_playwright() as play:
            browser = play.chromium.launch()
            ctx = browser.new_context(viewport={"width": 1200, "height": 760})
            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": "/"}]
            )
            errs: list[str] = []

            # Window 1 opens first and restores the seeded strip.
            p1 = ctx.new_page()
            p1.on("pageerror", lambda e: errs.append("p1:" + str(e)))
            p1.goto(vc.BASE, wait_until="networkidle")
            for _ in range(30):
                if p1.evaluate("() => openTabs.length") > 0:
                    break
                time.sleep(0.2)
            res["primary_restores_seed"] = p1.evaluate("(id) => openTabs.includes(id)", alpha)

            # Window 2 opens second and should start CLEAN.
            p2 = ctx.new_page()
            p2.on("pageerror", lambda e: errs.append("p2:" + str(e)))
            p2.goto(vc.BASE, wait_until="networkidle")
            time.sleep(2.0)
            res["secondary_opens_clean"] = p2.evaluate("() => openTabs.length") == 0
            res["presence_both_see_two"] = (
                p2.evaluate("() => winPeers.size") >= 2 and p1.evaluate("() => winPeers.size") >= 2
            )
            res["labels_distinct"] = {
                p1.evaluate("() => windowLabel(winId)"),
                p2.evaluate("() => windowLabel(winId)"),
            } == {1, 2}
            res["chip_shown_both"] = p1.evaluate(
                "() => !document.getElementById('winTag').hidden"
            ) and p2.evaluate("() => !document.getElementById('winTag').hidden")
            res["menu_offers_move"] = (
                p1.evaluate("(id) => windowMoveItems(session(id)).length", alpha) == 1
            )

            # Move alpha from window 1 to window 2.
            w2 = p2.evaluate("() => winId")
            p1.evaluate("([id, w]) => moveSessionToWindow(id, w)", [alpha, w2])
            time.sleep(1.0)
            res["move_source_released"] = not p1.evaluate("(id) => openTabs.includes(id)", alpha)
            res["move_target_received"] = p2.evaluate("(id) => openTabs.includes(id)", alpha)
            res["move_target_flashed"] = p2.evaluate(
                "() => document.body.classList.contains('win-flash')"
            )

            # Close window 2 — window 1 (primary) collects its tab back.
            time.sleep(0.7)  # let window 2 persist its strip
            p2.close()
            time.sleep(3.5)  # leave + collect grace
            res["collect_on_close"] = p1.evaluate("(id) => openTabs.includes(id)", alpha)

            res["no_console_errors"] = not errs
            if errs:
                res["errors"] = errs[:4]
    finally:
        panel.terminate()

    ok = all(v for k, v in res.items() if k != "errors")
    for key, value in res.items():
        print(f"  {'ok  ' if value or key == 'errors' else 'FAIL'} {key}: {value}")
    print("windows_check:", "PASS" if ok else "FAIL")
    return 0 if ok else 1


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