@crouton-kit/capture 1.3.1 → 1.3.3
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.
- package/bin/capture +107 -61
- package/package.json +2 -2
- package/src/capture.ts +106 -62
- package/src/cdp.ts +8 -4
package/bin/capture
CHANGED
|
@@ -4707,7 +4707,8 @@ async function main() {
|
|
|
4707
4707
|
`
|
|
4708
4708
|
Found ${endpoints.length} CDP endpoint${endpoints.length > 1 ? "s" : ""}. Default: port ${preferred.port} (${preferred.app}).
|
|
4709
4709
|
|
|
4710
|
-
Next: capture
|
|
4710
|
+
Next (most tasks): capture session start --url <your app url>
|
|
4711
|
+
(one-off): capture list --port ${preferred.port}`
|
|
4711
4712
|
);
|
|
4712
4713
|
break;
|
|
4713
4714
|
}
|
|
@@ -4785,9 +4786,13 @@ Target a tab with: --target <id prefix> (first 8 chars sufficient)`
|
|
|
4785
4786
|
`
|
|
4786
4787
|
Opened: ${tab.title || url}
|
|
4787
4788
|
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4789
|
+
For a multi-step validation, prefer a session (auto-targets this kind of tab):
|
|
4790
|
+
capture session start --url "${url}"
|
|
4791
|
+
|
|
4792
|
+
Or interact one-off against this tab:
|
|
4793
|
+
capture a11y --port ${p} --target ${tab.id.slice(0, 8)} --interactive
|
|
4794
|
+
capture screenshot --port ${p} --target ${tab.id.slice(0, 8)}
|
|
4795
|
+
capture exec "<js>" --port ${p} --target ${tab.id.slice(0, 8)}`
|
|
4791
4796
|
);
|
|
4792
4797
|
break;
|
|
4793
4798
|
}
|
|
@@ -5802,25 +5807,48 @@ async function sessionMain(args) {
|
|
|
5802
5807
|
default:
|
|
5803
5808
|
console.log(`capture session \u2014 manage capture sessions
|
|
5804
5809
|
|
|
5805
|
-
|
|
5806
|
-
start [--url <url>]
|
|
5807
|
-
stop
|
|
5808
|
-
list
|
|
5809
|
-
view
|
|
5810
|
-
|
|
5810
|
+
Sub-commands:
|
|
5811
|
+
start [--url <url>] Start a session (opens tab, records HAR, sets active context)
|
|
5812
|
+
stop <session-id> Finalize and bundle artifacts (screenshots, HAR, a11y, logs)
|
|
5813
|
+
list List active and stopped sessions
|
|
5814
|
+
view <id> [--filter section] View bundle manifest; section = screenshots|har|a11y|logs
|
|
5815
|
+
|
|
5816
|
+
Why sessions: once started, every subsequent capture command auto-fills
|
|
5817
|
+
--target (the tab) and --har (the recording). No manual flag threading.
|
|
5811
5818
|
|
|
5812
|
-
|
|
5819
|
+
Typical flow:
|
|
5813
5820
|
1. capture session start --url http://localhost:3000
|
|
5814
|
-
2.
|
|
5815
|
-
capture
|
|
5816
|
-
capture
|
|
5817
|
-
capture
|
|
5821
|
+
2. Interact \u2014 no --target / --har needed:
|
|
5822
|
+
capture a11y --interactive
|
|
5823
|
+
capture click "Sign in"
|
|
5824
|
+
capture type "hi@me.com" --into "Email"
|
|
5825
|
+
capture screenshot
|
|
5826
|
+
capture navigate https://app.example.com/dashboard
|
|
5827
|
+
capture har read --filter-url /api
|
|
5818
5828
|
3. capture session stop <session-id>
|
|
5819
|
-
4. capture session view <session-id
|
|
5829
|
+
4. capture session view <session-id>
|
|
5830
|
+
|
|
5831
|
+
Related: capture log <path> [--name label] Tail a log into the active session
|
|
5832
|
+
See also: capture --help Full command list`);
|
|
5820
5833
|
}
|
|
5821
5834
|
}
|
|
5822
5835
|
async function main2() {
|
|
5823
5836
|
const [command, ...args] = process.argv.slice(2);
|
|
5837
|
+
if (command === "--version" || command === "-v" || command === "version") {
|
|
5838
|
+
const declared = "1.3.3";
|
|
5839
|
+
if (declared) {
|
|
5840
|
+
console.log(declared);
|
|
5841
|
+
return;
|
|
5842
|
+
}
|
|
5843
|
+
try {
|
|
5844
|
+
const pkgPath = path4.resolve(__dirname, "..", "package.json");
|
|
5845
|
+
const pkg = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
|
|
5846
|
+
console.log(pkg.version);
|
|
5847
|
+
} catch {
|
|
5848
|
+
console.log("unknown");
|
|
5849
|
+
}
|
|
5850
|
+
return;
|
|
5851
|
+
}
|
|
5824
5852
|
switch (command) {
|
|
5825
5853
|
case "session":
|
|
5826
5854
|
return sessionMain(args);
|
|
@@ -5842,55 +5870,73 @@ async function main2() {
|
|
|
5842
5870
|
case "list":
|
|
5843
5871
|
return main();
|
|
5844
5872
|
default:
|
|
5845
|
-
console.log(`Capture \u2014
|
|
5873
|
+
console.log(`Capture \u2014 browser automation over CDP for validating UI features.
|
|
5846
5874
|
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
session list List active and stopped sessions
|
|
5851
|
-
session view <id> [--filter ...] View bundle manifest
|
|
5852
|
-
log <path> [--name label] Tail a log file into the session
|
|
5875
|
+
Most tasks start with a session. Once a session is active, every command
|
|
5876
|
+
auto-fills --target (the tab) and --har (the recording) \u2014 don't thread
|
|
5877
|
+
those flags yourself.
|
|
5853
5878
|
|
|
5854
|
-
|
|
5855
|
-
detect Detect CDP port
|
|
5856
|
-
exec <code> Execute JS in a browser tab
|
|
5857
|
-
exec --file <path> Execute JS from file
|
|
5858
|
-
list List all browser tabs
|
|
5859
|
-
open <url> Open URL in browser
|
|
5860
|
-
reset-tab <url> Abandon stuck tab, open fresh one
|
|
5861
|
-
screenshot Capture screenshot
|
|
5862
|
-
click "name" Click element by accessible name
|
|
5863
|
-
type "text" Type text into focused element
|
|
5864
|
-
a11y Get accessibility tree
|
|
5865
|
-
record Passive HAR recording
|
|
5866
|
-
navigate <url> Navigate to URL and record HAR
|
|
5867
|
-
network <offline|online> Toggle network (simulate disconnect)
|
|
5868
|
-
har create|read|delete Manage HAR recordings
|
|
5879
|
+
TYPICAL WORKFLOW
|
|
5869
5880
|
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
--target <tabId> Target tab by exact ID (preferred, parallel-safe)
|
|
5873
|
-
--url <pattern> Target tab by URL pattern (fuzzy match)
|
|
5874
|
-
--har <id> Append traffic to a HAR recording
|
|
5875
|
-
--out <path> Output path (screenshot)
|
|
5876
|
-
--json JSON output (a11y)
|
|
5877
|
-
--interactive Interactive elements only (a11y)
|
|
5878
|
-
--role <role> ARIA role filter (click)
|
|
5879
|
-
--into "field" Target field by name (type)
|
|
5880
|
-
--no-screenshot Skip auto-screenshot (click, type)
|
|
5881
|
-
--filter-url <pat> Filter HAR by URL substring/regex (har read)
|
|
5882
|
-
--filter-status <s> Filter HAR by status code, prefix, or range (har read)
|
|
5883
|
-
--filter-method <m> Filter HAR by HTTP method (har read)
|
|
5884
|
-
--limit <N> Limit HAR entries returned (har read)
|
|
5881
|
+
1. Start a session (opens tab, starts HAR, marks it active):
|
|
5882
|
+
capture session start --url http://localhost:3000
|
|
5885
5883
|
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5884
|
+
2. Interact \u2014 no --target / --har needed:
|
|
5885
|
+
capture a11y --interactive See what's on the page
|
|
5886
|
+
capture click "Sign in" Click by accessible name (auto-screenshots)
|
|
5887
|
+
capture type "hi@me.com" --into "Email"
|
|
5888
|
+
capture screenshot Save current state
|
|
5889
|
+
capture navigate https://... Navigate within the session
|
|
5890
|
+
capture exec "document.title" Run JS (supports await)
|
|
5891
|
+
capture har read --filter-url /api Inspect recorded traffic
|
|
5892
|
+
|
|
5893
|
+
3. Bundle and inspect:
|
|
5894
|
+
capture session stop <session-id>
|
|
5895
|
+
capture session view <session-id>
|
|
5896
|
+
|
|
5897
|
+
SESSION COMMANDS
|
|
5898
|
+
|
|
5899
|
+
session start [--url <url>] Start a session
|
|
5900
|
+
session stop <session-id> Finalize and bundle artifacts
|
|
5901
|
+
session list List active and stopped sessions
|
|
5902
|
+
session view <id> [--filter section] section = screenshots|har|a11y|logs
|
|
5903
|
+
log <path> [--name label] Tail a log file into the active session
|
|
5904
|
+
|
|
5905
|
+
INTERACTION COMMANDS (work inside or outside a session)
|
|
5906
|
+
|
|
5907
|
+
a11y [--interactive] [--json] Accessibility tree (use this first to see elements)
|
|
5908
|
+
click "name" [--role <role>] Click by accessible name
|
|
5909
|
+
type "text" [--into "Field"] Type into focused element or named field
|
|
5910
|
+
screenshot [--out <path>] [--full-page] Screenshot (viewport: desktop|desktop-wide|tablet|mobile)
|
|
5911
|
+
exec <code> | exec --file <path> Evaluate JS; await is supported
|
|
5912
|
+
navigate <url> [--settle <ms>] Navigate the current tab + record HAR
|
|
5913
|
+
|
|
5914
|
+
DIAGNOSTICS & ONE-OFFS (no session needed)
|
|
5915
|
+
|
|
5916
|
+
detect Find running CDP endpoints
|
|
5917
|
+
list List open tabs across endpoints
|
|
5918
|
+
open <url> [--new] Open a URL, return its tab id
|
|
5919
|
+
reset-tab <url> Abandon a stuck tab, open fresh (updates session)
|
|
5920
|
+
record [--duration <secs>] Passive HAR recording; parallel-safe capture
|
|
5921
|
+
network <offline|online> Toggle connectivity for a tab
|
|
5922
|
+
har create | read [id] | delete <id> Manage standalone HAR recordings
|
|
5923
|
+
|
|
5924
|
+
TARGETING (only when NOT in a session, or picking a parallel tab)
|
|
5925
|
+
|
|
5926
|
+
--target <tabId> Exact id; a prefix of 8 chars is enough (preferred, parallel-safe)
|
|
5927
|
+
--url <pattern> Fuzzy URL match against open tabs
|
|
5928
|
+
NOTE: on \`session start\`, --url is a URL to OPEN, not a pattern.
|
|
5929
|
+
|
|
5930
|
+
HELP
|
|
5931
|
+
|
|
5932
|
+
capture <command> --help Per-command usage, e.g. capture click --help, capture har --help
|
|
5933
|
+
capture --version Print version
|
|
5934
|
+
|
|
5935
|
+
PREREQ \u2014 a browser with CDP must be running:
|
|
5936
|
+
Arc enabled by default
|
|
5937
|
+
Chrome / Chromium --remote-debugging-port=9222
|
|
5938
|
+
Electron apps CDP exposed automatically
|
|
5939
|
+
Verify with: capture detect`);
|
|
5894
5940
|
}
|
|
5895
5941
|
}
|
|
5896
5942
|
main2().catch((err) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crouton-kit/capture",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "Browser automation and UI validation via CDP — session-based screenshots, HAR, a11y, click/type, and JS exec",
|
|
5
5
|
"bin": {
|
|
6
6
|
"capture": "./bin/capture"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"src"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "esbuild src/capture.ts --bundle --platform=node --format=cjs --outfile=bin/capture '--banner:js=#!/usr/bin/env node' && chmod +x bin/capture"
|
|
13
|
+
"build": "esbuild src/capture.ts --bundle --platform=node --format=cjs --outfile=bin/capture '--banner:js=#!/usr/bin/env node' \"--define:globalThis.__CAPTURE_VERSION__=\\\"$npm_package_version\\\"\" && chmod +x bin/capture"
|
|
14
14
|
},
|
|
15
15
|
"repository": {
|
|
16
16
|
"type": "git",
|
package/src/capture.ts
CHANGED
|
@@ -381,21 +381,29 @@ async function sessionMain(args: string[]): Promise<void> {
|
|
|
381
381
|
default:
|
|
382
382
|
console.log(`capture session — manage capture sessions
|
|
383
383
|
|
|
384
|
-
|
|
385
|
-
start [--url <url>]
|
|
386
|
-
stop
|
|
387
|
-
list
|
|
388
|
-
view
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
384
|
+
Sub-commands:
|
|
385
|
+
start [--url <url>] Start a session (opens tab, records HAR, sets active context)
|
|
386
|
+
stop <session-id> Finalize and bundle artifacts (screenshots, HAR, a11y, logs)
|
|
387
|
+
list List active and stopped sessions
|
|
388
|
+
view <id> [--filter section] View bundle manifest; section = screenshots|har|a11y|logs
|
|
389
|
+
|
|
390
|
+
Why sessions: once started, every subsequent capture command auto-fills
|
|
391
|
+
--target (the tab) and --har (the recording). No manual flag threading.
|
|
392
|
+
|
|
393
|
+
Typical flow:
|
|
392
394
|
1. capture session start --url http://localhost:3000
|
|
393
|
-
2.
|
|
394
|
-
capture
|
|
395
|
-
capture
|
|
396
|
-
capture
|
|
395
|
+
2. Interact — no --target / --har needed:
|
|
396
|
+
capture a11y --interactive
|
|
397
|
+
capture click "Sign in"
|
|
398
|
+
capture type "hi@me.com" --into "Email"
|
|
399
|
+
capture screenshot
|
|
400
|
+
capture navigate https://app.example.com/dashboard
|
|
401
|
+
capture har read --filter-url /api
|
|
397
402
|
3. capture session stop <session-id>
|
|
398
|
-
4. capture session view <session-id
|
|
403
|
+
4. capture session view <session-id>
|
|
404
|
+
|
|
405
|
+
Related: capture log <path> [--name label] Tail a log into the active session
|
|
406
|
+
See also: capture --help Full command list`);
|
|
399
407
|
}
|
|
400
408
|
}
|
|
401
409
|
|
|
@@ -406,6 +414,24 @@ Workflow:
|
|
|
406
414
|
async function main(): Promise<void> {
|
|
407
415
|
const [command, ...args] = process.argv.slice(2);
|
|
408
416
|
|
|
417
|
+
if (command === "--version" || command === "-v" || command === "version") {
|
|
418
|
+
// Version is injected at build time via esbuild's --define flag.
|
|
419
|
+
// Falls back to reading package.json at runtime if not injected.
|
|
420
|
+
const declared = (globalThis as { __CAPTURE_VERSION__?: string }).__CAPTURE_VERSION__;
|
|
421
|
+
if (declared) {
|
|
422
|
+
console.log(declared);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
try {
|
|
426
|
+
const pkgPath = path.resolve(__dirname, "..", "package.json");
|
|
427
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8")) as { version: string };
|
|
428
|
+
console.log(pkg.version);
|
|
429
|
+
} catch {
|
|
430
|
+
console.log("unknown");
|
|
431
|
+
}
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
|
|
409
435
|
switch (command) {
|
|
410
436
|
case "session":
|
|
411
437
|
return sessionMain(args);
|
|
@@ -430,55 +456,73 @@ async function main(): Promise<void> {
|
|
|
430
456
|
return cdpMain();
|
|
431
457
|
|
|
432
458
|
default:
|
|
433
|
-
console.log(`Capture —
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
--
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
--
|
|
468
|
-
--
|
|
469
|
-
--
|
|
470
|
-
--
|
|
471
|
-
|
|
472
|
-
--
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
459
|
+
console.log(`Capture — browser automation over CDP for validating UI features.
|
|
460
|
+
|
|
461
|
+
Most tasks start with a session. Once a session is active, every command
|
|
462
|
+
auto-fills --target (the tab) and --har (the recording) — don't thread
|
|
463
|
+
those flags yourself.
|
|
464
|
+
|
|
465
|
+
TYPICAL WORKFLOW
|
|
466
|
+
|
|
467
|
+
1. Start a session (opens tab, starts HAR, marks it active):
|
|
468
|
+
capture session start --url http://localhost:3000
|
|
469
|
+
|
|
470
|
+
2. Interact — no --target / --har needed:
|
|
471
|
+
capture a11y --interactive See what's on the page
|
|
472
|
+
capture click "Sign in" Click by accessible name (auto-screenshots)
|
|
473
|
+
capture type "hi@me.com" --into "Email"
|
|
474
|
+
capture screenshot Save current state
|
|
475
|
+
capture navigate https://... Navigate within the session
|
|
476
|
+
capture exec "document.title" Run JS (supports await)
|
|
477
|
+
capture har read --filter-url /api Inspect recorded traffic
|
|
478
|
+
|
|
479
|
+
3. Bundle and inspect:
|
|
480
|
+
capture session stop <session-id>
|
|
481
|
+
capture session view <session-id>
|
|
482
|
+
|
|
483
|
+
SESSION COMMANDS
|
|
484
|
+
|
|
485
|
+
session start [--url <url>] Start a session
|
|
486
|
+
session stop <session-id> Finalize and bundle artifacts
|
|
487
|
+
session list List active and stopped sessions
|
|
488
|
+
session view <id> [--filter section] section = screenshots|har|a11y|logs
|
|
489
|
+
log <path> [--name label] Tail a log file into the active session
|
|
490
|
+
|
|
491
|
+
INTERACTION COMMANDS (work inside or outside a session)
|
|
492
|
+
|
|
493
|
+
a11y [--interactive] [--json] Accessibility tree (use this first to see elements)
|
|
494
|
+
click "name" [--role <role>] Click by accessible name
|
|
495
|
+
type "text" [--into "Field"] Type into focused element or named field
|
|
496
|
+
screenshot [--out <path>] [--full-page] Screenshot (viewport: desktop|desktop-wide|tablet|mobile)
|
|
497
|
+
exec <code> | exec --file <path> Evaluate JS; await is supported
|
|
498
|
+
navigate <url> [--settle <ms>] Navigate the current tab + record HAR
|
|
499
|
+
|
|
500
|
+
DIAGNOSTICS & ONE-OFFS (no session needed)
|
|
501
|
+
|
|
502
|
+
detect Find running CDP endpoints
|
|
503
|
+
list List open tabs across endpoints
|
|
504
|
+
open <url> [--new] Open a URL, return its tab id
|
|
505
|
+
reset-tab <url> Abandon a stuck tab, open fresh (updates session)
|
|
506
|
+
record [--duration <secs>] Passive HAR recording; parallel-safe capture
|
|
507
|
+
network <offline|online> Toggle connectivity for a tab
|
|
508
|
+
har create | read [id] | delete <id> Manage standalone HAR recordings
|
|
509
|
+
|
|
510
|
+
TARGETING (only when NOT in a session, or picking a parallel tab)
|
|
511
|
+
|
|
512
|
+
--target <tabId> Exact id; a prefix of 8 chars is enough (preferred, parallel-safe)
|
|
513
|
+
--url <pattern> Fuzzy URL match against open tabs
|
|
514
|
+
NOTE: on \`session start\`, --url is a URL to OPEN, not a pattern.
|
|
515
|
+
|
|
516
|
+
HELP
|
|
517
|
+
|
|
518
|
+
capture <command> --help Per-command usage, e.g. capture click --help, capture har --help
|
|
519
|
+
capture --version Print version
|
|
520
|
+
|
|
521
|
+
PREREQ — a browser with CDP must be running:
|
|
522
|
+
Arc enabled by default
|
|
523
|
+
Chrome / Chromium --remote-debugging-port=9222
|
|
524
|
+
Electron apps CDP exposed automatically
|
|
525
|
+
Verify with: capture detect`);
|
|
482
526
|
}
|
|
483
527
|
}
|
|
484
528
|
|
package/src/cdp.ts
CHANGED
|
@@ -1684,7 +1684,8 @@ async function main() {
|
|
|
1684
1684
|
);
|
|
1685
1685
|
console.error(
|
|
1686
1686
|
`\nFound ${endpoints.length} CDP endpoint${endpoints.length > 1 ? 's' : ''}. Default: port ${preferred.port} (${preferred.app}).` +
|
|
1687
|
-
`\n\nNext: capture
|
|
1687
|
+
`\n\nNext (most tasks): capture session start --url <your app url>` +
|
|
1688
|
+
`\n (one-off): capture list --port ${preferred.port}`,
|
|
1688
1689
|
);
|
|
1689
1690
|
break;
|
|
1690
1691
|
}
|
|
@@ -1767,9 +1768,12 @@ async function main() {
|
|
|
1767
1768
|
}, null, 2));
|
|
1768
1769
|
console.error(
|
|
1769
1770
|
`\nOpened: ${tab.title || url}` +
|
|
1770
|
-
`\n\
|
|
1771
|
-
`\n
|
|
1772
|
-
`\n
|
|
1771
|
+
`\n\nFor a multi-step validation, prefer a session (auto-targets this kind of tab):` +
|
|
1772
|
+
`\n capture session start --url "${url}"` +
|
|
1773
|
+
`\n\nOr interact one-off against this tab:` +
|
|
1774
|
+
`\n capture a11y --port ${p} --target ${tab.id.slice(0, 8)} --interactive` +
|
|
1775
|
+
`\n capture screenshot --port ${p} --target ${tab.id.slice(0, 8)}` +
|
|
1776
|
+
`\n capture exec "<js>" --port ${p} --target ${tab.id.slice(0, 8)}`,
|
|
1773
1777
|
);
|
|
1774
1778
|
break;
|
|
1775
1779
|
}
|