@opensteer/engine-playwright 0.8.0 → 0.8.2
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 +433 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -3
- package/dist/index.d.ts +20 -3
- package/dist/index.js +433 -7
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1259,6 +1259,282 @@ function sleep(ms) {
|
|
|
1259
1259
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1260
1260
|
}
|
|
1261
1261
|
|
|
1262
|
+
// ../browser-core/src/post-load-tracker.ts
|
|
1263
|
+
var DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS = 400;
|
|
1264
|
+
var DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS = 100;
|
|
1265
|
+
function isRecord(value) {
|
|
1266
|
+
return typeof value === "object" && value !== null;
|
|
1267
|
+
}
|
|
1268
|
+
function readFiniteNumber(value) {
|
|
1269
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1270
|
+
}
|
|
1271
|
+
function readNonNegativeNumber(value) {
|
|
1272
|
+
const parsed = readFiniteNumber(value);
|
|
1273
|
+
return parsed === void 0 || parsed < 0 ? 0 : parsed;
|
|
1274
|
+
}
|
|
1275
|
+
function normalizePostLoadTrackerState(value) {
|
|
1276
|
+
if (!isRecord(value)) {
|
|
1277
|
+
return void 0;
|
|
1278
|
+
}
|
|
1279
|
+
const installedAt = readFiniteNumber(value.installedAt);
|
|
1280
|
+
const lastMutationAt = readFiniteNumber(value.lastMutationAt);
|
|
1281
|
+
const lastNetworkActivityAt = readFiniteNumber(value.lastNetworkActivityAt);
|
|
1282
|
+
const now = readFiniteNumber(value.now);
|
|
1283
|
+
const readyState = typeof value.readyState === "string" ? value.readyState : void 0;
|
|
1284
|
+
if (installedAt === void 0 || lastMutationAt === void 0 || lastNetworkActivityAt === void 0 || now === void 0 || readyState === void 0) {
|
|
1285
|
+
return void 0;
|
|
1286
|
+
}
|
|
1287
|
+
return {
|
|
1288
|
+
installedAt,
|
|
1289
|
+
lastMutationAt,
|
|
1290
|
+
lastNetworkActivityAt,
|
|
1291
|
+
now,
|
|
1292
|
+
pendingFetches: readNonNegativeNumber(value.pendingFetches),
|
|
1293
|
+
pendingTimeouts: readNonNegativeNumber(value.pendingTimeouts),
|
|
1294
|
+
pendingXhrs: readNonNegativeNumber(value.pendingXhrs),
|
|
1295
|
+
readyState
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
function buildPostLoadTrackerInstallScript() {
|
|
1299
|
+
return `(() => {
|
|
1300
|
+
const globalObject = globalThis;
|
|
1301
|
+
if (globalObject.__opensteerActionBoundaryTrackerInstalled) {
|
|
1302
|
+
return true;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
const tracker = {
|
|
1306
|
+
installedAt: performance.now(),
|
|
1307
|
+
lastMutationAt: performance.now(),
|
|
1308
|
+
lastNetworkActivityAt: performance.now(),
|
|
1309
|
+
pendingFetches: 0,
|
|
1310
|
+
pendingTimeouts: 0,
|
|
1311
|
+
pendingXhrs: 0,
|
|
1312
|
+
readyState: document.readyState,
|
|
1313
|
+
timeoutIds: new Set(),
|
|
1314
|
+
};
|
|
1315
|
+
globalObject.__opensteerActionBoundaryTrackerInstalled = true;
|
|
1316
|
+
globalObject.__opensteerActionBoundaryTracker = tracker;
|
|
1317
|
+
|
|
1318
|
+
const markMutation = () => {
|
|
1319
|
+
tracker.lastMutationAt = performance.now();
|
|
1320
|
+
tracker.readyState = document.readyState;
|
|
1321
|
+
};
|
|
1322
|
+
const markNetwork = () => {
|
|
1323
|
+
tracker.lastNetworkActivityAt = performance.now();
|
|
1324
|
+
tracker.readyState = document.readyState;
|
|
1325
|
+
};
|
|
1326
|
+
|
|
1327
|
+
const startObserver = () => {
|
|
1328
|
+
const target = document.documentElement ?? document;
|
|
1329
|
+
if (!(target instanceof Node)) {
|
|
1330
|
+
return;
|
|
1331
|
+
}
|
|
1332
|
+
const observer = new MutationObserver(markMutation);
|
|
1333
|
+
observer.observe(target, {
|
|
1334
|
+
subtree: true,
|
|
1335
|
+
childList: true,
|
|
1336
|
+
characterData: true,
|
|
1337
|
+
attributes: true,
|
|
1338
|
+
});
|
|
1339
|
+
markMutation();
|
|
1340
|
+
};
|
|
1341
|
+
|
|
1342
|
+
if (document.documentElement) {
|
|
1343
|
+
startObserver();
|
|
1344
|
+
} else {
|
|
1345
|
+
document.addEventListener("DOMContentLoaded", startObserver, { once: true });
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
document.addEventListener("readystatechange", markMutation);
|
|
1349
|
+
addEventListener("load", markMutation, { once: true });
|
|
1350
|
+
|
|
1351
|
+
const nativeSetTimeout = globalObject.setTimeout.bind(globalObject);
|
|
1352
|
+
const nativeClearTimeout = globalObject.clearTimeout.bind(globalObject);
|
|
1353
|
+
globalObject.setTimeout = function(callback, delay, ...args) {
|
|
1354
|
+
tracker.pendingTimeouts += 1;
|
|
1355
|
+
markNetwork();
|
|
1356
|
+
let handle;
|
|
1357
|
+
const wrapped =
|
|
1358
|
+
typeof callback === "function"
|
|
1359
|
+
? (...callbackArgs) => {
|
|
1360
|
+
if (tracker.timeoutIds.delete(handle)) {
|
|
1361
|
+
tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
|
|
1362
|
+
}
|
|
1363
|
+
try {
|
|
1364
|
+
return callback(...callbackArgs);
|
|
1365
|
+
} finally {
|
|
1366
|
+
markMutation();
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
: callback;
|
|
1370
|
+
handle = nativeSetTimeout(wrapped, delay, ...args);
|
|
1371
|
+
tracker.timeoutIds.add(handle);
|
|
1372
|
+
return handle;
|
|
1373
|
+
};
|
|
1374
|
+
globalObject.clearTimeout = function(handle) {
|
|
1375
|
+
if (tracker.timeoutIds.delete(handle)) {
|
|
1376
|
+
tracker.pendingTimeouts = Math.max(0, tracker.pendingTimeouts - 1);
|
|
1377
|
+
}
|
|
1378
|
+
return nativeClearTimeout(handle);
|
|
1379
|
+
};
|
|
1380
|
+
|
|
1381
|
+
if (typeof globalObject.fetch === "function") {
|
|
1382
|
+
const nativeFetch = globalObject.fetch.bind(globalObject);
|
|
1383
|
+
globalObject.fetch = (...args) => {
|
|
1384
|
+
tracker.pendingFetches += 1;
|
|
1385
|
+
markNetwork();
|
|
1386
|
+
return nativeFetch(...args)
|
|
1387
|
+
.finally(() => {
|
|
1388
|
+
tracker.pendingFetches = Math.max(0, tracker.pendingFetches - 1);
|
|
1389
|
+
markNetwork();
|
|
1390
|
+
});
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
if (typeof globalObject.XMLHttpRequest === "function") {
|
|
1395
|
+
const NativeXMLHttpRequest = globalObject.XMLHttpRequest;
|
|
1396
|
+
const nativeSend = NativeXMLHttpRequest.prototype.send;
|
|
1397
|
+
NativeXMLHttpRequest.prototype.send = function(...args) {
|
|
1398
|
+
tracker.pendingXhrs += 1;
|
|
1399
|
+
markNetwork();
|
|
1400
|
+
const finalize = () => {
|
|
1401
|
+
this.removeEventListener("loadend", finalize);
|
|
1402
|
+
tracker.pendingXhrs = Math.max(0, tracker.pendingXhrs - 1);
|
|
1403
|
+
markNetwork();
|
|
1404
|
+
};
|
|
1405
|
+
this.addEventListener("loadend", finalize, { once: true });
|
|
1406
|
+
return nativeSend.apply(this, args);
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
return true;
|
|
1411
|
+
})()`;
|
|
1412
|
+
}
|
|
1413
|
+
function buildPostLoadTrackerReadExpression() {
|
|
1414
|
+
return `(() => {
|
|
1415
|
+
const tracker = globalThis.__opensteerActionBoundaryTracker;
|
|
1416
|
+
if (!tracker) {
|
|
1417
|
+
return null;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
return {
|
|
1421
|
+
installedAt: Number(tracker.installedAt ?? 0),
|
|
1422
|
+
lastMutationAt: Number(tracker.lastMutationAt ?? 0),
|
|
1423
|
+
lastNetworkActivityAt: Number(tracker.lastNetworkActivityAt ?? 0),
|
|
1424
|
+
now: Number(performance.now()),
|
|
1425
|
+
pendingFetches: Number(tracker.pendingFetches ?? 0),
|
|
1426
|
+
pendingTimeouts: Number(tracker.pendingTimeouts ?? 0),
|
|
1427
|
+
pendingXhrs: Number(tracker.pendingXhrs ?? 0),
|
|
1428
|
+
readyState: String(document.readyState),
|
|
1429
|
+
};
|
|
1430
|
+
})()`;
|
|
1431
|
+
}
|
|
1432
|
+
function postLoadTrackerIsSettled(tracker, quietWindowMs = DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS) {
|
|
1433
|
+
if (!tracker) {
|
|
1434
|
+
return false;
|
|
1435
|
+
}
|
|
1436
|
+
if (tracker.readyState !== "complete") {
|
|
1437
|
+
return false;
|
|
1438
|
+
}
|
|
1439
|
+
if (tracker.pendingFetches > 0 || tracker.pendingTimeouts > 0 || tracker.pendingXhrs > 0) {
|
|
1440
|
+
return false;
|
|
1441
|
+
}
|
|
1442
|
+
const lastActivityAt = Math.max(
|
|
1443
|
+
tracker.installedAt,
|
|
1444
|
+
tracker.lastMutationAt,
|
|
1445
|
+
tracker.lastNetworkActivityAt
|
|
1446
|
+
);
|
|
1447
|
+
return tracker.now - lastActivityAt >= quietWindowMs;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
// ../browser-core/src/action-boundary.ts
|
|
1451
|
+
var CROSS_DOCUMENT_INTERACTION_TIMEOUT_MS = 3e4;
|
|
1452
|
+
var CROSS_DOCUMENT_DETECTION_WINDOW_MS = 500;
|
|
1453
|
+
async function waitForActionBoundary(input) {
|
|
1454
|
+
if (input.timeoutMs <= 0) {
|
|
1455
|
+
return {
|
|
1456
|
+
trigger: "dom-action",
|
|
1457
|
+
crossDocument: false,
|
|
1458
|
+
bootstrapSettled: false,
|
|
1459
|
+
timedOutPhase: "bootstrap"
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
const deadline = Date.now() + input.timeoutMs;
|
|
1463
|
+
const crossDocumentDetectionDeadline = input.snapshot === void 0 ? void 0 : Math.min(deadline, Date.now() + CROSS_DOCUMENT_DETECTION_WINDOW_MS);
|
|
1464
|
+
const pollIntervalMs = input.pollIntervalMs ?? DEFAULT_ACTION_BOUNDARY_POLL_INTERVAL_MS;
|
|
1465
|
+
let trigger = "dom-action";
|
|
1466
|
+
let crossDocument = false;
|
|
1467
|
+
let waitedForNavigationContentLoaded = false;
|
|
1468
|
+
while (Date.now() < deadline) {
|
|
1469
|
+
input.throwBackgroundError();
|
|
1470
|
+
if (input.isPageClosed()) {
|
|
1471
|
+
return {
|
|
1472
|
+
trigger,
|
|
1473
|
+
crossDocument,
|
|
1474
|
+
bootstrapSettled: true
|
|
1475
|
+
};
|
|
1476
|
+
}
|
|
1477
|
+
if (input.signal?.aborted) {
|
|
1478
|
+
if (isTimeoutAbort(input.signal.reason) && Date.now() >= deadline) {
|
|
1479
|
+
return {
|
|
1480
|
+
trigger,
|
|
1481
|
+
crossDocument,
|
|
1482
|
+
bootstrapSettled: false,
|
|
1483
|
+
timedOutPhase: "bootstrap"
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1486
|
+
throw abortError(input.signal);
|
|
1487
|
+
}
|
|
1488
|
+
const currentDocumentRef = input.getCurrentMainFrameDocumentRef();
|
|
1489
|
+
if (input.snapshot !== void 0 && currentDocumentRef !== void 0 && currentDocumentRef !== input.snapshot.documentRef) {
|
|
1490
|
+
trigger = "navigation";
|
|
1491
|
+
crossDocument = true;
|
|
1492
|
+
if (!waitedForNavigationContentLoaded) {
|
|
1493
|
+
waitedForNavigationContentLoaded = true;
|
|
1494
|
+
const remaining = Math.max(0, deadline - Date.now());
|
|
1495
|
+
if (remaining > 0) {
|
|
1496
|
+
await input.waitForNavigationContentLoaded(remaining);
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
if (!crossDocument && crossDocumentDetectionDeadline !== void 0 && Date.now() >= crossDocumentDetectionDeadline) {
|
|
1501
|
+
return {
|
|
1502
|
+
trigger,
|
|
1503
|
+
crossDocument,
|
|
1504
|
+
bootstrapSettled: true
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1507
|
+
if (crossDocument && postLoadTrackerIsSettled(await input.readTrackerState())) {
|
|
1508
|
+
return {
|
|
1509
|
+
trigger,
|
|
1510
|
+
crossDocument,
|
|
1511
|
+
bootstrapSettled: true
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
await delay(Math.min(pollIntervalMs, Math.max(0, deadline - Date.now())));
|
|
1515
|
+
}
|
|
1516
|
+
return {
|
|
1517
|
+
trigger,
|
|
1518
|
+
crossDocument,
|
|
1519
|
+
bootstrapSettled: false,
|
|
1520
|
+
timedOutPhase: "bootstrap"
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
function abortError(signal) {
|
|
1524
|
+
return signal.reason ?? new DOMException("The operation was aborted", "AbortError");
|
|
1525
|
+
}
|
|
1526
|
+
async function delay(ms) {
|
|
1527
|
+
if (ms <= 0) {
|
|
1528
|
+
return;
|
|
1529
|
+
}
|
|
1530
|
+
await new Promise((resolve) => {
|
|
1531
|
+
setTimeout(resolve, ms);
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
function isTimeoutAbort(reason) {
|
|
1535
|
+
return typeof reason === "object" && reason !== null && "code" in reason && reason.code === "timeout";
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1262
1538
|
// ../protocol/src/computer-use-bridge.ts
|
|
1263
1539
|
var OPENSTEER_COMPUTER_USE_BRIDGE_SYMBOL = /* @__PURE__ */ Symbol.for("@opensteer/computer-use-bridge");
|
|
1264
1540
|
|
|
@@ -1743,6 +2019,7 @@ function createPlaywrightComputerUseBridge(context) {
|
|
|
1743
2019
|
const startedAt = Date.now();
|
|
1744
2020
|
const actionController = context.resolveController(input.pageRef);
|
|
1745
2021
|
const action = input.action;
|
|
2022
|
+
let boundary;
|
|
1746
2023
|
let actionMs = 0;
|
|
1747
2024
|
let waitMs = 0;
|
|
1748
2025
|
const actionStartedAt = Date.now();
|
|
@@ -1808,7 +2085,12 @@ function createPlaywrightComputerUseBridge(context) {
|
|
|
1808
2085
|
await context.flushPendingPageTasks(actionController.sessionRef);
|
|
1809
2086
|
if (action.type !== "screenshot" && action.type !== "wait") {
|
|
1810
2087
|
const waitStartedAt = Date.now();
|
|
1811
|
-
await
|
|
2088
|
+
boundary = await context.settleActionBoundary(actionController, {
|
|
2089
|
+
signal: input.signal,
|
|
2090
|
+
...input.snapshot === void 0 ? {} : { snapshot: input.snapshot },
|
|
2091
|
+
remainingMs: input.remainingMs,
|
|
2092
|
+
policySettle: input.policySettle
|
|
2093
|
+
});
|
|
1812
2094
|
waitMs = Date.now() - waitStartedAt;
|
|
1813
2095
|
} else if (action.type === "wait") {
|
|
1814
2096
|
waitMs = actionMs;
|
|
@@ -1820,7 +2102,11 @@ function createPlaywrightComputerUseBridge(context) {
|
|
|
1820
2102
|
let resultController = context.resolveController(resultPageRef);
|
|
1821
2103
|
if (action.type !== "screenshot" && action.type !== "wait" && resultController.pageRef !== actionController.pageRef) {
|
|
1822
2104
|
const popupWaitStartedAt = Date.now();
|
|
1823
|
-
await
|
|
2105
|
+
await context.settleActionBoundary(resultController, {
|
|
2106
|
+
signal: input.signal,
|
|
2107
|
+
remainingMs: input.remainingMs,
|
|
2108
|
+
policySettle: input.policySettle
|
|
2109
|
+
});
|
|
1824
2110
|
waitMs += Date.now() - popupWaitStartedAt;
|
|
1825
2111
|
await context.flushPendingPageTasks(actionController.sessionRef);
|
|
1826
2112
|
resultController = context.resolveController(resultController.pageRef);
|
|
@@ -1844,7 +2130,8 @@ function createPlaywrightComputerUseBridge(context) {
|
|
|
1844
2130
|
actionMs,
|
|
1845
2131
|
waitMs,
|
|
1846
2132
|
totalMs: Date.now() - startedAt
|
|
1847
|
-
}
|
|
2133
|
+
},
|
|
2134
|
+
...boundary === void 0 ? {} : { boundary }
|
|
1848
2135
|
};
|
|
1849
2136
|
}
|
|
1850
2137
|
};
|
|
@@ -2877,10 +3164,12 @@ function createPlaywrightDomActionBridge(context) {
|
|
|
2877
3164
|
},
|
|
2878
3165
|
async finalizeDomAction(pageRef, options) {
|
|
2879
3166
|
const controller = context.resolveController(pageRef);
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
3167
|
+
return context.settleActionBoundary(controller, {
|
|
3168
|
+
signal: options.signal,
|
|
3169
|
+
...options.snapshot === void 0 ? {} : { snapshot: options.snapshot },
|
|
3170
|
+
remainingMs: options.remainingMs,
|
|
3171
|
+
policySettle: options.policySettle
|
|
3172
|
+
});
|
|
2884
3173
|
}
|
|
2885
3174
|
};
|
|
2886
3175
|
}
|
|
@@ -3148,6 +3437,121 @@ async function releaseObject(controller, objectId) {
|
|
|
3148
3437
|
await controller.cdp.send("Runtime.releaseObject", { objectId }).catch(() => void 0);
|
|
3149
3438
|
}
|
|
3150
3439
|
|
|
3440
|
+
// src/action-settle.ts
|
|
3441
|
+
var DEFAULT_PLAYWRIGHT_ACTION_SETTLE_TIMEOUT_MS = CROSS_DOCUMENT_INTERACTION_TIMEOUT_MS;
|
|
3442
|
+
function clampPlaywrightActionSettleTimeout(timeoutMs) {
|
|
3443
|
+
if (timeoutMs === void 0) {
|
|
3444
|
+
return DEFAULT_PLAYWRIGHT_ACTION_SETTLE_TIMEOUT_MS;
|
|
3445
|
+
}
|
|
3446
|
+
return Math.max(0, Math.min(DEFAULT_PLAYWRIGHT_ACTION_SETTLE_TIMEOUT_MS, timeoutMs));
|
|
3447
|
+
}
|
|
3448
|
+
function createPlaywrightActionSettler(context) {
|
|
3449
|
+
const installScript = buildPostLoadTrackerInstallScript();
|
|
3450
|
+
const readExpression = buildPostLoadTrackerReadExpression();
|
|
3451
|
+
async function installTracker(controller) {
|
|
3452
|
+
if (!controller.settleTrackerRegistered) {
|
|
3453
|
+
await controller.page.addInitScript(installScript);
|
|
3454
|
+
controller.settleTrackerRegistered = true;
|
|
3455
|
+
}
|
|
3456
|
+
try {
|
|
3457
|
+
await controller.cdp.send("Runtime.evaluate", {
|
|
3458
|
+
expression: installScript,
|
|
3459
|
+
returnByValue: true,
|
|
3460
|
+
awaitPromise: true
|
|
3461
|
+
});
|
|
3462
|
+
} catch (error) {
|
|
3463
|
+
if (controller.lifecycleState === "closed" || isContextClosedError(error)) {
|
|
3464
|
+
return;
|
|
3465
|
+
}
|
|
3466
|
+
throw normalizePlaywrightError(error, controller.pageRef);
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3469
|
+
async function readTrackerState(controller) {
|
|
3470
|
+
try {
|
|
3471
|
+
const evaluated = await controller.cdp.send("Runtime.evaluate", {
|
|
3472
|
+
expression: readExpression,
|
|
3473
|
+
returnByValue: true,
|
|
3474
|
+
awaitPromise: true
|
|
3475
|
+
});
|
|
3476
|
+
return normalizePostLoadTrackerState(evaluated.result?.value);
|
|
3477
|
+
} catch (error) {
|
|
3478
|
+
if (isIgnorableTrackerReadError(error)) {
|
|
3479
|
+
return void 0;
|
|
3480
|
+
}
|
|
3481
|
+
throw normalizePlaywrightError(error, controller.pageRef);
|
|
3482
|
+
}
|
|
3483
|
+
}
|
|
3484
|
+
async function settle(options) {
|
|
3485
|
+
const { controller, timeoutMs, signal, snapshot, policySettle } = options;
|
|
3486
|
+
if (timeoutMs <= 0) {
|
|
3487
|
+
return {
|
|
3488
|
+
trigger: "dom-action",
|
|
3489
|
+
crossDocument: false,
|
|
3490
|
+
bootstrapSettled: false,
|
|
3491
|
+
timedOutPhase: "bootstrap"
|
|
3492
|
+
};
|
|
3493
|
+
}
|
|
3494
|
+
await context.flushPendingPageTasks(controller.sessionRef);
|
|
3495
|
+
let boundary;
|
|
3496
|
+
if (snapshot === void 0) {
|
|
3497
|
+
if (policySettle) {
|
|
3498
|
+
if (signal?.aborted) {
|
|
3499
|
+
throw signal.reason ?? abortError2();
|
|
3500
|
+
}
|
|
3501
|
+
await policySettle(controller.pageRef, "dom-action");
|
|
3502
|
+
}
|
|
3503
|
+
boundary = {
|
|
3504
|
+
trigger: "dom-action",
|
|
3505
|
+
crossDocument: false,
|
|
3506
|
+
bootstrapSettled: true
|
|
3507
|
+
};
|
|
3508
|
+
} else {
|
|
3509
|
+
await installTracker(controller);
|
|
3510
|
+
boundary = await waitForActionBoundary({
|
|
3511
|
+
timeoutMs,
|
|
3512
|
+
...signal === void 0 ? {} : { signal },
|
|
3513
|
+
snapshot,
|
|
3514
|
+
getCurrentMainFrameDocumentRef: () => context.getMainFrameDocumentRef(controller),
|
|
3515
|
+
waitForNavigationContentLoaded: async (remainingMs) => {
|
|
3516
|
+
try {
|
|
3517
|
+
await controller.page.waitForLoadState("domcontentloaded", {
|
|
3518
|
+
timeout: remainingMs
|
|
3519
|
+
});
|
|
3520
|
+
} catch (error) {
|
|
3521
|
+
if (controller.lifecycleState === "closed" || isContextClosedError(error)) {
|
|
3522
|
+
return;
|
|
3523
|
+
}
|
|
3524
|
+
throw normalizePlaywrightError(error, controller.pageRef);
|
|
3525
|
+
}
|
|
3526
|
+
},
|
|
3527
|
+
readTrackerState: () => readTrackerState(controller),
|
|
3528
|
+
throwBackgroundError: () => context.throwBackgroundError(controller),
|
|
3529
|
+
isPageClosed: () => controller.lifecycleState === "closed"
|
|
3530
|
+
});
|
|
3531
|
+
if (policySettle) {
|
|
3532
|
+
await policySettle(controller.pageRef, boundary.trigger);
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
await context.flushPendingPageTasks(controller.sessionRef);
|
|
3536
|
+
if (controller.lifecycleState !== "closed") {
|
|
3537
|
+
await context.flushDomUpdateTask(controller);
|
|
3538
|
+
}
|
|
3539
|
+
return boundary;
|
|
3540
|
+
}
|
|
3541
|
+
return {
|
|
3542
|
+
installTracker,
|
|
3543
|
+
settle
|
|
3544
|
+
};
|
|
3545
|
+
}
|
|
3546
|
+
function abortError2() {
|
|
3547
|
+
return new DOMException("The operation was aborted", "AbortError");
|
|
3548
|
+
}
|
|
3549
|
+
function isIgnorableTrackerReadError(error) {
|
|
3550
|
+
return isContextClosedError(error) || error instanceof Error && /Execution context was destroyed|Cannot find context|Inspected target navigated or closed/i.test(
|
|
3551
|
+
error.message
|
|
3552
|
+
);
|
|
3553
|
+
}
|
|
3554
|
+
|
|
3151
3555
|
// src/storage-capture.ts
|
|
3152
3556
|
var ACTIVATION_PATH = "/__opensteer_storage_capture__";
|
|
3153
3557
|
var ACTIVATION_TIMEOUT_MS = 15e3;
|
|
@@ -3354,6 +3758,12 @@ var PlaywrightBrowserCoreEngine = class _PlaywrightBrowserCoreEngine {
|
|
|
3354
3758
|
pageByPlaywrightPage = /* @__PURE__ */ new WeakMap();
|
|
3355
3759
|
pendingPopupOpeners = /* @__PURE__ */ new WeakMap();
|
|
3356
3760
|
preassignedPopupPageRefs = /* @__PURE__ */ new WeakMap();
|
|
3761
|
+
actionSettler = createPlaywrightActionSettler({
|
|
3762
|
+
flushPendingPageTasks: (sessionRef) => this.flushPendingPageTasks(sessionRef),
|
|
3763
|
+
flushDomUpdateTask: (controller) => this.flushDomUpdateTask(controller),
|
|
3764
|
+
getMainFrameDocumentRef: (controller) => controller.mainFrameRef === void 0 ? void 0 : this.frames.get(controller.mainFrameRef)?.currentDocument.documentRef,
|
|
3765
|
+
throwBackgroundError: (controller) => this.throwBackgroundError(controller)
|
|
3766
|
+
});
|
|
3357
3767
|
pageCounter = 0;
|
|
3358
3768
|
frameCounter = 0;
|
|
3359
3769
|
documentCounter = 0;
|
|
@@ -3409,6 +3819,13 @@ var PlaywrightBrowserCoreEngine = class _PlaywrightBrowserCoreEngine {
|
|
|
3409
3819
|
resolveController: (pageRef) => this.requirePage(pageRef),
|
|
3410
3820
|
flushPendingPageTasks: (sessionRef) => this.flushPendingPageTasks(sessionRef),
|
|
3411
3821
|
flushDomUpdateTask: (controller) => this.flushDomUpdateTask(controller),
|
|
3822
|
+
settleActionBoundary: (controller, options) => this.actionSettler.settle({
|
|
3823
|
+
controller,
|
|
3824
|
+
timeoutMs: clampPlaywrightActionSettleTimeout(options.remainingMs()),
|
|
3825
|
+
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
3826
|
+
...options.snapshot === void 0 ? {} : { snapshot: options.snapshot },
|
|
3827
|
+
...options.policySettle === void 0 ? {} : { policySettle: options.policySettle }
|
|
3828
|
+
}),
|
|
3412
3829
|
requireMainFrame: (controller) => this.requireMainFrame(controller),
|
|
3413
3830
|
drainQueuedEvents: (pageRef) => this.drainQueuedEvents(pageRef),
|
|
3414
3831
|
withModifiers: (page, modifiers, action) => this.withModifiers(page, modifiers, action)
|
|
@@ -3420,6 +3837,13 @@ var PlaywrightBrowserCoreEngine = class _PlaywrightBrowserCoreEngine {
|
|
|
3420
3837
|
resolveController: (pageRef) => this.requirePage(pageRef),
|
|
3421
3838
|
flushPendingPageTasks: (sessionRef) => this.flushPendingPageTasks(sessionRef),
|
|
3422
3839
|
flushDomUpdateTask: (controller) => this.flushDomUpdateTask(controller),
|
|
3840
|
+
settleActionBoundary: (controller, options) => this.actionSettler.settle({
|
|
3841
|
+
controller,
|
|
3842
|
+
timeoutMs: clampPlaywrightActionSettleTimeout(options.remainingMs()),
|
|
3843
|
+
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
3844
|
+
...options.snapshot === void 0 ? {} : { snapshot: options.snapshot },
|
|
3845
|
+
...options.policySettle === void 0 ? {} : { policySettle: options.policySettle }
|
|
3846
|
+
}),
|
|
3423
3847
|
locateBackendNode: (document, backendNodeId) => createNodeLocator(
|
|
3424
3848
|
document.documentRef,
|
|
3425
3849
|
document.documentEpoch,
|
|
@@ -4514,6 +4938,7 @@ var PlaywrightBrowserCoreEngine = class _PlaywrightBrowserCoreEngine {
|
|
|
4514
4938
|
backgroundTasks: /* @__PURE__ */ new Set(),
|
|
4515
4939
|
domUpdateTask: void 0,
|
|
4516
4940
|
backgroundError: void 0,
|
|
4941
|
+
settleTrackerRegistered: false,
|
|
4517
4942
|
openerPageRef: void 0,
|
|
4518
4943
|
mainFrameRef: void 0,
|
|
4519
4944
|
lifecycleState: "open",
|
|
@@ -4530,6 +4955,7 @@ var PlaywrightBrowserCoreEngine = class _PlaywrightBrowserCoreEngine {
|
|
|
4530
4955
|
await cdp.send("DOM.enable", { includeWhitespace: "none" });
|
|
4531
4956
|
await cdp.send("DOMStorage.enable");
|
|
4532
4957
|
await cdp.send("DOM.getDocument", { depth: 0 });
|
|
4958
|
+
await this.actionSettler.installTracker(controller);
|
|
4533
4959
|
cdp.on(
|
|
4534
4960
|
"Page.frameAttached",
|
|
4535
4961
|
(payload) => this.runControllerEvent(
|