@crouton-kit/capture 1.3.8 → 1.3.9
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 +29841 -8539
- package/package.json +6 -3
- package/src/capture.ts +86 -173
- package/src/cdp/a11y.ts +113 -14
- package/src/cdp/args.ts +300 -205
- package/src/cdp/bridge/protocol.ts +93 -6
- package/src/cdp/bridge/server.ts +118 -53
- package/src/cdp/bridge/spawn.ts +53 -6
- package/src/cdp/client.ts +13 -3
- package/src/cdp/commands/bridge-serve.ts +20 -14
- package/src/cdp/commands/cdp.ts +259 -90
- package/src/cdp/commands/gate-guard.ts +43 -0
- package/src/cdp/commands/lib.ts +339 -213
- package/src/cdp/commands/measure/census.ts +76 -20
- package/src/cdp/commands/measure/check.ts +100 -26
- package/src/cdp/commands/measure/diff.ts +109 -21
- package/src/cdp/commands/measure/explain.ts +121 -19
- package/src/cdp/commands/measure/index.ts +31 -39
- package/src/cdp/commands/measure/map-ax.ts +52 -0
- package/src/cdp/commands/measure/map-focus.ts +41 -13
- package/src/cdp/commands/measure/map-layers.ts +49 -15
- package/src/cdp/commands/measure/map-scroll.ts +85 -15
- package/src/cdp/commands/measure/snap.ts +405 -25
- package/src/cdp/commands/measure/sweep.ts +217 -20
- package/src/cdp/commands/motion/index.ts +18 -17
- package/src/cdp/commands/motion/jank.ts +119 -9
- package/src/cdp/commands/motion/mask.ts +81 -12
- package/src/cdp/commands/motion/rec.ts +520 -19
- package/src/cdp/commands/motion/response.ts +65 -15
- package/src/cdp/commands/motion/timeline.ts +139 -14
- package/src/cdp/commands/page/click.ts +194 -0
- package/src/cdp/commands/page/elements.ts +154 -0
- package/src/cdp/commands/page/exec.ts +317 -0
- package/src/cdp/commands/page/index.ts +72 -0
- package/src/cdp/commands/page/navigate.ts +330 -0
- package/src/cdp/commands/page/scroll.ts +107 -0
- package/src/cdp/commands/page/shot.ts +208 -0
- package/src/cdp/commands/page/type.ts +104 -0
- package/src/cdp/commands/tab/index.ts +59 -0
- package/src/cdp/commands/tab/list.ts +167 -0
- package/src/cdp/commands/tab/network.ts +162 -0
- package/src/cdp/commands/tab/open.ts +90 -0
- package/src/cdp/commands/tab/reset.ts +160 -0
- package/src/cdp/connection.ts +368 -37
- package/src/cdp/detect.ts +42 -13
- package/src/cdp/dispatch.ts +74 -28
- package/src/cdp/har-recorder.ts +648 -115
- package/src/cdp/leaf-grammar.ts +99 -0
- package/src/cdp/measure/census.ts +205 -0
- package/src/cdp/measure/check.ts +318 -0
- package/src/cdp/measure/collectors/animation.ts +385 -0
- package/src/cdp/measure/collectors/ax.ts +278 -0
- package/src/cdp/measure/collectors/focus.ts +1041 -0
- package/src/cdp/measure/collectors/forms.ts +905 -0
- package/src/cdp/measure/collectors/geometry.ts +1038 -0
- package/src/cdp/measure/collectors/hittest.ts +835 -0
- package/src/cdp/measure/collectors/layers.ts +697 -0
- package/src/cdp/measure/collectors/media.ts +522 -0
- package/src/cdp/measure/collectors/pixels.ts +1584 -0
- package/src/cdp/measure/collectors/queries.ts +464 -0
- package/src/cdp/measure/collectors/scroll.ts +599 -0
- package/src/cdp/measure/collectors/states.ts +992 -0
- package/src/cdp/measure/collectors/style-provenance.ts +643 -0
- package/src/cdp/measure/collectors/styles.ts +355 -0
- package/src/cdp/measure/collectors/text.ts +713 -0
- package/src/cdp/measure/diff.ts +470 -0
- package/src/cdp/measure/explain.ts +498 -0
- package/src/cdp/measure/map-ax.ts +633 -0
- package/src/cdp/measure/map-focus.ts +188 -0
- package/src/cdp/measure/map-layers.ts +177 -0
- package/src/cdp/measure/map-scroll.ts +317 -0
- package/src/cdp/measure/redaction.ts +51 -0
- package/src/cdp/measure/settle.ts +1051 -0
- package/src/cdp/measure/snapshot.ts +390 -0
- package/src/cdp/measure/sweep.ts +330 -0
- package/src/cdp/measure/types.ts +220 -0
- package/src/cdp/measure/v2/collectors.ts +19 -0
- package/src/cdp/measure/v2/orchestrator.ts +46 -0
- package/src/cdp/measure/v2/snap-selection.ts +33 -0
- package/src/cdp/measure/v2/target-lock.ts +15 -0
- package/src/cdp/measure/v2/target.ts +16 -0
- package/src/cdp/motion/jank.ts +433 -0
- package/src/cdp/motion/mask.ts +421 -0
- package/src/cdp/motion/recorder.ts +764 -0
- package/src/cdp/motion/response.ts +356 -0
- package/src/cdp/motion/timeline.ts +215 -0
- package/src/cdp/record.ts +5 -212
- package/src/cdp/recorder-bridge.ts +1478 -105
- package/src/cdp/recorder-client.ts +326 -0
- package/src/cdp/scope-lock.ts +73 -0
- package/src/cdp/screenshot.ts +199 -66
- package/src/cdp/targets.ts +21 -1
- package/src/cdp/timing.ts +15 -10
- package/src/cdp/types.ts +22 -7
- package/src/cdp/viewport.ts +21 -0
- package/src/cdp.ts +12 -58
- package/src/command-help.ts +29 -0
- package/src/command-resolution.ts +22 -0
- package/src/command-walker.ts +35 -0
- package/src/contracts/a11y.ts +33 -0
- package/src/contracts/cursor.ts +35 -0
- package/src/contracts/index.ts +15 -0
- package/src/contracts/motion.ts +19 -0
- package/src/contracts/neutral.ts +56 -0
- package/src/contracts/primitives.ts +205 -0
- package/src/contracts/release.ts +17 -0
- package/src/contracts/results.ts +208 -0
- package/src/contracts/routes.ts +140 -0
- package/src/contracts/snapshot.ts +92 -0
- package/src/cursor/index.ts +13 -0
- package/src/cursor/service.ts +310 -0
- package/src/errors.ts +71 -0
- package/src/har-manager.ts +992 -41
- package/src/interact.ts +410 -98
- package/src/output/artifact-lifecycle.ts +371 -0
- package/src/output/artifact.ts +6 -0
- package/src/output/exact-raw.ts +114 -0
- package/src/output/render.ts +396 -2
- package/src/output/structured.ts +211 -0
- package/src/registry.ts +208 -0
- package/src/session/artifacts.ts +452 -200
- package/src/session/commands.ts +1162 -397
- package/src/session/coordinator.ts +251 -0
- package/src/session/har-filter.ts +57 -0
- package/src/session/log-tailer.ts +653 -0
- package/src/session-context.ts +279 -51
- package/src/vault/bundle.ts +32 -17
- package/src/cdp/commands/exec.ts +0 -105
- package/src/cdp/commands/har.ts +0 -128
- package/src/cdp/commands/tabs.ts +0 -183
- package/src/cdp/commands/traffic.ts +0 -121
- package/src/cdp/commands/ui.ts +0 -172
- package/src/cdp/execute.ts +0 -113
- package/src/cdp/har-output.ts +0 -47
- package/src/cdp/usage.ts +0 -79
- package/src/tab-session.ts +0 -91
package/src/cdp/execute.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { CDPClient } from './client.js';
|
|
2
|
-
import { findTabByIdAcrossEndpoints } from './targets.js';
|
|
3
|
-
import { buildExecExpression } from './exec-expression.js';
|
|
4
|
-
import { ConsoleRecorder, type ConsoleEntry } from './console-recorder.js';
|
|
5
|
-
import { HARRecorder } from './har-recorder.js';
|
|
6
|
-
import { printConsoleSummary } from './console-recorder.js';
|
|
7
|
-
import { writeHarAndPrintSummary } from './har-output.js';
|
|
8
|
-
import { type HAREntry } from '../har-manager.js';
|
|
9
|
-
|
|
10
|
-
export interface ExecuteOptions {
|
|
11
|
-
port?: number;
|
|
12
|
-
targetId?: string;
|
|
13
|
-
record?: boolean;
|
|
14
|
-
harOutPath?: string;
|
|
15
|
-
timeoutMs?: number;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface ExecuteResult {
|
|
19
|
-
success: boolean;
|
|
20
|
-
value?: unknown;
|
|
21
|
-
error?: string;
|
|
22
|
-
har?: { log: { entries: HAREntry[] } };
|
|
23
|
-
console: ConsoleEntry[];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export async function executeInBrowser(
|
|
27
|
-
code: string,
|
|
28
|
-
options: ExecuteOptions = {},
|
|
29
|
-
): Promise<ExecuteResult> {
|
|
30
|
-
if (!options.targetId) {
|
|
31
|
-
throw new Error('Use --target <tabId> to target a tab. Run "capture list" to see available tabs.');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const resolved = await findTabByIdAcrossEndpoints(options.targetId, options.port);
|
|
35
|
-
const tab = resolved?.tab ?? null;
|
|
36
|
-
if (!tab) {
|
|
37
|
-
throw new Error(
|
|
38
|
-
`No tab found for target "${options.targetId}". Run "capture list" to see available tabs.`,
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (!tab.webSocketDebuggerUrl) {
|
|
43
|
-
throw new Error('Tab has no WebSocket debugger URL');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const client = new CDPClient(tab.webSocketDebuggerUrl);
|
|
47
|
-
await client.waitReady();
|
|
48
|
-
|
|
49
|
-
// Emulate focus so network requests aren't deferred by the browser,
|
|
50
|
-
// without actually bringing the tab to the foreground
|
|
51
|
-
await client.send('Emulation.setFocusEmulationEnabled', { enabled: true });
|
|
52
|
-
|
|
53
|
-
const consoleRecorder = new ConsoleRecorder(client);
|
|
54
|
-
await consoleRecorder.start();
|
|
55
|
-
|
|
56
|
-
let harRecorder: HARRecorder | undefined;
|
|
57
|
-
if (options.record) {
|
|
58
|
-
harRecorder = new HARRecorder(client);
|
|
59
|
-
await harRecorder.start();
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
// Execute code
|
|
64
|
-
const result = (await client.send(
|
|
65
|
-
'Runtime.evaluate',
|
|
66
|
-
{
|
|
67
|
-
expression: buildExecExpression(code),
|
|
68
|
-
awaitPromise: true,
|
|
69
|
-
returnByValue: true,
|
|
70
|
-
},
|
|
71
|
-
options.timeoutMs,
|
|
72
|
-
)) as {
|
|
73
|
-
result?: { value?: unknown };
|
|
74
|
-
exceptionDetails?: { exception?: { description?: string } };
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// Build HAR if recording
|
|
78
|
-
let har: { log: { entries: HAREntry[] } } | undefined;
|
|
79
|
-
if (harRecorder) {
|
|
80
|
-
har = await harRecorder.finish();
|
|
81
|
-
writeHarAndPrintSummary(har, options.harOutPath);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const consoleEntries = consoleRecorder.finish();
|
|
85
|
-
printConsoleSummary(consoleEntries);
|
|
86
|
-
client.close();
|
|
87
|
-
|
|
88
|
-
if (result.exceptionDetails) {
|
|
89
|
-
return {
|
|
90
|
-
success: false,
|
|
91
|
-
error:
|
|
92
|
-
result.exceptionDetails.exception?.description ?? 'Unknown error',
|
|
93
|
-
har,
|
|
94
|
-
console: consoleEntries,
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return {
|
|
99
|
-
success: true,
|
|
100
|
-
value: result.result?.value,
|
|
101
|
-
har,
|
|
102
|
-
console: consoleEntries,
|
|
103
|
-
};
|
|
104
|
-
} catch (err) {
|
|
105
|
-
const consoleEntries = consoleRecorder.finish();
|
|
106
|
-
client.close();
|
|
107
|
-
return {
|
|
108
|
-
success: false,
|
|
109
|
-
error: err instanceof Error ? err.message : String(err),
|
|
110
|
-
console: consoleEntries,
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
}
|
package/src/cdp/har-output.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import { type HAREntry } from '../har-manager.js';
|
|
3
|
-
|
|
4
|
-
export function writeHarAndPrintSummary(
|
|
5
|
-
har: { log: { entries: HAREntry[] } },
|
|
6
|
-
harOutPath?: string,
|
|
7
|
-
): string | undefined {
|
|
8
|
-
if (har.log.entries.length === 0 && !harOutPath) return undefined;
|
|
9
|
-
|
|
10
|
-
const harPath = harOutPath ?? `/tmp/capture-har-${Date.now()}.json`;
|
|
11
|
-
try {
|
|
12
|
-
fs.writeFileSync(harPath, JSON.stringify(har, null, 2));
|
|
13
|
-
} catch (err) {
|
|
14
|
-
// Fallback: strip response bodies and retry
|
|
15
|
-
const stripped = {
|
|
16
|
-
log: {
|
|
17
|
-
...har.log,
|
|
18
|
-
entries: har.log.entries.map((e) => ({
|
|
19
|
-
...e,
|
|
20
|
-
response: { ...e.response, content: { text: '[body stripped — too large to serialize]' } },
|
|
21
|
-
})),
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
fs.writeFileSync(harPath, JSON.stringify(stripped, null, 2));
|
|
25
|
-
console.error(' WARNING: Response bodies stripped from HAR (too large to serialize)');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Print summary to stderr
|
|
29
|
-
const errors = har.log.entries.filter((e) => e.response.status >= 400);
|
|
30
|
-
console.error(
|
|
31
|
-
`\nHAR: ${har.log.entries.length} requests captured → ${harPath}`,
|
|
32
|
-
);
|
|
33
|
-
if (errors.length > 0) {
|
|
34
|
-
console.error(` ${errors.length} failed:`);
|
|
35
|
-
for (const entry of errors) {
|
|
36
|
-
const method = entry.request.method.padEnd(6);
|
|
37
|
-
const status = entry.response.status;
|
|
38
|
-
const url =
|
|
39
|
-
entry.request.url.length > 100
|
|
40
|
-
? entry.request.url.slice(0, 97) + '...'
|
|
41
|
-
: entry.request.url;
|
|
42
|
-
console.error(` ${method} ${status} ${url}`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return harPath;
|
|
47
|
-
}
|
package/src/cdp/usage.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
export const CDP_USAGE = `CDP — browser automation via exec, a11y interactions, and screenshots.
|
|
2
|
-
|
|
3
|
-
Commands:
|
|
4
|
-
exec <code> Execute JavaScript in a browser tab (expressions, return, await)
|
|
5
|
-
exec --file <path> Execute JS from file
|
|
6
|
-
detect Detect CDP port (prioritizes default browser)
|
|
7
|
-
list List all browser tabs
|
|
8
|
-
open <url> Open URL in browser (returns tab ID)
|
|
9
|
-
reset-tab <url> Abandon stuck tab, open fresh one (updates session)
|
|
10
|
-
screenshot Capture screenshot
|
|
11
|
-
click "name" Click element by accessible name
|
|
12
|
-
type "text" Type text into focused element
|
|
13
|
-
a11y Get accessibility tree
|
|
14
|
-
record Passive HAR recording
|
|
15
|
-
navigate <url> Navigate to URL and record HAR
|
|
16
|
-
network <offline|online> Toggle network (simulate disconnect)
|
|
17
|
-
har create Create a HAR recording (returns id)
|
|
18
|
-
har read [id] Read accumulated HAR entries (id optional in active session)
|
|
19
|
-
har delete <id> Delete a HAR recording
|
|
20
|
-
lib list List available vault libs (dev checkout only)
|
|
21
|
-
lib search "<q>" Fuzzy-search lib functions [--limit N]
|
|
22
|
-
lib show <name> Lib + function summaries
|
|
23
|
-
lib read <name> [fn…] Full input/output schemas (+ .ts source path)
|
|
24
|
-
cdp <Domain.method> Send a raw CDP command capture doesn't wrap [--browser] [--params json] [--wait-event name]
|
|
25
|
-
measure <leaf> Enriched snapshot substrate + read-only queries — see \`capture measure --help\`
|
|
26
|
-
motion <leaf> Recorder lifecycle + read-only queries over a recording — see \`capture motion --help\`
|
|
27
|
-
|
|
28
|
-
Options:
|
|
29
|
-
--port <port> Override CDP port
|
|
30
|
-
--target <tabId> Target tab by exact ID (preferred, parallel-safe)
|
|
31
|
-
CDP_PORT / CDP_TARGET Default port + tab when set by orchestrators
|
|
32
|
-
--new Force new tab (open)
|
|
33
|
-
--record Enable HAR recording (exec)
|
|
34
|
-
--har <id> Append traffic to a HAR recording
|
|
35
|
-
--har-out <path> HAR output path
|
|
36
|
-
--file <path> Read JS from file (exec)
|
|
37
|
-
--duration <secs> Recording duration (record, default: 10)
|
|
38
|
-
--settle <ms> Settle time override (navigate, click, type)
|
|
39
|
-
--filter-url <pat> Filter HAR entries by URL substring/regex (har read)
|
|
40
|
-
--filter-status <s> Filter HAR by status: code, prefix (4), or range (400-499)
|
|
41
|
-
--filter-method <m> Filter HAR by HTTP method (har read)
|
|
42
|
-
--limit <N> Return only first N matching HAR entries (har read)
|
|
43
|
-
--browser Target the browser-level connection (cdp)
|
|
44
|
-
--params '<json>' JSON params for the method (cdp)
|
|
45
|
-
--wait-event <name> Wait for a CDP event and return it (cdp)
|
|
46
|
-
--timeout <ms> Wait timeout, default 10000 (cdp)
|
|
47
|
-
--out <path> Output path (screenshot)
|
|
48
|
-
--viewport <preset> Viewport preset: desktop-wide|desktop|tablet|mobile (default: desktop)
|
|
49
|
-
--height <px> Override viewport height (screenshot)
|
|
50
|
-
--full-page Capture entire scrollable page (screenshot)
|
|
51
|
-
--json JSON output (a11y)
|
|
52
|
-
--interactive Interactive elements only (a11y)
|
|
53
|
-
--role <role> ARIA role filter (click)
|
|
54
|
-
--into "field" Target field by name (type)
|
|
55
|
-
--no-screenshot Skip auto-screenshot (click, type)
|
|
56
|
-
|
|
57
|
-
Console output (errors, warnings) is always captured and printed to stderr.
|
|
58
|
-
|
|
59
|
-
Examples:
|
|
60
|
-
capture detect
|
|
61
|
-
capture list
|
|
62
|
-
capture open "https://app.example.com" --new
|
|
63
|
-
capture exec "document.title" --target <id>
|
|
64
|
-
capture exec "return document.title" --target <id>
|
|
65
|
-
capture exec "const r = await fetch('/api/data'); return await r.json()" --target <id> --record
|
|
66
|
-
capture exec --file /tmp/scrape.js --target <id>
|
|
67
|
-
capture screenshot --target <id> --out /tmp/shot.png
|
|
68
|
-
capture a11y --target <id> --interactive
|
|
69
|
-
capture record --target <id> --duration 15
|
|
70
|
-
capture navigate "https://app.example.com/dashboard"
|
|
71
|
-
capture har create
|
|
72
|
-
capture exec "document.querySelector('form').submit()" --target <id> --har <id>
|
|
73
|
-
capture har read <id>
|
|
74
|
-
capture lib search "search emails"
|
|
75
|
-
capture lib read gmail searchEmails
|
|
76
|
-
capture exec "import {searchEmails} from 'libs/gmail'; const ctx = await getContext(); return await searchEmails({ ...ctx, query: 'invoice' })"
|
|
77
|
-
capture cdp Browser.grantPermissions --browser --params '{"origin":"http://localhost:3000","permissions":["notifications"]}'
|
|
78
|
-
capture cdp --help Raw CDP escape hatch (Browser.*, ServiceWorker.*, ...) + how session --hold keeps grants alive
|
|
79
|
-
`;
|
package/src/tab-session.ts
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TabSession — universal tab lifecycle abstraction for parallel-safe CDP usage.
|
|
3
|
-
*
|
|
4
|
-
* Manages: tab creation, HAR recording, environment injection, and cleanup.
|
|
5
|
-
* Callers create a TabSession, pass its env() to downstream scripts, and close() when done.
|
|
6
|
-
*
|
|
7
|
-
* Usage:
|
|
8
|
-
* const session = await TabSession.create({ url: 'https://app.hubspot.com' });
|
|
9
|
-
* console.log(session.env()); // { CDP_TARGET: '...', CDP_HAR_ID: '...' }
|
|
10
|
-
* await session.validate(); // throws if tab is gone
|
|
11
|
-
* await session.close(); // closes tab + deletes HAR
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
navigateAndWait,
|
|
16
|
-
findTabById,
|
|
17
|
-
detectCdpPort,
|
|
18
|
-
CDPClient,
|
|
19
|
-
} from './cdp.js';
|
|
20
|
-
import { createHarRecording, deleteHarRecording } from './har-manager.js';
|
|
21
|
-
|
|
22
|
-
export interface TabSessionOptions {
|
|
23
|
-
url: string;
|
|
24
|
-
forceNew?: boolean; // Default true (parallel-safe)
|
|
25
|
-
createHar?: boolean; // Default true
|
|
26
|
-
cdpPort?: number; // Auto-detect if not provided
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface TabSessionEnv {
|
|
30
|
-
CDP_TARGET: string;
|
|
31
|
-
CDP_HAR_ID?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export class TabSession {
|
|
35
|
-
readonly tabTarget: string;
|
|
36
|
-
readonly harId: string | null;
|
|
37
|
-
readonly cdpPort: number;
|
|
38
|
-
private closed = false;
|
|
39
|
-
|
|
40
|
-
private constructor(
|
|
41
|
-
tabTarget: string,
|
|
42
|
-
harId: string | null,
|
|
43
|
-
cdpPort: number,
|
|
44
|
-
) {
|
|
45
|
-
this.tabTarget = tabTarget;
|
|
46
|
-
this.harId = harId;
|
|
47
|
-
this.cdpPort = cdpPort;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
static async create(options: TabSessionOptions): Promise<TabSession> {
|
|
51
|
-
const port = options.cdpPort ?? (await detectCdpPort());
|
|
52
|
-
const tab = await navigateAndWait(port, options.url, {
|
|
53
|
-
forceNew: options.forceNew ?? true,
|
|
54
|
-
});
|
|
55
|
-
let harId: string | null = null;
|
|
56
|
-
if (options.createHar !== false) {
|
|
57
|
-
harId = createHarRecording().id;
|
|
58
|
-
}
|
|
59
|
-
return new TabSession(tab.id, harId, port);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async validate(): Promise<void> {
|
|
63
|
-
const tab = await findTabById(this.cdpPort, this.tabTarget);
|
|
64
|
-
if (!tab) throw new Error(`Tab ${this.tabTarget} no longer exists`);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
env(): TabSessionEnv {
|
|
68
|
-
const result: TabSessionEnv = { CDP_TARGET: this.tabTarget };
|
|
69
|
-
if (this.harId) result.CDP_HAR_ID = this.harId;
|
|
70
|
-
return result;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async close(): Promise<void> {
|
|
74
|
-
if (this.closed) return;
|
|
75
|
-
this.closed = true;
|
|
76
|
-
try {
|
|
77
|
-
const tab = await findTabById(this.cdpPort, this.tabTarget);
|
|
78
|
-
if (tab?.webSocketDebuggerUrl) {
|
|
79
|
-
const client = new CDPClient(tab.webSocketDebuggerUrl);
|
|
80
|
-
await client.waitReady();
|
|
81
|
-
await client.send('Runtime.evaluate', {
|
|
82
|
-
expression: 'window.close()',
|
|
83
|
-
});
|
|
84
|
-
client.close();
|
|
85
|
-
}
|
|
86
|
-
} catch {
|
|
87
|
-
/* best-effort */
|
|
88
|
-
}
|
|
89
|
-
if (this.harId) deleteHarRecording(this.harId);
|
|
90
|
-
}
|
|
91
|
-
}
|