browser-pilot-cli
Advanced tools
+37
-9
@@ -554,3 +554,4 @@ #!/usr/bin/env node | ||
| bp click <ref> # interact \u2014 returns updated snapshot | ||
| bp click 0 --xy 400,300 # click at coordinates (canvas/maps) | ||
| bp click --xy 400,300 # click at coordinates (canvas/maps) | ||
| bp locate ".selector" # get element coordinates for click --xy | ||
| bp type <ref> <text> # input text \u2014 returns updated snapshot | ||
@@ -783,11 +784,11 @@ bp keyboard <text> # type via keyboard events (Google Docs etc.) | ||
| })); | ||
| program.command("click <ref>").description("Click element by ref number and return page snapshot").option("--xy <coords>", "click at x,y coordinates instead of ref (e.g. --xy 400,300)").option("--double", "double-click").option("--right", "right-click (context menu)").option("-l, --limit <n>", "max elements in snapshot", "50").addHelpText("after", ` | ||
| Ref is a number from the snapshot output, or use --xy for coordinate clicks. | ||
| program.command("click [ref]").description("Click element by ref number or at x,y coordinates").option("--xy <coords>", "click at x,y viewport coordinates (e.g. --xy 400,300)").option("--double", "double-click").option("--right", "right-click (context menu)").option("-l, --limit <n>", "max elements in snapshot", "50").addHelpText("after", ` | ||
| Examples: | ||
| bp click 3 # click element [3] | ||
| bp click 0 --xy 400,300 # click at coordinates (ref ignored) | ||
| bp click 0 --xy 400,300 --double # double-click at coordinates | ||
| bp click 0 --xy 400,300 --right # right-click at coordinates`).action(action(async (ref, opts) => { | ||
| bp click 3 # click element [3] from snapshot | ||
| bp click --xy 400,300 # click at viewport coordinates | ||
| bp click --xy 400,300 --double # double-click at coordinates | ||
| bp click --xy 400,300 --right # right-click (context menu) | ||
| bp click 3 --right # right-click element [3]`).action(action(async (ref, opts) => { | ||
| if (opts.double && opts.right) throw new Error("--double and --right are mutually exclusive"); | ||
| if (!ref && !opts.xy) throw new Error("Provide a ref number or --xy coordinates"); | ||
| const limit = parseLimit(opts.limit); | ||
@@ -837,2 +838,24 @@ await withPilot(async ({ transport, sessionId, state }) => { | ||
| })); | ||
| program.command("locate <selector>").description("Get element coordinates by CSS selector (for use with click --xy)").addHelpText("after", ` | ||
| Returns center coordinates and bounding box of an element. | ||
| Use with click --xy for canvas apps, charts, or elements not in snapshot. | ||
| Examples: | ||
| bp locate ".kix-appview-editor" # Google Docs editor area | ||
| bp locate "canvas" # canvas element | ||
| bp locate "#map" # map container`).action(action(async (selector) => { | ||
| await withPilot(async ({ transport, sessionId }) => { | ||
| const { result } = await transport.send("Runtime.evaluate", { | ||
| expression: `JSON.stringify((function(){var el=document.querySelector(${JSON.stringify(selector)});if(!el)return null;el.scrollIntoView({block:'center',inline:'center'});var r=el.getBoundingClientRect();return{x:Math.round(r.x+r.width/2),y:Math.round(r.y+r.height/2),top:Math.round(r.top),left:Math.round(r.left),width:Math.round(r.width),height:Math.round(r.height)}})())`, | ||
| returnByValue: true | ||
| }, sessionId); | ||
| const coords = result.value ? JSON.parse(result.value) : null; | ||
| if (!coords) throw new Error(`Element not found: ${selector}`); | ||
| if (useJson()) { | ||
| console.log(JSON.stringify({ ok: true, ...coords })); | ||
| } else { | ||
| console.log(`center: ${coords.x},${coords.y} size: ${coords.width}x${coords.height} (top:${coords.top} left:${coords.left})`); | ||
| } | ||
| }); | ||
| })); | ||
| program.command("type <ref> <text>").description("Type text into element and return page snapshot").option("-c, --clear", "clear field before typing").option("-s, --submit", "press Enter after typing").option("-l, --limit <n>", "max elements in snapshot", "50").addHelpText("after", '\nExamples:\n bp type 2 "hello world"\n bp type 5 "query" --submit\n bp type 3 "new value" --clear').action(action(async (ref, text, opts) => { | ||
@@ -954,3 +977,8 @@ const limit = parseLimit(opts.limit); | ||
| if (opts.submit) await dispatchKey(transport, sessionId, "Enter"); | ||
| emitSnapshot(await snap(transport, sessionId, state.activeTargetId, limit)); | ||
| const snapResult = await snap(transport, sessionId, state.activeTargetId, limit); | ||
| if (useJson()) { | ||
| console.log(JSON.stringify({ ok: true, typed: text, ...snapResult.data })); | ||
| } else { | ||
| console.log(snapResult.text); | ||
| } | ||
| }); | ||
@@ -957,0 +985,0 @@ })); |
+1
-1
| { | ||
| "name": "browser-pilot-cli", | ||
| "version": "0.1.5", | ||
| "version": "0.1.6", | ||
| "description": "CLI tool to control your browser via Chrome DevTools Protocol", | ||
@@ -5,0 +5,0 @@ "type": "module", |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
304702
0.57%2697
1.09%