@jobshimo/browser-link 0.24.0 → 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
@@ -54,6 +54,15 @@ export const MAX_FLOW_STEPS = 20;
54
54
  * throttle by 60s and got 30s would hammer a backend at twice the
55
55
  * intended rate without ever saying so. */
56
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;
57
66
  const STEP_KINDS = [
58
67
  'find',
59
68
  'click',
@@ -62,6 +71,7 @@ const STEP_KINDS = [
62
71
  'wait_for',
63
72
  'drag',
64
73
  'sleep',
74
+ 'repeat',
65
75
  ];
66
76
  function isStepKind(key) {
67
77
  return STEP_KINDS.includes(key);
@@ -132,6 +142,359 @@ function resolveTarget(explicit, implicit) {
132
142
  * document rather than genuinely missing its target. */
133
143
  const NAVIGATION_RACE_HINT = " (previous step's settle reported context-destroyed — the page likely navigated;" +
134
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
+ }
135
498
  /**
136
499
  * Run a declarative sequence of steps strictly in order, stopping at the
137
500
  * first failure. See the module doc comment for the implicit-target and
@@ -142,168 +505,47 @@ const NAVIGATION_RACE_HINT = " (previous step's settle reported context-destroye
142
505
  * array may originate from an untrusted JSON payload cast at the wire
143
506
  * boundary in `background.ts` (extension) / `cdp/transport.ts` (server),
144
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.
145
511
  */
146
- export async function runFlow(steps, deps) {
512
+ export async function runFlow(steps, deps, options = {}) {
147
513
  if (!Array.isArray(steps) || steps.length === 0) {
148
514
  return withRecoverySnapshot(deps, 0, 'none', 'flow: steps must be a non-empty array', 0);
149
515
  }
150
- if (steps.length > MAX_FLOW_STEPS) {
151
- 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);
152
519
  }
520
+ if (options.dryRun === true)
521
+ return planFlow(steps, deps);
153
522
  const results = [];
154
- let implicitTarget;
155
- /** `settle.reason` from the most recent SUCCESSFUL action step. When it
156
- * is 'context-destroyed', the next step failure gets the page-load-race
157
- * hint appended. Reset by any successful find/wait_for step — those
158
- * prove the page is reachable again. */
159
- let lastSettleReason;
160
- const raceHint = () => lastSettleReason === 'context-destroyed' ? NAVIGATION_RACE_HINT : '';
523
+ const state = { implicitTarget: undefined, lastSettleReason: undefined };
161
524
  for (let i = 0; i < steps.length; i++) {
162
525
  const raw = steps[i];
163
526
  const kind = stepKind(raw);
164
527
  if (!kind) {
165
- return withRecoverySnapshot(deps, i, 'unknown', 'flow: each step must be exactly one of find | click | type | press | wait_for | drag | sleep', 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);
166
529
  }
167
530
  const stepRecord = raw;
168
- if (kind === 'find') {
169
- const params = stepRecord.find;
170
- const outcome = await deps.performFind(params);
531
+ if (kind === 'repeat') {
532
+ const outcome = await executeRepeatStep(stepRecord.repeat, deps);
171
533
  if (!outcome.ok) {
172
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
534
+ return withRecoverySnapshot(deps, i, kind, outcome.error, results.length);
173
535
  }
174
- const r = outcome.result;
175
- if (!r.matched) {
176
- const candidateNote = r.reason === 'multiple-matches' && r.candidates
177
- ? ` — candidates: ${JSON.stringify(r.candidates)}`
178
- : '';
179
- return withRecoverySnapshot(deps, i, kind, `find: ${r.reason ?? 'not-found'}${candidateNote}${raceHint()}`, results.length);
180
- }
181
- if (r.ambiguous) {
182
- return withRecoverySnapshot(deps, i, kind, `find: selector "${r.selector ?? ''}" is ambiguous across shadow roots/iframes — refine text/role for a unique match`, results.length);
183
- }
184
- implicitTarget = r.selector;
185
- lastSettleReason = undefined;
186
- results.push({ selector: r.selector });
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);
187
542
  continue;
188
543
  }
189
- if (kind === 'wait_for') {
190
- const params = stepRecord.wait_for;
191
- const outcome = await deps.performWaitFor(params);
192
- if (!outcome.ok) {
193
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
194
- }
195
- if (!outcome.result.matched) {
196
- // No race hint here: a wait_for step IS the recommended remedy for
197
- // a navigation race — a plain timeout is a genuine non-match.
198
- return withRecoverySnapshot(deps, i, kind, `wait_for: condition not met within timeout (${outcome.result.elapsed_ms}ms, ${outcome.result.checks} checks)`, results.length);
199
- }
200
- lastSettleReason = undefined;
201
- results.push({ ok: true });
202
- continue;
203
- }
204
- if (kind === 'drag') {
205
- const params = stepRecord.drag;
206
- // No resolveTarget here ON PURPOSE: a drag names BOTH endpoints
207
- // explicitly (selector or coords), so there is no single `selector`
208
- // slot the implicit target could unambiguously fill — a pending
209
- // implicit target survives this step untouched for a later
210
- // click/type/press, exactly like it survives a wait_for.
211
- const outcome = await deps.performDrag(params);
212
- if (!outcome.ok) {
213
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
214
- }
215
- // A successful drag resolved both endpoints via an in-page probe,
216
- // which proves the document is reachable again after any earlier
217
- // navigation — clear the race hint like find/wait_for do. (Drag has
218
- // no settle phase, so there is no settle reason to carry instead.)
219
- lastSettleReason = undefined;
220
- results.push(compactActionResult(outcome.result));
221
- continue;
222
- }
223
- if (kind === 'sleep') {
224
- const params = stepRecord.sleep;
225
- const ms = params?.ms;
226
- // Re-validated here even though the server already checked: this
227
- // module is reachable from a directly-wired caller that never went
228
- // through `validateFlowSteps` (see the runFlow doc comment).
229
- if (typeof ms !== 'number' || !Number.isInteger(ms) || ms < 1 || ms > MAX_FLOW_SLEEP_MS) {
230
- return withRecoverySnapshot(deps, i, kind, `sleep: ms must be an integer between 1 and ${MAX_FLOW_SLEEP_MS}`, results.length);
231
- }
232
- // The guard above already REJECTED anything outside 1..MAX, so this
233
- // Math.min can never actually reduce a value — it is not a silent
234
- // clamp and does not weaken the reject-don't-clamp contract. It is
235
- // here so the timer's upper bound is provable from this line alone:
236
- // static analysis (CodeQL `js/resource-exhaustion`) cannot follow the
237
- // bound through the compound guard, and an unbounded user-controlled
238
- // timer duration is a finding worth keeping impossible BY SHAPE
239
- // rather than by argument.
240
- const delayMs = Math.min(ms, MAX_FLOW_SLEEP_MS);
241
- await new Promise((resolve) => {
242
- setTimeout(resolve, delayMs);
243
- });
244
- // Deliberately does NOT clear `lastSettleReason`: find/wait_for/drag
245
- // clear it because each one probes the document and thereby PROVES
246
- // it is reachable again. A sleep proves nothing — it just waits — so
247
- // a pending navigation-race hint stays armed for the next failure.
248
- // The implicit target likewise survives untouched, exactly as it
249
- // survives a wait_for or a drag.
250
- results.push({ slept_ms: ms });
251
- continue;
252
- }
253
- if (kind === 'click') {
254
- const params = stepRecord.click;
255
- const { resolved, consumed } = resolveTarget(params.selector, implicitTarget);
256
- if (consumed)
257
- implicitTarget = undefined;
258
- if (resolved === undefined) {
259
- return withRecoverySnapshot(deps, i, kind, 'click: no selector provided and no implicit target from a preceding find', results.length);
260
- }
261
- const outcome = await deps.performClick({
262
- force: params.force,
263
- settle_ms: params.settle_ms,
264
- selector: resolved,
265
- });
266
- if (!outcome.ok) {
267
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
268
- }
269
- lastSettleReason = outcome.result.settle?.reason;
270
- results.push(compactActionResult(outcome.result));
271
- continue;
272
- }
273
- if (kind === 'type') {
274
- const params = stepRecord.type;
275
- const { resolved, consumed } = resolveTarget(params.selector, implicitTarget);
276
- if (consumed)
277
- implicitTarget = undefined;
278
- const outcome = await deps.performType({
279
- text: params.text,
280
- clear: params.clear,
281
- settle_ms: params.settle_ms,
282
- selector: resolved,
283
- });
284
- if (!outcome.ok) {
285
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
286
- }
287
- lastSettleReason = outcome.result.settle?.reason;
288
- results.push(compactActionResult(outcome.result));
289
- continue;
290
- }
291
- // press — the only kind left after the checks above.
292
- const params = stepRecord.press;
293
- const { resolved, consumed } = resolveTarget(params.selector, implicitTarget);
294
- if (consumed)
295
- implicitTarget = undefined;
296
- const outcome = await deps.performPress({
297
- key: params.key,
298
- modifiers: params.modifiers,
299
- settle_ms: params.settle_ms,
300
- selector: resolved,
301
- });
544
+ const outcome = await executeLeafStep(kind, stepRecord, state, deps);
302
545
  if (!outcome.ok) {
303
- return withRecoverySnapshot(deps, i, kind, outcome.error + raceHint(), results.length);
546
+ return withRecoverySnapshot(deps, i, kind, outcome.error, results.length);
304
547
  }
305
- lastSettleReason = outcome.result.settle?.reason;
306
- results.push(compactActionResult(outcome.result));
548
+ results.push(outcome.entry);
307
549
  }
308
550
  return { ok: true, steps_completed: results.length, results };
309
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