@opensteer/browser-core 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,2914 @@
1
+ 'use strict';
2
+
3
+ // src/brand.ts
4
+ function brand(value) {
5
+ return value;
6
+ }
7
+
8
+ // src/identity.ts
9
+ function normalizeRef(prefix, value) {
10
+ const trimmed = value.trim();
11
+ if (trimmed.length === 0) {
12
+ throw new TypeError(`${prefix} reference cannot be empty`);
13
+ }
14
+ const canonicalPrefix = `${prefix}:`;
15
+ if (trimmed.startsWith(canonicalPrefix)) {
16
+ if (trimmed.length === canonicalPrefix.length) {
17
+ throw new TypeError(`${prefix} reference must include an identifier`);
18
+ }
19
+ return trimmed;
20
+ }
21
+ if (trimmed.includes(":")) {
22
+ throw new TypeError(
23
+ `${prefix} reference "${trimmed}" must either omit a prefix or use ${canonicalPrefix}`
24
+ );
25
+ }
26
+ return `${canonicalPrefix}${trimmed}`;
27
+ }
28
+ function hasPrefix(prefix, value) {
29
+ return value.startsWith(`${prefix}:`) && value.length > prefix.length + 1;
30
+ }
31
+ function createStringRef(prefix, value) {
32
+ return brand(normalizeRef(prefix, value));
33
+ }
34
+ function createSessionRef(value) {
35
+ return createStringRef("session", value);
36
+ }
37
+ function createPageRef(value) {
38
+ return createStringRef("page", value);
39
+ }
40
+ function createFrameRef(value) {
41
+ return createStringRef("frame", value);
42
+ }
43
+ function createDocumentRef(value) {
44
+ return createStringRef("document", value);
45
+ }
46
+ function createNodeRef(value) {
47
+ return createStringRef("node", value);
48
+ }
49
+ function createNetworkRequestId(value) {
50
+ return createStringRef("request", value);
51
+ }
52
+ function createDownloadRef(value) {
53
+ return createStringRef("download", value);
54
+ }
55
+ function createDialogRef(value) {
56
+ return createStringRef("dialog", value);
57
+ }
58
+ function createChooserRef(value) {
59
+ return createStringRef("chooser", value);
60
+ }
61
+ function createWorkerRef(value) {
62
+ return createStringRef("worker", value);
63
+ }
64
+ function isSessionRef(value) {
65
+ return hasPrefix("session", value);
66
+ }
67
+ function isPageRef(value) {
68
+ return hasPrefix("page", value);
69
+ }
70
+ function isFrameRef(value) {
71
+ return hasPrefix("frame", value);
72
+ }
73
+ function isDocumentRef(value) {
74
+ return hasPrefix("document", value);
75
+ }
76
+ function isNodeRef(value) {
77
+ return hasPrefix("node", value);
78
+ }
79
+ function isNetworkRequestId(value) {
80
+ return hasPrefix("request", value);
81
+ }
82
+ function isDownloadRef(value) {
83
+ return hasPrefix("download", value);
84
+ }
85
+ function isDialogRef(value) {
86
+ return hasPrefix("dialog", value);
87
+ }
88
+ function isChooserRef(value) {
89
+ return hasPrefix("chooser", value);
90
+ }
91
+ function isWorkerRef(value) {
92
+ return hasPrefix("worker", value);
93
+ }
94
+ function serializeRef(ref) {
95
+ return ref;
96
+ }
97
+ function createDocumentEpoch(value) {
98
+ if (!Number.isInteger(value) || value < 0) {
99
+ throw new RangeError(
100
+ `document epoch must be a non-negative integer, received ${String(value)}`
101
+ );
102
+ }
103
+ return brand(value);
104
+ }
105
+ function nextDocumentEpoch(epoch) {
106
+ return createDocumentEpoch(epoch + 1);
107
+ }
108
+ function serializeDocumentEpoch(epoch) {
109
+ return epoch;
110
+ }
111
+ function createNodeLocator(documentRef, documentEpoch, nodeRef) {
112
+ return { documentRef, documentEpoch, nodeRef };
113
+ }
114
+
115
+ // src/geometry.ts
116
+ function assertFinite(value, name) {
117
+ if (!Number.isFinite(value)) {
118
+ throw new TypeError(`${name} must be a finite number`);
119
+ }
120
+ }
121
+ function assertNonNegative(value, name) {
122
+ assertFinite(value, name);
123
+ if (value < 0) {
124
+ throw new RangeError(`${name} must be greater than or equal to 0`);
125
+ }
126
+ }
127
+ function createScale(value, name) {
128
+ if (!Number.isFinite(value) || value <= 0) {
129
+ throw new RangeError(`${name} must be greater than 0`);
130
+ }
131
+ return brand(value);
132
+ }
133
+ function createPoint(x, y) {
134
+ assertFinite(x, "point.x");
135
+ assertFinite(y, "point.y");
136
+ return { x, y };
137
+ }
138
+ function createSize(width, height) {
139
+ assertNonNegative(width, "size.width");
140
+ assertNonNegative(height, "size.height");
141
+ return { width, height };
142
+ }
143
+ function createRect(x, y, width, height) {
144
+ assertFinite(x, "rect.x");
145
+ assertFinite(y, "rect.y");
146
+ assertNonNegative(width, "rect.width");
147
+ assertNonNegative(height, "rect.height");
148
+ return { x, y, width, height };
149
+ }
150
+ function createScrollOffset(x, y) {
151
+ assertFinite(x, "scrollOffset.x");
152
+ assertFinite(y, "scrollOffset.y");
153
+ return { x, y };
154
+ }
155
+ function createQuad(points) {
156
+ return points;
157
+ }
158
+ function rectToQuad(rect) {
159
+ return createQuad([
160
+ createPoint(rect.x, rect.y),
161
+ createPoint(rect.x + rect.width, rect.y),
162
+ createPoint(rect.x + rect.width, rect.y + rect.height),
163
+ createPoint(rect.x, rect.y + rect.height)
164
+ ]);
165
+ }
166
+ function quadBounds(quad) {
167
+ const xs = quad.map((point) => point.x);
168
+ const ys = quad.map((point) => point.y);
169
+ const minX = Math.min(...xs);
170
+ const maxX = Math.max(...xs);
171
+ const minY = Math.min(...ys);
172
+ const maxY = Math.max(...ys);
173
+ return createRect(minX, minY, maxX - minX, maxY - minY);
174
+ }
175
+ function rectContainsPoint(rect, point) {
176
+ return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height;
177
+ }
178
+ function createDevicePixelRatio(value) {
179
+ return createScale(value, "devicePixelRatio");
180
+ }
181
+ function createPageScaleFactor(value) {
182
+ return createScale(value, "pageScaleFactor");
183
+ }
184
+ function createPageZoomFactor(value) {
185
+ return createScale(value, "pageZoomFactor");
186
+ }
187
+
188
+ // src/network.ts
189
+ function createHeaderEntry(name, value) {
190
+ return { name, value };
191
+ }
192
+ function createBodyPayload(bytes, options = {}) {
193
+ return {
194
+ bytes,
195
+ encoding: options.encoding ?? "identity",
196
+ truncated: options.truncated ?? false,
197
+ capturedByteLength: bytes.byteLength,
198
+ ...options.mimeType === void 0 ? {} : { mimeType: options.mimeType },
199
+ ...options.charset === void 0 ? {} : { charset: options.charset },
200
+ ...options.originalByteLength === void 0 ? {} : { originalByteLength: options.originalByteLength }
201
+ };
202
+ }
203
+ function bodyPayloadFromUtf8(value, options = {}) {
204
+ return createBodyPayload(new TextEncoder().encode(value), {
205
+ ...options.mimeType === void 0 ? {} : { mimeType: options.mimeType },
206
+ ...options.encoding === void 0 ? {} : { encoding: options.encoding },
207
+ ...options.truncated === void 0 ? {} : { truncated: options.truncated },
208
+ ...options.originalByteLength === void 0 ? {} : { originalByteLength: options.originalByteLength },
209
+ charset: "utf-8"
210
+ });
211
+ }
212
+ function matchesNetworkRecordFilters(record, filters) {
213
+ if (filters.url !== void 0 && !includesCaseInsensitive(record.url, filters.url)) {
214
+ return false;
215
+ }
216
+ let parsedUrl;
217
+ const getParsedUrl = () => {
218
+ parsedUrl ??= new URL(record.url);
219
+ return parsedUrl;
220
+ };
221
+ if (filters.hostname !== void 0) {
222
+ const hostname = getParsedUrl().hostname;
223
+ if (!includesCaseInsensitive(hostname, filters.hostname)) {
224
+ return false;
225
+ }
226
+ }
227
+ if (filters.path !== void 0) {
228
+ const path = getParsedUrl().pathname;
229
+ if (!includesCaseInsensitive(path, filters.path)) {
230
+ return false;
231
+ }
232
+ }
233
+ if (filters.method !== void 0 && !includesCaseInsensitive(record.method, filters.method)) {
234
+ return false;
235
+ }
236
+ if (filters.status !== void 0 && !includesCaseInsensitive(
237
+ record.status === void 0 ? "" : String(record.status),
238
+ filters.status
239
+ )) {
240
+ return false;
241
+ }
242
+ if (filters.resourceType !== void 0 && record.resourceType !== filters.resourceType) {
243
+ return false;
244
+ }
245
+ return true;
246
+ }
247
+ function includesCaseInsensitive(value, query) {
248
+ return value.toLowerCase().includes(query.toLowerCase());
249
+ }
250
+
251
+ // src/snapshots.ts
252
+ function findDomSnapshotNode(snapshot, snapshotNodeId) {
253
+ return snapshot.nodes.find((node) => node.snapshotNodeId === snapshotNodeId);
254
+ }
255
+ function findDomSnapshotNodeByRef(snapshot, nodeRef) {
256
+ return snapshot.nodes.find((node) => node.nodeRef === nodeRef);
257
+ }
258
+
259
+ // src/storage.ts
260
+ function parseUrl(value) {
261
+ try {
262
+ return new URL(value);
263
+ } catch {
264
+ return null;
265
+ }
266
+ }
267
+ function isLocalHostname(hostname) {
268
+ return hostname === "localhost" || hostname.endsWith(".localhost");
269
+ }
270
+ function normalizeCookiePath(path) {
271
+ if (path.length === 0) {
272
+ return "/";
273
+ }
274
+ return path.startsWith("/") ? path : `/${path}`;
275
+ }
276
+ function pathMatchesCookiePath(requestPath, cookiePath) {
277
+ const normalizedRequestPath = requestPath.length === 0 ? "/" : requestPath;
278
+ const normalizedCookiePath = normalizeCookiePath(cookiePath);
279
+ if (normalizedRequestPath === normalizedCookiePath) {
280
+ return true;
281
+ }
282
+ if (!normalizedRequestPath.startsWith(normalizedCookiePath)) {
283
+ return false;
284
+ }
285
+ if (normalizedCookiePath.endsWith("/")) {
286
+ return true;
287
+ }
288
+ return normalizedRequestPath.charAt(normalizedCookiePath.length) === "/";
289
+ }
290
+ function filterCookieRecords(cookies, urls) {
291
+ const parsed = urls.map(parseUrl).filter((url) => url !== null);
292
+ if (parsed.length === 0) {
293
+ return [...cookies];
294
+ }
295
+ return cookies.filter((cookie) => {
296
+ return parsed.some((url) => {
297
+ let domain = cookie.domain;
298
+ if (!domain.startsWith(".")) {
299
+ domain = `.${domain}`;
300
+ }
301
+ if (!`.${url.hostname}`.endsWith(domain)) {
302
+ return false;
303
+ }
304
+ if (!pathMatchesCookiePath(url.pathname, cookie.path)) {
305
+ return false;
306
+ }
307
+ if (url.protocol !== "https:" && !isLocalHostname(url.hostname) && cookie.secure) {
308
+ return false;
309
+ }
310
+ return true;
311
+ });
312
+ });
313
+ }
314
+
315
+ // src/capabilities.ts
316
+ function noBrowserCapabilities() {
317
+ return {
318
+ executor: {
319
+ sessionLifecycle: false,
320
+ pageLifecycle: false,
321
+ navigation: false,
322
+ pointerInput: false,
323
+ keyboardInput: false,
324
+ touchInput: false,
325
+ screenshots: false,
326
+ executionControl: {
327
+ pause: false,
328
+ resume: false,
329
+ freeze: false
330
+ }
331
+ },
332
+ inspector: {
333
+ pageEnumeration: false,
334
+ frameEnumeration: false,
335
+ html: false,
336
+ domSnapshot: false,
337
+ visualStability: false,
338
+ text: false,
339
+ attributes: false,
340
+ hitTest: false,
341
+ viewportMetrics: false,
342
+ network: false,
343
+ networkBodies: false,
344
+ cookies: false,
345
+ localStorage: false,
346
+ sessionStorage: false,
347
+ indexedDb: false
348
+ },
349
+ transport: {
350
+ sessionHttp: false
351
+ },
352
+ instrumentation: {
353
+ initScripts: false,
354
+ routing: false
355
+ },
356
+ events: {
357
+ pageLifecycle: false,
358
+ dialog: false,
359
+ download: false,
360
+ chooser: false,
361
+ worker: false,
362
+ console: false,
363
+ pageError: false,
364
+ websocket: false,
365
+ eventStream: false,
366
+ executionState: false
367
+ }
368
+ };
369
+ }
370
+ function allBrowserCapabilities() {
371
+ return mergeBrowserCapabilities(noBrowserCapabilities(), {
372
+ executor: {
373
+ sessionLifecycle: true,
374
+ pageLifecycle: true,
375
+ navigation: true,
376
+ pointerInput: true,
377
+ keyboardInput: true,
378
+ touchInput: true,
379
+ screenshots: true,
380
+ executionControl: {
381
+ pause: true,
382
+ resume: true,
383
+ freeze: true
384
+ }
385
+ },
386
+ inspector: {
387
+ pageEnumeration: true,
388
+ frameEnumeration: true,
389
+ html: true,
390
+ domSnapshot: true,
391
+ visualStability: true,
392
+ text: true,
393
+ attributes: true,
394
+ hitTest: true,
395
+ viewportMetrics: true,
396
+ network: true,
397
+ networkBodies: true,
398
+ cookies: true,
399
+ localStorage: true,
400
+ sessionStorage: true,
401
+ indexedDb: true
402
+ },
403
+ transport: {
404
+ sessionHttp: true
405
+ },
406
+ instrumentation: {
407
+ initScripts: true,
408
+ routing: true
409
+ },
410
+ events: {
411
+ pageLifecycle: true,
412
+ dialog: true,
413
+ download: true,
414
+ chooser: true,
415
+ worker: true,
416
+ console: true,
417
+ pageError: true,
418
+ websocket: true,
419
+ eventStream: true,
420
+ executionState: true
421
+ }
422
+ });
423
+ }
424
+ function mergeBrowserCapabilities(base, override) {
425
+ return {
426
+ executor: {
427
+ ...base.executor,
428
+ ...override.executor,
429
+ executionControl: {
430
+ ...base.executor.executionControl,
431
+ ...override.executor?.executionControl
432
+ }
433
+ },
434
+ inspector: {
435
+ ...base.inspector,
436
+ ...override.inspector
437
+ },
438
+ transport: {
439
+ ...base.transport,
440
+ ...override.transport
441
+ },
442
+ instrumentation: {
443
+ ...base.instrumentation,
444
+ ...override.instrumentation
445
+ },
446
+ events: {
447
+ ...base.events,
448
+ ...override.events
449
+ }
450
+ };
451
+ }
452
+ function hasCapability(capabilities, path) {
453
+ switch (path) {
454
+ case "executor.sessionLifecycle":
455
+ return capabilities.executor.sessionLifecycle;
456
+ case "executor.pageLifecycle":
457
+ return capabilities.executor.pageLifecycle;
458
+ case "executor.navigation":
459
+ return capabilities.executor.navigation;
460
+ case "executor.pointerInput":
461
+ return capabilities.executor.pointerInput;
462
+ case "executor.keyboardInput":
463
+ return capabilities.executor.keyboardInput;
464
+ case "executor.touchInput":
465
+ return capabilities.executor.touchInput;
466
+ case "executor.screenshots":
467
+ return capabilities.executor.screenshots;
468
+ case "executor.executionControl.pause":
469
+ return capabilities.executor.executionControl.pause;
470
+ case "executor.executionControl.resume":
471
+ return capabilities.executor.executionControl.resume;
472
+ case "executor.executionControl.freeze":
473
+ return capabilities.executor.executionControl.freeze;
474
+ case "inspector.pageEnumeration":
475
+ return capabilities.inspector.pageEnumeration;
476
+ case "inspector.frameEnumeration":
477
+ return capabilities.inspector.frameEnumeration;
478
+ case "inspector.html":
479
+ return capabilities.inspector.html;
480
+ case "inspector.domSnapshot":
481
+ return capabilities.inspector.domSnapshot;
482
+ case "inspector.visualStability":
483
+ return capabilities.inspector.visualStability;
484
+ case "inspector.text":
485
+ return capabilities.inspector.text;
486
+ case "inspector.attributes":
487
+ return capabilities.inspector.attributes;
488
+ case "inspector.hitTest":
489
+ return capabilities.inspector.hitTest;
490
+ case "inspector.viewportMetrics":
491
+ return capabilities.inspector.viewportMetrics;
492
+ case "inspector.network":
493
+ return capabilities.inspector.network;
494
+ case "inspector.networkBodies":
495
+ return capabilities.inspector.networkBodies;
496
+ case "inspector.cookies":
497
+ return capabilities.inspector.cookies;
498
+ case "inspector.localStorage":
499
+ return capabilities.inspector.localStorage;
500
+ case "inspector.sessionStorage":
501
+ return capabilities.inspector.sessionStorage;
502
+ case "inspector.indexedDb":
503
+ return capabilities.inspector.indexedDb;
504
+ case "transport.sessionHttp":
505
+ return capabilities.transport.sessionHttp;
506
+ case "instrumentation.initScripts":
507
+ return capabilities.instrumentation.initScripts;
508
+ case "instrumentation.routing":
509
+ return capabilities.instrumentation.routing;
510
+ case "events.pageLifecycle":
511
+ return capabilities.events.pageLifecycle;
512
+ case "events.dialog":
513
+ return capabilities.events.dialog;
514
+ case "events.download":
515
+ return capabilities.events.download;
516
+ case "events.chooser":
517
+ return capabilities.events.chooser;
518
+ case "events.worker":
519
+ return capabilities.events.worker;
520
+ case "events.console":
521
+ return capabilities.events.console;
522
+ case "events.pageError":
523
+ return capabilities.events.pageError;
524
+ case "events.websocket":
525
+ return capabilities.events.websocket;
526
+ case "events.eventStream":
527
+ return capabilities.events.eventStream;
528
+ case "events.executionState":
529
+ return capabilities.events.executionState;
530
+ }
531
+ }
532
+
533
+ // src/errors.ts
534
+ var BrowserCoreError = class extends Error {
535
+ code;
536
+ retriable;
537
+ capability;
538
+ details;
539
+ constructor(code, message, options = {}) {
540
+ super(message, { cause: options.cause });
541
+ this.name = "BrowserCoreError";
542
+ this.code = code;
543
+ this.retriable = options.retriable ?? false;
544
+ this.capability = options.capability;
545
+ this.details = options.details;
546
+ }
547
+ };
548
+ function isBrowserCoreError(value) {
549
+ return value instanceof BrowserCoreError;
550
+ }
551
+ function createBrowserCoreError(code, message, options = {}) {
552
+ return new BrowserCoreError(code, message, options);
553
+ }
554
+ function unsupportedCapabilityError(capability) {
555
+ return new BrowserCoreError(
556
+ "unsupported-capability",
557
+ `capability ${capability} is not supported by this backend`,
558
+ {
559
+ capability,
560
+ details: { capability }
561
+ }
562
+ );
563
+ }
564
+ function staleNodeRefError(input) {
565
+ return new BrowserCoreError(
566
+ "stale-node-ref",
567
+ `node ${input.nodeRef} is stale for ${input.documentRef} at epoch ${input.documentEpoch}`,
568
+ {
569
+ details: {
570
+ nodeRef: input.nodeRef,
571
+ documentRef: input.documentRef,
572
+ documentEpoch: input.documentEpoch
573
+ }
574
+ }
575
+ );
576
+ }
577
+ function closedSessionError(sessionRef) {
578
+ return new BrowserCoreError("session-closed", `session ${sessionRef} is closed`, {
579
+ details: { sessionRef }
580
+ });
581
+ }
582
+ function closedPageError(pageRef) {
583
+ return new BrowserCoreError("page-closed", `page ${pageRef} is closed`, {
584
+ details: { pageRef }
585
+ });
586
+ }
587
+
588
+ // src/fake-engine.ts
589
+ function clone(value) {
590
+ return structuredClone(value);
591
+ }
592
+ function titleFromUrl(url) {
593
+ try {
594
+ const parsed = new URL(url);
595
+ if (parsed.hostname.length === 0) {
596
+ return url;
597
+ }
598
+ return parsed.hostname;
599
+ } catch {
600
+ return url;
601
+ }
602
+ }
603
+ function buildTransportKey(request) {
604
+ return `${request.method.toUpperCase()} ${request.url}`;
605
+ }
606
+ function stripFragment(url) {
607
+ const hashIndex = url.indexOf("#");
608
+ return hashIndex === -1 ? url : url.slice(0, hashIndex);
609
+ }
610
+ function originFromUrl(url) {
611
+ try {
612
+ return new URL(url).origin;
613
+ } catch {
614
+ return void 0;
615
+ }
616
+ }
617
+ var FakeBrowserCoreEngine = class {
618
+ capabilities;
619
+ sessions = /* @__PURE__ */ new Map();
620
+ pages = /* @__PURE__ */ new Map();
621
+ frames = /* @__PURE__ */ new Map();
622
+ documents = /* @__PURE__ */ new Map();
623
+ retiredDocuments = /* @__PURE__ */ new Set();
624
+ pageCounter = 0;
625
+ frameCounter = 0;
626
+ documentCounter = 0;
627
+ nodeCounter = 0;
628
+ requestCounter = 0;
629
+ sessionCounter = 0;
630
+ stepCounter = 0;
631
+ eventCounter = 0;
632
+ timestampMs;
633
+ constructor(options = {}) {
634
+ this.capabilities = options.capabilities ?? allBrowserCapabilities();
635
+ this.timestampMs = options.timestampSeedMs ?? 17e11;
636
+ if (options.initialPages && options.initialPages.length > 0) {
637
+ const sessionRef = createSessionRef(`seed-${++this.sessionCounter}`);
638
+ const storage = this.createDefaultStorage(sessionRef);
639
+ this.sessions.set(sessionRef, {
640
+ sessionRef,
641
+ pageRefs: /* @__PURE__ */ new Set(),
642
+ cookies: [],
643
+ storage,
644
+ transportResponses: /* @__PURE__ */ new Map()
645
+ });
646
+ for (const page of options.initialPages) {
647
+ void this.createPageInternal(sessionRef, {
648
+ ...page.url === void 0 ? {} : { url: page.url },
649
+ ...page.title === void 0 ? {} : { title: page.title },
650
+ ...page.viewportSize === void 0 ? {} : { viewportSize: page.viewportSize }
651
+ });
652
+ }
653
+ }
654
+ }
655
+ enqueueStepEvents(pageRef, events) {
656
+ const page = this.requirePage(pageRef);
657
+ for (const event of events) {
658
+ this.assertEventCapability(event.kind);
659
+ page.queuedEvents.push(clone(event));
660
+ }
661
+ }
662
+ advanceDocumentEpoch(documentRef) {
663
+ const document = this.requireDocument(documentRef);
664
+ const nextEpoch = nextDocumentEpoch(document.documentEpoch);
665
+ this.rebuildDocumentState(documentRef, {
666
+ documentRef,
667
+ documentEpoch: nextEpoch,
668
+ url: document.url,
669
+ title: titleFromUrl(document.url)
670
+ });
671
+ return nextEpoch;
672
+ }
673
+ seedCookies(sessionRef, cookies) {
674
+ const session = this.requireSession(sessionRef);
675
+ session.cookies = cookies.map((cookie) => clone(cookie));
676
+ }
677
+ seedTransportResponse(sessionRef, request, response) {
678
+ const session = this.requireSession(sessionRef);
679
+ session.transportResponses.set(buildTransportKey(request), clone(response));
680
+ }
681
+ async addInitScript(input) {
682
+ if (!hasCapability(this.capabilities, "instrumentation.initScripts")) {
683
+ throw unsupportedCapabilityError("instrumentation.initScripts");
684
+ }
685
+ this.requireSession(input.sessionRef);
686
+ return {
687
+ registrationId: `fake-init-script-${String(++this.stepCounter)}`,
688
+ sessionRef: input.sessionRef,
689
+ ...input.pageRef === void 0 ? {} : { pageRef: input.pageRef }
690
+ };
691
+ }
692
+ async registerRoute(input) {
693
+ if (!hasCapability(this.capabilities, "instrumentation.routing")) {
694
+ throw unsupportedCapabilityError("instrumentation.routing");
695
+ }
696
+ this.requireSession(input.sessionRef);
697
+ return {
698
+ routeId: `fake-route-${String(++this.stepCounter)}`,
699
+ sessionRef: input.sessionRef,
700
+ ...input.pageRef === void 0 ? {} : { pageRef: input.pageRef },
701
+ urlPattern: input.urlPattern
702
+ };
703
+ }
704
+ async createSession() {
705
+ this.requireCapability("executor.sessionLifecycle");
706
+ const sessionRef = createSessionRef(`fake-${++this.sessionCounter}`);
707
+ this.sessions.set(sessionRef, {
708
+ sessionRef,
709
+ pageRefs: /* @__PURE__ */ new Set(),
710
+ cookies: [],
711
+ storage: this.createDefaultStorage(sessionRef),
712
+ transportResponses: /* @__PURE__ */ new Map()
713
+ });
714
+ return sessionRef;
715
+ }
716
+ async closeSession(input) {
717
+ this.requireCapability("executor.sessionLifecycle");
718
+ const session = this.requireSession(input.sessionRef);
719
+ for (const pageRef of session.pageRefs) {
720
+ this.destroyPage(pageRef);
721
+ }
722
+ this.sessions.delete(input.sessionRef);
723
+ }
724
+ async createPage(input) {
725
+ this.requireCapability("executor.pageLifecycle");
726
+ const session = this.requireSession(input.sessionRef);
727
+ const page = this.createPageInternal(session.sessionRef, {
728
+ ...input.openerPageRef === void 0 ? {} : { openerPageRef: input.openerPageRef },
729
+ ...input.url === void 0 ? {} : { url: input.url }
730
+ });
731
+ const events = [];
732
+ const pageCreatedEvent = this.maybeCreateEvent({
733
+ kind: "page-created",
734
+ sessionRef: session.sessionRef,
735
+ pageRef: page.pageInfo.pageRef
736
+ });
737
+ if (pageCreatedEvent) {
738
+ events.push(pageCreatedEvent);
739
+ }
740
+ if (input.openerPageRef) {
741
+ const popupOpenedEvent = this.maybeCreateEvent({
742
+ kind: "popup-opened",
743
+ sessionRef: session.sessionRef,
744
+ pageRef: page.pageInfo.pageRef,
745
+ openerPageRef: input.openerPageRef
746
+ });
747
+ if (popupOpenedEvent) {
748
+ events.push(popupOpenedEvent);
749
+ }
750
+ }
751
+ return this.createStepResult(session.sessionRef, page.pageInfo.pageRef, {
752
+ frameRef: page.frameInfo.frameRef,
753
+ documentRef: page.frameInfo.documentRef,
754
+ documentEpoch: page.frameInfo.documentEpoch,
755
+ events,
756
+ data: clone(page.pageInfo)
757
+ });
758
+ }
759
+ async closePage(input) {
760
+ this.requireCapability("executor.pageLifecycle");
761
+ const page = this.requirePage(input.pageRef);
762
+ const frameInfo = this.getMainFrameInfo(page.pageRef);
763
+ const sessionRef = page.sessionRef;
764
+ this.destroyPage(page.pageRef);
765
+ const pageClosedEvent = this.maybeCreateEvent({
766
+ kind: "page-closed",
767
+ sessionRef,
768
+ pageRef: page.pageRef
769
+ });
770
+ return this.createStepResult(sessionRef, page.pageRef, {
771
+ frameRef: frameInfo.frameRef,
772
+ documentRef: frameInfo.documentRef,
773
+ documentEpoch: frameInfo.documentEpoch,
774
+ events: pageClosedEvent ? [pageClosedEvent] : [],
775
+ data: void 0
776
+ });
777
+ }
778
+ async activatePage(input) {
779
+ this.requireCapability("executor.pageLifecycle");
780
+ const page = this.requirePage(input.pageRef);
781
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
782
+ return this.createStepResult(page.sessionRef, page.pageRef, {
783
+ frameRef: mainFrame.frameRef,
784
+ documentRef: mainFrame.documentRef,
785
+ documentEpoch: mainFrame.documentEpoch,
786
+ events: this.drainQueuedEvents(page.pageRef),
787
+ data: clone(this.pageInfoFromState(page))
788
+ });
789
+ }
790
+ async navigate(input) {
791
+ return this.performNavigation(input.pageRef, input.url, {
792
+ forceNewDocument: false,
793
+ recordHistory: true,
794
+ ...input.referrer === void 0 ? {} : { referrer: input.referrer }
795
+ });
796
+ }
797
+ async reload(input) {
798
+ const page = this.requirePage(input.pageRef);
799
+ const pageInfo = this.pageInfoFromState(page);
800
+ return this.performNavigation(input.pageRef, pageInfo.url, {
801
+ forceNewDocument: true,
802
+ recordHistory: false
803
+ });
804
+ }
805
+ async goBack(input) {
806
+ this.requireCapability("executor.navigation");
807
+ const page = this.requirePage(input.pageRef);
808
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
809
+ if (page.historyIndex === 0) {
810
+ return this.createStepResult(page.sessionRef, page.pageRef, {
811
+ frameRef: mainFrame.frameRef,
812
+ documentRef: mainFrame.documentRef,
813
+ documentEpoch: mainFrame.documentEpoch,
814
+ events: this.drainQueuedEvents(page.pageRef),
815
+ data: false
816
+ });
817
+ }
818
+ page.historyIndex -= 1;
819
+ const url = page.history[page.historyIndex];
820
+ const result = await this.performNavigation(input.pageRef, url, {
821
+ forceNewDocument: false,
822
+ recordHistory: false
823
+ });
824
+ return {
825
+ ...result,
826
+ data: true
827
+ };
828
+ }
829
+ async goForward(input) {
830
+ this.requireCapability("executor.navigation");
831
+ const page = this.requirePage(input.pageRef);
832
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
833
+ if (page.historyIndex >= page.history.length - 1) {
834
+ return this.createStepResult(page.sessionRef, page.pageRef, {
835
+ frameRef: mainFrame.frameRef,
836
+ documentRef: mainFrame.documentRef,
837
+ documentEpoch: mainFrame.documentEpoch,
838
+ events: this.drainQueuedEvents(page.pageRef),
839
+ data: false
840
+ });
841
+ }
842
+ page.historyIndex += 1;
843
+ const url = page.history[page.historyIndex];
844
+ const result = await this.performNavigation(input.pageRef, url, {
845
+ forceNewDocument: false,
846
+ recordHistory: false
847
+ });
848
+ return {
849
+ ...result,
850
+ data: true
851
+ };
852
+ }
853
+ async stopLoading(input) {
854
+ this.requireCapability("executor.navigation");
855
+ const page = this.requirePage(input.pageRef);
856
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
857
+ return this.createStepResult(page.sessionRef, page.pageRef, {
858
+ frameRef: mainFrame.frameRef,
859
+ documentRef: mainFrame.documentRef,
860
+ documentEpoch: mainFrame.documentEpoch,
861
+ events: this.drainQueuedEvents(page.pageRef),
862
+ data: void 0
863
+ });
864
+ }
865
+ async mouseMove(input) {
866
+ this.requireCapability("executor.pointerInput");
867
+ const page = this.requirePage(input.pageRef);
868
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
869
+ return this.createStepResult(page.sessionRef, page.pageRef, {
870
+ frameRef: mainFrame.frameRef,
871
+ documentRef: mainFrame.documentRef,
872
+ documentEpoch: mainFrame.documentEpoch,
873
+ events: this.drainQueuedEvents(page.pageRef),
874
+ data: void 0
875
+ });
876
+ }
877
+ async mouseClick(input) {
878
+ this.requireCapability("executor.pointerInput");
879
+ const page = this.requirePage(input.pageRef);
880
+ const hitTest = await this.hitTest({
881
+ pageRef: input.pageRef,
882
+ point: input.point,
883
+ coordinateSpace: input.coordinateSpace
884
+ });
885
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
886
+ return this.createStepResult(page.sessionRef, page.pageRef, {
887
+ frameRef: mainFrame.frameRef,
888
+ documentRef: mainFrame.documentRef,
889
+ documentEpoch: mainFrame.documentEpoch,
890
+ events: this.drainQueuedEvents(page.pageRef),
891
+ data: hitTest
892
+ });
893
+ }
894
+ async mouseScroll(input) {
895
+ this.requireCapability("executor.pointerInput");
896
+ const page = this.requirePage(input.pageRef);
897
+ const mainFrame = this.getMainFrame(page.pageRef);
898
+ const nextScroll = createScrollOffset(
899
+ page.viewportMetrics.scrollOffset.x + input.delta.x,
900
+ page.viewportMetrics.scrollOffset.y + input.delta.y
901
+ );
902
+ page.viewportMetrics = {
903
+ ...page.viewportMetrics,
904
+ scrollOffset: nextScroll,
905
+ layoutViewport: {
906
+ ...page.viewportMetrics.layoutViewport,
907
+ origin: createPoint(nextScroll.x, nextScroll.y)
908
+ },
909
+ visualViewport: {
910
+ ...page.viewportMetrics.visualViewport,
911
+ origin: createPoint(nextScroll.x, nextScroll.y)
912
+ }
913
+ };
914
+ this.rebuildDocumentState(mainFrame.frameInfo.documentRef, {
915
+ documentRef: mainFrame.frameInfo.documentRef,
916
+ documentEpoch: mainFrame.frameInfo.documentEpoch,
917
+ url: mainFrame.frameInfo.url,
918
+ title: titleFromUrl(mainFrame.frameInfo.url)
919
+ });
920
+ return this.createStepResult(page.sessionRef, page.pageRef, {
921
+ frameRef: mainFrame.frameInfo.frameRef,
922
+ documentRef: mainFrame.frameInfo.documentRef,
923
+ documentEpoch: mainFrame.frameInfo.documentEpoch,
924
+ events: this.drainQueuedEvents(page.pageRef),
925
+ data: void 0
926
+ });
927
+ }
928
+ async keyPress(input) {
929
+ this.requireCapability("executor.keyboardInput");
930
+ const page = this.requirePage(input.pageRef);
931
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
932
+ return this.createStepResult(page.sessionRef, page.pageRef, {
933
+ frameRef: mainFrame.frameRef,
934
+ documentRef: mainFrame.documentRef,
935
+ documentEpoch: mainFrame.documentEpoch,
936
+ events: this.drainQueuedEvents(page.pageRef),
937
+ data: void 0
938
+ });
939
+ }
940
+ async textInput(input) {
941
+ this.requireCapability("executor.keyboardInput");
942
+ const page = this.requirePage(input.pageRef);
943
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
944
+ return this.createStepResult(page.sessionRef, page.pageRef, {
945
+ frameRef: mainFrame.frameRef,
946
+ documentRef: mainFrame.documentRef,
947
+ documentEpoch: mainFrame.documentEpoch,
948
+ events: this.drainQueuedEvents(page.pageRef),
949
+ data: void 0
950
+ });
951
+ }
952
+ async captureScreenshot(input) {
953
+ this.requireCapability("executor.screenshots");
954
+ const page = this.requirePage(input.pageRef);
955
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
956
+ const targetSize = input.fullPage ? page.viewportMetrics.contentSize : page.viewportMetrics.visualViewport.size;
957
+ const payload = bodyPayloadFromUtf8(
958
+ JSON.stringify({
959
+ pageRef: page.pageRef,
960
+ url: mainFrame.url,
961
+ format: input.format ?? "webp",
962
+ includeCursor: input.includeCursor ?? false
963
+ }),
964
+ { mimeType: `image/${input.format ?? "webp"}` }
965
+ );
966
+ const artifact = {
967
+ pageRef: page.pageRef,
968
+ frameRef: mainFrame.frameRef,
969
+ documentRef: mainFrame.documentRef,
970
+ documentEpoch: mainFrame.documentEpoch,
971
+ payload,
972
+ format: input.format ?? "webp",
973
+ size: targetSize,
974
+ coordinateSpace: input.clipSpace ?? "layout-viewport-css",
975
+ ...input.clip === void 0 ? {} : { clip: input.clip }
976
+ };
977
+ return this.createStepResult(page.sessionRef, page.pageRef, {
978
+ frameRef: mainFrame.frameRef,
979
+ documentRef: mainFrame.documentRef,
980
+ documentEpoch: mainFrame.documentEpoch,
981
+ events: this.drainQueuedEvents(page.pageRef),
982
+ data: artifact
983
+ });
984
+ }
985
+ async setExecutionState(input) {
986
+ const page = this.requirePage(input.pageRef);
987
+ const pausedChanged = input.paused !== void 0 && input.paused !== page.paused;
988
+ const frozenChanged = input.frozen !== void 0 && input.frozen !== page.frozen;
989
+ const nextPaused = input.paused ?? page.paused;
990
+ const nextFrozen = input.frozen ?? page.frozen;
991
+ if (pausedChanged) {
992
+ this.requireCapability(
993
+ nextPaused ? "executor.executionControl.pause" : "executor.executionControl.resume"
994
+ );
995
+ }
996
+ if (frozenChanged) {
997
+ this.requireCapability("executor.executionControl.freeze");
998
+ }
999
+ page.paused = nextPaused;
1000
+ page.frozen = nextFrozen;
1001
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
1002
+ const events = this.drainQueuedEvents(page.pageRef);
1003
+ if (pausedChanged) {
1004
+ const executionEvent = this.maybeCreateEvent({
1005
+ kind: nextPaused ? "paused" : "resumed",
1006
+ sessionRef: page.sessionRef,
1007
+ pageRef: page.pageRef,
1008
+ frameRef: mainFrame.frameRef,
1009
+ documentRef: mainFrame.documentRef,
1010
+ documentEpoch: mainFrame.documentEpoch
1011
+ });
1012
+ if (executionEvent) {
1013
+ events.push(executionEvent);
1014
+ }
1015
+ }
1016
+ if (frozenChanged && nextFrozen) {
1017
+ const frozenEvent = this.maybeCreateEvent({
1018
+ kind: "frozen",
1019
+ sessionRef: page.sessionRef,
1020
+ pageRef: page.pageRef,
1021
+ frameRef: mainFrame.frameRef,
1022
+ documentRef: mainFrame.documentRef,
1023
+ documentEpoch: mainFrame.documentEpoch
1024
+ });
1025
+ if (frozenEvent) {
1026
+ events.push(frozenEvent);
1027
+ }
1028
+ }
1029
+ return this.createStepResult(page.sessionRef, page.pageRef, {
1030
+ frameRef: mainFrame.frameRef,
1031
+ documentRef: mainFrame.documentRef,
1032
+ documentEpoch: mainFrame.documentEpoch,
1033
+ events,
1034
+ data: {
1035
+ paused: page.paused,
1036
+ frozen: page.frozen
1037
+ }
1038
+ });
1039
+ }
1040
+ async listPages(input) {
1041
+ this.requireCapability("inspector.pageEnumeration");
1042
+ const session = this.requireSession(input.sessionRef);
1043
+ return Array.from(
1044
+ session.pageRefs,
1045
+ (pageRef) => clone(this.pageInfoFromState(this.requirePage(pageRef)))
1046
+ );
1047
+ }
1048
+ async listFrames(input) {
1049
+ this.requireCapability("inspector.frameEnumeration");
1050
+ const page = this.requirePage(input.pageRef);
1051
+ return Array.from(page.frameRefs, (frameRef) => clone(this.requireFrame(frameRef).frameInfo));
1052
+ }
1053
+ async getPageInfo(input) {
1054
+ this.requireCapability("inspector.pageEnumeration");
1055
+ return clone(this.pageInfoFromState(this.requirePage(input.pageRef)));
1056
+ }
1057
+ async getFrameInfo(input) {
1058
+ this.requireCapability("inspector.frameEnumeration");
1059
+ return clone(this.requireFrame(input.frameRef).frameInfo);
1060
+ }
1061
+ async getHtmlSnapshot(input) {
1062
+ this.requireCapability("inspector.html");
1063
+ const document = this.resolveDocumentInput(input);
1064
+ return clone(document.htmlSnapshot);
1065
+ }
1066
+ async getDomSnapshot(input) {
1067
+ this.requireCapability("inspector.domSnapshot");
1068
+ const document = this.resolveDocumentInput(input);
1069
+ return clone(document.domSnapshot);
1070
+ }
1071
+ async waitForVisualStability(_input) {
1072
+ this.requireCapability("inspector.visualStability");
1073
+ }
1074
+ async readText(input) {
1075
+ this.requireCapability("inspector.text");
1076
+ const document = this.requireLiveNode(input);
1077
+ return clone(document.nodeText.get(input.nodeRef) ?? null);
1078
+ }
1079
+ async readAttributes(input) {
1080
+ this.requireCapability("inspector.attributes");
1081
+ const document = this.requireLiveNode(input);
1082
+ return clone(document.nodeAttributes.get(input.nodeRef) ?? []);
1083
+ }
1084
+ async hitTest(input) {
1085
+ this.requireCapability("inspector.hitTest");
1086
+ const page = this.requirePage(input.pageRef);
1087
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
1088
+ const document = this.requireDocument(mainFrame.documentRef);
1089
+ const resolvedPoint = this.resolvePoint(
1090
+ page.viewportMetrics,
1091
+ input.point,
1092
+ input.coordinateSpace
1093
+ );
1094
+ const key = this.hitTestKey(resolvedPoint, input.ignorePointerEventsNone ?? false);
1095
+ const hit = document.hitTests.get(key);
1096
+ if (hit) {
1097
+ return clone({
1098
+ inputPoint: input.point,
1099
+ inputCoordinateSpace: input.coordinateSpace,
1100
+ ...hit
1101
+ });
1102
+ }
1103
+ return {
1104
+ inputPoint: input.point,
1105
+ inputCoordinateSpace: input.coordinateSpace,
1106
+ resolvedPoint,
1107
+ resolvedCoordinateSpace: "document-css",
1108
+ pageRef: page.pageRef,
1109
+ frameRef: mainFrame.frameRef,
1110
+ documentRef: mainFrame.documentRef,
1111
+ documentEpoch: mainFrame.documentEpoch,
1112
+ obscured: false,
1113
+ pointerEventsSkipped: false
1114
+ };
1115
+ }
1116
+ async getViewportMetrics(input) {
1117
+ this.requireCapability("inspector.viewportMetrics");
1118
+ return clone(this.requirePage(input.pageRef).viewportMetrics);
1119
+ }
1120
+ async getNetworkRecords(input) {
1121
+ this.requireCapability("inspector.network");
1122
+ input.signal?.throwIfAborted?.();
1123
+ const session = this.requireSession(input.sessionRef);
1124
+ const records = [];
1125
+ const includeBodies = input.includeBodies ?? false;
1126
+ const pageRefs = input.pageRef === void 0 ? Array.from(session.pageRefs) : [input.pageRef];
1127
+ const requestIds = input.requestIds === void 0 ? void 0 : new Set(input.requestIds);
1128
+ for (const pageRef of pageRefs) {
1129
+ const page = this.requirePage(pageRef);
1130
+ const mainFrame = this.getMainFrame(page.pageRef);
1131
+ const document = this.requireDocument(mainFrame.frameInfo.documentRef);
1132
+ records.push(
1133
+ ...document.networkRecords.filter(
1134
+ (record) => (requestIds === void 0 || requestIds.has(record.requestId)) && matchesNetworkRecordFilters(record, input)
1135
+ ).map((record) => clone(record))
1136
+ );
1137
+ }
1138
+ if (!includeBodies) {
1139
+ return records.map(
1140
+ ({ requestBody: _requestBody, responseBody: _responseBody, ...record }) => ({
1141
+ ...record
1142
+ })
1143
+ );
1144
+ }
1145
+ this.requireCapability("inspector.networkBodies");
1146
+ return records;
1147
+ }
1148
+ async getCookies(input) {
1149
+ this.requireCapability("inspector.cookies");
1150
+ const session = this.requireSession(input.sessionRef);
1151
+ const cookies = input.urls && input.urls.length > 0 ? filterCookieRecords(session.cookies, input.urls) : session.cookies;
1152
+ return cookies.map((cookie) => clone(cookie));
1153
+ }
1154
+ async setCookies(input) {
1155
+ const session = this.requireSession(input.sessionRef);
1156
+ const merged = new Map(
1157
+ session.cookies.map((cookie) => [
1158
+ `${cookie.name}\0${cookie.domain}\0${cookie.path}`,
1159
+ clone(cookie)
1160
+ ])
1161
+ );
1162
+ for (const cookie of input.cookies) {
1163
+ merged.set(`${cookie.name}\0${cookie.domain}\0${cookie.path}`, clone(cookie));
1164
+ }
1165
+ session.cookies = [...merged.values()];
1166
+ }
1167
+ async getStorageSnapshot(input) {
1168
+ const session = this.requireSession(input.sessionRef);
1169
+ this.requireCapability("inspector.localStorage");
1170
+ if (input.includeSessionStorage ?? true) {
1171
+ this.requireCapability("inspector.sessionStorage");
1172
+ }
1173
+ if (input.includeIndexedDb ?? true) {
1174
+ this.requireCapability("inspector.indexedDb");
1175
+ }
1176
+ const snapshot = clone(session.storage);
1177
+ return {
1178
+ sessionRef: snapshot.sessionRef,
1179
+ capturedAt: snapshot.capturedAt,
1180
+ origins: snapshot.origins.map((origin) => ({
1181
+ origin: origin.origin,
1182
+ localStorage: origin.localStorage,
1183
+ ...(input.includeIndexedDb ?? true) && origin.indexedDb ? { indexedDb: origin.indexedDb } : {}
1184
+ })),
1185
+ ...input.includeSessionStorage ?? true ? { sessionStorage: snapshot.sessionStorage ?? [] } : {}
1186
+ };
1187
+ }
1188
+ async evaluatePage(input) {
1189
+ const page = this.requirePage(input.pageRef);
1190
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
1191
+ const value = await Promise.resolve().then(() => {
1192
+ const evaluated = (0, eval)(input.script);
1193
+ if (typeof evaluated === "function") {
1194
+ return evaluated(...input.args ?? []);
1195
+ }
1196
+ return evaluated;
1197
+ });
1198
+ return this.createStepResult(page.sessionRef, page.pageRef, {
1199
+ frameRef: mainFrame.frameRef,
1200
+ documentRef: mainFrame.documentRef,
1201
+ documentEpoch: mainFrame.documentEpoch,
1202
+ events: this.drainQueuedEvents(page.pageRef),
1203
+ data: clone(value)
1204
+ });
1205
+ }
1206
+ async executeRequest(input) {
1207
+ this.requireCapability("transport.sessionHttp");
1208
+ input.signal?.throwIfAborted?.();
1209
+ const session = this.requireSession(input.sessionRef);
1210
+ const key = buildTransportKey(input.request);
1211
+ const seededResponse = session.transportResponses.get(key);
1212
+ const response = seededResponse ?? {
1213
+ url: input.request.url,
1214
+ status: 200,
1215
+ statusText: "OK",
1216
+ headers: [createHeaderEntry("content-type", "text/plain; charset=utf-8")],
1217
+ body: bodyPayloadFromUtf8(`${input.request.method.toUpperCase()} ${input.request.url}`, {
1218
+ mimeType: "text/plain"
1219
+ }),
1220
+ redirected: false
1221
+ };
1222
+ const requestId = createNetworkRequestId(`transport-${++this.requestCounter}`);
1223
+ const transportRecord = {
1224
+ kind: "http",
1225
+ requestId,
1226
+ sessionRef: input.sessionRef,
1227
+ method: input.request.method.toUpperCase(),
1228
+ url: input.request.url,
1229
+ requestHeaders: input.request.headers ?? [],
1230
+ responseHeaders: response.headers,
1231
+ status: response.status,
1232
+ statusText: response.statusText,
1233
+ resourceType: "fetch",
1234
+ navigationRequest: false,
1235
+ captureState: "complete",
1236
+ requestBodyState: input.request.body === void 0 ? "skipped" : "complete",
1237
+ responseBodyState: response.body === void 0 ? "skipped" : "complete",
1238
+ ...input.request.body === void 0 ? { requestBodySkipReason: "not-present" } : {},
1239
+ ...response.body === void 0 ? { responseBodySkipReason: "not-present" } : {},
1240
+ ...input.request.body === void 0 ? {} : { requestBody: input.request.body },
1241
+ ...response.body === void 0 ? {} : { responseBody: response.body }
1242
+ };
1243
+ for (const pageRef of session.pageRefs) {
1244
+ const mainFrame = this.getMainFrame(pageRef);
1245
+ this.requireDocument(mainFrame.frameInfo.documentRef).networkRecords.push(transportRecord);
1246
+ break;
1247
+ }
1248
+ return this.createStepResult(input.sessionRef, void 0, {
1249
+ events: [],
1250
+ data: clone(response)
1251
+ });
1252
+ }
1253
+ createPageInternal(sessionRef, options) {
1254
+ const session = this.requireSession(sessionRef);
1255
+ const pageRef = createPageRef(`fake-${++this.pageCounter}`);
1256
+ const frameRef = createFrameRef(`fake-${++this.frameCounter}`);
1257
+ const documentRef = createDocumentRef(`fake-${++this.documentCounter}`);
1258
+ const documentEpoch = createDocumentEpoch(0);
1259
+ const url = options.url ?? "about:blank";
1260
+ const title = options.title ?? titleFromUrl(url);
1261
+ const viewportSize = options.viewportSize ?? createSize(1280, 720);
1262
+ const page = {
1263
+ pageRef,
1264
+ sessionRef,
1265
+ frameRefs: /* @__PURE__ */ new Set([frameRef]),
1266
+ queuedEvents: [],
1267
+ history: [url],
1268
+ historyIndex: 0,
1269
+ lifecycleState: "open",
1270
+ paused: false,
1271
+ frozen: false,
1272
+ viewportMetrics: {
1273
+ layoutViewport: {
1274
+ origin: createPoint(0, 0),
1275
+ size: viewportSize
1276
+ },
1277
+ visualViewport: {
1278
+ origin: createPoint(0, 0),
1279
+ offsetWithinLayoutViewport: createScrollOffset(0, 0),
1280
+ size: viewportSize
1281
+ },
1282
+ scrollOffset: createScrollOffset(0, 0),
1283
+ contentSize: createSize(1280, 2400),
1284
+ devicePixelRatio: createDevicePixelRatio(2),
1285
+ pageScaleFactor: createPageScaleFactor(1),
1286
+ pageZoomFactor: createPageZoomFactor(1)
1287
+ },
1288
+ ...options.openerPageRef === void 0 ? {} : { openerPageRef: options.openerPageRef }
1289
+ };
1290
+ const frameInfo = {
1291
+ frameRef,
1292
+ pageRef,
1293
+ documentRef,
1294
+ documentEpoch,
1295
+ url,
1296
+ isMainFrame: true
1297
+ };
1298
+ this.pages.set(pageRef, page);
1299
+ this.frames.set(frameRef, { frameInfo });
1300
+ session.pageRefs.add(pageRef);
1301
+ this.rebuildDocumentStateForFrame(pageRef, frameRef, {
1302
+ documentRef,
1303
+ documentEpoch,
1304
+ url,
1305
+ title
1306
+ });
1307
+ session.storage = this.seedDefaultSessionStorage(session.storage, pageRef, frameRef, url);
1308
+ return {
1309
+ pageInfo: this.pageInfoFromState(page, url, title),
1310
+ frameInfo
1311
+ };
1312
+ }
1313
+ pageInfoFromState(page, url, title) {
1314
+ const mainFrame = this.getMainFrameInfo(page.pageRef);
1315
+ return {
1316
+ pageRef: page.pageRef,
1317
+ sessionRef: page.sessionRef,
1318
+ url: url ?? mainFrame.url,
1319
+ title: title ?? titleFromUrl(mainFrame.url),
1320
+ lifecycleState: page.lifecycleState,
1321
+ ...page.openerPageRef === void 0 ? {} : { openerPageRef: page.openerPageRef }
1322
+ };
1323
+ }
1324
+ createDefaultStorage(sessionRef) {
1325
+ return {
1326
+ sessionRef,
1327
+ capturedAt: this.timestampMs,
1328
+ origins: [
1329
+ {
1330
+ origin: "https://example.com",
1331
+ localStorage: [
1332
+ { key: "theme", value: "dark" },
1333
+ { key: "draft", value: "hello" }
1334
+ ],
1335
+ indexedDb: [
1336
+ {
1337
+ name: "app-db",
1338
+ version: 1,
1339
+ objectStores: [
1340
+ {
1341
+ name: "messages",
1342
+ keyPath: "id",
1343
+ autoIncrement: false,
1344
+ indexes: [],
1345
+ records: [
1346
+ {
1347
+ key: "1",
1348
+ value: { id: "1", text: "hello" }
1349
+ }
1350
+ ]
1351
+ }
1352
+ ]
1353
+ }
1354
+ ]
1355
+ }
1356
+ ],
1357
+ sessionStorage: []
1358
+ };
1359
+ }
1360
+ seedDefaultSessionStorage(storage, pageRef, frameRef, url) {
1361
+ const origin = originFromUrl(url);
1362
+ if (origin === void 0) {
1363
+ return storage;
1364
+ }
1365
+ if (storage.sessionStorage?.some(
1366
+ (snapshot) => snapshot.pageRef === pageRef && snapshot.frameRef === frameRef && snapshot.origin === origin
1367
+ )) {
1368
+ return storage;
1369
+ }
1370
+ return {
1371
+ ...storage,
1372
+ sessionStorage: [
1373
+ ...storage.sessionStorage ?? [],
1374
+ {
1375
+ pageRef,
1376
+ frameRef,
1377
+ origin,
1378
+ entries: [{ key: "csrf", value: "token-123" }]
1379
+ }
1380
+ ]
1381
+ };
1382
+ }
1383
+ async performNavigation(pageRef, url, options) {
1384
+ this.requireCapability("executor.navigation");
1385
+ const page = this.requirePage(pageRef);
1386
+ const mainFrame = this.getMainFrame(page.pageRef);
1387
+ const currentFrameInfo = mainFrame.frameInfo;
1388
+ const currentDocument = this.requireDocument(currentFrameInfo.documentRef);
1389
+ const sameDocument = !options.forceNewDocument && stripFragment(currentFrameInfo.url) === stripFragment(url);
1390
+ const title = titleFromUrl(url);
1391
+ const requestBody = options.referrer === void 0 ? void 0 : bodyPayloadFromUtf8(options.referrer, { mimeType: "text/plain" });
1392
+ const requestHeaders = options.referrer === void 0 ? [] : [createHeaderEntry("referer", options.referrer)];
1393
+ let nextDocumentRef = currentFrameInfo.documentRef;
1394
+ let nextDocumentEpoch2 = currentFrameInfo.documentEpoch;
1395
+ if (sameDocument) {
1396
+ currentDocument.url = url;
1397
+ currentDocument.htmlSnapshot = {
1398
+ ...currentDocument.htmlSnapshot,
1399
+ url,
1400
+ capturedAt: this.nextTimestamp()
1401
+ };
1402
+ currentDocument.domSnapshot = {
1403
+ ...currentDocument.domSnapshot,
1404
+ url,
1405
+ capturedAt: this.nextTimestamp()
1406
+ };
1407
+ mainFrame.frameInfo = {
1408
+ ...currentFrameInfo,
1409
+ url
1410
+ };
1411
+ } else {
1412
+ nextDocumentRef = createDocumentRef(`fake-${++this.documentCounter}`);
1413
+ nextDocumentEpoch2 = createDocumentEpoch(0);
1414
+ mainFrame.frameInfo = {
1415
+ ...currentFrameInfo,
1416
+ url,
1417
+ documentRef: nextDocumentRef,
1418
+ documentEpoch: nextDocumentEpoch2
1419
+ };
1420
+ this.rebuildDocumentStateForFrame(page.pageRef, currentFrameInfo.frameRef, {
1421
+ documentRef: nextDocumentRef,
1422
+ documentEpoch: nextDocumentEpoch2,
1423
+ url,
1424
+ title
1425
+ });
1426
+ this.retireDocument(currentFrameInfo.documentRef);
1427
+ const requestId = createNetworkRequestId(`fake-${++this.requestCounter}`);
1428
+ const responseBody = bodyPayloadFromUtf8(`<html><title>${title}</title></html>`, {
1429
+ mimeType: "text/html"
1430
+ });
1431
+ this.requireDocument(nextDocumentRef).networkRecords.push({
1432
+ kind: "http",
1433
+ requestId,
1434
+ sessionRef: page.sessionRef,
1435
+ pageRef: page.pageRef,
1436
+ frameRef: currentFrameInfo.frameRef,
1437
+ documentRef: nextDocumentRef,
1438
+ method: "GET",
1439
+ url,
1440
+ requestHeaders,
1441
+ responseHeaders: [
1442
+ createHeaderEntry("content-type", "text/html; charset=utf-8"),
1443
+ createHeaderEntry("set-cookie", "session=abc"),
1444
+ createHeaderEntry("set-cookie", "theme=dark")
1445
+ ],
1446
+ status: 200,
1447
+ statusText: "OK",
1448
+ resourceType: "document",
1449
+ navigationRequest: true,
1450
+ captureState: "complete",
1451
+ requestBodyState: requestBody === void 0 ? "skipped" : "complete",
1452
+ responseBodyState: "complete",
1453
+ ...requestBody === void 0 ? { requestBodySkipReason: "not-present" } : {},
1454
+ timing: {
1455
+ requestStartMs: this.timestampMs,
1456
+ responseStartMs: this.timestampMs + 5,
1457
+ responseEndMs: this.timestampMs + 10
1458
+ },
1459
+ transfer: {
1460
+ encodedBodyBytes: responseBody.capturedByteLength,
1461
+ decodedBodyBytes: responseBody.capturedByteLength,
1462
+ transferSizeBytes: responseBody.capturedByteLength + 256
1463
+ },
1464
+ ...requestBody === void 0 ? {} : { requestBody },
1465
+ responseBody
1466
+ });
1467
+ }
1468
+ if (options.recordHistory) {
1469
+ page.history = [...page.history.slice(0, page.historyIndex + 1), url];
1470
+ page.historyIndex = page.history.length - 1;
1471
+ }
1472
+ const pageInfo = this.pageInfoFromState(page, url, title);
1473
+ return this.createStepResult(page.sessionRef, page.pageRef, {
1474
+ frameRef: mainFrame.frameInfo.frameRef,
1475
+ documentRef: nextDocumentRef,
1476
+ documentEpoch: nextDocumentEpoch2,
1477
+ events: this.drainQueuedEvents(page.pageRef),
1478
+ data: {
1479
+ pageInfo,
1480
+ mainFrame: clone(mainFrame.frameInfo)
1481
+ }
1482
+ });
1483
+ }
1484
+ createDocumentSnapshot(pageRef, frameRef, documentRef, documentEpoch, url, title) {
1485
+ const bodyRect = createRect(0, 0, 1280, 2400);
1486
+ const buttonRect = createRect(16, 16, 160, 48);
1487
+ const obscuredRect = createRect(240, 16, 160, 48);
1488
+ const titleRect = createRect(16, 96, 220, 32);
1489
+ const buttonRef = createNodeRef(`fake-${++this.nodeCounter}`);
1490
+ const obscuredRef = createNodeRef(`fake-${++this.nodeCounter}`);
1491
+ const documentNodeRef = createNodeRef(`fake-${++this.nodeCounter}`);
1492
+ const htmlNodeRef = createNodeRef(`fake-${++this.nodeCounter}`);
1493
+ const bodyNodeRef = createNodeRef(`fake-${++this.nodeCounter}`);
1494
+ const titleRef = createNodeRef(`fake-${++this.nodeCounter}`);
1495
+ const hiddenPanelRef = createNodeRef(`fake-${++this.nodeCounter}`);
1496
+ const shadowHostRef = createNodeRef(`fake-${++this.nodeCounter}`);
1497
+ const shadowActionRef = createNodeRef(`fake-${++this.nodeCounter}`);
1498
+ const nestedShadowHostRef = createNodeRef(`fake-${++this.nodeCounter}`);
1499
+ const nestedShadowActionRef = createNodeRef(`fake-${++this.nodeCounter}`);
1500
+ const nodes = [
1501
+ {
1502
+ snapshotNodeId: 1,
1503
+ nodeRef: documentNodeRef,
1504
+ childSnapshotNodeIds: [2],
1505
+ nodeType: 9,
1506
+ nodeName: "#document",
1507
+ nodeValue: "",
1508
+ attributes: []
1509
+ },
1510
+ {
1511
+ snapshotNodeId: 2,
1512
+ nodeRef: htmlNodeRef,
1513
+ parentSnapshotNodeId: 1,
1514
+ childSnapshotNodeIds: [3],
1515
+ nodeType: 1,
1516
+ nodeName: "HTML",
1517
+ nodeValue: "",
1518
+ attributes: []
1519
+ },
1520
+ {
1521
+ snapshotNodeId: 3,
1522
+ nodeRef: bodyNodeRef,
1523
+ parentSnapshotNodeId: 2,
1524
+ childSnapshotNodeIds: [4, 5, 6, 7, 8, 9, 10, 11],
1525
+ nodeType: 1,
1526
+ nodeName: "BODY",
1527
+ nodeValue: "",
1528
+ attributes: [],
1529
+ layout: {
1530
+ rect: bodyRect,
1531
+ quad: rectToQuad(bodyRect),
1532
+ paintOrder: 1
1533
+ }
1534
+ },
1535
+ {
1536
+ snapshotNodeId: 4,
1537
+ nodeRef: buttonRef,
1538
+ parentSnapshotNodeId: 3,
1539
+ childSnapshotNodeIds: [],
1540
+ nodeType: 1,
1541
+ nodeName: "BUTTON",
1542
+ nodeValue: "",
1543
+ textContent: "Continue",
1544
+ attributes: [
1545
+ { name: "id", value: "continue" },
1546
+ { name: "type", value: "button" }
1547
+ ],
1548
+ layout: {
1549
+ rect: buttonRect,
1550
+ quad: rectToQuad(buttonRect),
1551
+ paintOrder: 2
1552
+ }
1553
+ },
1554
+ {
1555
+ snapshotNodeId: 5,
1556
+ nodeRef: obscuredRef,
1557
+ parentSnapshotNodeId: 3,
1558
+ childSnapshotNodeIds: [],
1559
+ nodeType: 1,
1560
+ nodeName: "DIV",
1561
+ nodeValue: "",
1562
+ textContent: "Overlay",
1563
+ attributes: [{ name: "id", value: "overlay" }],
1564
+ layout: {
1565
+ rect: obscuredRect,
1566
+ quad: rectToQuad(obscuredRect),
1567
+ paintOrder: 3
1568
+ }
1569
+ },
1570
+ {
1571
+ snapshotNodeId: 6,
1572
+ nodeRef: titleRef,
1573
+ parentSnapshotNodeId: 3,
1574
+ childSnapshotNodeIds: [],
1575
+ nodeType: 1,
1576
+ nodeName: "H1",
1577
+ nodeValue: "",
1578
+ textContent: "Snapshot Heading",
1579
+ attributes: [{ name: "id", value: "snapshot-title" }],
1580
+ layout: {
1581
+ rect: titleRect,
1582
+ quad: rectToQuad(titleRect),
1583
+ paintOrder: 4
1584
+ }
1585
+ },
1586
+ {
1587
+ snapshotNodeId: 7,
1588
+ nodeRef: hiddenPanelRef,
1589
+ parentSnapshotNodeId: 3,
1590
+ childSnapshotNodeIds: [],
1591
+ nodeType: 1,
1592
+ nodeName: "DIV",
1593
+ nodeValue: "",
1594
+ textContent: "Hidden panel",
1595
+ computedStyle: {
1596
+ display: "none"
1597
+ },
1598
+ attributes: [{ name: "id", value: "hidden-panel" }]
1599
+ },
1600
+ {
1601
+ snapshotNodeId: 8,
1602
+ nodeRef: shadowHostRef,
1603
+ parentSnapshotNodeId: 3,
1604
+ childSnapshotNodeIds: [],
1605
+ nodeType: 1,
1606
+ nodeName: "DIV",
1607
+ nodeValue: "",
1608
+ textContent: "",
1609
+ attributes: [{ name: "id", value: "shadow-host" }]
1610
+ },
1611
+ {
1612
+ snapshotNodeId: 9,
1613
+ nodeRef: shadowActionRef,
1614
+ parentSnapshotNodeId: 3,
1615
+ childSnapshotNodeIds: [],
1616
+ shadowHostNodeRef: shadowHostRef,
1617
+ nodeType: 1,
1618
+ nodeName: "BUTTON",
1619
+ nodeValue: "",
1620
+ textContent: "Shadow Action",
1621
+ attributes: [{ name: "id", value: "shadow-action" }]
1622
+ },
1623
+ {
1624
+ snapshotNodeId: 10,
1625
+ nodeRef: nestedShadowHostRef,
1626
+ parentSnapshotNodeId: 3,
1627
+ childSnapshotNodeIds: [],
1628
+ nodeType: 1,
1629
+ nodeName: "DIV",
1630
+ nodeValue: "",
1631
+ textContent: "",
1632
+ attributes: [{ name: "id", value: "nested-shadow-host" }]
1633
+ },
1634
+ {
1635
+ snapshotNodeId: 11,
1636
+ nodeRef: nestedShadowActionRef,
1637
+ parentSnapshotNodeId: 3,
1638
+ childSnapshotNodeIds: [],
1639
+ shadowHostNodeRef: nestedShadowHostRef,
1640
+ nodeType: 1,
1641
+ nodeName: "BUTTON",
1642
+ nodeValue: "",
1643
+ textContent: "Nested Shadow",
1644
+ attributes: [{ name: "id", value: "nested-shadow-action" }]
1645
+ }
1646
+ ];
1647
+ const domSnapshot = {
1648
+ pageRef,
1649
+ frameRef,
1650
+ documentRef,
1651
+ documentEpoch,
1652
+ url,
1653
+ capturedAt: this.timestampMs,
1654
+ rootSnapshotNodeId: 1,
1655
+ shadowDomMode: "flattened",
1656
+ geometryCoordinateSpace: "document-css",
1657
+ nodes
1658
+ };
1659
+ const nodeText = /* @__PURE__ */ new Map([
1660
+ [buttonRef, "Continue"],
1661
+ [obscuredRef, "Overlay"],
1662
+ [titleRef, "Snapshot Heading"],
1663
+ [hiddenPanelRef, "Hidden panel"],
1664
+ [shadowHostRef, ""],
1665
+ [shadowActionRef, "Shadow Action"],
1666
+ [nestedShadowHostRef, ""],
1667
+ [nestedShadowActionRef, "Nested Shadow"],
1668
+ [documentNodeRef, null],
1669
+ [htmlNodeRef, null],
1670
+ [bodyNodeRef, null]
1671
+ ]);
1672
+ const nodeAttributes = /* @__PURE__ */ new Map([
1673
+ [buttonRef, nodes[3].attributes],
1674
+ [obscuredRef, nodes[4].attributes],
1675
+ [titleRef, nodes[5].attributes],
1676
+ [hiddenPanelRef, nodes[6].attributes],
1677
+ [shadowHostRef, nodes[7].attributes],
1678
+ [shadowActionRef, nodes[8].attributes],
1679
+ [nestedShadowHostRef, nodes[9].attributes],
1680
+ [nestedShadowActionRef, nodes[10].attributes],
1681
+ [documentNodeRef, []],
1682
+ [htmlNodeRef, []],
1683
+ [bodyNodeRef, []]
1684
+ ]);
1685
+ const nodeRects = /* @__PURE__ */ new Map([
1686
+ [buttonRef, buttonRect],
1687
+ [obscuredRef, obscuredRect],
1688
+ [titleRef, titleRect],
1689
+ [bodyNodeRef, bodyRect]
1690
+ ]);
1691
+ const hitTests = /* @__PURE__ */ new Map([
1692
+ [
1693
+ this.hitTestKey(createPoint(20, 20), false),
1694
+ {
1695
+ resolvedPoint: createPoint(20, 20),
1696
+ resolvedCoordinateSpace: "document-css",
1697
+ pageRef,
1698
+ frameRef,
1699
+ documentRef,
1700
+ documentEpoch,
1701
+ nodeRef: buttonRef,
1702
+ targetQuad: rectToQuad(buttonRect),
1703
+ obscured: false,
1704
+ pointerEventsSkipped: false
1705
+ }
1706
+ ],
1707
+ [
1708
+ this.hitTestKey(createPoint(260, 20), false),
1709
+ {
1710
+ resolvedPoint: createPoint(260, 20),
1711
+ resolvedCoordinateSpace: "document-css",
1712
+ pageRef,
1713
+ frameRef,
1714
+ documentRef,
1715
+ documentEpoch,
1716
+ nodeRef: obscuredRef,
1717
+ targetQuad: rectToQuad(obscuredRect),
1718
+ obscured: true,
1719
+ pointerEventsSkipped: false
1720
+ }
1721
+ ],
1722
+ [
1723
+ this.hitTestKey(createPoint(20, 20), true),
1724
+ {
1725
+ resolvedPoint: createPoint(20, 20),
1726
+ resolvedCoordinateSpace: "document-css",
1727
+ pageRef,
1728
+ frameRef,
1729
+ documentRef,
1730
+ documentEpoch,
1731
+ nodeRef: buttonRef,
1732
+ targetQuad: rectToQuad(buttonRect),
1733
+ obscured: false,
1734
+ pointerEventsSkipped: true
1735
+ }
1736
+ ]
1737
+ ]);
1738
+ return {
1739
+ htmlSnapshot: {
1740
+ pageRef,
1741
+ frameRef,
1742
+ documentRef,
1743
+ documentEpoch,
1744
+ url,
1745
+ capturedAt: this.timestampMs,
1746
+ html: `<html><head><title>${title}</title></head><body><button id="continue" type="button">Continue</button><div id="overlay">Overlay</div><h1 id="snapshot-title">Snapshot Heading</h1><div id="hidden-panel" style="display:none">Hidden panel</div><div id="shadow-host"></div><button id="shadow-action">Shadow Action</button><div id="nested-shadow-host"></div><button id="nested-shadow-action">Nested Shadow</button></body></html>`
1747
+ },
1748
+ domSnapshot,
1749
+ nodeText,
1750
+ nodeAttributes,
1751
+ nodeRects,
1752
+ hitTests,
1753
+ networkRecords: []
1754
+ };
1755
+ }
1756
+ rebuildDocumentStateForFrame(pageRef, frameRef, input) {
1757
+ const nextState = this.createDocumentSnapshot(
1758
+ pageRef,
1759
+ frameRef,
1760
+ input.documentRef,
1761
+ input.documentEpoch,
1762
+ input.url,
1763
+ input.title
1764
+ );
1765
+ this.retiredDocuments.delete(input.documentRef);
1766
+ this.documents.set(input.documentRef, {
1767
+ pageRef,
1768
+ frameRef,
1769
+ documentRef: input.documentRef,
1770
+ documentEpoch: input.documentEpoch,
1771
+ url: input.url,
1772
+ ...nextState
1773
+ });
1774
+ }
1775
+ rebuildDocumentState(documentRef, input) {
1776
+ const existing = this.requireDocument(documentRef);
1777
+ this.rebuildDocumentStateForFrame(existing.pageRef, existing.frameRef, input);
1778
+ const frame = this.requireFrame(existing.frameRef);
1779
+ frame.frameInfo = {
1780
+ ...frame.frameInfo,
1781
+ documentRef: input.documentRef,
1782
+ documentEpoch: input.documentEpoch,
1783
+ url: input.url
1784
+ };
1785
+ }
1786
+ resolveDocumentInput(input) {
1787
+ if (input.frameRef && input.documentRef) {
1788
+ throw createBrowserCoreError(
1789
+ "invalid-argument",
1790
+ "provide either frameRef or documentRef, not both"
1791
+ );
1792
+ }
1793
+ if (input.documentRef) {
1794
+ return this.requireDocument(input.documentRef);
1795
+ }
1796
+ if (input.frameRef) {
1797
+ return this.requireDocument(this.requireFrame(input.frameRef).frameInfo.documentRef);
1798
+ }
1799
+ throw createBrowserCoreError("invalid-argument", "either frameRef or documentRef is required");
1800
+ }
1801
+ requireLiveNode(input) {
1802
+ if (this.retiredDocuments.has(input.documentRef)) {
1803
+ throw staleNodeRefError(input);
1804
+ }
1805
+ const document = this.requireDocument(input.documentRef);
1806
+ if (document.documentEpoch !== input.documentEpoch) {
1807
+ throw staleNodeRefError(input);
1808
+ }
1809
+ const node = findDomSnapshotNodeByRef(document.domSnapshot, input.nodeRef);
1810
+ if (!node) {
1811
+ throw staleNodeRefError(input);
1812
+ }
1813
+ return document;
1814
+ }
1815
+ resolvePoint(metrics, point, coordinateSpace) {
1816
+ switch (coordinateSpace) {
1817
+ case "document-css":
1818
+ return point;
1819
+ case "layout-viewport-css":
1820
+ case "visual-viewport-css":
1821
+ return createPoint(point.x + metrics.scrollOffset.x, point.y + metrics.scrollOffset.y);
1822
+ case "computer-display-css":
1823
+ throw createBrowserCoreError(
1824
+ "unsupported-capability",
1825
+ `coordinate space ${coordinateSpace} is not supported by the fake engine`,
1826
+ {
1827
+ details: {
1828
+ coordinateSpace
1829
+ }
1830
+ }
1831
+ );
1832
+ case "window":
1833
+ case "screen":
1834
+ case "device-pixel":
1835
+ return createPoint(
1836
+ point.x / metrics.devicePixelRatio + metrics.scrollOffset.x,
1837
+ point.y / metrics.devicePixelRatio + metrics.scrollOffset.y
1838
+ );
1839
+ }
1840
+ throw createBrowserCoreError(
1841
+ "invalid-argument",
1842
+ `coordinate space ${coordinateSpace} is not supported by the fake engine`
1843
+ );
1844
+ }
1845
+ hitTestKey(point, ignorePointerEventsNone) {
1846
+ return `${Math.round(point.x)}:${Math.round(point.y)}:${ignorePointerEventsNone ? "ignore" : "respect"}`;
1847
+ }
1848
+ requireCapability(path) {
1849
+ if (!hasCapability(this.capabilities, path)) {
1850
+ throw unsupportedCapabilityError(path);
1851
+ }
1852
+ }
1853
+ assertEventCapability(kind) {
1854
+ const capability = this.eventCapabilityForKind(kind);
1855
+ if (!hasCapability(this.capabilities, capability)) {
1856
+ throw unsupportedCapabilityError(capability);
1857
+ }
1858
+ }
1859
+ eventCapabilityForKind(kind) {
1860
+ switch (kind) {
1861
+ case "page-created":
1862
+ case "popup-opened":
1863
+ case "page-closed":
1864
+ return "events.pageLifecycle";
1865
+ case "dialog-opened":
1866
+ return "events.dialog";
1867
+ case "download-started":
1868
+ case "download-finished":
1869
+ return "events.download";
1870
+ case "chooser-opened":
1871
+ return "events.chooser";
1872
+ case "worker-created":
1873
+ case "worker-destroyed":
1874
+ return "events.worker";
1875
+ case "console":
1876
+ return "events.console";
1877
+ case "page-error":
1878
+ return "events.pageError";
1879
+ case "websocket-opened":
1880
+ case "websocket-frame":
1881
+ case "websocket-closed":
1882
+ return "events.websocket";
1883
+ case "event-stream-message":
1884
+ return "events.eventStream";
1885
+ case "paused":
1886
+ case "resumed":
1887
+ case "frozen":
1888
+ return "events.executionState";
1889
+ }
1890
+ }
1891
+ createEvent(value) {
1892
+ this.assertEventCapability(value.kind);
1893
+ return {
1894
+ ...value,
1895
+ eventId: `event:${++this.eventCounter}`,
1896
+ timestamp: this.nextTimestamp()
1897
+ };
1898
+ }
1899
+ maybeCreateEvent(value) {
1900
+ if (!hasCapability(this.capabilities, this.eventCapabilityForKind(value.kind))) {
1901
+ return void 0;
1902
+ }
1903
+ return this.createEvent(value);
1904
+ }
1905
+ createStepResult(sessionRef, pageRef, input) {
1906
+ const startedAt = this.nextTimestamp();
1907
+ const completedAt = this.nextTimestamp();
1908
+ return {
1909
+ stepId: `step:${++this.stepCounter}`,
1910
+ sessionRef,
1911
+ startedAt,
1912
+ completedAt,
1913
+ durationMs: completedAt - startedAt,
1914
+ events: input.events.map((event) => clone(event)),
1915
+ data: clone(input.data),
1916
+ ...pageRef === void 0 ? {} : { pageRef },
1917
+ ...input.frameRef === void 0 ? {} : { frameRef: input.frameRef },
1918
+ ...input.documentRef === void 0 ? {} : { documentRef: input.documentRef },
1919
+ ...input.documentEpoch === void 0 ? {} : { documentEpoch: input.documentEpoch }
1920
+ };
1921
+ }
1922
+ drainQueuedEvents(pageRef) {
1923
+ const page = this.requirePage(pageRef);
1924
+ const events = page.queuedEvents.splice(0, page.queuedEvents.length);
1925
+ return events.map((event) => clone(event));
1926
+ }
1927
+ requireSession(sessionRef) {
1928
+ const session = this.sessions.get(sessionRef);
1929
+ if (!session) {
1930
+ throw closedSessionError(sessionRef);
1931
+ }
1932
+ return session;
1933
+ }
1934
+ requirePage(pageRef) {
1935
+ const page = this.pages.get(pageRef);
1936
+ if (!page || page.lifecycleState === "closed") {
1937
+ throw closedPageError(pageRef);
1938
+ }
1939
+ return page;
1940
+ }
1941
+ requireFrame(frameRef) {
1942
+ const frame = this.frames.get(frameRef);
1943
+ if (!frame) {
1944
+ throw createBrowserCoreError("not-found", `frame ${frameRef} was not found`, {
1945
+ details: { frameRef }
1946
+ });
1947
+ }
1948
+ return frame;
1949
+ }
1950
+ requireDocument(documentRef) {
1951
+ const document = this.documents.get(documentRef);
1952
+ if (!document) {
1953
+ throw createBrowserCoreError("not-found", `document ${documentRef} was not found`, {
1954
+ details: { documentRef }
1955
+ });
1956
+ }
1957
+ return document;
1958
+ }
1959
+ getMainFrame(pageRef) {
1960
+ const page = this.requirePage(pageRef);
1961
+ const mainFrameRef = Array.from(page.frameRefs).find(
1962
+ (frameRef) => this.requireFrame(frameRef).frameInfo.isMainFrame
1963
+ );
1964
+ if (!mainFrameRef) {
1965
+ throw createBrowserCoreError("operation-failed", `page ${pageRef} has no main frame`);
1966
+ }
1967
+ return this.requireFrame(mainFrameRef);
1968
+ }
1969
+ getMainFrameInfo(pageRef) {
1970
+ return clone(this.getMainFrame(pageRef).frameInfo);
1971
+ }
1972
+ destroyPage(pageRef) {
1973
+ const page = this.requirePage(pageRef);
1974
+ page.lifecycleState = "closed";
1975
+ this.pages.delete(pageRef);
1976
+ const session = this.requireSession(page.sessionRef);
1977
+ session.pageRefs.delete(pageRef);
1978
+ for (const frameRef of page.frameRefs) {
1979
+ const frame = this.frames.get(frameRef);
1980
+ if (!frame) {
1981
+ continue;
1982
+ }
1983
+ this.documents.delete(frame.frameInfo.documentRef);
1984
+ this.frames.delete(frameRef);
1985
+ }
1986
+ }
1987
+ retireDocument(documentRef) {
1988
+ this.documents.delete(documentRef);
1989
+ this.retiredDocuments.add(documentRef);
1990
+ }
1991
+ nextTimestamp() {
1992
+ return this.timestampMs += 5;
1993
+ }
1994
+ };
1995
+ function createFakeBrowserCoreEngine(options = {}) {
1996
+ const capabilities = options.capabilities ?? allBrowserCapabilities();
1997
+ return new FakeBrowserCoreEngine({ ...options, capabilities });
1998
+ }
1999
+
2000
+ // src/cdp-dom-snapshot.ts
2001
+ var DOM_SNAPSHOT_COMPUTED_STYLE_NAMES = [
2002
+ "display",
2003
+ "visibility",
2004
+ "opacity",
2005
+ "position",
2006
+ "cursor",
2007
+ "overflow-x",
2008
+ "overflow-y"
2009
+ ];
2010
+ function parseCdpStringTable(strings, index) {
2011
+ if (index === void 0 || index < 0) {
2012
+ return "";
2013
+ }
2014
+ return strings[index] ?? "";
2015
+ }
2016
+ function rareCdpStringValue(strings, data, index) {
2017
+ if (!data) {
2018
+ return void 0;
2019
+ }
2020
+ const matchIndex = data.index.findIndex((candidate) => candidate === index);
2021
+ if (matchIndex === -1) {
2022
+ return void 0;
2023
+ }
2024
+ return parseCdpStringTable(strings, data.value[matchIndex]);
2025
+ }
2026
+ function rareCdpIntegerValue(data, index) {
2027
+ if (!data) {
2028
+ return void 0;
2029
+ }
2030
+ const matchIndex = data.index.findIndex((candidate) => candidate === index);
2031
+ if (matchIndex === -1) {
2032
+ return void 0;
2033
+ }
2034
+ return data.value[matchIndex];
2035
+ }
2036
+ function normalizeCdpShadowRootType(value) {
2037
+ switch (value) {
2038
+ case "open":
2039
+ case "closed":
2040
+ return value;
2041
+ case "user-agent":
2042
+ case "user_agent":
2043
+ return "user-agent";
2044
+ default:
2045
+ return void 0;
2046
+ }
2047
+ }
2048
+ function buildCdpShadowBoundaryIndex(root) {
2049
+ const byBackendNodeId = /* @__PURE__ */ new Map();
2050
+ const visit = (node, boundary) => {
2051
+ if (node.backendNodeId !== void 0) {
2052
+ byBackendNodeId.set(node.backendNodeId, boundary);
2053
+ }
2054
+ for (const child of node.children ?? []) {
2055
+ visit(child, boundary);
2056
+ }
2057
+ for (const shadowRoot of node.shadowRoots ?? []) {
2058
+ const normalizedShadowRootType = normalizeCdpShadowRootType(shadowRoot.shadowRootType);
2059
+ const shadowBoundary = {
2060
+ ...node.backendNodeId === void 0 ? {} : { shadowHostBackendNodeId: node.backendNodeId },
2061
+ ...normalizedShadowRootType === void 0 ? {} : { shadowRootType: normalizedShadowRootType }
2062
+ };
2063
+ if (shadowRoot.backendNodeId !== void 0) {
2064
+ byBackendNodeId.set(shadowRoot.backendNodeId, shadowBoundary);
2065
+ }
2066
+ for (const child of shadowRoot.children ?? []) {
2067
+ visit(child, shadowBoundary);
2068
+ }
2069
+ }
2070
+ if (node.contentDocument) {
2071
+ visit(node.contentDocument, {});
2072
+ }
2073
+ };
2074
+ visit(root, {});
2075
+ return byBackendNodeId;
2076
+ }
2077
+ function buildDomSnapshotFromCdpCapture(document, captured, nodeRefResolver, contentDocRefResolver) {
2078
+ const parentIndexes = captured.rawDocument.nodes.parentIndex ?? [];
2079
+ const childIndexes = /* @__PURE__ */ new Map();
2080
+ for (let index = 0; index < parentIndexes.length; index += 1) {
2081
+ const parentIndex = parentIndexes[index];
2082
+ if (parentIndex === void 0 || parentIndex < 0) {
2083
+ continue;
2084
+ }
2085
+ const children = childIndexes.get(parentIndex) ?? [];
2086
+ children.push(index);
2087
+ childIndexes.set(parentIndex, children);
2088
+ }
2089
+ const layoutByNodeIndex = decodeLayoutByNodeIndex(captured.rawDocument, captured.strings);
2090
+ const aggregatedTextByNodeIndex = buildAggregatedTextIndex(
2091
+ captured.rawDocument,
2092
+ captured.shadowBoundariesByBackendNodeId,
2093
+ captured.strings
2094
+ );
2095
+ const rootNodeIndex = findRootNodeIndex(parentIndexes);
2096
+ const nodes = [];
2097
+ const nodeCount = captured.rawDocument.nodes.nodeType?.length ?? 0;
2098
+ for (let index = 0; index < nodeCount; index += 1) {
2099
+ const backendNodeId = captured.rawDocument.nodes.backendNodeId?.[index];
2100
+ const nodeRef = backendNodeId === void 0 ? void 0 : nodeRefResolver(backendNodeId);
2101
+ const rawAttributes = captured.rawDocument.nodes.attributes?.[index] ?? [];
2102
+ const attributes = [];
2103
+ for (let pairIndex = 0; pairIndex < rawAttributes.length; pairIndex += 2) {
2104
+ const nameIndex = rawAttributes[pairIndex];
2105
+ const valueIndex = rawAttributes[pairIndex + 1];
2106
+ if (nameIndex === void 0 || valueIndex === void 0) {
2107
+ continue;
2108
+ }
2109
+ attributes.push({
2110
+ name: parseCdpStringTable(captured.strings, nameIndex),
2111
+ value: parseCdpStringTable(captured.strings, valueIndex)
2112
+ });
2113
+ }
2114
+ const directShadowRootType = rareCdpStringValue(
2115
+ captured.strings,
2116
+ captured.rawDocument.nodes.shadowRootType,
2117
+ index
2118
+ );
2119
+ const normalizedShadowRootType = normalizeCdpShadowRootType(directShadowRootType);
2120
+ const shadowBoundary = backendNodeId === void 0 ? void 0 : captured.shadowBoundariesByBackendNodeId.get(backendNodeId);
2121
+ const shadowHostNodeRef = shadowBoundary?.shadowHostBackendNodeId === void 0 ? void 0 : nodeRefResolver(shadowBoundary.shadowHostBackendNodeId);
2122
+ const contentDocumentIndex = rareCdpIntegerValue(
2123
+ captured.rawDocument.nodes.contentDocumentIndex,
2124
+ index
2125
+ );
2126
+ const contentDocumentRef = contentDocumentIndex === void 0 ? void 0 : contentDocRefResolver(contentDocumentIndex);
2127
+ const layout = layoutByNodeIndex.get(index);
2128
+ const textContent = aggregatedTextByNodeIndex.get(index);
2129
+ const computedStyle = layout?.computedStyle ?? decodeInlineComputedStyle(attributes);
2130
+ nodes.push({
2131
+ snapshotNodeId: index + 1,
2132
+ ...nodeRef === void 0 ? {} : { nodeRef },
2133
+ ...parentIndexes[index] === void 0 || parentIndexes[index] < 0 ? {} : { parentSnapshotNodeId: parentIndexes[index] + 1 },
2134
+ childSnapshotNodeIds: (childIndexes.get(index) ?? []).map((childIndex) => childIndex + 1),
2135
+ ...normalizedShadowRootType === void 0 ? {} : { shadowRootType: normalizedShadowRootType },
2136
+ ...shadowHostNodeRef === void 0 ? {} : { shadowHostNodeRef },
2137
+ ...contentDocumentRef === void 0 ? {} : { contentDocumentRef },
2138
+ nodeType: captured.rawDocument.nodes.nodeType?.[index] ?? 0,
2139
+ nodeName: parseCdpStringTable(captured.strings, captured.rawDocument.nodes.nodeName?.[index]),
2140
+ nodeValue: parseCdpStringTable(
2141
+ captured.strings,
2142
+ captured.rawDocument.nodes.nodeValue?.[index]
2143
+ ),
2144
+ ...textContent === void 0 || textContent.length === 0 ? {} : { textContent },
2145
+ ...computedStyle === void 0 ? {} : { computedStyle },
2146
+ attributes,
2147
+ ...layout?.rect === void 0 ? {} : {
2148
+ layout: {
2149
+ rect: layout.rect,
2150
+ quad: rectToQuad(layout.rect),
2151
+ ...layout.paintOrder === void 0 ? {} : { paintOrder: layout.paintOrder }
2152
+ }
2153
+ }
2154
+ });
2155
+ }
2156
+ return {
2157
+ pageRef: document.pageRef,
2158
+ frameRef: document.frameRef,
2159
+ documentRef: document.documentRef,
2160
+ ...document.parentDocumentRef === void 0 ? {} : { parentDocumentRef: document.parentDocumentRef },
2161
+ documentEpoch: document.documentEpoch,
2162
+ url: document.url,
2163
+ capturedAt: captured.capturedAt,
2164
+ rootSnapshotNodeId: rootNodeIndex + 1,
2165
+ shadowDomMode: "preserved",
2166
+ geometryCoordinateSpace: "document-css",
2167
+ nodes
2168
+ };
2169
+ }
2170
+ function findRootNodeIndex(parentIndexes) {
2171
+ const explicitRootIndex = parentIndexes.findIndex(
2172
+ (parentIndex) => parentIndex === void 0 || parentIndex < 0
2173
+ );
2174
+ return explicitRootIndex >= 0 ? explicitRootIndex : 0;
2175
+ }
2176
+ function decodeLayoutByNodeIndex(document, strings) {
2177
+ const byNodeIndex = /* @__PURE__ */ new Map();
2178
+ for (let layoutIndex = 0; layoutIndex < document.layout.nodeIndex.length; layoutIndex += 1) {
2179
+ const nodeIndex = document.layout.nodeIndex[layoutIndex];
2180
+ if (nodeIndex === void 0) {
2181
+ continue;
2182
+ }
2183
+ const bounds = document.layout.bounds[layoutIndex];
2184
+ const styleIndexes = document.layout.styles?.[layoutIndex];
2185
+ byNodeIndex.set(nodeIndex, {
2186
+ ...bounds === void 0 ? {} : {
2187
+ rect: createRect(bounds[0] ?? 0, bounds[1] ?? 0, bounds[2] ?? 0, bounds[3] ?? 0)
2188
+ },
2189
+ ...document.layout.paintOrders?.[layoutIndex] === void 0 ? {} : { paintOrder: document.layout.paintOrders[layoutIndex] },
2190
+ ...styleIndexes === void 0 ? {} : { computedStyle: decodeComputedStyle(styleIndexes, strings) }
2191
+ });
2192
+ }
2193
+ return byNodeIndex;
2194
+ }
2195
+ function decodeComputedStyle(styleIndexes, strings) {
2196
+ const styleEntries = DOM_SNAPSHOT_COMPUTED_STYLE_NAMES.reduce(
2197
+ (out, propertyName, propertyIndex) => {
2198
+ const value = parseCdpStringTable(strings, styleIndexes[propertyIndex]);
2199
+ if (value.length > 0) {
2200
+ out[propertyName] = value;
2201
+ }
2202
+ return out;
2203
+ },
2204
+ {}
2205
+ );
2206
+ return {
2207
+ ...styleEntries.display === void 0 ? {} : { display: styleEntries.display },
2208
+ ...styleEntries.visibility === void 0 ? {} : { visibility: styleEntries.visibility },
2209
+ ...styleEntries.opacity === void 0 ? {} : { opacity: styleEntries.opacity },
2210
+ ...styleEntries.position === void 0 ? {} : { position: styleEntries.position },
2211
+ ...styleEntries.cursor === void 0 ? {} : { cursor: styleEntries.cursor },
2212
+ ...styleEntries["overflow-x"] === void 0 ? {} : { overflowX: styleEntries["overflow-x"] },
2213
+ ...styleEntries["overflow-y"] === void 0 ? {} : { overflowY: styleEntries["overflow-y"] }
2214
+ };
2215
+ }
2216
+ function decodeInlineComputedStyle(attributes) {
2217
+ const styleAttribute = attributes.find((attribute) => attribute.name === "style")?.value;
2218
+ if (styleAttribute === void 0 || styleAttribute.trim().length === 0) {
2219
+ return void 0;
2220
+ }
2221
+ const styleEntries = /* @__PURE__ */ new Map();
2222
+ for (const declaration of styleAttribute.split(";")) {
2223
+ const separatorIndex = declaration.indexOf(":");
2224
+ if (separatorIndex <= 0) {
2225
+ continue;
2226
+ }
2227
+ const propertyName = declaration.slice(0, separatorIndex).trim().toLowerCase();
2228
+ const propertyValue = declaration.slice(separatorIndex + 1).trim();
2229
+ if (propertyName.length === 0 || propertyValue.length === 0) {
2230
+ continue;
2231
+ }
2232
+ styleEntries.set(propertyName, propertyValue);
2233
+ }
2234
+ const display = styleEntries.get("display");
2235
+ const visibility = styleEntries.get("visibility");
2236
+ const opacity = styleEntries.get("opacity");
2237
+ const position = styleEntries.get("position");
2238
+ const cursor = styleEntries.get("cursor");
2239
+ const overflow = styleEntries.get("overflow");
2240
+ const overflowX = styleEntries.get("overflow-x") ?? overflow;
2241
+ const overflowY = styleEntries.get("overflow-y") ?? overflow;
2242
+ const computedStyle = {
2243
+ ...display === void 0 ? {} : { display },
2244
+ ...visibility === void 0 ? {} : { visibility },
2245
+ ...opacity === void 0 ? {} : { opacity },
2246
+ ...position === void 0 ? {} : { position },
2247
+ ...cursor === void 0 ? {} : { cursor },
2248
+ ...overflowX === void 0 ? {} : { overflowX },
2249
+ ...overflowY === void 0 ? {} : { overflowY }
2250
+ };
2251
+ return Object.keys(computedStyle).length === 0 ? void 0 : computedStyle;
2252
+ }
2253
+ function buildAggregatedTextIndex(document, shadowBoundariesByBackendNodeId, strings) {
2254
+ const parentIndexes = document.nodes.parentIndex ?? [];
2255
+ const backendNodeIds = document.nodes.backendNodeId ?? [];
2256
+ const childIndexes = /* @__PURE__ */ new Map();
2257
+ for (let index = 0; index < parentIndexes.length; index += 1) {
2258
+ const parentIndex = parentIndexes[index];
2259
+ if (parentIndex === void 0 || parentIndex < 0) {
2260
+ continue;
2261
+ }
2262
+ const children = childIndexes.get(parentIndex) ?? [];
2263
+ children.push(index);
2264
+ childIndexes.set(parentIndex, children);
2265
+ }
2266
+ const layoutTextByNodeIndex = /* @__PURE__ */ new Map();
2267
+ for (let layoutIndex = 0; layoutIndex < document.layout.nodeIndex.length; layoutIndex += 1) {
2268
+ const nodeIndex = document.layout.nodeIndex[layoutIndex];
2269
+ if (nodeIndex === void 0) {
2270
+ continue;
2271
+ }
2272
+ const text = parseCdpStringTable(strings, document.layout.text[layoutIndex]);
2273
+ if (text.length > 0) {
2274
+ layoutTextByNodeIndex.set(nodeIndex, text);
2275
+ }
2276
+ }
2277
+ const shadowHostBackendNodeIdByNodeIndex = /* @__PURE__ */ new Map();
2278
+ const resolveShadowHostBackendNodeId = (index) => {
2279
+ const existing = shadowHostBackendNodeIdByNodeIndex.get(index);
2280
+ if (existing !== void 0) {
2281
+ return existing;
2282
+ }
2283
+ const backendNodeId = backendNodeIds[index];
2284
+ const directShadowHostBackendNodeId = backendNodeId === void 0 ? void 0 : shadowBoundariesByBackendNodeId.get(backendNodeId)?.shadowHostBackendNodeId;
2285
+ if (directShadowHostBackendNodeId !== void 0) {
2286
+ shadowHostBackendNodeIdByNodeIndex.set(index, directShadowHostBackendNodeId);
2287
+ return directShadowHostBackendNodeId;
2288
+ }
2289
+ const parentIndex = parentIndexes[index];
2290
+ if (parentIndex === void 0 || parentIndex < 0) {
2291
+ shadowHostBackendNodeIdByNodeIndex.set(index, null);
2292
+ return null;
2293
+ }
2294
+ const inheritedShadowHostBackendNodeId = resolveShadowHostBackendNodeId(parentIndex);
2295
+ shadowHostBackendNodeIdByNodeIndex.set(index, inheritedShadowHostBackendNodeId);
2296
+ return inheritedShadowHostBackendNodeId;
2297
+ };
2298
+ const memo = /* @__PURE__ */ new Map();
2299
+ const visit = (index) => {
2300
+ const existing = memo.get(index);
2301
+ if (existing !== void 0) {
2302
+ return existing;
2303
+ }
2304
+ const nodeType = document.nodes.nodeType?.[index] ?? 0;
2305
+ const ownText = readOwnNodeText(document, strings, layoutTextByNodeIndex, index);
2306
+ if (nodeType === 3 || nodeType === 4) {
2307
+ memo.set(index, ownText);
2308
+ return ownText;
2309
+ }
2310
+ if (nodeType === 8 || nodeType === 10) {
2311
+ memo.set(index, "");
2312
+ return "";
2313
+ }
2314
+ let text = ownText;
2315
+ const currentShadowHostBackendNodeId = resolveShadowHostBackendNodeId(index);
2316
+ for (const childIndex of childIndexes.get(index) ?? []) {
2317
+ if (resolveShadowHostBackendNodeId(childIndex) !== currentShadowHostBackendNodeId) {
2318
+ continue;
2319
+ }
2320
+ text += visit(childIndex);
2321
+ }
2322
+ memo.set(index, text);
2323
+ return text;
2324
+ };
2325
+ const aggregated = /* @__PURE__ */ new Map();
2326
+ const nodeCount = document.nodes.nodeType?.length ?? 0;
2327
+ for (let index = 0; index < nodeCount; index += 1) {
2328
+ const text = visit(index);
2329
+ if (text.length > 0) {
2330
+ aggregated.set(index, text);
2331
+ }
2332
+ }
2333
+ return aggregated;
2334
+ }
2335
+ function readOwnNodeText(document, strings, layoutTextByNodeIndex, index) {
2336
+ return rareCdpStringValue(strings, document.nodes.textValue, index) || rareCdpStringValue(strings, document.nodes.inputValue, index) || (document.nodes.nodeType?.[index] === 3 || document.nodes.nodeType?.[index] === 4 ? parseCdpStringTable(strings, document.nodes.nodeValue?.[index]) || layoutTextByNodeIndex.get(index) || "" : "");
2337
+ }
2338
+
2339
+ // src/cdp-visual-stability.ts
2340
+ var DEFAULT_VISUAL_STABILITY_TIMEOUT_MS = 3e4;
2341
+ var DEFAULT_VISUAL_STABILITY_SETTLE_MS = 750;
2342
+ var FRAME_EVALUATE_GRACE_MS = 200;
2343
+ var TRANSIENT_CONTEXT_RETRY_DELAY_MS = 25;
2344
+ var STEALTH_WORLD_NAME = "__opensteer_wait__";
2345
+ var FRAME_OWNER_VISIBILITY_FUNCTION = `function() {
2346
+ if (!(this instanceof HTMLElement)) return false;
2347
+
2348
+ var rect = this.getBoundingClientRect();
2349
+ if (rect.width <= 0 || rect.height <= 0) return false;
2350
+ if (
2351
+ rect.bottom <= 0 ||
2352
+ rect.right <= 0 ||
2353
+ rect.top >= window.innerHeight ||
2354
+ rect.left >= window.innerWidth
2355
+ ) {
2356
+ return false;
2357
+ }
2358
+
2359
+ var style = window.getComputedStyle(this);
2360
+ if (
2361
+ style.display === 'none' ||
2362
+ style.visibility === 'hidden' ||
2363
+ Number(style.opacity) === 0
2364
+ ) {
2365
+ return false;
2366
+ }
2367
+
2368
+ return true;
2369
+ }`;
2370
+ async function waitForCdpVisualStability(cdp, options = {}) {
2371
+ const timeoutMs = options.timeoutMs ?? DEFAULT_VISUAL_STABILITY_TIMEOUT_MS;
2372
+ const settleMs = options.settleMs ?? DEFAULT_VISUAL_STABILITY_SETTLE_MS;
2373
+ const scope = options.scope ?? "main-frame";
2374
+ if (timeoutMs <= 0) {
2375
+ return;
2376
+ }
2377
+ const runtime = new StealthCdpRuntime(cdp);
2378
+ if (scope === "visible-frames") {
2379
+ await runtime.waitForVisibleFramesVisualStability(timeoutMs, settleMs);
2380
+ return;
2381
+ }
2382
+ await runtime.waitForMainFrameVisualStability(timeoutMs, settleMs);
2383
+ }
2384
+ function buildStabilityScript(timeout, settleMs) {
2385
+ return `new Promise(function(resolve) {
2386
+ var deadline = Date.now() + ${timeout};
2387
+ var resolved = false;
2388
+ var timer = null;
2389
+ var observers = [];
2390
+ var observedShadowRoots = [];
2391
+ var fonts = document.fonts;
2392
+ var fontsReady = !fonts || fonts.status === 'loaded';
2393
+ var lastRelevantMutationAt = Date.now();
2394
+
2395
+ function clearObservers() {
2396
+ for (var i = 0; i < observers.length; i++) {
2397
+ observers[i].disconnect();
2398
+ }
2399
+ observers = [];
2400
+ }
2401
+
2402
+ function done() {
2403
+ if (resolved) return;
2404
+ resolved = true;
2405
+ if (timer) clearTimeout(timer);
2406
+ if (safetyTimer) clearTimeout(safetyTimer);
2407
+ clearObservers();
2408
+ resolve();
2409
+ }
2410
+
2411
+ function isElementVisiblyIntersectingViewport(element) {
2412
+ if (!(element instanceof Element)) return false;
2413
+
2414
+ var rect = element.getBoundingClientRect();
2415
+ var inViewport =
2416
+ rect.width > 0 &&
2417
+ rect.height > 0 &&
2418
+ rect.bottom > 0 &&
2419
+ rect.right > 0 &&
2420
+ rect.top < window.innerHeight &&
2421
+ rect.left < window.innerWidth;
2422
+
2423
+ if (!inViewport) return false;
2424
+
2425
+ var style = window.getComputedStyle(element);
2426
+ if (style.visibility === 'hidden' || style.display === 'none') {
2427
+ return false;
2428
+ }
2429
+ if (Number(style.opacity) === 0) {
2430
+ return false;
2431
+ }
2432
+
2433
+ return true;
2434
+ }
2435
+
2436
+ function resolveRelevantElement(node) {
2437
+ if (!node) return null;
2438
+ if (node instanceof Element) return node;
2439
+ if (typeof ShadowRoot !== 'undefined' && node instanceof ShadowRoot) {
2440
+ return node.host instanceof Element ? node.host : null;
2441
+ }
2442
+ var parentElement = node.parentElement;
2443
+ return parentElement instanceof Element ? parentElement : null;
2444
+ }
2445
+
2446
+ function isNodeVisiblyRelevant(node) {
2447
+ var element = resolveRelevantElement(node);
2448
+ if (!element) return false;
2449
+ return isElementVisiblyIntersectingViewport(element);
2450
+ }
2451
+
2452
+ function hasRelevantMutation(records) {
2453
+ for (var i = 0; i < records.length; i++) {
2454
+ var record = records[i];
2455
+ if (isNodeVisiblyRelevant(record.target)) return true;
2456
+
2457
+ var addedNodes = record.addedNodes;
2458
+ for (var j = 0; j < addedNodes.length; j++) {
2459
+ if (isNodeVisiblyRelevant(addedNodes[j])) return true;
2460
+ }
2461
+
2462
+ var removedNodes = record.removedNodes;
2463
+ for (var k = 0; k < removedNodes.length; k++) {
2464
+ if (isNodeVisiblyRelevant(removedNodes[k])) return true;
2465
+ }
2466
+ }
2467
+
2468
+ return false;
2469
+ }
2470
+
2471
+ function scheduleCheck() {
2472
+ if (resolved) return;
2473
+ if (timer) clearTimeout(timer);
2474
+
2475
+ var remaining = deadline - Date.now();
2476
+ if (remaining <= 0) {
2477
+ done();
2478
+ return;
2479
+ }
2480
+
2481
+ var checkDelay = Math.min(120, Math.max(16, ${settleMs}));
2482
+ timer = setTimeout(checkNow, checkDelay);
2483
+ }
2484
+
2485
+ function observeMutations(target) {
2486
+ if (!target) return;
2487
+ var observer = new MutationObserver(function(records) {
2488
+ if (!hasRelevantMutation(records)) return;
2489
+ lastRelevantMutationAt = Date.now();
2490
+ scheduleCheck();
2491
+ });
2492
+ observer.observe(target, {
2493
+ childList: true,
2494
+ subtree: true,
2495
+ attributes: true,
2496
+ characterData: true
2497
+ });
2498
+ observers.push(observer);
2499
+ }
2500
+
2501
+ function hasObservedShadowRoot(root) {
2502
+ for (var i = 0; i < observedShadowRoots.length; i++) {
2503
+ if (observedShadowRoots[i] === root) return true;
2504
+ }
2505
+ return false;
2506
+ }
2507
+
2508
+ function observeOpenShadowRoots() {
2509
+ if (!document.documentElement || !document.createTreeWalker) return;
2510
+ var walker = document.createTreeWalker(
2511
+ document.documentElement,
2512
+ NodeFilter.SHOW_ELEMENT
2513
+ );
2514
+ while (walker.nextNode()) {
2515
+ var current = walker.currentNode;
2516
+ if (!(current instanceof Element)) continue;
2517
+ var shadowRoot = current.shadowRoot;
2518
+ if (!shadowRoot || shadowRoot.mode !== 'open') continue;
2519
+ if (hasObservedShadowRoot(shadowRoot)) continue;
2520
+ observedShadowRoots.push(shadowRoot);
2521
+ observeMutations(shadowRoot);
2522
+ }
2523
+ }
2524
+
2525
+ function checkViewportImages(root) {
2526
+ var images = root.querySelectorAll('img');
2527
+ for (var i = 0; i < images.length; i++) {
2528
+ var img = images[i];
2529
+ if (!isElementVisiblyIntersectingViewport(img)) continue;
2530
+ if (!img.complete) return false;
2531
+ }
2532
+ return true;
2533
+ }
2534
+
2535
+ function getAnimationTarget(effect) {
2536
+ if (!effect) return null;
2537
+ var target = effect.target;
2538
+ if (target instanceof Element) return target;
2539
+
2540
+ if (target && target.element instanceof Element) {
2541
+ return target.element;
2542
+ }
2543
+
2544
+ return null;
2545
+ }
2546
+
2547
+ function hasRunningVisibleFiniteAnimations() {
2548
+ if (typeof document.getAnimations !== 'function') return false;
2549
+ var animations = document.getAnimations();
2550
+
2551
+ for (var i = 0; i < animations.length; i++) {
2552
+ var animation = animations[i];
2553
+ if (!animation || animation.playState !== 'running') continue;
2554
+ var effect = animation.effect;
2555
+ if (!effect || typeof effect.getComputedTiming !== 'function') continue;
2556
+ var timing = effect.getComputedTiming();
2557
+ var endTime = timing && typeof timing.endTime === 'number'
2558
+ ? timing.endTime
2559
+ : Number.POSITIVE_INFINITY;
2560
+ if (Number.isFinite(endTime) && endTime > 0) {
2561
+ var target = getAnimationTarget(effect);
2562
+ if (!target) continue;
2563
+ if (!isElementVisiblyIntersectingViewport(target)) continue;
2564
+ return true;
2565
+ }
2566
+ }
2567
+
2568
+ return false;
2569
+ }
2570
+
2571
+ function isVisuallyReady() {
2572
+ if (!fontsReady) return false;
2573
+ if (!checkViewportImages(document)) return false;
2574
+ if (hasRunningVisibleFiniteAnimations()) return false;
2575
+ return true;
2576
+ }
2577
+
2578
+ function checkNow() {
2579
+ if (Date.now() >= deadline) {
2580
+ done();
2581
+ return;
2582
+ }
2583
+
2584
+ observeOpenShadowRoots();
2585
+
2586
+ if (!isVisuallyReady()) {
2587
+ scheduleCheck();
2588
+ return;
2589
+ }
2590
+
2591
+ if (Date.now() - lastRelevantMutationAt >= ${settleMs}) {
2592
+ done();
2593
+ return;
2594
+ }
2595
+
2596
+ scheduleCheck();
2597
+ }
2598
+
2599
+ observeMutations(document.documentElement);
2600
+ observeOpenShadowRoots();
2601
+
2602
+ if (fonts && fonts.ready && typeof fonts.ready.then === 'function') {
2603
+ fonts.ready.then(function() {
2604
+ fontsReady = true;
2605
+ scheduleCheck();
2606
+ }, function() {
2607
+ fontsReady = true;
2608
+ scheduleCheck();
2609
+ });
2610
+ }
2611
+
2612
+ var safetyTimer = setTimeout(done, ${timeout});
2613
+
2614
+ scheduleCheck();
2615
+ })`;
2616
+ }
2617
+ var StealthCdpRuntime = class {
2618
+ constructor(session) {
2619
+ this.session = session;
2620
+ }
2621
+ contextsByFrame = /* @__PURE__ */ new Map();
2622
+ async waitForMainFrameVisualStability(timeoutMs, settleMs) {
2623
+ const frameRecords = await this.getFrameRecords();
2624
+ const mainFrame = frameRecords[0];
2625
+ if (!mainFrame) {
2626
+ return;
2627
+ }
2628
+ await this.waitForFrameVisualStability(mainFrame.frameId, timeoutMs, settleMs, true);
2629
+ }
2630
+ async waitForVisibleFramesVisualStability(timeoutMs, settleMs) {
2631
+ const deadline = Date.now() + timeoutMs;
2632
+ while (true) {
2633
+ const remaining = Math.max(0, deadline - Date.now());
2634
+ if (remaining === 0) {
2635
+ return;
2636
+ }
2637
+ const frameIds = await this.collectVisibleFrameIds();
2638
+ if (frameIds.length === 0) {
2639
+ return;
2640
+ }
2641
+ await Promise.all(
2642
+ frameIds.map(async (frameId) => {
2643
+ try {
2644
+ await this.waitForFrameVisualStability(frameId, remaining, settleMs, false);
2645
+ } catch (error) {
2646
+ if (isIgnorableFrameError(error)) {
2647
+ return;
2648
+ }
2649
+ throw error;
2650
+ }
2651
+ })
2652
+ );
2653
+ const currentFrameIds = await this.collectVisibleFrameIds();
2654
+ if (sameFrameIds(frameIds, currentFrameIds)) {
2655
+ return;
2656
+ }
2657
+ }
2658
+ }
2659
+ async getFrameRecords() {
2660
+ const treeResult = await this.session.send("Page.getFrameTree");
2661
+ const records = [];
2662
+ walkFrameTree(treeResult.frameTree, null, records);
2663
+ return records;
2664
+ }
2665
+ async collectVisibleFrameIds() {
2666
+ const frameRecords = await this.getFrameRecords();
2667
+ if (frameRecords.length === 0) {
2668
+ return [];
2669
+ }
2670
+ const visibleFrameIds = [];
2671
+ for (const frameRecord of frameRecords) {
2672
+ if (!frameRecord.parentFrameId) {
2673
+ visibleFrameIds.push(frameRecord.frameId);
2674
+ continue;
2675
+ }
2676
+ try {
2677
+ const parentContextId = await this.ensureFrameContextId(frameRecord.parentFrameId);
2678
+ if (await this.isFrameOwnerVisible(frameRecord.frameId, parentContextId)) {
2679
+ visibleFrameIds.push(frameRecord.frameId);
2680
+ }
2681
+ } catch (error) {
2682
+ if (isIgnorableFrameError(error)) {
2683
+ continue;
2684
+ }
2685
+ throw error;
2686
+ }
2687
+ }
2688
+ return visibleFrameIds;
2689
+ }
2690
+ async ensureFrameContextId(frameId) {
2691
+ const existing = this.contextsByFrame.get(frameId);
2692
+ if (existing !== void 0) {
2693
+ return existing;
2694
+ }
2695
+ const world = await this.session.send("Page.createIsolatedWorld", {
2696
+ frameId,
2697
+ worldName: STEALTH_WORLD_NAME
2698
+ });
2699
+ this.contextsByFrame.set(frameId, world.executionContextId);
2700
+ return world.executionContextId;
2701
+ }
2702
+ async waitForFrameVisualStability(frameId, timeoutMs, settleMs, retryTransientContextErrors) {
2703
+ if (timeoutMs <= 0) {
2704
+ return;
2705
+ }
2706
+ const script = buildStabilityScript(timeoutMs, settleMs);
2707
+ if (!retryTransientContextErrors) {
2708
+ let contextId = await this.ensureFrameContextId(frameId);
2709
+ try {
2710
+ await this.evaluateWithGuard(contextId, script, timeoutMs);
2711
+ } catch (error) {
2712
+ if (!isMissingExecutionContextError(error)) {
2713
+ throw error;
2714
+ }
2715
+ this.contextsByFrame.delete(frameId);
2716
+ contextId = await this.ensureFrameContextId(frameId);
2717
+ await this.evaluateWithGuard(contextId, script, timeoutMs);
2718
+ }
2719
+ return;
2720
+ }
2721
+ const deadline = Date.now() + timeoutMs;
2722
+ while (true) {
2723
+ const remaining = Math.max(0, deadline - Date.now());
2724
+ if (remaining === 0) {
2725
+ return;
2726
+ }
2727
+ const contextId = await this.ensureFrameContextId(frameId);
2728
+ try {
2729
+ await this.evaluateWithGuard(contextId, script, remaining);
2730
+ return;
2731
+ } catch (error) {
2732
+ if (!isTransientExecutionContextError(error)) {
2733
+ throw error;
2734
+ }
2735
+ this.contextsByFrame.delete(frameId);
2736
+ await sleep(Math.min(TRANSIENT_CONTEXT_RETRY_DELAY_MS, Math.max(0, deadline - Date.now())));
2737
+ }
2738
+ }
2739
+ }
2740
+ async evaluateWithGuard(contextId, script, timeoutMs) {
2741
+ const guardedPromise = this.evaluateScript(contextId, script).then(() => ({ kind: "resolved" })).catch((error) => ({ kind: "rejected", error }));
2742
+ const timeoutPromise = new Promise((resolve) => {
2743
+ setTimeout(() => resolve({ kind: "timeout" }), timeoutMs + FRAME_EVALUATE_GRACE_MS);
2744
+ });
2745
+ const outcome = await Promise.race([guardedPromise, timeoutPromise]);
2746
+ if (outcome.kind === "rejected") {
2747
+ throw outcome.error;
2748
+ }
2749
+ }
2750
+ async evaluateScript(contextId, script) {
2751
+ const evaluated = await this.session.send("Runtime.evaluate", {
2752
+ contextId,
2753
+ expression: script,
2754
+ returnByValue: true,
2755
+ awaitPromise: true
2756
+ });
2757
+ if (evaluated.exceptionDetails) {
2758
+ throw new Error(formatCdpException(evaluated.exceptionDetails));
2759
+ }
2760
+ }
2761
+ async isFrameOwnerVisible(frameId, executionContextId) {
2762
+ const frameOwner = await this.session.send("DOM.getFrameOwner", {
2763
+ frameId
2764
+ });
2765
+ if (frameOwner.backendNodeId === void 0) {
2766
+ return false;
2767
+ }
2768
+ const resolved = await this.session.send("DOM.resolveNode", {
2769
+ backendNodeId: frameOwner.backendNodeId,
2770
+ executionContextId
2771
+ });
2772
+ const objectId = resolved.object?.objectId;
2773
+ if (!objectId) {
2774
+ return false;
2775
+ }
2776
+ try {
2777
+ const callResult = await this.session.send("Runtime.callFunctionOn", {
2778
+ objectId,
2779
+ functionDeclaration: FRAME_OWNER_VISIBILITY_FUNCTION,
2780
+ returnByValue: true
2781
+ });
2782
+ if (callResult.exceptionDetails) {
2783
+ throw new Error(formatCdpException(callResult.exceptionDetails));
2784
+ }
2785
+ return callResult.result.value === true;
2786
+ } finally {
2787
+ await this.releaseObject(objectId);
2788
+ }
2789
+ }
2790
+ async releaseObject(objectId) {
2791
+ await this.session.send("Runtime.releaseObject", {
2792
+ objectId
2793
+ }).catch(() => void 0);
2794
+ }
2795
+ };
2796
+ function walkFrameTree(node, parentFrameId, records) {
2797
+ const frameId = node.frame?.id;
2798
+ if (!frameId) {
2799
+ return;
2800
+ }
2801
+ records.push({
2802
+ frameId,
2803
+ parentFrameId
2804
+ });
2805
+ for (const child of node.childFrames ?? []) {
2806
+ walkFrameTree(child, frameId, records);
2807
+ }
2808
+ }
2809
+ function sameFrameIds(before, after) {
2810
+ if (before.length !== after.length) {
2811
+ return false;
2812
+ }
2813
+ return before.every((frameId) => after.includes(frameId));
2814
+ }
2815
+ function formatCdpException(details) {
2816
+ return details.exception?.description || details.text || "CDP runtime evaluation failed.";
2817
+ }
2818
+ function isIgnorableFrameError(error) {
2819
+ if (!(error instanceof Error)) {
2820
+ return false;
2821
+ }
2822
+ const message = error.message;
2823
+ return message.includes("Frame with the given id was not found") || message.includes("No frame for given id found") || isTransientExecutionContextError(error);
2824
+ }
2825
+ function isTransientExecutionContextError(error) {
2826
+ if (!(error instanceof Error)) {
2827
+ return false;
2828
+ }
2829
+ const message = error.message;
2830
+ return message.includes("Execution context was destroyed") || message.includes("Cannot find context with specified id") || message.includes("Cannot find execution context");
2831
+ }
2832
+ function isMissingExecutionContextError(error) {
2833
+ if (!(error instanceof Error)) {
2834
+ return false;
2835
+ }
2836
+ const message = error.message;
2837
+ return message.includes("Cannot find context with specified id") || message.includes("Cannot find execution context");
2838
+ }
2839
+ function sleep(ms) {
2840
+ if (ms <= 0) {
2841
+ return Promise.resolve();
2842
+ }
2843
+ return new Promise((resolve) => setTimeout(resolve, ms));
2844
+ }
2845
+
2846
+ exports.BrowserCoreError = BrowserCoreError;
2847
+ exports.DEFAULT_VISUAL_STABILITY_SETTLE_MS = DEFAULT_VISUAL_STABILITY_SETTLE_MS;
2848
+ exports.DEFAULT_VISUAL_STABILITY_TIMEOUT_MS = DEFAULT_VISUAL_STABILITY_TIMEOUT_MS;
2849
+ exports.DOM_SNAPSHOT_COMPUTED_STYLE_NAMES = DOM_SNAPSHOT_COMPUTED_STYLE_NAMES;
2850
+ exports.FakeBrowserCoreEngine = FakeBrowserCoreEngine;
2851
+ exports.allBrowserCapabilities = allBrowserCapabilities;
2852
+ exports.bodyPayloadFromUtf8 = bodyPayloadFromUtf8;
2853
+ exports.brand = brand;
2854
+ exports.buildCdpShadowBoundaryIndex = buildCdpShadowBoundaryIndex;
2855
+ exports.buildDomSnapshotFromCdpCapture = buildDomSnapshotFromCdpCapture;
2856
+ exports.closedPageError = closedPageError;
2857
+ exports.closedSessionError = closedSessionError;
2858
+ exports.createBodyPayload = createBodyPayload;
2859
+ exports.createBrowserCoreError = createBrowserCoreError;
2860
+ exports.createChooserRef = createChooserRef;
2861
+ exports.createDevicePixelRatio = createDevicePixelRatio;
2862
+ exports.createDialogRef = createDialogRef;
2863
+ exports.createDocumentEpoch = createDocumentEpoch;
2864
+ exports.createDocumentRef = createDocumentRef;
2865
+ exports.createDownloadRef = createDownloadRef;
2866
+ exports.createFakeBrowserCoreEngine = createFakeBrowserCoreEngine;
2867
+ exports.createFrameRef = createFrameRef;
2868
+ exports.createHeaderEntry = createHeaderEntry;
2869
+ exports.createNetworkRequestId = createNetworkRequestId;
2870
+ exports.createNodeLocator = createNodeLocator;
2871
+ exports.createNodeRef = createNodeRef;
2872
+ exports.createPageRef = createPageRef;
2873
+ exports.createPageScaleFactor = createPageScaleFactor;
2874
+ exports.createPageZoomFactor = createPageZoomFactor;
2875
+ exports.createPoint = createPoint;
2876
+ exports.createQuad = createQuad;
2877
+ exports.createRect = createRect;
2878
+ exports.createScrollOffset = createScrollOffset;
2879
+ exports.createSessionRef = createSessionRef;
2880
+ exports.createSize = createSize;
2881
+ exports.createWorkerRef = createWorkerRef;
2882
+ exports.filterCookieRecords = filterCookieRecords;
2883
+ exports.findDomSnapshotNode = findDomSnapshotNode;
2884
+ exports.findDomSnapshotNodeByRef = findDomSnapshotNodeByRef;
2885
+ exports.hasCapability = hasCapability;
2886
+ exports.isBrowserCoreError = isBrowserCoreError;
2887
+ exports.isChooserRef = isChooserRef;
2888
+ exports.isDialogRef = isDialogRef;
2889
+ exports.isDocumentRef = isDocumentRef;
2890
+ exports.isDownloadRef = isDownloadRef;
2891
+ exports.isFrameRef = isFrameRef;
2892
+ exports.isNetworkRequestId = isNetworkRequestId;
2893
+ exports.isNodeRef = isNodeRef;
2894
+ exports.isPageRef = isPageRef;
2895
+ exports.isSessionRef = isSessionRef;
2896
+ exports.isWorkerRef = isWorkerRef;
2897
+ exports.matchesNetworkRecordFilters = matchesNetworkRecordFilters;
2898
+ exports.mergeBrowserCapabilities = mergeBrowserCapabilities;
2899
+ exports.nextDocumentEpoch = nextDocumentEpoch;
2900
+ exports.noBrowserCapabilities = noBrowserCapabilities;
2901
+ exports.normalizeCdpShadowRootType = normalizeCdpShadowRootType;
2902
+ exports.parseCdpStringTable = parseCdpStringTable;
2903
+ exports.quadBounds = quadBounds;
2904
+ exports.rareCdpIntegerValue = rareCdpIntegerValue;
2905
+ exports.rareCdpStringValue = rareCdpStringValue;
2906
+ exports.rectContainsPoint = rectContainsPoint;
2907
+ exports.rectToQuad = rectToQuad;
2908
+ exports.serializeDocumentEpoch = serializeDocumentEpoch;
2909
+ exports.serializeRef = serializeRef;
2910
+ exports.staleNodeRefError = staleNodeRefError;
2911
+ exports.unsupportedCapabilityError = unsupportedCapabilityError;
2912
+ exports.waitForCdpVisualStability = waitForCdpVisualStability;
2913
+ //# sourceMappingURL=index.cjs.map
2914
+ //# sourceMappingURL=index.cjs.map