pi-ui-extend 0.1.67 → 0.1.69

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.
@@ -215,8 +215,8 @@ class LazySessionManager {
215
215
  createBranchedSession(leafId) {
216
216
  return this.hydrate().createBranchedSession(leafId);
217
217
  }
218
- branchWithSummary(branchFromId, summary, details, fromHook) {
219
- return this.hydrate().branchWithSummary(branchFromId, summary, details, fromHook);
218
+ branchWithSummary(branchFromId, summary, details, fromHook, usage) {
219
+ return this.hydrate().branchWithSummary(branchFromId, summary, details, fromHook, usage);
220
220
  }
221
221
  appendLabelChange(targetId, label) {
222
222
  if (this.hydrated)
@@ -248,14 +248,16 @@ class LazySessionManager {
248
248
  return this.hydrated.appendModelChange(provider, modelId);
249
249
  return this.appendEntry(this.newEntry("model_change", { provider, modelId }));
250
250
  }
251
- appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook) {
251
+ appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook, usage) {
252
252
  if (this.hydrated)
253
- return this.hydrated.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook);
253
+ return this.hydrated.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromHook, usage);
254
254
  const payload = { summary, firstKeptEntryId, tokensBefore };
255
255
  if (details !== undefined)
256
256
  payload.details = details;
257
257
  if (fromHook !== undefined)
258
258
  payload.fromHook = fromHook;
259
+ if (usage !== undefined)
260
+ payload.usage = usage;
259
261
  return this.appendEntry(this.newEntry("compaction", payload));
260
262
  }
261
263
  appendCustomEntry(customType, data) {
@@ -17,7 +17,18 @@ export function aggregateSessionStats(entries, base) {
17
17
  let cacheRead = 0;
18
18
  let cacheWrite = 0;
19
19
  let cost = 0;
20
+ function addUsage(usage) {
21
+ input += finiteNumber(usage?.input);
22
+ output += finiteNumber(usage?.output);
23
+ cacheRead += finiteNumber(usage?.cacheRead);
24
+ cacheWrite += finiteNumber(usage?.cacheWrite);
25
+ cost += finiteNumber(usage?.cost?.total);
26
+ }
20
27
  for (const entry of entries) {
28
+ if (entry.type === "compaction" || entry.type === "branch_summary") {
29
+ addUsage(entry.usage);
30
+ continue;
31
+ }
21
32
  if (entry.type !== "message")
22
33
  continue;
23
34
  totalMessages += 1;
@@ -28,6 +39,7 @@ export function aggregateSessionStats(entries, base) {
28
39
  }
29
40
  if (message.role === "toolResult") {
30
41
  toolResults += 1;
42
+ addUsage(message.usage);
31
43
  continue;
32
44
  }
33
45
  if (message.role !== "assistant")
@@ -36,12 +48,7 @@ export function aggregateSessionStats(entries, base) {
36
48
  if (Array.isArray(message.content)) {
37
49
  toolCalls += message.content.filter((content) => content.type === "toolCall").length;
38
50
  }
39
- const usage = message.usage;
40
- input += finiteNumber(usage?.input);
41
- output += finiteNumber(usage?.output);
42
- cacheRead += finiteNumber(usage?.cacheRead);
43
- cacheWrite += finiteNumber(usage?.cacheWrite);
44
- cost += finiteNumber(usage?.cost?.total);
51
+ addUsage(message.usage);
45
52
  }
46
53
  return {
47
54
  ...base,
@@ -43,9 +43,9 @@
43
43
  "vscode-languageserver-protocol": "^3.17.5"
44
44
  },
45
45
  "peerDependencies": {
46
- "@earendil-works/pi-ai": "0.80.10",
47
- "@earendil-works/pi-coding-agent": "0.80.10",
48
- "@earendil-works/pi-tui": "0.80.10",
46
+ "@earendil-works/pi-ai": "0.81.0",
47
+ "@earendil-works/pi-coding-agent": "0.81.0",
48
+ "@earendil-works/pi-tui": "0.81.0",
49
49
  "typebox": "*"
50
50
  },
51
51
  "devDependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-ui-extend",
3
- "version": "0.1.67",
3
+ "version": "0.1.69",
4
4
  "description": "Pix: a workspace-first terminal UI for Pi with tabs, readable tool activity, voice input, and bundled agent tools.",
5
5
  "private": false,
6
6
  "repository": {
@@ -75,9 +75,9 @@
75
75
  "prepublishOnly": "npm run check && npm run build:pix && npm run generate-schemas"
76
76
  },
77
77
  "dependencies": {
78
- "@earendil-works/pi-ai": "0.80.10",
79
- "@earendil-works/pi-coding-agent": "0.80.10",
80
- "@earendil-works/pi-tui": "0.80.10",
78
+ "@earendil-works/pi-ai": "0.81.0",
79
+ "@earendil-works/pi-coding-agent": "0.81.0",
80
+ "@earendil-works/pi-tui": "0.81.0",
81
81
  "@mariozechner/clipboard": "^0.3.9",
82
82
  "jsonc-parser": "3.3.1",
83
83
  "typebox": "1.1.38",
@@ -6,31 +6,49 @@ allowed-tools: Bash(playwright-cli:*) Bash(npx:*) Bash(npm:*)
6
6
 
7
7
  # Browser Automation with playwright-cli
8
8
 
9
+ ## Required session lifecycle
10
+
11
+ Browser sessions are daemon-backed and can outlive both a command and its task. Treat each session as an owned resource:
12
+
13
+ 1. Before the first session-scoped command, choose a unique, task-scoped name (semantic prefix plus timestamp/PID or random suffix), confirm it is not already in `playwright-cli list`, and record the exact name in task state as owned by this task. Do not create automation in the shared `default` session.
14
+ 2. Pass that exact name with `-s=<name>` to **every** command. In examples, `$SESSION` is shorthand for the recorded literal; do not assume shell variables persist between tool calls.
15
+ 3. As soon as the session is created, plan cleanup for success, failure, cancellation, and timeout. In a shell script, install an `EXIT INT TERM` trap immediately after registering the name.
16
+ 4. Before the final response—and on every error path—run `playwright-cli -s=<owned-name> close`. Then run `playwright-cli list` and verify that the exact owned name is absent. If it remains, retry the session-specific close and investigate before finishing.
17
+
18
+ Only close sessions registered as owned by the current task. `close-all` and `kill-all` can disrupt other agents or users and are not routine cleanup. Use `kill-all` only as an emergency fallback when session-specific cleanup cannot remove a confirmed stale daemon, after checking `list` and either confirming every listed session is yours or obtaining user approval.
19
+
20
+ For sessions attached to an external browser, use a unique name but `detach` instead of `close`; do not close the external browser. Only attach to a user's regular Chrome/Edge when explicitly requested. For `--debug=cli` sessions, also stop the background test process that owns the browser and verify its generated session is gone.
21
+
9
22
  ## Quick start
10
23
 
11
24
  ```bash
25
+ # Pick once and record as owned; use this exact value for the whole task.
26
+ SESSION="docs-check-$(date +%s)-$$"
12
27
  # open new browser
13
- playwright-cli open
28
+ playwright-cli -s="$SESSION" open
14
29
  # navigate to a page
15
- playwright-cli goto https://playwright.dev
30
+ playwright-cli -s="$SESSION" goto https://playwright.dev
16
31
  # interact with the page using refs from the snapshot
17
- playwright-cli click e15
18
- playwright-cli type "page.click"
19
- playwright-cli press Enter
32
+ playwright-cli -s="$SESSION" click e15
33
+ playwright-cli -s="$SESSION" type "page.click"
34
+ playwright-cli -s="$SESSION" press Enter
20
35
  # take a screenshot (rarely used, as snapshot is more common)
21
- playwright-cli screenshot
22
- # close the browser
23
- playwright-cli close
36
+ playwright-cli -s="$SESSION" screenshot
37
+ # mandatory task cleanup, including error paths
38
+ playwright-cli -s="$SESSION" close
39
+ playwright-cli list # verify the exact value of $SESSION is absent
24
40
  ```
25
41
 
26
42
  ## Commands
27
43
 
44
+ Most of the command catalog omits `-s="$SESSION"` for readability. When executing it, always target the unique session registered under [Required session lifecycle](#required-session-lifecycle); session creation and cleanup show the option explicitly.
45
+
28
46
  ### Core
29
47
 
30
48
  ```bash
31
- playwright-cli open
49
+ playwright-cli -s="$SESSION" open
32
50
  # open and navigate right away
33
- playwright-cli open https://example.com/
51
+ playwright-cli -s="$SESSION" open https://example.com/
34
52
  playwright-cli goto https://playwright.dev
35
53
  playwright-cli type "search query"
36
54
  playwright-cli click e3
@@ -56,7 +74,7 @@ playwright-cli dialog-accept
56
74
  playwright-cli dialog-accept "confirmation text"
57
75
  playwright-cli dialog-dismiss
58
76
  playwright-cli resize 1920 1080
59
- playwright-cli close
77
+ playwright-cli -s="$SESSION" close
60
78
  ```
61
79
 
62
80
  ### Navigation
@@ -200,33 +218,34 @@ playwright-cli list --json
200
218
  ## Open parameters
201
219
  ```bash
202
220
  # Use specific browser when creating session
203
- playwright-cli open --browser=chrome
204
- playwright-cli open --browser=firefox
205
- playwright-cli open --browser=webkit
206
- playwright-cli open --browser=msedge
221
+ playwright-cli -s="$SESSION" open --browser=chrome
222
+ playwright-cli -s="$SESSION" open --browser=firefox
223
+ playwright-cli -s="$SESSION" open --browser=webkit
224
+ playwright-cli -s="$SESSION" open --browser=msedge
207
225
 
208
226
  # Use persistent profile (by default profile is in-memory)
209
- playwright-cli open --persistent
227
+ playwright-cli -s="$SESSION" open --persistent
210
228
  # Use persistent profile with custom directory
211
- playwright-cli open --profile=/path/to/profile
229
+ playwright-cli -s="$SESSION" open --profile=/path/to/profile
212
230
 
213
231
  # Connect to browser via Playwright Extension
214
- playwright-cli attach --extension=chrome
232
+ playwright-cli -s="$SESSION" attach --extension=chrome
215
233
 
216
234
  # Connect to a running Chrome or Edge by channel name
217
- playwright-cli attach --cdp=chrome
218
- playwright-cli attach --cdp=msedge
235
+ playwright-cli -s="$SESSION" attach --cdp=chrome
236
+ playwright-cli -s="$SESSION" attach --cdp=msedge
219
237
 
220
238
  # Connect to a running browser via CDP endpoint
221
- playwright-cli attach --cdp=http://localhost:9222
239
+ playwright-cli -s="$SESSION" attach --cdp=http://localhost:9222
222
240
 
223
241
  # Start with config file
224
- playwright-cli open --config=my-config.json
242
+ playwright-cli -s="$SESSION" open --config=my-config.json
225
243
 
226
- # Close the browser
227
- playwright-cli close
244
+ # Close and verify an owned browser
245
+ playwright-cli -s="$SESSION" close
246
+ playwright-cli list
228
247
  # Detach from an attached browser (leaves the external browser running)
229
- playwright-cli -s=msedge detach
248
+ playwright-cli -s="$SESSION" detach
230
249
  # Delete user data for the default session
231
250
  playwright-cli delete-data
232
251
  ```
@@ -292,21 +311,23 @@ playwright-cli click "getByTestId('submit-button')"
292
311
  ## Browser Sessions
293
312
 
294
313
  ```bash
295
- # create new browser session named "mysession" with persistent profile
296
- playwright-cli -s=mysession open example.com --persistent
297
- # same with manually specified profile directory (use when requested explicitly)
298
- playwright-cli -s=mysession open example.com --profile=/path/to/profile
299
- playwright-cli -s=mysession click e6
300
- playwright-cli -s=mysession close # stop a named browser
301
- playwright-cli -s=mysession delete-data # delete user data for persistent session
314
+ # Choose a unique name once and register it as owned by this task.
315
+ SESSION="profile-check-$(date +%s)-$$"
316
+ # Choose either persistent option, not both.
317
+ # Auto-generated profile location:
318
+ playwright-cli -s="$SESSION" open example.com --persistent
319
+ # Or a manually specified profile directory (only when requested explicitly):
320
+ playwright-cli -s="$SESSION" open example.com --profile=/path/to/profile
321
+ playwright-cli -s="$SESSION" click e6
322
+ playwright-cli -s="$SESSION" delete-data # delete user data if requested
323
+ playwright-cli -s="$SESSION" close # mandatory on success and errors
324
+ playwright-cli list # verify $SESSION is absent
302
325
 
303
326
  playwright-cli list
304
- # Close all browsers
305
- playwright-cli close-all
306
- # Forcefully kill all browser processes
307
- playwright-cli kill-all
308
327
  ```
309
328
 
329
+ The global commands `playwright-cli close-all` and `playwright-cli kill-all` may affect sessions owned by others. Do not use them for this workflow; follow the emergency-only policy above.
330
+
310
331
  ## Installation
311
332
 
312
333
  If global `playwright-cli` command is not available, try a local version via `npx playwright-cli`:
@@ -324,45 +345,53 @@ npm install -g @playwright/cli@latest
324
345
  ## Example: Form submission
325
346
 
326
347
  ```bash
327
- playwright-cli open https://example.com/form
328
- playwright-cli snapshot
329
-
330
- playwright-cli fill e1 "user@example.com"
331
- playwright-cli fill e2 "password123"
332
- playwright-cli click e3
333
- playwright-cli snapshot
334
- playwright-cli close
348
+ SESSION="form-check-$(date +%s)-$$"
349
+ playwright-cli -s="$SESSION" open https://example.com/form
350
+ playwright-cli -s="$SESSION" snapshot
351
+
352
+ playwright-cli -s="$SESSION" fill e1 "user@example.com"
353
+ playwright-cli -s="$SESSION" fill e2 "password123"
354
+ playwright-cli -s="$SESSION" click e3
355
+ playwright-cli -s="$SESSION" snapshot
356
+ playwright-cli -s="$SESSION" close
357
+ playwright-cli list # verify $SESSION is absent
335
358
  ```
336
359
 
337
360
  ## Example: Multi-tab workflow
338
361
 
339
362
  ```bash
340
- playwright-cli open https://example.com
341
- playwright-cli tab-new https://example.com/other
342
- playwright-cli tab-list
343
- playwright-cli tab-select 0
344
- playwright-cli snapshot
345
- playwright-cli close
363
+ SESSION="tabs-check-$(date +%s)-$$"
364
+ playwright-cli -s="$SESSION" open https://example.com
365
+ playwright-cli -s="$SESSION" tab-new https://example.com/other
366
+ playwright-cli -s="$SESSION" tab-list
367
+ playwright-cli -s="$SESSION" tab-select 0
368
+ playwright-cli -s="$SESSION" snapshot
369
+ playwright-cli -s="$SESSION" close
370
+ playwright-cli list # verify $SESSION is absent
346
371
  ```
347
372
 
348
373
  ## Example: Debugging with DevTools
349
374
 
350
375
  ```bash
351
- playwright-cli open https://example.com
352
- playwright-cli click e4
353
- playwright-cli fill e7 "test"
354
- playwright-cli console
355
- playwright-cli requests
356
- playwright-cli close
376
+ SESSION="devtools-check-$(date +%s)-$$"
377
+ playwright-cli -s="$SESSION" open https://example.com
378
+ playwright-cli -s="$SESSION" click e4
379
+ playwright-cli -s="$SESSION" fill e7 "test"
380
+ playwright-cli -s="$SESSION" console
381
+ playwright-cli -s="$SESSION" requests
382
+ playwright-cli -s="$SESSION" close
383
+ playwright-cli list # verify $SESSION is absent
357
384
  ```
358
385
 
359
386
  ```bash
360
- playwright-cli open https://example.com
361
- playwright-cli tracing-start
362
- playwright-cli click e4
363
- playwright-cli fill e7 "test"
364
- playwright-cli tracing-stop
365
- playwright-cli close
387
+ SESSION="trace-check-$(date +%s)-$$"
388
+ playwright-cli -s="$SESSION" open https://example.com
389
+ playwright-cli -s="$SESSION" tracing-start
390
+ playwright-cli -s="$SESSION" click e4
391
+ playwright-cli -s="$SESSION" fill e7 "test"
392
+ playwright-cli -s="$SESSION" tracing-stop
393
+ playwright-cli -s="$SESSION" close
394
+ playwright-cli list # verify $SESSION is absent
366
395
  ```
367
396
 
368
397
  ## Example: Interactive session
@@ -370,8 +399,11 @@ playwright-cli close
370
399
  Ask the user for UI review or design feedback. The user draws boxes on the live page and types comments; you receive the annotated screenshot, the snapshot of the marked region, and the user's notes. Use this whenever the user asks for "UI review", "design feedback", or to "ask the user what they think / want / mean":
371
400
 
372
401
  ```bash
373
- playwright-cli open https://example.com
374
- playwright-cli show --annotate
402
+ SESSION="ui-review-$(date +%s)-$$"
403
+ playwright-cli -s="$SESSION" open https://example.com
404
+ playwright-cli -s="$SESSION" show --annotate
405
+ playwright-cli -s="$SESSION" close
406
+ playwright-cli list # verify $SESSION is absent
375
407
  ```
376
408
 
377
409
  ## Specific tasks
@@ -14,13 +14,14 @@ PLAYWRIGHT_HTML_OPEN=never npm run special-test-command
14
14
 
15
15
  To debug a failing Playwright test, run it with `--debug=cli` option. This command will pause the test at the start and print the debugging instructions.
16
16
 
17
- **IMPORTANT**: run the command in the background and check the output until "Debugging Instructions" is printed. Make sure to stop the command after you have finished.
17
+ **IMPORTANT**: run the command in the background, record its PID as owned by the task, and check the output until "Debugging Instructions" is printed. As soon as the generated `tw-...` name appears, register that exact session as owned by this debug run. Plan cleanup immediately: on success, failure, interruption, or timeout, detach the CLI session, stop and reap the background test PID, then check `playwright-cli list` and verify the generated name is absent.
18
18
 
19
19
  Once instructions containing a session name are printed, use `playwright-cli` to attach the session and explore the page.
20
20
 
21
21
  ```bash
22
- # Run the test
23
- PLAYWRIGHT_HTML_OPEN=never npx playwright test --debug=cli
22
+ # Run the test in the background and retain ownership of its PID.
23
+ PLAYWRIGHT_HTML_OPEN=never npx playwright test --debug=cli > playwright-debug.log 2>&1 &
24
+ TEST_PID=$!
24
25
  # ...
25
26
  # ... debugging instructions for "tw-abcdef" session ...
26
27
  # ...
@@ -36,4 +37,14 @@ where the problem is most likely to be.
36
37
  Every action you perform with `playwright-cli` generates corresponding Playwright TypeScript code.
37
38
  This code appears in the output and can be copied directly into the test. Most of the time, a specific locator or an expectation should be updated, but it could also be a bug in the app. Use your judgement.
38
39
 
39
- After fixing the test, stop the background test run. Rerun to check that test passes.
40
+ After fixing the test, clean up before rerunning or responding:
41
+
42
+ ```bash
43
+ # Detach does not close an external browser. Ignore "not attached" if the test already exited.
44
+ playwright-cli -s=tw-abcdef detach || true
45
+ kill "$TEST_PID" 2>/dev/null || true
46
+ wait "$TEST_PID" 2>/dev/null || true
47
+ playwright-cli list # verify tw-abcdef is absent
48
+ ```
49
+
50
+ Do not use `close-all` or `kill-all`: other debug or automation sessions may belong to another task. Rerun normally to check that the test passes.
@@ -2,20 +2,38 @@
2
2
 
3
3
  Run multiple isolated browser sessions concurrently with state persistence.
4
4
 
5
+ ## Ownership and cleanup contract
6
+
7
+ Browser sessions are backed by daemons and can survive the task that created them. Before the first session-scoped command:
8
+
9
+ 1. Generate a unique task-scoped name (semantic purpose plus timestamp/PID or random suffix).
10
+ 2. Confirm the candidate is absent from `playwright-cli list`, then record the exact name in the task's owned-session list. Do not use `default` for agent automation.
11
+ 3. Use that exact name on every command. `$SESSION` below is shorthand for the recorded literal, not a shell variable that can be assumed to persist between tool calls.
12
+ 4. On success, error, cancellation, or timeout, close each session owned by the task individually, then run `playwright-cli list` and verify every owned name is absent. Retry a session-specific close if needed.
13
+
14
+ Never close a session merely because it looks stale: it may belong to another agent or user. Do not use `close-all` or `kill-all` as normal cleanup.
15
+
5
16
  ## Named Browser Sessions
6
17
 
7
18
  Use `-s` flag to isolate browser contexts:
8
19
 
9
20
  ```bash
21
+ AUTH_SESSION="auth-check-$(date +%s)-$$"
22
+ PUBLIC_SESSION="public-check-$(date +%s)-$$"
10
23
  # Browser 1: Authentication flow
11
- playwright-cli -s=auth open https://app.example.com/login
24
+ playwright-cli -s="$AUTH_SESSION" open https://app.example.com/login
12
25
 
13
26
  # Browser 2: Public browsing (separate cookies, storage)
14
- playwright-cli -s=public open https://example.com
27
+ playwright-cli -s="$PUBLIC_SESSION" open https://example.com
15
28
 
16
29
  # Commands are isolated by browser session
17
- playwright-cli -s=auth fill e1 "user@example.com"
18
- playwright-cli -s=public snapshot
30
+ playwright-cli -s="$AUTH_SESSION" fill e1 "user@example.com"
31
+ playwright-cli -s="$PUBLIC_SESSION" snapshot
32
+
33
+ # Mandatory cleanup, including error paths
34
+ playwright-cli -s="$AUTH_SESSION" close
35
+ playwright-cli -s="$PUBLIC_SESSION" close
36
+ playwright-cli list # verify both exact names are absent
19
37
  ```
20
38
 
21
39
  ## Browser Session Isolation Properties
@@ -34,19 +52,11 @@ Each browser session has independent:
34
52
  # List all browser sessions
35
53
  playwright-cli list
36
54
 
37
- # Stop a browser session (close the browser)
38
- playwright-cli close # stop the default browser
39
- playwright-cli -s=mysession close # stop a named browser
40
-
41
- # Stop all browser sessions
42
- playwright-cli close-all
55
+ # Stop a browser session owned by this task
56
+ playwright-cli -s="$OWNED_SESSION" close
43
57
 
44
- # Forcefully kill all daemon processes (for stale/zombie processes)
45
- playwright-cli kill-all
46
-
47
- # Delete browser session user data (profile directory)
48
- playwright-cli delete-data # delete default browser data
49
- playwright-cli -s=mysession delete-data # delete named browser data
58
+ # Delete user data for a persistent session owned by this task
59
+ playwright-cli -s="$OWNED_SESSION" delete-data
50
60
  ```
51
61
 
52
62
  ## Environment Variable
@@ -54,43 +64,70 @@ playwright-cli -s=mysession delete-data # delete named browser data
54
64
  Set a default browser session name via environment variable:
55
65
 
56
66
  ```bash
57
- export PLAYWRIGHT_CLI_SESSION="mysession"
58
- playwright-cli open example.com # Uses "mysession" automatically
67
+ export PLAYWRIGHT_CLI_SESSION="env-check-$(date +%s)-$$"
68
+ playwright-cli list # first confirm $PLAYWRIGHT_CLI_SESSION is absent
69
+ playwright-cli -s="$PLAYWRIGHT_CLI_SESSION" open example.com
70
+ playwright-cli -s="$PLAYWRIGHT_CLI_SESSION" close
71
+ playwright-cli list # verify $PLAYWRIGHT_CLI_SESSION is absent
72
+ unset PLAYWRIGHT_CLI_SESSION
59
73
  ```
60
74
 
75
+ For agent tasks, prefer an explicit unique `-s=<owned-name>` on every command. Environment variables may not persist across tool calls, and a fixed value such as `mysession` can collide with another task.
76
+
61
77
  ## Common Patterns
62
78
 
63
79
  ### Concurrent Scraping
64
80
 
65
81
  ```bash
66
82
  #!/bin/bash
83
+ set -u
67
84
  # Scrape multiple sites concurrently
68
85
 
86
+ sessions=(
87
+ "site1-$(date +%s)-$$-1"
88
+ "site2-$(date +%s)-$$-2"
89
+ "site3-$(date +%s)-$$-3"
90
+ )
91
+
92
+ cleanup() {
93
+ for session in "${sessions[@]}"; do
94
+ playwright-cli -s="$session" close || true
95
+ done
96
+ # Inspect this output and verify every name above is absent.
97
+ playwright-cli list
98
+ }
99
+ trap cleanup EXIT
100
+ trap 'exit 130' INT
101
+ trap 'exit 143' TERM
102
+
69
103
  # Start all browsers
70
- playwright-cli -s=site1 open https://site1.com &
71
- playwright-cli -s=site2 open https://site2.com &
72
- playwright-cli -s=site3 open https://site3.com &
104
+ playwright-cli -s="${sessions[0]}" open https://site1.com &
105
+ playwright-cli -s="${sessions[1]}" open https://site2.com &
106
+ playwright-cli -s="${sessions[2]}" open https://site3.com &
73
107
  wait
74
108
 
75
109
  # Take snapshots from each
76
- playwright-cli -s=site1 snapshot
77
- playwright-cli -s=site2 snapshot
78
- playwright-cli -s=site3 snapshot
79
-
80
- # Cleanup
81
- playwright-cli close-all
110
+ playwright-cli -s="${sessions[0]}" snapshot
111
+ playwright-cli -s="${sessions[1]}" snapshot
112
+ playwright-cli -s="${sessions[2]}" snapshot
82
113
  ```
83
114
 
84
115
  ### A/B Testing Sessions
85
116
 
86
117
  ```bash
118
+ VARIANT_A="variant-a-$(date +%s)-$$"
119
+ VARIANT_B="variant-b-$(date +%s)-$$"
87
120
  # Test different user experiences
88
- playwright-cli -s=variant-a open "https://app.com?variant=a"
89
- playwright-cli -s=variant-b open "https://app.com?variant=b"
121
+ playwright-cli -s="$VARIANT_A" open "https://app.com?variant=a"
122
+ playwright-cli -s="$VARIANT_B" open "https://app.com?variant=b"
90
123
 
91
124
  # Compare
92
- playwright-cli -s=variant-a screenshot
93
- playwright-cli -s=variant-b screenshot
125
+ playwright-cli -s="$VARIANT_A" screenshot
126
+ playwright-cli -s="$VARIANT_B" screenshot
127
+
128
+ playwright-cli -s="$VARIANT_A" close
129
+ playwright-cli -s="$VARIANT_B" close
130
+ playwright-cli list # verify both exact names are absent
94
131
  ```
95
132
 
96
133
  ### Persistent Profile
@@ -98,11 +135,15 @@ playwright-cli -s=variant-b screenshot
98
135
  By default, browser profile is kept in memory only. Use `--persistent` flag on `open` to persist the browser profile to disk:
99
136
 
100
137
  ```bash
101
- # Use persistent profile (auto-generated location)
102
- playwright-cli open https://example.com --persistent
138
+ SESSION="persistent-check-$(date +%s)-$$"
139
+ # Choose one persistent-profile option. Auto-generated location:
140
+ playwright-cli -s="$SESSION" open https://example.com --persistent
103
141
 
104
- # Use persistent profile with custom directory
105
- playwright-cli open https://example.com --profile=/path/to/profile
142
+ # Or a custom directory:
143
+ playwright-cli -s="$SESSION" open https://example.com --profile=/path/to/profile
144
+
145
+ playwright-cli -s="$SESSION" close
146
+ playwright-cli list # verify $SESSION is absent
106
147
  ```
107
148
 
108
149
  ## Attaching to a Running Browser
@@ -111,32 +152,40 @@ Use `attach` to connect to a browser that is already running, instead of launchi
111
152
 
112
153
  ### Attach by channel name
113
154
 
114
- Connect to a running Chrome or Edge instance by its channel name. The browser must have remote debugging enabled — navigate to `chrome://inspect/#remote-debugging` in the target browser and check "Allow remote debugging for this browser instance".
155
+ Connect to a running Chrome or Edge instance by its channel name only when the user explicitly requests interaction with that external browser. The browser must have remote debugging enabled — navigate to `chrome://inspect/#remote-debugging` in the target browser and check "Allow remote debugging for this browser instance".
115
156
 
116
157
  ```bash
158
+ SESSION="external-debug-$(date +%s)-$$"
117
159
  # Attach to Chrome
118
- playwright-cli attach --cdp=chrome
160
+ playwright-cli -s="$SESSION" attach --cdp=chrome
119
161
 
120
162
  # Attach to Chrome Canary
121
- playwright-cli attach --cdp=chrome-canary
163
+ playwright-cli -s="$SESSION" attach --cdp=chrome-canary
122
164
 
123
165
  # Attach to Microsoft Edge
124
- playwright-cli attach --cdp=msedge
166
+ playwright-cli -s="$SESSION" attach --cdp=msedge
125
167
 
126
168
  # Attach to Edge Dev
127
- playwright-cli attach --cdp=msedge-dev
169
+ playwright-cli -s="$SESSION" attach --cdp=msedge-dev
170
+
171
+ # End the CLI attachment without closing the external browser
172
+ playwright-cli -s="$SESSION" detach
173
+ playwright-cli list # verify $SESSION is absent
128
174
  ```
129
175
 
130
176
  Supported channels: `chrome`, `chrome-beta`, `chrome-dev`, `chrome-canary`, `msedge`, `msedge-beta`, `msedge-dev`, `msedge-canary`.
131
177
 
132
- When `--session` is not provided, the session is named after the channel (e.g. `--cdp=msedge` creates a session called `msedge`), so parallel attaches to Chrome and Edge don't collide on `default`. Pass `--session=<name>` to override.
178
+ When `--session` is not provided, the session is named after the channel (for example, `msedge`). Agent tasks must override this with their unique owned name so they do not collide with another task.
133
179
 
134
180
  ### Attach via CDP endpoint
135
181
 
136
182
  Connect to a browser that exposes a Chrome DevTools Protocol endpoint:
137
183
 
138
184
  ```bash
139
- playwright-cli attach --cdp=http://localhost:9222
185
+ SESSION="cdp-debug-$(date +%s)-$$"
186
+ playwright-cli -s="$SESSION" attach --cdp=http://localhost:9222
187
+ playwright-cli -s="$SESSION" detach
188
+ playwright-cli list # verify $SESSION is absent
140
189
  ```
141
190
 
142
191
  ### Attach via browser extension
@@ -144,7 +193,10 @@ playwright-cli attach --cdp=http://localhost:9222
144
193
  Connect to a browser with the Playwright extension installed:
145
194
 
146
195
  ```bash
147
- playwright-cli attach --extension
196
+ SESSION="extension-debug-$(date +%s)-$$"
197
+ playwright-cli -s="$SESSION" attach --extension
198
+ playwright-cli -s="$SESSION" detach
199
+ playwright-cli list # verify $SESSION is absent
148
200
  ```
149
201
 
150
202
  ### Detach
@@ -152,74 +204,70 @@ playwright-cli attach --extension
152
204
  Tear down an attached session without affecting the external browser:
153
205
 
154
206
  ```bash
155
- # Detach the default attached session
156
- playwright-cli detach
157
-
158
207
  # Detach a specific attached session
159
- playwright-cli -s=msedge detach
208
+ playwright-cli -s="$SESSION" detach
209
+ playwright-cli list # verify the exact owned name is absent
160
210
  ```
161
211
 
162
212
  `detach` only works on sessions created via `attach`. For sessions created via `open`, use `close`.
163
213
 
164
- ## Default Browser Session
214
+ ## Default Browser Session (avoid for agent-created browsers)
165
215
 
166
- When `-s` is omitted, commands use the default browser session:
167
-
168
- ```bash
169
- # These use the same default browser session
170
- playwright-cli open https://example.com
171
- playwright-cli snapshot
172
- playwright-cli close # Stops default browser
173
- ```
216
+ When `-s` is omitted, commands use a shared session named `default`. Do not use this legacy behavior for agent-created browsers: ownership is ambiguous and concurrent tasks can collide.
174
217
 
175
218
  ## Browser Session Configuration
176
219
 
177
220
  Configure a browser session with specific settings when opening:
178
221
 
179
222
  ```bash
180
- # Open with config file
181
- playwright-cli open https://example.com --config=.playwright/my-cli.json
223
+ SESSION="configured-check-$(date +%s)-$$"
224
+ # Choose one of these open configurations.
225
+ # Config file:
226
+ playwright-cli -s="$SESSION" open https://example.com --config=.playwright/my-cli.json
182
227
 
183
228
  # Open with specific browser
184
- playwright-cli open https://example.com --browser=firefox
229
+ playwright-cli -s="$SESSION" open https://example.com --browser=firefox
185
230
 
186
231
  # Open in headed mode
187
- playwright-cli open https://example.com --headed
232
+ playwright-cli -s="$SESSION" open https://example.com --headed
188
233
 
189
234
  # Open with persistent profile
190
- playwright-cli open https://example.com --persistent
235
+ playwright-cli -s="$SESSION" open https://example.com --persistent
236
+
237
+ playwright-cli -s="$SESSION" close
238
+ playwright-cli list # verify $SESSION is absent
191
239
  ```
192
240
 
193
241
  ## Best Practices
194
242
 
195
- ### 1. Name Browser Sessions Semantically
243
+ ### 1. Name Browser Sessions Uniquely and Semantically
196
244
 
197
245
  ```bash
198
- # GOOD: Clear purpose
199
- playwright-cli -s=github-auth open https://github.com
200
- playwright-cli -s=docs-scrape open https://docs.example.com
201
-
202
- # AVOID: Generic names
203
- playwright-cli -s=s1 open https://github.com
246
+ # GOOD: Clear purpose plus a per-task uniqueness suffix.
247
+ SESSION="github-auth-$(date +%s)-$$"
248
+ playwright-cli -s="$SESSION" open https://github.com
249
+ playwright-cli -s="$SESSION" close
250
+ playwright-cli list # verify $SESSION is absent
204
251
  ```
205
252
 
253
+ Avoid shared, generic, or reusable names such as `s1` or `github-auth`, and never omit `-s` for a session the task creates.
254
+
206
255
  ### 2. Always Clean Up
207
256
 
208
257
  ```bash
209
- # Stop browsers when done
210
- playwright-cli -s=auth close
211
- playwright-cli -s=scrape close
258
+ # Stop only browsers registered as owned by this task, including on errors.
259
+ playwright-cli -s="$AUTH_SESSION" close
260
+ playwright-cli -s="$SCRAPE_SESSION" close
261
+ playwright-cli list # verify both exact names are absent
262
+ ```
212
263
 
213
- # Or stop all at once
214
- playwright-cli close-all
264
+ ### 3. Reserve Global Cleanup for Emergencies
215
265
 
216
- # If browsers become unresponsive or zombie processes remain
217
- playwright-cli kill-all
218
- ```
266
+ If session-specific `close` repeatedly fails and a daemon is confirmed stale, inspect `playwright-cli list`. Use `kill-all` only if every listed session belongs to the current task or the user approves disrupting foreign sessions. `close-all` has the same ownership risk and is not a shortcut for tracked cleanup. Never use either command to manage the user's ordinary Chrome/Edge processes.
219
267
 
220
- ### 3. Delete Stale Browser Data
268
+ ### 4. Delete Stale Browser Data
221
269
 
222
270
  ```bash
223
271
  # Remove old browser data to free disk space
224
- playwright-cli -s=oldsession delete-data
272
+ playwright-cli -s="$OWNED_SESSION" delete-data
225
273
  ```
@@ -8,6 +8,8 @@ End-to-end workflow for authoring and maintaining Playwright tests using `playwr
8
8
 
9
9
  All three lean on the same mechanic: run `npx playwright test --debug=cli` in the background, then `playwright-cli attach tw-XXXX` to drive the paused page interactively. See [playwright-tests.md](playwright-tests.md) for the debug/attach mechanics and [test-generation.md](test-generation.md) for how every `playwright-cli` action emits Playwright TypeScript.
10
10
 
11
+ Each debug run owns two resources: the background test PID and the unique generated `tw-XXXX` session. Record both as soon as they exist. On success, failure, interruption, or timeout, detach that exact CLI session, stop and reap that exact PID, and verify the session name is absent from `playwright-cli list` before starting another run or responding. Never substitute `close-all` or `kill-all`, because other sessions may have different owners.
12
+
11
13
  ---
12
14
 
13
15
  ## 1. Planning
@@ -76,7 +78,8 @@ If no seed exists, create one that at least navigates to the app.
76
78
  Launch the app via the seed in the background and attach:
77
79
 
78
80
  ```bash
79
- PLAYWRIGHT_HTML_OPEN=never npx playwright test tests/seed.spec.ts --debug=cli
81
+ PLAYWRIGHT_HTML_OPEN=never npx playwright test tests/seed.spec.ts --debug=cli > playwright-debug.log 2>&1 &
82
+ TEST_PID=$!
80
83
  # wait for "Debugging Instructions" and the session name tw-XXXX
81
84
  playwright-cli attach tw-XXXX
82
85
  ```
@@ -100,7 +103,7 @@ Map out:
100
103
  - Navigation: which controls change the URL, back/forward behaviour.
101
104
 
102
105
  **Important**: Do not just open the app url with playwright-cli, always go through the test to capture any custom setup done there.
103
- **Important**: Stop the background test when done exploring.
106
+ **Important**: When done exploring, run `playwright-cli -s=tw-XXXX detach`, stop and `wait` for `$TEST_PID`, then run `playwright-cli list` and verify `tw-XXXX` is absent.
104
107
 
105
108
  ### 1.4 Write the spec file
106
109
 
@@ -164,7 +167,9 @@ Goal: take a spec file and produce Playwright test files. Optionally update the
164
167
  For each target scenario, in sequence (never in parallel — scenarios share the seed session):
165
168
 
166
169
  ```bash
167
- PLAYWRIGHT_HTML_OPEN=never npx playwright test <seed-file> --debug=cli # background
170
+ PLAYWRIGHT_HTML_OPEN=never npx playwright test <seed-file> --debug=cli > playwright-debug.log 2>&1 &
171
+ TEST_PID=$!
172
+ # Read the log, register the generated session name, then attach.
168
173
  playwright-cli attach tw-XXXX
169
174
  # resume
170
175
  ```
@@ -216,11 +221,11 @@ Rules:
216
221
  - Prefix each numbered step with a `// N. <step text>` comment before its actions.
217
222
  - Use the describe group name verbatim from the spec (no `1.` ordinal).
218
223
  - Import from `./fixtures` if the project has one; otherwise `@playwright/test`.
219
- - **Important**: close the CLI session and stop the background test before moving to the next scenario.
224
+ - **Important**: detach the exact `tw-XXXX` CLI session, stop and reap `$TEST_PID`, and verify the session is absent from `playwright-cli list` before moving to the next scenario.
220
225
 
221
226
  ### 2.3 Generate multiple scenarios
222
227
 
223
- Loop 2.2 over the targeted scenarios one at a time, restarting the seed between each so every test starts from a clean page. This is safe to parallelise due to unique generated session names - just make sure each test run is stopped.
228
+ Loop 2.2 over the targeted scenarios one at a time, restarting the seed between each so every test starts from a clean page. Keep this sequential as required above; unique generated names prevent collisions but do not replace per-run ownership and verified cleanup.
224
229
 
225
230
  ### 2.4 Run generated tests
226
231
 
@@ -251,7 +256,8 @@ Record the list of failing `<file>:<line>` entries and process them one at a tim
251
256
  Run the single failing test in debug mode in the background, then attach:
252
257
 
253
258
  ```bash
254
- PLAYWRIGHT_HTML_OPEN=never npx playwright test tests/<group>/<scenario>.spec.ts:<line> --debug=cli
259
+ PLAYWRIGHT_HTML_OPEN=never npx playwright test tests/<group>/<scenario>.spec.ts:<line> --debug=cli > playwright-debug.log 2>&1 &
260
+ TEST_PID=$!
255
261
  # wait for "Debugging Instructions" and the tw-XXXX session name
256
262
  playwright-cli attach tw-XXXX
257
263
  ```
@@ -271,7 +277,7 @@ Rehearse the corrected interaction with `playwright-cli` — the generated code
271
277
 
272
278
  ### 3.3 Apply the fix
273
279
 
274
- Edit the test file: update the locator, assertion, step order, or inputs to match the corrected behaviour. Stop the background debug run. Rerun the single test to confirm green.
280
+ Edit the test file: update the locator, assertion, step order, or inputs to match the corrected behaviour. Detach the exact generated CLI session, stop and reap the background debug PID, and verify the session name is absent from `playwright-cli list`. Then rerun the single test to confirm green.
275
281
 
276
282
  Never skip hooks or add sleeps as a fix. Never use `networkidle`.
277
283
 
@@ -19,11 +19,14 @@ playwright-cli state-save my-auth-state.json
19
19
  ### Restore Storage State
20
20
 
21
21
  ```bash
22
+ SESSION="state-restore-$(date +%s)-$$" # record as owned before first command
22
23
  # Load storage state from file
23
- playwright-cli state-load my-auth-state.json
24
+ playwright-cli -s="$SESSION" state-load my-auth-state.json
24
25
 
25
26
  # Reload page to apply cookies
26
- playwright-cli open https://example.com
27
+ playwright-cli -s="$SESSION" open https://example.com
28
+ playwright-cli -s="$SESSION" close
29
+ playwright-cli list # verify $SESSION is absent
27
30
  ```
28
31
 
29
32
  ### Storage State File Format
@@ -233,37 +236,49 @@ playwright-cli run-code "async page => {
233
236
 
234
237
  ```bash
235
238
  # Step 1: Login and save state
236
- playwright-cli open https://app.example.com/login
237
- playwright-cli snapshot
238
- playwright-cli fill e1 "user@example.com"
239
- playwright-cli fill e2 "password123"
240
- playwright-cli click e3
239
+ LOGIN_SESSION="auth-save-$(date +%s)-$$"
240
+ playwright-cli -s="$LOGIN_SESSION" open https://app.example.com/login
241
+ playwright-cli -s="$LOGIN_SESSION" snapshot
242
+ playwright-cli -s="$LOGIN_SESSION" fill e1 "user@example.com"
243
+ playwright-cli -s="$LOGIN_SESSION" fill e2 "password123"
244
+ playwright-cli -s="$LOGIN_SESSION" click e3
241
245
 
242
246
  # Save the authenticated state
243
- playwright-cli state-save auth.json
247
+ playwright-cli -s="$LOGIN_SESSION" state-save auth.json
248
+ playwright-cli -s="$LOGIN_SESSION" close
249
+ playwright-cli list # verify $LOGIN_SESSION is absent
244
250
 
245
251
  # Step 2: Later, restore state and skip login
246
- playwright-cli state-load auth.json
247
- playwright-cli open https://app.example.com/dashboard
252
+ RESTORE_SESSION="auth-restore-$(date +%s)-$$"
253
+ playwright-cli -s="$RESTORE_SESSION" state-load auth.json
254
+ playwright-cli -s="$RESTORE_SESSION" open https://app.example.com/dashboard
248
255
  # Already logged in!
256
+ playwright-cli -s="$RESTORE_SESSION" close
257
+ playwright-cli list # verify $RESTORE_SESSION is absent
249
258
  ```
250
259
 
251
260
  ### Save and Restore Roundtrip
252
261
 
253
262
  ```bash
254
263
  # Set up authentication state
255
- playwright-cli open https://example.com
256
- playwright-cli eval "() => { document.cookie = 'session=abc123'; localStorage.setItem('user', 'john'); }"
264
+ SAVE_SESSION="state-save-$(date +%s)-$$"
265
+ playwright-cli -s="$SAVE_SESSION" open https://example.com
266
+ playwright-cli -s="$SAVE_SESSION" eval "() => { document.cookie = 'session=abc123'; localStorage.setItem('user', 'john'); }"
257
267
 
258
268
  # Save state to file
259
- playwright-cli state-save my-session.json
269
+ playwright-cli -s="$SAVE_SESSION" state-save my-session.json
270
+ playwright-cli -s="$SAVE_SESSION" close
271
+ playwright-cli list # verify $SAVE_SESSION is absent
260
272
 
261
273
  # ... later, in a new session ...
262
274
 
263
275
  # Restore state
264
- playwright-cli state-load my-session.json
265
- playwright-cli open https://example.com
276
+ LOAD_SESSION="state-load-$(date +%s)-$$"
277
+ playwright-cli -s="$LOAD_SESSION" state-load my-session.json
278
+ playwright-cli -s="$LOAD_SESSION" open https://example.com
266
279
  # Cookies and localStorage are restored!
280
+ playwright-cli -s="$LOAD_SESSION" close
281
+ playwright-cli list # verify $LOAD_SESSION is absent
267
282
  ```
268
283
 
269
284
  ## Security Notes
@@ -10,25 +10,30 @@ This code appears in the output and can be copied directly into your test files.
10
10
  ## Example Workflow
11
11
 
12
12
  ```bash
13
- # Start a session
14
- playwright-cli open https://example.com/login
13
+ # Choose a unique name, record it as owned by this task, and start the session.
14
+ SESSION="testgen-login-$(date +%s)-$$"
15
+ playwright-cli -s="$SESSION" open https://example.com/login
15
16
 
16
17
  # Take a snapshot to see elements
17
- playwright-cli snapshot
18
+ playwright-cli -s="$SESSION" snapshot
18
19
  # Output shows: e1 [textbox "Email"], e2 [textbox "Password"], e3 [button "Sign In"]
19
20
 
20
21
  # Fill form fields - generates code automatically
21
- playwright-cli fill e1 "user@example.com"
22
+ playwright-cli -s="$SESSION" fill e1 "user@example.com"
22
23
  # Ran Playwright code:
23
24
  # await page.getByRole('textbox', { name: 'Email' }).fill('user@example.com');
24
25
 
25
- playwright-cli fill e2 "password123"
26
+ playwright-cli -s="$SESSION" fill e2 "password123"
26
27
  # Ran Playwright code:
27
28
  # await page.getByRole('textbox', { name: 'Password' }).fill('password123');
28
29
 
29
- playwright-cli click e3
30
+ playwright-cli -s="$SESSION" click e3
30
31
  # Ran Playwright code:
31
32
  # await page.getByRole('button', { name: 'Sign In' }).click();
33
+
34
+ # Mandatory on success and errors.
35
+ playwright-cli -s="$SESSION" close
36
+ playwright-cli list # verify $SESSION is absent
32
37
  ```
33
38
 
34
39
  ## Building a Test File
@@ -69,10 +74,13 @@ await page.locator('#submit-btn').click();
69
74
  Take snapshots to understand the page structure before recording actions:
70
75
 
71
76
  ```bash
72
- playwright-cli open https://example.com
73
- playwright-cli snapshot
77
+ SESSION="testgen-explore-$(date +%s)-$$"
78
+ playwright-cli -s="$SESSION" open https://example.com
79
+ playwright-cli -s="$SESSION" snapshot
74
80
  # Review the element structure
75
- playwright-cli click e5
81
+ playwright-cli -s="$SESSION" click e5
82
+ playwright-cli -s="$SESSION" close
83
+ playwright-cli list # verify $SESSION is absent
76
84
  ```
77
85
 
78
86
  ### 3. Add Assertions Manually
@@ -5,16 +5,19 @@ Capture detailed execution traces for debugging and analysis. Traces include DOM
5
5
  ## Basic Usage
6
6
 
7
7
  ```bash
8
+ SESSION="trace-basic-$(date +%s)-$$" # record as owned before first command
8
9
  # Start trace recording
9
- playwright-cli tracing-start
10
+ playwright-cli -s="$SESSION" tracing-start
10
11
 
11
12
  # Perform actions
12
- playwright-cli open https://example.com
13
- playwright-cli click e1
14
- playwright-cli fill e2 "test"
13
+ playwright-cli -s="$SESSION" open https://example.com
14
+ playwright-cli -s="$SESSION" click e1
15
+ playwright-cli -s="$SESSION" fill e2 "test"
15
16
 
16
17
  # Stop trace recording
17
- playwright-cli tracing-stop
18
+ playwright-cli -s="$SESSION" tracing-stop
19
+ playwright-cli -s="$SESSION" close
20
+ playwright-cli list # verify $SESSION is absent
18
21
  ```
19
22
 
20
23
  ## Trace Output Files
@@ -64,22 +67,28 @@ When you start tracing, Playwright creates a `traces/` directory with several fi
64
67
  ### Debugging Failed Actions
65
68
 
66
69
  ```bash
67
- playwright-cli tracing-start
68
- playwright-cli open https://app.example.com
70
+ SESSION="trace-failure-$(date +%s)-$$"
71
+ playwright-cli -s="$SESSION" tracing-start
72
+ playwright-cli -s="$SESSION" open https://app.example.com
69
73
 
70
74
  # This click fails - why?
71
- playwright-cli click e5
75
+ playwright-cli -s="$SESSION" click e5
72
76
 
73
- playwright-cli tracing-stop
77
+ playwright-cli -s="$SESSION" tracing-stop
78
+ playwright-cli -s="$SESSION" close
79
+ playwright-cli list # verify $SESSION is absent
74
80
  # Open trace to see DOM state when click was attempted
75
81
  ```
76
82
 
77
83
  ### Analyzing Performance
78
84
 
79
85
  ```bash
80
- playwright-cli tracing-start
81
- playwright-cli open https://slow-site.com
82
- playwright-cli tracing-stop
86
+ SESSION="trace-performance-$(date +%s)-$$"
87
+ playwright-cli -s="$SESSION" tracing-start
88
+ playwright-cli -s="$SESSION" open https://slow-site.com
89
+ playwright-cli -s="$SESSION" tracing-stop
90
+ playwright-cli -s="$SESSION" close
91
+ playwright-cli list # verify $SESSION is absent
83
92
 
84
93
  # View network waterfall to identify slow resources
85
94
  ```
@@ -88,15 +97,18 @@ playwright-cli tracing-stop
88
97
 
89
98
  ```bash
90
99
  # Record a complete user flow for documentation
91
- playwright-cli tracing-start
92
-
93
- playwright-cli open https://app.example.com/checkout
94
- playwright-cli fill e1 "4111111111111111"
95
- playwright-cli fill e2 "12/25"
96
- playwright-cli fill e3 "123"
97
- playwright-cli click e4
98
-
99
- playwright-cli tracing-stop
100
+ SESSION="trace-evidence-$(date +%s)-$$"
101
+ playwright-cli -s="$SESSION" tracing-start
102
+
103
+ playwright-cli -s="$SESSION" open https://app.example.com/checkout
104
+ playwright-cli -s="$SESSION" fill e1 "4111111111111111"
105
+ playwright-cli -s="$SESSION" fill e2 "12/25"
106
+ playwright-cli -s="$SESSION" fill e3 "123"
107
+ playwright-cli -s="$SESSION" click e4
108
+
109
+ playwright-cli -s="$SESSION" tracing-stop
110
+ playwright-cli -s="$SESSION" close
111
+ playwright-cli list # verify $SESSION is absent
100
112
  # Trace shows exact sequence of events
101
113
  ```
102
114
 
@@ -117,10 +129,13 @@ playwright-cli tracing-stop
117
129
 
118
130
  ```bash
119
131
  # Trace the entire flow, not just the failing step
120
- playwright-cli tracing-start
121
- playwright-cli open https://example.com
132
+ SESSION="trace-flow-$(date +%s)-$$"
133
+ playwright-cli -s="$SESSION" tracing-start
134
+ playwright-cli -s="$SESSION" open https://example.com
122
135
  # ... all steps leading to the issue ...
123
- playwright-cli tracing-stop
136
+ playwright-cli -s="$SESSION" tracing-stop
137
+ playwright-cli -s="$SESSION" close
138
+ playwright-cli list # verify $SESSION is absent
124
139
  ```
125
140
 
126
141
  ### 2. Clean Up Old Traces
@@ -5,26 +5,30 @@ Capture browser automation sessions as video for debugging, documentation, or ve
5
5
  ## Basic Recording
6
6
 
7
7
  ```bash
8
+ # Choose a unique name and record it as owned before opening.
9
+ SESSION="video-demo-$(date +%s)-$$"
8
10
  # Open browser first
9
- playwright-cli open
11
+ playwright-cli -s="$SESSION" open
10
12
 
11
13
  # Start recording
12
- playwright-cli video-start demo.webm
14
+ playwright-cli -s="$SESSION" video-start demo.webm
13
15
 
14
16
  # Add a chapter marker for section transitions
15
- playwright-cli video-chapter "Getting Started" --description="Opening the homepage" --duration=2000
17
+ playwright-cli -s="$SESSION" video-chapter "Getting Started" --description="Opening the homepage" --duration=2000
16
18
 
17
19
  # Navigate and perform actions
18
- playwright-cli goto https://example.com
19
- playwright-cli snapshot
20
- playwright-cli click e1
20
+ playwright-cli -s="$SESSION" goto https://example.com
21
+ playwright-cli -s="$SESSION" snapshot
22
+ playwright-cli -s="$SESSION" click e1
21
23
 
22
24
  # Add another chapter
23
- playwright-cli video-chapter "Filling Form" --description="Entering test data" --duration=2000
24
- playwright-cli fill e2 "test input"
25
+ playwright-cli -s="$SESSION" video-chapter "Filling Form" --description="Entering test data" --duration=2000
26
+ playwright-cli -s="$SESSION" fill e2 "test input"
25
27
 
26
28
  # Stop and save
27
- playwright-cli video-stop
29
+ playwright-cli -s="$SESSION" video-stop
30
+ playwright-cli -s="$SESSION" close
31
+ playwright-cli list # verify $SESSION is absent
28
32
  ```
29
33
 
30
34
  ## Best Practices
@@ -44,7 +48,7 @@ It allows pulling appropriate pauses between the actions and annotating the vide
44
48
 
45
49
  1) Perform scenario using CLI and take note of all locators and actions. You'll need those locators to request their bounding boxes for highlight.
46
50
  2) Create a file with the intended script for video (below). Use pressSequentially w/ delay for nice typing, make reasonable pauses.
47
- 3) Use playwright-cli run-code --filename your-script.js
51
+ 3) In the task-owned unique session, use `playwright-cli -s="$SESSION" run-code --filename your-script.js`, then close that exact session and verify it is absent from `playwright-cli list`, including on errors.
48
52
 
49
53
  **Important**: Overlays are `pointer-events: none` — they do not interfere with page interactions. You can safely keep sticky overlays visible while clicking, filling, or performing any actions on the page.
50
54