feat: add browser automation commands (v0.6.0)
Navigation: open-wait (open + block until loaded) DOM: key, hover, check/uncheck, clear, focus, submit, poll, scroll, select, eval, wait-for Tabs: pin/unpin, screenshot, watch-url (block until URL matches regex) New command groups: page info, storage get/set, cookies list/get/set Extension: add cookies permission
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import base64
|
||||
import click
|
||||
from browser_cli.client import BrowserNotConnected, active_browser_targets, send_command
|
||||
from rich.console import Console
|
||||
@@ -236,3 +237,54 @@ def tabs_unmute(tab_id):
|
||||
result = _handle("tabs.unmute", {"tabId": tab_id})
|
||||
target = result.get("tabId", tab_id) if isinstance(result, dict) else tab_id
|
||||
console.print(f"[green]Unmuted tab {target}[/green]")
|
||||
|
||||
|
||||
@tabs_group.command("pin")
|
||||
@click.argument("tab_id", type=int, required=False)
|
||||
def tabs_pin(tab_id):
|
||||
"""Pin the active tab or a specific tab."""
|
||||
result = _handle("tabs.pin", {"tabId": tab_id})
|
||||
target = result.get("tabId", tab_id) if isinstance(result, dict) else tab_id
|
||||
console.print(f"[green]Pinned tab {target}[/green]")
|
||||
|
||||
|
||||
@tabs_group.command("unpin")
|
||||
@click.argument("tab_id", type=int, required=False)
|
||||
def tabs_unpin(tab_id):
|
||||
"""Unpin the active tab or a specific tab."""
|
||||
result = _handle("tabs.unpin", {"tabId": tab_id})
|
||||
target = result.get("tabId", tab_id) if isinstance(result, dict) else tab_id
|
||||
console.print(f"[green]Unpinned tab {target}[/green]")
|
||||
|
||||
|
||||
@tabs_group.command("watch-url")
|
||||
@click.argument("pattern")
|
||||
@click.option("--tab", "tab_id", type=int, default=None, help="Tab ID (default: active tab)")
|
||||
@click.option("--timeout", type=float, default=30.0, show_default=True, help="Max seconds to wait")
|
||||
def tabs_watch_url(pattern, tab_id, timeout):
|
||||
"""Wait until the active (or specified) tab URL matches regex PATTERN."""
|
||||
result = _handle("tabs.watch_url", {"pattern": pattern, "tabId": tab_id, "timeout": int(timeout * 1000)})
|
||||
url = result.get("url", "") if isinstance(result, dict) else ""
|
||||
console.print(f"[green]URL matched:[/green] {url}")
|
||||
|
||||
|
||||
@tabs_group.command("screenshot")
|
||||
@click.argument("output", required=False, metavar="FILE")
|
||||
@click.option("--tab", "tab_id", type=int, default=None, help="Tab ID (default: active tab)")
|
||||
@click.option("--format", "fmt", type=click.Choice(["png", "jpeg"]), default="png", show_default=True)
|
||||
@click.option("--quality", type=int, default=None, help="JPEG quality 0-100")
|
||||
def tabs_screenshot(output, tab_id, fmt, quality):
|
||||
"""Capture a screenshot of the active (or specified) tab.
|
||||
|
||||
Saves to FILE if given, otherwise prints the base64 data URL.
|
||||
"""
|
||||
result = _handle("tabs.screenshot", {"tabId": tab_id, "format": fmt, "quality": quality})
|
||||
data_url = result.get("dataUrl", "") if isinstance(result, dict) else ""
|
||||
if output:
|
||||
header = f"data:image/{fmt};base64,"
|
||||
raw = base64.b64decode(data_url[len(header):])
|
||||
with open(output, "wb") as f:
|
||||
f.write(raw)
|
||||
console.print(f"[green]Screenshot saved:[/green] {output}")
|
||||
else:
|
||||
console.print(data_url)
|
||||
|
||||
Reference in New Issue
Block a user