patchright-cli 0.6.0__py3-none-any.whl → 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
1
  """patchright-cli — Undetected browser automation CLI using Patchright."""
2
2
 
3
- __version__ = "0.6.0"
3
+ __version__ = "0.7.0"
@@ -9,6 +9,14 @@ patchright-cli drives a real Chrome browser that passes bot detection (Cloudflar
9
9
 
10
10
  ## Quick start
11
11
 
12
+ If `patchright-cli` is not on PATH yet, install it first -- one of:
13
+
14
+ ```bash
15
+ uvx patchright-cli --version # run without installing
16
+ pip install patchright-cli # or install it
17
+ python -m patchright install chromium # then fetch the browser, once
18
+ ```
19
+
12
20
  ```bash
13
21
  patchright-cli open https://example.com # launch browser + navigate
14
22
  patchright-cli snapshot # get element refs
@@ -35,33 +43,63 @@ patchright-cli snapshot # read refs from output
35
43
  patchright-cli click e5 # use discovered ref
36
44
  ```
37
45
 
46
+ ## Shell quoting
47
+
48
+ Quote any URL containing `&`. Unquoted, the shell eats it before patchright-cli
49
+ sees it:
50
+
51
+ ```bash
52
+ # WRONG -- PowerShell 7 treats `&` as the background operator: the command is
53
+ # detached and everything after `&` is run as a separate command.
54
+ # cmd.exe treats it as a command separator. Either way the URL is truncated.
55
+ patchright-cli goto https://example.com/search?q=cats&page=2
56
+
57
+ # RIGHT -- on any shell
58
+ patchright-cli goto "https://example.com/search?q=cats&page=2"
59
+ ```
60
+
61
+ The same applies to `#` (a bash comment), spaces, and `%` (expanded by
62
+ cmd.exe), and to any argument holding shell metacharacters. Quoting always
63
+ works; leave it on.
64
+
38
65
  ## Global options
39
66
 
40
67
  These go before the command:
41
68
 
42
69
  ```bash
43
70
  --headless # Run headless (default: headed -- headed is less detectable)
44
- --persistent # Use persistent profile (keeps cookies/storage across sessions)
45
- --profile=/path # Custom profile directory
71
+ --profile=<name> # Named profile any session can use (default: the session name);
72
+ # profiles always persist. A value with / or \ is a directory
46
73
  --proxy=<url> # Proxy server (http, https, socks5) -- supports user:pass@host auth
47
74
  -s=mysession # Named session (default: "default", or PATCHRIGHT_CLI_SESSION env var)
48
75
  --port=9322 # Custom daemon port (default: 9321)
49
76
  --config=<path> # Load options from JSON config file
50
77
  --cdp=<url> # Attach to Chrome via CDP endpoint (use with `attach` command)
78
+ --context=new|host # With `attach`: fresh isolated context (default) or the browser's own
51
79
  --device="iPhone 15" # Emulate a device
80
+ --mobile # Emulate a generic mobile device (Pixel 7); mobile pages
81
+ # are lighter, so snapshots are smaller and cheaper
52
82
  --viewport-size=1280x720 # Set viewport size
53
83
  --locale=en-US # Browser locale
54
84
  --timezone=America/New_York # Timezone ID
55
85
  --geolocation=40.7,-74.0 # Geolocation override (lat,lon)
56
86
  --user-agent=<ua> # Custom user agent string
57
87
  --grant-permissions=geolocation,camera # Grant permissions at launch
58
- --timeout-action=10000 # Default action timeout (ms)
59
- --timeout-navigation=30000 # Default navigation timeout (ms)
60
88
  --show-port=9322 # Dashboard port (default: 9322)
61
89
  --raw # Strip page/snapshot decorations from output
62
90
  --json # Wrap full response as JSON ({success, output, ...})
63
91
  ```
64
92
 
93
+ These go *after* the command instead:
94
+
95
+ ```bash
96
+ --timeout=1800 # Daemon idle timeout in seconds before it exits and
97
+ # takes the browser (and its login) with it. Default 1800.
98
+ # Also settable up front via $PATCHRIGHT_CLI_IDLE_TIMEOUT.
99
+ --timeout-action=10000 # Default action timeout (ms)
100
+ --timeout-navigation=30000 # Default navigation timeout (ms)
101
+ ```
102
+
65
103
  ---
66
104
 
67
105
  ## Core commands
@@ -70,10 +108,11 @@ These go before the command:
70
108
 
71
109
  ```bash
72
110
  open [url] # Launch browser (optionally navigate)
73
- open --persistent # Keep cookies/storage between runs
111
+ open --profile=work # Run on a named profile (logins persist; one session at a time)
74
112
  open --headless # Headless mode
75
- attach --cdp=<url> # Attach to existing Chrome via CDP
76
- close # Close session (closes the browser)
113
+ attach --cdp=<url> # Attach to existing Chrome via CDP (fresh, isolated context)
114
+ attach --cdp=<url> --context=host # Use the Host Context: the browser's own logins, cookies, storage
115
+ close # Close session (closes the browser); refused on --context=host -- use detach
77
116
  detach # Detach an attached session (keeps external browser running)
78
117
  ```
79
118
 
@@ -92,11 +131,47 @@ title # Print page title
92
131
  ```bash
93
132
  snapshot # Full page snapshot
94
133
  snapshot <ref> # Subtree of a specific element
134
+ snapshot --selector="#main" # Subtree of a CSS selector -- must match exactly
135
+ # one element. No ref needed, so
136
+ # this works before the first snapshot
95
137
  snapshot --depth=N # Limit depth
96
138
  snapshot -i # Interactive elements only
97
139
  snapshot --boxes # Append [box=x,y,w,h] to each [ref=eN] line
98
140
  ```
99
141
 
142
+ ### Searching instead of snapshotting
143
+
144
+ On a large page, `find` is the cheaper first move — a full snapshot of a
145
+ Wikipedia article is ~87k tokens; `find` returns a few hundred.
146
+
147
+ ```bash
148
+ patchright-cli find "Sign in" # substring, case-insensitive
149
+ patchright-cli find --regex "sign (in|up)" # regex, case-insensitive
150
+ patchright-cli find --regex "/Sign In/" # slash form carries flags (i, m, s)
151
+ patchright-cli find "price" --all # include text/paragraph nodes
152
+ patchright-cli find "hide" --limit=50 # default limit is 20
153
+ ```
154
+
155
+ `find` searches links, buttons, inputs and headings by default — the things
156
+ you can act on. Use `--all` when you are looking for page *content* rather
157
+ than a control.
158
+
159
+ Each hit prints a `#` breadcrumb showing where it sits, so identical
160
+ controls stay distinguishable:
161
+
162
+ ```
163
+ # table > rowgroup > cell "407 points by pluc 4 hours ago | hide | 321 ..."
164
+ - link "hide": [ref=e49]
165
+ - /url: hide?id=49489982
166
+ ```
167
+
168
+ Refs from `find` are numbered across the whole page and are immediately
169
+ usable with `click`, `fill`, and the rest. They stay valid until the next
170
+ `snapshot` or `find`.
171
+
172
+ When output says `Found 20 of 340 matches`, narrow the query rather than
173
+ raising `--limit`.
174
+
100
175
  ### Interaction
101
176
 
102
177
  ```bash
@@ -138,6 +213,9 @@ screenshot --filename=F # Custom filename
138
213
  scroll <dx> <dy> # Scroll by pixels
139
214
  scroll-to <ref> # Scroll element into view
140
215
  wait <ms> # Wait N milliseconds
216
+ wait --url="**/dashboard" # Wait until the URL matches -- the right tool
217
+ # after a login or any redirect. `*` does NOT
218
+ # cross a `/`, so use `**`; `/regex/i` also works
141
219
  wait-for <ref> # Wait until element visible
142
220
  wait-for <ref> --state=hidden # Wait until hidden
143
221
  press <key> # Keypress (Enter, ArrowDown, etc.)
@@ -157,10 +235,51 @@ mousewheel <dx> <dy> # Scroll wheel
157
235
  ```bash
158
236
  tab-list # List open tabs
159
237
  tab-new <url> # Open new tab
160
- tab-select <index> # Switch to tab
161
- tab-close [index] # Close tab
238
+ tab-select <index> # Switch to tab (default tab only; a --tab
239
+ # caller is pinned to its own page)
240
+ tab-close [index] # Close tab (with --context=host, only tabs this session opened)
241
+ ```
242
+
243
+ ### Parallel agents: --tab
244
+
245
+ `--tab <name>` gives a caller its own page, its own refs and its own history
246
+ inside one shared browser -- same fingerprint, same cookies, same login. It is
247
+ the cheap way to parallelise: one Chrome total, not one per agent.
248
+
249
+ ```bash
250
+ patchright-cli --tab inbox-scan open https://app.example.com/inbox
251
+ patchright-cli --tab report-pull open https://app.example.com/reports
252
+ patchright-cli --tab inbox-scan snapshot # refs belong to this tab only
253
+ patchright-cli tab-list # every tab, labelled by owner
254
+ patchright-cli --tab inbox-scan close # frees this tab; browser stays
255
+ ```
256
+
257
+ **Choose the name once, with a shell-generated suffix.** Nothing enforces
258
+ uniqueness -- two agents on the same name share one page and clobber each
259
+ other. Do not invent the random part yourself; LLM-chosen "random" characters
260
+ collide.
261
+
262
+ ```bash
263
+ TAB="price-scan-$(openssl rand -hex 2)" && echo "$TAB"
264
+ patchright-cli --tab "$TAB" open https://example.com
265
+ # reuse that exact printed name in every later command
162
266
  ```
163
267
 
268
+ `$PATCHRIGHT_CLI_TAB` sets it for a whole shell, the way `$PATCHRIGHT_CLI_SESSION`
269
+ does for sessions.
270
+
271
+ Cleanup needs no coordination: every agent runs `close` addressed to its own
272
+ tab, and the browser exits when the last tab goes. On an `attach --context=host`
273
+ session the host's browser never exits: closing tabs leaves it attached, and
274
+ whoever attached runs `detach` at the end.
275
+
276
+ **`--tab` vs `-s`.** `--tab` shares identity, one browser (~50-150MB per extra
277
+ tab), for agents acting as the same logged-in user. `-s` isolates identity --
278
+ its own profile, cookies and fingerprint, a full Chrome each (~300-500MB) --
279
+ for multi-account work. Tabs share one browser process, so commands from
280
+ different tabs queue behind a slow navigation; separate sessions run fully in
281
+ parallel.
282
+
164
283
  ### Dialogs
165
284
 
166
285
  Dialogs must be pre-armed *before* the action that triggers them:
@@ -191,11 +310,14 @@ highlight <ref> --hide # Remove overlay; `highlight --hide` clears all
191
310
  ```bash
192
311
  screenshot / pdf # Static capture
193
312
  video-start / video-stop # Video recording
313
+ video-show-actions # Label each action in the recording [--duration=ms] [--position=P]
314
+ video-hide-actions # Stop labelling actions
194
315
  tracing-start / tracing-stop # Playwright trace
195
316
  codegen / codegen-stop # Record interactions as script
196
317
  resize <w> <h> # Viewport resize
197
318
  upload <file> [ref] # File upload
198
319
  show # Live dashboard
320
+ show --annotate # Ask a human to mark up the page and wait for it
199
321
  ```
200
322
 
201
323
  ### Storage
@@ -224,6 +346,8 @@ list # List active sessions
224
346
  close-all # Close all sessions
225
347
  kill-all # Force-kill all + stop daemon
226
348
  delete-data # Delete session profile data
349
+ profile-list # List profiles, size, and which session uses each
350
+ profile-delete <name> # Delete an idle named profile
227
351
  grant-permissions <perms> # Grant browser permissions
228
352
  ```
229
353
 
@@ -234,13 +358,13 @@ grant-permissions <perms> # Grant browser permissions
234
358
  ### Login flow
235
359
 
236
360
  ```bash
237
- patchright-cli open https://example.com/login --persistent
361
+ patchright-cli open --profile=myapp https://example.com/login
238
362
  patchright-cli snapshot
239
363
  patchright-cli fill e3 "user@example.com"
240
364
  patchright-cli fill e5 "password123"
241
365
  patchright-cli click e8
242
366
  patchright-cli snapshot
243
- # With --persistent, cookies survive across sessions
367
+ # The login persists in profile "myapp" for any later session that opens it
244
368
  ```
245
369
 
246
370
  ### Extracting data
@@ -278,11 +402,35 @@ patchright-cli click e5 # This click triggers the dialog
278
402
  ```bash
279
403
  patchright-cli wait-for e12 # Wait for element
280
404
  patchright-cli wait 1000 # Fixed wait
405
+ patchright-cli wait --url="**/dashboard" # Wait for a redirect to land
281
406
  # For custom conditions, use run-code (see references/running-code.md)
282
407
  ```
283
408
 
284
409
  ---
285
410
 
411
+ ## Asking a human what to change
412
+
413
+ `show --annotate` is for design and UI review: it opens a page in the user's
414
+ browser showing a live capture of the current page, they draw on it and write
415
+ what they want changed, and the command returns their drawing plus their notes.
416
+
417
+ ```bash
418
+ patchright-cli show --annotate # waits up to 5 minutes
419
+ patchright-cli show --annotate --wait=900 # give them longer
420
+ patchright-cli show --annotate --no-open # headless box: do not launch a browser
421
+ ```
422
+
423
+ The command **blocks** until they submit, so it opens the review link for them
424
+ rather than printing it. The link is also written to
425
+ `.patchright-cli/annotate-url.txt`, which is how you get it when `--no-open`
426
+ suppressed the browser. You get back the annotated screenshot saved under
427
+ `.patchright-cli/`, their notes, and a fresh snapshot of the page -- enough to
428
+ act on the feedback without asking follow-up questions.
429
+
430
+ Reach for it when the decision is aesthetic or subjective and you would
431
+ otherwise be guessing: which of two layouts, where an element belongs, whether
432
+ spacing reads right. Do not use it for anything you can check yourself.
433
+
286
434
  ## Anti-detect notes
287
435
 
288
436
  - Uses real Chrome (not Chromium) -- this is what makes it undetectable
@@ -291,7 +439,8 @@ patchright-cli wait 1000 # Fixed wait
291
439
  - No custom user-agent or headers by default -- preserves Chrome's natural fingerprint
292
440
  - Persistent profiles maintain realistic browser history and cookies
293
441
  - The daemon architecture means Chrome stays running between commands, behaving like a real user's browser
294
- - `attach --cdp` lets you connect to an existing Chrome instance
442
+ - `attach --cdp` lets you connect to an existing Chrome instance; add `--context=host` to reuse its logins,
443
+ cookies and storage (see references/session-management.md)
295
444
 
296
445
  ## Config files
297
446
 
@@ -339,6 +488,16 @@ pip install patchright-cli && patchright-cli install --skills
339
488
  # "Install patchright-cli skill from https://raw.githubusercontent.com/AhaiMk01/patchright-cli/main/skills/patchright-cli/SKILL.md"
340
489
  ```
341
490
 
491
+ When an installed copy of this skill drifts from the tool version,
492
+ patchright-cli prints a one-line warning on stderr -- once a day per
493
+ version, so a chained run is not buried in it. Re-run
494
+ `patchright-cli install --skills` to resync, or set
495
+ `PATCHRIGHT_CLI_NO_SKILL_CHECK=1` to silence the check.
496
+
497
+ `open` also checks PyPI once a day for a newer patchright-cli and prints a
498
+ one-line note when there is one. Set `PATCHRIGHT_CLI_NO_VERSION_CHECK=1` to
499
+ turn that off.
500
+
342
501
  ## Specific tasks
343
502
 
344
503
  * **Snapshots and element refs** [references/snapshot-refs.md](references/snapshot-refs.md)
@@ -21,25 +21,37 @@ patchright-cli open https://example.com # Uses "myproject" session
21
21
  patchright-cli snapshot # Same session
22
22
  ```
23
23
 
24
- ## Persistent profiles
24
+ ## Profiles
25
25
 
26
- Use `--persistent` to keep cookies, localStorage, and browser data across sessions:
26
+ Every session you `open` runs on a **profile**: a persistent store of cookies,
27
+ storage, logins and history. (Attached sessions use the browser's own data.) Profiles always persist -- close the session, open it
28
+ again later, and you are still logged in. (`--persistent` is accepted but
29
+ changes nothing.)
27
30
 
28
- ```bash
29
- patchright-cli open https://example.com --persistent
30
- # ... log in, do work ...
31
- patchright-cli close
32
- # Later:
33
- patchright-cli open https://example.com --persistent
34
- # Cookies and storage are restored
35
- ```
36
-
37
- Profiles are stored at `~/.patchright-cli/profiles/<session-name>`. Use `--profile=/path` to specify a custom profile directory:
31
+ By default the profile is named after the session. `--profile=<name>` picks a
32
+ named profile instead, so any session can use it:
38
33
 
39
34
  ```bash
40
- patchright-cli open --persistent --profile=/path/to/my/profile https://example.com
35
+ patchright-cli -s=agent1 open --profile=work https://app.example.com
36
+ # ... log in once, then close ...
37
+ patchright-cli -s=agent1 close
38
+ patchright-cli -s=agent2 open --profile=work https://app.example.com # still logged in
41
39
  ```
42
40
 
41
+ - A value containing `/` or `\` is a directory instead of a name:
42
+ `--profile=/path/to/dir`, `--profile=./browser` (relative to where you run
43
+ the command). Names use letters, digits, `.`, `_`, `-`.
44
+ - A session name that isn't a valid profile name (e.g. has spaces) needs an
45
+ explicit `--profile`.
46
+ - One session per profile at a time -- Chrome locks it. A second session asking
47
+ for a busy profile is refused; run extra agents as `--tab`s on the session that
48
+ holds it.
49
+ - `profile-list` shows every profile, its size, and which session uses it.
50
+ - `profile-delete <name>` deletes an idle named profile (never a path).
51
+ `delete-data` deletes only the profile named after the session; for a
52
+ shared profile use `profile-delete`.
53
+ - Profiles live at `~/.patchright-cli/profiles/<name>`.
54
+
43
55
  ## CDP attach
44
56
 
45
57
  Connect to an already-running Chrome instance via Chrome DevTools Protocol instead of launching a new one:
@@ -50,6 +62,31 @@ patchright-cli attach --cdp=http://localhost:9222
50
62
 
51
63
  This is useful for debugging or controlling a browser you launched manually with `--remote-debugging-port`.
52
64
 
65
+ By default `attach` opens a fresh Isolated Context inside that browser, so it
66
+ does not see the browser's existing cookies, localStorage or logins. To work in
67
+ the Host Context instead -- the browser's own context, e.g. a Chrome started
68
+ with a persistent `--user-data-dir` -- pass `--context=host`:
69
+
70
+ ```bash
71
+ patchright-cli attach --cdp=http://localhost:9222 --context=host
72
+ ```
73
+
74
+ With `--context=host`:
75
+
76
+ - Emulation flags (`--device`, `--mobile`, `--viewport-size`, `--locale`,
77
+ `--timezone`, `--geolocation`, `--user-agent`, `--grant-permissions`) are
78
+ rejected -- the Host Context's settings are fixed. The same keys in a config
79
+ file are ignored for this attach.
80
+ - Only one session may use a given Host Context, however its endpoint is
81
+ spelled. Run extra agents as `--tab`s on that session, or attach them with
82
+ `--context=new`.
83
+ - The session only closes Pages it opened (`--tab`s, `tab-new`, and popups
84
+ they spawn). Plain `close` and `delete-data` are refused, and `tab-close`
85
+ refuses the Host's own tabs: use `detach`. `detach`, `close-all` and
86
+ `kill-all` close your Pages and leave the Host's tabs and state untouched.
87
+ - If the Host restarts Chrome, re-run the same `attach`: the stale session is
88
+ replaced automatically and the output says so.
89
+
53
90
  ## Session commands
54
91
 
55
92
  ```bash
@@ -61,13 +98,39 @@ patchright-cli delete-data # Delete default session's profile da
61
98
  patchright-cli -s=mysession delete-data # Delete named session's profile data
62
99
  ```
63
100
 
101
+ ## Concurrent tabs (shared identity)
102
+
103
+ `--tab <name>` is the cheaper unit of concurrency: one browser, one login, but
104
+ a page, ref registry and navigation history per caller.
105
+
106
+ ```bash
107
+ patchright-cli --tab orders-audit open https://app.example.com/a
108
+ patchright-cli --tab user-export open https://app.example.com/b
109
+ patchright-cli tab-list # labelled by owning tab
110
+ patchright-cli --tab orders-audit close # frees one tab only
111
+ ```
112
+
113
+ `close` releases the tab it is addressed to and the session ends when the last
114
+ tab closes, so concurrent agents clean up without coordinating. A session opened
115
+ only through `--tab` has no default tab in use, so closing the named tabs ends
116
+ it; one opened with a plain `open` keeps its default tab until that is closed
117
+ too. A command
118
+ addressed to a tab that was never opened is an error rather than a silent
119
+ fallback to the default tab -- a typo in a tab name should not quietly drive
120
+ someone else's page.
121
+
122
+ Named tabs are pinned to their own page, so `tab-select` and popups cannot move
123
+ them; `tab-select` addressed to a named tab is refused rather than silently
124
+ moving somebody else's page. The default tab still follows the index-based
125
+ `tab-select`.
126
+
64
127
  ## Concurrent sessions
65
128
 
66
129
  You can run multiple sessions simultaneously for parallel workflows:
67
130
 
68
131
  ```bash
69
- patchright-cli -s=scrape1 open https://site1.com --persistent
70
- patchright-cli -s=scrape2 open https://site2.com --persistent
132
+ patchright-cli -s=scrape1 open https://site1.com
133
+ patchright-cli -s=scrape2 open https://site2.com
71
134
  # Work with both independently
72
135
  patchright-cli -s=scrape1 snapshot
73
136
  patchright-cli -s=scrape2 snapshot
@@ -95,7 +158,10 @@ You can also grant permissions at launch with `--grant-permissions=geolocation,c
95
158
 
96
159
  ## Daemon behavior
97
160
 
98
- The daemon auto-starts on the first command and auto-shuts down after 5 minutes of inactivity. If it ever crashes, the next command will respawn it automatically.
161
+ The daemon auto-starts on the first command and auto-shuts down after 30 minutes of inactivity
162
+ (`--timeout=<seconds>` after the command, or `$PATCHRIGHT_CLI_IDLE_TIMEOUT` up front). A command
163
+ that is still running does not count as inactivity, so a long `show --annotate` will not be cut
164
+ short. If the daemon ever crashes, the next command respawns it automatically.
99
165
 
100
166
  ## Cleanup best practices
101
167
 
@@ -26,6 +26,7 @@ patchright-cli snapshot --interactive # Same as -i
26
26
  | Flag | Effect |
27
27
  |------|--------|
28
28
  | `[ref]` | Show only the subtree rooted at the given ref |
29
+ | `--selector=<css>` | Show only the subtree under a CSS selector. Must match exactly one element |
29
30
  | `--depth=N` | Limit depth of the tree (useful for complex pages) |
30
31
  | `-i` / `--interactive` | Show only interactive elements (buttons, links, inputs) |
31
32
  | `--filename=F` | Save snapshot to a custom file path |
@@ -73,6 +74,15 @@ Some elements are hidden or overlapped. Try:
73
74
  - `wait-for <ref>` to wait until the element appears
74
75
  - `snapshot -i` to see only interactive elements
75
76
  - `snapshot <ref>` to inspect a subtree for nested elements
77
+ - `snapshot --selector="#main"` to scope by CSS when you have no ref yet
78
+
79
+ ### Refs from a scoped snapshot
80
+
81
+ A scoped snapshot -- `snapshot <ref>` or `snapshot --selector=<css>` -- numbers
82
+ its refs from `e1` within that subtree, and those refs resolve inside the same
83
+ subtree. They are not the numbers a full-page `snapshot` would give, so do not
84
+ mix refs from a scoped snapshot with refs from a full one: take a fresh
85
+ snapshot at the scope you intend to work in.
76
86
 
77
87
  ### Too many elements in snapshot
78
88
  Use `--depth=N` to limit tree depth, or snapshot a specific subtree with `snapshot <ref>`. The `-i` flag also helps by filtering to interactive elements only.
@@ -84,3 +94,49 @@ patchright-cli click e5 # Triggers dynamic load
84
94
  patchright-cli wait 1000 # Wait for content
85
95
  patchright-cli snapshot # Get fresh refs
86
96
  ```
97
+
98
+ ## `find` — searching the snapshot
99
+
100
+ ```
101
+ find <text> Substring match on the accessible name, case-insensitive
102
+ find --regex <pattern> Regex match; bare patterns are case-insensitive
103
+ find --regex "/p/ims" Slash form; supported flags are i, m, s
104
+ find --all Search every node, not just interactive roles + heading
105
+ find --limit=N Cap rendered hits (default 20)
106
+ ```
107
+
108
+ ### What gets searched
109
+
110
+ By default, roles in `SEARCHABLE_ROLES` — every interactive role plus
111
+ `heading`. This is deliberate: role filtering is the single biggest lever on
112
+ output size. Measured across 13 queries on four real pages it cut hits 4.3x
113
+ (729 to 168); on one Wikipedia query, 442 hits became 53.
114
+
115
+ Matching runs against a node's accessible name. For unnamed nodes such as
116
+ `- text: Star 95.3k`, the value after the colon is used instead. Property
117
+ lines like `- /url: ...` are not nodes and never match.
118
+
119
+ ### Output
120
+
121
+ Per hit: a ` # ancestor > ancestor > parent` breadcrumb (3 deep, names cut at
122
+ 45 characters, repeated names collapsed), then the matched node with its ref,
123
+ then its subtree.
124
+
125
+ `find` prints inline and writes no `.yml` file. `snapshot` still writes one.
126
+
127
+ ### Divergence from playwright-cli
128
+
129
+ playwright-cli's `find` searches all nodes and returns grep-style +/-3 lines of
130
+ context. This one defaults to interactive roles and returns the matched
131
+ subtree with a breadcrumb. Across 13 queries on four real pages, total output
132
+ was 13KB here against 37KB there (a single lookup is a few hundred bytes). `--all` widens the search to every node like
133
+ playwright-cli's does, but each hit still renders as a full subtree rather
134
+ than +/-3 lines of context — on content-heavy pages a matching container can
135
+ print its entire subtree, plus its matching descendants again as their own
136
+ hits (Hacker News `find "comments"` returned 45% of the page this way).
137
+
138
+ ### When hits are truncated
139
+
140
+ `Found 20 of 340 matches` means the query is too broad. Narrow it — a longer
141
+ substring, or a regex anchored with `\b`. Raising `--limit` just buys more
142
+ tokens for the same ambiguity.
@@ -27,6 +27,30 @@ patchright-cli video-stop
27
27
 
28
28
  Chapters are saved as a JSON file alongside the video.
29
29
 
30
+ ### Action callouts
31
+
32
+ Label each action in the recording as it happens: a badge naming the action
33
+ and the element, plus a ring around the target.
34
+
35
+ ```bash
36
+ patchright-cli video-start
37
+ patchright-cli video-show-actions # 600ms, top-right
38
+ patchright-cli video-show-actions --duration=1200 --position=bottom-left
39
+ patchright-cli click e5 # renders: click button "Sign in"
40
+ patchright-cli video-hide-actions # stop annotating
41
+ patchright-cli video-stop
42
+ ```
43
+
44
+ `--position` takes `top-left`, `top-right`, `bottom-left`, or `bottom-right`.
45
+
46
+ The callout is drawn *before* the action, because a click can navigate away
47
+ or detach the element. It is `pointer-events: none` and `aria-hidden`, so it
48
+ neither blocks the interaction nor shows up in `snapshot`.
49
+
50
+ Callouts are only drawn while a recording is running -- the flag persists
51
+ across `video-start` / `video-stop`, but outside a recording the page is left
52
+ alone.
53
+
30
54
  ## Codegen (interaction recording)
31
55
 
32
56
  Record your browser interactions and save them as a replayable bash script:
@@ -47,8 +71,15 @@ patchright-cli screenshot # Page screenshot
47
71
  patchright-cli screenshot e3 # Element screenshot by ref
48
72
  patchright-cli screenshot --filename=page.png # Custom filename
49
73
  patchright-cli screenshot --full-page # Full scrollable page
74
+ patchright-cli screenshot --hires # Capture at device pixel ratio
50
75
  ```
51
76
 
77
+ Screenshots capture one image pixel per CSS pixel. That matches the desktop
78
+ default (device pixel ratio 1), so `--hires` only changes anything under
79
+ `open --mobile` or `open --device=...`, where the ratio is 2-3x and `--hires`
80
+ produces a correspondingly larger file.
81
+
82
+
52
83
  Screenshots save to `.patchright-cli/` in the current directory.
53
84
 
54
85
  ## PDF capture