@toolstackhq/cdpwright 1.0.0 → 1.2.0
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/README.md +34 -9
- package/dist/assert/expect.d.ts +1 -1
- package/dist/assert/expect.js +1 -1
- package/dist/{chunk-6BPF3IEU.js → chunk-PDUS6BDZ.js} +64 -3
- package/dist/chunk-PDUS6BDZ.js.map +1 -0
- package/dist/cli.js +856 -19
- package/dist/cli.js.map +1 -1
- package/dist/{expect-CY70zJc0.d.ts → expect-CLal_AQd.d.ts} +18 -0
- package/dist/index.d.ts +25 -4
- package/dist/index.js +73 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6BPF3IEU.js.map +0 -1
|
@@ -181,6 +181,21 @@ type ScreenshotOptions = {
|
|
|
181
181
|
path?: string;
|
|
182
182
|
format?: "png" | "jpeg";
|
|
183
183
|
quality?: number;
|
|
184
|
+
fullPage?: boolean;
|
|
185
|
+
};
|
|
186
|
+
type PdfOptions = {
|
|
187
|
+
path?: string;
|
|
188
|
+
landscape?: boolean;
|
|
189
|
+
printBackground?: boolean;
|
|
190
|
+
scale?: number;
|
|
191
|
+
paperWidth?: number;
|
|
192
|
+
paperHeight?: number;
|
|
193
|
+
marginTop?: number;
|
|
194
|
+
marginBottom?: number;
|
|
195
|
+
marginLeft?: number;
|
|
196
|
+
marginRight?: number;
|
|
197
|
+
pageRanges?: string;
|
|
198
|
+
preferCSSPageSize?: boolean;
|
|
184
199
|
};
|
|
185
200
|
declare class Page {
|
|
186
201
|
private session;
|
|
@@ -227,10 +242,13 @@ declare class Page {
|
|
|
227
242
|
setFileInput(selector: string, name: string, contents: string, options?: {
|
|
228
243
|
mimeType?: string;
|
|
229
244
|
}): Promise<void>;
|
|
245
|
+
content(): Promise<string>;
|
|
230
246
|
screenshot(options?: ScreenshotOptions): Promise<Buffer<ArrayBuffer>>;
|
|
231
247
|
screenshotBase64(options?: Omit<ScreenshotOptions, "path">): Promise<string>;
|
|
248
|
+
pdf(options?: PdfOptions): Promise<Buffer>;
|
|
232
249
|
getEvents(): AutomationEvents;
|
|
233
250
|
getDefaultTimeout(): number;
|
|
251
|
+
waitForLoad(timeoutMs?: number): Promise<void>;
|
|
234
252
|
private buildFrameTree;
|
|
235
253
|
private ensureFrame;
|
|
236
254
|
private onFrameAttached;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as Connection, L as Logger, A as AutomationEvents, P as Page, a as LogLevel } from './expect-
|
|
2
|
-
export { F as Frame, b as Locator, e as expect } from './expect-
|
|
1
|
+
import { C as Connection, L as Logger, A as AutomationEvents, P as Page, a as LogLevel } from './expect-CLal_AQd.js';
|
|
2
|
+
export { F as Frame, b as Locator, e as expect } from './expect-CLal_AQd.js';
|
|
3
3
|
import { ChildProcess } from 'child_process';
|
|
4
4
|
|
|
5
5
|
declare class BrowserContext {
|
|
@@ -17,12 +17,24 @@ declare class Browser {
|
|
|
17
17
|
private events;
|
|
18
18
|
private cleanupTasks;
|
|
19
19
|
private contexts;
|
|
20
|
-
|
|
20
|
+
readonly wsEndpoint: string;
|
|
21
|
+
readonly pid: number;
|
|
22
|
+
constructor(connection: Connection, child: ChildProcess | null, logger: Logger, events: AutomationEvents, cleanupTasks?: Array<() => void>, wsEndpoint?: string);
|
|
21
23
|
on(event: "action:start" | "action:end" | "assertion:start" | "assertion:end", handler: (payload: any) => void): void;
|
|
22
24
|
newContext(): Promise<BrowserContext>;
|
|
23
25
|
newPage(options?: {
|
|
24
26
|
browserContextId?: string;
|
|
25
27
|
}): Promise<Page>;
|
|
28
|
+
/** Attach to an existing page by target ID. */
|
|
29
|
+
attachPage(targetId: string): Promise<Page>;
|
|
30
|
+
/** List open page targets. */
|
|
31
|
+
pages(): Promise<Array<{
|
|
32
|
+
targetId: string;
|
|
33
|
+
url: string;
|
|
34
|
+
title: string;
|
|
35
|
+
}>>;
|
|
36
|
+
/** Disconnect without killing the browser process. */
|
|
37
|
+
disconnect(): Promise<void>;
|
|
26
38
|
disposeContext(contextId: string): Promise<void>;
|
|
27
39
|
close(): Promise<void>;
|
|
28
40
|
}
|
|
@@ -54,11 +66,20 @@ declare class AssertionError extends Error {
|
|
|
54
66
|
type AutomatonLaunchOptions = LaunchOptions & {
|
|
55
67
|
logger?: Logger;
|
|
56
68
|
};
|
|
69
|
+
type ConnectOptions = {
|
|
70
|
+
logLevel?: LogLevel;
|
|
71
|
+
logger?: Logger;
|
|
72
|
+
logEvents?: boolean;
|
|
73
|
+
logActions?: boolean;
|
|
74
|
+
logAssertions?: boolean;
|
|
75
|
+
};
|
|
57
76
|
declare const automaton: {
|
|
58
77
|
launch(options?: AutomatonLaunchOptions): Promise<Browser>;
|
|
78
|
+
connect(wsEndpoint: string, options?: ConnectOptions): Promise<Browser>;
|
|
59
79
|
};
|
|
60
80
|
declare const chromium: {
|
|
61
81
|
launch(options?: AutomatonLaunchOptions): Promise<Browser>;
|
|
82
|
+
connect(wsEndpoint: string, options?: ConnectOptions): Promise<Browser>;
|
|
62
83
|
};
|
|
63
84
|
|
|
64
|
-
export { AssertionError, AutomationEvents, type AutomatonLaunchOptions, Browser, BrowserContext, LogLevel, Logger, Page, automaton, chromium };
|
|
85
|
+
export { AssertionError, AutomationEvents, type AutomatonLaunchOptions, Browser, BrowserContext, type ConnectOptions, LogLevel, Logger, Page, automaton, chromium };
|
package/dist/index.js
CHANGED
|
@@ -4,13 +4,13 @@ import {
|
|
|
4
4
|
Locator,
|
|
5
5
|
Page,
|
|
6
6
|
expect
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PDUS6BDZ.js";
|
|
8
8
|
|
|
9
9
|
// src/browser/ChromiumManager.ts
|
|
10
10
|
import fs2 from "fs";
|
|
11
11
|
import path2 from "path";
|
|
12
12
|
import os2 from "os";
|
|
13
|
-
import
|
|
13
|
+
import http2 from "http";
|
|
14
14
|
import { spawn as spawn2 } from "child_process";
|
|
15
15
|
|
|
16
16
|
// src/logging/Logger.ts
|
|
@@ -292,12 +292,16 @@ var Browser = class {
|
|
|
292
292
|
events;
|
|
293
293
|
cleanupTasks;
|
|
294
294
|
contexts = /* @__PURE__ */ new Set();
|
|
295
|
-
|
|
295
|
+
wsEndpoint;
|
|
296
|
+
pid;
|
|
297
|
+
constructor(connection, child, logger, events, cleanupTasks = [], wsEndpoint = "") {
|
|
296
298
|
this.connection = connection;
|
|
297
299
|
this.process = child;
|
|
298
300
|
this.logger = logger;
|
|
299
301
|
this.events = events;
|
|
300
302
|
this.cleanupTasks = cleanupTasks;
|
|
303
|
+
this.wsEndpoint = wsEndpoint;
|
|
304
|
+
this.pid = child?.pid ?? 0;
|
|
301
305
|
}
|
|
302
306
|
on(event, handler) {
|
|
303
307
|
this.events.on(event, handler);
|
|
@@ -319,6 +323,23 @@ var Browser = class {
|
|
|
319
323
|
await page.initialize();
|
|
320
324
|
return page;
|
|
321
325
|
}
|
|
326
|
+
/** Attach to an existing page by target ID. */
|
|
327
|
+
async attachPage(targetId) {
|
|
328
|
+
const { sessionId } = await this.connection.send("Target.attachToTarget", { targetId, flatten: true });
|
|
329
|
+
const session = this.connection.createSession(sessionId);
|
|
330
|
+
const page = new Page(session, this.logger, this.events);
|
|
331
|
+
await page.initialize();
|
|
332
|
+
return page;
|
|
333
|
+
}
|
|
334
|
+
/** List open page targets. */
|
|
335
|
+
async pages() {
|
|
336
|
+
const result = await this.connection.send("Target.getTargets");
|
|
337
|
+
return result.targetInfos.filter((t) => t.type === "page").map((t) => ({ targetId: t.targetId, url: t.url, title: t.title }));
|
|
338
|
+
}
|
|
339
|
+
/** Disconnect without killing the browser process. */
|
|
340
|
+
async disconnect() {
|
|
341
|
+
await this.connection.close();
|
|
342
|
+
}
|
|
322
343
|
async disposeContext(contextId) {
|
|
323
344
|
if (!contextId) return;
|
|
324
345
|
try {
|
|
@@ -338,7 +359,7 @@ var Browser = class {
|
|
|
338
359
|
} catch {
|
|
339
360
|
}
|
|
340
361
|
await this.connection.close();
|
|
341
|
-
if (!this.process.killed) {
|
|
362
|
+
if (this.process && !this.process.killed) {
|
|
342
363
|
this.process.kill();
|
|
343
364
|
}
|
|
344
365
|
for (const task of this.cleanupTasks) {
|
|
@@ -354,6 +375,7 @@ var Browser = class {
|
|
|
354
375
|
import fs from "fs";
|
|
355
376
|
import path from "path";
|
|
356
377
|
import os from "os";
|
|
378
|
+
import http from "http";
|
|
357
379
|
import https from "https";
|
|
358
380
|
import { spawn } from "child_process";
|
|
359
381
|
import yauzl from "yauzl";
|
|
@@ -391,11 +413,22 @@ function chromiumExecutableRelativePath(platform) {
|
|
|
391
413
|
if (platform === "mac") return path.join("chrome-mac", "Chromium.app", "Contents", "MacOS", "Chromium");
|
|
392
414
|
return path.join("chrome-win", "chrome.exe");
|
|
393
415
|
}
|
|
416
|
+
function httpGet(url) {
|
|
417
|
+
return url.startsWith("http://") ? http : https;
|
|
418
|
+
}
|
|
419
|
+
function resolveSnapshotBase() {
|
|
420
|
+
const mirror = process.env.CDPWRIGHT_DOWNLOAD_MIRROR;
|
|
421
|
+
if (mirror && mirror.trim()) {
|
|
422
|
+
return mirror.trim().replace(/\/+$/, "");
|
|
423
|
+
}
|
|
424
|
+
return SNAPSHOT_BASE;
|
|
425
|
+
}
|
|
394
426
|
async function fetchLatestRevision(platform) {
|
|
427
|
+
const base = resolveSnapshotBase();
|
|
395
428
|
const folder = platformFolder(platform);
|
|
396
|
-
const url = `${
|
|
429
|
+
const url = `${base}/${folder}/LAST_CHANGE`;
|
|
397
430
|
return new Promise((resolve, reject) => {
|
|
398
|
-
|
|
431
|
+
httpGet(url).get(url, (res) => {
|
|
399
432
|
if (res.statusCode && res.statusCode >= 400) {
|
|
400
433
|
reject(new Error(`Failed to fetch LAST_CHANGE: ${res.statusCode}`));
|
|
401
434
|
return;
|
|
@@ -420,7 +453,9 @@ async function ensureDownloaded(options) {
|
|
|
420
453
|
fs.mkdirSync(revisionDir, { recursive: true });
|
|
421
454
|
const folder = platformFolder(platform);
|
|
422
455
|
const zipName = platform === "win" ? "chrome-win.zip" : platform === "mac" ? "chrome-mac.zip" : "chrome-linux.zip";
|
|
423
|
-
const
|
|
456
|
+
const explicitUrl = process.env.CDPWRIGHT_DOWNLOAD_URL?.trim();
|
|
457
|
+
const base = resolveSnapshotBase();
|
|
458
|
+
const downloadUrl = explicitUrl || `${base}/${folder}/${revision}/${zipName}`;
|
|
424
459
|
const tempZipPath = path.join(os.tmpdir(), `cdpwright-${platform}-${revision}.zip`);
|
|
425
460
|
logger.info("Downloading Chromium snapshot", downloadUrl);
|
|
426
461
|
await downloadFile(downloadUrl, tempZipPath, logger);
|
|
@@ -437,7 +472,7 @@ async function ensureDownloaded(options) {
|
|
|
437
472
|
function downloadFile(url, dest, logger) {
|
|
438
473
|
return new Promise((resolve, reject) => {
|
|
439
474
|
const file = fs.createWriteStream(dest);
|
|
440
|
-
|
|
475
|
+
httpGet(url).get(url, (res) => {
|
|
441
476
|
if (res.statusCode && res.statusCode >= 400) {
|
|
442
477
|
reject(new Error(`Failed to download: ${res.statusCode}`));
|
|
443
478
|
return;
|
|
@@ -666,6 +701,7 @@ var ChromiumManager = class {
|
|
|
666
701
|
}
|
|
667
702
|
if (options.maximize) {
|
|
668
703
|
args.push("--start-maximized");
|
|
704
|
+
args.push("--window-size=1920,1080");
|
|
669
705
|
}
|
|
670
706
|
if (options.args) {
|
|
671
707
|
args.push(...options.args);
|
|
@@ -694,7 +730,7 @@ var ChromiumManager = class {
|
|
|
694
730
|
logger.info(`Assertion ${payload.name}`, ...args2);
|
|
695
731
|
});
|
|
696
732
|
}
|
|
697
|
-
const browser = new Browser(connection, child, logger, events, cleanupTasks);
|
|
733
|
+
const browser = new Browser(connection, child, logger, events, cleanupTasks, wsEndpoint);
|
|
698
734
|
return browser;
|
|
699
735
|
}
|
|
700
736
|
resolveCacheRoot(platform) {
|
|
@@ -831,7 +867,7 @@ function toHttpVersionUrl(wsUrl) {
|
|
|
831
867
|
}
|
|
832
868
|
function fetchWebSocketDebuggerUrl(versionUrl) {
|
|
833
869
|
return new Promise((resolve, reject) => {
|
|
834
|
-
|
|
870
|
+
http2.get(versionUrl, (res) => {
|
|
835
871
|
if (res.statusCode && res.statusCode >= 400) {
|
|
836
872
|
reject(new Error(`Failed to fetch /json/version: ${res.statusCode}`));
|
|
837
873
|
return;
|
|
@@ -859,6 +895,33 @@ var automaton = {
|
|
|
859
895
|
async launch(options = {}) {
|
|
860
896
|
const manager = new ChromiumManager(options.logger);
|
|
861
897
|
return manager.launch(options);
|
|
898
|
+
},
|
|
899
|
+
async connect(wsEndpoint, options = {}) {
|
|
900
|
+
const logger = options.logger ?? new Logger(options.logLevel ?? "warn");
|
|
901
|
+
const connection = new Connection(wsEndpoint, logger);
|
|
902
|
+
await connection.waitForOpen();
|
|
903
|
+
const events = new AutomationEvents();
|
|
904
|
+
const logEvents = options.logEvents ?? true;
|
|
905
|
+
const logActions = options.logActions ?? true;
|
|
906
|
+
const logAssertions = options.logAssertions ?? true;
|
|
907
|
+
if (logEvents && logActions) {
|
|
908
|
+
events.on("action:end", (payload) => {
|
|
909
|
+
const selector = payload.sensitive ? void 0 : payload.selector;
|
|
910
|
+
const args = [];
|
|
911
|
+
if (selector) args.push(selector);
|
|
912
|
+
if (typeof payload.durationMs === "number") args.push(`${payload.durationMs}ms`);
|
|
913
|
+
logger.info(`Action ${payload.name}`, ...args);
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
if (logEvents && logAssertions) {
|
|
917
|
+
events.on("assertion:end", (payload) => {
|
|
918
|
+
const args = [];
|
|
919
|
+
if (payload.selector) args.push(payload.selector);
|
|
920
|
+
if (typeof payload.durationMs === "number") args.push(`${payload.durationMs}ms`);
|
|
921
|
+
logger.info(`Assertion ${payload.name}`, ...args);
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
return new Browser(connection, null, logger, events, [], wsEndpoint);
|
|
862
925
|
}
|
|
863
926
|
};
|
|
864
927
|
var chromium = automaton;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/browser/ChromiumManager.ts","../src/logging/Logger.ts","../src/core/Events.ts","../src/cdp/Connection.ts","../src/cdp/Session.ts","../src/core/Browser.ts","../src/browser/Downloader.ts","../src/browser/Revision.ts","../src/index.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport http from \"http\";\nimport { spawn } from \"child_process\";\nimport { Logger, LogLevel } from \"../logging/Logger.js\";\nimport { AutomationEvents } from \"../core/Events.js\";\nimport { Connection } from \"../cdp/Connection.js\";\nimport { Browser } from \"../core/Browser.js\";\nimport { detectPlatform, defaultCacheRoot, ensureDownloaded, fetchLatestRevision, Platform, chromiumVersion } from \"./Downloader.js\";\nimport { resolveRevision } from \"./Revision.js\";\n\nexport type LaunchOptions = {\n headless?: boolean;\n args?: string[];\n timeoutMs?: number;\n logLevel?: LogLevel;\n logEvents?: boolean;\n logActions?: boolean;\n logAssertions?: boolean;\n executablePath?: string;\n userDataDir?: string;\n maximize?: boolean;\n};\n\nexport type DownloadOptions = {\n latest?: boolean;\n};\n\nexport type ResolvedDownload = {\n cacheRoot: string;\n platform: Platform;\n revision: string;\n executablePath: string;\n revisionDir: string;\n chromiumVersion?: string;\n};\n\nexport class ChromiumManager {\n private logger: Logger;\n\n constructor(logger?: Logger) {\n const envLevel = (process.env.CDPWRIGHT_LOG_LEVEL as LogLevel | undefined) ?? \"info\";\n this.logger = logger ?? new Logger(envLevel);\n }\n\n getLogger() {\n return this.logger;\n }\n\n async download(options: DownloadOptions = {}): Promise<ResolvedDownload> {\n const platform = detectPlatform();\n const cacheRoot = this.resolveCacheRoot(platform);\n const overrideExecutable = process.env.CDPWRIGHT_EXECUTABLE_PATH;\n let revision = options.latest ? await fetchLatestRevision(platform) : resolveRevision(process.env.CDPWRIGHT_REVISION);\n let executablePath: string;\n let revisionDir = \"\";\n if (overrideExecutable) {\n executablePath = path.resolve(overrideExecutable);\n } else {\n const downloaded = await ensureDownloaded({\n cacheRoot,\n platform,\n revision,\n logger: this.logger\n });\n executablePath = downloaded.executablePath;\n revisionDir = downloaded.revisionDir;\n }\n\n if (!fs.existsSync(executablePath)) {\n throw new Error(`Chromium executable not found: ${executablePath}`);\n }\n\n const version = await chromiumVersion(executablePath);\n\n this.logger.info(\"Chromium cache root\", cacheRoot);\n this.logger.info(\"Platform\", platform);\n this.logger.info(\"Revision\", revision);\n this.logger.info(\"Chromium version\", version);\n\n return {\n cacheRoot,\n platform,\n revision,\n executablePath,\n revisionDir,\n chromiumVersion: version\n };\n }\n\n async launch(options: LaunchOptions = {}) {\n const logger = this.logger;\n if (options.logLevel) {\n logger.setLevel(options.logLevel);\n }\n\n const executablePath = options.executablePath || process.env.CDPWRIGHT_EXECUTABLE_PATH;\n let resolvedExecutable = executablePath;\n if (!resolvedExecutable) {\n const platform = detectPlatform();\n const cacheRoot = this.resolveCacheRoot(platform);\n const revision = resolveRevision(process.env.CDPWRIGHT_REVISION);\n const downloaded = await ensureDownloaded({\n cacheRoot,\n platform,\n revision,\n logger\n });\n resolvedExecutable = downloaded.executablePath;\n }\n\n if (!resolvedExecutable || !fs.existsSync(resolvedExecutable)) {\n throw new Error(`Chromium executable not found: ${resolvedExecutable}`);\n }\n const stats = fs.statSync(resolvedExecutable);\n if (!stats.isFile()) {\n throw new Error(`Chromium executable is not a file: ${resolvedExecutable}`);\n }\n ensureExecutable(resolvedExecutable);\n\n const cleanupTasks: Array<() => void> = [];\n let userDataDir = options.userDataDir ?? process.env.CDPWRIGHT_USER_DATA_DIR;\n if (!userDataDir) {\n userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), \"cdpwright-\"));\n cleanupTasks.push(() => fs.rmSync(userDataDir as string, { recursive: true, force: true }));\n }\n\n const args = [\n \"--remote-debugging-port=0\",\n \"--no-first-run\",\n \"--no-default-browser-check\",\n \"--disable-background-networking\",\n \"--disable-background-timer-throttling\",\n \"--disable-backgrounding-occluded-windows\",\n \"--disable-renderer-backgrounding\"\n ];\n if (userDataDir) {\n args.push(`--user-data-dir=${userDataDir}`);\n }\n if (process.platform === \"linux\") {\n args.push(\"--disable-crash-reporter\", \"--disable-crashpad\");\n }\n if (options.headless ?? true) {\n args.push(\"--headless=new\");\n }\n if (options.maximize) {\n args.push(\"--start-maximized\");\n }\n if (options.args) {\n args.push(...options.args);\n }\n\n logger.info(\"Launching Chromium\", resolvedExecutable);\n const child = spawn(resolvedExecutable, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\n const websocketUrl = await waitForWebSocketEndpoint(child, logger, options.timeoutMs ?? 30_000);\n const httpUrl = toHttpVersionUrl(websocketUrl);\n const wsEndpoint = await fetchWebSocketDebuggerUrl(httpUrl);\n\n const connection = new Connection(wsEndpoint, logger);\n await closeInitialPages(connection, logger);\n const events = new AutomationEvents();\n const logEvents = resolveLogFlag(options.logEvents, process.env.CDPWRIGHT_LOG, true);\n const logActions = resolveLogFlag(options.logActions, process.env.CDPWRIGHT_LOG_ACTIONS, true);\n const logAssertions = resolveLogFlag(options.logAssertions, process.env.CDPWRIGHT_LOG_ASSERTIONS, true);\n if (logEvents && logActions) {\n events.on(\"action:end\", (payload) => {\n const selector = payload.sensitive ? undefined : payload.selector;\n const args = buildLogArgs(selector, payload.durationMs);\n logger.info(`Action ${payload.name}`, ...args);\n });\n }\n if (logEvents && logAssertions) {\n events.on(\"assertion:end\", (payload) => {\n const args = buildLogArgs(payload.selector, payload.durationMs);\n logger.info(`Assertion ${payload.name}`, ...args);\n });\n }\n const browser = new Browser(connection, child, logger, events, cleanupTasks);\n\n return browser;\n }\n\n private resolveCacheRoot(platform: Platform) {\n const envRoot = process.env.CDPWRIGHT_CACHE_DIR;\n if (envRoot && envRoot.trim()) {\n return path.resolve(envRoot.trim());\n }\n return defaultCacheRoot(platform);\n }\n}\n\nasync function closeInitialPages(connection: Connection, logger: Logger) {\n try {\n const targets = await connection.send<{ targetInfos: Array<{ targetId: string; type: string }> }>(\"Target.getTargets\");\n for (const info of targets.targetInfos) {\n if (info.type === \"page\") {\n await connection.send(\"Target.closeTarget\", { targetId: info.targetId });\n }\n }\n } catch (err) {\n logger.warn(\"Failed to close initial pages\", err);\n }\n}\n\nfunction resolveLogFlag(explicit: boolean | undefined, envValue: string | undefined, defaultValue: boolean) {\n if (explicit !== undefined) {\n return explicit;\n }\n if (envValue == null) {\n return defaultValue;\n }\n const normalized = envValue.trim().toLowerCase();\n return ![\"0\", \"false\", \"no\", \"off\"].includes(normalized);\n}\n\nfunction buildLogArgs(selector?: string, durationMs?: number) {\n const args: string[] = [];\n if (selector) {\n args.push(selector);\n }\n if (typeof durationMs === \"number\") {\n args.push(`${durationMs}ms`);\n }\n return args;\n}\n\nfunction ensureExecutable(executablePath: string) {\n if (process.platform === \"win32\") {\n return;\n }\n try {\n const stat = fs.statSync(executablePath);\n const isExecutable = (stat.mode & 0o111) !== 0;\n if (!isExecutable) {\n fs.chmodSync(executablePath, 0o755);\n }\n } catch {\n // ignore chmod errors\n }\n\n const dir = path.dirname(executablePath);\n const helpers = [\n \"chrome_crashpad_handler\",\n \"chrome_sandbox\",\n \"chrome-wrapper\",\n \"xdg-mime\",\n \"xdg-settings\"\n ];\n for (const name of helpers) {\n const helperPath = path.join(dir, name);\n if (!fs.existsSync(helperPath)) {\n continue;\n }\n try {\n const stat = fs.statSync(helperPath);\n const isExecutable = (stat.mode & 0o111) !== 0;\n if (!isExecutable) {\n fs.chmodSync(helperPath, 0o755);\n }\n } catch {\n // ignore chmod errors\n }\n }\n}\n\nfunction waitForWebSocketEndpoint(child: ReturnType<typeof spawn>, logger: Logger, timeoutMs: number): Promise<string> {\n return new Promise((resolve, reject) => {\n const start = Date.now();\n const timeout = setTimeout(() => {\n reject(new Error(\"Timed out waiting for DevTools endpoint\"));\n }, timeoutMs);\n\n const outputLines: string[] = [];\n const pushOutput = (data: Buffer) => {\n const text = data.toString();\n for (const line of text.split(/\\r?\\n/)) {\n if (!line.trim()) continue;\n outputLines.push(line);\n if (outputLines.length > 50) {\n outputLines.shift();\n }\n }\n };\n\n const onData = (data: Buffer) => {\n const text = data.toString();\n const match = text.match(/DevTools listening on (ws:\\/\\/[^\\s]+)/);\n if (match) {\n clearTimeout(timeout);\n cleanup();\n logger.info(\"DevTools endpoint\", match[1]);\n resolve(match[1]);\n }\n pushOutput(data);\n };\n\n const onExit = (code: number | null, signal: NodeJS.Signals | null) => {\n cleanup();\n const tail = outputLines.length ? `\\nChromium output:\\n${outputLines.join(\"\\n\")}` : \"\";\n reject(new Error(`Chromium exited early with code ${code ?? \"null\"} signal ${signal ?? \"null\"}${tail}`));\n };\n\n const cleanup = () => {\n child.stdout?.off(\"data\", onData);\n child.stderr?.off(\"data\", onData);\n child.off(\"exit\", onExit);\n };\n\n child.stdout?.on(\"data\", onData);\n child.stderr?.on(\"data\", onData);\n child.on(\"exit\", onExit);\n\n if (Date.now() - start > timeoutMs) {\n cleanup();\n }\n });\n}\n\nfunction toHttpVersionUrl(wsUrl: string) {\n try {\n const url = new URL(wsUrl);\n const port = url.port || \"9222\";\n return `http://127.0.0.1:${port}/json/version`;\n } catch {\n throw new Error(`Invalid DevTools endpoint: ${wsUrl}`);\n }\n}\n\nfunction fetchWebSocketDebuggerUrl(versionUrl: string): Promise<string> {\n return new Promise((resolve, reject) => {\n http.get(versionUrl, (res) => {\n if (res.statusCode && res.statusCode >= 400) {\n reject(new Error(`Failed to fetch /json/version: ${res.statusCode}`));\n return;\n }\n let data = \"\";\n res.on(\"data\", (chunk) => (data += chunk.toString()));\n res.on(\"end\", () => {\n try {\n const parsed = JSON.parse(data);\n if (!parsed.webSocketDebuggerUrl) {\n reject(new Error(\"webSocketDebuggerUrl missing\"));\n return;\n }\n resolve(parsed.webSocketDebuggerUrl);\n } catch (err) {\n reject(err);\n }\n });\n }).on(\"error\", reject);\n });\n}\n","export type LogLevel = \"error\" | \"warn\" | \"info\" | \"debug\" | \"trace\";\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4\n};\n\nconst REDACT_KEYS = [\"password\", \"token\", \"secret\", \"authorization\", \"cookie\"];\n\nfunction redactValue(value: unknown): string {\n if (typeof value === \"string\") {\n try {\n const url = new URL(value);\n if (url.search) {\n url.search = \"?redacted\";\n }\n return url.toString();\n } catch {\n return value;\n }\n }\n if (value && typeof value === \"object\") {\n return JSON.stringify(value, (key, val) => {\n if (REDACT_KEYS.some((k) => key.toLowerCase().includes(k))) {\n return \"[redacted]\";\n }\n return val;\n });\n }\n return String(value);\n}\n\nexport class Logger {\n private level: LogLevel;\n\n constructor(level: LogLevel = \"info\") {\n this.level = level;\n }\n\n setLevel(level: LogLevel) {\n this.level = level;\n }\n\n error(message: string, ...args: unknown[]) {\n this.log(\"error\", message, ...args);\n }\n\n warn(message: string, ...args: unknown[]) {\n this.log(\"warn\", message, ...args);\n }\n\n info(message: string, ...args: unknown[]) {\n this.log(\"info\", message, ...args);\n }\n\n debug(message: string, ...args: unknown[]) {\n this.log(\"debug\", message, ...args);\n }\n\n trace(message: string, ...args: unknown[]) {\n this.log(\"trace\", message, ...args);\n }\n\n log(level: LogLevel, message: string, ...args: unknown[]) {\n if (LEVEL_ORDER[level] > LEVEL_ORDER[this.level]) {\n return;\n }\n const time = new Date().toISOString();\n const suffix = args.length ? \" \" + args.map(redactValue).join(\" \") : \"\";\n const line = `[${time}] [${level}] ${message}${suffix}`;\n if (level === \"error\") {\n console.error(line);\n } else if (level === \"warn\") {\n console.warn(line);\n } else {\n console.log(line);\n }\n }\n}\n","import { EventEmitter } from \"events\";\n\nexport type ActionEvent = {\n name: string;\n selector?: string;\n frameId?: string;\n durationMs?: number;\n sensitive?: boolean;\n status?: \"passed\" | \"failed\";\n};\n\nexport type AssertionEvent = {\n name: string;\n selector?: string;\n frameId?: string;\n durationMs?: number;\n status?: \"passed\" | \"failed\";\n};\n\nexport type AutomationEventMap = {\n \"action:start\": ActionEvent;\n \"action:end\": ActionEvent;\n \"assertion:start\": AssertionEvent;\n \"assertion:end\": AssertionEvent;\n};\n\nexport class AutomationEvents {\n private emitter = new EventEmitter();\n\n on<K extends keyof AutomationEventMap>(event: K, handler: (payload: AutomationEventMap[K]) => void) {\n this.emitter.on(event, handler);\n }\n\n off<K extends keyof AutomationEventMap>(event: K, handler: (payload: AutomationEventMap[K]) => void) {\n this.emitter.off(event, handler);\n }\n\n emit<K extends keyof AutomationEventMap>(event: K, payload: AutomationEventMap[K]) {\n this.emitter.emit(event, payload);\n }\n}\n","import WebSocket from \"ws\";\nimport { EventEmitter } from \"events\";\nimport { Logger } from \"../logging/Logger.js\";\nimport { Session } from \"./Session.js\";\n\nexport type CDPResponse = {\n id: number;\n result?: unknown;\n error?: { message: string; data?: unknown };\n sessionId?: string;\n};\n\nexport type CDPEvent = {\n method: string;\n params?: unknown;\n sessionId?: string;\n};\n\nexport class Connection {\n private ws: WebSocket;\n private id = 0;\n private callbacks = new Map<number, { resolve: (value: unknown) => void; reject: (reason?: unknown) => void; method: string; start: number }>();\n private sessions = new Map<string, Session>();\n private emitter = new EventEmitter();\n private logger: Logger;\n private closed = false;\n\n constructor(url: string, logger: Logger) {\n this.logger = logger;\n this.ws = new WebSocket(url);\n this.ws.on(\"message\", (data: WebSocket.RawData) => this.onMessage(data.toString()));\n this.ws.on(\"error\", (err: Error) => this.onError(err));\n this.ws.on(\"close\", (code: number, reason: Buffer) => this.onClose(code, reason));\n }\n\n async waitForOpen() {\n if (this.ws.readyState === WebSocket.OPEN) {\n return;\n }\n if (this.ws.readyState === WebSocket.CLOSED) {\n throw new Error(\"CDP socket is closed\");\n }\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup();\n resolve();\n };\n const onError = (err: Error) => {\n cleanup();\n reject(err);\n };\n const onClose = () => {\n cleanup();\n reject(new Error(\"CDP socket closed before opening\"));\n };\n const cleanup = () => {\n this.ws.off(\"open\", onOpen);\n this.ws.off(\"error\", onError);\n this.ws.off(\"close\", onClose);\n };\n this.ws.on(\"open\", onOpen);\n this.ws.on(\"error\", onError);\n this.ws.on(\"close\", onClose);\n });\n }\n\n createSession(sessionId: string): Session {\n const session = new Session(this, sessionId);\n this.sessions.set(sessionId, session);\n return session;\n }\n\n removeSession(sessionId: string) {\n this.sessions.delete(sessionId);\n }\n\n on(event: string, handler: (params: unknown) => void) {\n this.emitter.on(event, handler);\n }\n\n async send<T = unknown>(method: string, params: Record<string, unknown> = {}, sessionId?: string): Promise<T> {\n await this.waitForOpen();\n const id = ++this.id;\n const payload = sessionId ? { id, method, params, sessionId } : { id, method, params };\n const start = Date.now();\n const promise = new Promise<T>((resolve, reject) => {\n this.callbacks.set(id, { resolve: resolve as (value: unknown) => void, reject, method, start });\n });\n if (this.logger) {\n this.logger.trace(\"CDP send\", method);\n }\n this.ws.send(JSON.stringify(payload));\n return promise;\n }\n\n async close() {\n if (this.ws.readyState === WebSocket.CLOSED) {\n return;\n }\n await new Promise<void>((resolve) => {\n this.ws.once(\"close\", () => resolve());\n if (this.ws.readyState === WebSocket.CLOSING) {\n return;\n }\n this.ws.close();\n });\n }\n\n private onError(err: unknown) {\n this.logger.error(\"CDP socket error\", err);\n }\n\n private onClose(code: number, reason: Buffer) {\n if (this.closed) {\n return;\n }\n this.closed = true;\n const reasonText = reason.toString() || \"no reason\";\n this.failPending(new Error(`CDP socket closed (${code}): ${reasonText}`));\n this.sessions.clear();\n }\n\n private failPending(error: Error) {\n if (this.callbacks.size === 0) {\n return;\n }\n for (const [, callback] of this.callbacks) {\n callback.reject(error);\n }\n this.callbacks.clear();\n }\n\n private onMessage(message: string) {\n let parsed: CDPResponse & CDPEvent;\n try {\n parsed = JSON.parse(message) as CDPResponse & CDPEvent;\n } catch (err) {\n this.logger.warn(\"Failed to parse CDP message\", err);\n return;\n }\n if (typeof parsed.id === \"number\") {\n const callback = this.callbacks.get(parsed.id);\n if (!callback) {\n return;\n }\n this.callbacks.delete(parsed.id);\n const duration = Date.now() - callback.start;\n this.logger.debug(\"CDP recv\", callback.method, `${duration}ms`);\n if (parsed.error) {\n callback.reject(new Error(parsed.error.message));\n } else {\n callback.resolve(parsed.result);\n }\n return;\n }\n\n if (parsed.sessionId) {\n const session = this.sessions.get(parsed.sessionId);\n if (session) {\n session.dispatch(parsed.method, parsed.params);\n }\n return;\n }\n\n if (parsed.method) {\n this.emitter.emit(parsed.method, parsed.params);\n }\n }\n}\n","import { EventEmitter } from \"events\";\nimport { Connection } from \"./Connection.js\";\n\nexport class Session {\n private connection: Connection;\n private sessionId: string;\n private emitter = new EventEmitter();\n\n constructor(connection: Connection, sessionId: string) {\n this.connection = connection;\n this.sessionId = sessionId;\n }\n\n on(event: string, handler: (params: unknown) => void) {\n this.emitter.on(event, handler);\n }\n\n once(event: string, handler: (params: unknown) => void) {\n this.emitter.once(event, handler);\n }\n\n async send<T = unknown>(method: string, params: Record<string, unknown> = {}): Promise<T> {\n return this.connection.send<T>(method, params, this.sessionId);\n }\n\n dispatch(method: string, params: unknown) {\n this.emitter.emit(method, params);\n }\n}\n","import { ChildProcess } from \"child_process\";\nimport { Connection } from \"../cdp/Connection.js\";\nimport { Session } from \"../cdp/Session.js\";\nimport { Logger } from \"../logging/Logger.js\";\nimport { AutomationEvents } from \"./Events.js\";\nimport { Page } from \"./Page.js\";\n\nexport class BrowserContext {\n private browser: Browser;\n private id: string;\n\n constructor(browser: Browser, id: string) {\n this.browser = browser;\n this.id = id;\n }\n\n getId() {\n return this.id;\n }\n\n async newPage() {\n return this.browser.newPage({ browserContextId: this.id });\n }\n\n async close() {\n await this.browser.disposeContext(this.id);\n }\n}\n\nexport class Browser {\n private connection: Connection;\n private process: ChildProcess;\n private logger: Logger;\n private events: AutomationEvents;\n private cleanupTasks: Array<() => void>;\n private contexts = new Set<string>();\n\n constructor(connection: Connection, child: ChildProcess, logger: Logger, events: AutomationEvents, cleanupTasks: Array<() => void> = []) {\n this.connection = connection;\n this.process = child;\n this.logger = logger;\n this.events = events;\n this.cleanupTasks = cleanupTasks;\n }\n\n on(event: \"action:start\" | \"action:end\" | \"assertion:start\" | \"assertion:end\", handler: (payload: any) => void) {\n this.events.on(event, handler as any);\n }\n\n async newContext() {\n const { browserContextId } = await this.connection.send<{ browserContextId: string }>(\"Target.createBrowserContext\");\n this.contexts.add(browserContextId);\n return new BrowserContext(this, browserContextId);\n }\n\n async newPage(options: { browserContextId?: string } = {}) {\n const { browserContextId } = options;\n const { targetId } = await this.connection.send<{ targetId: string }>(\"Target.createTarget\", {\n url: \"about:blank\",\n browserContextId\n });\n const { sessionId } = await this.connection.send<{ sessionId: string }>(\"Target.attachToTarget\", { targetId, flatten: true });\n const session = this.connection.createSession(sessionId);\n const page = new Page(session, this.logger, this.events);\n await page.initialize();\n return page;\n }\n\n async disposeContext(contextId: string) {\n if (!contextId) return;\n try {\n await this.connection.send(\"Target.disposeBrowserContext\", { browserContextId: contextId });\n } catch {\n // ignore dispose failures\n }\n this.contexts.delete(contextId);\n }\n\n async close() {\n if (this.contexts.size > 0) {\n for (const contextId of Array.from(this.contexts)) {\n await this.disposeContext(contextId);\n }\n }\n try {\n await this.connection.send(\"Browser.close\");\n } catch {\n // ignore\n }\n await this.connection.close();\n if (!this.process.killed) {\n this.process.kill();\n }\n for (const task of this.cleanupTasks) {\n try {\n task();\n } catch {\n // ignore cleanup errors\n }\n }\n }\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport https from \"https\";\nimport { spawn } from \"child_process\";\nimport yauzl from \"yauzl\";\nimport { Logger } from \"../logging/Logger.js\";\n\nexport type Platform = \"linux\" | \"mac\" | \"win\";\n\nconst SNAPSHOT_BASE = \"https://commondatastorage.googleapis.com/chromium-browser-snapshots\";\n\nexport function detectPlatform(platform = process.platform): Platform {\n if (platform === \"linux\") return \"linux\";\n if (platform === \"darwin\") return \"mac\";\n if (platform === \"win32\") return \"win\";\n throw new Error(`Unsupported platform: ${platform}`);\n}\n\nexport function platformFolder(platform: Platform) {\n if (platform === \"linux\") return \"Linux_x64\";\n if (platform === \"mac\") return \"Mac\";\n return \"Win\";\n}\n\nexport function defaultCacheRoot(platform: Platform) {\n if (platform === \"win\") {\n const localAppData = process.env.LOCALAPPDATA || path.join(os.homedir(), \"AppData\", \"Local\");\n return path.join(localAppData, \"cdpwright\");\n }\n return path.join(os.homedir(), \".cache\", \"cdpwright\");\n}\n\nexport function ensureWithinRoot(root: string, target: string) {\n const resolvedRoot = path.resolve(root);\n const resolvedTarget = path.resolve(target);\n if (resolvedTarget === resolvedRoot) {\n return;\n }\n if (!resolvedTarget.startsWith(resolvedRoot + path.sep)) {\n throw new Error(`Path escapes cache root: ${resolvedTarget}`);\n }\n}\n\nexport function chromiumExecutableRelativePath(platform: Platform) {\n if (platform === \"linux\") return path.join(\"chrome-linux\", \"chrome\");\n if (platform === \"mac\") return path.join(\"chrome-mac\", \"Chromium.app\", \"Contents\", \"MacOS\", \"Chromium\");\n return path.join(\"chrome-win\", \"chrome.exe\");\n}\n\nexport async function fetchLatestRevision(platform: Platform): Promise<string> {\n const folder = platformFolder(platform);\n const url = `${SNAPSHOT_BASE}/${folder}/LAST_CHANGE`;\n return new Promise((resolve, reject) => {\n https.get(url, (res) => {\n if (res.statusCode && res.statusCode >= 400) {\n reject(new Error(`Failed to fetch LAST_CHANGE: ${res.statusCode}`));\n return;\n }\n let data = \"\";\n res.on(\"data\", (chunk) => (data += chunk.toString()));\n res.on(\"end\", () => resolve(data.trim()));\n }).on(\"error\", reject);\n });\n}\n\nexport type DownloadOptions = {\n cacheRoot: string;\n platform: Platform;\n revision: string;\n logger: Logger;\n};\n\nexport async function ensureDownloaded(options: DownloadOptions) {\n const { cacheRoot, platform, revision, logger } = options;\n ensureWithinRoot(cacheRoot, cacheRoot);\n const platformDir = path.join(cacheRoot, platform);\n const revisionDir = path.join(platformDir, revision);\n ensureWithinRoot(cacheRoot, revisionDir);\n\n const executablePath = path.join(revisionDir, chromiumExecutableRelativePath(platform));\n const markerFile = path.join(revisionDir, \"INSTALLATION_COMPLETE\");\n\n if (fs.existsSync(executablePath) && fs.existsSync(markerFile)) {\n return { executablePath, revisionDir };\n }\n\n fs.mkdirSync(revisionDir, { recursive: true });\n\n const folder = platformFolder(platform);\n const zipName = platform === \"win\" ? \"chrome-win.zip\" : platform === \"mac\" ? \"chrome-mac.zip\" : \"chrome-linux.zip\";\n const downloadUrl = `${SNAPSHOT_BASE}/${folder}/${revision}/${zipName}`;\n\n const tempZipPath = path.join(os.tmpdir(), `cdpwright-${platform}-${revision}.zip`);\n\n logger.info(\"Downloading Chromium snapshot\", downloadUrl);\n await downloadFile(downloadUrl, tempZipPath, logger);\n logger.info(\"Extracting Chromium snapshot\", tempZipPath);\n await extractZipSafe(tempZipPath, revisionDir);\n fs.writeFileSync(markerFile, new Date().toISOString());\n fs.unlinkSync(tempZipPath);\n\n if (!fs.existsSync(executablePath)) {\n throw new Error(`Executable not found after extraction: ${executablePath}`);\n }\n ensureExecutable(executablePath, platform);\n\n return { executablePath, revisionDir };\n}\n\nfunction downloadFile(url: string, dest: string, logger: Logger): Promise<void> {\n return new Promise((resolve, reject) => {\n const file = fs.createWriteStream(dest);\n https.get(url, (res) => {\n if (res.statusCode && res.statusCode >= 400) {\n reject(new Error(`Failed to download: ${res.statusCode}`));\n return;\n }\n const total = Number(res.headers[\"content-length\"] || 0);\n let downloaded = 0;\n let lastLoggedPercent = -1;\n let lastLoggedTime = Date.now();\n res.pipe(file);\n res.on(\"data\", (chunk) => {\n downloaded += chunk.length;\n if (!total) {\n const now = Date.now();\n if (now - lastLoggedTime > 2000) {\n logger.info(\"Download progress\", `${(downloaded / (1024 * 1024)).toFixed(1)} MB`);\n lastLoggedTime = now;\n }\n return;\n }\n const percent = Math.floor((downloaded / total) * 100);\n if (percent >= lastLoggedPercent + 5) {\n logger.info(\"Download progress\", `${percent}%`);\n lastLoggedPercent = percent;\n }\n });\n file.on(\"finish\", () => file.close(() => resolve()));\n }).on(\"error\", (err) => {\n fs.unlink(dest, () => reject(err));\n });\n });\n}\n\nexport async function extractZipSafe(zipPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n yauzl.open(zipPath, { lazyEntries: true }, (err, zipfile) => {\n if (err || !zipfile) {\n reject(err || new Error(\"Unable to open zip\"));\n return;\n }\n\n zipfile.readEntry();\n zipfile.on(\"entry\", (entry) => {\n const entryPath = entry.fileName.replace(/\\\\/g, \"/\");\n const targetPath = path.join(destDir, entryPath);\n try {\n ensureWithinRoot(destDir, targetPath);\n } catch (error) {\n zipfile.close();\n reject(error);\n return;\n }\n\n if (/\\/$/.test(entry.fileName)) {\n fs.mkdirSync(targetPath, { recursive: true });\n zipfile.readEntry();\n return;\n }\n\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n zipfile.openReadStream(entry, (streamErr, readStream) => {\n if (streamErr || !readStream) {\n zipfile.close();\n reject(streamErr || new Error(\"Unable to read zip entry\"));\n return;\n }\n const rawMode = entry.externalFileAttributes ? (entry.externalFileAttributes >>> 16) & 0xffff : 0;\n const mode = rawMode > 0 ? rawMode : undefined;\n const writeStream = fs.createWriteStream(targetPath);\n readStream.pipe(writeStream);\n writeStream.on(\"error\", (writeErr) => {\n zipfile.close();\n reject(writeErr);\n });\n writeStream.on(\"close\", () => {\n if (mode && mode <= 0o777) {\n try {\n fs.chmodSync(targetPath, mode);\n } catch {\n // ignore chmod errors\n }\n }\n zipfile.readEntry();\n });\n });\n });\n\n zipfile.on(\"end\", () => {\n zipfile.close();\n resolve();\n });\n\n zipfile.on(\"error\", (zipErr) => {\n zipfile.close();\n reject(zipErr);\n });\n });\n });\n}\n\nexport async function chromiumVersion(executablePath: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(executablePath, [\"--version\"], { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let output = \"\";\n child.stdout.on(\"data\", (chunk) => (output += chunk.toString()));\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(output.trim());\n } else {\n reject(new Error(`Failed to get Chromium version: ${code}`));\n }\n });\n child.on(\"error\", reject);\n });\n}\n\nfunction ensureExecutable(executablePath: string, platform: Platform) {\n if (platform === \"win\") {\n return;\n }\n try {\n const stat = fs.statSync(executablePath);\n const isExecutable = (stat.mode & 0o111) !== 0;\n if (!isExecutable) {\n fs.chmodSync(executablePath, 0o755);\n }\n } catch {\n // ignore chmod errors\n }\n}\n","export const PINNED_REVISION = \"1567454\";\n\nexport function resolveRevision(envRevision?: string) {\n if (envRevision && envRevision.trim()) {\n return envRevision.trim();\n }\n return PINNED_REVISION;\n}\n","import { ChromiumManager, LaunchOptions } from \"./browser/ChromiumManager.js\";\nimport { Browser, BrowserContext } from \"./core/Browser.js\";\nimport { Page } from \"./core/Page.js\";\nimport { Frame } from \"./core/Frame.js\";\nimport { Locator } from \"./core/Locator.js\";\nimport { Logger, LogLevel } from \"./logging/Logger.js\";\nimport { AutomationEvents } from \"./core/Events.js\";\nimport { expect } from \"./assert/expect.js\";\nimport { AssertionError } from \"./assert/AssertionError.js\";\n\nexport type AutomatonLaunchOptions = LaunchOptions & {\n logger?: Logger;\n};\n\nexport const automaton = {\n async launch(options: AutomatonLaunchOptions = {}): Promise<Browser> {\n const manager = new ChromiumManager(options.logger);\n return manager.launch(options);\n }\n};\n\nexport const chromium = automaton;\n\nexport { Browser, BrowserContext, Page, Frame, Locator, Logger, LogLevel, AutomationEvents, expect, AssertionError };\n"],"mappings":"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","names":["fs","path","os","spawn","EventEmitter","EventEmitter","EventEmitter","path","fs","ensureExecutable","os","spawn","args"]}
|
|
1
|
+
{"version":3,"sources":["../src/browser/ChromiumManager.ts","../src/logging/Logger.ts","../src/core/Events.ts","../src/cdp/Connection.ts","../src/cdp/Session.ts","../src/core/Browser.ts","../src/browser/Downloader.ts","../src/browser/Revision.ts","../src/index.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport http from \"http\";\nimport { spawn } from \"child_process\";\nimport { Logger, LogLevel } from \"../logging/Logger.js\";\nimport { AutomationEvents } from \"../core/Events.js\";\nimport { Connection } from \"../cdp/Connection.js\";\nimport { Browser } from \"../core/Browser.js\";\nimport { detectPlatform, defaultCacheRoot, ensureDownloaded, fetchLatestRevision, Platform, chromiumVersion } from \"./Downloader.js\";\nimport { resolveRevision } from \"./Revision.js\";\n\nexport type LaunchOptions = {\n headless?: boolean;\n args?: string[];\n timeoutMs?: number;\n logLevel?: LogLevel;\n logEvents?: boolean;\n logActions?: boolean;\n logAssertions?: boolean;\n executablePath?: string;\n userDataDir?: string;\n maximize?: boolean;\n};\n\nexport type DownloadOptions = {\n latest?: boolean;\n};\n\nexport type ResolvedDownload = {\n cacheRoot: string;\n platform: Platform;\n revision: string;\n executablePath: string;\n revisionDir: string;\n chromiumVersion?: string;\n};\n\nexport class ChromiumManager {\n private logger: Logger;\n\n constructor(logger?: Logger) {\n const envLevel = (process.env.CDPWRIGHT_LOG_LEVEL as LogLevel | undefined) ?? \"info\";\n this.logger = logger ?? new Logger(envLevel);\n }\n\n getLogger() {\n return this.logger;\n }\n\n async download(options: DownloadOptions = {}): Promise<ResolvedDownload> {\n const platform = detectPlatform();\n const cacheRoot = this.resolveCacheRoot(platform);\n const overrideExecutable = process.env.CDPWRIGHT_EXECUTABLE_PATH;\n let revision = options.latest ? await fetchLatestRevision(platform) : resolveRevision(process.env.CDPWRIGHT_REVISION);\n let executablePath: string;\n let revisionDir = \"\";\n if (overrideExecutable) {\n executablePath = path.resolve(overrideExecutable);\n } else {\n const downloaded = await ensureDownloaded({\n cacheRoot,\n platform,\n revision,\n logger: this.logger\n });\n executablePath = downloaded.executablePath;\n revisionDir = downloaded.revisionDir;\n }\n\n if (!fs.existsSync(executablePath)) {\n throw new Error(`Chromium executable not found: ${executablePath}`);\n }\n\n const version = await chromiumVersion(executablePath);\n\n this.logger.info(\"Chromium cache root\", cacheRoot);\n this.logger.info(\"Platform\", platform);\n this.logger.info(\"Revision\", revision);\n this.logger.info(\"Chromium version\", version);\n\n return {\n cacheRoot,\n platform,\n revision,\n executablePath,\n revisionDir,\n chromiumVersion: version\n };\n }\n\n async launch(options: LaunchOptions = {}) {\n const logger = this.logger;\n if (options.logLevel) {\n logger.setLevel(options.logLevel);\n }\n\n const executablePath = options.executablePath || process.env.CDPWRIGHT_EXECUTABLE_PATH;\n let resolvedExecutable = executablePath;\n if (!resolvedExecutable) {\n const platform = detectPlatform();\n const cacheRoot = this.resolveCacheRoot(platform);\n const revision = resolveRevision(process.env.CDPWRIGHT_REVISION);\n const downloaded = await ensureDownloaded({\n cacheRoot,\n platform,\n revision,\n logger\n });\n resolvedExecutable = downloaded.executablePath;\n }\n\n if (!resolvedExecutable || !fs.existsSync(resolvedExecutable)) {\n throw new Error(`Chromium executable not found: ${resolvedExecutable}`);\n }\n const stats = fs.statSync(resolvedExecutable);\n if (!stats.isFile()) {\n throw new Error(`Chromium executable is not a file: ${resolvedExecutable}`);\n }\n ensureExecutable(resolvedExecutable);\n\n const cleanupTasks: Array<() => void> = [];\n let userDataDir = options.userDataDir ?? process.env.CDPWRIGHT_USER_DATA_DIR;\n if (!userDataDir) {\n userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), \"cdpwright-\"));\n cleanupTasks.push(() => fs.rmSync(userDataDir as string, { recursive: true, force: true }));\n }\n\n const args = [\n \"--remote-debugging-port=0\",\n \"--no-first-run\",\n \"--no-default-browser-check\",\n \"--disable-background-networking\",\n \"--disable-background-timer-throttling\",\n \"--disable-backgrounding-occluded-windows\",\n \"--disable-renderer-backgrounding\"\n ];\n if (userDataDir) {\n args.push(`--user-data-dir=${userDataDir}`);\n }\n if (process.platform === \"linux\") {\n args.push(\"--disable-crash-reporter\", \"--disable-crashpad\");\n }\n if (options.headless ?? true) {\n args.push(\"--headless=new\");\n }\n if (options.maximize) {\n args.push(\"--start-maximized\");\n args.push(\"--window-size=1920,1080\");\n }\n if (options.args) {\n args.push(...options.args);\n }\n\n logger.info(\"Launching Chromium\", resolvedExecutable);\n const child = spawn(resolvedExecutable, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n\n const websocketUrl = await waitForWebSocketEndpoint(child, logger, options.timeoutMs ?? 30_000);\n const httpUrl = toHttpVersionUrl(websocketUrl);\n const wsEndpoint = await fetchWebSocketDebuggerUrl(httpUrl);\n\n const connection = new Connection(wsEndpoint, logger);\n await closeInitialPages(connection, logger);\n const events = new AutomationEvents();\n const logEvents = resolveLogFlag(options.logEvents, process.env.CDPWRIGHT_LOG, true);\n const logActions = resolveLogFlag(options.logActions, process.env.CDPWRIGHT_LOG_ACTIONS, true);\n const logAssertions = resolveLogFlag(options.logAssertions, process.env.CDPWRIGHT_LOG_ASSERTIONS, true);\n if (logEvents && logActions) {\n events.on(\"action:end\", (payload) => {\n const selector = payload.sensitive ? undefined : payload.selector;\n const args = buildLogArgs(selector, payload.durationMs);\n logger.info(`Action ${payload.name}`, ...args);\n });\n }\n if (logEvents && logAssertions) {\n events.on(\"assertion:end\", (payload) => {\n const args = buildLogArgs(payload.selector, payload.durationMs);\n logger.info(`Assertion ${payload.name}`, ...args);\n });\n }\n const browser = new Browser(connection, child, logger, events, cleanupTasks, wsEndpoint);\n\n return browser;\n }\n\n private resolveCacheRoot(platform: Platform) {\n const envRoot = process.env.CDPWRIGHT_CACHE_DIR;\n if (envRoot && envRoot.trim()) {\n return path.resolve(envRoot.trim());\n }\n return defaultCacheRoot(platform);\n }\n}\n\nasync function closeInitialPages(connection: Connection, logger: Logger) {\n try {\n const targets = await connection.send<{ targetInfos: Array<{ targetId: string; type: string }> }>(\"Target.getTargets\");\n for (const info of targets.targetInfos) {\n if (info.type === \"page\") {\n await connection.send(\"Target.closeTarget\", { targetId: info.targetId });\n }\n }\n } catch (err) {\n logger.warn(\"Failed to close initial pages\", err);\n }\n}\n\nfunction resolveLogFlag(explicit: boolean | undefined, envValue: string | undefined, defaultValue: boolean) {\n if (explicit !== undefined) {\n return explicit;\n }\n if (envValue == null) {\n return defaultValue;\n }\n const normalized = envValue.trim().toLowerCase();\n return ![\"0\", \"false\", \"no\", \"off\"].includes(normalized);\n}\n\nfunction buildLogArgs(selector?: string, durationMs?: number) {\n const args: string[] = [];\n if (selector) {\n args.push(selector);\n }\n if (typeof durationMs === \"number\") {\n args.push(`${durationMs}ms`);\n }\n return args;\n}\n\nfunction ensureExecutable(executablePath: string) {\n if (process.platform === \"win32\") {\n return;\n }\n try {\n const stat = fs.statSync(executablePath);\n const isExecutable = (stat.mode & 0o111) !== 0;\n if (!isExecutable) {\n fs.chmodSync(executablePath, 0o755);\n }\n } catch {\n // ignore chmod errors\n }\n\n const dir = path.dirname(executablePath);\n const helpers = [\n \"chrome_crashpad_handler\",\n \"chrome_sandbox\",\n \"chrome-wrapper\",\n \"xdg-mime\",\n \"xdg-settings\"\n ];\n for (const name of helpers) {\n const helperPath = path.join(dir, name);\n if (!fs.existsSync(helperPath)) {\n continue;\n }\n try {\n const stat = fs.statSync(helperPath);\n const isExecutable = (stat.mode & 0o111) !== 0;\n if (!isExecutable) {\n fs.chmodSync(helperPath, 0o755);\n }\n } catch {\n // ignore chmod errors\n }\n }\n}\n\nfunction waitForWebSocketEndpoint(child: ReturnType<typeof spawn>, logger: Logger, timeoutMs: number): Promise<string> {\n return new Promise((resolve, reject) => {\n const start = Date.now();\n const timeout = setTimeout(() => {\n reject(new Error(\"Timed out waiting for DevTools endpoint\"));\n }, timeoutMs);\n\n const outputLines: string[] = [];\n const pushOutput = (data: Buffer) => {\n const text = data.toString();\n for (const line of text.split(/\\r?\\n/)) {\n if (!line.trim()) continue;\n outputLines.push(line);\n if (outputLines.length > 50) {\n outputLines.shift();\n }\n }\n };\n\n const onData = (data: Buffer) => {\n const text = data.toString();\n const match = text.match(/DevTools listening on (ws:\\/\\/[^\\s]+)/);\n if (match) {\n clearTimeout(timeout);\n cleanup();\n logger.info(\"DevTools endpoint\", match[1]);\n resolve(match[1]);\n }\n pushOutput(data);\n };\n\n const onExit = (code: number | null, signal: NodeJS.Signals | null) => {\n cleanup();\n const tail = outputLines.length ? `\\nChromium output:\\n${outputLines.join(\"\\n\")}` : \"\";\n reject(new Error(`Chromium exited early with code ${code ?? \"null\"} signal ${signal ?? \"null\"}${tail}`));\n };\n\n const cleanup = () => {\n child.stdout?.off(\"data\", onData);\n child.stderr?.off(\"data\", onData);\n child.off(\"exit\", onExit);\n };\n\n child.stdout?.on(\"data\", onData);\n child.stderr?.on(\"data\", onData);\n child.on(\"exit\", onExit);\n\n if (Date.now() - start > timeoutMs) {\n cleanup();\n }\n });\n}\n\nfunction toHttpVersionUrl(wsUrl: string) {\n try {\n const url = new URL(wsUrl);\n const port = url.port || \"9222\";\n return `http://127.0.0.1:${port}/json/version`;\n } catch {\n throw new Error(`Invalid DevTools endpoint: ${wsUrl}`);\n }\n}\n\nfunction fetchWebSocketDebuggerUrl(versionUrl: string): Promise<string> {\n return new Promise((resolve, reject) => {\n http.get(versionUrl, (res) => {\n if (res.statusCode && res.statusCode >= 400) {\n reject(new Error(`Failed to fetch /json/version: ${res.statusCode}`));\n return;\n }\n let data = \"\";\n res.on(\"data\", (chunk) => (data += chunk.toString()));\n res.on(\"end\", () => {\n try {\n const parsed = JSON.parse(data);\n if (!parsed.webSocketDebuggerUrl) {\n reject(new Error(\"webSocketDebuggerUrl missing\"));\n return;\n }\n resolve(parsed.webSocketDebuggerUrl);\n } catch (err) {\n reject(err);\n }\n });\n }).on(\"error\", reject);\n });\n}\n","export type LogLevel = \"error\" | \"warn\" | \"info\" | \"debug\" | \"trace\";\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4\n};\n\nconst REDACT_KEYS = [\"password\", \"token\", \"secret\", \"authorization\", \"cookie\"];\n\nfunction redactValue(value: unknown): string {\n if (typeof value === \"string\") {\n try {\n const url = new URL(value);\n if (url.search) {\n url.search = \"?redacted\";\n }\n return url.toString();\n } catch {\n return value;\n }\n }\n if (value && typeof value === \"object\") {\n return JSON.stringify(value, (key, val) => {\n if (REDACT_KEYS.some((k) => key.toLowerCase().includes(k))) {\n return \"[redacted]\";\n }\n return val;\n });\n }\n return String(value);\n}\n\nexport class Logger {\n private level: LogLevel;\n\n constructor(level: LogLevel = \"info\") {\n this.level = level;\n }\n\n setLevel(level: LogLevel) {\n this.level = level;\n }\n\n error(message: string, ...args: unknown[]) {\n this.log(\"error\", message, ...args);\n }\n\n warn(message: string, ...args: unknown[]) {\n this.log(\"warn\", message, ...args);\n }\n\n info(message: string, ...args: unknown[]) {\n this.log(\"info\", message, ...args);\n }\n\n debug(message: string, ...args: unknown[]) {\n this.log(\"debug\", message, ...args);\n }\n\n trace(message: string, ...args: unknown[]) {\n this.log(\"trace\", message, ...args);\n }\n\n log(level: LogLevel, message: string, ...args: unknown[]) {\n if (LEVEL_ORDER[level] > LEVEL_ORDER[this.level]) {\n return;\n }\n const time = new Date().toISOString();\n const suffix = args.length ? \" \" + args.map(redactValue).join(\" \") : \"\";\n const line = `[${time}] [${level}] ${message}${suffix}`;\n if (level === \"error\") {\n console.error(line);\n } else if (level === \"warn\") {\n console.warn(line);\n } else {\n console.log(line);\n }\n }\n}\n","import { EventEmitter } from \"events\";\n\nexport type ActionEvent = {\n name: string;\n selector?: string;\n frameId?: string;\n durationMs?: number;\n sensitive?: boolean;\n status?: \"passed\" | \"failed\";\n};\n\nexport type AssertionEvent = {\n name: string;\n selector?: string;\n frameId?: string;\n durationMs?: number;\n status?: \"passed\" | \"failed\";\n};\n\nexport type AutomationEventMap = {\n \"action:start\": ActionEvent;\n \"action:end\": ActionEvent;\n \"assertion:start\": AssertionEvent;\n \"assertion:end\": AssertionEvent;\n};\n\nexport class AutomationEvents {\n private emitter = new EventEmitter();\n\n on<K extends keyof AutomationEventMap>(event: K, handler: (payload: AutomationEventMap[K]) => void) {\n this.emitter.on(event, handler);\n }\n\n off<K extends keyof AutomationEventMap>(event: K, handler: (payload: AutomationEventMap[K]) => void) {\n this.emitter.off(event, handler);\n }\n\n emit<K extends keyof AutomationEventMap>(event: K, payload: AutomationEventMap[K]) {\n this.emitter.emit(event, payload);\n }\n}\n","import WebSocket from \"ws\";\nimport { EventEmitter } from \"events\";\nimport { Logger } from \"../logging/Logger.js\";\nimport { Session } from \"./Session.js\";\n\nexport type CDPResponse = {\n id: number;\n result?: unknown;\n error?: { message: string; data?: unknown };\n sessionId?: string;\n};\n\nexport type CDPEvent = {\n method: string;\n params?: unknown;\n sessionId?: string;\n};\n\nexport class Connection {\n private ws: WebSocket;\n private id = 0;\n private callbacks = new Map<number, { resolve: (value: unknown) => void; reject: (reason?: unknown) => void; method: string; start: number }>();\n private sessions = new Map<string, Session>();\n private emitter = new EventEmitter();\n private logger: Logger;\n private closed = false;\n\n constructor(url: string, logger: Logger) {\n this.logger = logger;\n this.ws = new WebSocket(url);\n this.ws.on(\"message\", (data: WebSocket.RawData) => this.onMessage(data.toString()));\n this.ws.on(\"error\", (err: Error) => this.onError(err));\n this.ws.on(\"close\", (code: number, reason: Buffer) => this.onClose(code, reason));\n }\n\n async waitForOpen() {\n if (this.ws.readyState === WebSocket.OPEN) {\n return;\n }\n if (this.ws.readyState === WebSocket.CLOSED) {\n throw new Error(\"CDP socket is closed\");\n }\n await new Promise<void>((resolve, reject) => {\n const onOpen = () => {\n cleanup();\n resolve();\n };\n const onError = (err: Error) => {\n cleanup();\n reject(err);\n };\n const onClose = () => {\n cleanup();\n reject(new Error(\"CDP socket closed before opening\"));\n };\n const cleanup = () => {\n this.ws.off(\"open\", onOpen);\n this.ws.off(\"error\", onError);\n this.ws.off(\"close\", onClose);\n };\n this.ws.on(\"open\", onOpen);\n this.ws.on(\"error\", onError);\n this.ws.on(\"close\", onClose);\n });\n }\n\n createSession(sessionId: string): Session {\n const session = new Session(this, sessionId);\n this.sessions.set(sessionId, session);\n return session;\n }\n\n removeSession(sessionId: string) {\n this.sessions.delete(sessionId);\n }\n\n on(event: string, handler: (params: unknown) => void) {\n this.emitter.on(event, handler);\n }\n\n async send<T = unknown>(method: string, params: Record<string, unknown> = {}, sessionId?: string): Promise<T> {\n await this.waitForOpen();\n const id = ++this.id;\n const payload = sessionId ? { id, method, params, sessionId } : { id, method, params };\n const start = Date.now();\n const promise = new Promise<T>((resolve, reject) => {\n this.callbacks.set(id, { resolve: resolve as (value: unknown) => void, reject, method, start });\n });\n if (this.logger) {\n this.logger.trace(\"CDP send\", method);\n }\n this.ws.send(JSON.stringify(payload));\n return promise;\n }\n\n async close() {\n if (this.ws.readyState === WebSocket.CLOSED) {\n return;\n }\n await new Promise<void>((resolve) => {\n this.ws.once(\"close\", () => resolve());\n if (this.ws.readyState === WebSocket.CLOSING) {\n return;\n }\n this.ws.close();\n });\n }\n\n private onError(err: unknown) {\n this.logger.error(\"CDP socket error\", err);\n }\n\n private onClose(code: number, reason: Buffer) {\n if (this.closed) {\n return;\n }\n this.closed = true;\n const reasonText = reason.toString() || \"no reason\";\n this.failPending(new Error(`CDP socket closed (${code}): ${reasonText}`));\n this.sessions.clear();\n }\n\n private failPending(error: Error) {\n if (this.callbacks.size === 0) {\n return;\n }\n for (const [, callback] of this.callbacks) {\n callback.reject(error);\n }\n this.callbacks.clear();\n }\n\n private onMessage(message: string) {\n let parsed: CDPResponse & CDPEvent;\n try {\n parsed = JSON.parse(message) as CDPResponse & CDPEvent;\n } catch (err) {\n this.logger.warn(\"Failed to parse CDP message\", err);\n return;\n }\n if (typeof parsed.id === \"number\") {\n const callback = this.callbacks.get(parsed.id);\n if (!callback) {\n return;\n }\n this.callbacks.delete(parsed.id);\n const duration = Date.now() - callback.start;\n this.logger.debug(\"CDP recv\", callback.method, `${duration}ms`);\n if (parsed.error) {\n callback.reject(new Error(parsed.error.message));\n } else {\n callback.resolve(parsed.result);\n }\n return;\n }\n\n if (parsed.sessionId) {\n const session = this.sessions.get(parsed.sessionId);\n if (session) {\n session.dispatch(parsed.method, parsed.params);\n }\n return;\n }\n\n if (parsed.method) {\n this.emitter.emit(parsed.method, parsed.params);\n }\n }\n}\n","import { EventEmitter } from \"events\";\nimport { Connection } from \"./Connection.js\";\n\nexport class Session {\n private connection: Connection;\n private sessionId: string;\n private emitter = new EventEmitter();\n\n constructor(connection: Connection, sessionId: string) {\n this.connection = connection;\n this.sessionId = sessionId;\n }\n\n on(event: string, handler: (params: unknown) => void) {\n this.emitter.on(event, handler);\n }\n\n once(event: string, handler: (params: unknown) => void) {\n this.emitter.once(event, handler);\n }\n\n async send<T = unknown>(method: string, params: Record<string, unknown> = {}): Promise<T> {\n return this.connection.send<T>(method, params, this.sessionId);\n }\n\n dispatch(method: string, params: unknown) {\n this.emitter.emit(method, params);\n }\n}\n","import { ChildProcess } from \"child_process\";\nimport { Connection } from \"../cdp/Connection.js\";\nimport { Session } from \"../cdp/Session.js\";\nimport { Logger } from \"../logging/Logger.js\";\nimport { AutomationEvents } from \"./Events.js\";\nimport { Page } from \"./Page.js\";\n\nexport class BrowserContext {\n private browser: Browser;\n private id: string;\n\n constructor(browser: Browser, id: string) {\n this.browser = browser;\n this.id = id;\n }\n\n getId() {\n return this.id;\n }\n\n async newPage() {\n return this.browser.newPage({ browserContextId: this.id });\n }\n\n async close() {\n await this.browser.disposeContext(this.id);\n }\n}\n\nexport class Browser {\n private connection: Connection;\n private process: ChildProcess | null;\n private logger: Logger;\n private events: AutomationEvents;\n private cleanupTasks: Array<() => void>;\n private contexts = new Set<string>();\n readonly wsEndpoint: string;\n readonly pid: number;\n\n constructor(connection: Connection, child: ChildProcess | null, logger: Logger, events: AutomationEvents, cleanupTasks: Array<() => void> = [], wsEndpoint: string = \"\") {\n this.connection = connection;\n this.process = child;\n this.logger = logger;\n this.events = events;\n this.cleanupTasks = cleanupTasks;\n this.wsEndpoint = wsEndpoint;\n this.pid = child?.pid ?? 0;\n }\n\n on(event: \"action:start\" | \"action:end\" | \"assertion:start\" | \"assertion:end\", handler: (payload: any) => void) {\n this.events.on(event, handler as any);\n }\n\n async newContext() {\n const { browserContextId } = await this.connection.send<{ browserContextId: string }>(\"Target.createBrowserContext\");\n this.contexts.add(browserContextId);\n return new BrowserContext(this, browserContextId);\n }\n\n async newPage(options: { browserContextId?: string } = {}) {\n const { browserContextId } = options;\n const { targetId } = await this.connection.send<{ targetId: string }>(\"Target.createTarget\", {\n url: \"about:blank\",\n browserContextId\n });\n const { sessionId } = await this.connection.send<{ sessionId: string }>(\"Target.attachToTarget\", { targetId, flatten: true });\n const session = this.connection.createSession(sessionId);\n const page = new Page(session, this.logger, this.events);\n await page.initialize();\n return page;\n }\n\n /** Attach to an existing page by target ID. */\n async attachPage(targetId: string) {\n const { sessionId } = await this.connection.send<{ sessionId: string }>(\"Target.attachToTarget\", { targetId, flatten: true });\n const session = this.connection.createSession(sessionId);\n const page = new Page(session, this.logger, this.events);\n await page.initialize();\n return page;\n }\n\n /** List open page targets. */\n async pages(): Promise<Array<{ targetId: string; url: string; title: string }>> {\n const result = await this.connection.send<{ targetInfos: Array<{ targetId: string; type: string; url: string; title: string }> }>(\"Target.getTargets\");\n return result.targetInfos\n .filter((t) => t.type === \"page\")\n .map((t) => ({ targetId: t.targetId, url: t.url, title: t.title }));\n }\n\n /** Disconnect without killing the browser process. */\n async disconnect() {\n await this.connection.close();\n }\n\n async disposeContext(contextId: string) {\n if (!contextId) return;\n try {\n await this.connection.send(\"Target.disposeBrowserContext\", { browserContextId: contextId });\n } catch {\n // ignore dispose failures\n }\n this.contexts.delete(contextId);\n }\n\n async close() {\n if (this.contexts.size > 0) {\n for (const contextId of Array.from(this.contexts)) {\n await this.disposeContext(contextId);\n }\n }\n try {\n await this.connection.send(\"Browser.close\");\n } catch {\n // ignore\n }\n await this.connection.close();\n if (this.process && !this.process.killed) {\n this.process.kill();\n }\n for (const task of this.cleanupTasks) {\n try {\n task();\n } catch {\n // ignore cleanup errors\n }\n }\n }\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport http from \"http\";\nimport https from \"https\";\nimport { spawn } from \"child_process\";\nimport yauzl from \"yauzl\";\nimport { Logger } from \"../logging/Logger.js\";\n\nexport type Platform = \"linux\" | \"mac\" | \"win\";\n\nconst SNAPSHOT_BASE = \"https://commondatastorage.googleapis.com/chromium-browser-snapshots\";\n\nexport function detectPlatform(platform = process.platform): Platform {\n if (platform === \"linux\") return \"linux\";\n if (platform === \"darwin\") return \"mac\";\n if (platform === \"win32\") return \"win\";\n throw new Error(`Unsupported platform: ${platform}`);\n}\n\nexport function platformFolder(platform: Platform) {\n if (platform === \"linux\") return \"Linux_x64\";\n if (platform === \"mac\") return \"Mac\";\n return \"Win\";\n}\n\nexport function defaultCacheRoot(platform: Platform) {\n if (platform === \"win\") {\n const localAppData = process.env.LOCALAPPDATA || path.join(os.homedir(), \"AppData\", \"Local\");\n return path.join(localAppData, \"cdpwright\");\n }\n return path.join(os.homedir(), \".cache\", \"cdpwright\");\n}\n\nexport function ensureWithinRoot(root: string, target: string) {\n const resolvedRoot = path.resolve(root);\n const resolvedTarget = path.resolve(target);\n if (resolvedTarget === resolvedRoot) {\n return;\n }\n if (!resolvedTarget.startsWith(resolvedRoot + path.sep)) {\n throw new Error(`Path escapes cache root: ${resolvedTarget}`);\n }\n}\n\nexport function chromiumExecutableRelativePath(platform: Platform) {\n if (platform === \"linux\") return path.join(\"chrome-linux\", \"chrome\");\n if (platform === \"mac\") return path.join(\"chrome-mac\", \"Chromium.app\", \"Contents\", \"MacOS\", \"Chromium\");\n return path.join(\"chrome-win\", \"chrome.exe\");\n}\n\nfunction httpGet(url: string): typeof https {\n return url.startsWith(\"http://\") ? http as any : https;\n}\n\nfunction resolveSnapshotBase(): string {\n const mirror = process.env.CDPWRIGHT_DOWNLOAD_MIRROR;\n if (mirror && mirror.trim()) {\n return mirror.trim().replace(/\\/+$/, \"\");\n }\n return SNAPSHOT_BASE;\n}\n\nexport async function fetchLatestRevision(platform: Platform): Promise<string> {\n const base = resolveSnapshotBase();\n const folder = platformFolder(platform);\n const url = `${base}/${folder}/LAST_CHANGE`;\n return new Promise((resolve, reject) => {\n httpGet(url).get(url, (res) => {\n if (res.statusCode && res.statusCode >= 400) {\n reject(new Error(`Failed to fetch LAST_CHANGE: ${res.statusCode}`));\n return;\n }\n let data = \"\";\n res.on(\"data\", (chunk) => (data += chunk.toString()));\n res.on(\"end\", () => resolve(data.trim()));\n }).on(\"error\", reject);\n });\n}\n\nexport type DownloadOptions = {\n cacheRoot: string;\n platform: Platform;\n revision: string;\n logger: Logger;\n};\n\nexport async function ensureDownloaded(options: DownloadOptions) {\n const { cacheRoot, platform, revision, logger } = options;\n ensureWithinRoot(cacheRoot, cacheRoot);\n const platformDir = path.join(cacheRoot, platform);\n const revisionDir = path.join(platformDir, revision);\n ensureWithinRoot(cacheRoot, revisionDir);\n\n const executablePath = path.join(revisionDir, chromiumExecutableRelativePath(platform));\n const markerFile = path.join(revisionDir, \"INSTALLATION_COMPLETE\");\n\n if (fs.existsSync(executablePath) && fs.existsSync(markerFile)) {\n return { executablePath, revisionDir };\n }\n\n fs.mkdirSync(revisionDir, { recursive: true });\n\n const folder = platformFolder(platform);\n const zipName = platform === \"win\" ? \"chrome-win.zip\" : platform === \"mac\" ? \"chrome-mac.zip\" : \"chrome-linux.zip\";\n\n const explicitUrl = process.env.CDPWRIGHT_DOWNLOAD_URL?.trim();\n const base = resolveSnapshotBase();\n const downloadUrl = explicitUrl || `${base}/${folder}/${revision}/${zipName}`;\n\n const tempZipPath = path.join(os.tmpdir(), `cdpwright-${platform}-${revision}.zip`);\n\n logger.info(\"Downloading Chromium snapshot\", downloadUrl);\n await downloadFile(downloadUrl, tempZipPath, logger);\n logger.info(\"Extracting Chromium snapshot\", tempZipPath);\n await extractZipSafe(tempZipPath, revisionDir);\n fs.writeFileSync(markerFile, new Date().toISOString());\n fs.unlinkSync(tempZipPath);\n\n if (!fs.existsSync(executablePath)) {\n throw new Error(`Executable not found after extraction: ${executablePath}`);\n }\n ensureExecutable(executablePath, platform);\n\n return { executablePath, revisionDir };\n}\n\nfunction downloadFile(url: string, dest: string, logger: Logger): Promise<void> {\n return new Promise((resolve, reject) => {\n const file = fs.createWriteStream(dest);\n httpGet(url).get(url, (res) => {\n if (res.statusCode && res.statusCode >= 400) {\n reject(new Error(`Failed to download: ${res.statusCode}`));\n return;\n }\n const total = Number(res.headers[\"content-length\"] || 0);\n let downloaded = 0;\n let lastLoggedPercent = -1;\n let lastLoggedTime = Date.now();\n res.pipe(file);\n res.on(\"data\", (chunk) => {\n downloaded += chunk.length;\n if (!total) {\n const now = Date.now();\n if (now - lastLoggedTime > 2000) {\n logger.info(\"Download progress\", `${(downloaded / (1024 * 1024)).toFixed(1)} MB`);\n lastLoggedTime = now;\n }\n return;\n }\n const percent = Math.floor((downloaded / total) * 100);\n if (percent >= lastLoggedPercent + 5) {\n logger.info(\"Download progress\", `${percent}%`);\n lastLoggedPercent = percent;\n }\n });\n file.on(\"finish\", () => file.close(() => resolve()));\n }).on(\"error\", (err) => {\n fs.unlink(dest, () => reject(err));\n });\n });\n}\n\nexport async function extractZipSafe(zipPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n yauzl.open(zipPath, { lazyEntries: true }, (err, zipfile) => {\n if (err || !zipfile) {\n reject(err || new Error(\"Unable to open zip\"));\n return;\n }\n\n zipfile.readEntry();\n zipfile.on(\"entry\", (entry) => {\n const entryPath = entry.fileName.replace(/\\\\/g, \"/\");\n const targetPath = path.join(destDir, entryPath);\n try {\n ensureWithinRoot(destDir, targetPath);\n } catch (error) {\n zipfile.close();\n reject(error);\n return;\n }\n\n if (/\\/$/.test(entry.fileName)) {\n fs.mkdirSync(targetPath, { recursive: true });\n zipfile.readEntry();\n return;\n }\n\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n zipfile.openReadStream(entry, (streamErr, readStream) => {\n if (streamErr || !readStream) {\n zipfile.close();\n reject(streamErr || new Error(\"Unable to read zip entry\"));\n return;\n }\n const rawMode = entry.externalFileAttributes ? (entry.externalFileAttributes >>> 16) & 0xffff : 0;\n const mode = rawMode > 0 ? rawMode : undefined;\n const writeStream = fs.createWriteStream(targetPath);\n readStream.pipe(writeStream);\n writeStream.on(\"error\", (writeErr) => {\n zipfile.close();\n reject(writeErr);\n });\n writeStream.on(\"close\", () => {\n if (mode && mode <= 0o777) {\n try {\n fs.chmodSync(targetPath, mode);\n } catch {\n // ignore chmod errors\n }\n }\n zipfile.readEntry();\n });\n });\n });\n\n zipfile.on(\"end\", () => {\n zipfile.close();\n resolve();\n });\n\n zipfile.on(\"error\", (zipErr) => {\n zipfile.close();\n reject(zipErr);\n });\n });\n });\n}\n\nexport async function chromiumVersion(executablePath: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(executablePath, [\"--version\"], { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let output = \"\";\n child.stdout.on(\"data\", (chunk) => (output += chunk.toString()));\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve(output.trim());\n } else {\n reject(new Error(`Failed to get Chromium version: ${code}`));\n }\n });\n child.on(\"error\", reject);\n });\n}\n\nfunction ensureExecutable(executablePath: string, platform: Platform) {\n if (platform === \"win\") {\n return;\n }\n try {\n const stat = fs.statSync(executablePath);\n const isExecutable = (stat.mode & 0o111) !== 0;\n if (!isExecutable) {\n fs.chmodSync(executablePath, 0o755);\n }\n } catch {\n // ignore chmod errors\n }\n}\n","export const PINNED_REVISION = \"1567454\";\n\nexport function resolveRevision(envRevision?: string) {\n if (envRevision && envRevision.trim()) {\n return envRevision.trim();\n }\n return PINNED_REVISION;\n}\n","import { ChromiumManager, LaunchOptions } from \"./browser/ChromiumManager.js\";\nimport { Connection } from \"./cdp/Connection.js\";\nimport { Browser, BrowserContext } from \"./core/Browser.js\";\nimport { Page } from \"./core/Page.js\";\nimport { Frame } from \"./core/Frame.js\";\nimport { Locator } from \"./core/Locator.js\";\nimport { Logger, LogLevel } from \"./logging/Logger.js\";\nimport { AutomationEvents } from \"./core/Events.js\";\nimport { expect } from \"./assert/expect.js\";\nimport { AssertionError } from \"./assert/AssertionError.js\";\n\nexport type AutomatonLaunchOptions = LaunchOptions & {\n logger?: Logger;\n};\n\nexport type ConnectOptions = {\n logLevel?: LogLevel;\n logger?: Logger;\n logEvents?: boolean;\n logActions?: boolean;\n logAssertions?: boolean;\n};\n\nexport const automaton = {\n async launch(options: AutomatonLaunchOptions = {}): Promise<Browser> {\n const manager = new ChromiumManager(options.logger);\n return manager.launch(options);\n },\n\n async connect(wsEndpoint: string, options: ConnectOptions = {}): Promise<Browser> {\n const logger = options.logger ?? new Logger(options.logLevel ?? \"warn\");\n const connection = new Connection(wsEndpoint, logger);\n await connection.waitForOpen();\n const events = new AutomationEvents();\n const logEvents = options.logEvents ?? true;\n const logActions = options.logActions ?? true;\n const logAssertions = options.logAssertions ?? true;\n if (logEvents && logActions) {\n events.on(\"action:end\", (payload) => {\n const selector = payload.sensitive ? undefined : payload.selector;\n const args: string[] = [];\n if (selector) args.push(selector);\n if (typeof payload.durationMs === \"number\") args.push(`${payload.durationMs}ms`);\n logger.info(`Action ${payload.name}`, ...args);\n });\n }\n if (logEvents && logAssertions) {\n events.on(\"assertion:end\", (payload) => {\n const args: string[] = [];\n if (payload.selector) args.push(payload.selector);\n if (typeof payload.durationMs === \"number\") args.push(`${payload.durationMs}ms`);\n logger.info(`Assertion ${payload.name}`, ...args);\n });\n }\n return new Browser(connection, null, logger, events, [], wsEndpoint);\n }\n};\n\nexport const chromium = automaton;\n\nexport { Browser, BrowserContext, Page, Frame, Locator, Logger, LogLevel, AutomationEvents, expect, AssertionError };\n"],"mappings":"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","names":["fs","path","os","http","spawn","EventEmitter","EventEmitter","EventEmitter","path","fs","ensureExecutable","os","spawn","args","http"]}
|