@toolstackhq/cdpwright 1.2.0 → 1.3.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.
@@ -71,12 +71,40 @@ declare class AutomationEvents {
71
71
  emit<K extends keyof AutomationEventMap>(event: K, payload: AutomationEventMap[K]): void;
72
72
  }
73
73
 
74
- type LocatorOptions = {};
74
+ type SelectorLocatorOptions = {
75
+ pierceShadowDom?: boolean;
76
+ timeoutMs?: number;
77
+ };
78
+ type TextLocatorOptions$1 = {
79
+ exact?: boolean;
80
+ timeoutMs?: number;
81
+ };
82
+ type RoleLocatorOptions$1 = {
83
+ name?: string | RegExp;
84
+ exact?: boolean;
85
+ includeHidden?: boolean;
86
+ timeoutMs?: number;
87
+ };
88
+ type LocatorQuery = {
89
+ kind: "selector";
90
+ selector: string;
91
+ options?: SelectorLocatorOptions;
92
+ } | {
93
+ kind: "text";
94
+ text: string | RegExp;
95
+ options?: TextLocatorOptions$1;
96
+ } | {
97
+ kind: "role";
98
+ role: string;
99
+ options?: RoleLocatorOptions$1;
100
+ };
75
101
  declare class Locator {
76
102
  private frame;
77
- private selector;
78
- private options;
79
- constructor(frame: Frame, selector: string, options?: LocatorOptions);
103
+ private query;
104
+ constructor(frame: Frame, query: LocatorQuery);
105
+ getEvents(): AutomationEvents;
106
+ getFrameId(): string;
107
+ describe(): string;
80
108
  click(options?: {
81
109
  timeoutMs?: number;
82
110
  }): Promise<void>;
@@ -87,13 +115,35 @@ declare class Locator {
87
115
  timeoutMs?: number;
88
116
  }): Promise<void>;
89
117
  exists(): Promise<boolean>;
118
+ isVisible(): Promise<boolean | null>;
119
+ isEnabled(): Promise<boolean | null>;
120
+ isChecked(): Promise<boolean | null>;
90
121
  text(): Promise<string | null>;
122
+ value(): Promise<string | null>;
123
+ attribute(name: string): Promise<string | null>;
124
+ classes(): Promise<string[] | null>;
125
+ css(property: string): Promise<string | null>;
126
+ hasFocus(): Promise<boolean | null>;
127
+ isInViewport(fully?: boolean): Promise<boolean | null>;
128
+ isEditable(): Promise<boolean | null>;
129
+ count(): Promise<number>;
130
+ private queryTimeoutOptions;
91
131
  }
92
132
 
93
133
  type FrameSelectorOptions = {
94
134
  pierceShadowDom?: boolean;
95
135
  timeoutMs?: number;
96
136
  };
137
+ type TextLocatorOptions = {
138
+ exact?: boolean;
139
+ timeoutMs?: number;
140
+ };
141
+ type RoleLocatorOptions = {
142
+ name?: string | RegExp;
143
+ exact?: boolean;
144
+ includeHidden?: boolean;
145
+ timeoutMs?: number;
146
+ };
97
147
  type ClickOptions = {
98
148
  timeoutMs?: number;
99
149
  };
@@ -123,12 +173,15 @@ declare class Frame {
123
173
  url?: string;
124
174
  parentId?: string;
125
175
  }): void;
176
+ getEvents(): AutomationEvents;
126
177
  evaluate<T = unknown>(fnOrString: string | ((...args: any[]) => any), ...args: any[]): Promise<T>;
127
178
  query(selector: string, options?: FrameSelectorOptions): Promise<QueryResult | null>;
128
179
  queryAll(selector: string, options?: FrameSelectorOptions): Promise<QueryResult[]>;
129
180
  queryXPath(selector: string, options?: FrameSelectorOptions): Promise<QueryResult | null>;
130
181
  queryAllXPath(selector: string, options?: FrameSelectorOptions): Promise<QueryResult[]>;
131
182
  locator(selector: string, options?: FrameSelectorOptions): Locator;
183
+ getByText(text: string | RegExp, options?: TextLocatorOptions): Locator;
184
+ getByRole(role: string, options?: RoleLocatorOptions): Locator;
132
185
  click(selector: string, options?: ClickOptions): Promise<void>;
133
186
  dblclick(selector: string, options?: ClickOptions): Promise<void>;
134
187
  type(selector: string, text: string, options?: TypeOptions): Promise<void>;
@@ -145,6 +198,22 @@ declare class Frame {
145
198
  private writeLocatorHtml;
146
199
  exists(selector: string, options?: FrameSelectorOptions): Promise<boolean>;
147
200
  isVisible(selector: string, options?: FrameSelectorOptions): Promise<boolean>;
201
+ clickLocator(query: LocatorQuery, options?: ClickOptions): Promise<void>;
202
+ dblclickLocator(query: LocatorQuery, options?: ClickOptions): Promise<void>;
203
+ typeLocator(query: LocatorQuery, text: string, options?: TypeOptions): Promise<void>;
204
+ existsLocator(query: LocatorQuery): Promise<boolean>;
205
+ isVisibleLocator(query: LocatorQuery): Promise<boolean | null>;
206
+ isEnabledLocator(query: LocatorQuery): Promise<boolean | null>;
207
+ isCheckedLocator(query: LocatorQuery): Promise<boolean | null>;
208
+ textLocator(query: LocatorQuery): Promise<string | null>;
209
+ valueLocator(query: LocatorQuery): Promise<string | null>;
210
+ attributeLocator(query: LocatorQuery, name: string): Promise<string | null>;
211
+ classesLocator(query: LocatorQuery): Promise<string[] | null>;
212
+ cssLocator(query: LocatorQuery, property: string): Promise<string | null>;
213
+ hasFocusLocator(query: LocatorQuery): Promise<boolean | null>;
214
+ isInViewportLocator(query: LocatorQuery, fully?: boolean): Promise<boolean | null>;
215
+ isEditableLocator(query: LocatorQuery): Promise<boolean | null>;
216
+ countLocator(query: LocatorQuery): Promise<number>;
148
217
  text(selector: string, options?: FrameSelectorOptions): Promise<string | null>;
149
218
  textSecure(selector: string, options?: FrameSelectorOptions): Promise<string | null>;
150
219
  selectOption(selector: string, value: string): Promise<void>;
@@ -162,6 +231,13 @@ declare class Frame {
162
231
  hasFocus(selector: string, options?: FrameSelectorOptions): Promise<boolean | null>;
163
232
  isInViewport(selector: string, options?: FrameSelectorOptions, fully?: boolean): Promise<boolean | null>;
164
233
  isEditable(selector: string, options?: FrameSelectorOptions): Promise<boolean | null>;
234
+ private performClickLocator;
235
+ private locatorDescription;
236
+ private resolveLocatorElementBox;
237
+ private evalOnLocator;
238
+ private buildLocatorExpression;
239
+ private serializeLocatorQuery;
240
+ private serializeTextQuery;
165
241
  private performClick;
166
242
  private resolveElementBox;
167
243
  private querySelectorInternal;
@@ -215,6 +291,16 @@ declare class Page {
215
291
  predicate?: (frame: Frame) => boolean;
216
292
  }): Frame | null;
217
293
  locator(selector: string): Locator;
294
+ getByText(text: string | RegExp, options?: {
295
+ exact?: boolean;
296
+ timeoutMs?: number;
297
+ }): Locator;
298
+ getByRole(role: string, options?: {
299
+ name?: string | RegExp;
300
+ exact?: boolean;
301
+ includeHidden?: boolean;
302
+ timeoutMs?: number;
303
+ }): Locator;
218
304
  goto(url: string, options?: GotoOptions): Promise<void>;
219
305
  query(selector: string): Promise<QueryResult | null>;
220
306
  queryAll(selector: string): Promise<QueryResult[]>;
@@ -264,13 +350,29 @@ declare class Page {
264
350
  type ExpectSelectorOptions = {
265
351
  timeoutMs?: number;
266
352
  };
353
+ type ExpectTarget = {
354
+ label: string;
355
+ frameId: string;
356
+ exists(): Promise<boolean>;
357
+ isVisible(): Promise<boolean | null>;
358
+ isEnabled(): Promise<boolean | null>;
359
+ isChecked(): Promise<boolean | null>;
360
+ text(): Promise<string | null>;
361
+ value(): Promise<string | null>;
362
+ attribute(name: string): Promise<string | null>;
363
+ count(): Promise<number>;
364
+ classes(): Promise<string[] | null>;
365
+ css(property: string): Promise<string | null>;
366
+ hasFocus(): Promise<boolean | null>;
367
+ isInViewport(fully?: boolean): Promise<boolean | null>;
368
+ isEditable(): Promise<boolean | null>;
369
+ };
267
370
  declare class ElementExpectation {
268
- private frame;
269
- private selector;
371
+ private target;
270
372
  private options;
271
373
  private negate;
272
374
  private events;
273
- constructor(frame: Frame, selector: string, options: ExpectSelectorOptions, negate: boolean, events: AutomationEvents);
375
+ constructor(target: ExpectTarget, options: ExpectSelectorOptions, negate: boolean, events: AutomationEvents);
274
376
  get not(): ElementExpectation;
275
377
  toExist(): Promise<void>;
276
378
  toBeVisible(): Promise<void>;
@@ -311,11 +413,13 @@ declare function expect(page: Page): {
311
413
  predicate?: (frame: Frame) => boolean;
312
414
  }) => ExpectFrame;
313
415
  };
416
+ declare function expect(locator: Locator): ElementExpectation;
314
417
 
315
418
  declare module "../core/Page.js" {
316
419
  interface Page {
317
420
  expect(): ReturnType<typeof expect>;
318
421
  expect(selector: string, options?: ExpectSelectorOptions): ElementExpectation;
422
+ expect(locator: Locator): ElementExpectation;
319
423
  find: {
320
424
  locators: (options?: {
321
425
  highlight?: boolean;
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-CLal_AQd.js';
2
- export { F as Frame, b as Locator, e as expect } from './expect-CLal_AQd.js';
1
+ import { C as Connection, L as Logger, A as AutomationEvents, P as Page, a as LogLevel } from './expect-Cd5SNFuF.js';
2
+ export { F as Frame, b as Locator, e as expect } from './expect-Cd5SNFuF.js';
3
3
  import { ChildProcess } from 'child_process';
4
4
 
5
5
  declare class BrowserContext {
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  Locator,
5
5
  Page,
6
6
  expect
7
- } from "./chunk-PDUS6BDZ.js";
7
+ } from "./chunk-EIAXMGD5.js";
8
8
 
9
9
  // src/browser/ChromiumManager.ts
10
10
  import fs2 from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolstackhq/cdpwright",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Lightweight Chromium-only browser automation library using CDP",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/assert/AssertionError.ts","../src/core/Waiter.ts","../src/core/Page.ts","../src/core/Frame.ts","../src/core/Selectors.ts","../src/core/ShadowDom.ts","../src/core/Locator.ts","../src/core/UrlGuard.ts","../src/assert/expect.ts"],"sourcesContent":["export class AssertionError extends Error {\n selector?: string;\n timeoutMs?: number;\n lastState?: unknown;\n\n constructor(message: string, options: { selector?: string; timeoutMs?: number; lastState?: unknown } = {}) {\n super(message);\n this.name = \"AssertionError\";\n this.selector = options.selector;\n this.timeoutMs = options.timeoutMs;\n this.lastState = options.lastState;\n }\n}\n","export type WaitForOptions = {\n timeoutMs?: number;\n intervalMs?: number;\n description?: string;\n};\n\nexport async function waitFor<T>(predicate: () => Promise<T> | T, options: WaitForOptions = {}): Promise<NonNullable<T>> {\n const timeoutMs = options.timeoutMs ?? 30_000;\n const intervalMs = options.intervalMs ?? 100;\n const start = Date.now();\n\n let lastError: unknown;\n while (Date.now() - start < timeoutMs) {\n try {\n const result = await predicate();\n if (result) {\n return result as NonNullable<T>;\n }\n } catch (err) {\n lastError = err;\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n\n const description = options.description ? ` (${options.description})` : \"\";\n const error = new Error(`Timeout after ${timeoutMs}ms${description}`);\n (error as Error & { cause?: unknown }).cause = lastError;\n throw error;\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { Session } from \"../cdp/Session.js\";\nimport { Logger } from \"../logging/Logger.js\";\nimport { AutomationEvents } from \"./Events.js\";\nimport { Frame } from \"./Frame.js\";\nimport { Locator } from \"./Locator.js\";\nimport { ensureAllowedUrl } from \"./UrlGuard.js\";\nimport { waitFor } from \"./Waiter.js\";\n\nexport type GotoOptions = {\n waitUntil?: \"domcontentloaded\" | \"load\";\n timeoutMs?: number;\n allowFileUrl?: boolean;\n};\n\nexport type ScreenshotOptions = {\n path?: string;\n format?: \"png\" | \"jpeg\";\n quality?: number;\n fullPage?: boolean;\n};\n\nexport type PdfOptions = {\n path?: string;\n landscape?: boolean;\n printBackground?: boolean;\n scale?: number;\n paperWidth?: number;\n paperHeight?: number;\n marginTop?: number;\n marginBottom?: number;\n marginLeft?: number;\n marginRight?: number;\n pageRanges?: string;\n preferCSSPageSize?: boolean;\n};\n\nfunction assertPdfBuffer(buffer: Buffer) {\n if (buffer.length < 5 || buffer.subarray(0, 5).toString(\"utf-8\") !== \"%PDF-\") {\n throw new Error(\"PDF generation failed: Chromium did not return a valid PDF\");\n }\n}\n\nexport class Page {\n private session: Session;\n private logger: Logger;\n private events: AutomationEvents;\n private framesById = new Map<string, Frame>();\n private mainFrameId?: string;\n private lifecycleEvents = new Map<string, Set<string>>();\n private defaultTimeout = 30_000;\n\n constructor(session: Session, logger: Logger, events: AutomationEvents) {\n this.session = session;\n this.logger = logger;\n this.events = events;\n }\n\n async initialize() {\n await this.session.send(\"Page.enable\");\n await this.session.send(\"DOM.enable\");\n await this.session.send(\"Runtime.enable\");\n await this.session.send(\"Network.enable\");\n await this.session.send(\"Page.setLifecycleEventsEnabled\", { enabled: true });\n\n this.session.on(\"Page.frameAttached\", (params) => this.onFrameAttached(params as any));\n this.session.on(\"Page.frameNavigated\", (params) => this.onFrameNavigated(params as any));\n this.session.on(\"Page.frameDetached\", (params) => this.onFrameDetached(params as any));\n this.session.on(\"Runtime.executionContextCreated\", (params) => this.onExecutionContextCreated(params as any));\n this.session.on(\"Runtime.executionContextDestroyed\", (params) => this.onExecutionContextDestroyed(params as any));\n this.session.on(\"Runtime.executionContextsCleared\", () => this.onExecutionContextsCleared());\n this.session.on(\"Page.lifecycleEvent\", (params) => this.onLifecycleEvent(params as any));\n\n const tree = await this.session.send<{ frameTree: { frame: { id: string; name?: string; url?: string; parentId?: string }; childFrames?: any[] } }>(\"Page.getFrameTree\");\n this.buildFrameTree(tree.frameTree);\n }\n\n frames() {\n return Array.from(this.framesById.values());\n }\n\n mainFrame() {\n if (!this.mainFrameId) {\n throw new Error(\"Main frame not initialized\");\n }\n const frame = this.framesById.get(this.mainFrameId);\n if (!frame) {\n throw new Error(\"Main frame missing\");\n }\n return frame;\n }\n\n frame(options: { name?: string; urlIncludes?: string; predicate?: (frame: Frame) => boolean }) {\n for (const frame of this.framesById.values()) {\n if (options.name && frame.name !== options.name) continue;\n if (options.urlIncludes && !frame.url?.includes(options.urlIncludes)) continue;\n if (options.predicate && !options.predicate(frame)) continue;\n return frame;\n }\n return null;\n }\n\n locator(selector: string) {\n return new Locator(this.mainFrame(), selector);\n }\n\n async goto(url: string, options: GotoOptions = {}) {\n ensureAllowedUrl(url, { allowFileUrl: options.allowFileUrl });\n const waitUntil = options.waitUntil ?? \"load\";\n const lifecycleName = waitUntil === \"domcontentloaded\" ? \"DOMContentLoaded\" : waitUntil === \"load\" ? \"load\" : null;\n if (!lifecycleName) {\n throw new Error(`Invalid waitUntil \"${waitUntil}\". Use \"load\" or \"domcontentloaded\".`);\n }\n const timeoutMs = options.timeoutMs ?? this.defaultTimeout;\n\n this.events.emit(\"action:start\", { name: \"goto\", selector: url, frameId: this.mainFrameId });\n const start = Date.now();\n // Clear any stale lifecycle state from prior navigations before issuing a new navigate.\n this.lifecycleEvents.clear();\n const navigation = await this.session.send<{ errorText?: string }>(\"Page.navigate\", { url });\n if (navigation?.errorText) {\n throw new Error(`Navigation failed: ${navigation.errorText}`);\n }\n await this.waitForLifecycle(this.mainFrameId, lifecycleName, timeoutMs);\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: \"goto\", selector: url, frameId: this.mainFrameId, durationMs: duration });\n this.logger.debug(\"Goto\", url, `${duration}ms`);\n }\n\n async query(selector: string) {\n return this.mainFrame().query(selector);\n }\n\n async queryAll(selector: string) {\n return this.mainFrame().queryAll(selector);\n }\n\n async queryXPath(selector: string) {\n return this.mainFrame().queryXPath(selector);\n }\n\n async queryAllXPath(selector: string) {\n return this.mainFrame().queryAllXPath(selector);\n }\n\n async click(selector: string, options?: { timeoutMs?: number }) {\n return this.mainFrame().click(selector, options);\n }\n\n async dblclick(selector: string, options?: { timeoutMs?: number }) {\n return this.mainFrame().dblclick(selector, options);\n }\n\n async type(selector: string, text: string, options?: { timeoutMs?: number }) {\n return this.mainFrame().type(selector, text, options);\n }\n\n async typeSecure(selector: string, text: string, options?: { timeoutMs?: number }) {\n return this.mainFrame().typeSecure(selector, text, options);\n }\n\n async fillInput(selector: string, value: string, options: { timeoutMs?: number } = {}) {\n return this.mainFrame().fillInput(selector, value, options);\n }\n\n async evaluate<T = unknown>(fnOrString: string | ((...args: any[]) => any), ...args: any[]): Promise<T> {\n return this.mainFrame().evaluate(fnOrString, ...args);\n }\n\n async textSecure(selector: string) {\n return this.mainFrame().textSecure(selector);\n }\n\n async valueSecure(selector: string) {\n return this.mainFrame().valueSecure(selector);\n }\n\n async selectOption(selector: string, value: string) {\n return this.mainFrame().selectOption(selector, value);\n }\n\n async setFileInput(selector: string, name: string, contents: string, options: { mimeType?: string } = {}) {\n return this.mainFrame().setFileInput(selector, name, contents, options);\n }\n\n async findLocators(options: { highlight?: boolean } = {}) {\n return this.mainFrame().findLocators(options);\n }\n\n async content(): Promise<string> {\n await this.waitForLoad();\n return this.mainFrame().evaluate<string>(() => {\n const doctype = document.doctype;\n const doctypeText = doctype\n ? `<!DOCTYPE ${doctype.name}${doctype.publicId ? ` PUBLIC \"${doctype.publicId}\"` : \"\"}${doctype.systemId ? ` \"${doctype.systemId}\"` : \"\"}>`\n : \"<!doctype html>\";\n return `${doctypeText}\\n${document.documentElement.outerHTML}`;\n });\n }\n\n async screenshot(options: ScreenshotOptions = {}) {\n const start = Date.now();\n this.events.emit(\"action:start\", { name: \"screenshot\", frameId: this.mainFrameId });\n await this.waitForLoad();\n const result = await this.session.send<{ data: string }>(\"Page.captureScreenshot\", {\n format: options.format ?? \"png\",\n quality: options.quality,\n fromSurface: true,\n captureBeyondViewport: options.fullPage ?? false\n });\n const buffer = Buffer.from(result.data, \"base64\");\n if (options.path) {\n const resolved = path.resolve(options.path);\n fs.writeFileSync(resolved, buffer);\n }\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: \"screenshot\", frameId: this.mainFrameId, durationMs: duration });\n return buffer;\n }\n\n async screenshotBase64(options: Omit<ScreenshotOptions, \"path\"> = {}) {\n const start = Date.now();\n this.events.emit(\"action:start\", { name: \"screenshotBase64\", frameId: this.mainFrameId });\n await this.waitForLoad();\n const result = await this.session.send<{ data: string }>(\"Page.captureScreenshot\", {\n format: options.format ?? \"png\",\n quality: options.quality,\n fromSurface: true,\n captureBeyondViewport: options.fullPage ?? false\n });\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: \"screenshotBase64\", frameId: this.mainFrameId, durationMs: duration });\n return result.data;\n }\n\n async pdf(options: PdfOptions = {}): Promise<Buffer> {\n const start = Date.now();\n this.events.emit(\"action:start\", { name: \"pdf\", frameId: this.mainFrameId });\n await this.waitForLoad();\n await this.session.send(\"Emulation.setEmulatedMedia\", { media: \"screen\" });\n let buffer: Buffer;\n try {\n const result = await this.session.send<{ data: string }>(\"Page.printToPDF\", {\n landscape: options.landscape ?? false,\n printBackground: options.printBackground ?? true,\n scale: options.scale,\n paperWidth: options.paperWidth,\n paperHeight: options.paperHeight,\n marginTop: options.marginTop,\n marginBottom: options.marginBottom,\n marginLeft: options.marginLeft,\n marginRight: options.marginRight,\n pageRanges: options.pageRanges,\n preferCSSPageSize: options.preferCSSPageSize,\n });\n buffer = Buffer.from(result.data, \"base64\");\n assertPdfBuffer(buffer);\n if (options.path) {\n const resolved = path.resolve(options.path);\n fs.writeFileSync(resolved, buffer);\n }\n } finally {\n try {\n await this.session.send(\"Emulation.setEmulatedMedia\", { media: \"\" });\n } catch {\n // ignore reset failures\n }\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: \"pdf\", frameId: this.mainFrameId, durationMs: duration });\n }\n return buffer!;\n }\n\n getEvents() {\n return this.events;\n }\n\n getDefaultTimeout() {\n return this.defaultTimeout;\n }\n\n async waitForLoad(timeoutMs: number = this.defaultTimeout) {\n const frame = this.mainFrame();\n await waitFor(async () => {\n const readyState = await frame.evaluate<string>(\"document.readyState\");\n return readyState === \"complete\";\n }, { timeoutMs, description: \"page load\" });\n }\n\n private buildFrameTree(tree: { frame: { id: string; name?: string; url?: string; parentId?: string }; childFrames?: any[] }) {\n const frame = this.ensureFrame(tree.frame.id);\n frame.setMeta({ name: tree.frame.name, url: tree.frame.url, parentId: tree.frame.parentId });\n if (!tree.frame.parentId) {\n this.mainFrameId = tree.frame.id;\n }\n if (tree.childFrames) {\n for (const child of tree.childFrames) {\n this.buildFrameTree(child);\n }\n }\n }\n\n private ensureFrame(id: string) {\n let frame = this.framesById.get(id);\n if (!frame) {\n frame = new Frame(id, this.session, this.logger, this.events);\n this.framesById.set(id, frame);\n }\n return frame;\n }\n\n private onFrameAttached(params: { frameId: string; parentFrameId?: string }) {\n const frame = this.ensureFrame(params.frameId);\n frame.setMeta({ parentId: params.parentFrameId });\n }\n\n private onFrameNavigated(params: { frame: { id: string; name?: string; url?: string; parentId?: string } }) {\n const frame = this.ensureFrame(params.frame.id);\n frame.setMeta({ name: params.frame.name, url: params.frame.url, parentId: params.frame.parentId });\n if (!params.frame.parentId) {\n this.mainFrameId = params.frame.id;\n }\n }\n\n private onFrameDetached(params: { frameId: string }) {\n this.framesById.delete(params.frameId);\n }\n\n private onExecutionContextCreated(params: { context: { id: number; auxData?: { frameId?: string } } }) {\n const frameId = params.context.auxData?.frameId;\n if (!frameId) {\n return;\n }\n const frame = this.ensureFrame(frameId);\n frame.setExecutionContext(params.context.id);\n }\n\n private onExecutionContextDestroyed(params: { executionContextId: number }) {\n for (const frame of this.framesById.values()) {\n if (frame.getExecutionContext() === params.executionContextId) {\n frame.setExecutionContext(undefined);\n }\n }\n }\n\n private onExecutionContextsCleared() {\n for (const frame of this.framesById.values()) {\n frame.setExecutionContext(undefined);\n }\n }\n\n private onLifecycleEvent(params: { frameId: string; name: string }) {\n if (!this.lifecycleEvents.has(params.frameId)) {\n this.lifecycleEvents.set(params.frameId, new Set());\n }\n this.lifecycleEvents.get(params.frameId)!.add(params.name);\n }\n\n private async waitForLifecycle(frameId: string | undefined, eventName: string, timeoutMs: number) {\n if (!frameId) {\n throw new Error(\"Missing frame id for lifecycle wait\");\n }\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const events = this.lifecycleEvents.get(frameId);\n if (events && events.has(eventName)) {\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n throw new Error(`Timeout waiting for lifecycle event: ${eventName}`);\n }\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport { Session } from \"../cdp/Session.js\";\nimport { Logger } from \"../logging/Logger.js\";\nimport { AutomationEvents } from \"./Events.js\";\nimport { waitFor } from \"./Waiter.js\";\nimport { parseSelector } from \"./Selectors.js\";\nimport { serializeShadowDomHelpers } from \"./ShadowDom.js\";\nimport { Locator } from \"./Locator.js\";\n\nexport type FrameSelectorOptions = {\n pierceShadowDom?: boolean;\n timeoutMs?: number;\n};\n\nexport type ClickOptions = {\n timeoutMs?: number;\n};\n\nexport type TypeOptions = {\n timeoutMs?: number;\n sensitive?: boolean;\n};\n\nexport type QueryResult = {\n objectId: string;\n contextId: number;\n};\n\ntype ElementBox = {\n x: number;\n y: number;\n width: number;\n height: number;\n visible: boolean;\n};\n\nexport class Frame {\n readonly id: string;\n name?: string;\n url?: string;\n parentId?: string;\n private session: Session;\n private logger: Logger;\n private events: AutomationEvents;\n private contextId?: number;\n private defaultTimeout = 30_000;\n\n constructor(id: string, session: Session, logger: Logger, events: AutomationEvents) {\n this.id = id;\n this.session = session;\n this.logger = logger;\n this.events = events;\n }\n\n setExecutionContext(contextId?: number) {\n this.contextId = contextId;\n }\n\n getExecutionContext() {\n return this.contextId;\n }\n\n setMeta(meta: { name?: string; url?: string; parentId?: string }) {\n this.name = meta.name;\n this.url = meta.url;\n this.parentId = meta.parentId;\n }\n\n async evaluate<T = unknown>(fnOrString: string | ((...args: any[]) => any), ...args: any[]): Promise<T> {\n return this.evaluateInContext(fnOrString, args);\n }\n\n async query(selector: string, options: FrameSelectorOptions = {}): Promise<QueryResult | null> {\n return this.querySelectorInternal(selector, options, false);\n }\n\n async queryAll(selector: string, options: FrameSelectorOptions = {}): Promise<QueryResult[]> {\n return this.querySelectorAllInternal(selector, options, false);\n }\n\n async queryXPath(selector: string, options: FrameSelectorOptions = {}): Promise<QueryResult | null> {\n return this.querySelectorInternal(selector, options, true);\n }\n\n async queryAllXPath(selector: string, options: FrameSelectorOptions = {}): Promise<QueryResult[]> {\n return this.querySelectorAllInternal(selector, options, true);\n }\n\n locator(selector: string, options: FrameSelectorOptions = {}) {\n return new Locator(this, selector, options);\n }\n\n async click(selector: string, options: ClickOptions = {}) {\n await this.performClick(selector, options, false);\n }\n\n async dblclick(selector: string, options: ClickOptions = {}) {\n await this.performClick(selector, options, true);\n }\n\n async type(selector: string, text: string, options: TypeOptions = {}) {\n const start = Date.now();\n const parsed = parseSelector(selector);\n const pierce = Boolean(parsed.pierceShadowDom);\n this.events.emit(\"action:start\", { name: \"type\", selector, frameId: this.id, sensitive: options.sensitive });\n await waitFor(async () => {\n const box = await this.resolveElementBox(selector, options);\n if (!box || !box.visible) {\n return false;\n }\n return true;\n }, { timeoutMs: options.timeoutMs ?? this.defaultTimeout, description: `type ${selector}` });\n\n const helpers = serializeShadowDomHelpers();\n const focusExpression = `(function() {\n const querySelectorDeep = ${helpers.querySelectorDeep};\n const root = document;\n const selector = ${JSON.stringify(selector)};\n const el = ${pierce ? \"querySelectorDeep(root, selector)\" : \"root.querySelector(selector)\"};\n if (!el) {\n return;\n }\n el.focus();\n })()`;\n const focusParams: Record<string, unknown> = {\n expression: focusExpression,\n returnByValue: true\n };\n if (this.contextId) {\n focusParams.contextId = this.contextId;\n }\n await this.session.send(\"Runtime.evaluate\", focusParams);\n\n await this.session.send(\"Input.insertText\", { text });\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: \"type\", selector, frameId: this.id, durationMs: duration, sensitive: options.sensitive });\n this.logger.debug(\"Type\", selector, `${duration}ms`);\n }\n\n async typeSecure(selector: string, text: string, options: TypeOptions = {}) {\n return this.type(selector, text, { ...options, sensitive: true });\n }\n\n async fillInput(selector: string, value: string, options: { timeoutMs?: number } = {}) {\n const start = Date.now();\n this.events.emit(\"action:start\", { name: \"fillInput\", selector, frameId: this.id });\n await waitFor(async () => {\n const expression = `(function() {\n const selector = ${JSON.stringify(selector)};\n const findDeep = (sel) => {\n if (sel.includes(\">>>\")) {\n const parts = sel.split(\">>>\").map((s) => s.trim()).filter(Boolean);\n let scope = [document];\n for (const part of parts) {\n const next = [];\n for (const node of scope) {\n const roots = [node];\n if (node instanceof Element && node.shadowRoot) roots.push(node.shadowRoot);\n for (const root of roots) {\n next.push(...root.querySelectorAll(part));\n }\n }\n if (!next.length) return null;\n scope = next;\n }\n return scope[0] || null;\n }\n return document.querySelector(sel);\n };\n const el = findDeep(selector);\n if (!el) return false;\n if (!(el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement)) {\n return false;\n }\n el.value = ${JSON.stringify(value)};\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return true;\n })()`;\n const params: Record<string, unknown> = {\n expression,\n returnByValue: true\n };\n if (this.contextId) {\n params.contextId = this.contextId;\n }\n const result = await this.session.send<{ result: { value?: boolean } }>(\"Runtime.evaluate\", params);\n return Boolean(result.result?.value);\n }, { timeoutMs: options.timeoutMs ?? this.defaultTimeout, description: `fillInput ${selector}` });\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: \"fillInput\", selector, frameId: this.id, durationMs: duration });\n this.logger.debug(\"FillInput\", selector, `${duration}ms`);\n }\n\n async findLocators(options: { highlight?: boolean; outputPath?: string; outputJson?: string; outputHtml?: string } = {}) {\n const start = Date.now();\n this.events.emit(\"action:start\", { name: \"findLocators\", frameId: this.id });\n const artifactsDir = path.resolve(process.cwd(), \"artifacts\");\n try {\n fs.mkdirSync(artifactsDir, { recursive: true });\n } catch {\n // ignore dir creation errors\n }\n const resolveOut = (name?: string) => {\n if (!name) return null;\n const base = path.basename(name);\n return path.join(artifactsDir, base);\n };\n const outputJson = resolveOut(options.outputJson || options.outputPath);\n const outputHtml = resolveOut(options.outputHtml);\n const expression = `(function() {\n const highlight = ${options.highlight !== false};\n const previous = Array.from(document.querySelectorAll(\".__cdpwright-locator-overlay\"));\n previous.forEach((el) => el.remove());\n\n const cssEscape = (value) => {\n if (typeof CSS !== \"undefined\" && CSS.escape) return CSS.escape(value);\n return value.replace(/[^a-zA-Z0-9_-]/g, (c) => \"\\\\\\\\\" + c.charCodeAt(0).toString(16) + \" \");\n };\n\n const visible = (el) => {\n const rect = el.getBoundingClientRect();\n const style = window.getComputedStyle(el);\n return rect.width > 0 && rect.height > 0 && style.visibility !== \"hidden\" && style.display !== \"none\" && Number(style.opacity || \"1\") > 0;\n };\n\n const siblingsIndex = (el) => {\n if (!el.parentElement) return 1;\n const sibs = Array.from(el.parentElement.children).filter((n) => n.tagName === el.tagName);\n return sibs.indexOf(el) + 1;\n };\n\n const xpathFor = (el) => {\n const parts = [];\n let node = el;\n while (node && node.nodeType === 1 && node !== document.documentElement) {\n const idx = siblingsIndex(node);\n parts.unshift(node.tagName.toLowerCase() + \"[\" + idx + \"]\");\n node = node.parentElement;\n }\n return \"//\" + parts.join(\"/\");\n };\n\n const buildLocator = (el) => {\n const testid = el.getAttribute(\"data-testid\");\n const id = el.id;\n const name = el.getAttribute(\"name\");\n const aria = el.getAttribute(\"aria-label\");\n const labelledBy = el.getAttribute(\"aria-labelledby\");\n const placeholder = el.getAttribute(\"placeholder\");\n const role = el.getAttribute(\"role\");\n const labelText = (() => {\n if (labelledBy) {\n const ref = document.getElementById(labelledBy);\n if (ref) return ref.textContent?.trim() || \"\";\n }\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {\n const idRef = el.id && document.querySelector(\"label[for='\" + el.id.replace(/'/g, \"\\\\\\\\'\") + \"']\");\n if (idRef) return idRef.textContent?.trim() || \"\";\n const wrap = el.closest(\"label\");\n if (wrap) return wrap.textContent?.trim() || \"\";\n }\n return \"\";\n })();\n\n let css = \"\";\n let quality = \"low\";\n let reason = \"fallback\";\n if (testid) {\n css = \"[data-testid=\\\"\" + testid.replace(/\"/g, '\\\\\\\\\"') + \"\\\"]\";\n quality = \"high\";\n reason = \"data-testid\";\n } else if (id) {\n css = \"#\" + cssEscape(id);\n quality = \"high\";\n reason = \"id\";\n } else if (name) {\n css = \"[name=\\\"\" + name.replace(/\"/g, '\\\\\\\\\"') + \"\\\"]\";\n quality = \"ok\";\n reason = \"name\";\n } else if (aria) {\n css = \"[aria-label=\\\"\" + aria.replace(/\"/g, '\\\\\\\\\"') + \"\\\"]\";\n quality = \"ok\";\n reason = \"aria-label\";\n } else if (placeholder) {\n css = \"[placeholder=\\\"\" + placeholder.replace(/\"/g, '\\\\\\\\\"') + \"\\\"]\";\n quality = \"low\";\n reason = \"placeholder\";\n } else if (labelText) {\n css = el.tagName.toLowerCase() + \"[aria-label=\\\"\" + labelText.replace(/\"/g, '\\\\\\\\\"') + \"\\\"]\";\n quality = \"low\";\n reason = \"label text\";\n } else {\n const nth = siblingsIndex(el);\n css = el.tagName.toLowerCase() + \":nth-of-type(\" + nth + \")\";\n quality = \"low\";\n reason = \"nth-of-type\";\n }\n\n const tag = el.tagName.toLowerCase();\n const type = el.getAttribute(\"type\") || \"\";\n const text = (el.textContent || \"\").trim().slice(0, 80);\n\n return {\n name: labelText || aria || placeholder || name || testid || id || tag,\n css,\n xpath: xpathFor(el),\n quality,\n reason,\n visible: true,\n tag,\n type,\n role,\n text,\n id,\n nameAttr: name,\n dataTestid: testid\n };\n };\n\n const preferredSelectors = [\"input\", \"select\", \"textarea\", \"button\", \"a[href]\", \"[role='button']\", \"[contenteditable='true']\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"label\", \"legend\", \"fieldset\"];\n let nodes = Array.from(document.querySelectorAll(preferredSelectors.join(\", \")));\n if (nodes.length === 0) {\n nodes = Array.from(document.querySelectorAll(\"*\")).filter((el) => {\n if (!(el instanceof HTMLElement)) return false;\n const tag = el.tagName.toLowerCase();\n if (preferredSelectors.includes(tag)) return true;\n if (tag === \"a\" && el.hasAttribute(\"href\")) return true;\n if (el.getAttribute(\"role\") === \"button\") return true;\n if (el.hasAttribute(\"contenteditable\")) return true;\n return false;\n });\n }\n const results = [];\n nodes.forEach((el) => {\n const isVisible = visible(el);\n const locator = buildLocator(el);\n locator.visible = isVisible;\n results.push(locator);\n });\n\n if (highlight) {\n results.forEach((loc, index) => {\n const el = nodes[index];\n if (!el) return;\n const rect = el.getBoundingClientRect();\n const overlay = document.createElement(\"div\");\n overlay.className = \"__cdpwright-locator-overlay\";\n overlay.style.position = \"absolute\";\n overlay.style.left = rect.x + window.scrollX + \"px\";\n overlay.style.top = rect.y + window.scrollY + \"px\";\n overlay.style.width = rect.width + \"px\";\n overlay.style.height = rect.height + \"px\";\n overlay.style.border = \"2px solid #e67e22\";\n overlay.style.borderRadius = \"6px\";\n overlay.style.pointerEvents = \"none\";\n overlay.style.zIndex = \"99999\";\n const badge = document.createElement(\"div\");\n badge.textContent = String(index);\n badge.style.position = \"absolute\";\n badge.style.top = \"-10px\";\n badge.style.left = \"-10px\";\n badge.style.background = \"#e67e22\";\n badge.style.color = \"#fff\";\n badge.style.fontSize = \"12px\";\n badge.style.padding = \"2px 6px\";\n badge.style.borderRadius = \"10px\";\n overlay.appendChild(badge);\n document.body.appendChild(overlay);\n });\n }\n\n if (console && console.table) {\n console.table(results.map((r, idx) => ({ idx, name: r.name, css: r.css, quality: r.quality, reason: r.reason, tag: r.tag, type: r.type })));\n }\n return results;\n })()`;\n\n const params: Record<string, unknown> = {\n expression,\n returnByValue: true\n };\n if (this.contextId) {\n params.contextId = this.contextId;\n }\n let result = await this.session.send<{ result: { value?: any[] } }>(\"Runtime.evaluate\", params);\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: \"findLocators\", frameId: this.id, durationMs: duration });\n const value = (result.result?.value as any[]) ?? [];\n if (Array.isArray(value) && value.length > 0) {\n this.logger.info(\"FindLocators\", `${value.length} candidates`, value.slice(0, 5).map((v) => v.css || v.name || v.tag));\n if (outputJson) {\n try {\n fs.writeFileSync(outputJson, JSON.stringify(value, null, 2), \"utf-8\");\n this.logger.info(\"FindLocators\", `written to ${outputJson}`);\n } catch (err) {\n this.logger.warn(\"FindLocators write failed\", err);\n }\n }\n if (outputHtml) {\n this.writeLocatorHtml(outputHtml, value);\n }\n return value;\n }\n // Fallback: filtered scan to avoid empty results while ignoring document chrome\n result = await this.session.send<{ result: { value?: any[] } }>(\"Runtime.evaluate\", {\n expression: `(function() {\n const allowed = [\"input\",\"select\",\"textarea\",\"button\",\"a\",\"label\",\"legend\",\"fieldset\",\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\"];\n const skip = [\"html\",\"head\",\"body\",\"meta\",\"link\",\"script\",\"style\"];\n return Array.from(document.querySelectorAll(\"*\"))\n .filter((el) => {\n if (!(el instanceof HTMLElement)) return false;\n const tag = el.tagName.toLowerCase();\n if (skip.includes(tag)) return false;\n if (tag === \"a\" && el.hasAttribute(\"href\")) return true;\n if (el.getAttribute(\"role\") === \"button\") return true;\n if (el.hasAttribute(\"contenteditable\")) return true;\n return allowed.includes(tag);\n })\n .slice(0, 200)\n .map((el, idx) => ({\n name: el.getAttribute(\"aria-label\") || el.getAttribute(\"name\") || el.getAttribute(\"data-testid\") || el.id || el.tagName.toLowerCase() + \"-\" + idx,\n css: el.id ? \"#\" + el.id : el.getAttribute(\"data-testid\") ? \"[data-testid=\\\\\"\" + el.getAttribute(\"data-testid\") + \"\\\\\"]\" : el.tagName.toLowerCase(),\n xpath: \"\",\n quality: \"low\",\n reason: \"fallback\",\n visible: true,\n tag: el.tagName.toLowerCase(),\n type: el.getAttribute(\"type\") || \"\",\n role: el.getAttribute(\"role\") || \"\"\n }));\n })()`,\n returnByValue: true\n });\n const fallback = (result.result?.value as any[]) ?? [];\n this.logger.info(\"FindLocators\", `${fallback.length} candidates`, fallback.slice(0, 5).map((v) => v.css || v.name || v.tag));\n if (outputJson) {\n try {\n fs.writeFileSync(outputJson, JSON.stringify(fallback, null, 2), \"utf-8\");\n this.logger.info(\"FindLocators\", `written to ${outputJson}`);\n } catch (err) {\n this.logger.warn(\"FindLocators write failed\", err);\n }\n }\n if (outputHtml) {\n this.writeLocatorHtml(outputHtml, fallback);\n }\n return fallback;\n }\n\n private writeLocatorHtml(filePath: string, data: any[]) {\n const html = `<!doctype html>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <title>Locators</title>\n <style>\n body { font-family: \"Segoe UI\", system-ui, -apple-system, sans-serif; padding: 16px; background: #f8f9fa; color: #222; }\n h1 { font-size: 20px; margin-bottom: 12px; }\n table { border-collapse: collapse; width: 100%; background: #fff; box-shadow: 0 2px 6px rgba(0,0,0,0.08); }\n th, td { border: 1px solid #e5e7eb; padding: 8px; font-size: 13px; text-align: left; }\n th { background: linear-gradient(180deg, #f6f7fb, #edf0f7); font-weight: 600; }\n tr:nth-child(even) { background: #fafbfc; }\n .copy { color: #2563eb; text-decoration: underline dotted; cursor: pointer; font-size: 12px; background: none; border: none; padding: 0; opacity: 0; transition: opacity 0.15s ease; }\n tr:hover .copy { opacity: 1; }\n .copy:hover { color: #1d4ed8; }\n .loc-value { margin-left: 6px; font-family: ui-monospace, SFMono-Regular, SFMono, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }\n </style>\n</head>\n<body>\n <h1>Locator candidates</h1>\n <table>\n <thead>\n <tr><th>#</th><th>Name</th><th>CSS</th><th>XPath</th><th>Quality</th><th>Reason</th><th>Visible</th></tr>\n </thead>\n <tbody id=\"rows\"></tbody>\n </table>\n <script>\n const data = ${JSON.stringify(data)};\n const rows = document.getElementById(\"rows\");\n data.forEach((loc, idx) => {\n const tr = document.createElement(\"tr\");\n const cells = [\n idx,\n loc.name || \"\",\n loc.css || \"\",\n loc.xpath || \"\",\n loc.quality || \"\",\n loc.reason || \"\",\n String(loc.visible)\n ];\n cells.forEach((val, i) => {\n const td = document.createElement(\"td\");\n if (i === 2 || i === 3) {\n const link = document.createElement(\"button\");\n link.className = \"copy\";\n link.textContent = \"copy\";\n link.addEventListener(\"click\", async (e) => {\n e.preventDefault();\n try { await navigator.clipboard.writeText(val); link.textContent = \"copied\"; setTimeout(() => link.textContent = \"copy\", 1000); }\n catch { link.textContent = \"error\"; }\n });\n const span = document.createElement(\"span\");\n span.className = \"loc-value\";\n span.textContent = val;\n td.appendChild(link);\n td.appendChild(span);\n } else {\n td.textContent = val;\n }\n tr.appendChild(td);\n });\n rows.appendChild(tr);\n });\n </script>\n</body>\n</html>`;\n try {\n fs.writeFileSync(filePath, html, \"utf-8\");\n this.logger.info(\"FindLocators\", `HTML written to ${filePath}`);\n } catch (err) {\n this.logger.warn(\"FindLocators HTML write failed\", err);\n }\n }\n\n async exists(selector: string, options: FrameSelectorOptions = {}) {\n const handle = await this.query(selector, options);\n if (handle) {\n await this.releaseObject(handle.objectId);\n return true;\n }\n return false;\n }\n\n async isVisible(selector: string, options: FrameSelectorOptions = {}) {\n const box = await this.resolveElementBox(selector, options);\n return Boolean(box && box.visible);\n }\n\n async text(selector: string, options: FrameSelectorOptions = {}) {\n return this.evalOnSelector<string | null>(selector, options, false, `\n if (!el) {\n return null;\n }\n return el.textContent || \"\";\n `);\n }\n\n async textSecure(selector: string, options: FrameSelectorOptions = {}) {\n const start = Date.now();\n this.events.emit(\"action:start\", { name: \"text\", selector, frameId: this.id, sensitive: true });\n const result = await this.text(selector, options);\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: \"text\", selector, frameId: this.id, durationMs: duration, sensitive: true });\n return result;\n }\n\n async selectOption(selector: string, value: string) {\n await this.evaluate(\n (sel, val) => {\n const el = document.querySelector(sel);\n if (!(el instanceof HTMLSelectElement)) return false;\n el.value = val;\n el.dispatchEvent(new Event(\"input\", { bubbles: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return true;\n },\n selector,\n value\n );\n }\n\n async setFileInput(selector: string, name: string, contents: string, options: { mimeType?: string } = {}) {\n await this.evaluate(\n (sel, fileName, text, mime) => {\n const input = document.querySelector(sel);\n if (!(input instanceof HTMLInputElement)) return false;\n const file = new File([text], fileName, { type: mime || \"text/plain\" });\n const data = new DataTransfer();\n data.items.add(file);\n input.files = data.files;\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return true;\n },\n selector,\n name,\n contents,\n options.mimeType || \"text/plain\"\n );\n }\n\n async attribute(selector: string, name: string, options: FrameSelectorOptions = {}) {\n return this.evalOnSelector<string | null>(selector, options, false, `\n if (!el || !(el instanceof Element)) {\n return null;\n }\n return el.getAttribute(${JSON.stringify(name)});\n `);\n }\n\n async value(selector: string, options: FrameSelectorOptions = {}) {\n return this.evalOnSelector<string | null>(selector, options, false, `\n if (!el) {\n return null;\n }\n if (\"value\" in el) {\n return el.value ?? \"\";\n }\n return el.getAttribute(\"value\");\n `);\n }\n\n async valueSecure(selector: string, options: FrameSelectorOptions = {}) {\n const start = Date.now();\n this.events.emit(\"action:start\", { name: \"value\", selector, frameId: this.id, sensitive: true });\n const result = await this.value(selector, options);\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: \"value\", selector, frameId: this.id, durationMs: duration, sensitive: true });\n return result;\n }\n\n async isEnabled(selector: string, options: FrameSelectorOptions = {}) {\n return this.evalOnSelector<boolean | null>(selector, options, false, `\n if (!el) {\n return null;\n }\n const disabled = Boolean(el.disabled) || el.hasAttribute(\"disabled\");\n const ariaDisabled = el.getAttribute && el.getAttribute(\"aria-disabled\") === \"true\";\n return !(disabled || ariaDisabled);\n `);\n }\n\n async isChecked(selector: string, options: FrameSelectorOptions = {}) {\n return this.evalOnSelector<boolean | null>(selector, options, false, `\n if (!el) {\n return null;\n }\n const aria = el.getAttribute && el.getAttribute(\"aria-checked\");\n if (aria === \"true\") {\n return true;\n }\n if (aria === \"false\") {\n return false;\n }\n if (\"checked\" in el) {\n return Boolean(el.checked);\n }\n return null;\n `);\n }\n\n async count(selector: string, options: FrameSelectorOptions = {}) {\n const parsed = parseSelector(selector);\n const pierce = Boolean(parsed.pierceShadowDom);\n const helpers = serializeShadowDomHelpers();\n const expression = parsed.type === \"xpath\"\n ? `(function() {\n const result = document.evaluate(${JSON.stringify(parsed.value)}, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);\n return result.snapshotLength;\n })()`\n : `(function() {\n const querySelectorAllDeep = ${helpers.querySelectorAllDeep};\n const root = document;\n const selector = ${JSON.stringify(parsed.value)};\n const nodes = ${pierce ? \"querySelectorAllDeep(root, selector)\" : \"root.querySelectorAll(selector)\"};\n return nodes.length;\n })()`;\n\n const params: Record<string, unknown> = {\n expression,\n returnByValue: true\n };\n if (this.contextId) {\n params.contextId = this.contextId;\n }\n const result = await this.session.send<{ result: { value?: number } }>(\"Runtime.evaluate\", params);\n return result.result.value ?? 0;\n }\n\n async classes(selector: string, options: FrameSelectorOptions = {}) {\n return this.evalOnSelector<string[] | null>(selector, options, false, `\n if (!el) {\n return null;\n }\n if (!el.classList) {\n return [];\n }\n return Array.from(el.classList);\n `);\n }\n\n async css(selector: string, property: string, options: FrameSelectorOptions = {}) {\n return this.evalOnSelector<string | null>(selector, options, false, `\n if (!el) {\n return null;\n }\n const style = window.getComputedStyle(el);\n return style.getPropertyValue(${JSON.stringify(property)}) || \"\";\n `);\n }\n\n async hasFocus(selector: string, options: FrameSelectorOptions = {}) {\n return this.evalOnSelector<boolean | null>(selector, options, false, `\n if (!el) {\n return null;\n }\n return document.activeElement === el;\n `);\n }\n\n async isInViewport(selector: string, options: FrameSelectorOptions = {}, fully = false) {\n return this.evalOnSelector<boolean | null>(selector, options, false, `\n if (!el) {\n return null;\n }\n const rect = el.getBoundingClientRect();\n const viewWidth = window.innerWidth || document.documentElement.clientWidth;\n const viewHeight = window.innerHeight || document.documentElement.clientHeight;\n if (${fully ? \"true\" : \"false\"}) {\n return rect.top >= 0 && rect.left >= 0 && rect.bottom <= viewHeight && rect.right <= viewWidth;\n }\n return rect.bottom > 0 && rect.right > 0 && rect.top < viewHeight && rect.left < viewWidth;\n `);\n }\n\n async isEditable(selector: string, options: FrameSelectorOptions = {}) {\n return this.evalOnSelector<boolean | null>(selector, options, false, `\n if (!el) {\n return null;\n }\n const disabled = Boolean(el.disabled) || el.hasAttribute(\"disabled\");\n const readOnly = Boolean(el.readOnly) || el.hasAttribute(\"readonly\");\n const ariaDisabled = el.getAttribute && el.getAttribute(\"aria-disabled\") === \"true\";\n return !(disabled || readOnly || ariaDisabled);\n `);\n }\n\n private async performClick(selector: string, options: ClickOptions, isDouble: boolean) {\n const start = Date.now();\n const actionName = isDouble ? \"dblclick\" : \"click\";\n this.events.emit(\"action:start\", { name: actionName, selector, frameId: this.id });\n const box = await waitFor(async () => {\n const result = await this.resolveElementBox(selector, options);\n if (!result || !result.visible) {\n return null;\n }\n return result;\n }, { timeoutMs: options.timeoutMs ?? this.defaultTimeout, description: `${actionName} ${selector}` });\n\n const centerX = box.x + box.width / 2;\n const centerY = box.y + box.height / 2;\n await this.session.send(\"Input.dispatchMouseEvent\", { type: \"mouseMoved\", x: centerX, y: centerY });\n await this.session.send(\"Input.dispatchMouseEvent\", { type: \"mousePressed\", x: centerX, y: centerY, button: \"left\", clickCount: 1, buttons: 1 });\n await this.session.send(\"Input.dispatchMouseEvent\", { type: \"mouseReleased\", x: centerX, y: centerY, button: \"left\", clickCount: 1, buttons: 0 });\n\n if (isDouble) {\n await this.session.send(\"Input.dispatchMouseEvent\", { type: \"mouseMoved\", x: centerX, y: centerY });\n await this.session.send(\"Input.dispatchMouseEvent\", { type: \"mousePressed\", x: centerX, y: centerY, button: \"left\", clickCount: 2, buttons: 1 });\n await this.session.send(\"Input.dispatchMouseEvent\", { type: \"mouseReleased\", x: centerX, y: centerY, button: \"left\", clickCount: 2, buttons: 0 });\n }\n\n const duration = Date.now() - start;\n this.events.emit(\"action:end\", { name: actionName, selector, frameId: this.id, durationMs: duration });\n this.logger.debug(\"Click\", selector, `${duration}ms`);\n }\n\n private async resolveElementBox(selector: string, options: FrameSelectorOptions): Promise<ElementBox | null> {\n const parsed = parseSelector(selector);\n const pierce = Boolean(parsed.pierceShadowDom);\n const helpers = serializeShadowDomHelpers();\n const expression = parsed.type === \"xpath\"\n ? `(function() {\n const result = document.evaluate(${JSON.stringify(parsed.value)}, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;\n if (!result || !(result instanceof Element)) {\n return null;\n }\n result.scrollIntoView({ block: 'center', inline: 'center' });\n const rect = result.getBoundingClientRect();\n const style = window.getComputedStyle(result);\n return { x: rect.x, y: rect.y, width: rect.width, height: rect.height, visible: rect.width > 0 && rect.height > 0 && style.visibility !== 'hidden' && style.display !== 'none' && Number(style.opacity || '1') > 0 };\n })()`\n : `(function() {\n const querySelectorDeep = ${helpers.querySelectorDeep};\n const root = document;\n const selector = ${JSON.stringify(parsed.value)};\n const el = ${pierce ? \"querySelectorDeep(root, selector)\" : \"root.querySelector(selector)\"};\n if (!el) {\n return null;\n }\n el.scrollIntoView({ block: 'center', inline: 'center' });\n const rect = el.getBoundingClientRect();\n const style = window.getComputedStyle(el);\n return { x: rect.x, y: rect.y, width: rect.width, height: rect.height, visible: rect.width > 0 && rect.height > 0 && style.visibility !== 'hidden' && style.display !== 'none' && Number(style.opacity || '1') > 0 };\n })()`;\n\n const boxParams: Record<string, unknown> = {\n expression,\n returnByValue: true\n };\n if (this.contextId) {\n boxParams.contextId = this.contextId;\n }\n const result = await this.session.send<{ result: { value: ElementBox | null } }>(\"Runtime.evaluate\", boxParams);\n\n return result?.result?.value ?? null;\n }\n\n private async querySelectorInternal(selector: string, options: FrameSelectorOptions, forceXPath: boolean): Promise<QueryResult | null> {\n const parsed = forceXPath ? { type: \"xpath\", value: selector.trim(), pierceShadowDom: undefined } : parseSelector(selector);\n const pierce = Boolean(parsed.pierceShadowDom);\n const helpers = serializeShadowDomHelpers();\n const expression = parsed.type === \"xpath\"\n ? `(function() {\n const result = document.evaluate(${JSON.stringify(parsed.value)}, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;\n return result || null;\n })()`\n : `(function() {\n const querySelectorDeep = ${helpers.querySelectorDeep};\n const root = document;\n const selector = ${JSON.stringify(parsed.value)};\n return ${pierce ? \"querySelectorDeep(root, selector)\" : \"root.querySelector(selector)\"};\n })()`;\n\n const queryParams: Record<string, unknown> = {\n expression,\n returnByValue: false\n };\n if (this.contextId) {\n queryParams.contextId = this.contextId;\n }\n const response = await this.session.send<{ result: { subtype?: string; objectId?: string } }>(\"Runtime.evaluate\", queryParams);\n\n if (response.result?.subtype === \"null\" || !response.result?.objectId) {\n return null;\n }\n\n return { objectId: response.result.objectId, contextId: this.contextId ?? 0 };\n }\n\n private async querySelectorAllInternal(selector: string, options: FrameSelectorOptions, forceXPath: boolean): Promise<QueryResult[]> {\n const parsed = forceXPath ? { type: \"xpath\", value: selector.trim(), pierceShadowDom: undefined } : parseSelector(selector);\n const pierce = Boolean(parsed.pierceShadowDom);\n const helpers = serializeShadowDomHelpers();\n const expression = parsed.type === \"xpath\"\n ? `(function() {\n const result = document.evaluate(${JSON.stringify(parsed.value)}, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);\n const nodes = [];\n for (let i = 0; i < result.snapshotLength; i += 1) {\n nodes.push(result.snapshotItem(i));\n }\n return nodes;\n })()`\n : `(function() {\n const querySelectorAllDeep = ${helpers.querySelectorAllDeep};\n const root = document;\n const selector = ${JSON.stringify(parsed.value)};\n return ${pierce ? \"querySelectorAllDeep(root, selector)\" : \"Array.from(root.querySelectorAll(selector))\"};\n })()`;\n\n const listParams: Record<string, unknown> = {\n expression,\n returnByValue: false\n };\n if (this.contextId) {\n listParams.contextId = this.contextId;\n }\n const response = await this.session.send<{ result: { objectId?: string } }>(\"Runtime.evaluate\", listParams);\n\n if (!response.result?.objectId) {\n return [];\n }\n\n const properties = await this.session.send<{ result: Array<{ name?: string; value?: { objectId?: string } }> }>(\"Runtime.getProperties\", {\n objectId: response.result.objectId,\n ownProperties: true\n });\n\n const handles: QueryResult[] = [];\n for (const prop of properties.result) {\n if (prop.name && !/^\\d+$/.test(prop.name)) {\n continue;\n }\n const objectId = prop.value?.objectId;\n if (objectId) {\n handles.push({ objectId, contextId: this.contextId ?? 0 });\n }\n }\n\n await this.releaseObject(response.result.objectId);\n return handles;\n }\n\n private async evaluateInContext(fnOrString: string | ((...args: any[]) => any), args: any[]): Promise<any> {\n if (typeof fnOrString === \"string\") {\n const params: Record<string, unknown> = {\n expression: fnOrString,\n returnByValue: true,\n awaitPromise: true\n };\n if (this.contextId) {\n params.contextId = this.contextId;\n }\n const result = await this.session.send<{ result: { value?: unknown } }>(\"Runtime.evaluate\", params);\n return result.result.value;\n }\n\n const serializedArgs = args.map((arg) => serializeArgument(arg)).join(\", \");\n const expression = `(${fnOrString.toString()})(${serializedArgs})`;\n const params: Record<string, unknown> = {\n expression,\n returnByValue: true,\n awaitPromise: true\n };\n if (this.contextId) {\n params.contextId = this.contextId;\n }\n const result = await this.session.send<{ result: { value?: unknown } }>(\"Runtime.evaluate\", params);\n return result.result.value;\n }\n\n private async releaseObject(objectId: string) {\n try {\n await this.session.send(\"Runtime.releaseObject\", { objectId });\n } catch {\n // ignore release errors\n }\n }\n\n private buildElementExpression(selector: string, options: FrameSelectorOptions, forceXPath: boolean, body: string) {\n const parsed = forceXPath ? { type: \"xpath\", value: selector.trim(), pierceShadowDom: undefined } : parseSelector(selector);\n const pierce = options.pierceShadowDom ?? Boolean(parsed.pierceShadowDom);\n const helpers = serializeShadowDomHelpers();\n if (parsed.type === \"xpath\") {\n return `(function() {\n const el = document.evaluate(${JSON.stringify(parsed.value)}, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;\n ${body}\n })()`;\n }\n return `(function() {\n const querySelectorDeep = ${helpers.querySelectorDeep};\n const root = document;\n const selector = ${JSON.stringify(parsed.value)};\n const el = ${pierce ? \"querySelectorDeep(root, selector)\" : \"root.querySelector(selector)\"};\n ${body}\n })()`;\n }\n\n private async evalOnSelector<T>(selector: string, options: FrameSelectorOptions, forceXPath: boolean, body: string): Promise<T> {\n const expression = this.buildElementExpression(selector, options, forceXPath, body);\n const params: Record<string, unknown> = {\n expression,\n returnByValue: true\n };\n if (this.contextId) {\n params.contextId = this.contextId;\n }\n const result = await this.session.send<{ result: { value?: T } }>(\"Runtime.evaluate\", params);\n return result.result.value as T;\n }\n}\n\nfunction serializeArgument(value: unknown) {\n if (value === undefined) {\n return \"undefined\";\n }\n return JSON.stringify(value);\n}\n","export type SelectorType = \"css\" | \"xpath\";\n\nexport type ParsedSelector = {\n type: SelectorType;\n value: string;\n pierceShadowDom?: boolean;\n};\n\nfunction isXPathSelector(input: string): boolean {\n if (input.startsWith(\"/\")) return true;\n if (input.startsWith(\"./\")) return true;\n if (input.startsWith(\".//\")) return true;\n if (input.startsWith(\"..\")) return true;\n if (input.startsWith(\"(\")) {\n const trimmed = input.trimStart();\n if (trimmed.startsWith(\"(\")) {\n const inner = trimmed.slice(1).trimStart();\n return inner.startsWith(\"/\") || inner.startsWith(\".\");\n }\n }\n return false;\n}\n\nexport function parseSelector(input: string): ParsedSelector {\n const value = input.trim();\n const pierceShadowDom = value.includes(\">>>\");\n return {\n type: isXPathSelector(value) ? \"xpath\" : \"css\",\n value,\n pierceShadowDom\n };\n}\n","type RootNode = Document | ShadowRoot | Element;\n\nfunction getElementCtor(root: RootNode): typeof Element | null {\n if (typeof Element !== \"undefined\") return Element;\n const doc = (root as Document | ShadowRoot | Element & { ownerDocument?: Document }).ownerDocument;\n const view = (doc || (root as any)).defaultView;\n return view?.Element ?? null;\n}\n\nfunction isElementNode(node: RootNode, ElementCtor: typeof Element): node is Element {\n return node instanceof ElementCtor;\n}\n\nfunction nodeChildren(node: RootNode): Element[] {\n if (!(\"children\" in node)) {\n return [];\n }\n return Array.from(node.children as unknown as Iterable<Element>);\n}\n\nexport function querySelectorDeep(root: RootNode, selector: string): Element | null {\n const ElementCtor = getElementCtor(root);\n if (!ElementCtor) return null;\n const elementCtor = ElementCtor;\n function walk(node: RootNode, sel: string, results: Element[]) {\n if (isElementNode(node, elementCtor) && node.matches(sel)) {\n results.push(node);\n }\n if (isElementNode(node, elementCtor) && node.shadowRoot) {\n walk(node.shadowRoot, sel, results);\n }\n for (const child of nodeChildren(node)) {\n walk(child, sel, results);\n }\n }\n\n function findAll(rootNode: RootNode, sel: string) {\n const results: Element[] = [];\n walk(rootNode, sel, results);\n return results;\n }\n\n if (selector.includes(\">>>\")) {\n const parts = selector.split(\">>>\").map((p) => p.trim()).filter(Boolean);\n let scope: RootNode[] = [root];\n for (const part of parts) {\n const matches: Element[] = [];\n for (const item of scope) {\n matches.push(...findAll(item, part));\n }\n if (matches.length === 0) return null;\n scope = matches;\n }\n return (scope[0] as Element) ?? null;\n }\n const results = findAll(root, selector);\n return results[0] ?? null;\n}\n\nexport function querySelectorAllDeep(root: Document | ShadowRoot | Element, selector: string): Element[] {\n const ElementCtor = getElementCtor(root);\n if (!ElementCtor) return [];\n const elementCtor = ElementCtor;\n function walk(node: RootNode, sel: string, results: Element[]) {\n if (isElementNode(node, elementCtor) && node.matches(sel)) {\n results.push(node);\n }\n if (isElementNode(node, elementCtor) && node.shadowRoot) {\n walk(node.shadowRoot, sel, results);\n }\n for (const child of nodeChildren(node)) {\n walk(child, sel, results);\n }\n }\n\n function findAll(rootNode: RootNode, sel: string) {\n const results: Element[] = [];\n walk(rootNode, sel, results);\n return results;\n }\n\n if (selector.includes(\">>>\")) {\n const parts = selector.split(\">>>\").map((p) => p.trim()).filter(Boolean);\n let scope: RootNode[] = [root];\n for (const part of parts) {\n const matches: Element[] = [];\n for (const item of scope) {\n matches.push(...findAll(item, part));\n }\n scope = matches;\n if (scope.length === 0) return [];\n }\n return scope.filter((el): el is Element => el instanceof Element);\n }\n return findAll(root, selector);\n}\n\nexport function serializeShadowDomHelpers() {\n return {\n querySelectorDeep: querySelectorDeep.toString(),\n querySelectorAllDeep: querySelectorAllDeep.toString()\n };\n}\n","import type { Frame } from \"./Frame.js\";\n\nexport type LocatorOptions = {};\n\nexport class Locator {\n private frame: Frame;\n private selector: string;\n private options: LocatorOptions;\n\n constructor(frame: Frame, selector: string, options: LocatorOptions = {}) {\n this.frame = frame;\n this.selector = selector;\n this.options = options;\n }\n\n async click(options: { timeoutMs?: number } = {}) {\n return this.frame.click(this.selector, { ...this.options, ...options });\n }\n\n async dblclick(options: { timeoutMs?: number } = {}) {\n return this.frame.dblclick(this.selector, { ...this.options, ...options });\n }\n\n async type(text: string, options: { timeoutMs?: number } = {}) {\n return this.frame.type(this.selector, text, { ...this.options, ...options });\n }\n\n async exists() {\n return this.frame.exists(this.selector, this.options);\n }\n\n async text() {\n return this.frame.text(this.selector, this.options);\n }\n}\n","export type UrlGuardOptions = {\n allowFileUrl?: boolean;\n};\n\nexport function ensureAllowedUrl(url: string, options: UrlGuardOptions = {}) {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new Error(`Invalid URL: ${url}`);\n }\n if (parsed.protocol === \"http:\" || parsed.protocol === \"https:\") {\n return;\n }\n if (parsed.protocol === \"file:\" && options.allowFileUrl) {\n return;\n }\n throw new Error(`URL protocol not allowed: ${parsed.protocol}`);\n}\n","import { AssertionError } from \"./AssertionError.js\";\nimport { waitFor } from \"../core/Waiter.js\";\nimport { Page } from \"../core/Page.js\";\nimport { Frame } from \"../core/Frame.js\";\nimport { AutomationEvents } from \"../core/Events.js\";\n\nexport type ExpectSelectorOptions = {\n timeoutMs?: number;\n};\n\nclass ElementExpectation {\n private frame: Frame;\n private selector: string;\n private options: ExpectSelectorOptions;\n private negate: boolean;\n private events: AutomationEvents;\n\n constructor(frame: Frame, selector: string, options: ExpectSelectorOptions, negate: boolean, events: AutomationEvents) {\n this.frame = frame;\n this.selector = selector;\n this.options = options;\n this.negate = negate;\n this.events = events;\n }\n\n get not() {\n return new ElementExpectation(this.frame, this.selector, this.options, !this.negate, this.events);\n }\n\n async toExist() {\n return this.assert(async () => {\n const exists = await this.frame.exists(this.selector, this.options);\n return this.negate ? !exists : exists;\n }, this.negate ? \"Expected element not to exist\" : \"Expected element to exist\");\n }\n\n async toBeVisible() {\n return this.assert(async () => {\n const visible = await this.frame.isVisible(this.selector, this.options);\n return this.negate ? !visible : visible;\n }, this.negate ? \"Expected element not to be visible\" : \"Expected element to be visible\");\n }\n\n async toBeHidden() {\n return this.assert(async () => {\n const visible = await this.frame.isVisible(this.selector, this.options);\n return this.negate ? visible : !visible;\n }, this.negate ? \"Expected element not to be hidden\" : \"Expected element to be hidden\");\n }\n\n async toBeEnabled() {\n return this.assert(async () => {\n const enabled = await this.frame.isEnabled(this.selector, this.options);\n if (enabled == null) {\n return this.negate ? true : false;\n }\n return this.negate ? !enabled : enabled;\n }, this.negate ? \"Expected element not to be enabled\" : \"Expected element to be enabled\");\n }\n\n async toBeDisabled() {\n return this.assert(async () => {\n const enabled = await this.frame.isEnabled(this.selector, this.options);\n if (enabled == null) {\n return this.negate ? true : false;\n }\n const disabled = !enabled;\n return this.negate ? !disabled : disabled;\n }, this.negate ? \"Expected element not to be disabled\" : \"Expected element to be disabled\");\n }\n\n async toBeChecked() {\n return this.assert(async () => {\n const checked = await this.frame.isChecked(this.selector, this.options);\n if (checked == null) {\n return this.negate ? true : false;\n }\n return this.negate ? !checked : checked;\n }, this.negate ? \"Expected element not to be checked\" : \"Expected element to be checked\");\n }\n\n async toBeUnchecked() {\n return this.assert(async () => {\n const checked = await this.frame.isChecked(this.selector, this.options);\n if (checked == null) {\n return this.negate ? true : false;\n }\n const unchecked = !checked;\n return this.negate ? !unchecked : unchecked;\n }, this.negate ? \"Expected element not to be unchecked\" : \"Expected element to be unchecked\");\n }\n\n async toHaveText(textOrRegex: string | RegExp) {\n const expected = textOrRegex;\n return this.assert(async () => {\n const text = await this.frame.text(this.selector, this.options);\n if (text == null) {\n return this.negate ? true : false;\n }\n const matches = expected instanceof RegExp\n ? new RegExp(expected.source, expected.flags.replace(\"g\", \"\")).test(text)\n : text.includes(expected);\n return this.negate ? !matches : matches;\n }, this.negate ? \"Expected element text not to match\" : \"Expected element text to match\", { expected });\n }\n\n async toHaveExactText(textOrRegex: string | RegExp) {\n const expected = textOrRegex;\n return this.assert(async () => {\n const text = await this.frame.text(this.selector, this.options);\n if (text == null) {\n return this.negate ? true : false;\n }\n const matches = expected instanceof RegExp\n ? new RegExp(expected.source, expected.flags.replace(\"g\", \"\")).test(text)\n : text === expected;\n return this.negate ? !matches : matches;\n }, this.negate ? \"Expected element text not to match exactly\" : \"Expected element text to match exactly\", { expected });\n }\n\n async toContainText(textOrRegex: string | RegExp) {\n const expected = textOrRegex;\n return this.assert(async () => {\n const text = await this.frame.text(this.selector, this.options);\n if (text == null) {\n return this.negate ? true : false;\n }\n const matches = expected instanceof RegExp\n ? new RegExp(expected.source, expected.flags.replace(\"g\", \"\")).test(text)\n : text.includes(expected);\n return this.negate ? !matches : matches;\n }, this.negate ? \"Expected element text not to contain\" : \"Expected element text to contain\", { expected });\n }\n\n async toHaveValue(valueOrRegex: string | RegExp) {\n const expected = valueOrRegex;\n return this.assert(async () => {\n const value = await this.frame.value(this.selector, this.options);\n if (value == null) {\n return this.negate ? true : false;\n }\n const matches = expected instanceof RegExp\n ? new RegExp(expected.source, expected.flags.replace(\"g\", \"\")).test(value)\n : value === expected;\n return this.negate ? !matches : matches;\n }, this.negate ? \"Expected element value not to match\" : \"Expected element value to match\", { expected });\n }\n\n async toHaveAttribute(name: string, valueOrRegex?: string | RegExp) {\n const expected = valueOrRegex;\n return this.assert(async () => {\n const value = await this.frame.attribute(this.selector, name, this.options);\n if (expected === undefined) {\n const exists = value != null;\n return this.negate ? !exists : exists;\n }\n if (value == null) {\n return this.negate ? true : false;\n }\n const matches = expected instanceof RegExp\n ? new RegExp(expected.source, expected.flags.replace(\"g\", \"\")).test(value)\n : value === expected;\n return this.negate ? !matches : matches;\n }, this.negate ? \"Expected element attribute not to match\" : \"Expected element attribute to match\", { expected, name });\n }\n\n async toHaveId(idOrRegex: string | RegExp) {\n return this.toHaveAttribute(\"id\", idOrRegex);\n }\n\n async toHaveName(nameOrRegex: string | RegExp) {\n return this.toHaveAttribute(\"name\", nameOrRegex);\n }\n\n async toHaveCount(expected: number) {\n return this.assert(async () => {\n const count = await this.frame.count(this.selector, this.options);\n const matches = count === expected;\n return this.negate ? !matches : matches;\n }, this.negate ? \"Expected element count not to match\" : \"Expected element count to match\", { expected });\n }\n\n async toHaveClass(nameOrRegex: string | RegExp) {\n const expected = nameOrRegex;\n return this.assert(async () => {\n const classes = await this.frame.classes(this.selector, this.options);\n if (classes == null) {\n return this.negate ? true : false;\n }\n const matches = expected instanceof RegExp\n ? classes.some((value) => new RegExp(expected.source, expected.flags.replace(\"g\", \"\")).test(value))\n : classes.includes(expected);\n return this.negate ? !matches : matches;\n }, this.negate ? \"Expected element class not to match\" : \"Expected element class to match\", { expected });\n }\n\n async toHaveClasses(expected: string[]) {\n return this.assert(async () => {\n const classes = await this.frame.classes(this.selector, this.options);\n if (classes == null) {\n return this.negate ? true : false;\n }\n const matches = expected.every((value) => classes.includes(value));\n return this.negate ? !matches : matches;\n }, this.negate ? \"Expected element classes not to match\" : \"Expected element classes to match\", { expected });\n }\n\n async toHaveCss(property: string, valueOrRegex: string | RegExp) {\n const expected = valueOrRegex;\n return this.assert(async () => {\n const value = await this.frame.css(this.selector, property, this.options);\n if (value == null) {\n return this.negate ? true : false;\n }\n const actual = value.trim();\n const matches = expected instanceof RegExp\n ? new RegExp(expected.source, expected.flags.replace(\"g\", \"\")).test(actual)\n : actual === expected;\n return this.negate ? !matches : matches;\n }, this.negate ? \"Expected element css not to match\" : \"Expected element css to match\", { expected, property });\n }\n\n async toHaveFocus() {\n return this.assert(async () => {\n const focused = await this.frame.hasFocus(this.selector, this.options);\n if (focused == null) {\n return this.negate ? true : false;\n }\n return this.negate ? !focused : focused;\n }, this.negate ? \"Expected element not to have focus\" : \"Expected element to have focus\");\n }\n\n async toBeInViewport(options: { fully?: boolean } = {}) {\n return this.assert(async () => {\n const inViewport = await this.frame.isInViewport(this.selector, this.options, Boolean(options.fully));\n if (inViewport == null) {\n return this.negate ? true : false;\n }\n return this.negate ? !inViewport : inViewport;\n }, this.negate ? \"Expected element not to be in viewport\" : \"Expected element to be in viewport\");\n }\n\n async toBeEditable() {\n return this.assert(async () => {\n const editable = await this.frame.isEditable(this.selector, this.options);\n if (editable == null) {\n return this.negate ? true : false;\n }\n return this.negate ? !editable : editable;\n }, this.negate ? \"Expected element not to be editable\" : \"Expected element to be editable\");\n }\n\n private async assert(predicate: () => Promise<boolean>, message: string, details: Record<string, unknown> = {}) {\n const timeoutMs = this.options.timeoutMs ?? 30_000;\n const start = Date.now();\n this.events.emit(\"assertion:start\", { name: message, selector: this.selector, frameId: this.frame.id });\n\n let lastState: unknown;\n try {\n await waitFor(async () => {\n const result = await predicate();\n lastState = result;\n return result;\n }, { timeoutMs, description: message });\n } catch {\n const duration = Date.now() - start;\n this.events.emit(\"assertion:end\", { name: message, selector: this.selector, frameId: this.frame.id, durationMs: duration, status: \"failed\" });\n throw new AssertionError(message, { selector: this.selector, timeoutMs, lastState: { lastState, ...details } });\n }\n\n const duration = Date.now() - start;\n this.events.emit(\"assertion:end\", { name: message, selector: this.selector, frameId: this.frame.id, durationMs: duration, status: \"passed\" });\n }\n}\n\nclass ExpectFrame {\n private frame: Frame;\n private events: AutomationEvents;\n\n constructor(frame: Frame, events: AutomationEvents) {\n this.frame = frame;\n this.events = events;\n }\n\n element(selector: string, options: ExpectSelectorOptions = {}) {\n return new ElementExpectation(this.frame, selector, options, false, this.events);\n }\n}\n\nexport function expect(page: Page) {\n return {\n element: (selector: string, options: ExpectSelectorOptions = {}) => new ElementExpectation(page.mainFrame(), selector, options, false, page.getEvents()),\n frame: (options: { name?: string; urlIncludes?: string; predicate?: (frame: Frame) => boolean }) => {\n const frame = page.frame(options);\n if (!frame) {\n throw new AssertionError(\"Frame not found\", { selector: JSON.stringify(options) });\n }\n return new ExpectFrame(frame, page.getEvents());\n }\n };\n}\n\nexport type { ElementExpectation, ExpectFrame };\n\n// Convenience: page.expect().element(\"selector\") or page.expect(\"selector\").toExist()\ndeclare module \"../core/Page.js\" {\n interface Page {\n expect(): ReturnType<typeof expect>;\n expect(selector: string, options?: ExpectSelectorOptions): ElementExpectation;\n find: {\n locators: (options?: { highlight?: boolean; outputPath?: string; outputJson?: string; outputHtml?: string }) => Promise<any[]>;\n };\n findLocators(options?: { highlight?: boolean; outputPath?: string; outputJson?: string; outputHtml?: string }): Promise<any[]>;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\n(Page.prototype as any).expect = function(selector?: string, options?: ExpectSelectorOptions) {\n const builder = expect(this as Page);\n if (selector) {\n return builder.element(selector, options);\n }\n return builder;\n};\n\nObject.defineProperty(Page.prototype, \"find\", {\n get: function() {\n return {\n locators: (options?: { highlight?: boolean; outputPath?: string; outputJson?: string; outputHtml?: string }) =>\n (this as Page).findLocators(options)\n };\n }\n});\n"],"mappings":"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","names":["fs","path","results","params","result","path","fs","duration"]}