from __future__ import annotations import json import time import click from browser_cli.commands import client_from_ctx, handle_errors @click.group("watch") def watch_group(): """Watch browser state and print changes.""" @watch_group.command("tabs") @click.option("--interval", type=float, default=1.0, show_default=True) @click.option("--once", is_flag=True) @handle_errors def watch_tabs(interval, once): """Watch the tab list as JSON snapshots.""" client = client_from_ctx() previous = None while True: current = [t.__dict__ for t in client.tabs.list()] if current != previous: click.echo(json.dumps({"type": "tabs", "tabs": current}, default=str), flush=True) previous = current if once: return time.sleep(interval) @watch_group.command("page") @click.option("--field", default=None, help="Only print a single page.info field") @click.option("--interval", type=float, default=1.0, show_default=True) @handle_errors def watch_page(field, interval): """Watch page.info for the active tab.""" client = client_from_ctx() previous = object() while True: info = client.page.info() current = info.get(field) if field else info if current != previous: click.echo(json.dumps({"type": "page", "field": field, "value": current}, default=str), flush=True) previous = current time.sleep(interval) @watch_group.command("dom") @click.argument("selector") @click.option("--interval", type=float, default=1.0, show_default=True) @handle_errors def watch_dom(selector, interval): """Watch textContent for a selector.""" client = client_from_ctx() previous = object() while True: current = client.dom.text(selector) if current != previous: click.echo(json.dumps({"type": "dom", "selector": selector, "text": current}, default=str), flush=True) previous = current time.sleep(interval)