@enricai/barnacle 1.6.12 → 1.6.14
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/README.md +113 -9
- package/dist/api/schemas/submissions.d.ts +14 -0
- package/dist/api/schemas/submissions.d.ts.map +1 -1
- package/dist/api/schemas/submissions.js +1 -0
- package/dist/api/schemas/submissions.js.map +1 -1
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/lib/bedrock.d.ts +8 -5
- package/dist/lib/bedrock.d.ts.map +1 -1
- package/dist/lib/bedrock.js +8 -5
- package/dist/lib/bedrock.js.map +1 -1
- package/dist/lib/http.d.ts +4 -3
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +25 -3
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/telemetry/beacon-capture.d.ts +45 -2
- package/dist/lib/telemetry/beacon-capture.d.ts.map +1 -1
- package/dist/lib/telemetry/beacon-capture.js +36 -0
- package/dist/lib/telemetry/beacon-capture.js.map +1 -1
- package/dist/lib/telemetry/reconciliation-record.d.ts +41 -1
- package/dist/lib/telemetry/reconciliation-record.d.ts.map +1 -1
- package/dist/lib/telemetry/reconciliation-record.js +29 -2
- package/dist/lib/telemetry/reconciliation-record.js.map +1 -1
- package/dist/lib/telemetry/reconciliation-source.d.ts +7 -1
- package/dist/lib/telemetry/reconciliation-source.d.ts.map +1 -1
- package/dist/lib/telemetry/reconciliation-source.js +21 -5
- package/dist/lib/telemetry/reconciliation-source.js.map +1 -1
- package/dist/lib/telemetry/run-telemetry.d.ts +67 -0
- package/dist/lib/telemetry/run-telemetry.d.ts.map +1 -0
- package/dist/lib/telemetry/run-telemetry.js +55 -0
- package/dist/lib/telemetry/run-telemetry.js.map +1 -0
- package/dist/lib/telemetry/submission-capture.d.ts +11 -4
- package/dist/lib/telemetry/submission-capture.d.ts.map +1 -1
- package/dist/lib/telemetry/submission-capture.js +1 -0
- package/dist/lib/telemetry/submission-capture.js.map +1 -1
- package/dist/lib/telemetry/submission-reader.d.ts +11 -3
- package/dist/lib/telemetry/submission-reader.d.ts.map +1 -1
- package/dist/lib/telemetry/submission-reader.js +32 -8
- package/dist/lib/telemetry/submission-reader.js.map +1 -1
- package/dist/lib/tracking-click.d.ts.map +1 -1
- package/dist/lib/tracking-click.js +19 -0
- package/dist/lib/tracking-click.js.map +1 -1
- package/dist/plugins/config-plugin.js +3 -3
- package/dist/plugins/loader.d.ts +20 -0
- package/dist/plugins/loader.d.ts.map +1 -1
- package/dist/plugins/loader.js +94 -17
- package/dist/plugins/loader.js.map +1 -1
- package/dist/scraper/deep-locator-actuate.d.ts +94 -0
- package/dist/scraper/deep-locator-actuate.d.ts.map +1 -0
- package/dist/scraper/deep-locator-actuate.js +216 -0
- package/dist/scraper/deep-locator-actuate.js.map +1 -0
- package/dist/scraper/deep-locator-candidates.d.ts +105 -18
- package/dist/scraper/deep-locator-candidates.d.ts.map +1 -1
- package/dist/scraper/deep-locator-candidates.js +238 -46
- package/dist/scraper/deep-locator-candidates.js.map +1 -1
- package/dist/scraper/deep-locator-click.d.ts +71 -0
- package/dist/scraper/deep-locator-click.d.ts.map +1 -0
- package/dist/scraper/deep-locator-click.js +71 -0
- package/dist/scraper/deep-locator-click.js.map +1 -0
- package/dist/scraper/deep-locator-fake.d.ts +344 -14
- package/dist/scraper/deep-locator-fake.d.ts.map +1 -1
- package/dist/scraper/deep-locator-fake.js +509 -7
- package/dist/scraper/deep-locator-fake.js.map +1 -1
- package/dist/scraper/deep-locator-scan.d.ts +220 -0
- package/dist/scraper/deep-locator-scan.d.ts.map +1 -0
- package/dist/scraper/deep-locator-scan.js +386 -0
- package/dist/scraper/deep-locator-scan.js.map +1 -0
- package/dist/scraper/fake-timer-advance.d.ts +47 -0
- package/dist/scraper/fake-timer-advance.d.ts.map +1 -0
- package/dist/scraper/fake-timer-advance.js +44 -0
- package/dist/scraper/fake-timer-advance.js.map +1 -0
- package/dist/scraper/flow-runner.d.ts +80 -9
- package/dist/scraper/flow-runner.d.ts.map +1 -1
- package/dist/scraper/flow-runner.js +417 -63
- package/dist/scraper/flow-runner.js.map +1 -1
- package/dist/scraper/frame-target.d.ts +28 -0
- package/dist/scraper/frame-target.d.ts.map +1 -1
- package/dist/scraper/frame-target.js +30 -0
- package/dist/scraper/frame-target.js.map +1 -1
- package/dist/scraper/session-browserbase.d.ts +13 -0
- package/dist/scraper/session-browserbase.d.ts.map +1 -1
- package/dist/scraper/session-browserbase.js +29 -0
- package/dist/scraper/session-browserbase.js.map +1 -1
- package/dist/scraper/session-ip.d.ts +69 -0
- package/dist/scraper/session-ip.d.ts.map +1 -0
- package/dist/scraper/session-ip.js +88 -0
- package/dist/scraper/session-ip.js.map +1 -0
- package/dist/scraper/session-shared.d.ts +9 -0
- package/dist/scraper/session-shared.d.ts.map +1 -1
- package/dist/scraper/session-shared.js.map +1 -1
- package/dist/scraper/submit-control.d.ts +14 -2
- package/dist/scraper/submit-control.d.ts.map +1 -1
- package/dist/scraper/submit-control.js +33 -2
- package/dist/scraper/submit-control.js.map +1 -1
- package/dist/scripts/recon-browser.d.ts +1 -1
- package/dist/scripts/recon-browser.d.ts.map +1 -1
- package/dist/scripts/recon-browser.js +48 -16
- package/dist/scripts/recon-browser.js.map +1 -1
- package/dist/scripts/recon-generate.js +3 -3
- package/dist/scripts/recon-generate.js.map +1 -1
- package/dist/site-plugin.d.ts +20 -0
- package/dist/site-plugin.d.ts.map +1 -1
- package/dist/testing/integration-runner.d.ts.map +1 -1
- package/dist/testing/integration-runner.js +6 -7
- package/dist/testing/integration-runner.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fill/select actuation seam over `deepLocator`, mirroring
|
|
4
|
+
* `clickDeepLocatorCandidate`'s contract (`deep-locator-candidates.ts`) for
|
|
5
|
+
* the two other primitives a cross-origin OOPIF form's text/select steps
|
|
6
|
+
* need. Stagehand `act`/`observe` are measured blind inside that OOPIF, and
|
|
7
|
+
* `verifyDomEffect` (`flow-runner.ts`) can't locate a `deeplocator=` selector
|
|
8
|
+
* to confirm the write, so both actuators here read the written value back
|
|
9
|
+
* through the same delegate before reporting success — the caller gets a
|
|
10
|
+
* trustworthy boolean instead of a downstream verifier that can never fire.
|
|
11
|
+
*
|
|
12
|
+
* Both actuators prefer one batched `frameTarget.evaluate(buildFillFrameCandidateExpr(...) |
|
|
13
|
+
* buildSelectFrameCandidateExpr(...))` round-trip (`deep-locator-scan.ts`) over
|
|
14
|
+
* the legacy `deepLocator(hop).nth(index).fill()`/`.selectOption()` +
|
|
15
|
+
* `.inputValue()` pair, which pays Stagehand's `index + 1` serial
|
|
16
|
+
* `resolveAtIndex` round-trips per call — the same cost
|
|
17
|
+
* `clickDeepLocatorCandidate` already batches away. The legacy fallback's
|
|
18
|
+
* watchdog budget scales with `index` using
|
|
19
|
+
* {@link DEEP_LOCATOR_CLICK_INDEX_ROUND_TRIP_MS} — the same per-round-trip
|
|
20
|
+
* constant `clickDeepLocatorCandidate` uses — so a legitimately-reachable
|
|
21
|
+
* candidate deep in a dense OOPIF form isn't killed by a budget sized for one
|
|
22
|
+
* round-trip.
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.fillDeepLocatorCandidate = fillDeepLocatorCandidate;
|
|
26
|
+
exports.selectDeepLocatorCandidateOption = selectDeepLocatorCandidateOption;
|
|
27
|
+
const errors_1 = require("../lib/errors");
|
|
28
|
+
const logging_1 = require("../lib/logging");
|
|
29
|
+
const deep_locator_scan_1 = require("../scraper/deep-locator-scan");
|
|
30
|
+
const frame_target_1 = require("../scraper/frame-target");
|
|
31
|
+
const watchdog_1 = require("../scraper/watchdog");
|
|
32
|
+
const logger = (0, logging_1.getLogger)({ name: "scraper/deep-locator-actuate" });
|
|
33
|
+
/**
|
|
34
|
+
* Per-CDP-call watchdog default: bounds a single `fill()`/`selectOption()`/
|
|
35
|
+
* `inputValue()` round-trip. Owned locally (not imported from
|
|
36
|
+
* `deep-locator-candidates.ts` or `flow-runner.ts`) so this module stays a
|
|
37
|
+
* self-contained leaf, matching how `deep-locator-candidates.ts` already
|
|
38
|
+
* avoids the `flow-runner.ts` import cycle by owning its own timeout
|
|
39
|
+
* constant.
|
|
40
|
+
*/
|
|
41
|
+
const DEFAULT_DEEP_LOCATOR_CALL_TIMEOUT_MS = 10_000;
|
|
42
|
+
/**
|
|
43
|
+
* Runs `write`, then `readBack`, and reports whether the read-back matches
|
|
44
|
+
* `expected` — the shared write/verify shape `fillDeepLocatorCandidate` and
|
|
45
|
+
* `selectDeepLocatorCandidateOption` both need, differing only in which
|
|
46
|
+
* delegate method performs the write. A {@link WatchdogTimeoutError} from
|
|
47
|
+
* either await (a wedged CDP round-trip) propagates so the caller can tell a
|
|
48
|
+
* genuine hang apart from an ordinary failed write — everything else (the
|
|
49
|
+
* delegate rejecting, or a read-back that disagrees with `expected`) resolves
|
|
50
|
+
* to `false` instead of throwing.
|
|
51
|
+
*/
|
|
52
|
+
async function writeAndVerify(write, readBack, expected) {
|
|
53
|
+
try {
|
|
54
|
+
await write();
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (error instanceof watchdog_1.WatchdogTimeoutError)
|
|
58
|
+
throw error;
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
return (await readBack()) === expected;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error instanceof watchdog_1.WatchdogTimeoutError)
|
|
66
|
+
throw error;
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolves the `FrameTarget` a batched actuation evaluate should run
|
|
72
|
+
* against: `timeoutOptions.frameTarget` when the caller already resolved
|
|
73
|
+
* one, else a single non-polling `probeAttachedFrameTarget(page,
|
|
74
|
+
* frameSelector)` pass (`frame-target.ts`) so existing call sites — which
|
|
75
|
+
* pass only a `frameSelector` string — still get the batched fast path
|
|
76
|
+
* without themselves changing. Unlike a bare `resolveFrameTarget(page,
|
|
77
|
+
* frameSelector, { timeoutMs: 0 })` pass, the probe carries a real per-probe
|
|
78
|
+
* budget, so it can land against an already-attached frame under genuine CDP
|
|
79
|
+
* latency instead of always losing a zero-budget race. Returns `null` (never
|
|
80
|
+
* throws) when `frameSelector` is unset, the probe rejects (e.g. a fake
|
|
81
|
+
* `Page` in a legacy-path test lacking `evaluate`/`frames`), or nothing
|
|
82
|
+
* attaches within the probe's budget — each of those means "no frame seam
|
|
83
|
+
* available", and the caller degrades to the legacy delegate path. Mirrors
|
|
84
|
+
* `deep-locator-candidates.ts`'s `resolveScanFrameTarget` exactly; duplicated
|
|
85
|
+
* (not imported) so this module stays a leaf that never depends on
|
|
86
|
+
* `deep-locator-candidates.ts`.
|
|
87
|
+
*/
|
|
88
|
+
async function resolveActuateFrameTarget(page, frameSelector, timeoutOptions) {
|
|
89
|
+
if (timeoutOptions.frameTarget)
|
|
90
|
+
return timeoutOptions.frameTarget;
|
|
91
|
+
if (!frameSelector)
|
|
92
|
+
return null;
|
|
93
|
+
try {
|
|
94
|
+
return await (0, frame_target_1.probeAttachedFrameTarget)(page, frameSelector);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/** Narrows a batched fill/select evaluate result to {@link FrameCandidateWriteResult}'s shape, guarding against a non-conforming payload (the same degrade-to-legacy contract `deep-locator-candidates.ts`'s `isFrameCandidateScanResult`/`isFrameCandidateClickResult` enforce). */
|
|
101
|
+
function isFrameCandidateWriteResult(entry) {
|
|
102
|
+
if (typeof entry !== "object" || entry === null)
|
|
103
|
+
return false;
|
|
104
|
+
const result = entry;
|
|
105
|
+
if (typeof result.written !== "boolean")
|
|
106
|
+
return false;
|
|
107
|
+
if (result.written)
|
|
108
|
+
return typeof result.readBack === "string";
|
|
109
|
+
return result.reason === "out-of-range" || result.reason === "not-actionable";
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Batched fill/select fast path: one `frameTarget.evaluate(expression)`
|
|
113
|
+
* round-trip replaces the legacy `nth(index).fill()`/`.selectOption()` +
|
|
114
|
+
* `.inputValue()` pair. Returns `null` (never throws) when no frame seam is
|
|
115
|
+
* available, the evaluate call rejects, or the resolved payload doesn't
|
|
116
|
+
* conform to {@link FrameCandidateWriteResult} — every one of those degrades
|
|
117
|
+
* the caller to the legacy delegate path instead of losing the write,
|
|
118
|
+
* mirroring `clickCandidateBatched`'s degrade contract
|
|
119
|
+
* (`deep-locator-candidates.ts`).
|
|
120
|
+
*/
|
|
121
|
+
async function actuateCandidateBatched(page, frameSelector, hopSelector, index, timeoutOptions, expression, actionLabel) {
|
|
122
|
+
const frameTarget = await resolveActuateFrameTarget(page, frameSelector, timeoutOptions);
|
|
123
|
+
if (!frameTarget)
|
|
124
|
+
return null;
|
|
125
|
+
let result;
|
|
126
|
+
try {
|
|
127
|
+
result = await frameTarget.evaluate(expression);
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
logger.warn(`deepLocator batched ${actionLabel} for ${hopSelector} nth=${index} failed, degrading to delegate ${actionLabel}: ${(0, errors_1.toErrorMessage)(err)}`);
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
if (!isFrameCandidateWriteResult(result)) {
|
|
134
|
+
logger.warn(`deepLocator batched ${actionLabel} for ${hopSelector} nth=${index} returned a non-conforming payload, degrading to delegate ${actionLabel}`);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Fills the candidate at `index` inside the frame scoped by `frameSelector`
|
|
141
|
+
* with `value`, re-deriving the same hop selector
|
|
142
|
+
* `resolveDeepLocatorCandidates` used (`deep-locator-candidates.ts`) rather
|
|
143
|
+
* than trusting a candidate's display `selector` (`deeplocator=`-prefixed,
|
|
144
|
+
* deliberately not an xpath).
|
|
145
|
+
*
|
|
146
|
+
* Prefers the one-round-trip {@link actuateCandidateBatched} fast path when a
|
|
147
|
+
* frame seam is available: a `written: true` result whose inline `readBack`
|
|
148
|
+
* already matches `value` resolves `true` immediately (no second round-trip
|
|
149
|
+
* needed); a `reason: "not-actionable"` result (the matched element has no
|
|
150
|
+
* layout box) resolves `false` immediately — no delegate write against that
|
|
151
|
+
* same node could succeed either. Every other batched outcome — no frame
|
|
152
|
+
* seam, a rejecting or non-conforming evaluate, `reason: "out-of-range"`, or
|
|
153
|
+
* a `written: true` result whose inline `readBack` disagrees with `value`
|
|
154
|
+
* (e.g. a controlled component's `onChange` reverted the write on a tick the
|
|
155
|
+
* single synchronous evaluate call couldn't observe) — degrades to the
|
|
156
|
+
* legacy `deepLocator(hop).nth(index).fill()` + `.inputValue()` pair rather
|
|
157
|
+
* than trusting the batched call's verdict outright: returns `true` only
|
|
158
|
+
* when that separate read-back equals `value`, and `false` — never a throw —
|
|
159
|
+
* when the delegate rejects the fill/read-back or the read-back disagrees.
|
|
160
|
+
* The legacy path's watchdog budget scales with `index`
|
|
161
|
+
* ({@link DEEP_LOCATOR_CLICK_INDEX_ROUND_TRIP_MS}, the same per-round-trip
|
|
162
|
+
* cost `clickDeepLocatorCandidate`'s legacy fallback charges), so a candidate
|
|
163
|
+
* deep in a dense OOPIF form isn't killed by a budget sized for a single
|
|
164
|
+
* round-trip. A wedged `fill()`/`inputValue()` call that still exceeds that
|
|
165
|
+
* scaled budget rejects with a `WatchdogTimeoutError` instead of hanging the
|
|
166
|
+
* caller, the same "rejects on a genuine hang" contract
|
|
167
|
+
* `clickDeepLocatorCandidate` uses.
|
|
168
|
+
*/
|
|
169
|
+
async function fillDeepLocatorCandidate(page, frameSelector, innerSelector, index, value, timeoutOptions = {}) {
|
|
170
|
+
const callTimeoutMs = timeoutOptions.callTimeoutMs ?? DEFAULT_DEEP_LOCATOR_CALL_TIMEOUT_MS;
|
|
171
|
+
const hopSelector = (0, frame_target_1.buildHopSelector)(frameSelector, innerSelector);
|
|
172
|
+
const batchedResult = await actuateCandidateBatched(page, frameSelector, hopSelector, index, timeoutOptions, (0, deep_locator_scan_1.buildFillFrameCandidateExpr)(innerSelector, index, value), "fill");
|
|
173
|
+
if (batchedResult?.written && batchedResult.readBack === value)
|
|
174
|
+
return true;
|
|
175
|
+
if (batchedResult?.reason === "not-actionable")
|
|
176
|
+
return false;
|
|
177
|
+
const scaledCallTimeoutMs = callTimeoutMs + index * deep_locator_scan_1.DEEP_LOCATOR_CLICK_INDEX_ROUND_TRIP_MS;
|
|
178
|
+
return writeAndVerify(() => (0, watchdog_1.withWatchdog)(() => page.deepLocator(hopSelector).nth(index).fill(value), {
|
|
179
|
+
timeoutMs: scaledCallTimeoutMs,
|
|
180
|
+
label: `deepLocator fill() for ${hopSelector} nth=${index}`,
|
|
181
|
+
}), () => (0, watchdog_1.withWatchdog)(() => page.deepLocator(hopSelector).nth(index).inputValue(), {
|
|
182
|
+
timeoutMs: scaledCallTimeoutMs,
|
|
183
|
+
label: `deepLocator inputValue() for ${hopSelector} nth=${index}`,
|
|
184
|
+
}), value);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Selects `value` on the `<select>`-shaped candidate at `index` inside the
|
|
188
|
+
* frame scoped by `frameSelector`, under the same re-derived-hop,
|
|
189
|
+
* batched-first, index-scaled-watchdog-guarded contract as
|
|
190
|
+
* {@link fillDeepLocatorCandidate} — `selectOption()` is the legacy write,
|
|
191
|
+
* and `inputValue()` (which reads a `<select>`'s selected value the same as
|
|
192
|
+
* any other form control) is the legacy confirmation. Differs from
|
|
193
|
+
* `fillDeepLocatorCandidate` in one respect: a batched `written: true` result
|
|
194
|
+
* resolves `true` on its own, without comparing `readBack` to `value` —
|
|
195
|
+
* {@link buildSelectFrameCandidateExpr} matches an option by value OR trimmed
|
|
196
|
+
* label, so `readBack` (the MATCHED option's value) can legitimately differ
|
|
197
|
+
* from a caller-supplied label string even on a successful write.
|
|
198
|
+
*/
|
|
199
|
+
async function selectDeepLocatorCandidateOption(page, frameSelector, innerSelector, index, value, timeoutOptions = {}) {
|
|
200
|
+
const callTimeoutMs = timeoutOptions.callTimeoutMs ?? DEFAULT_DEEP_LOCATOR_CALL_TIMEOUT_MS;
|
|
201
|
+
const hopSelector = (0, frame_target_1.buildHopSelector)(frameSelector, innerSelector);
|
|
202
|
+
const batchedResult = await actuateCandidateBatched(page, frameSelector, hopSelector, index, timeoutOptions, (0, deep_locator_scan_1.buildSelectFrameCandidateExpr)(innerSelector, index, value), "select");
|
|
203
|
+
if (batchedResult?.written)
|
|
204
|
+
return true;
|
|
205
|
+
if (batchedResult?.reason === "not-actionable")
|
|
206
|
+
return false;
|
|
207
|
+
const scaledCallTimeoutMs = callTimeoutMs + index * deep_locator_scan_1.DEEP_LOCATOR_CLICK_INDEX_ROUND_TRIP_MS;
|
|
208
|
+
return writeAndVerify(() => (0, watchdog_1.withWatchdog)(() => page.deepLocator(hopSelector).nth(index).selectOption(value), {
|
|
209
|
+
timeoutMs: scaledCallTimeoutMs,
|
|
210
|
+
label: `deepLocator selectOption() for ${hopSelector} nth=${index}`,
|
|
211
|
+
}), () => (0, watchdog_1.withWatchdog)(() => page.deepLocator(hopSelector).nth(index).inputValue(), {
|
|
212
|
+
timeoutMs: scaledCallTimeoutMs,
|
|
213
|
+
label: `deepLocator inputValue() for ${hopSelector} nth=${index}`,
|
|
214
|
+
}), value);
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=deep-locator-actuate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-locator-actuate.js","sourceRoot":"","sources":["../../src/scraper/deep-locator-actuate.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,12 +9,31 @@
|
|
|
9
9
|
* when the step is scoped to a child frame.
|
|
10
10
|
*/
|
|
11
11
|
import type { Page } from "@browserbasehq/stagehand";
|
|
12
|
+
import { type FrameTarget } from "../scraper/frame-target";
|
|
12
13
|
/** Overrides for the watchdog timeouts this module applies to every `deepLocator()` await; tests pass small values so cases don't burn wall-clock. */
|
|
13
14
|
export interface DeepLocatorTimeoutOptions {
|
|
14
15
|
/** Per-call watchdog timeout for `count()`/`textContent()`/`click()`. Defaults to {@link DEFAULT_DEEP_LOCATOR_CALL_TIMEOUT_MS}. */
|
|
15
16
|
callTimeoutMs?: number;
|
|
16
|
-
/** Total budget for {@link resolveDeepLocatorCandidates}'s enumeration loop. Defaults to {@link DEFAULT_DEEP_LOCATOR_ENUMERATION_BUDGET_MS}. */
|
|
17
|
+
/** Total budget for {@link resolveDeepLocatorCandidates}'s legacy enumeration loop. Defaults to {@link DEFAULT_DEEP_LOCATOR_ENUMERATION_BUDGET_MS}. */
|
|
17
18
|
enumerationBudgetMs?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Pre-resolved `FrameTarget` to scan via one batched
|
|
21
|
+
* `evaluate(buildScanFrameCandidatesExpr(innerSelector))` round-trip
|
|
22
|
+
* instead of the legacy `count()` + per-candidate `textContent()` loop.
|
|
23
|
+
* When omitted, a single non-polling `probeAttachedFrameTarget(page,
|
|
24
|
+
* frameSelector)` pass (`frame-target.ts`) is attempted internally so
|
|
25
|
+
* existing call sites get the batched fast path for free. Unlike a bare
|
|
26
|
+
* `resolveFrameTarget(page, frameSelector, { timeoutMs: 0 })` pass — which
|
|
27
|
+
* always loses the race against genuine CDP latency — this probe carries a
|
|
28
|
+
* real per-probe budget (`config.scraper.framePresenceProbeFloorMs`), so it
|
|
29
|
+
* can actually land against an already-attached frame under live latency.
|
|
30
|
+
* If the probe doesn't land a resolved child frame (not yet attached, or
|
|
31
|
+
* `frameSelector` is null/undefined), the legacy loop runs unchanged. A
|
|
32
|
+
* caller that already resolved a `FrameTarget` (e.g. `flow-runner.ts`'s
|
|
33
|
+
* per-step resolution) should pass it here to skip the redundant internal
|
|
34
|
+
* probe.
|
|
35
|
+
*/
|
|
36
|
+
frameTarget?: FrameTarget;
|
|
18
37
|
}
|
|
19
38
|
/**
|
|
20
39
|
* One candidate element `page.deepLocator()` resolved inside a scoped frame.
|
|
@@ -33,9 +52,48 @@ export interface DeepLocatorCandidate {
|
|
|
33
52
|
index: number;
|
|
34
53
|
/** `deeplocator=`-prefixed selector identifying this candidate for downstream `resolvedAction` synthesis; deliberately not `xpath=` (see {@link DeepLocatorCandidate} docs). */
|
|
35
54
|
selector: string;
|
|
36
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* Accessible text for this candidate: the derived accessible name (see
|
|
57
|
+
* {@link buildScanFrameCandidatesExpr}) on the batched-scan fast path,
|
|
58
|
+
* or the delegate's raw `textContent()` on the legacy per-candidate
|
|
59
|
+
* enumeration fallback.
|
|
60
|
+
*/
|
|
37
61
|
accessibleText: string;
|
|
38
62
|
}
|
|
63
|
+
/** One quoted phrase from an instruction, tagged with whether a negation marker (`NEGATION_MARKERS`) governs it. See {@link extractTaggedPhrases}. */
|
|
64
|
+
export interface TaggedPhrase {
|
|
65
|
+
text: string;
|
|
66
|
+
negated: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Extracts every single-quoted phrase from `instruction`, tagging each as
|
|
70
|
+
* negated when a negation marker (`NEGATION_MARKERS`) precedes it within the
|
|
71
|
+
* same sentence — flow instructions keep each "Do NOT click 'X', 'Y', ..."
|
|
72
|
+
* clause as one sentence listing every negated phrase, so a sentence
|
|
73
|
+
* boundary (`.`/`;`) between the marker and the phrase ends the negation's
|
|
74
|
+
* reach. Mirrors the quoted-phrase extraction convention in
|
|
75
|
+
* `parseSelectStep`/`parseRadioStep` (`flow-runner.ts`) — same
|
|
76
|
+
* `/'([^']+)'/g` shape — but here we need ALL quoted phrases plus their
|
|
77
|
+
* polarity, not just one option/label pair. Exported so `flow-runner.ts` can
|
|
78
|
+
* re-derive the exact same ranking {@link scoreCandidate} used to sort
|
|
79
|
+
* `deepLocatorCandidates`, to detect a tie for the top rank rather than
|
|
80
|
+
* duplicating this logic.
|
|
81
|
+
*/
|
|
82
|
+
export declare function extractTaggedPhrases(instruction: string): TaggedPhrase[];
|
|
83
|
+
/**
|
|
84
|
+
* Scores one candidate's relevance to `instruction`'s tagged phrases, higher
|
|
85
|
+
* is more relevant. Mirrors `submit-control.ts`'s tiered-ranking shape:
|
|
86
|
+
* negative signal is checked first and wins outright (a candidate matching
|
|
87
|
+
* ANY negated phrase is actively demoted below "no match" — a decoy sibling
|
|
88
|
+
* button is worse than an unrelated structural node), then positive
|
|
89
|
+
* exact/substring match tiers, falling through to 0 for empty or
|
|
90
|
+
* unrelated text so a structural container with no accessible text can
|
|
91
|
+
* never outrank a candidate whose text actually matches the instruction.
|
|
92
|
+
* Exported so `flow-runner.ts` can detect a tie for the top rank among
|
|
93
|
+
* `resolveDeepLocatorCandidates`'s already-sorted output (see
|
|
94
|
+
* {@link extractTaggedPhrases}'s docblock).
|
|
95
|
+
*/
|
|
96
|
+
export declare function scoreCandidate(accessibleText: string, phrases: TaggedPhrase[]): number;
|
|
39
97
|
/**
|
|
40
98
|
* Enumerates every element `page.deepLocator()` matches inside the frame
|
|
41
99
|
* scoped by `frameSelector`, ranked by relevance to `instruction` (highest
|
|
@@ -50,20 +108,25 @@ export interface DeepLocatorCandidate {
|
|
|
50
108
|
* cascading through candidate sources can move on to the next technique
|
|
51
109
|
* instead of hanging the step forever.
|
|
52
110
|
*
|
|
111
|
+
* Prefers a single batched `evaluate` round-trip over the frame
|
|
112
|
+
* (see {@link scanFrameCandidatesBatched}) — collapsing the O(n) per-candidate
|
|
113
|
+
* `textContent()` round-trips that made a dense OOPIF form (371 candidates
|
|
114
|
+
* measured live) unresolvable inside any reasonable budget — and falls back
|
|
115
|
+
* to the legacy `count()` + per-candidate loop (see
|
|
116
|
+
* {@link enumerateCandidatesViaLegacyLoop}) when no frame seam is available,
|
|
117
|
+
* the batched scan fails, or the batched scan resolves to zero candidates —
|
|
118
|
+
* the batched expression's light-DOM `querySelectorAll` can't see into a
|
|
119
|
+
* shadow root the way `page.deepLocator()` can, so a zero-length scan is
|
|
120
|
+
* treated as inconclusive rather than authoritative. Pass an already-resolved
|
|
121
|
+
* {@link DeepLocatorTimeoutOptions.frameTarget} to use the fast path without
|
|
122
|
+
* paying for an internal re-resolution.
|
|
123
|
+
*
|
|
53
124
|
* Ranking exists because a hop like `"*"` matches every element inside a
|
|
54
125
|
* wizard iframe (html, body, every div, ...) — DOM order alone almost always
|
|
55
126
|
* puts a structural container first, not the control the step instruction
|
|
56
127
|
* actually names. Pass `instruction` as `null`/`undefined` (or omit it) to
|
|
57
128
|
* skip ranking and get delegate order — e.g. for pre-cascade reachability
|
|
58
129
|
* probes that only care whether the frame has ANY candidates.
|
|
59
|
-
*
|
|
60
|
-
* `count()` and each per-candidate `textContent()` are individually bounded
|
|
61
|
-
* by `timeoutOptions.callTimeoutMs` via {@link withWatchdog}; the enumeration
|
|
62
|
-
* loop as a whole is additionally bounded by `timeoutOptions.enumerationBudgetMs`
|
|
63
|
-
* so a hop with dozens of slow-but-settling elements (e.g. 65 candidates
|
|
64
|
-
* matched against a live OOPIF) can't rack up an unbounded total cost even
|
|
65
|
-
* when no single call hangs — the loop aborts early and returns whatever
|
|
66
|
-
* candidates it already resolved.
|
|
67
130
|
*/
|
|
68
131
|
export declare function resolveDeepLocatorCandidates(page: Page, frameSelector: string | null | undefined, innerSelector: string, instruction?: string | null, timeoutOptions?: DeepLocatorTimeoutOptions): Promise<DeepLocatorCandidate[]>;
|
|
69
132
|
/**
|
|
@@ -71,14 +134,38 @@ export declare function resolveDeepLocatorCandidates(page: Page, frameSelector:
|
|
|
71
134
|
* re-deriving the same hop selector `resolveDeepLocatorCandidates` used
|
|
72
135
|
* rather than trusting a caller-supplied `xpath=` string, so the two stay in
|
|
73
136
|
* lockstep even if a candidate's `selector` field is only ever used for
|
|
74
|
-
* display/logging.
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* the same
|
|
81
|
-
*
|
|
137
|
+
* display/logging. Resolves on success and rejects on failure — the caller
|
|
138
|
+
* must infer the outcome from whether this call throws plus their own
|
|
139
|
+
* downstream DOM verification, not from a returned boolean.
|
|
140
|
+
*
|
|
141
|
+
* Prefers the one-round-trip {@link clickCandidateBatched} fast path when a
|
|
142
|
+
* frame seam is available (`timeoutOptions.frameTarget`, or one resolved
|
|
143
|
+
* internally the same way {@link scanFrameCandidatesBatched} does), falling
|
|
144
|
+
* back to the legacy `DeepLocatorDelegate.click()` — which never reports
|
|
145
|
+
* success via a return value, only via not rejecting — when no seam is
|
|
146
|
+
* available, the batched call fails/degrades, or it reports the index
|
|
147
|
+
* stale (`reason: "out-of-range"`). A batched `reason: "not-actionable"`
|
|
148
|
+
* result throws an error {@link isNodeNotActionableError} classifies, the
|
|
149
|
+
* same contract a real click against an unrendered node rejects with via the
|
|
150
|
+
* CDP `-32000 Node does not have a layout object` error, so a caller
|
|
151
|
+
* cascading through candidates treats both paths identically.
|
|
152
|
+
*
|
|
153
|
+
* The legacy fallback's watchdog scales with `index` (see
|
|
154
|
+
* {@link DEEP_LOCATOR_CLICK_INDEX_ROUND_TRIP_MS}) so a legitimately-reachable
|
|
155
|
+
* candidate isn't killed by a budget sized for a single round-trip. A
|
|
156
|
+
* `click()` that still exceeds that scaled budget (a wedged CDP round-trip
|
|
157
|
+
* against a racy OOPIF frame) rejects with a `WatchdogTimeoutError` the same
|
|
158
|
+
* as any other failure, preserving the "rejects on failure" contract instead
|
|
159
|
+
* of hanging the caller forever.
|
|
82
160
|
*/
|
|
83
161
|
export declare function clickDeepLocatorCandidate(page: Page, frameSelector: string | null | undefined, innerSelector: string, index: number, timeoutOptions?: DeepLocatorTimeoutOptions): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* `fillDeepLocatorCandidate`/`selectDeepLocatorCandidateOption` live in
|
|
164
|
+
* `deep-locator-actuate.ts`, not here — that module's `writeAndVerify` wraps
|
|
165
|
+
* the same `buildHopSelector`/`withWatchdog` contract this file's
|
|
166
|
+
* `clickDeepLocatorCandidate` uses, but additionally reads the write back
|
|
167
|
+
* through `inputValue()` before reporting success (`verifyDomEffect` can't
|
|
168
|
+
* resolve a `deeplocator=` selector, so the read-back is the only
|
|
169
|
+
* confirmation a fill/select actually landed).
|
|
170
|
+
*/
|
|
84
171
|
//# sourceMappingURL=deep-locator-candidates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-locator-candidates.d.ts","sourceRoot":"","sources":["../../src/scraper/deep-locator-candidates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"deep-locator-candidates.d.ts","sourceRoot":"","sources":["../../src/scraper/deep-locator-candidates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAWrD,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,wBAAwB,CAAC;AA2BhC,sJAAsJ;AACtJ,MAAM,WAAW,yBAAyB;IACxC,mIAAmI;IACnI,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uJAAuJ;IACvJ,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;;;;;;;;;;OAgBG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAKD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,oBAAoB;IACnC,kJAAkJ;IAClJ,KAAK,EAAE,MAAM,CAAC;IACd,gLAAgL;IAChL,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAsBD,sJAAsJ;AACtJ,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,EAAE,CAaxE;AAOD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAStF;AA6JD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,EAC3B,cAAc,GAAE,yBAA8B,GAC7C,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAuCjC;AAqDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACxC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,cAAc,GAAE,yBAA8B,GAC7C,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED;;;;;;;;GAQG"}
|