@toolstackhq/cdpwright 1.1.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.
@@ -242,11 +242,13 @@ declare class Page {
242
242
  setFileInput(selector: string, name: string, contents: string, options?: {
243
243
  mimeType?: string;
244
244
  }): Promise<void>;
245
+ content(): Promise<string>;
245
246
  screenshot(options?: ScreenshotOptions): Promise<Buffer<ArrayBuffer>>;
246
247
  screenshotBase64(options?: Omit<ScreenshotOptions, "path">): Promise<string>;
247
248
  pdf(options?: PdfOptions): Promise<Buffer>;
248
249
  getEvents(): AutomationEvents;
249
250
  getDefaultTimeout(): number;
251
+ waitForLoad(timeoutMs?: number): Promise<void>;
250
252
  private buildFrameTree;
251
253
  private ensureFrame;
252
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-BY8vnFfi.js';
2
- export { F as Frame, b as Locator, e as expect } from './expect-BY8vnFfi.js';
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
- constructor(connection: Connection, child: ChildProcess, logger: Logger, events: AutomationEvents, cleanupTasks?: Array<() => void>);
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,7 +4,7 @@ import {
4
4
  Locator,
5
5
  Page,
6
6
  expect
7
- } from "./chunk-M5G6EMAS.js";
7
+ } from "./chunk-PDUS6BDZ.js";
8
8
 
9
9
  // src/browser/ChromiumManager.ts
10
10
  import fs2 from "fs";
@@ -292,12 +292,16 @@ var Browser = class {
292
292
  events;
293
293
  cleanupTasks;
294
294
  contexts = /* @__PURE__ */ new Set();
295
- constructor(connection, child, logger, events, cleanupTasks = []) {
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) {
@@ -680,6 +701,7 @@ var ChromiumManager = class {
680
701
  }
681
702
  if (options.maximize) {
682
703
  args.push("--start-maximized");
704
+ args.push("--window-size=1920,1080");
683
705
  }
684
706
  if (options.args) {
685
707
  args.push(...options.args);
@@ -708,7 +730,7 @@ var ChromiumManager = class {
708
730
  logger.info(`Assertion ${payload.name}`, ...args2);
709
731
  });
710
732
  }
711
- const browser = new Browser(connection, child, logger, events, cleanupTasks);
733
+ const browser = new Browser(connection, child, logger, events, cleanupTasks, wsEndpoint);
712
734
  return browser;
713
735
  }
714
736
  resolveCacheRoot(platform) {
@@ -873,6 +895,33 @@ var automaton = {
873
895
  async launch(options = {}) {
874
896
  const manager = new ChromiumManager(options.logger);
875
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);
876
925
  }
877
926
  };
878
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 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 { 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":";;;;;;;;;AAAA,OAAOA,SAAQ;AACf,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,SAAAC,cAAa;;;ACFtB,IAAM,cAAwC;AAAA,EAC5C,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AACT;AAEA,IAAM,cAAc,CAAC,YAAY,SAAS,UAAU,iBAAiB,QAAQ;AAE7E,SAAS,YAAY,OAAwB;AAC3C,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,KAAK;AACzB,UAAI,IAAI,QAAQ;AACd,YAAI,SAAS;AAAA,MACf;AACA,aAAO,IAAI,SAAS;AAAA,IACtB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,WAAO,KAAK,UAAU,OAAO,CAAC,KAAK,QAAQ;AACzC,UAAI,YAAY,KAAK,CAAC,MAAM,IAAI,YAAY,EAAE,SAAS,CAAC,CAAC,GAAG;AAC1D,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,SAAO,OAAO,KAAK;AACrB;AAEO,IAAM,SAAN,MAAa;AAAA,EACV;AAAA,EAER,YAAY,QAAkB,QAAQ;AACpC,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,SAAS,OAAiB;AACxB,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAM,YAAoB,MAAiB;AACzC,SAAK,IAAI,SAAS,SAAS,GAAG,IAAI;AAAA,EACpC;AAAA,EAEA,KAAK,YAAoB,MAAiB;AACxC,SAAK,IAAI,QAAQ,SAAS,GAAG,IAAI;AAAA,EACnC;AAAA,EAEA,KAAK,YAAoB,MAAiB;AACxC,SAAK,IAAI,QAAQ,SAAS,GAAG,IAAI;AAAA,EACnC;AAAA,EAEA,MAAM,YAAoB,MAAiB;AACzC,SAAK,IAAI,SAAS,SAAS,GAAG,IAAI;AAAA,EACpC;AAAA,EAEA,MAAM,YAAoB,MAAiB;AACzC,SAAK,IAAI,SAAS,SAAS,GAAG,IAAI;AAAA,EACpC;AAAA,EAEA,IAAI,OAAiB,YAAoB,MAAiB;AACxD,QAAI,YAAY,KAAK,IAAI,YAAY,KAAK,KAAK,GAAG;AAChD;AAAA,IACF;AACA,UAAM,QAAO,oBAAI,KAAK,GAAE,YAAY;AACpC,UAAM,SAAS,KAAK,SAAS,MAAM,KAAK,IAAI,WAAW,EAAE,KAAK,GAAG,IAAI;AACrE,UAAM,OAAO,IAAI,IAAI,MAAM,KAAK,KAAK,OAAO,GAAG,MAAM;AACrD,QAAI,UAAU,SAAS;AACrB,cAAQ,MAAM,IAAI;AAAA,IACpB,WAAW,UAAU,QAAQ;AAC3B,cAAQ,KAAK,IAAI;AAAA,IACnB,OAAO;AACL,cAAQ,IAAI,IAAI;AAAA,IAClB;AAAA,EACF;AACF;;;ACjFA,SAAS,oBAAoB;AA0BtB,IAAM,mBAAN,MAAuB;AAAA,EACpB,UAAU,IAAI,aAAa;AAAA,EAEnC,GAAuC,OAAU,SAAmD;AAClG,SAAK,QAAQ,GAAG,OAAO,OAAO;AAAA,EAChC;AAAA,EAEA,IAAwC,OAAU,SAAmD;AACnG,SAAK,QAAQ,IAAI,OAAO,OAAO;AAAA,EACjC;AAAA,EAEA,KAAyC,OAAU,SAAgC;AACjF,SAAK,QAAQ,KAAK,OAAO,OAAO;AAAA,EAClC;AACF;;;ACxCA,OAAO,eAAe;AACtB,SAAS,gBAAAC,qBAAoB;;;ACD7B,SAAS,gBAAAC,qBAAoB;AAGtB,IAAM,UAAN,MAAc;AAAA,EACX;AAAA,EACA;AAAA,EACA,UAAU,IAAIA,cAAa;AAAA,EAEnC,YAAY,YAAwB,WAAmB;AACrD,SAAK,aAAa;AAClB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,GAAG,OAAe,SAAoC;AACpD,SAAK,QAAQ,GAAG,OAAO,OAAO;AAAA,EAChC;AAAA,EAEA,KAAK,OAAe,SAAoC;AACtD,SAAK,QAAQ,KAAK,OAAO,OAAO;AAAA,EAClC;AAAA,EAEA,MAAM,KAAkB,QAAgB,SAAkC,CAAC,GAAe;AACxF,WAAO,KAAK,WAAW,KAAQ,QAAQ,QAAQ,KAAK,SAAS;AAAA,EAC/D;AAAA,EAEA,SAAS,QAAgB,QAAiB;AACxC,SAAK,QAAQ,KAAK,QAAQ,MAAM;AAAA,EAClC;AACF;;;ADVO,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EACA,KAAK;AAAA,EACL,YAAY,oBAAI,IAAsH;AAAA,EACtI,WAAW,oBAAI,IAAqB;AAAA,EACpC,UAAU,IAAIC,cAAa;AAAA,EAC3B;AAAA,EACA,SAAS;AAAA,EAEjB,YAAY,KAAa,QAAgB;AACvC,SAAK,SAAS;AACd,SAAK,KAAK,IAAI,UAAU,GAAG;AAC3B,SAAK,GAAG,GAAG,WAAW,CAAC,SAA4B,KAAK,UAAU,KAAK,SAAS,CAAC,CAAC;AAClF,SAAK,GAAG,GAAG,SAAS,CAAC,QAAe,KAAK,QAAQ,GAAG,CAAC;AACrD,SAAK,GAAG,GAAG,SAAS,CAAC,MAAc,WAAmB,KAAK,QAAQ,MAAM,MAAM,CAAC;AAAA,EAClF;AAAA,EAEA,MAAM,cAAc;AAClB,QAAI,KAAK,GAAG,eAAe,UAAU,MAAM;AACzC;AAAA,IACF;AACA,QAAI,KAAK,GAAG,eAAe,UAAU,QAAQ;AAC3C,YAAM,IAAI,MAAM,sBAAsB;AAAA,IACxC;AACA,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAM,SAAS,MAAM;AACnB,gBAAQ;AACR,gBAAQ;AAAA,MACV;AACA,YAAM,UAAU,CAAC,QAAe;AAC9B,gBAAQ;AACR,eAAO,GAAG;AAAA,MACZ;AACA,YAAM,UAAU,MAAM;AACpB,gBAAQ;AACR,eAAO,IAAI,MAAM,kCAAkC,CAAC;AAAA,MACtD;AACA,YAAM,UAAU,MAAM;AACpB,aAAK,GAAG,IAAI,QAAQ,MAAM;AAC1B,aAAK,GAAG,IAAI,SAAS,OAAO;AAC5B,aAAK,GAAG,IAAI,SAAS,OAAO;AAAA,MAC9B;AACA,WAAK,GAAG,GAAG,QAAQ,MAAM;AACzB,WAAK,GAAG,GAAG,SAAS,OAAO;AAC3B,WAAK,GAAG,GAAG,SAAS,OAAO;AAAA,IAC7B,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,WAA4B;AACxC,UAAM,UAAU,IAAI,QAAQ,MAAM,SAAS;AAC3C,SAAK,SAAS,IAAI,WAAW,OAAO;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,WAAmB;AAC/B,SAAK,SAAS,OAAO,SAAS;AAAA,EAChC;AAAA,EAEA,GAAG,OAAe,SAAoC;AACpD,SAAK,QAAQ,GAAG,OAAO,OAAO;AAAA,EAChC;AAAA,EAEA,MAAM,KAAkB,QAAgB,SAAkC,CAAC,GAAG,WAAgC;AAC5G,UAAM,KAAK,YAAY;AACvB,UAAM,KAAK,EAAE,KAAK;AAClB,UAAM,UAAU,YAAY,EAAE,IAAI,QAAQ,QAAQ,UAAU,IAAI,EAAE,IAAI,QAAQ,OAAO;AACrF,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,UAAU,IAAI,QAAW,CAAC,SAAS,WAAW;AAClD,WAAK,UAAU,IAAI,IAAI,EAAE,SAA8C,QAAQ,QAAQ,MAAM,CAAC;AAAA,IAChG,CAAC;AACD,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,MAAM,YAAY,MAAM;AAAA,IACtC;AACA,SAAK,GAAG,KAAK,KAAK,UAAU,OAAO,CAAC;AACpC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ;AACZ,QAAI,KAAK,GAAG,eAAe,UAAU,QAAQ;AAC3C;AAAA,IACF;AACA,UAAM,IAAI,QAAc,CAAC,YAAY;AACnC,WAAK,GAAG,KAAK,SAAS,MAAM,QAAQ,CAAC;AACrC,UAAI,KAAK,GAAG,eAAe,UAAU,SAAS;AAC5C;AAAA,MACF;AACA,WAAK,GAAG,MAAM;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEQ,QAAQ,KAAc;AAC5B,SAAK,OAAO,MAAM,oBAAoB,GAAG;AAAA,EAC3C;AAAA,EAEQ,QAAQ,MAAc,QAAgB;AAC5C,QAAI,KAAK,QAAQ;AACf;AAAA,IACF;AACA,SAAK,SAAS;AACd,UAAM,aAAa,OAAO,SAAS,KAAK;AACxC,SAAK,YAAY,IAAI,MAAM,sBAAsB,IAAI,MAAM,UAAU,EAAE,CAAC;AACxE,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA,EAEQ,YAAY,OAAc;AAChC,QAAI,KAAK,UAAU,SAAS,GAAG;AAC7B;AAAA,IACF;AACA,eAAW,CAAC,EAAE,QAAQ,KAAK,KAAK,WAAW;AACzC,eAAS,OAAO,KAAK;AAAA,IACvB;AACA,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEQ,UAAU,SAAiB;AACjC,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,OAAO;AAAA,IAC7B,SAAS,KAAK;AACZ,WAAK,OAAO,KAAK,+BAA+B,GAAG;AACnD;AAAA,IACF;AACA,QAAI,OAAO,OAAO,OAAO,UAAU;AACjC,YAAM,WAAW,KAAK,UAAU,IAAI,OAAO,EAAE;AAC7C,UAAI,CAAC,UAAU;AACb;AAAA,MACF;AACA,WAAK,UAAU,OAAO,OAAO,EAAE;AAC/B,YAAM,WAAW,KAAK,IAAI,IAAI,SAAS;AACvC,WAAK,OAAO,MAAM,YAAY,SAAS,QAAQ,GAAG,QAAQ,IAAI;AAC9D,UAAI,OAAO,OAAO;AAChB,iBAAS,OAAO,IAAI,MAAM,OAAO,MAAM,OAAO,CAAC;AAAA,MACjD,OAAO;AACL,iBAAS,QAAQ,OAAO,MAAM;AAAA,MAChC;AACA;AAAA,IACF;AAEA,QAAI,OAAO,WAAW;AACpB,YAAM,UAAU,KAAK,SAAS,IAAI,OAAO,SAAS;AAClD,UAAI,SAAS;AACX,gBAAQ,SAAS,OAAO,QAAQ,OAAO,MAAM;AAAA,MAC/C;AACA;AAAA,IACF;AAEA,QAAI,OAAO,QAAQ;AACjB,WAAK,QAAQ,KAAK,OAAO,QAAQ,OAAO,MAAM;AAAA,IAChD;AAAA,EACF;AACF;;;AEjKO,IAAM,iBAAN,MAAqB;AAAA,EAClB;AAAA,EACA;AAAA,EAER,YAAY,SAAkB,IAAY;AACxC,SAAK,UAAU;AACf,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,QAAQ;AACN,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,UAAU;AACd,WAAO,KAAK,QAAQ,QAAQ,EAAE,kBAAkB,KAAK,GAAG,CAAC;AAAA,EAC3D;AAAA,EAEA,MAAM,QAAQ;AACZ,UAAM,KAAK,QAAQ,eAAe,KAAK,EAAE;AAAA,EAC3C;AACF;AAEO,IAAM,UAAN,MAAc;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW,oBAAI,IAAY;AAAA,EAEnC,YAAY,YAAwB,OAAqB,QAAgB,QAA0B,eAAkC,CAAC,GAAG;AACvI,SAAK,aAAa;AAClB,SAAK,UAAU;AACf,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,eAAe;AAAA,EACtB;AAAA,EAEA,GAAG,OAA4E,SAAiC;AAC9G,SAAK,OAAO,GAAG,OAAO,OAAc;AAAA,EACtC;AAAA,EAEA,MAAM,aAAa;AACjB,UAAM,EAAE,iBAAiB,IAAI,MAAM,KAAK,WAAW,KAAmC,6BAA6B;AACnH,SAAK,SAAS,IAAI,gBAAgB;AAClC,WAAO,IAAI,eAAe,MAAM,gBAAgB;AAAA,EAClD;AAAA,EAEA,MAAM,QAAQ,UAAyC,CAAC,GAAG;AACzD,UAAM,EAAE,iBAAiB,IAAI;AAC7B,UAAM,EAAE,SAAS,IAAI,MAAM,KAAK,WAAW,KAA2B,uBAAuB;AAAA,MAC3F,KAAK;AAAA,MACL;AAAA,IACF,CAAC;AACD,UAAM,EAAE,UAAU,IAAI,MAAM,KAAK,WAAW,KAA4B,yBAAyB,EAAE,UAAU,SAAS,KAAK,CAAC;AAC5H,UAAM,UAAU,KAAK,WAAW,cAAc,SAAS;AACvD,UAAM,OAAO,IAAI,KAAK,SAAS,KAAK,QAAQ,KAAK,MAAM;AACvD,UAAM,KAAK,WAAW;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,WAAmB;AACtC,QAAI,CAAC,UAAW;AAChB,QAAI;AACF,YAAM,KAAK,WAAW,KAAK,gCAAgC,EAAE,kBAAkB,UAAU,CAAC;AAAA,IAC5F,QAAQ;AAAA,IAER;AACA,SAAK,SAAS,OAAO,SAAS;AAAA,EAChC;AAAA,EAEA,MAAM,QAAQ;AACZ,QAAI,KAAK,SAAS,OAAO,GAAG;AAC1B,iBAAW,aAAa,MAAM,KAAK,KAAK,QAAQ,GAAG;AACjD,cAAM,KAAK,eAAe,SAAS;AAAA,MACrC;AAAA,IACF;AACA,QAAI;AACF,YAAM,KAAK,WAAW,KAAK,eAAe;AAAA,IAC5C,QAAQ;AAAA,IAER;AACA,UAAM,KAAK,WAAW,MAAM;AAC5B,QAAI,CAAC,KAAK,QAAQ,QAAQ;AACxB,WAAK,QAAQ,KAAK;AAAA,IACpB;AACA,eAAW,QAAQ,KAAK,cAAc;AACpC,UAAI;AACF,aAAK;AAAA,MACP,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;;;ACrGA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,WAAW;AAClB,SAAS,aAAa;AACtB,OAAO,WAAW;AAKlB,IAAM,gBAAgB;AAEf,SAAS,eAAe,WAAW,QAAQ,UAAoB;AACpE,MAAI,aAAa,QAAS,QAAO;AACjC,MAAI,aAAa,SAAU,QAAO;AAClC,MAAI,aAAa,QAAS,QAAO;AACjC,QAAM,IAAI,MAAM,yBAAyB,QAAQ,EAAE;AACrD;AAEO,SAAS,eAAe,UAAoB;AACjD,MAAI,aAAa,QAAS,QAAO;AACjC,MAAI,aAAa,MAAO,QAAO;AAC/B,SAAO;AACT;AAEO,SAAS,iBAAiB,UAAoB;AACnD,MAAI,aAAa,OAAO;AACtB,UAAM,eAAe,QAAQ,IAAI,gBAAgB,KAAK,KAAK,GAAG,QAAQ,GAAG,WAAW,OAAO;AAC3F,WAAO,KAAK,KAAK,cAAc,WAAW;AAAA,EAC5C;AACA,SAAO,KAAK,KAAK,GAAG,QAAQ,GAAG,UAAU,WAAW;AACtD;AAEO,SAAS,iBAAiB,MAAc,QAAgB;AAC7D,QAAM,eAAe,KAAK,QAAQ,IAAI;AACtC,QAAM,iBAAiB,KAAK,QAAQ,MAAM;AAC1C,MAAI,mBAAmB,cAAc;AACnC;AAAA,EACF;AACA,MAAI,CAAC,eAAe,WAAW,eAAe,KAAK,GAAG,GAAG;AACvD,UAAM,IAAI,MAAM,4BAA4B,cAAc,EAAE;AAAA,EAC9D;AACF;AAEO,SAAS,+BAA+B,UAAoB;AACjE,MAAI,aAAa,QAAS,QAAO,KAAK,KAAK,gBAAgB,QAAQ;AACnE,MAAI,aAAa,MAAO,QAAO,KAAK,KAAK,cAAc,gBAAgB,YAAY,SAAS,UAAU;AACtG,SAAO,KAAK,KAAK,cAAc,YAAY;AAC7C;AAEA,SAAS,QAAQ,KAA2B;AAC1C,SAAO,IAAI,WAAW,SAAS,IAAI,OAAc;AACnD;AAEA,SAAS,sBAA8B;AACrC,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,UAAU,OAAO,KAAK,GAAG;AAC3B,WAAO,OAAO,KAAK,EAAE,QAAQ,QAAQ,EAAE;AAAA,EACzC;AACA,SAAO;AACT;AAEA,eAAsB,oBAAoB,UAAqC;AAC7E,QAAM,OAAO,oBAAoB;AACjC,QAAM,SAAS,eAAe,QAAQ;AACtC,QAAM,MAAM,GAAG,IAAI,IAAI,MAAM;AAC7B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAQ,GAAG,EAAE,IAAI,KAAK,CAAC,QAAQ;AAC7B,UAAI,IAAI,cAAc,IAAI,cAAc,KAAK;AAC3C,eAAO,IAAI,MAAM,gCAAgC,IAAI,UAAU,EAAE,CAAC;AAClE;AAAA,MACF;AACA,UAAI,OAAO;AACX,UAAI,GAAG,QAAQ,CAAC,UAAW,QAAQ,MAAM,SAAS,CAAE;AACpD,UAAI,GAAG,OAAO,MAAM,QAAQ,KAAK,KAAK,CAAC,CAAC;AAAA,IAC1C,CAAC,EAAE,GAAG,SAAS,MAAM;AAAA,EACvB,CAAC;AACH;AASA,eAAsB,iBAAiB,SAA0B;AAC/D,QAAM,EAAE,WAAW,UAAU,UAAU,OAAO,IAAI;AAClD,mBAAiB,WAAW,SAAS;AACrC,QAAM,cAAc,KAAK,KAAK,WAAW,QAAQ;AACjD,QAAM,cAAc,KAAK,KAAK,aAAa,QAAQ;AACnD,mBAAiB,WAAW,WAAW;AAEvC,QAAM,iBAAiB,KAAK,KAAK,aAAa,+BAA+B,QAAQ,CAAC;AACtF,QAAM,aAAa,KAAK,KAAK,aAAa,uBAAuB;AAEjE,MAAI,GAAG,WAAW,cAAc,KAAK,GAAG,WAAW,UAAU,GAAG;AAC9D,WAAO,EAAE,gBAAgB,YAAY;AAAA,EACvC;AAEA,KAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAE7C,QAAM,SAAS,eAAe,QAAQ;AACtC,QAAM,UAAU,aAAa,QAAQ,mBAAmB,aAAa,QAAQ,mBAAmB;AAEhG,QAAM,cAAc,QAAQ,IAAI,wBAAwB,KAAK;AAC7D,QAAM,OAAO,oBAAoB;AACjC,QAAM,cAAc,eAAe,GAAG,IAAI,IAAI,MAAM,IAAI,QAAQ,IAAI,OAAO;AAE3E,QAAM,cAAc,KAAK,KAAK,GAAG,OAAO,GAAG,aAAa,QAAQ,IAAI,QAAQ,MAAM;AAElF,SAAO,KAAK,iCAAiC,WAAW;AACxD,QAAM,aAAa,aAAa,aAAa,MAAM;AACnD,SAAO,KAAK,gCAAgC,WAAW;AACvD,QAAM,eAAe,aAAa,WAAW;AAC7C,KAAG,cAAc,aAAY,oBAAI,KAAK,GAAE,YAAY,CAAC;AACrD,KAAG,WAAW,WAAW;AAEzB,MAAI,CAAC,GAAG,WAAW,cAAc,GAAG;AAClC,UAAM,IAAI,MAAM,0CAA0C,cAAc,EAAE;AAAA,EAC5E;AACA,mBAAiB,gBAAgB,QAAQ;AAEzC,SAAO,EAAE,gBAAgB,YAAY;AACvC;AAEA,SAAS,aAAa,KAAa,MAAc,QAA+B;AAC9E,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,OAAO,GAAG,kBAAkB,IAAI;AACtC,YAAQ,GAAG,EAAE,IAAI,KAAK,CAAC,QAAQ;AAC7B,UAAI,IAAI,cAAc,IAAI,cAAc,KAAK;AAC3C,eAAO,IAAI,MAAM,uBAAuB,IAAI,UAAU,EAAE,CAAC;AACzD;AAAA,MACF;AACA,YAAM,QAAQ,OAAO,IAAI,QAAQ,gBAAgB,KAAK,CAAC;AACvD,UAAI,aAAa;AACjB,UAAI,oBAAoB;AACxB,UAAI,iBAAiB,KAAK,IAAI;AAC9B,UAAI,KAAK,IAAI;AACb,UAAI,GAAG,QAAQ,CAAC,UAAU;AACxB,sBAAc,MAAM;AACpB,YAAI,CAAC,OAAO;AACV,gBAAM,MAAM,KAAK,IAAI;AACrB,cAAI,MAAM,iBAAiB,KAAM;AAC/B,mBAAO,KAAK,qBAAqB,IAAI,cAAc,OAAO,OAAO,QAAQ,CAAC,CAAC,KAAK;AAChF,6BAAiB;AAAA,UACnB;AACA;AAAA,QACF;AACA,cAAM,UAAU,KAAK,MAAO,aAAa,QAAS,GAAG;AACrD,YAAI,WAAW,oBAAoB,GAAG;AACpC,iBAAO,KAAK,qBAAqB,GAAG,OAAO,GAAG;AAC9C,8BAAoB;AAAA,QACtB;AAAA,MACF,CAAC;AACD,WAAK,GAAG,UAAU,MAAM,KAAK,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA,IACrD,CAAC,EAAE,GAAG,SAAS,CAAC,QAAQ;AACtB,SAAG,OAAO,MAAM,MAAM,OAAO,GAAG,CAAC;AAAA,IACnC,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAsB,eAAe,SAAiB,SAAgC;AACpF,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,KAAK,SAAS,EAAE,aAAa,KAAK,GAAG,CAAC,KAAK,YAAY;AAC3D,UAAI,OAAO,CAAC,SAAS;AACnB,eAAO,OAAO,IAAI,MAAM,oBAAoB,CAAC;AAC7C;AAAA,MACF;AAEA,cAAQ,UAAU;AAClB,cAAQ,GAAG,SAAS,CAAC,UAAU;AAC7B,cAAM,YAAY,MAAM,SAAS,QAAQ,OAAO,GAAG;AACnD,cAAM,aAAa,KAAK,KAAK,SAAS,SAAS;AAC/C,YAAI;AACF,2BAAiB,SAAS,UAAU;AAAA,QACtC,SAAS,OAAO;AACd,kBAAQ,MAAM;AACd,iBAAO,KAAK;AACZ;AAAA,QACF;AAEA,YAAI,MAAM,KAAK,MAAM,QAAQ,GAAG;AAC9B,aAAG,UAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAC5C,kBAAQ,UAAU;AAClB;AAAA,QACF;AAEA,WAAG,UAAU,KAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAC1D,gBAAQ,eAAe,OAAO,CAAC,WAAW,eAAe;AACvD,cAAI,aAAa,CAAC,YAAY;AAC5B,oBAAQ,MAAM;AACd,mBAAO,aAAa,IAAI,MAAM,0BAA0B,CAAC;AACzD;AAAA,UACF;AACA,gBAAM,UAAU,MAAM,yBAA0B,MAAM,2BAA2B,KAAM,QAAS;AAChG,gBAAM,OAAO,UAAU,IAAI,UAAU;AACrC,gBAAM,cAAc,GAAG,kBAAkB,UAAU;AACnD,qBAAW,KAAK,WAAW;AAC3B,sBAAY,GAAG,SAAS,CAAC,aAAa;AACpC,oBAAQ,MAAM;AACd,mBAAO,QAAQ;AAAA,UACjB,CAAC;AACD,sBAAY,GAAG,SAAS,MAAM;AAC5B,gBAAI,QAAQ,QAAQ,KAAO;AACzB,kBAAI;AACF,mBAAG,UAAU,YAAY,IAAI;AAAA,cAC/B,QAAQ;AAAA,cAER;AAAA,YACF;AACA,oBAAQ,UAAU;AAAA,UACpB,CAAC;AAAA,QACH,CAAC;AAAA,MACH,CAAC;AAED,cAAQ,GAAG,OAAO,MAAM;AACtB,gBAAQ,MAAM;AACd,gBAAQ;AAAA,MACV,CAAC;AAED,cAAQ,GAAG,SAAS,CAAC,WAAW;AAC9B,gBAAQ,MAAM;AACd,eAAO,MAAM;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;AAEA,eAAsB,gBAAgB,gBAAyC;AAC7E,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,QAAQ,MAAM,gBAAgB,CAAC,WAAW,GAAG,EAAE,OAAO,CAAC,UAAU,QAAQ,MAAM,EAAE,CAAC;AACxF,QAAI,SAAS;AACb,UAAM,OAAO,GAAG,QAAQ,CAAC,UAAW,UAAU,MAAM,SAAS,CAAE;AAC/D,UAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,UAAI,SAAS,GAAG;AACd,gBAAQ,OAAO,KAAK,CAAC;AAAA,MACvB,OAAO;AACL,eAAO,IAAI,MAAM,mCAAmC,IAAI,EAAE,CAAC;AAAA,MAC7D;AAAA,IACF,CAAC;AACD,UAAM,GAAG,SAAS,MAAM;AAAA,EAC1B,CAAC;AACH;AAEA,SAAS,iBAAiB,gBAAwB,UAAoB;AACpE,MAAI,aAAa,OAAO;AACtB;AAAA,EACF;AACA,MAAI;AACF,UAAM,OAAO,GAAG,SAAS,cAAc;AACvC,UAAM,gBAAgB,KAAK,OAAO,QAAW;AAC7C,QAAI,CAAC,cAAc;AACjB,SAAG,UAAU,gBAAgB,GAAK;AAAA,IACpC;AAAA,EACF,QAAQ;AAAA,EAER;AACF;;;ACnQO,IAAM,kBAAkB;AAExB,SAAS,gBAAgB,aAAsB;AACpD,MAAI,eAAe,YAAY,KAAK,GAAG;AACrC,WAAO,YAAY,KAAK;AAAA,EAC1B;AACA,SAAO;AACT;;;AP+BO,IAAM,kBAAN,MAAsB;AAAA,EACnB;AAAA,EAER,YAAY,QAAiB;AAC3B,UAAM,WAAY,QAAQ,IAAI,uBAAgD;AAC9E,SAAK,SAAS,UAAU,IAAI,OAAO,QAAQ;AAAA,EAC7C;AAAA,EAEA,YAAY;AACV,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,MAAM,SAAS,UAA2B,CAAC,GAA8B;AACvE,UAAM,WAAW,eAAe;AAChC,UAAM,YAAY,KAAK,iBAAiB,QAAQ;AAChD,UAAM,qBAAqB,QAAQ,IAAI;AACvC,QAAI,WAAW,QAAQ,SAAS,MAAM,oBAAoB,QAAQ,IAAI,gBAAgB,QAAQ,IAAI,kBAAkB;AACpH,QAAI;AACJ,QAAI,cAAc;AAClB,QAAI,oBAAoB;AACtB,uBAAiBC,MAAK,QAAQ,kBAAkB;AAAA,IAClD,OAAO;AACL,YAAM,aAAa,MAAM,iBAAiB;AAAA,QACxC;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,KAAK;AAAA,MACf,CAAC;AACD,uBAAiB,WAAW;AAC5B,oBAAc,WAAW;AAAA,IAC3B;AAEA,QAAI,CAACC,IAAG,WAAW,cAAc,GAAG;AAClC,YAAM,IAAI,MAAM,kCAAkC,cAAc,EAAE;AAAA,IACpE;AAEA,UAAM,UAAU,MAAM,gBAAgB,cAAc;AAEpD,SAAK,OAAO,KAAK,uBAAuB,SAAS;AACjD,SAAK,OAAO,KAAK,YAAY,QAAQ;AACrC,SAAK,OAAO,KAAK,YAAY,QAAQ;AACrC,SAAK,OAAO,KAAK,oBAAoB,OAAO;AAE5C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,IACnB;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,UAAyB,CAAC,GAAG;AACxC,UAAM,SAAS,KAAK;AACpB,QAAI,QAAQ,UAAU;AACpB,aAAO,SAAS,QAAQ,QAAQ;AAAA,IAClC;AAEA,UAAM,iBAAiB,QAAQ,kBAAkB,QAAQ,IAAI;AAC7D,QAAI,qBAAqB;AACzB,QAAI,CAAC,oBAAoB;AACvB,YAAM,WAAW,eAAe;AAChC,YAAM,YAAY,KAAK,iBAAiB,QAAQ;AAChD,YAAM,WAAW,gBAAgB,QAAQ,IAAI,kBAAkB;AAC/D,YAAM,aAAa,MAAM,iBAAiB;AAAA,QACxC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AACD,2BAAqB,WAAW;AAAA,IAClC;AAEA,QAAI,CAAC,sBAAsB,CAACA,IAAG,WAAW,kBAAkB,GAAG;AAC7D,YAAM,IAAI,MAAM,kCAAkC,kBAAkB,EAAE;AAAA,IACxE;AACA,UAAM,QAAQA,IAAG,SAAS,kBAAkB;AAC5C,QAAI,CAAC,MAAM,OAAO,GAAG;AACnB,YAAM,IAAI,MAAM,sCAAsC,kBAAkB,EAAE;AAAA,IAC5E;AACA,IAAAC,kBAAiB,kBAAkB;AAEnC,UAAM,eAAkC,CAAC;AACzC,QAAI,cAAc,QAAQ,eAAe,QAAQ,IAAI;AACrD,QAAI,CAAC,aAAa;AAChB,oBAAcD,IAAG,YAAYD,MAAK,KAAKG,IAAG,OAAO,GAAG,YAAY,CAAC;AACjE,mBAAa,KAAK,MAAMF,IAAG,OAAO,aAAuB,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,IAC5F;AAEA,UAAM,OAAO;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,aAAa;AACf,WAAK,KAAK,mBAAmB,WAAW,EAAE;AAAA,IAC5C;AACA,QAAI,QAAQ,aAAa,SAAS;AAChC,WAAK,KAAK,4BAA4B,oBAAoB;AAAA,IAC5D;AACA,QAAI,QAAQ,YAAY,MAAM;AAC5B,WAAK,KAAK,gBAAgB;AAAA,IAC5B;AACA,QAAI,QAAQ,UAAU;AACpB,WAAK,KAAK,mBAAmB;AAAA,IAC/B;AACA,QAAI,QAAQ,MAAM;AAChB,WAAK,KAAK,GAAG,QAAQ,IAAI;AAAA,IAC3B;AAEA,WAAO,KAAK,sBAAsB,kBAAkB;AACpD,UAAM,QAAQG,OAAM,oBAAoB,MAAM,EAAE,OAAO,CAAC,UAAU,QAAQ,MAAM,EAAE,CAAC;AAEnF,UAAM,eAAe,MAAM,yBAAyB,OAAO,QAAQ,QAAQ,aAAa,GAAM;AAC9F,UAAM,UAAU,iBAAiB,YAAY;AAC7C,UAAM,aAAa,MAAM,0BAA0B,OAAO;AAE1D,UAAM,aAAa,IAAI,WAAW,YAAY,MAAM;AACpD,UAAM,kBAAkB,YAAY,MAAM;AAC1C,UAAM,SAAS,IAAI,iBAAiB;AACpC,UAAM,YAAY,eAAe,QAAQ,WAAW,QAAQ,IAAI,eAAe,IAAI;AACnF,UAAM,aAAa,eAAe,QAAQ,YAAY,QAAQ,IAAI,uBAAuB,IAAI;AAC7F,UAAM,gBAAgB,eAAe,QAAQ,eAAe,QAAQ,IAAI,0BAA0B,IAAI;AACtG,QAAI,aAAa,YAAY;AAC3B,aAAO,GAAG,cAAc,CAAC,YAAY;AACnC,cAAM,WAAW,QAAQ,YAAY,SAAY,QAAQ;AACzD,cAAMC,QAAO,aAAa,UAAU,QAAQ,UAAU;AACtD,eAAO,KAAK,UAAU,QAAQ,IAAI,IAAI,GAAGA,KAAI;AAAA,MAC/C,CAAC;AAAA,IACH;AACA,QAAI,aAAa,eAAe;AAC9B,aAAO,GAAG,iBAAiB,CAAC,YAAY;AACtC,cAAMA,QAAO,aAAa,QAAQ,UAAU,QAAQ,UAAU;AAC9D,eAAO,KAAK,aAAa,QAAQ,IAAI,IAAI,GAAGA,KAAI;AAAA,MAClD,CAAC;AAAA,IACH;AACA,UAAM,UAAU,IAAI,QAAQ,YAAY,OAAO,QAAQ,QAAQ,YAAY;AAE3E,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiB,UAAoB;AAC3C,UAAM,UAAU,QAAQ,IAAI;AAC5B,QAAI,WAAW,QAAQ,KAAK,GAAG;AAC7B,aAAOL,MAAK,QAAQ,QAAQ,KAAK,CAAC;AAAA,IACpC;AACA,WAAO,iBAAiB,QAAQ;AAAA,EAClC;AACF;AAEA,eAAe,kBAAkB,YAAwB,QAAgB;AACvE,MAAI;AACF,UAAM,UAAU,MAAM,WAAW,KAAiE,mBAAmB;AACrH,eAAW,QAAQ,QAAQ,aAAa;AACtC,UAAI,KAAK,SAAS,QAAQ;AACxB,cAAM,WAAW,KAAK,sBAAsB,EAAE,UAAU,KAAK,SAAS,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,KAAK,iCAAiC,GAAG;AAAA,EAClD;AACF;AAEA,SAAS,eAAe,UAA+B,UAA8B,cAAuB;AAC1G,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,YAAY,MAAM;AACpB,WAAO;AAAA,EACT;AACA,QAAM,aAAa,SAAS,KAAK,EAAE,YAAY;AAC/C,SAAO,CAAC,CAAC,KAAK,SAAS,MAAM,KAAK,EAAE,SAAS,UAAU;AACzD;AAEA,SAAS,aAAa,UAAmB,YAAqB;AAC5D,QAAM,OAAiB,CAAC;AACxB,MAAI,UAAU;AACZ,SAAK,KAAK,QAAQ;AAAA,EACpB;AACA,MAAI,OAAO,eAAe,UAAU;AAClC,SAAK,KAAK,GAAG,UAAU,IAAI;AAAA,EAC7B;AACA,SAAO;AACT;AAEA,SAASE,kBAAiB,gBAAwB;AAChD,MAAI,QAAQ,aAAa,SAAS;AAChC;AAAA,EACF;AACA,MAAI;AACF,UAAM,OAAOD,IAAG,SAAS,cAAc;AACvC,UAAM,gBAAgB,KAAK,OAAO,QAAW;AAC7C,QAAI,CAAC,cAAc;AACjB,MAAAA,IAAG,UAAU,gBAAgB,GAAK;AAAA,IACpC;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,QAAM,MAAMD,MAAK,QAAQ,cAAc;AACvC,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,aAAW,QAAQ,SAAS;AAC1B,UAAM,aAAaA,MAAK,KAAK,KAAK,IAAI;AACtC,QAAI,CAACC,IAAG,WAAW,UAAU,GAAG;AAC9B;AAAA,IACF;AACA,QAAI;AACF,YAAM,OAAOA,IAAG,SAAS,UAAU;AACnC,YAAM,gBAAgB,KAAK,OAAO,QAAW;AAC7C,UAAI,CAAC,cAAc;AACjB,QAAAA,IAAG,UAAU,YAAY,GAAK;AAAA,MAChC;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,SAAS,yBAAyB,OAAiC,QAAgB,WAAoC;AACrH,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,UAAU,WAAW,MAAM;AAC/B,aAAO,IAAI,MAAM,yCAAyC,CAAC;AAAA,IAC7D,GAAG,SAAS;AAEZ,UAAM,cAAwB,CAAC;AAC/B,UAAM,aAAa,CAAC,SAAiB;AACnC,YAAM,OAAO,KAAK,SAAS;AAC3B,iBAAW,QAAQ,KAAK,MAAM,OAAO,GAAG;AACtC,YAAI,CAAC,KAAK,KAAK,EAAG;AAClB,oBAAY,KAAK,IAAI;AACrB,YAAI,YAAY,SAAS,IAAI;AAC3B,sBAAY,MAAM;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,CAAC,SAAiB;AAC/B,YAAM,OAAO,KAAK,SAAS;AAC3B,YAAM,QAAQ,KAAK,MAAM,uCAAuC;AAChE,UAAI,OAAO;AACT,qBAAa,OAAO;AACpB,gBAAQ;AACR,eAAO,KAAK,qBAAqB,MAAM,CAAC,CAAC;AACzC,gBAAQ,MAAM,CAAC,CAAC;AAAA,MAClB;AACA,iBAAW,IAAI;AAAA,IACjB;AAEA,UAAM,SAAS,CAAC,MAAqB,WAAkC;AACrE,cAAQ;AACR,YAAM,OAAO,YAAY,SAAS;AAAA;AAAA,EAAuB,YAAY,KAAK,IAAI,CAAC,KAAK;AACpF,aAAO,IAAI,MAAM,mCAAmC,QAAQ,MAAM,WAAW,UAAU,MAAM,GAAG,IAAI,EAAE,CAAC;AAAA,IACzG;AAEA,UAAM,UAAU,MAAM;AACpB,YAAM,QAAQ,IAAI,QAAQ,MAAM;AAChC,YAAM,QAAQ,IAAI,QAAQ,MAAM;AAChC,YAAM,IAAI,QAAQ,MAAM;AAAA,IAC1B;AAEA,UAAM,QAAQ,GAAG,QAAQ,MAAM;AAC/B,UAAM,QAAQ,GAAG,QAAQ,MAAM;AAC/B,UAAM,GAAG,QAAQ,MAAM;AAEvB,QAAI,KAAK,IAAI,IAAI,QAAQ,WAAW;AAClC,cAAQ;AAAA,IACV;AAAA,EACF,CAAC;AACH;AAEA,SAAS,iBAAiB,OAAe;AACvC,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,KAAK;AACzB,UAAM,OAAO,IAAI,QAAQ;AACzB,WAAO,oBAAoB,IAAI;AAAA,EACjC,QAAQ;AACN,UAAM,IAAI,MAAM,8BAA8B,KAAK,EAAE;AAAA,EACvD;AACF;AAEA,SAAS,0BAA0B,YAAqC;AACtE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,IAAAK,MAAK,IAAI,YAAY,CAAC,QAAQ;AAC5B,UAAI,IAAI,cAAc,IAAI,cAAc,KAAK;AAC3C,eAAO,IAAI,MAAM,kCAAkC,IAAI,UAAU,EAAE,CAAC;AACpE;AAAA,MACF;AACA,UAAI,OAAO;AACX,UAAI,GAAG,QAAQ,CAAC,UAAW,QAAQ,MAAM,SAAS,CAAE;AACpD,UAAI,GAAG,OAAO,MAAM;AAClB,YAAI;AACF,gBAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,cAAI,CAAC,OAAO,sBAAsB;AAChC,mBAAO,IAAI,MAAM,8BAA8B,CAAC;AAChD;AAAA,UACF;AACA,kBAAQ,OAAO,oBAAoB;AAAA,QACrC,SAAS,KAAK;AACZ,iBAAO,GAAG;AAAA,QACZ;AAAA,MACF,CAAC;AAAA,IACH,CAAC,EAAE,GAAG,SAAS,MAAM;AAAA,EACvB,CAAC;AACH;;;AQnVO,IAAM,YAAY;AAAA,EACvB,MAAM,OAAO,UAAkC,CAAC,GAAqB;AACnE,UAAM,UAAU,IAAI,gBAAgB,QAAQ,MAAM;AAClD,WAAO,QAAQ,OAAO,OAAO;AAAA,EAC/B;AACF;AAEO,IAAM,WAAW;","names":["fs","path","os","http","spawn","EventEmitter","EventEmitter","EventEmitter","path","fs","ensureExecutable","os","spawn","args","http"]}
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolstackhq/cdpwright",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Lightweight Chromium-only browser automation library using CDP",
5
5
  "type": "module",
6
6
  "bin": {