Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Headless browser (signals-ui verification)

UI changes must be exercised with a real browser, not only curl. Signals ships Playwright + Chromium for that.

What is installed

PieceSource
Python APIplaywright (uv dev group + optional extra browser)
Launchersignals.browser — resolves Chromium, fixes devenv/nix driver env
Chromiumdevenv package chromium on PATH, or SIGNALS_CHROMIUM_PATH, or Playwright-bundled after just browser-install
Node for driverdevenv nodejs_22 via PLAYWRIGHT_NODEJS_PATH (auto)

Recipes

just browser-install   # no-op when chromium already on PATH
just ui-verify         # queues lineup one-shot → build/ui-verify/*.png
just ui-test           # pytest tests/ui/ -m browser

just test ignores tests/ui/ (needs live UI). Unit suite stays hermetic.

Env

VariableRole
SIGNALS_UI_BASEdefault http://127.0.0.1:9889
SIGNALS_CHROMIUM_PATHforce Chromium binary
SIGNALS_BROWSER_HEADED=1show window
SIGNALS_BROWSER_SLOW_MO_MSPlaywright slow_mo
SIGNALS_UI_BROWSER_SKIP=1skip browser fixtures
SIGNALS_BROWSER_KEEP_LD_PATH=1do not clear LD_LIBRARY_PATH

devenv / nix note

Playwright ships its own Node. Under devenv, a nix LD_LIBRARY_PATH with a newer libstdc++ can break that Node (GLIBC_2.3x not found). signals.browser and just ui-* clear LD_LIBRARY_PATH and point the driver at system/devenv Node. Prefer system Chromium from devenv (packages = [ chromium … ]).

Code

from signals.browser import launch_chromium, sync_playwright, default_ui_base

with sync_playwright() as p:
    browser = launch_chromium(p)
    page = browser.new_page()
    page.goto(f"{default_ui_base()}/queues")
    page.locator("#queues-lineup-shell").wait_for()
    browser.close()