opensteer 0.9.5 → 0.9.6
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/{chunk-ZRF7WMS3.js → chunk-3I3A5OLB.js} +3 -3
- package/dist/{chunk-ZRF7WMS3.js.map → chunk-3I3A5OLB.js.map} +1 -1
- package/dist/{chunk-GSCQQKZZ.js → chunk-3XBQRZZC.js} +221 -6
- package/dist/chunk-3XBQRZZC.js.map +1 -0
- package/dist/{chunk-7LQL5YUR.js → chunk-BVRIPCWA.js} +259 -277
- package/dist/chunk-BVRIPCWA.js.map +1 -0
- package/dist/chunk-L4NF74KI.js +458 -0
- package/dist/chunk-L4NF74KI.js.map +1 -0
- package/dist/cli/bin.cjs +760 -282
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +225 -84
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +527 -202
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -3
- package/dist/index.d.ts +32 -3
- package/dist/index.js +3 -3
- package/dist/local-view/serve-entry.cjs +5354 -4
- package/dist/local-view/serve-entry.cjs.map +1 -1
- package/dist/local-view/serve-entry.js +1 -1
- package/dist/opensteer-UGA6YBRN.js +6 -0
- package/dist/{opensteer-T2JENADR.js.map → opensteer-UGA6YBRN.js.map} +1 -1
- package/dist/{session-control-M3JD7ZKA.js → session-control-U3L5H2ZI.js} +3 -3
- package/dist/{session-control-M3JD7ZKA.js.map → session-control-U3L5H2ZI.js.map} +1 -1
- package/package.json +6 -6
- package/dist/chunk-7D45QUZ3.js +0 -332
- package/dist/chunk-7D45QUZ3.js.map +0 -1
- package/dist/chunk-7LQL5YUR.js.map +0 -1
- package/dist/chunk-GSCQQKZZ.js.map +0 -1
- package/dist/opensteer-T2JENADR.js +0 -6
package/dist/index.cjs
CHANGED
|
@@ -1037,9 +1037,6 @@ function isBrowserCoreError(value) {
|
|
|
1037
1037
|
return value instanceof BrowserCoreError;
|
|
1038
1038
|
}
|
|
1039
1039
|
|
|
1040
|
-
// ../browser-core/src/cdp-visual-stability.ts
|
|
1041
|
-
var DEFAULT_VISUAL_STABILITY_SETTLE_MS = 750;
|
|
1042
|
-
|
|
1043
1040
|
// ../browser-core/src/post-load-tracker.ts
|
|
1044
1041
|
var DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS = 400;
|
|
1045
1042
|
|
|
@@ -6845,21 +6842,6 @@ var DEFAULT_SETTLE_DELAYS = {
|
|
|
6845
6842
|
"dom-action": 100,
|
|
6846
6843
|
snapshot: 0
|
|
6847
6844
|
};
|
|
6848
|
-
var defaultSnapshotSettleObserver = {
|
|
6849
|
-
async settle(input) {
|
|
6850
|
-
if (input.trigger !== "snapshot") {
|
|
6851
|
-
return false;
|
|
6852
|
-
}
|
|
6853
|
-
await input.engine.waitForVisualStability({
|
|
6854
|
-
pageRef: input.pageRef,
|
|
6855
|
-
...input.remainingMs === void 0 ? {} : { timeoutMs: input.remainingMs },
|
|
6856
|
-
settleMs: DEFAULT_VISUAL_STABILITY_SETTLE_MS,
|
|
6857
|
-
scope: "visible-frames"
|
|
6858
|
-
});
|
|
6859
|
-
return true;
|
|
6860
|
-
}
|
|
6861
|
-
};
|
|
6862
|
-
Object.freeze(defaultSnapshotSettleObserver);
|
|
6863
6845
|
var DOM_ACTION_VISUAL_STABILITY_PROFILES = {
|
|
6864
6846
|
"dom.click": { settleMs: 750, scope: "visible-frames", timeoutMs: 7e3 },
|
|
6865
6847
|
"dom.input": { settleMs: 750, scope: "visible-frames", timeoutMs: 7e3 },
|
|
@@ -6938,7 +6920,6 @@ var defaultNavigationSettleObserver = {
|
|
|
6938
6920
|
};
|
|
6939
6921
|
Object.freeze(defaultNavigationSettleObserver);
|
|
6940
6922
|
var DEFAULT_SETTLE_OBSERVERS = Object.freeze([
|
|
6941
|
-
defaultSnapshotSettleObserver,
|
|
6942
6923
|
defaultDomActionSettleObserver,
|
|
6943
6924
|
defaultNavigationSettleObserver
|
|
6944
6925
|
]);
|
|
@@ -7391,6 +7372,9 @@ function buildClauseSelector(node, clause) {
|
|
|
7391
7372
|
if (!clause || typeof clause !== "object") {
|
|
7392
7373
|
return "";
|
|
7393
7374
|
}
|
|
7375
|
+
if (clause.kind === "text") {
|
|
7376
|
+
return "";
|
|
7377
|
+
}
|
|
7394
7378
|
if (clause.kind === "position") {
|
|
7395
7379
|
if (clause.axis === "nthOfType") {
|
|
7396
7380
|
return `:nth-of-type(${Math.max(1, Number(node.position?.nthOfType || 1))})`;
|
|
@@ -7515,7 +7499,7 @@ function resolveExtractedValueInContext(normalizedValue, options) {
|
|
|
7515
7499
|
function stripPositionClauses(nodes) {
|
|
7516
7500
|
return (nodes || []).map((node) => ({
|
|
7517
7501
|
...node,
|
|
7518
|
-
match: (node.match || []).filter((clause) => clause.kind !== "position")
|
|
7502
|
+
match: (node.match || []).filter((clause) => clause.kind !== "position" && clause.kind !== "text")
|
|
7519
7503
|
}));
|
|
7520
7504
|
}
|
|
7521
7505
|
function dedupeSelectors(selectors) {
|
|
@@ -8092,9 +8076,17 @@ function resolveDomPathInScope(index, domPath, scope) {
|
|
|
8092
8076
|
if (!candidates.length) {
|
|
8093
8077
|
return null;
|
|
8094
8078
|
}
|
|
8079
|
+
const lastNode = domPath[domPath.length - 1];
|
|
8080
|
+
const textClauses = lastNode?.match.filter((c) => c.kind === "text") ?? [];
|
|
8095
8081
|
let fallback = null;
|
|
8096
8082
|
for (const selector of candidates) {
|
|
8097
|
-
|
|
8083
|
+
let matches = querySelectorAllInScope(index, selector, scope);
|
|
8084
|
+
if (textClauses.length > 0 && matches.length > 1) {
|
|
8085
|
+
const filtered = matches.filter((node) => matchesTextClauses(node, textClauses));
|
|
8086
|
+
if (filtered.length > 0) {
|
|
8087
|
+
matches = filtered;
|
|
8088
|
+
}
|
|
8089
|
+
}
|
|
8098
8090
|
if (matches.length === 1) {
|
|
8099
8091
|
return {
|
|
8100
8092
|
node: matches[0],
|
|
@@ -8114,6 +8106,10 @@ function resolveDomPathInScope(index, domPath, scope) {
|
|
|
8114
8106
|
}
|
|
8115
8107
|
return fallback;
|
|
8116
8108
|
}
|
|
8109
|
+
function matchesTextClauses(node, clauses) {
|
|
8110
|
+
const text = (node.textContent ?? "").replace(/\s+/g, " ").trim();
|
|
8111
|
+
return clauses.every((clause) => text.includes(clause.value));
|
|
8112
|
+
}
|
|
8117
8113
|
function queryAllDomPathInScope(index, domPath, scope) {
|
|
8118
8114
|
const selectors = buildPathCandidates(domPath);
|
|
8119
8115
|
for (const selector of selectors) {
|
|
@@ -8272,7 +8268,13 @@ function clonePathNode(node) {
|
|
|
8272
8268
|
};
|
|
8273
8269
|
}
|
|
8274
8270
|
function cloneMatchClause(clause) {
|
|
8275
|
-
|
|
8271
|
+
if (clause.kind === "position") {
|
|
8272
|
+
return { kind: "position", axis: clause.axis };
|
|
8273
|
+
}
|
|
8274
|
+
if (clause.kind === "text") {
|
|
8275
|
+
return { kind: "text", value: clause.value };
|
|
8276
|
+
}
|
|
8277
|
+
return {
|
|
8276
8278
|
kind: "attr",
|
|
8277
8279
|
key: clause.key,
|
|
8278
8280
|
...clause.op === void 0 ? {} : { op: clause.op },
|
|
@@ -8327,6 +8329,13 @@ function normalizeMatch(rawMatch, attrs, position, tag) {
|
|
|
8327
8329
|
op,
|
|
8328
8330
|
...value === void 0 ? {} : { value }
|
|
8329
8331
|
});
|
|
8332
|
+
continue;
|
|
8333
|
+
}
|
|
8334
|
+
if (record.kind === "text") {
|
|
8335
|
+
const textValue = typeof record.value === "string" ? record.value.trim() : "";
|
|
8336
|
+
if (textValue) {
|
|
8337
|
+
push({ kind: "text", value: textValue.slice(0, 80) });
|
|
8338
|
+
}
|
|
8330
8339
|
}
|
|
8331
8340
|
}
|
|
8332
8341
|
}
|
|
@@ -8694,7 +8703,7 @@ function isTimeoutError(error) {
|
|
|
8694
8703
|
}
|
|
8695
8704
|
|
|
8696
8705
|
// ../runtime-core/src/runtimes/dom/executor.ts
|
|
8697
|
-
var MAX_DOM_ACTION_ATTEMPTS =
|
|
8706
|
+
var MAX_DOM_ACTION_ATTEMPTS = 2;
|
|
8698
8707
|
var DEFAULT_SCROLL_OPTIONS = {
|
|
8699
8708
|
block: "center",
|
|
8700
8709
|
inline: "center"
|
|
@@ -9181,11 +9190,12 @@ var DomActionExecutor = class {
|
|
|
9181
9190
|
throw this.createActionabilityError(
|
|
9182
9191
|
operation,
|
|
9183
9192
|
"obscured",
|
|
9184
|
-
`
|
|
9193
|
+
`target is obscured by ${assessment.blockingDescription ?? "another element"} at the click point`,
|
|
9185
9194
|
{
|
|
9186
9195
|
...details,
|
|
9187
9196
|
hitRelation: assessment.relation,
|
|
9188
9197
|
...assessment.ambiguous === void 0 ? {} : { hitAmbiguous: assessment.ambiguous },
|
|
9198
|
+
...assessment.blockingDescription === void 0 ? {} : { blockingDescription: assessment.blockingDescription },
|
|
9189
9199
|
...assessment.canonicalTarget === void 0 ? {} : {
|
|
9190
9200
|
canonicalNodeRef: assessment.canonicalTarget.nodeRef,
|
|
9191
9201
|
canonicalDocumentRef: assessment.canonicalTarget.documentRef,
|
|
@@ -9199,8 +9209,7 @@ var DomActionExecutor = class {
|
|
|
9199
9209
|
hitMissingFromSnapshot: !resolved.snapshot.nodes.some(
|
|
9200
9210
|
(node) => node.nodeRef === hit.nodeRef
|
|
9201
9211
|
)
|
|
9202
|
-
}
|
|
9203
|
-
true
|
|
9212
|
+
}
|
|
9204
9213
|
);
|
|
9205
9214
|
}
|
|
9206
9215
|
async resolveActionablePointerTarget(session, operation, resolved) {
|
|
@@ -9412,7 +9421,12 @@ var DefaultDomRuntime = class {
|
|
|
9412
9421
|
});
|
|
9413
9422
|
}
|
|
9414
9423
|
async buildPath(input) {
|
|
9415
|
-
return sanitizeReplayElementPath(
|
|
9424
|
+
return sanitizeReplayElementPath(
|
|
9425
|
+
await this.requireBridge().buildReplayPath(
|
|
9426
|
+
input.locator,
|
|
9427
|
+
input.enableTextMatch ? { enableTextMatch: true } : void 0
|
|
9428
|
+
)
|
|
9429
|
+
);
|
|
9416
9430
|
}
|
|
9417
9431
|
async resolveTarget(input) {
|
|
9418
9432
|
return this.withSnapshotSession((session) => this.resolveTargetWithSession(session, input));
|
|
@@ -9632,7 +9646,7 @@ var DefaultDomRuntime = class {
|
|
|
9632
9646
|
if (resolvedByLocator) {
|
|
9633
9647
|
const { snapshot, node } = resolvedByLocator;
|
|
9634
9648
|
const anchor = await this.buildAnchorFromSnapshotNode(session, snapshot, node);
|
|
9635
|
-
const replayPath = await this.tryBuildPathFromNode(snapshot, node);
|
|
9649
|
+
const replayPath = await this.tryBuildPathFromNode(snapshot, node, { enableTextMatch: true });
|
|
9636
9650
|
return this.createResolvedTarget("live", snapshot, node, anchor, {
|
|
9637
9651
|
...target.persist === void 0 ? {} : { persist: target.persist },
|
|
9638
9652
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -9650,11 +9664,12 @@ var DefaultDomRuntime = class {
|
|
|
9650
9664
|
const { snapshot, node } = resolved;
|
|
9651
9665
|
const anchor = await this.buildAnchorFromSnapshotNode(session, snapshot, node);
|
|
9652
9666
|
const writeDescriptor = descriptorWriter ?? ((input) => this.descriptors.write(input));
|
|
9653
|
-
const
|
|
9667
|
+
const enableTextMatch = method !== "extract";
|
|
9668
|
+
const replayPath = await this.tryBuildPathFromNode(snapshot, node, { enableTextMatch });
|
|
9654
9669
|
const descriptor = target.persist === void 0 ? void 0 : await writeDescriptor({
|
|
9655
9670
|
method,
|
|
9656
9671
|
persist: target.persist,
|
|
9657
|
-
path: replayPath ?? await this.buildPathForNode(snapshot, node),
|
|
9672
|
+
path: replayPath ?? await this.buildPathForNode(snapshot, node, { enableTextMatch }),
|
|
9658
9673
|
sourceUrl: snapshot.url
|
|
9659
9674
|
});
|
|
9660
9675
|
return this.createResolvedTarget("selector", snapshot, node, anchor, {
|
|
@@ -9754,7 +9769,7 @@ var DefaultDomRuntime = class {
|
|
|
9754
9769
|
`Unable to resolve structural anchor "${buildPathSelectorHint(anchor)}" in the current session`
|
|
9755
9770
|
);
|
|
9756
9771
|
}
|
|
9757
|
-
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node);
|
|
9772
|
+
const replayPath = await this.tryBuildPathFromNode(context.snapshot, target.node, { enableTextMatch: true });
|
|
9758
9773
|
return this.createResolvedTarget(source, context.snapshot, target.node, anchor, {
|
|
9759
9774
|
...persist === void 0 ? {} : { persist },
|
|
9760
9775
|
...replayPath === void 0 ? {} : { replayPath }
|
|
@@ -9925,19 +9940,20 @@ var DefaultDomRuntime = class {
|
|
|
9925
9940
|
}
|
|
9926
9941
|
return this.bridge;
|
|
9927
9942
|
}
|
|
9928
|
-
async buildPathForNode(snapshot, node) {
|
|
9943
|
+
async buildPathForNode(snapshot, node, options) {
|
|
9929
9944
|
if (node.nodeRef === void 0) {
|
|
9930
9945
|
throw new Error(
|
|
9931
9946
|
`snapshot node ${String(node.snapshotNodeId)} does not expose a live node reference`
|
|
9932
9947
|
);
|
|
9933
9948
|
}
|
|
9934
9949
|
return this.buildPath({
|
|
9935
|
-
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef)
|
|
9950
|
+
locator: createNodeLocator(snapshot.documentRef, snapshot.documentEpoch, node.nodeRef),
|
|
9951
|
+
...options?.enableTextMatch ? { enableTextMatch: true } : {}
|
|
9936
9952
|
});
|
|
9937
9953
|
}
|
|
9938
|
-
async tryBuildPathFromNode(snapshot, node) {
|
|
9954
|
+
async tryBuildPathFromNode(snapshot, node, options) {
|
|
9939
9955
|
try {
|
|
9940
|
-
return await this.buildPathForNode(snapshot, node);
|
|
9956
|
+
return await this.buildPathForNode(snapshot, node, options);
|
|
9941
9957
|
} catch {
|
|
9942
9958
|
return void 0;
|
|
9943
9959
|
}
|
|
@@ -10551,6 +10567,9 @@ function relaxPathForSingleSample(path18, mode) {
|
|
|
10551
10567
|
}
|
|
10552
10568
|
return !isLast;
|
|
10553
10569
|
}
|
|
10570
|
+
if (clause.kind === "text") {
|
|
10571
|
+
return false;
|
|
10572
|
+
}
|
|
10554
10573
|
const key = String(clause.key || "").trim().toLowerCase();
|
|
10555
10574
|
if (!key || !shouldKeepAttrForSingleSample(key)) {
|
|
10556
10575
|
return false;
|
|
@@ -10653,9 +10672,11 @@ function buildNodeStructure(node) {
|
|
|
10653
10672
|
}
|
|
10654
10673
|
structuralAttrs[key] = value;
|
|
10655
10674
|
}
|
|
10656
|
-
const matchClauses = (node.match || []).map(
|
|
10657
|
-
(clause
|
|
10658
|
-
|
|
10675
|
+
const matchClauses = (node.match || []).map((clause) => {
|
|
10676
|
+
if (clause.kind === "position") return `position:${clause.axis}`;
|
|
10677
|
+
if (clause.kind === "text") return `text:${clause.value}`;
|
|
10678
|
+
return `attr:${String(clause.key || "").trim().toLowerCase()}`;
|
|
10679
|
+
}).sort();
|
|
10659
10680
|
return {
|
|
10660
10681
|
tag,
|
|
10661
10682
|
attrs: structuralAttrs,
|
|
@@ -11061,6 +11082,9 @@ function mergeMatchByMajority(matchLists, attrs, threshold, positionFlags = {
|
|
|
11061
11082
|
});
|
|
11062
11083
|
continue;
|
|
11063
11084
|
}
|
|
11085
|
+
if (clause.kind === "text") {
|
|
11086
|
+
continue;
|
|
11087
|
+
}
|
|
11064
11088
|
if (clause.axis === "nthOfType") {
|
|
11065
11089
|
if (positionFlags.hasNthOfType) {
|
|
11066
11090
|
merged.push({ kind: "position", axis: "nthOfType" });
|
|
@@ -13875,7 +13899,8 @@ function normalizeOpensteerEngineName(value, source = "engine") {
|
|
|
13875
13899
|
if (normalized === "playwright" || normalized === "abp") {
|
|
13876
13900
|
return normalized;
|
|
13877
13901
|
}
|
|
13878
|
-
throw new
|
|
13902
|
+
throw new OpensteerProtocolError(
|
|
13903
|
+
"invalid-argument",
|
|
13879
13904
|
`${source} must be one of ${OPENSTEER_ENGINE_NAMES.join(", ")}; received "${value}".`
|
|
13880
13905
|
);
|
|
13881
13906
|
}
|
|
@@ -13884,7 +13909,8 @@ function assertSupportedEngineOptions(input) {
|
|
|
13884
13909
|
return;
|
|
13885
13910
|
}
|
|
13886
13911
|
if (typeof input.browser === "object" && input.browser !== null && input.browser.mode === "attach") {
|
|
13887
|
-
throw new
|
|
13912
|
+
throw new OpensteerProtocolError(
|
|
13913
|
+
"invalid-argument",
|
|
13888
13914
|
'ABP engine does not support browser.mode="attach". Use the Playwright engine for attach flows.'
|
|
13889
13915
|
);
|
|
13890
13916
|
}
|
|
@@ -13892,7 +13918,8 @@ function assertSupportedEngineOptions(input) {
|
|
|
13892
13918
|
if (unsupportedContextOptionNames.length === 0) {
|
|
13893
13919
|
return;
|
|
13894
13920
|
}
|
|
13895
|
-
throw new
|
|
13921
|
+
throw new OpensteerProtocolError(
|
|
13922
|
+
"invalid-argument",
|
|
13896
13923
|
`ABP engine does not support ${unsupportedContextOptionNames.join(", ")}. Supported ABP context options: context.viewport.`
|
|
13897
13924
|
);
|
|
13898
13925
|
}
|
|
@@ -14994,6 +15021,48 @@ function isOpensteerEnvironmentKey(key) {
|
|
|
14994
15021
|
return key.startsWith(OPENSTEER_ENV_PREFIX);
|
|
14995
15022
|
}
|
|
14996
15023
|
|
|
15024
|
+
// src/internal/errors.ts
|
|
15025
|
+
function normalizeThrownOpensteerError(error, fallbackMessage) {
|
|
15026
|
+
if (isOpensteerProtocolError(error)) {
|
|
15027
|
+
return toOpensteerError(error);
|
|
15028
|
+
}
|
|
15029
|
+
if (isBrowserCoreError(error)) {
|
|
15030
|
+
return createOpensteerError(error.code, error.message, {
|
|
15031
|
+
retriable: error.retriable,
|
|
15032
|
+
...error.details === void 0 ? {} : { details: error.details }
|
|
15033
|
+
});
|
|
15034
|
+
}
|
|
15035
|
+
if (error instanceof OpensteerAttachAmbiguousError) {
|
|
15036
|
+
return createOpensteerError("conflict", error.message, {
|
|
15037
|
+
details: {
|
|
15038
|
+
candidates: error.candidates,
|
|
15039
|
+
code: error.code,
|
|
15040
|
+
name: error.name
|
|
15041
|
+
}
|
|
15042
|
+
});
|
|
15043
|
+
}
|
|
15044
|
+
if (error instanceof Error && "opensteerError" in error && typeof error.opensteerError === "object" && error.opensteerError !== null) {
|
|
15045
|
+
const oe = error.opensteerError;
|
|
15046
|
+
return createOpensteerError(oe.code, oe.message, {
|
|
15047
|
+
retriable: oe.retriable,
|
|
15048
|
+
...oe.capability === void 0 ? {} : { capability: oe.capability },
|
|
15049
|
+
...oe.details === void 0 ? {} : { details: oe.details }
|
|
15050
|
+
});
|
|
15051
|
+
}
|
|
15052
|
+
if (error instanceof Error) {
|
|
15053
|
+
return createOpensteerError("operation-failed", error.message, {
|
|
15054
|
+
details: {
|
|
15055
|
+
name: error.name
|
|
15056
|
+
}
|
|
15057
|
+
});
|
|
15058
|
+
}
|
|
15059
|
+
return createOpensteerError("internal", fallbackMessage, {
|
|
15060
|
+
details: {
|
|
15061
|
+
value: error
|
|
15062
|
+
}
|
|
15063
|
+
});
|
|
15064
|
+
}
|
|
15065
|
+
|
|
14997
15066
|
// src/provider/config.ts
|
|
14998
15067
|
var OPENSTEER_PROVIDER_MODES = ["local", "cloud"];
|
|
14999
15068
|
function assertProviderSupportsEngine(provider, engine) {
|
|
@@ -15001,7 +15070,8 @@ function assertProviderSupportsEngine(provider, engine) {
|
|
|
15001
15070
|
return;
|
|
15002
15071
|
}
|
|
15003
15072
|
if (provider === "cloud") {
|
|
15004
|
-
throw new
|
|
15073
|
+
throw new OpensteerProtocolError(
|
|
15074
|
+
"invalid-argument",
|
|
15005
15075
|
"ABP is not supported for provider=cloud. Cloud provider currently requires Playwright."
|
|
15006
15076
|
);
|
|
15007
15077
|
}
|
|
@@ -15011,7 +15081,8 @@ function normalizeOpensteerProviderMode(value, source = "OPENSTEER_PROVIDER") {
|
|
|
15011
15081
|
if (normalized === OPENSTEER_PROVIDER_MODES[0] || normalized === OPENSTEER_PROVIDER_MODES[1]) {
|
|
15012
15082
|
return normalized;
|
|
15013
15083
|
}
|
|
15014
|
-
throw new
|
|
15084
|
+
throw new OpensteerProtocolError(
|
|
15085
|
+
"invalid-argument",
|
|
15015
15086
|
`${source} must be one of ${OPENSTEER_PROVIDER_MODES.join(", ")}; received "${value}".`
|
|
15016
15087
|
);
|
|
15017
15088
|
}
|
|
@@ -15451,6 +15522,24 @@ async function sleep3(ms) {
|
|
|
15451
15522
|
// src/cloud/client.ts
|
|
15452
15523
|
var CLOUD_CLOSE_TIMEOUT_MS = 6e4;
|
|
15453
15524
|
var CLOUD_CLOSE_POLL_INTERVAL_MS = 250;
|
|
15525
|
+
var OpensteerCloudRequestError = class extends Error {
|
|
15526
|
+
statusCode;
|
|
15527
|
+
code;
|
|
15528
|
+
details;
|
|
15529
|
+
method;
|
|
15530
|
+
pathname;
|
|
15531
|
+
url;
|
|
15532
|
+
constructor(args) {
|
|
15533
|
+
super(args.message);
|
|
15534
|
+
this.name = "OpensteerCloudRequestError";
|
|
15535
|
+
this.statusCode = args.statusCode;
|
|
15536
|
+
this.code = args.code;
|
|
15537
|
+
this.details = args.details;
|
|
15538
|
+
this.method = args.method;
|
|
15539
|
+
this.pathname = args.pathname;
|
|
15540
|
+
this.url = args.url;
|
|
15541
|
+
}
|
|
15542
|
+
};
|
|
15454
15543
|
var OpensteerCloudClient = class {
|
|
15455
15544
|
constructor(config) {
|
|
15456
15545
|
this.config = config;
|
|
@@ -15626,7 +15715,11 @@ var OpensteerCloudClient = class {
|
|
|
15626
15715
|
});
|
|
15627
15716
|
}
|
|
15628
15717
|
if (!response.ok) {
|
|
15629
|
-
throw
|
|
15718
|
+
throw await createCloudRequestError(response, {
|
|
15719
|
+
method: init.method,
|
|
15720
|
+
pathname,
|
|
15721
|
+
url
|
|
15722
|
+
});
|
|
15630
15723
|
}
|
|
15631
15724
|
return response;
|
|
15632
15725
|
}
|
|
@@ -15674,6 +15767,36 @@ function wrapCloudFetchError(error, input) {
|
|
|
15674
15767
|
wrapped.name = error.name;
|
|
15675
15768
|
return wrapped;
|
|
15676
15769
|
}
|
|
15770
|
+
async function createCloudRequestError(response, input) {
|
|
15771
|
+
const payload = await readCloudErrorPayload(response);
|
|
15772
|
+
return new OpensteerCloudRequestError({
|
|
15773
|
+
statusCode: response.status,
|
|
15774
|
+
method: input.method,
|
|
15775
|
+
pathname: input.pathname,
|
|
15776
|
+
url: input.url,
|
|
15777
|
+
message: payload?.error ?? `${input.method} ${input.pathname} failed with ${String(response.status)}.`,
|
|
15778
|
+
...payload?.code === void 0 ? {} : { code: payload.code },
|
|
15779
|
+
...payload?.details === void 0 ? {} : { details: payload.details }
|
|
15780
|
+
});
|
|
15781
|
+
}
|
|
15782
|
+
async function readCloudErrorPayload(response) {
|
|
15783
|
+
try {
|
|
15784
|
+
return asCloudErrorPayload(await response.json());
|
|
15785
|
+
} catch {
|
|
15786
|
+
return void 0;
|
|
15787
|
+
}
|
|
15788
|
+
}
|
|
15789
|
+
function asCloudErrorPayload(value) {
|
|
15790
|
+
if (value === null || typeof value !== "object") {
|
|
15791
|
+
return void 0;
|
|
15792
|
+
}
|
|
15793
|
+
const payload = value;
|
|
15794
|
+
return {
|
|
15795
|
+
...typeof payload.error === "string" ? { error: payload.error } : {},
|
|
15796
|
+
...typeof payload.code === "string" ? { code: payload.code } : {},
|
|
15797
|
+
..."details" in payload ? { details: payload.details } : {}
|
|
15798
|
+
};
|
|
15799
|
+
}
|
|
15677
15800
|
|
|
15678
15801
|
// src/cloud/config.ts
|
|
15679
15802
|
function resolveCloudConfig(input = {}) {
|
|
@@ -15704,13 +15827,13 @@ function resolveCloudConfig(input = {}) {
|
|
|
15704
15827
|
|
|
15705
15828
|
// ../runtime-core/package.json
|
|
15706
15829
|
var package_default = {
|
|
15707
|
-
version: "0.2.
|
|
15830
|
+
version: "0.2.5"};
|
|
15708
15831
|
|
|
15709
15832
|
// ../runtime-core/src/version.ts
|
|
15710
15833
|
var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
|
|
15711
15834
|
|
|
15712
15835
|
// ../runtime-core/src/internal/errors.ts
|
|
15713
|
-
function
|
|
15836
|
+
function normalizeThrownOpensteerError2(error, fallbackMessage) {
|
|
15714
15837
|
if (isOpensteerProtocolError(error)) {
|
|
15715
15838
|
return toOpensteerError(error);
|
|
15716
15839
|
}
|
|
@@ -24843,7 +24966,7 @@ function toOpensteerResolvedTarget2(target) {
|
|
|
24843
24966
|
};
|
|
24844
24967
|
}
|
|
24845
24968
|
function normalizeOpensteerError(error) {
|
|
24846
|
-
return
|
|
24969
|
+
return normalizeThrownOpensteerError2(error, "Unknown Opensteer runtime failure");
|
|
24847
24970
|
}
|
|
24848
24971
|
function observationArtifactKindFromManifest(kind) {
|
|
24849
24972
|
switch (kind) {
|
|
@@ -25543,6 +25666,7 @@ function payloadByteLength(value) {
|
|
|
25543
25666
|
|
|
25544
25667
|
// src/cloud/session-proxy.ts
|
|
25545
25668
|
var TEMPORARY_CLOUD_WORKSPACE_PREFIX = "opensteer-cloud-workspace-";
|
|
25669
|
+
var CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS = 1e4;
|
|
25546
25670
|
var CloudSessionProxy = class {
|
|
25547
25671
|
rootPath;
|
|
25548
25672
|
workspace;
|
|
@@ -25556,6 +25680,8 @@ var CloudSessionProxy = class {
|
|
|
25556
25680
|
automation;
|
|
25557
25681
|
workspaceStore;
|
|
25558
25682
|
syncWorkspaceOnClose = false;
|
|
25683
|
+
liveSessionStateEstablished = false;
|
|
25684
|
+
storedInstrumentation = [];
|
|
25559
25685
|
constructor(cloud, options = {}) {
|
|
25560
25686
|
this.cloud = cloud;
|
|
25561
25687
|
this.workspace = options.workspace;
|
|
@@ -25585,15 +25711,12 @@ var CloudSessionProxy = class {
|
|
|
25585
25711
|
if (this.client === void 0 && this.sessionId === void 0 && persisted !== void 0 && await this.isReusableCloudSession(persisted.sessionId)) {
|
|
25586
25712
|
this.bindClient(persisted);
|
|
25587
25713
|
}
|
|
25588
|
-
|
|
25589
|
-
|
|
25590
|
-
|
|
25591
|
-
|
|
25592
|
-
|
|
25593
|
-
|
|
25594
|
-
};
|
|
25595
|
-
} catch {
|
|
25596
|
-
}
|
|
25714
|
+
const sessionInfo = this.automation ? await this.automation.getSessionInfo().catch(() => void 0) : void 0;
|
|
25715
|
+
if (sessionInfo !== void 0) {
|
|
25716
|
+
return {
|
|
25717
|
+
...sessionInfo,
|
|
25718
|
+
...this.workspace === void 0 ? {} : { workspace: this.workspace }
|
|
25719
|
+
};
|
|
25597
25720
|
}
|
|
25598
25721
|
return {
|
|
25599
25722
|
provider: {
|
|
@@ -25705,12 +25828,26 @@ var CloudSessionProxy = class {
|
|
|
25705
25828
|
return this.invokeSemanticOperation("session.cookies", input);
|
|
25706
25829
|
}
|
|
25707
25830
|
async route(input) {
|
|
25708
|
-
await this.
|
|
25709
|
-
|
|
25831
|
+
const registration = await this.invokeBootstrapInstrumentationOperation(
|
|
25832
|
+
"instrumentation.route",
|
|
25833
|
+
(automation) => automation.route(input)
|
|
25834
|
+
);
|
|
25835
|
+
this.storedInstrumentation.push({
|
|
25836
|
+
kind: "route",
|
|
25837
|
+
input
|
|
25838
|
+
});
|
|
25839
|
+
return registration;
|
|
25710
25840
|
}
|
|
25711
25841
|
async interceptScript(input) {
|
|
25712
|
-
await this.
|
|
25713
|
-
|
|
25842
|
+
const registration = await this.invokeBootstrapInstrumentationOperation(
|
|
25843
|
+
"instrumentation.intercept-script",
|
|
25844
|
+
(automation) => automation.interceptScript(input)
|
|
25845
|
+
);
|
|
25846
|
+
this.storedInstrumentation.push({
|
|
25847
|
+
kind: "intercept-script",
|
|
25848
|
+
input
|
|
25849
|
+
});
|
|
25850
|
+
return registration;
|
|
25714
25851
|
}
|
|
25715
25852
|
async getStorageSnapshot(input = {}) {
|
|
25716
25853
|
return this.invokeSemanticOperation("session.storage", input);
|
|
@@ -25758,6 +25895,8 @@ var CloudSessionProxy = class {
|
|
|
25758
25895
|
this.client = void 0;
|
|
25759
25896
|
this.sessionId = void 0;
|
|
25760
25897
|
this.semanticGrant = void 0;
|
|
25898
|
+
this.liveSessionStateEstablished = false;
|
|
25899
|
+
this.storedInstrumentation.length = 0;
|
|
25761
25900
|
if (this.cleanupRootOnClose) {
|
|
25762
25901
|
await promises.rm(this.rootPath, { recursive: true, force: true }).catch(() => void 0);
|
|
25763
25902
|
}
|
|
@@ -25785,6 +25924,8 @@ var CloudSessionProxy = class {
|
|
|
25785
25924
|
this.automation = void 0;
|
|
25786
25925
|
this.sessionId = void 0;
|
|
25787
25926
|
this.semanticGrant = void 0;
|
|
25927
|
+
this.liveSessionStateEstablished = false;
|
|
25928
|
+
this.storedInstrumentation.length = 0;
|
|
25788
25929
|
if (syncError !== void 0) {
|
|
25789
25930
|
throw syncError;
|
|
25790
25931
|
}
|
|
@@ -25832,6 +25973,7 @@ var CloudSessionProxy = class {
|
|
|
25832
25973
|
};
|
|
25833
25974
|
await this.writePersistedSession(record);
|
|
25834
25975
|
this.bindClient(record, session.initialGrants?.semantic);
|
|
25976
|
+
await this.restoreStoredInstrumentation();
|
|
25835
25977
|
}
|
|
25836
25978
|
async syncWorkspaceToCloud() {
|
|
25837
25979
|
if (this.workspace === void 0) {
|
|
@@ -25843,6 +25985,7 @@ var CloudSessionProxy = class {
|
|
|
25843
25985
|
bindClient(record, initialSemanticGrant) {
|
|
25844
25986
|
this.sessionId = record.sessionId;
|
|
25845
25987
|
this.semanticGrant = initialSemanticGrant?.kind === "semantic" ? initialSemanticGrant : void 0;
|
|
25988
|
+
this.liveSessionStateEstablished = false;
|
|
25846
25989
|
this.client = new OpensteerSemanticRestClient({
|
|
25847
25990
|
getBaseUrl: async () => (await this.ensureSemanticGrant()).url,
|
|
25848
25991
|
getAuthorizationHeader: async () => `Bearer ${(await this.ensureSemanticGrant()).token}`,
|
|
@@ -25850,6 +25993,19 @@ var CloudSessionProxy = class {
|
|
|
25850
25993
|
});
|
|
25851
25994
|
this.automation = new OpensteerCloudAutomationClient(this.cloud, record.sessionId);
|
|
25852
25995
|
}
|
|
25996
|
+
async restoreStoredInstrumentation() {
|
|
25997
|
+
if (this.storedInstrumentation.length === 0) {
|
|
25998
|
+
return;
|
|
25999
|
+
}
|
|
26000
|
+
const automation = this.requireAutomation();
|
|
26001
|
+
for (const registration of this.storedInstrumentation) {
|
|
26002
|
+
if (registration.kind === "route") {
|
|
26003
|
+
await automation.route(registration.input);
|
|
26004
|
+
} else {
|
|
26005
|
+
await automation.interceptScript(registration.input);
|
|
26006
|
+
}
|
|
26007
|
+
}
|
|
26008
|
+
}
|
|
25853
26009
|
async ensureWorkspaceStore() {
|
|
25854
26010
|
if (this.workspaceStore !== void 0) {
|
|
25855
26011
|
return this.workspaceStore;
|
|
@@ -25872,13 +26028,22 @@ var CloudSessionProxy = class {
|
|
|
25872
26028
|
async clearPersistedSession() {
|
|
25873
26029
|
await clearPersistedSessionRecord(this.rootPath, "cloud").catch(() => void 0);
|
|
25874
26030
|
}
|
|
26031
|
+
async invalidateSession() {
|
|
26032
|
+
await this.automation?.close().catch(() => void 0);
|
|
26033
|
+
this.automation = void 0;
|
|
26034
|
+
this.client = void 0;
|
|
26035
|
+
this.sessionId = void 0;
|
|
26036
|
+
this.semanticGrant = void 0;
|
|
26037
|
+
this.liveSessionStateEstablished = false;
|
|
26038
|
+
await this.clearPersistedSession();
|
|
26039
|
+
}
|
|
25875
26040
|
async isReusableCloudSession(sessionId, timeout) {
|
|
25876
26041
|
try {
|
|
25877
26042
|
const session = await this.cloud.getSession(sessionId, {
|
|
25878
26043
|
signal: timeout?.signal,
|
|
25879
26044
|
timeoutMs: timeout?.remainingMs()
|
|
25880
26045
|
});
|
|
25881
|
-
return session
|
|
26046
|
+
return isReusableCloudSessionState(session);
|
|
25882
26047
|
} catch (error) {
|
|
25883
26048
|
if (isMissingCloudSessionError(error)) {
|
|
25884
26049
|
return false;
|
|
@@ -25927,26 +26092,79 @@ var CloudSessionProxy = class {
|
|
|
25927
26092
|
try {
|
|
25928
26093
|
await this.ensureSemanticGrant(true);
|
|
25929
26094
|
return true;
|
|
25930
|
-
} catch {
|
|
26095
|
+
} catch (refreshError) {
|
|
26096
|
+
if (await this.resetStaleSession(refreshError)) {
|
|
26097
|
+
throw refreshError;
|
|
26098
|
+
}
|
|
25931
26099
|
return false;
|
|
25932
26100
|
}
|
|
25933
26101
|
}
|
|
25934
26102
|
async invokeSemanticOperation(operation, input, sessionInit = {}) {
|
|
25935
|
-
return this.
|
|
26103
|
+
return this.runOperationWithSessionRecovery(operation, async (timeout) => {
|
|
25936
26104
|
await this.ensureSession(sessionInit, timeout);
|
|
25937
26105
|
await this.ensureSemanticGrant(false, timeout);
|
|
25938
|
-
|
|
26106
|
+
const output = await this.requireClient().invoke(operation, input, {
|
|
25939
26107
|
signal: timeout.signal,
|
|
25940
26108
|
timeoutMs: timeout.remainingMs()
|
|
25941
26109
|
});
|
|
26110
|
+
this.noteSuccessfulLiveOperation(operation);
|
|
26111
|
+
return output;
|
|
25942
26112
|
});
|
|
25943
26113
|
}
|
|
25944
26114
|
async invokeAutomationOperation(operation, invoke, sessionInit = {}) {
|
|
25945
|
-
return this.
|
|
26115
|
+
return this.runOperationWithSessionRecovery(operation, async (timeout) => {
|
|
25946
26116
|
await this.ensureSession(sessionInit, timeout);
|
|
25947
|
-
|
|
26117
|
+
const output = await invoke(this.requireAutomation());
|
|
26118
|
+
this.noteSuccessfulLiveOperation(operation);
|
|
26119
|
+
return output;
|
|
25948
26120
|
});
|
|
25949
26121
|
}
|
|
26122
|
+
async invokeBootstrapInstrumentationOperation(operation, invoke) {
|
|
26123
|
+
let recovered = false;
|
|
26124
|
+
while (true) {
|
|
26125
|
+
try {
|
|
26126
|
+
await this.ensureSession();
|
|
26127
|
+
return await invoke(this.requireAutomation());
|
|
26128
|
+
} catch (error) {
|
|
26129
|
+
const stale = await this.resetStaleSession(error);
|
|
26130
|
+
if (!stale || recovered || !this.canRecoverWithFreshSession(operation)) {
|
|
26131
|
+
throw error;
|
|
26132
|
+
}
|
|
26133
|
+
recovered = true;
|
|
26134
|
+
}
|
|
26135
|
+
}
|
|
26136
|
+
}
|
|
26137
|
+
async runOperationWithSessionRecovery(operation, invoke) {
|
|
26138
|
+
return this.runOperationWithPolicy(operation, async (timeout) => {
|
|
26139
|
+
let recovered = false;
|
|
26140
|
+
while (true) {
|
|
26141
|
+
try {
|
|
26142
|
+
return await invoke(timeout);
|
|
26143
|
+
} catch (error) {
|
|
26144
|
+
const stale = await this.resetStaleSession(error);
|
|
26145
|
+
if (!stale || recovered || !this.canRecoverWithFreshSession(operation)) {
|
|
26146
|
+
throw error;
|
|
26147
|
+
}
|
|
26148
|
+
recovered = true;
|
|
26149
|
+
}
|
|
26150
|
+
}
|
|
26151
|
+
});
|
|
26152
|
+
}
|
|
26153
|
+
async resetStaleSession(error) {
|
|
26154
|
+
if (!isRecoverableCloudSessionError(error)) {
|
|
26155
|
+
return false;
|
|
26156
|
+
}
|
|
26157
|
+
await this.invalidateSession();
|
|
26158
|
+
return true;
|
|
26159
|
+
}
|
|
26160
|
+
canRecoverWithFreshSession(operation) {
|
|
26161
|
+
return !this.liveSessionStateEstablished && isBootstrapRecoveryOperation(operation);
|
|
26162
|
+
}
|
|
26163
|
+
noteSuccessfulLiveOperation(operation) {
|
|
26164
|
+
if (operation === "session.open" || operation === "page.list" || operation === "page.new" || operation === "page.activate" || operation === "page.close" || operation === "page.goto" || operation === "page.evaluate" || operation === "page.add-init-script" || operation === "page.snapshot" || operation === "dom.click" || operation === "dom.hover" || operation === "dom.input" || operation === "dom.scroll" || operation === "dom.extract" || operation === "network.query" || operation === "network.detail" || operation === "interaction.capture" || operation === "interaction.get" || operation === "interaction.diff" || operation === "interaction.replay" || operation === "scripts.capture" || operation === "artifact.read" || operation === "scripts.beautify" || operation === "scripts.deobfuscate" || operation === "scripts.sandbox" || operation === "captcha.solve" || operation === "session.cookies" || operation === "session.storage" || operation === "session.state" || operation === "session.fetch" || operation === "computer.execute") {
|
|
26165
|
+
this.liveSessionStateEstablished = true;
|
|
26166
|
+
}
|
|
26167
|
+
}
|
|
25950
26168
|
async runOperationWithPolicy(operation, invoke) {
|
|
25951
26169
|
return runWithPolicyTimeout(this.policy.timeout, { operation }, invoke);
|
|
25952
26170
|
}
|
|
@@ -25970,8 +26188,29 @@ function assertSupportedCloudBrowserMode(browser) {
|
|
|
25970
26188
|
}
|
|
25971
26189
|
}
|
|
25972
26190
|
function isMissingCloudSessionError(error) {
|
|
26191
|
+
if (error instanceof OpensteerCloudRequestError) {
|
|
26192
|
+
return error.statusCode === 404 && (error.code === void 0 || error.code === "CLOUD_SESSION_NOT_FOUND");
|
|
26193
|
+
}
|
|
25973
26194
|
return error instanceof Error && /\b404\b/.test(error.message);
|
|
25974
26195
|
}
|
|
26196
|
+
function isRecoverableCloudSessionError(error) {
|
|
26197
|
+
if (!(error instanceof OpensteerCloudRequestError)) {
|
|
26198
|
+
return false;
|
|
26199
|
+
}
|
|
26200
|
+
if (error.statusCode === 404) {
|
|
26201
|
+
return error.code === void 0 || error.code === "CLOUD_SESSION_NOT_FOUND";
|
|
26202
|
+
}
|
|
26203
|
+
return error.statusCode === 409 && error.code === "CLOUD_SESSION_STALE";
|
|
26204
|
+
}
|
|
26205
|
+
function isBootstrapRecoveryOperation(operation) {
|
|
26206
|
+
return operation === "session.open" || operation === "instrumentation.route" || operation === "instrumentation.intercept-script";
|
|
26207
|
+
}
|
|
26208
|
+
function isReusableCloudSessionState(session) {
|
|
26209
|
+
if (session.status === "closing" || session.status === "closed" || session.status === "failed") {
|
|
26210
|
+
return false;
|
|
26211
|
+
}
|
|
26212
|
+
return !(typeof session.expiresAt === "number" && session.expiresAt <= Date.now() + CLOUD_SESSION_REUSE_EXPIRY_SKEW_MS);
|
|
26213
|
+
}
|
|
25975
26214
|
function isLoopbackBaseUrl(baseUrl) {
|
|
25976
26215
|
let url;
|
|
25977
26216
|
try {
|
|
@@ -26133,6 +26372,25 @@ var SessionCookieJar = class {
|
|
|
26133
26372
|
return this.cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join("; ");
|
|
26134
26373
|
}
|
|
26135
26374
|
};
|
|
26375
|
+
function createSdkProtocolError(error, fallbackMessage) {
|
|
26376
|
+
const normalized = normalizeThrownOpensteerError(error, fallbackMessage);
|
|
26377
|
+
return new OpensteerProtocolError(normalized.code, normalized.message, {
|
|
26378
|
+
cause: error,
|
|
26379
|
+
retriable: normalized.retriable,
|
|
26380
|
+
...normalized.capability === void 0 ? {} : { capability: normalized.capability },
|
|
26381
|
+
...normalized.details === void 0 ? {} : { details: normalized.details }
|
|
26382
|
+
});
|
|
26383
|
+
}
|
|
26384
|
+
async function wrapSdkError(operation, fn) {
|
|
26385
|
+
try {
|
|
26386
|
+
return await fn();
|
|
26387
|
+
} catch (error) {
|
|
26388
|
+
if (isOpensteerProtocolError(error)) {
|
|
26389
|
+
throw error;
|
|
26390
|
+
}
|
|
26391
|
+
throw createSdkProtocolError(error, `${operation} failed`);
|
|
26392
|
+
}
|
|
26393
|
+
}
|
|
26136
26394
|
var Opensteer = class {
|
|
26137
26395
|
runtime;
|
|
26138
26396
|
browserManager;
|
|
@@ -26140,207 +26398,265 @@ var Opensteer = class {
|
|
|
26140
26398
|
dom;
|
|
26141
26399
|
network;
|
|
26142
26400
|
constructor(options = {}) {
|
|
26143
|
-
|
|
26144
|
-
|
|
26145
|
-
|
|
26146
|
-
|
|
26147
|
-
environment
|
|
26148
|
-
});
|
|
26149
|
-
if (runtimeConfig.provider.mode === "cloud") {
|
|
26150
|
-
this.browserManager = void 0;
|
|
26151
|
-
this.runtime = createOpensteerSemanticRuntime({
|
|
26152
|
-
...provider === void 0 ? {} : { provider },
|
|
26153
|
-
...engineName === void 0 ? {} : { engine: engineName },
|
|
26154
|
-
environment,
|
|
26155
|
-
runtimeOptions
|
|
26156
|
-
});
|
|
26157
|
-
this.browser = createUnsupportedBrowserController();
|
|
26158
|
-
} else {
|
|
26159
|
-
this.browserManager = new OpensteerBrowserManager({
|
|
26160
|
-
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
26161
|
-
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
26162
|
-
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
26163
|
-
...engineName === void 0 ? {} : { engineName },
|
|
26164
|
-
environment,
|
|
26165
|
-
...runtimeOptions.browser === void 0 ? {} : { browser: runtimeOptions.browser },
|
|
26166
|
-
...runtimeOptions.launch === void 0 ? {} : { launch: runtimeOptions.launch },
|
|
26167
|
-
...runtimeOptions.context === void 0 ? {} : { context: runtimeOptions.context }
|
|
26168
|
-
});
|
|
26169
|
-
this.runtime = createOpensteerSemanticRuntime({
|
|
26401
|
+
try {
|
|
26402
|
+
const environment = resolveOpensteerEnvironment(options.rootDir);
|
|
26403
|
+
const { provider, engineName, ...runtimeOptions } = options;
|
|
26404
|
+
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
26170
26405
|
...provider === void 0 ? {} : { provider },
|
|
26171
|
-
|
|
26172
|
-
environment,
|
|
26173
|
-
runtimeOptions: {
|
|
26174
|
-
...runtimeOptions,
|
|
26175
|
-
rootPath: this.browserManager.rootPath,
|
|
26176
|
-
cleanupRootOnClose: this.browserManager.cleanupRootOnDisconnect
|
|
26177
|
-
}
|
|
26406
|
+
environment
|
|
26178
26407
|
});
|
|
26179
|
-
|
|
26180
|
-
|
|
26181
|
-
|
|
26182
|
-
|
|
26183
|
-
|
|
26408
|
+
if (runtimeConfig.provider.mode === "cloud") {
|
|
26409
|
+
this.browserManager = void 0;
|
|
26410
|
+
this.runtime = createOpensteerSemanticRuntime({
|
|
26411
|
+
...provider === void 0 ? {} : { provider },
|
|
26412
|
+
...engineName === void 0 ? {} : { engine: engineName },
|
|
26413
|
+
environment,
|
|
26414
|
+
runtimeOptions
|
|
26415
|
+
});
|
|
26416
|
+
this.browser = createUnsupportedBrowserController();
|
|
26417
|
+
} else {
|
|
26418
|
+
this.browserManager = new OpensteerBrowserManager({
|
|
26419
|
+
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
26420
|
+
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
26421
|
+
...runtimeOptions.workspace === void 0 ? {} : { workspace: runtimeOptions.workspace },
|
|
26422
|
+
...engineName === void 0 ? {} : { engineName },
|
|
26423
|
+
environment,
|
|
26424
|
+
...runtimeOptions.browser === void 0 ? {} : { browser: runtimeOptions.browser },
|
|
26425
|
+
...runtimeOptions.launch === void 0 ? {} : { launch: runtimeOptions.launch },
|
|
26426
|
+
...runtimeOptions.context === void 0 ? {} : { context: runtimeOptions.context }
|
|
26427
|
+
});
|
|
26428
|
+
this.runtime = createOpensteerSemanticRuntime({
|
|
26429
|
+
...provider === void 0 ? {} : { provider },
|
|
26430
|
+
...engineName === void 0 ? {} : { engine: engineName },
|
|
26431
|
+
environment,
|
|
26432
|
+
runtimeOptions: {
|
|
26433
|
+
...runtimeOptions,
|
|
26434
|
+
rootPath: this.browserManager.rootPath,
|
|
26435
|
+
cleanupRootOnClose: this.browserManager.cleanupRootOnDisconnect
|
|
26436
|
+
}
|
|
26437
|
+
});
|
|
26438
|
+
this.browser = {
|
|
26439
|
+
status: () => wrapSdkError("browser.status", () => this.browserManager.status()),
|
|
26440
|
+
clone: (input) => wrapSdkError("browser.clone", () => this.browserManager.clonePersistentBrowser(input)),
|
|
26441
|
+
reset: () => wrapSdkError("browser.reset", () => this.browserManager.reset()),
|
|
26442
|
+
delete: () => wrapSdkError("browser.delete", () => this.browserManager.delete())
|
|
26443
|
+
};
|
|
26444
|
+
}
|
|
26445
|
+
this.dom = {
|
|
26446
|
+
click: (input) => this.click(input),
|
|
26447
|
+
hover: (input) => this.hover(input),
|
|
26448
|
+
input: (input) => this.input(input),
|
|
26449
|
+
scroll: (input) => this.scroll(input)
|
|
26184
26450
|
};
|
|
26451
|
+
this.network = {
|
|
26452
|
+
query: (input = {}) => wrapSdkError("network.query", () => this.runtime.queryNetwork(input)),
|
|
26453
|
+
detail: (recordId, options2) => wrapSdkError(
|
|
26454
|
+
"network.detail",
|
|
26455
|
+
() => this.runtime.getNetworkDetail({ recordId, ...options2 })
|
|
26456
|
+
)
|
|
26457
|
+
};
|
|
26458
|
+
} catch (error) {
|
|
26459
|
+
if (isOpensteerProtocolError(error)) {
|
|
26460
|
+
throw error;
|
|
26461
|
+
}
|
|
26462
|
+
throw createSdkProtocolError(error, "Failed to initialize Opensteer");
|
|
26185
26463
|
}
|
|
26186
|
-
this.dom = {
|
|
26187
|
-
click: (input) => this.click(input),
|
|
26188
|
-
hover: (input) => this.hover(input),
|
|
26189
|
-
input: (input) => this.input(input),
|
|
26190
|
-
scroll: (input) => this.scroll(input)
|
|
26191
|
-
};
|
|
26192
|
-
this.network = {
|
|
26193
|
-
query: (input = {}) => this.runtime.queryNetwork(input),
|
|
26194
|
-
detail: (recordId, options2) => this.runtime.getNetworkDetail({ recordId, ...options2 })
|
|
26195
|
-
};
|
|
26196
26464
|
}
|
|
26197
26465
|
async open(input = {}) {
|
|
26198
|
-
return
|
|
26466
|
+
return wrapSdkError(
|
|
26467
|
+
"session.open",
|
|
26468
|
+
() => this.runtime.open(typeof input === "string" ? { url: input } : input)
|
|
26469
|
+
);
|
|
26199
26470
|
}
|
|
26200
26471
|
async info() {
|
|
26201
|
-
return this.runtime.info();
|
|
26472
|
+
return wrapSdkError("session.info", () => this.runtime.info());
|
|
26202
26473
|
}
|
|
26203
26474
|
async listPages(input = {}) {
|
|
26204
|
-
return this.runtime.listPages(input);
|
|
26475
|
+
return wrapSdkError("page.list", () => this.runtime.listPages(input));
|
|
26205
26476
|
}
|
|
26206
26477
|
async newPage(input = {}) {
|
|
26207
|
-
return this.runtime.newPage(input);
|
|
26478
|
+
return wrapSdkError("page.new", () => this.runtime.newPage(input));
|
|
26208
26479
|
}
|
|
26209
26480
|
async activatePage(input) {
|
|
26210
|
-
return this.runtime.activatePage(input);
|
|
26481
|
+
return wrapSdkError("page.activate", () => this.runtime.activatePage(input));
|
|
26211
26482
|
}
|
|
26212
26483
|
async closePage(input = {}) {
|
|
26213
|
-
return this.runtime.closePage(input);
|
|
26484
|
+
return wrapSdkError("page.close", () => this.runtime.closePage(input));
|
|
26214
26485
|
}
|
|
26215
26486
|
async goto(url, options = {}) {
|
|
26216
|
-
return
|
|
26217
|
-
|
|
26218
|
-
|
|
26219
|
-
|
|
26487
|
+
return wrapSdkError(
|
|
26488
|
+
"page.goto",
|
|
26489
|
+
() => this.runtime.goto({
|
|
26490
|
+
url,
|
|
26491
|
+
...options
|
|
26492
|
+
})
|
|
26493
|
+
);
|
|
26220
26494
|
}
|
|
26221
26495
|
async evaluate(input) {
|
|
26222
|
-
|
|
26223
|
-
|
|
26224
|
-
|
|
26225
|
-
|
|
26496
|
+
return wrapSdkError("page.evaluate", async () => {
|
|
26497
|
+
const normalized = typeof input === "string" ? {
|
|
26498
|
+
script: input
|
|
26499
|
+
} : input;
|
|
26500
|
+
return (await this.runtime.evaluate(normalized)).value;
|
|
26501
|
+
});
|
|
26226
26502
|
}
|
|
26227
26503
|
async addInitScript(input) {
|
|
26228
|
-
return
|
|
26229
|
-
|
|
26230
|
-
|
|
26231
|
-
|
|
26504
|
+
return wrapSdkError(
|
|
26505
|
+
"page.addInitScript",
|
|
26506
|
+
() => this.runtime.addInitScript(
|
|
26507
|
+
typeof input === "string" ? {
|
|
26508
|
+
script: input
|
|
26509
|
+
} : input
|
|
26510
|
+
)
|
|
26232
26511
|
);
|
|
26233
26512
|
}
|
|
26234
26513
|
async click(input) {
|
|
26235
|
-
|
|
26236
|
-
|
|
26237
|
-
|
|
26238
|
-
|
|
26239
|
-
|
|
26240
|
-
|
|
26514
|
+
return wrapSdkError("dom.click", () => {
|
|
26515
|
+
const { button, clickCount, modifiers, ...target } = input;
|
|
26516
|
+
return this.runtime.click({
|
|
26517
|
+
...normalizeTargetOptions(target),
|
|
26518
|
+
...button === void 0 ? {} : { button },
|
|
26519
|
+
...clickCount === void 0 ? {} : { clickCount },
|
|
26520
|
+
...modifiers === void 0 ? {} : { modifiers }
|
|
26521
|
+
});
|
|
26241
26522
|
});
|
|
26242
26523
|
}
|
|
26243
26524
|
async hover(input) {
|
|
26244
|
-
return this.runtime.hover(normalizeTargetOptions(input));
|
|
26525
|
+
return wrapSdkError("dom.hover", () => this.runtime.hover(normalizeTargetOptions(input)));
|
|
26245
26526
|
}
|
|
26246
26527
|
async input(input) {
|
|
26247
|
-
return
|
|
26248
|
-
|
|
26249
|
-
|
|
26250
|
-
|
|
26251
|
-
|
|
26528
|
+
return wrapSdkError(
|
|
26529
|
+
"dom.input",
|
|
26530
|
+
() => this.runtime.input({
|
|
26531
|
+
...normalizeTargetOptions(input),
|
|
26532
|
+
text: input.text,
|
|
26533
|
+
...input.pressEnter === void 0 ? {} : { pressEnter: input.pressEnter }
|
|
26534
|
+
})
|
|
26535
|
+
);
|
|
26252
26536
|
}
|
|
26253
26537
|
async scroll(input) {
|
|
26254
|
-
return
|
|
26255
|
-
|
|
26256
|
-
|
|
26257
|
-
|
|
26258
|
-
|
|
26538
|
+
return wrapSdkError(
|
|
26539
|
+
"dom.scroll",
|
|
26540
|
+
() => this.runtime.scroll({
|
|
26541
|
+
...normalizeTargetOptions(input),
|
|
26542
|
+
direction: input.direction,
|
|
26543
|
+
amount: input.amount
|
|
26544
|
+
})
|
|
26545
|
+
);
|
|
26259
26546
|
}
|
|
26260
26547
|
async extract(input) {
|
|
26261
|
-
return (await this.runtime.extract(input)).data;
|
|
26548
|
+
return wrapSdkError("extract", async () => (await this.runtime.extract(input)).data);
|
|
26262
26549
|
}
|
|
26263
26550
|
async waitForPage(input = {}) {
|
|
26264
|
-
|
|
26265
|
-
|
|
26266
|
-
|
|
26267
|
-
|
|
26268
|
-
|
|
26269
|
-
|
|
26270
|
-
|
|
26271
|
-
|
|
26272
|
-
|
|
26273
|
-
|
|
26551
|
+
return wrapSdkError("page.waitForPage", async () => {
|
|
26552
|
+
const baseline = new Set((await this.runtime.listPages()).pages.map((page) => page.pageRef));
|
|
26553
|
+
const timeoutAt = Date.now() + (input.timeoutMs ?? 3e4);
|
|
26554
|
+
const pollIntervalMs = input.pollIntervalMs ?? 100;
|
|
26555
|
+
while (true) {
|
|
26556
|
+
const match = (await this.runtime.listPages()).pages.find((page) => {
|
|
26557
|
+
if (baseline.has(page.pageRef)) {
|
|
26558
|
+
return false;
|
|
26559
|
+
}
|
|
26560
|
+
if (input.openerPageRef !== void 0 && page.openerPageRef !== input.openerPageRef) {
|
|
26561
|
+
return false;
|
|
26562
|
+
}
|
|
26563
|
+
if (input.urlIncludes !== void 0 && !page.url.includes(input.urlIncludes)) {
|
|
26564
|
+
return false;
|
|
26565
|
+
}
|
|
26566
|
+
return true;
|
|
26567
|
+
});
|
|
26568
|
+
if (match !== void 0) {
|
|
26569
|
+
return match;
|
|
26274
26570
|
}
|
|
26275
|
-
if (
|
|
26276
|
-
|
|
26571
|
+
if (Date.now() >= timeoutAt) {
|
|
26572
|
+
throw new OpensteerProtocolError("timeout", "waitForPage timed out");
|
|
26277
26573
|
}
|
|
26278
|
-
|
|
26279
|
-
});
|
|
26280
|
-
if (match !== void 0) {
|
|
26281
|
-
return match;
|
|
26282
|
-
}
|
|
26283
|
-
if (Date.now() >= timeoutAt) {
|
|
26284
|
-
throw new Error("waitForPage timed out");
|
|
26574
|
+
await delay3(pollIntervalMs);
|
|
26285
26575
|
}
|
|
26286
|
-
|
|
26287
|
-
}
|
|
26576
|
+
});
|
|
26288
26577
|
}
|
|
26289
26578
|
async cookies(domain) {
|
|
26290
|
-
return
|
|
26291
|
-
|
|
26579
|
+
return wrapSdkError(
|
|
26580
|
+
"session.cookies",
|
|
26581
|
+
async () => new SessionCookieJar(await this.runtime.getCookies(domain === void 0 ? {} : { domain }))
|
|
26292
26582
|
);
|
|
26293
26583
|
}
|
|
26294
26584
|
async storage(domain, type = "local") {
|
|
26295
|
-
|
|
26296
|
-
|
|
26297
|
-
|
|
26298
|
-
|
|
26299
|
-
|
|
26300
|
-
|
|
26301
|
-
|
|
26585
|
+
return wrapSdkError("session.storage", async () => {
|
|
26586
|
+
const snapshot = await this.runtime.getStorageSnapshot(
|
|
26587
|
+
domain === void 0 ? {} : { domain }
|
|
26588
|
+
);
|
|
26589
|
+
const domainSnapshot = pickStorageDomainSnapshot(snapshot, domain);
|
|
26590
|
+
if (domainSnapshot === void 0) {
|
|
26591
|
+
return {};
|
|
26592
|
+
}
|
|
26593
|
+
const entries = type === "local" ? domainSnapshot.localStorage : domainSnapshot.sessionStorage;
|
|
26594
|
+
return Object.fromEntries(entries.map((entry) => [entry.key, entry.value]));
|
|
26595
|
+
});
|
|
26302
26596
|
}
|
|
26303
26597
|
async state(domain) {
|
|
26304
|
-
return
|
|
26598
|
+
return wrapSdkError(
|
|
26599
|
+
"session.state",
|
|
26600
|
+
() => this.runtime.getBrowserState(domain === void 0 ? {} : { domain })
|
|
26601
|
+
);
|
|
26305
26602
|
}
|
|
26306
26603
|
async fetch(url, options = {}) {
|
|
26307
|
-
|
|
26308
|
-
|
|
26309
|
-
|
|
26310
|
-
|
|
26311
|
-
|
|
26312
|
-
|
|
26604
|
+
return wrapSdkError("session.fetch", async () => {
|
|
26605
|
+
const input = buildFetchInput(url, options);
|
|
26606
|
+
const result = await this.runtime.fetch(input);
|
|
26607
|
+
if (result.response === void 0) {
|
|
26608
|
+
throw new OpensteerProtocolError(
|
|
26609
|
+
"operation-failed",
|
|
26610
|
+
result.note ?? `session.fetch did not produce a response for ${url}`
|
|
26611
|
+
);
|
|
26612
|
+
}
|
|
26613
|
+
return toResponse(result.response);
|
|
26614
|
+
});
|
|
26313
26615
|
}
|
|
26314
26616
|
async computerExecute(input) {
|
|
26315
|
-
return this.runtime.computerExecute(input);
|
|
26617
|
+
return wrapSdkError("session.computerExecute", () => this.runtime.computerExecute(input));
|
|
26316
26618
|
}
|
|
26317
26619
|
async route(input) {
|
|
26318
|
-
return
|
|
26620
|
+
return wrapSdkError(
|
|
26621
|
+
"session.route",
|
|
26622
|
+
() => this.requireOwnedInstrumentationRuntime("route").route(input)
|
|
26623
|
+
);
|
|
26319
26624
|
}
|
|
26320
26625
|
async interceptScript(input) {
|
|
26321
|
-
return
|
|
26626
|
+
return wrapSdkError(
|
|
26627
|
+
"session.interceptScript",
|
|
26628
|
+
() => this.requireOwnedInstrumentationRuntime("interceptScript").interceptScript(input)
|
|
26629
|
+
);
|
|
26322
26630
|
}
|
|
26323
26631
|
async close() {
|
|
26324
|
-
|
|
26325
|
-
|
|
26326
|
-
|
|
26327
|
-
|
|
26328
|
-
|
|
26329
|
-
|
|
26632
|
+
return wrapSdkError("session.close", async () => {
|
|
26633
|
+
if (this.browserManager === void 0 || this.browserManager.mode === "temporary") {
|
|
26634
|
+
return this.runtime.close();
|
|
26635
|
+
}
|
|
26636
|
+
const output = await this.runtime.close();
|
|
26637
|
+
await this.browserManager.close();
|
|
26638
|
+
return output;
|
|
26639
|
+
});
|
|
26330
26640
|
}
|
|
26331
26641
|
async disconnect() {
|
|
26332
|
-
|
|
26642
|
+
return wrapSdkError("session.disconnect", () => this.runtime.disconnect());
|
|
26333
26643
|
}
|
|
26334
26644
|
requireOwnedInstrumentationRuntime(method) {
|
|
26335
26645
|
if (typeof this.runtime.route === "function" && typeof this.runtime.interceptScript === "function") {
|
|
26336
26646
|
return this.runtime;
|
|
26337
26647
|
}
|
|
26338
|
-
throw new
|
|
26648
|
+
throw new OpensteerProtocolError(
|
|
26649
|
+
"unsupported-operation",
|
|
26650
|
+
`${method}() is not available for this session runtime.`
|
|
26651
|
+
);
|
|
26339
26652
|
}
|
|
26340
26653
|
};
|
|
26341
26654
|
function createUnsupportedBrowserController() {
|
|
26342
26655
|
const fail = async () => {
|
|
26343
|
-
throw new
|
|
26656
|
+
throw new OpensteerProtocolError(
|
|
26657
|
+
"unsupported-operation",
|
|
26658
|
+
"browser.* helpers are only available in local mode."
|
|
26659
|
+
);
|
|
26344
26660
|
};
|
|
26345
26661
|
return {
|
|
26346
26662
|
status: fail,
|
|
@@ -26353,7 +26669,10 @@ function normalizeTargetOptions(input) {
|
|
|
26353
26669
|
const hasElement = input.element !== void 0;
|
|
26354
26670
|
const hasSelector = input.selector !== void 0;
|
|
26355
26671
|
if (hasElement && hasSelector) {
|
|
26356
|
-
throw new
|
|
26672
|
+
throw new OpensteerProtocolError(
|
|
26673
|
+
"invalid-argument",
|
|
26674
|
+
"Specify exactly one of element, selector, or persist."
|
|
26675
|
+
);
|
|
26357
26676
|
}
|
|
26358
26677
|
if (hasElement) {
|
|
26359
26678
|
return {
|
|
@@ -26376,7 +26695,10 @@ function normalizeTargetOptions(input) {
|
|
|
26376
26695
|
};
|
|
26377
26696
|
}
|
|
26378
26697
|
if (input.persist === void 0) {
|
|
26379
|
-
throw new
|
|
26698
|
+
throw new OpensteerProtocolError(
|
|
26699
|
+
"invalid-argument",
|
|
26700
|
+
"Specify exactly one of element, selector, or persist."
|
|
26701
|
+
);
|
|
26380
26702
|
}
|
|
26381
26703
|
return {
|
|
26382
26704
|
target: {
|
|
@@ -26448,6 +26770,7 @@ exports.Opensteer = Opensteer;
|
|
|
26448
26770
|
exports.OpensteerAttachAmbiguousError = OpensteerAttachAmbiguousError;
|
|
26449
26771
|
exports.OpensteerBrowserManager = OpensteerBrowserManager;
|
|
26450
26772
|
exports.OpensteerCloudClient = OpensteerCloudClient;
|
|
26773
|
+
exports.OpensteerProtocolError = OpensteerProtocolError;
|
|
26451
26774
|
exports.STABLE_PRIMARY_ATTR_KEYS = STABLE_PRIMARY_ATTR_KEYS;
|
|
26452
26775
|
exports.assertProviderSupportsEngine = assertProviderSupportsEngine;
|
|
26453
26776
|
exports.buildArrayFieldPathCandidates = buildArrayFieldPathCandidates;
|
|
@@ -26477,6 +26800,7 @@ exports.discoverLocalCdpBrowsers = discoverLocalCdpBrowsers;
|
|
|
26477
26800
|
exports.hashDomDescriptorPersist = hashDomDescriptorPersist;
|
|
26478
26801
|
exports.inspectCdpEndpoint = inspectCdpEndpoint;
|
|
26479
26802
|
exports.isCurrentUrlField = isCurrentUrlField;
|
|
26803
|
+
exports.isOpensteerProtocolError = isOpensteerProtocolError;
|
|
26480
26804
|
exports.isValidCssAttributeKey = isValidCssAttributeKey;
|
|
26481
26805
|
exports.listLocalChromeProfiles = listLocalChromeProfiles;
|
|
26482
26806
|
exports.manifestToExternalBinaryLocation = manifestToExternalBinaryLocation;
|
|
@@ -26485,6 +26809,7 @@ exports.normalizeObservabilityConfig = normalizeObservabilityConfig;
|
|
|
26485
26809
|
exports.normalizeOpensteerEngineName = normalizeOpensteerEngineName;
|
|
26486
26810
|
exports.normalizeOpensteerProviderMode = normalizeOpensteerProviderMode;
|
|
26487
26811
|
exports.normalizeWorkspaceId = normalizeWorkspaceId;
|
|
26812
|
+
exports.opensteerErrorCodes = opensteerErrorCodes;
|
|
26488
26813
|
exports.parseDomDescriptorRecord = parseDomDescriptorRecord;
|
|
26489
26814
|
exports.parseExtractionDescriptorRecord = parseExtractionDescriptorRecord;
|
|
26490
26815
|
exports.readPersistedCloudSessionRecord = readPersistedCloudSessionRecord;
|