@jobshimo/browser-link 0.23.14 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cdp/flow.js CHANGED
@@ -12,13 +12,15 @@
12
12
  *
13
13
  * browser.flow step sequencing — the logic behind the composite action
14
14
  * tool. Runs a short, declarative list of find/click/type/press/wait_for/
15
- * drag steps strictly in order, fails fast on the first step that does
16
- * not succeed, and threads an "implicit target" from a `find` step into
17
- * the very next click/type/press step that omits its own `selector`. A
18
- * `drag` step stays OUT of that chain: both of its endpoints are always
19
- * explicit (selector or coords), so it neither consumes nor sets the
20
- * implicit target — a pending target survives a drag step untouched for
21
- * a later click/type/press, exactly like it survives a wait_for.
15
+ * drag/sleep steps strictly in order, fails fast on the first step that
16
+ * does not succeed, and threads an "implicit target" from a `find` step
17
+ * into the very next click/type/press step that omits its own
18
+ * `selector`. A `drag` step stays OUT of that chain: both of its
19
+ * endpoints are always explicit (selector or coords), so it neither
20
+ * consumes nor sets the implicit target — a pending target survives a
21
+ * drag step untouched for a later click/type/press, exactly like it
22
+ * survives a wait_for. A `sleep` step is a fixed pause and stays out of
23
+ * the chain for the same reason: it names no target at all.
22
24
  *
23
25
  * Deliberately decoupled from any specific transport: every side effect
24
26
  * goes through the `FlowDeps` the caller injects. The concrete wiring —
@@ -45,7 +47,32 @@
45
47
  * nor cdp-direct ever runs an oversized flow even if a future caller
46
48
  * bypasses the server's own check (e.g. a directly-wired test harness). */
47
49
  export const MAX_FLOW_STEPS = 20;
48
- const STEP_KINDS = ['find', 'click', 'type', 'press', 'wait_for', 'drag'];
50
+ /** Hard cap on one `sleep` step's `ms`. Matches the ceiling a single
51
+ * `wait_for` step may request, so no one step can park the flow longer
52
+ * than the longest wait already expressible. Out-of-range values are a
53
+ * validation ERROR rather than a silent clamp: a flow that asked to
54
+ * throttle by 60s and got 30s would hammer a backend at twice the
55
+ * intended rate without ever saying so. */
56
+ export const MAX_FLOW_SLEEP_MS = 30_000;
57
+ /** Hard cap on one `repeat` step's `max_iterations`. The real ceiling in
58
+ * practice is the flow's own worst-case time budget (a repeat's budget is
59
+ * `max_iterations × (inner steps + delay)`), which bites long before this
60
+ * does; this is the backstop that keeps a typo from producing an
61
+ * absurd projected budget. */
62
+ export const MAX_FLOW_REPEAT_ITERATIONS = 500;
63
+ /** Hard cap on a `repeat`'s inter-iteration `delay_ms` — same ceiling a
64
+ * standalone `sleep` step may request. */
65
+ export const MAX_FLOW_REPEAT_DELAY_MS = 30_000;
66
+ const STEP_KINDS = [
67
+ 'find',
68
+ 'click',
69
+ 'type',
70
+ 'press',
71
+ 'wait_for',
72
+ 'drag',
73
+ 'sleep',
74
+ 'repeat',
75
+ ];
49
76
  function isStepKind(key) {
50
77
  return STEP_KINDS.includes(key);
51
78
  }
@@ -115,6 +142,359 @@ function resolveTarget(explicit, implicit) {
115
142
  * document rather than genuinely missing its target. */
116
143
  const NAVIGATION_RACE_HINT = " (previous step's settle reported context-destroyed — the page likely navigated;" +
117
144
  ' insert a wait_for step after the navigating action so this step does not race the page load)';
145
+ /** Execute ONE non-repeat step against `state`, which it mutates. */
146
+ async function executeLeafStep(kind, stepRecord, state, deps) {
147
+ const raceHint = () => state.lastSettleReason === 'context-destroyed' ? NAVIGATION_RACE_HINT : '';
148
+ if (kind === 'find') {
149
+ const params = stepRecord.find;
150
+ const outcome = await deps.performFind(params);
151
+ if (!outcome.ok)
152
+ return { ok: false, error: outcome.error + raceHint() };
153
+ const r = outcome.result;
154
+ if (!r.matched) {
155
+ const candidateNote = r.reason === 'multiple-matches' && r.candidates
156
+ ? ` — candidates: ${JSON.stringify(r.candidates)}`
157
+ : '';
158
+ return { ok: false, error: `find: ${r.reason ?? 'not-found'}${candidateNote}${raceHint()}` };
159
+ }
160
+ if (r.ambiguous) {
161
+ return {
162
+ ok: false,
163
+ error: `find: selector "${r.selector ?? ''}" is ambiguous across shadow roots/iframes — refine text/role for a unique match`,
164
+ };
165
+ }
166
+ state.implicitTarget = r.selector;
167
+ state.lastSettleReason = undefined;
168
+ return { ok: true, entry: { selector: r.selector } };
169
+ }
170
+ if (kind === 'wait_for') {
171
+ const params = stepRecord.wait_for;
172
+ const outcome = await deps.performWaitFor(params);
173
+ if (!outcome.ok)
174
+ return { ok: false, error: outcome.error + raceHint() };
175
+ if (!outcome.result.matched) {
176
+ // No race hint here: a wait_for step IS the recommended remedy for
177
+ // a navigation race — a plain timeout is a genuine non-match.
178
+ return {
179
+ ok: false,
180
+ error: `wait_for: condition not met within timeout (${outcome.result.elapsed_ms}ms, ${outcome.result.checks} checks)`,
181
+ };
182
+ }
183
+ state.lastSettleReason = undefined;
184
+ return { ok: true, entry: { ok: true } };
185
+ }
186
+ if (kind === 'drag') {
187
+ const params = stepRecord.drag;
188
+ // No resolveTarget here ON PURPOSE: a drag names BOTH endpoints
189
+ // explicitly (selector or coords), so there is no single `selector`
190
+ // slot the implicit target could unambiguously fill — a pending
191
+ // implicit target survives this step untouched for a later
192
+ // click/type/press, exactly like it survives a wait_for.
193
+ const outcome = await deps.performDrag(params);
194
+ if (!outcome.ok)
195
+ return { ok: false, error: outcome.error + raceHint() };
196
+ // A successful drag resolved both endpoints via an in-page probe,
197
+ // which proves the document is reachable again after any earlier
198
+ // navigation — clear the race hint like find/wait_for do. (Drag has
199
+ // no settle phase, so there is no settle reason to carry instead.)
200
+ state.lastSettleReason = undefined;
201
+ return { ok: true, entry: compactActionResult(outcome.result) };
202
+ }
203
+ if (kind === 'sleep') {
204
+ const params = stepRecord.sleep;
205
+ const ms = params?.ms;
206
+ // Re-validated here even though the server already checked: this
207
+ // module is reachable from a directly-wired caller that never went
208
+ // through `validateFlowSteps` (see the runFlow doc comment).
209
+ if (typeof ms !== 'number' || !Number.isInteger(ms) || ms < 1 || ms > MAX_FLOW_SLEEP_MS) {
210
+ return {
211
+ ok: false,
212
+ error: `sleep: ms must be an integer between 1 and ${MAX_FLOW_SLEEP_MS}`,
213
+ };
214
+ }
215
+ // The guard above already REJECTED anything outside 1..MAX, so this
216
+ // Math.min can never actually reduce a value — it is not a silent
217
+ // clamp and does not weaken the reject-don't-clamp contract. It is
218
+ // here so the timer's upper bound is provable from this line alone:
219
+ // static analysis (CodeQL `js/resource-exhaustion`) cannot follow the
220
+ // bound through the compound guard, and an unbounded user-controlled
221
+ // timer duration is a finding worth keeping impossible BY SHAPE
222
+ // rather than by argument.
223
+ const delayMs = Math.min(ms, MAX_FLOW_SLEEP_MS);
224
+ await new Promise((resolve) => {
225
+ setTimeout(resolve, delayMs);
226
+ });
227
+ // Deliberately does NOT clear `lastSettleReason`: find/wait_for/drag
228
+ // clear it because each one probes the document and thereby PROVES
229
+ // it is reachable again. A sleep proves nothing — it just waits — so
230
+ // a pending navigation-race hint stays armed for the next failure.
231
+ // The implicit target likewise survives untouched, exactly as it
232
+ // survives a wait_for or a drag.
233
+ return { ok: true, entry: { slept_ms: ms } };
234
+ }
235
+ if (kind === 'click') {
236
+ const params = stepRecord.click;
237
+ const { resolved, consumed } = resolveTarget(params.selector, state.implicitTarget);
238
+ if (consumed)
239
+ state.implicitTarget = undefined;
240
+ if (resolved === undefined) {
241
+ return {
242
+ ok: false,
243
+ error: 'click: no selector provided and no implicit target from a preceding find',
244
+ };
245
+ }
246
+ const outcome = await deps.performClick({
247
+ force: params.force,
248
+ settle_ms: params.settle_ms,
249
+ selector: resolved,
250
+ });
251
+ if (!outcome.ok)
252
+ return { ok: false, error: outcome.error + raceHint() };
253
+ state.lastSettleReason = outcome.result.settle?.reason;
254
+ return { ok: true, entry: compactActionResult(outcome.result) };
255
+ }
256
+ if (kind === 'type') {
257
+ const params = stepRecord.type;
258
+ const { resolved, consumed } = resolveTarget(params.selector, state.implicitTarget);
259
+ if (consumed)
260
+ state.implicitTarget = undefined;
261
+ const outcome = await deps.performType({
262
+ text: params.text,
263
+ clear: params.clear,
264
+ settle_ms: params.settle_ms,
265
+ selector: resolved,
266
+ });
267
+ if (!outcome.ok)
268
+ return { ok: false, error: outcome.error + raceHint() };
269
+ state.lastSettleReason = outcome.result.settle?.reason;
270
+ return { ok: true, entry: compactActionResult(outcome.result) };
271
+ }
272
+ // press — the only kind left after the checks above.
273
+ const params = stepRecord.press;
274
+ const { resolved, consumed } = resolveTarget(params.selector, state.implicitTarget);
275
+ if (consumed)
276
+ state.implicitTarget = undefined;
277
+ const outcome = await deps.performPress({
278
+ key: params.key,
279
+ modifiers: params.modifiers,
280
+ settle_ms: params.settle_ms,
281
+ selector: resolved,
282
+ });
283
+ if (!outcome.ok)
284
+ return { ok: false, error: outcome.error + raceHint() };
285
+ state.lastSettleReason = outcome.result.settle?.reason;
286
+ return { ok: true, entry: compactActionResult(outcome.result) };
287
+ }
288
+ /** Validate a raw `repeat` body. Shared by the executor and the dry-run
289
+ * planner so a flow can never be projected under looser rules than it
290
+ * would actually run under. */
291
+ function normalizeRepeat(raw) {
292
+ const params = raw;
293
+ const innerSteps = params?.steps;
294
+ if (!Array.isArray(innerSteps) || innerSteps.length === 0) {
295
+ return { ok: false, error: 'repeat: steps must be a non-empty array' };
296
+ }
297
+ const maxIterations = params?.max_iterations;
298
+ if (typeof maxIterations !== 'number' ||
299
+ !Number.isInteger(maxIterations) ||
300
+ maxIterations < 1 ||
301
+ maxIterations > MAX_FLOW_REPEAT_ITERATIONS) {
302
+ return {
303
+ ok: false,
304
+ error: `repeat: max_iterations is required and must be an integer between 1 and ${MAX_FLOW_REPEAT_ITERATIONS}`,
305
+ };
306
+ }
307
+ const whileFound = params?.while_found;
308
+ if (whileFound !== undefined && (typeof whileFound !== 'string' || whileFound.length === 0)) {
309
+ return { ok: false, error: 'repeat: while_found must be a non-empty string' };
310
+ }
311
+ const delayRaw = params?.delay_ms;
312
+ if (delayRaw !== undefined &&
313
+ (typeof delayRaw !== 'number' ||
314
+ !Number.isInteger(delayRaw) ||
315
+ delayRaw < 0 ||
316
+ delayRaw > MAX_FLOW_REPEAT_DELAY_MS)) {
317
+ return {
318
+ ok: false,
319
+ error: `repeat: delay_ms must be an integer between 0 and ${MAX_FLOW_REPEAT_DELAY_MS}`,
320
+ };
321
+ }
322
+ for (let j = 0; j < innerSteps.length; j++) {
323
+ const innerKind = stepKind(innerSteps[j]);
324
+ if (!innerKind) {
325
+ return {
326
+ ok: false,
327
+ error: `repeat: step ${j}: each step must be exactly one of find | click | type | press | wait_for | drag | sleep`,
328
+ };
329
+ }
330
+ if (innerKind === 'repeat') {
331
+ return {
332
+ ok: false,
333
+ error: 'repeat: steps may not contain another repeat — nesting is not supported',
334
+ };
335
+ }
336
+ }
337
+ return {
338
+ ok: true,
339
+ value: {
340
+ steps: innerSteps,
341
+ maxIterations,
342
+ whileFound,
343
+ // Bounded with Math.min for the same reason `sleep` is: the guard
344
+ // above already rejected anything larger, so this cannot silently
345
+ // clamp — it makes the timer's ceiling provable from the call site.
346
+ delayMs: Math.min(delayRaw ?? 0, MAX_FLOW_REPEAT_DELAY_MS),
347
+ },
348
+ };
349
+ }
350
+ /**
351
+ * One-shot presence test for `while_found`.
352
+ *
353
+ * Deliberately reuses the existing `performWaitFor` seam instead of adding
354
+ * a new `FlowDeps` method: `timeout_ms: 0` makes its poll loop run exactly
355
+ * ONE check and return (it evaluates the condition BEFORE testing the
356
+ * deadline), so this is a single in-page probe with no new wiring and
357
+ * identical behaviour on both transports. `condition: 'visible'` matches
358
+ * what `browser.find` considers a real element, so a row that is merely
359
+ * hidden ends the loop just as a removed one does.
360
+ */
361
+ async function whileFoundStillMatches(selector, deps) {
362
+ const outcome = await deps.performWaitFor({ selector, condition: 'visible', timeout_ms: 0 });
363
+ if (!outcome.ok)
364
+ return { ok: false, error: outcome.error };
365
+ return { ok: true, matched: outcome.result.matched };
366
+ }
367
+ /** Run one `repeat` step to completion. */
368
+ async function executeRepeatStep(raw, deps) {
369
+ const normalized = normalizeRepeat(raw);
370
+ if (!normalized.ok)
371
+ return normalized;
372
+ const { steps: innerSteps, maxIterations, whileFound, delayMs } = normalized.value;
373
+ // Local, explicitly range-checked copy of the pause. `normalizeRepeat`
374
+ // already rejected anything outside 0..MAX, so the `else` is
375
+ // unreachable in practice — but the timer's ceiling has to be provable
376
+ // from an upper-bound COMPARISON inside this function. A `Math.min` is
377
+ // not enough here: the value reaches us through a property of the
378
+ // normalized object, and static analysis (CodeQL
379
+ // `js/resource-exhaustion`) does not carry the sanitizer across that
380
+ // hop. An unbounded user-controlled timer duration stays impossible by
381
+ // shape rather than by argument.
382
+ let iterationDelayMs = 0;
383
+ if (Number.isInteger(delayMs) && delayMs > 0 && delayMs <= MAX_FLOW_REPEAT_DELAY_MS) {
384
+ iterationDelayMs = delayMs;
385
+ }
386
+ const iterations = [];
387
+ let stoppedBy = 'max_iterations';
388
+ for (let iter = 0; iter < maxIterations; iter++) {
389
+ if (whileFound !== undefined) {
390
+ const probe = await whileFoundStillMatches(whileFound, deps);
391
+ if (!probe.ok) {
392
+ return { ok: false, error: `repeat: while_found probe failed — ${probe.error}` };
393
+ }
394
+ if (!probe.matched) {
395
+ stoppedBy = 'condition';
396
+ break;
397
+ }
398
+ }
399
+ // Fresh state per iteration: iteration N can never act on whatever
400
+ // iteration N-1's `find` happened to resolve.
401
+ const state = { implicitTarget: undefined, lastSettleReason: undefined };
402
+ const entries = [];
403
+ for (let j = 0; j < innerSteps.length; j++) {
404
+ const innerRaw = innerSteps[j];
405
+ // Re-derived per iteration rather than trusted from normalizeRepeat:
406
+ // same defense-in-depth every other step shape gets.
407
+ const innerKind = stepKind(innerRaw);
408
+ if (innerKind === null || innerKind === 'repeat') {
409
+ return {
410
+ ok: false,
411
+ error: `repeat: iteration ${iter}, step ${j}: invalid step shape`,
412
+ };
413
+ }
414
+ const outcome = await executeLeafStep(innerKind, innerRaw, state, deps);
415
+ if (!outcome.ok) {
416
+ return {
417
+ ok: false,
418
+ error: `repeat: iteration ${iter}, step ${j} (${innerKind}) failed — ${outcome.error}`,
419
+ };
420
+ }
421
+ entries.push(outcome.entry);
422
+ }
423
+ iterations.push(entries);
424
+ if (iterationDelayMs > 0) {
425
+ await new Promise((resolve) => {
426
+ setTimeout(resolve, iterationDelayMs);
427
+ });
428
+ }
429
+ }
430
+ const entry = {
431
+ iterations_completed: iterations.length,
432
+ stopped_by: stoppedBy,
433
+ iterations,
434
+ };
435
+ return { ok: true, entry };
436
+ }
437
+ /** Total step count INCLUDING a repeat's inner steps. A 20-step ceiling
438
+ * that only counted the outer array would let a single repeat smuggle in
439
+ * an arbitrarily long body. */
440
+ function countTotalSteps(steps) {
441
+ let total = 0;
442
+ // Walked as `unknown`, not as FlowStep: the array is typed for
443
+ // ergonomic test-writing but arrives as untrusted JSON cast at the wire
444
+ // boundary, so an entry can genuinely be null or a primitive. Narrowing
445
+ // from `unknown` keeps those guards meaningful instead of letting the
446
+ // declared type talk the compiler out of them.
447
+ for (const step of steps) {
448
+ total++;
449
+ if (typeof step === 'object' && step !== null && 'repeat' in step) {
450
+ const inner = step.repeat?.steps;
451
+ if (Array.isArray(inner))
452
+ total += inner.length;
453
+ }
454
+ }
455
+ return total;
456
+ }
457
+ /**
458
+ * Project a flow without executing it. Reads are allowed (a `while_found`
459
+ * probe is a read); nothing is ever dispatched.
460
+ */
461
+ async function planFlow(steps, deps) {
462
+ const results = [];
463
+ for (let i = 0; i < steps.length; i++) {
464
+ const raw = steps[i];
465
+ const kind = stepKind(raw);
466
+ if (!kind) {
467
+ return withRecoverySnapshot(deps, i, 'unknown', 'flow: each step must be exactly one of find | click | type | press | wait_for | drag | sleep | repeat', results.length);
468
+ }
469
+ if (kind !== 'repeat') {
470
+ results.push({ step: kind });
471
+ continue;
472
+ }
473
+ const stepRecord = raw;
474
+ const normalized = normalizeRepeat(stepRecord.repeat);
475
+ if (!normalized.ok) {
476
+ return withRecoverySnapshot(deps, i, kind, normalized.error, results.length);
477
+ }
478
+ const { maxIterations, whileFound, delayMs } = normalized.value;
479
+ let wouldStart = true;
480
+ if (whileFound !== undefined) {
481
+ const probe = await whileFoundStillMatches(whileFound, deps);
482
+ if (!probe.ok) {
483
+ return withRecoverySnapshot(deps, i, kind, `repeat: while_found probe failed — ${probe.error}`, results.length);
484
+ }
485
+ wouldStart = probe.matched;
486
+ }
487
+ results.push({
488
+ step: 'repeat',
489
+ max_iterations: maxIterations,
490
+ inner_steps: normalized.value.steps.length,
491
+ delay_ms: delayMs,
492
+ ...(whileFound === undefined ? {} : { while_found: whileFound }),
493
+ would_start: wouldStart,
494
+ });
495
+ }
496
+ return { ok: true, steps_completed: 0, results, dry_run: true };
497
+ }
118
498
  /**
119
499
  * Run a declarative sequence of steps strictly in order, stopping at the
120
500
  * first failure. See the module doc comment for the implicit-target and
@@ -125,138 +505,47 @@ const NAVIGATION_RACE_HINT = " (previous step's settle reported context-destroye
125
505
  * array may originate from an untrusted JSON payload cast at the wire
126
506
  * boundary in `background.ts` (extension) / `cdp/transport.ts` (server),
127
507
  * and a malformed entry must fail the flow cleanly rather than throw.
508
+ *
509
+ * With `options.dryRun`, the flow is validated and projected instead:
510
+ * nothing is dispatched, and each entry describes what WOULD run.
128
511
  */
129
- export async function runFlow(steps, deps) {
512
+ export async function runFlow(steps, deps, options = {}) {
130
513
  if (!Array.isArray(steps) || steps.length === 0) {
131
514
  return withRecoverySnapshot(deps, 0, 'none', 'flow: steps must be a non-empty array', 0);
132
515
  }
133
- if (steps.length > MAX_FLOW_STEPS) {
134
- return withRecoverySnapshot(deps, 0, 'none', `flow: at most ${MAX_FLOW_STEPS} steps allowed, got ${steps.length}`, 0);
516
+ const totalSteps = countTotalSteps(steps);
517
+ if (totalSteps > MAX_FLOW_STEPS) {
518
+ return withRecoverySnapshot(deps, 0, 'none', `flow: at most ${MAX_FLOW_STEPS} steps allowed, got ${totalSteps}`, 0);
135
519
  }
520
+ if (options.dryRun === true)
521
+ return planFlow(steps, deps);
136
522
  const results = [];
137
- let implicitTarget;
138
- /** `settle.reason` from the most recent SUCCESSFUL action step. When it
139
- * is 'context-destroyed', the next step failure gets the page-load-race
140
- * hint appended. Reset by any successful find/wait_for step — those
141
- * prove the page is reachable again. */
142
- let lastSettleReason;
143
- const raceHint = () => lastSettleReason === 'context-destroyed' ? NAVIGATION_RACE_HINT : '';
523
+ const state = { implicitTarget: undefined, lastSettleReason: undefined };
144
524
  for (let i = 0; i < steps.length; i++) {
145
525
  const raw = steps[i];
146
526
  const kind = stepKind(raw);
147
527
  if (!kind) {
148
- return withRecoverySnapshot(deps, i, 'unknown', 'flow: each step must be exactly one of find | click | type | press | wait_for | drag', results.length);
528
+ return withRecoverySnapshot(deps, i, 'unknown', 'flow: each step must be exactly one of find | click | type | press | wait_for | drag | sleep | repeat', results.length);
149
529
  }
150
530
  const stepRecord = raw;
151
- if (kind === 'find') {
152
- const params = stepRecord.find;
153
- const outcome = await deps.performFind(params);
154
- if (!outcome.ok) {
155
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
156
- }
157
- const r = outcome.result;
158
- if (!r.matched) {
159
- const candidateNote = r.reason === 'multiple-matches' && r.candidates
160
- ? ` — candidates: ${JSON.stringify(r.candidates)}`
161
- : '';
162
- return withRecoverySnapshot(deps, i, kind, `find: ${r.reason ?? 'not-found'}${candidateNote}${raceHint()}`, results.length);
163
- }
164
- if (r.ambiguous) {
165
- return withRecoverySnapshot(deps, i, kind, `find: selector "${r.selector ?? ''}" is ambiguous across shadow roots/iframes — refine text/role for a unique match`, results.length);
166
- }
167
- implicitTarget = r.selector;
168
- lastSettleReason = undefined;
169
- results.push({ selector: r.selector });
170
- continue;
171
- }
172
- if (kind === 'wait_for') {
173
- const params = stepRecord.wait_for;
174
- const outcome = await deps.performWaitFor(params);
175
- if (!outcome.ok) {
176
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
177
- }
178
- if (!outcome.result.matched) {
179
- // No race hint here: a wait_for step IS the recommended remedy for
180
- // a navigation race — a plain timeout is a genuine non-match.
181
- return withRecoverySnapshot(deps, i, kind, `wait_for: condition not met within timeout (${outcome.result.elapsed_ms}ms, ${outcome.result.checks} checks)`, results.length);
182
- }
183
- lastSettleReason = undefined;
184
- results.push({ ok: true });
185
- continue;
186
- }
187
- if (kind === 'drag') {
188
- const params = stepRecord.drag;
189
- // No resolveTarget here ON PURPOSE: a drag names BOTH endpoints
190
- // explicitly (selector or coords), so there is no single `selector`
191
- // slot the implicit target could unambiguously fill — a pending
192
- // implicit target survives this step untouched for a later
193
- // click/type/press, exactly like it survives a wait_for.
194
- const outcome = await deps.performDrag(params);
195
- if (!outcome.ok) {
196
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
197
- }
198
- // A successful drag resolved both endpoints via an in-page probe,
199
- // which proves the document is reachable again after any earlier
200
- // navigation — clear the race hint like find/wait_for do. (Drag has
201
- // no settle phase, so there is no settle reason to carry instead.)
202
- lastSettleReason = undefined;
203
- results.push(compactActionResult(outcome.result));
204
- continue;
205
- }
206
- if (kind === 'click') {
207
- const params = stepRecord.click;
208
- const { resolved, consumed } = resolveTarget(params.selector, implicitTarget);
209
- if (consumed)
210
- implicitTarget = undefined;
211
- if (resolved === undefined) {
212
- return withRecoverySnapshot(deps, i, kind, 'click: no selector provided and no implicit target from a preceding find', results.length);
213
- }
214
- const outcome = await deps.performClick({
215
- force: params.force,
216
- settle_ms: params.settle_ms,
217
- selector: resolved,
218
- });
219
- if (!outcome.ok) {
220
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
221
- }
222
- lastSettleReason = outcome.result.settle?.reason;
223
- results.push(compactActionResult(outcome.result));
224
- continue;
225
- }
226
- if (kind === 'type') {
227
- const params = stepRecord.type;
228
- const { resolved, consumed } = resolveTarget(params.selector, implicitTarget);
229
- if (consumed)
230
- implicitTarget = undefined;
231
- const outcome = await deps.performType({
232
- text: params.text,
233
- clear: params.clear,
234
- settle_ms: params.settle_ms,
235
- selector: resolved,
236
- });
531
+ if (kind === 'repeat') {
532
+ const outcome = await executeRepeatStep(stepRecord.repeat, deps);
237
533
  if (!outcome.ok) {
238
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
534
+ return withRecoverySnapshot(deps, i, kind, outcome.error, results.length);
239
535
  }
240
- lastSettleReason = outcome.result.settle?.reason;
241
- results.push(compactActionResult(outcome.result));
536
+ // A repeat body runs with its own state and does not leak one out:
537
+ // a pending implicit target from BEFORE the repeat also does not
538
+ // survive it, since the body may have navigated or re-rendered.
539
+ state.implicitTarget = undefined;
540
+ state.lastSettleReason = undefined;
541
+ results.push(outcome.entry);
242
542
  continue;
243
543
  }
244
- // press — the only kind left after the checks above.
245
- const params = stepRecord.press;
246
- const { resolved, consumed } = resolveTarget(params.selector, implicitTarget);
247
- if (consumed)
248
- implicitTarget = undefined;
249
- const outcome = await deps.performPress({
250
- key: params.key,
251
- modifiers: params.modifiers,
252
- settle_ms: params.settle_ms,
253
- selector: resolved,
254
- });
544
+ const outcome = await executeLeafStep(kind, stepRecord, state, deps);
255
545
  if (!outcome.ok) {
256
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
546
+ return withRecoverySnapshot(deps, i, kind, outcome.error, results.length);
257
547
  }
258
- lastSettleReason = outcome.result.settle?.reason;
259
- results.push(compactActionResult(outcome.result));
548
+ results.push(outcome.entry);
260
549
  }
261
550
  return { ok: true, steps_completed: results.length, results };
262
551
  }
@@ -1 +1 @@
1
- {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/cdp/flow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../src/cdp/flow.ts"],"names":[],"mappings":"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"}
@@ -593,7 +593,11 @@ export async function callCdpTool(tabId, tool, params, timeoutMs) {
593
593
  // naming the extension transport as the fallback.
594
594
  performDrag: () => Promise.resolve({ ok: false, error: cdpUnsupportedToolError('drag').message }),
595
595
  buildRecoverySnapshot: () => evaluateInTab(client, buildSnapshotJs({ only_interactive: true, max_interactive: 40 })),
596
- });
596
+ },
597
+ // Strict `=== true`: any other value runs the flow FOR REAL. A dry
598
+ // run that silently became a real run would be the worst possible
599
+ // failure of this flag, so only the exact boolean opts into it.
600
+ { dryRun: p.dry_run === true });
597
601
  }
598
602
  default:
599
603
  // Reached only if a caller bypasses CDP_TOOL_SUPPORT's gate — defense