@opensteer/engine-abp 0.8.3 → 0.8.5

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.d.cts CHANGED
@@ -378,6 +378,27 @@ interface BrowserCapabilities {
378
378
  };
379
379
  }
380
380
 
381
+ interface PostLoadTrackerSnapshot {
382
+ readonly lastTrackedNetworkActivityAt: number;
383
+ readonly trackedPendingFetches: number;
384
+ readonly trackedPendingXhrs: number;
385
+ }
386
+
387
+ interface ActionBoundarySnapshot {
388
+ readonly pageRef: PageRef;
389
+ readonly documentRef: DocumentRef;
390
+ readonly url?: string;
391
+ readonly tracker?: PostLoadTrackerSnapshot;
392
+ }
393
+ type ActionBoundarySettleTrigger = "dom-action" | "navigation";
394
+ type ActionBoundaryTimedOutPhase = "bootstrap";
395
+ interface ActionBoundaryOutcome {
396
+ readonly trigger: ActionBoundarySettleTrigger;
397
+ readonly crossDocument: boolean;
398
+ readonly bootstrapSettled: boolean;
399
+ readonly timedOutPhase?: ActionBoundaryTimedOutPhase;
400
+ }
401
+
381
402
  type ConsoleLevel = "debug" | "log" | "info" | "warn" | "error" | "trace";
382
403
  interface StepEventBase {
383
404
  readonly eventId: string;
@@ -675,6 +696,9 @@ interface BrowserExecutor {
675
696
  }
676
697
  interface BrowserInspector {
677
698
  readonly capabilities: Readonly<BrowserCapabilities>;
699
+ drainEvents(input: {
700
+ readonly pageRef: PageRef;
701
+ }): Promise<readonly StepEvent[]>;
678
702
  listPages(input: {
679
703
  readonly sessionRef: SessionRef;
680
704
  }): Promise<readonly PageInfo[]>;
@@ -695,12 +719,22 @@ interface BrowserInspector {
695
719
  readonly frameRef?: FrameRef;
696
720
  readonly documentRef?: DocumentRef;
697
721
  }): Promise<DomSnapshot>;
722
+ getActionBoundarySnapshot(input: {
723
+ readonly pageRef: PageRef;
724
+ }): Promise<ActionBoundarySnapshot>;
698
725
  waitForVisualStability(input: {
699
726
  readonly pageRef: PageRef;
700
727
  readonly timeoutMs?: number;
701
728
  readonly settleMs?: number;
702
729
  readonly scope?: VisualStabilityScope;
703
730
  }): Promise<void>;
731
+ waitForPostLoadQuiet(input: {
732
+ readonly pageRef: PageRef;
733
+ readonly timeoutMs?: number;
734
+ readonly quietMs?: number;
735
+ readonly captureWindowMs?: number;
736
+ readonly signal?: AbortSignal;
737
+ }): Promise<void>;
704
738
  readText(input: NodeLocator): Promise<string | null>;
705
739
  readAttributes(input: NodeLocator): Promise<readonly {
706
740
  readonly name: string;
@@ -753,19 +787,6 @@ interface BrowserInstrumentation {
753
787
  interface BrowserCoreEngine extends BrowserExecutor, BrowserInspector, SessionTransportExecutor, BrowserInstrumentation {
754
788
  }
755
789
 
756
- interface ActionBoundarySnapshot {
757
- readonly pageRef: PageRef;
758
- readonly documentRef: DocumentRef;
759
- }
760
- type ActionBoundarySettleTrigger = "dom-action" | "navigation";
761
- type ActionBoundaryTimedOutPhase = "bootstrap";
762
- interface ActionBoundaryOutcome {
763
- readonly trigger: ActionBoundarySettleTrigger;
764
- readonly crossDocument: boolean;
765
- readonly bootstrapSettled: boolean;
766
- readonly timedOutPhase?: ActionBoundaryTimedOutPhase;
767
- }
768
-
769
790
  declare const opensteerComputerAnnotationNames: readonly ["clickable", "typeable", "scrollable", "grid", "selected"];
770
791
  type OpensteerComputerAnnotation = (typeof opensteerComputerAnnotationNames)[number];
771
792
  type OpensteerComputerMouseButton = "left" | "middle" | "right";
@@ -1077,6 +1098,9 @@ declare class AbpBrowserCoreEngine implements BrowserCoreEngine {
1077
1098
  listPages(input: {
1078
1099
  readonly sessionRef: SessionRef;
1079
1100
  }): Promise<readonly PageInfo[]>;
1101
+ drainEvents(input: {
1102
+ readonly pageRef: PageRef;
1103
+ }): Promise<readonly StepEvent[]>;
1080
1104
  listFrames(input: {
1081
1105
  readonly pageRef: PageRef;
1082
1106
  }): Promise<readonly FrameInfo[]>;
@@ -1094,12 +1118,22 @@ declare class AbpBrowserCoreEngine implements BrowserCoreEngine {
1094
1118
  readonly frameRef?: FrameRef;
1095
1119
  readonly documentRef?: DocumentRef;
1096
1120
  }): Promise<DomSnapshot>;
1121
+ getActionBoundarySnapshot(input: {
1122
+ readonly pageRef: PageRef;
1123
+ }): Promise<ActionBoundarySnapshot>;
1097
1124
  waitForVisualStability(input: {
1098
1125
  readonly pageRef: PageRef;
1099
1126
  readonly timeoutMs?: number;
1100
1127
  readonly settleMs?: number;
1101
1128
  readonly scope?: "main-frame" | "visible-frames";
1102
1129
  }): Promise<void>;
1130
+ waitForPostLoadQuiet(input: {
1131
+ readonly pageRef: PageRef;
1132
+ readonly timeoutMs?: number;
1133
+ readonly quietMs?: number;
1134
+ readonly captureWindowMs?: number;
1135
+ readonly signal?: AbortSignal;
1136
+ }): Promise<void>;
1103
1137
  readText(input: NodeLocator): Promise<string | null>;
1104
1138
  readAttributes(input: NodeLocator): Promise<readonly {
1105
1139
  readonly name: string;
package/dist/index.d.ts CHANGED
@@ -378,6 +378,27 @@ interface BrowserCapabilities {
378
378
  };
379
379
  }
380
380
 
381
+ interface PostLoadTrackerSnapshot {
382
+ readonly lastTrackedNetworkActivityAt: number;
383
+ readonly trackedPendingFetches: number;
384
+ readonly trackedPendingXhrs: number;
385
+ }
386
+
387
+ interface ActionBoundarySnapshot {
388
+ readonly pageRef: PageRef;
389
+ readonly documentRef: DocumentRef;
390
+ readonly url?: string;
391
+ readonly tracker?: PostLoadTrackerSnapshot;
392
+ }
393
+ type ActionBoundarySettleTrigger = "dom-action" | "navigation";
394
+ type ActionBoundaryTimedOutPhase = "bootstrap";
395
+ interface ActionBoundaryOutcome {
396
+ readonly trigger: ActionBoundarySettleTrigger;
397
+ readonly crossDocument: boolean;
398
+ readonly bootstrapSettled: boolean;
399
+ readonly timedOutPhase?: ActionBoundaryTimedOutPhase;
400
+ }
401
+
381
402
  type ConsoleLevel = "debug" | "log" | "info" | "warn" | "error" | "trace";
382
403
  interface StepEventBase {
383
404
  readonly eventId: string;
@@ -675,6 +696,9 @@ interface BrowserExecutor {
675
696
  }
676
697
  interface BrowserInspector {
677
698
  readonly capabilities: Readonly<BrowserCapabilities>;
699
+ drainEvents(input: {
700
+ readonly pageRef: PageRef;
701
+ }): Promise<readonly StepEvent[]>;
678
702
  listPages(input: {
679
703
  readonly sessionRef: SessionRef;
680
704
  }): Promise<readonly PageInfo[]>;
@@ -695,12 +719,22 @@ interface BrowserInspector {
695
719
  readonly frameRef?: FrameRef;
696
720
  readonly documentRef?: DocumentRef;
697
721
  }): Promise<DomSnapshot>;
722
+ getActionBoundarySnapshot(input: {
723
+ readonly pageRef: PageRef;
724
+ }): Promise<ActionBoundarySnapshot>;
698
725
  waitForVisualStability(input: {
699
726
  readonly pageRef: PageRef;
700
727
  readonly timeoutMs?: number;
701
728
  readonly settleMs?: number;
702
729
  readonly scope?: VisualStabilityScope;
703
730
  }): Promise<void>;
731
+ waitForPostLoadQuiet(input: {
732
+ readonly pageRef: PageRef;
733
+ readonly timeoutMs?: number;
734
+ readonly quietMs?: number;
735
+ readonly captureWindowMs?: number;
736
+ readonly signal?: AbortSignal;
737
+ }): Promise<void>;
704
738
  readText(input: NodeLocator): Promise<string | null>;
705
739
  readAttributes(input: NodeLocator): Promise<readonly {
706
740
  readonly name: string;
@@ -753,19 +787,6 @@ interface BrowserInstrumentation {
753
787
  interface BrowserCoreEngine extends BrowserExecutor, BrowserInspector, SessionTransportExecutor, BrowserInstrumentation {
754
788
  }
755
789
 
756
- interface ActionBoundarySnapshot {
757
- readonly pageRef: PageRef;
758
- readonly documentRef: DocumentRef;
759
- }
760
- type ActionBoundarySettleTrigger = "dom-action" | "navigation";
761
- type ActionBoundaryTimedOutPhase = "bootstrap";
762
- interface ActionBoundaryOutcome {
763
- readonly trigger: ActionBoundarySettleTrigger;
764
- readonly crossDocument: boolean;
765
- readonly bootstrapSettled: boolean;
766
- readonly timedOutPhase?: ActionBoundaryTimedOutPhase;
767
- }
768
-
769
790
  declare const opensteerComputerAnnotationNames: readonly ["clickable", "typeable", "scrollable", "grid", "selected"];
770
791
  type OpensteerComputerAnnotation = (typeof opensteerComputerAnnotationNames)[number];
771
792
  type OpensteerComputerMouseButton = "left" | "middle" | "right";
@@ -1077,6 +1098,9 @@ declare class AbpBrowserCoreEngine implements BrowserCoreEngine {
1077
1098
  listPages(input: {
1078
1099
  readonly sessionRef: SessionRef;
1079
1100
  }): Promise<readonly PageInfo[]>;
1101
+ drainEvents(input: {
1102
+ readonly pageRef: PageRef;
1103
+ }): Promise<readonly StepEvent[]>;
1080
1104
  listFrames(input: {
1081
1105
  readonly pageRef: PageRef;
1082
1106
  }): Promise<readonly FrameInfo[]>;
@@ -1094,12 +1118,22 @@ declare class AbpBrowserCoreEngine implements BrowserCoreEngine {
1094
1118
  readonly frameRef?: FrameRef;
1095
1119
  readonly documentRef?: DocumentRef;
1096
1120
  }): Promise<DomSnapshot>;
1121
+ getActionBoundarySnapshot(input: {
1122
+ readonly pageRef: PageRef;
1123
+ }): Promise<ActionBoundarySnapshot>;
1097
1124
  waitForVisualStability(input: {
1098
1125
  readonly pageRef: PageRef;
1099
1126
  readonly timeoutMs?: number;
1100
1127
  readonly settleMs?: number;
1101
1128
  readonly scope?: "main-frame" | "visible-frames";
1102
1129
  }): Promise<void>;
1130
+ waitForPostLoadQuiet(input: {
1131
+ readonly pageRef: PageRef;
1132
+ readonly timeoutMs?: number;
1133
+ readonly quietMs?: number;
1134
+ readonly captureWindowMs?: number;
1135
+ readonly signal?: AbortSignal;
1136
+ }): Promise<void>;
1103
1137
  readText(input: NodeLocator): Promise<string | null>;
1104
1138
  readAttributes(input: NodeLocator): Promise<readonly {
1105
1139
  readonly name: string;
package/dist/index.js CHANGED
@@ -1272,19 +1272,24 @@ function normalizePostLoadTrackerState(value) {
1272
1272
  const installedAt = readFiniteNumber(value.installedAt);
1273
1273
  const lastMutationAt = readFiniteNumber(value.lastMutationAt);
1274
1274
  const lastNetworkActivityAt = readFiniteNumber(value.lastNetworkActivityAt);
1275
+ const lastTrackedNetworkActivityAt = readFiniteNumber(value.lastTrackedNetworkActivityAt);
1275
1276
  const now = readFiniteNumber(value.now);
1276
1277
  const readyState = typeof value.readyState === "string" ? value.readyState : void 0;
1277
- if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
1278
+ if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || lastTrackedNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
1278
1279
  return void 0;
1279
1280
  }
1280
1281
  return {
1281
1282
  installedAt,
1282
1283
  lastMutationAt,
1283
1284
  lastNetworkActivityAt,
1285
+ lastTrackedNetworkActivityAt,
1284
1286
  now,
1285
1287
  pendingFetches: readNonNegativeNumber(value.pendingFetches),
1286
1288
  pendingTimeouts: readNonNegativeNumber(value.pendingTimeouts),
1287
1289
  pendingXhrs: readNonNegativeNumber(value.pendingXhrs),
1290
+ trackedPendingFetches: readNonNegativeNumber(value.trackedPendingFetches),
1291
+ trackedPendingXhrs: readNonNegativeNumber(value.trackedPendingXhrs),
1292
+ collecting: value.collecting === true,
1288
1293
  readyState
1289
1294
  };
1290
1295
  }
@@ -1299,11 +1304,14 @@ function buildPostLoadTrackerInstallScript() {
1299
1304
  installedAt: performance.now(),
1300
1305
  lastMutationAt: performance.now(),
1301
1306
  lastNetworkActivityAt: performance.now(),
1307
+ lastTrackedNetworkActivityAt: performance.now(),
1302
1308
  pendingFetches: 0,
1303
1309
  pendingTimeouts: 0,
1304
1310
  pendingXhrs: 0,
1311
+ trackedPendingFetches: 0,
1312
+ trackedPendingXhrs: 0,
1313
+ collecting: true,
1305
1314
  readyState: document.readyState,
1306
- timeoutIds: new Set(),
1307
1315
  };
1308
1316
  globalObject.__opensteerActionBoundaryTrackerInstalled = true;
1309
1317
  globalObject.__opensteerActionBoundaryTracker = tracker;
@@ -1316,6 +1324,18 @@ function buildPostLoadTrackerInstallScript() {
1316
1324
  tracker.lastNetworkActivityAt = performance.now();
1317
1325
  tracker.readyState = document.readyState;
1318
1326
  };
1327
+ const markTrackedNetwork = () => {
1328
+ tracker.lastTrackedNetworkActivityAt = performance.now();
1329
+ markNetwork();
1330
+ };
1331
+ const resetTracking = () => {
1332
+ const now = performance.now();
1333
+ tracker.lastTrackedNetworkActivityAt = now;
1334
+ tracker.trackedPendingFetches = 0;
1335
+ tracker.trackedPendingXhrs = 0;
1336
+ tracker.collecting = true;
1337
+ tracker.readyState = document.readyState;
1338
+ };
1319
1339
 
1320
1340
  const startObserver = () => {
1321
1341
  const target = document.documentElement ?? document;
@@ -1341,45 +1361,26 @@ function buildPostLoadTrackerInstallScript() {
1341
1361
  document.addEventListener("readystatechange", markMutation);
1342
1362
  addEventListener("load", markMutation, { once: true });
1343
1363
 
1344
- const nativeSetTimeout = globalObject.setTimeout.bind(globalObject);
1345
- const nativeClearTimeout = globalObject.clearTimeout.bind(globalObject);
1346
- globalObject.setTimeout = function(callback, delay, ...args) {
1347
- tracker.pendingTimeouts += 1;
1348
- markNetwork();
1349
- let handle;
1350
- const wrapped =
1351
- typeof callback === "function"
1352
- ? (...callbackArgs) => {
1353
- if (tracker.timeoutIds.delete(handle)) {
1354
- tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
1355
- }
1356
- try {
1357
- return callback(...callbackArgs);
1358
- } finally {
1359
- markMutation();
1360
- }
1361
- }
1362
- : callback;
1363
- handle = nativeSetTimeout(wrapped, delay, ...args);
1364
- tracker.timeoutIds.add(handle);
1365
- return handle;
1366
- };
1367
- globalObject.clearTimeout = function(handle) {
1368
- if (tracker.timeoutIds.delete(handle)) {
1369
- tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
1370
- }
1371
- return nativeClearTimeout(handle);
1372
- };
1373
-
1374
1364
  if (typeof globalObject.fetch === "function") {
1375
1365
  const nativeFetch = globalObject.fetch.bind(globalObject);
1376
1366
  globalObject.fetch = (...args) => {
1367
+ const tracked = tracker.collecting === true;
1377
1368
  tracker.pendingFetches += 1;
1378
- markNetwork();
1369
+ if (tracked) {
1370
+ tracker.trackedPendingFetches += 1;
1371
+ markTrackedNetwork();
1372
+ } else {
1373
+ markNetwork();
1374
+ }
1379
1375
  return nativeFetch(...args)
1380
1376
  .finally(() => {
1381
1377
  tracker.pendingFetches = Math.max(0, tracker.pendingFetches - 1);
1382
- markNetwork();
1378
+ if (tracked) {
1379
+ tracker.trackedPendingFetches = Math.max(0, tracker.trackedPendingFetches - 1);
1380
+ markTrackedNetwork();
1381
+ } else {
1382
+ markNetwork();
1383
+ }
1383
1384
  });
1384
1385
  };
1385
1386
  }
@@ -1388,21 +1389,60 @@ function buildPostLoadTrackerInstallScript() {
1388
1389
  const NativeXMLHttpRequest = globalObject.XMLHttpRequest;
1389
1390
  const nativeSend = NativeXMLHttpRequest.prototype.send;
1390
1391
  NativeXMLHttpRequest.prototype.send = function(...args) {
1392
+ const tracked = tracker.collecting === true;
1391
1393
  tracker.pendingXhrs += 1;
1392
- markNetwork();
1394
+ if (tracked) {
1395
+ tracker.trackedPendingXhrs += 1;
1396
+ markTrackedNetwork();
1397
+ } else {
1398
+ markNetwork();
1399
+ }
1393
1400
  const finalize = () => {
1394
1401
  this.removeEventListener("loadend", finalize);
1395
1402
  tracker.pendingXhrs = Math.max(0, tracker.pendingXhrs - 1);
1396
- markNetwork();
1403
+ if (tracked) {
1404
+ tracker.trackedPendingXhrs = Math.max(0, tracker.trackedPendingXhrs - 1);
1405
+ markTrackedNetwork();
1406
+ } else {
1407
+ markNetwork();
1408
+ }
1397
1409
  };
1398
1410
  this.addEventListener("loadend", finalize, { once: true });
1399
1411
  return nativeSend.apply(this, args);
1400
1412
  };
1401
1413
  }
1402
1414
 
1415
+ tracker.beginObservation = () => {
1416
+ resetTracking();
1417
+ return true;
1418
+ };
1419
+ tracker.freezeObservation = () => {
1420
+ tracker.collecting = false;
1421
+ tracker.readyState = document.readyState;
1422
+ return true;
1423
+ };
1424
+
1403
1425
  return true;
1404
1426
  })()`;
1405
1427
  }
1428
+ function buildPostLoadTrackerBeginExpression() {
1429
+ return `(() => {
1430
+ const tracker = globalThis.__opensteerActionBoundaryTracker;
1431
+ if (!tracker || typeof tracker.beginObservation !== "function") {
1432
+ return false;
1433
+ }
1434
+ return tracker.beginObservation();
1435
+ })()`;
1436
+ }
1437
+ function buildPostLoadTrackerFreezeExpression() {
1438
+ return `(() => {
1439
+ const tracker = globalThis.__opensteerActionBoundaryTracker;
1440
+ if (!tracker || typeof tracker.freezeObservation !== "function") {
1441
+ return false;
1442
+ }
1443
+ return tracker.freezeObservation();
1444
+ })()`;
1445
+ }
1406
1446
  function buildPostLoadTrackerReadExpression() {
1407
1447
  return `(() => {
1408
1448
  const tracker = globalThis.__opensteerActionBoundaryTracker;
@@ -1414,14 +1454,31 @@ function buildPostLoadTrackerReadExpression() {
1414
1454
  installedAt: Number(tracker.installedAt ?? 0),
1415
1455
  lastMutationAt: Number(tracker.lastMutationAt ?? 0),
1416
1456
  lastNetworkActivityAt: Number(tracker.lastNetworkActivityAt ?? 0),
1457
+ lastTrackedNetworkActivityAt: Number(tracker.lastTrackedNetworkActivityAt ?? 0),
1417
1458
  now: Number(performance.now()),
1418
1459
  pendingFetches: Number(tracker.pendingFetches ?? 0),
1419
1460
  pendingTimeouts: Number(tracker.pendingTimeouts ?? 0),
1420
1461
  pendingXhrs: Number(tracker.pendingXhrs ?? 0),
1462
+ trackedPendingFetches: Number(tracker.trackedPendingFetches ?? 0),
1463
+ trackedPendingXhrs: Number(tracker.trackedPendingXhrs ?? 0),
1464
+ collecting: tracker.collecting === true,
1421
1465
  readyState: String(document.readyState),
1422
1466
  };
1423
1467
  })()`;
1424
1468
  }
1469
+ function capturePostLoadTrackerSnapshot(tracker) {
1470
+ return {
1471
+ lastTrackedNetworkActivityAt: tracker.lastTrackedNetworkActivityAt,
1472
+ trackedPendingFetches: tracker.trackedPendingFetches,
1473
+ trackedPendingXhrs: tracker.trackedPendingXhrs
1474
+ };
1475
+ }
1476
+ function postLoadTrackerHasTrackedNetworkActivitySince(snapshot, tracker) {
1477
+ if (!tracker) {
1478
+ return false;
1479
+ }
1480
+ return tracker.trackedPendingFetches > snapshot.trackedPendingFetches || tracker.trackedPendingXhrs > snapshot.trackedPendingXhrs || tracker.lastTrackedNetworkActivityAt > snapshot.lastTrackedNetworkActivityAt;
1481
+ }
1425
1482
  function postLoadTrackerIsSettled(tracker, quietWindowMs = DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS) {
1426
1483
  if (!tracker) {
1427
1484
  return false;
@@ -1429,13 +1486,13 @@ function postLoadTrackerIsSettled(tracker, quietWindowMs = DEFAULT_POST_LOAD_TRA
1429
1486
  if (tracker.readyState !== "complete") {
1430
1487
  return false;
1431
1488
  }
1432
- if (tracker.pendingFetches > 0 || tracker.pendingTimeouts > 0 || tracker.pendingXhrs > 0) {
1489
+ if (tracker.trackedPendingFetches > 0 || tracker.trackedPendingXhrs > 0) {
1433
1490
  return false;
1434
1491
  }
1435
1492
  const lastActivityAt = Math.max(
1436
1493
  tracker.installedAt,
1437
1494
  tracker.lastMutationAt,
1438
- tracker.lastNetworkActivityAt
1495
+ tracker.lastTrackedNetworkActivityAt
1439
1496
  );
1440
1497
  return tracker.now - lastActivityAt >= quietWindowMs;
1441
1498
  }
@@ -1457,7 +1514,7 @@ async function waitForActionBoundary(input) {
1457
1514
  const pollIntervalMs = input.pollIntervalMs ?? DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS;
1458
1515
  let trigger = "dom-action";
1459
1516
  let crossDocument = false;
1460
- let waitedForNavigationContentLoaded = false;
1517
+ let sameDocumentAsyncActivity = false;
1461
1518
  while (Date.now() < deadline) {
1462
1519
  input.throwBackgroundError();
1463
1520
  if (input.isPageClosed()) {
@@ -1479,16 +1536,21 @@ async function waitForActionBoundary(input) {
1479
1536
  throw abortError(input.signal);
1480
1537
  }
1481
1538
  const currentDocumentRef = input.getCurrentMainFrameDocumentRef();
1539
+ const currentPageUrl = input.getCurrentPageUrl?.();
1482
1540
  if (input.snapshot !== void 0 && currentDocumentRef !== void 0 && currentDocumentRef !== input.snapshot.documentRef) {
1483
1541
  trigger = "navigation";
1484
1542
  crossDocument = true;
1485
- if (!waitedForNavigationContentLoaded) {
1486
- waitedForNavigationContentLoaded = true;
1487
- const remaining = Math.max(0, deadline - Date.now());
1488
- if (remaining > 0) {
1489
- await input.waitForNavigationContentLoaded(remaining);
1490
- }
1491
- }
1543
+ }
1544
+ if (!crossDocument && !sameDocumentAsyncActivity && input.snapshot?.tracker !== void 0 && postLoadTrackerHasTrackedNetworkActivitySince(
1545
+ input.snapshot.tracker,
1546
+ await input.readTrackerState()
1547
+ )) {
1548
+ trigger = "navigation";
1549
+ sameDocumentAsyncActivity = true;
1550
+ }
1551
+ if (!crossDocument && input.snapshot?.url !== void 0 && currentPageUrl !== void 0 && currentPageUrl !== input.snapshot.url && input.isCurrentMainFrameBootstrapSettled !== void 0 && !input.isCurrentMainFrameBootstrapSettled()) {
1552
+ trigger = "navigation";
1553
+ crossDocument = true;
1492
1554
  }
1493
1555
  if (!crossDocument && crossDocumentDetectionDeadline !== void 0 && Date.now() >= crossDocumentDetectionDeadline) {
1494
1556
  return {
@@ -1497,7 +1559,18 @@ async function waitForActionBoundary(input) {
1497
1559
  bootstrapSettled: true
1498
1560
  };
1499
1561
  }
1500
- if (crossDocument && postLoadTrackerIsSettled(await input.readTrackerState())) {
1562
+ if (sameDocumentAsyncActivity) {
1563
+ return {
1564
+ trigger,
1565
+ crossDocument,
1566
+ bootstrapSettled: true
1567
+ };
1568
+ }
1569
+ if (crossDocument && input.isCurrentMainFrameBootstrapSettled !== void 0 && !input.isCurrentMainFrameBootstrapSettled()) {
1570
+ await delay(Math.min(pollIntervalMs, Math.max(0, deadline - Date.now())));
1571
+ continue;
1572
+ }
1573
+ if (crossDocument) {
1501
1574
  return {
1502
1575
  trigger,
1503
1576
  crossDocument,
@@ -2264,6 +2337,7 @@ function normalizeSelectChooserEventData(data) {
2264
2337
 
2265
2338
  // src/action-settle.ts
2266
2339
  var DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS = CROSS_DOCUMENT_INTERACTION_TIMEOUT_MS;
2340
+ var DEFAULT_ABP_POST_LOAD_CAPTURE_WINDOW_MS = 1e3;
2267
2341
  function clampAbpActionSettleTimeout(timeoutMs) {
2268
2342
  if (timeoutMs === void 0) {
2269
2343
  return DEFAULT_ABP_ACTION_SETTLE_TIMEOUT_MS;
@@ -2275,6 +2349,8 @@ function abortError2(signal) {
2275
2349
  }
2276
2350
  function createAbpActionSettler(context) {
2277
2351
  const installScript = buildPostLoadTrackerInstallScript();
2352
+ const beginExpression = buildPostLoadTrackerBeginExpression();
2353
+ const freezeExpression = buildPostLoadTrackerFreezeExpression();
2278
2354
  const readExpression = buildPostLoadTrackerReadExpression();
2279
2355
  async function installTracker(controller) {
2280
2356
  if (!controller.settleTrackerRegistered) {
@@ -2304,6 +2380,67 @@ function createAbpActionSettler(context) {
2304
2380
  throw error;
2305
2381
  }
2306
2382
  }
2383
+ async function beginTrackerObservation(controller) {
2384
+ await installTracker(controller);
2385
+ await controller.cdp.send("Runtime.evaluate", {
2386
+ expression: beginExpression,
2387
+ returnByValue: true,
2388
+ awaitPromise: true
2389
+ });
2390
+ }
2391
+ async function freezeTrackerObservation(controller) {
2392
+ await controller.cdp.send("Runtime.evaluate", {
2393
+ expression: freezeExpression,
2394
+ returnByValue: true,
2395
+ awaitPromise: true
2396
+ });
2397
+ }
2398
+ async function captureSnapshot(controller) {
2399
+ const documentRef = context.getMainFrameDocumentRef(controller);
2400
+ if (documentRef === void 0) {
2401
+ throw new Error(`page ${controller.pageRef} does not expose a main frame`);
2402
+ }
2403
+ await beginTrackerObservation(controller);
2404
+ const tracker = await readTrackerState(controller);
2405
+ return {
2406
+ pageRef: controller.pageRef,
2407
+ documentRef,
2408
+ ...controller.mainFrameRef === void 0 ? {} : {
2409
+ url: controller.framesByCdpId.get(controller.mainFrameRef)?.currentDocument.url
2410
+ },
2411
+ ...tracker === void 0 ? {} : { tracker: capturePostLoadTrackerSnapshot(tracker) }
2412
+ };
2413
+ }
2414
+ async function waitForPostLoadQuiet(input) {
2415
+ const { controller, timeoutMs, signal } = input;
2416
+ if (timeoutMs <= 0) {
2417
+ return;
2418
+ }
2419
+ const quietMs = input.quietMs ?? DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS;
2420
+ const captureWindowMs = Math.max(
2421
+ 0,
2422
+ Math.min(input.captureWindowMs ?? DEFAULT_ABP_POST_LOAD_CAPTURE_WINDOW_MS, timeoutMs)
2423
+ );
2424
+ const deadline = Date.now() + timeoutMs;
2425
+ await installTracker(controller);
2426
+ if (captureWindowMs > 0) {
2427
+ await delayWithSignal(captureWindowMs, signal, deadline);
2428
+ }
2429
+ await freezeTrackerObservation(controller);
2430
+ while (Date.now() < deadline) {
2431
+ if (signal?.aborted) {
2432
+ throw abortError2(signal);
2433
+ }
2434
+ context.throwBackgroundError(controller);
2435
+ if (controller.lifecycleState === "closed") {
2436
+ return;
2437
+ }
2438
+ if (postLoadTrackerIsSettled(await readTrackerState(controller), quietMs)) {
2439
+ return;
2440
+ }
2441
+ await delayWithSignal(100, signal, deadline);
2442
+ }
2443
+ }
2307
2444
  async function settle(options) {
2308
2445
  const { controller, timeoutMs, signal, snapshot, policySettle } = options;
2309
2446
  if (timeoutMs <= 0) {
@@ -2344,7 +2481,8 @@ function createAbpActionSettler(context) {
2344
2481
  ...signal === void 0 ? {} : { signal },
2345
2482
  snapshot,
2346
2483
  getCurrentMainFrameDocumentRef: () => context.getMainFrameDocumentRef(controller),
2347
- waitForNavigationContentLoaded: (remainingMs) => context.waitForNavigationContentLoaded(controller, remainingMs),
2484
+ getCurrentPageUrl: () => controller.mainFrameRef === void 0 ? void 0 : controller.framesByCdpId.get(controller.mainFrameRef)?.currentDocument.url,
2485
+ isCurrentMainFrameBootstrapSettled: () => context.isCurrentMainFrameBootstrapSettled(controller),
2348
2486
  readTrackerState: () => readTrackerState(controller),
2349
2487
  throwBackgroundError: () => context.throwBackgroundError(controller),
2350
2488
  isPageClosed: () => controller.lifecycleState === "closed"
@@ -2376,10 +2514,33 @@ function createAbpActionSettler(context) {
2376
2514
  return boundary;
2377
2515
  }
2378
2516
  return {
2517
+ captureSnapshot,
2379
2518
  installTracker,
2519
+ waitForPostLoadQuiet,
2380
2520
  settle
2381
2521
  };
2382
2522
  }
2523
+ async function delayWithSignal(delayMs, signal, deadline) {
2524
+ const effectiveDelay = Math.max(0, Math.min(delayMs, Math.max(0, deadline - Date.now())));
2525
+ if (effectiveDelay <= 0) {
2526
+ return;
2527
+ }
2528
+ if (signal?.aborted) {
2529
+ throw abortError2(signal);
2530
+ }
2531
+ await new Promise((resolve, reject) => {
2532
+ const timer = setTimeout(() => {
2533
+ signal?.removeEventListener("abort", onAbort);
2534
+ resolve();
2535
+ }, effectiveDelay);
2536
+ const onAbort = () => {
2537
+ clearTimeout(timer);
2538
+ signal?.removeEventListener("abort", onAbort);
2539
+ reject(abortError2(signal));
2540
+ };
2541
+ signal?.addEventListener("abort", onAbort, { once: true });
2542
+ });
2543
+ }
2383
2544
 
2384
2545
  // src/rest-client.ts
2385
2546
  function isRecord3(value) {
@@ -4294,7 +4455,7 @@ var AbpBrowserCoreEngine = class _AbpBrowserCoreEngine {
4294
4455
  setExecutionPaused: (controller, paused) => this.setControllerExecutionPaused(controller, paused),
4295
4456
  flushDomUpdateTask: (controller) => this.flushDomUpdateTask(controller),
4296
4457
  getMainFrameDocumentRef: (controller) => controller.mainFrameRef === void 0 ? void 0 : this.frames.get(controller.mainFrameRef)?.currentDocument.documentRef,
4297
- waitForNavigationContentLoaded: async () => void 0,
4458
+ isCurrentMainFrameBootstrapSettled: () => true,
4298
4459
  throwBackgroundError: (controller) => this.throwBackgroundError(controller),
4299
4460
  isPageClosedError: isAbpPageClosedError
4300
4461
  });
@@ -5057,6 +5218,9 @@ var AbpBrowserCoreEngine = class _AbpBrowserCoreEngine {
5057
5218
  )
5058
5219
  );
5059
5220
  }
5221
+ async drainEvents(input) {
5222
+ return this.drainQueuedEvents(input.pageRef);
5223
+ }
5060
5224
  async listFrames(input) {
5061
5225
  const controller = this.requirePage(input.pageRef);
5062
5226
  await this.flushDomUpdateTask(controller);
@@ -5108,6 +5272,11 @@ var AbpBrowserCoreEngine = class _AbpBrowserCoreEngine {
5108
5272
  (contentDocumentIndex) => resolveCapturedContentDocumentRef(controller.framesByCdpId, captured, contentDocumentIndex)
5109
5273
  );
5110
5274
  }
5275
+ async getActionBoundarySnapshot(input) {
5276
+ const controller = this.requirePage(input.pageRef);
5277
+ await this.flushDomUpdateTask(controller);
5278
+ return this.actionSettler.captureSnapshot(controller);
5279
+ }
5111
5280
  async waitForVisualStability(input) {
5112
5281
  const controller = this.requirePage(input.pageRef);
5113
5282
  await this.flushDomUpdateTask(controller);
@@ -5118,6 +5287,20 @@ var AbpBrowserCoreEngine = class _AbpBrowserCoreEngine {
5118
5287
  });
5119
5288
  await this.flushDomUpdateTask(controller);
5120
5289
  }
5290
+ async waitForPostLoadQuiet(input) {
5291
+ const controller = this.requirePage(input.pageRef);
5292
+ await this.flushDomUpdateTask(controller);
5293
+ await this.actionSettler.waitForPostLoadQuiet({
5294
+ controller,
5295
+ timeoutMs: clampAbpActionSettleTimeout(input.timeoutMs),
5296
+ ...input.quietMs === void 0 ? {} : { quietMs: input.quietMs },
5297
+ ...input.captureWindowMs === void 0 ? {} : { captureWindowMs: input.captureWindowMs },
5298
+ ...input.signal === void 0 ? {} : { signal: input.signal }
5299
+ });
5300
+ if (controller.lifecycleState !== "closed") {
5301
+ await this.flushDomUpdateTask(controller);
5302
+ }
5303
+ }
5121
5304
  async readText(input) {
5122
5305
  const document = this.requireDocument(input.documentRef);
5123
5306
  const controller = this.requirePage(document.pageRef);