"""Headless-Chromium screenshot helper for the dev UI. Logs in once via the API, injects the token into localStorage the same way the auth store does, then screenshots each path passed on the command line. venv/bin/python tools/shot.py /printers/1 /reports/toner /printers/1/edit Images land in the scratchpad dir as shot_.png. """ import os import sys import json import urllib.request from playwright.sync_api import sync_playwright UI = "http://localhost:5173" API = "http://localhost:5001/api" # creds from env so no real login lands in source; fall back to dev defaults USERNAME = os.environ.get("SHOT_USERNAME", "270015376") PASSWORD = os.environ.get("SHOT_PASSWORD", "changeme") OUTDIR = "/tmp/claude-1000/-home-camp-projects/effc3424-ed5e-4b09-b83e-d141bee23c42/scratchpad" def login(): body = json.dumps({"username": USERNAME, "password": PASSWORD}).encode() loginrequest = urllib.request.Request(f"{API}/auth/login", data=body, headers={"Content-Type": "application/json"}) data = json.load(urllib.request.urlopen(loginrequest))["data"] return data["access_token"], data["refresh_token"], data["user"] def main(paths): token, refresh, user = login() seed = f""" localStorage.setItem('token', {json.dumps(token)}); localStorage.setItem('refreshToken', {json.dumps(refresh)}); localStorage.setItem('user', {json.dumps(json.dumps(user))}); """ with sync_playwright() as p: browser = p.chromium.launch() context = browser.new_context(viewport={"width": 1400, "height": 1000}) context.add_init_script(seed) page = context.new_page() for path in paths: page.goto(f"{UI}{path}", wait_until="networkidle", timeout=30000) page.wait_for_timeout(1200) # let supply fetch + render settle name = "shot_" + (path.strip("/").replace("/", "_") or "home") + ".png" out = f"{OUTDIR}/{name}" page.screenshot(path=out, full_page=True) print(out) browser.close() if __name__ == "__main__": main(sys.argv[1:] or ["/printers/1"])