@riddledc/riddle-proof 0.7.196 → 0.7.198

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -8778,6 +8778,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
8778
8778
  var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
8779
8779
  "click",
8780
8780
  "tap",
8781
+ "tap_until",
8781
8782
  "drag",
8782
8783
  "press",
8783
8784
  "key_down",
@@ -9348,6 +9349,28 @@ function profileSetupTapReceipts(results) {
9348
9349
  reason: result.reason ?? result.error ?? null
9349
9350
  }));
9350
9351
  }
9352
+ function profileSetupTapUntilReceipts(results) {
9353
+ return results.filter((result) => profileSetupResultAction(result) === "tap_until").map((result) => ({
9354
+ ordinal: result.ordinal ?? null,
9355
+ ok: result.ok !== false,
9356
+ selector: result.selector ?? null,
9357
+ frame_selector: result.frame_selector ?? null,
9358
+ pointer_type: result.pointer_type ?? null,
9359
+ input_dispatch: result.input_dispatch ?? null,
9360
+ coordinate_mode: result.coordinate_mode ?? null,
9361
+ x: result.x ?? null,
9362
+ y: result.y ?? null,
9363
+ duration_ms: result.duration_ms ?? null,
9364
+ until_path: result.until_path ?? null,
9365
+ until_value: result.until_value ?? null,
9366
+ until_expected_value: result.until_expected_value ?? null,
9367
+ tap_count: result.tap_count ?? null,
9368
+ max_taps: result.max_taps ?? result.max_calls ?? null,
9369
+ interval_ms: result.interval_ms ?? null,
9370
+ timeout_ms: result.timeout_ms ?? null,
9371
+ reason: result.reason ?? result.error ?? null
9372
+ }));
9373
+ }
9351
9374
  function profileSetupKeyboardReceipts(results) {
9352
9375
  return results.filter((result) => ["press", "key_down", "key_up"].includes(profileSetupResultAction(result))).map((result) => ({
9353
9376
  action: profileSetupResultAction(result),
@@ -9523,6 +9546,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
9523
9546
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
9524
9547
  const tapReceipts = profileSetupTapReceipts(results);
9525
9548
  const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
9549
+ const tapUntilReceipts = profileSetupTapUntilReceipts(results);
9550
+ const tapUntilTapCounts = tapUntilReceipts.map((result) => typeof result.tap_count === "number" && Number.isFinite(result.tap_count) ? result.tap_count : void 0).filter((value) => value !== void 0);
9551
+ const sampledTapUntilReceipts = sampleProfileSetupSummaryItems(tapUntilReceipts, 8);
9526
9552
  const keyboardReceipts = profileSetupKeyboardReceipts(results);
9527
9553
  const sampledKeyboardReceipts = sampleProfileSetupSummaryItems(keyboardReceipts, 8);
9528
9554
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
@@ -9534,6 +9560,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
9534
9560
  selector: result.selector ?? null,
9535
9561
  frame_selector: result.frame_selector ?? null,
9536
9562
  text: compactProfileSetupSummaryText(result.text),
9563
+ ...result.fallback_to_tap === true ? { fallback_to_tap: true } : {},
9564
+ ...result.input_dispatch ? { input_dispatch: result.input_dispatch } : {},
9565
+ ...result.click_error ? { click_error: compactProfileSetupSummaryText(result.click_error) } : {},
9537
9566
  ...clickCount ? { click_count: clickCount } : {}
9538
9567
  };
9539
9568
  });
@@ -9592,6 +9621,10 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
9592
9621
  tap_total: tapReceipts.length,
9593
9622
  tap_truncated: tapReceipts.length > sampledTapReceipts.length,
9594
9623
  tap: sampledTapReceipts,
9624
+ tap_until_total: tapUntilReceipts.length,
9625
+ tap_until_tap_total: tapUntilTapCounts.reduce((sum, value) => sum + value, 0),
9626
+ tap_until_truncated: tapUntilReceipts.length > sampledTapUntilReceipts.length,
9627
+ tap_until: sampledTapUntilReceipts,
9595
9628
  keyboard_total: keyboardReceipts.length,
9596
9629
  keyboard_truncated: keyboardReceipts.length > sampledKeyboardReceipts.length,
9597
9630
  keyboard: sampledKeyboardReceipts,
@@ -9653,7 +9686,7 @@ function isSupportedCheckType(value) {
9653
9686
  }
9654
9687
  function normalizeSetupActionType(value, index) {
9655
9688
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
9656
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "pointer_tap" || normalizedInput === "touch_tap" || normalizedInput === "canvas_tap" ? "tap" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "keyboard_down" || normalizedInput === "key_down" || normalizedInput === "keydown" || normalizedInput === "press_down" ? "key_down" : normalizedInput === "keyboard_up" || normalizedInput === "key_up" || normalizedInput === "keyup" || normalizedInput === "press_up" || normalizedInput === "release_key" || normalizedInput === "key_release" ? "key_up" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
9689
+ const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "pointer_tap" || normalizedInput === "touch_tap" || normalizedInput === "canvas_tap" ? "tap" : normalizedInput === "tap_until" || normalizedInput === "pointer_tap_until" || normalizedInput === "touch_tap_until" || normalizedInput === "canvas_tap_until" || normalizedInput === "tap_repeat_until" || normalizedInput === "repeat_tap_until" ? "tap_until" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "keyboard_down" || normalizedInput === "key_down" || normalizedInput === "keydown" || normalizedInput === "press_down" ? "key_down" : normalizedInput === "keyboard_up" || normalizedInput === "key_up" || normalizedInput === "keyup" || normalizedInput === "press_up" || normalizedInput === "release_key" || normalizedInput === "key_release" ? "key_up" : normalizedInput === "set_slider_value" || normalizedInput === "slider_value" || normalizedInput === "set_slider" || normalizedInput === "set_range" || normalizedInput === "range_value" || normalizedInput === "range_input" || normalizedInput === "set_range_input" ? "set_range_value" : normalizedInput === "deterministic_runtime" || normalizedInput === "mock_runtime" || normalizedInput === "mock_random" || normalizedInput === "mock_random_queue" || normalizedInput === "seed_random_queue" || normalizedInput === "set_random_queue" || normalizedInput === "mock_clock" || normalizedInput === "set_mock_clock" || normalizedInput === "set_runtime_determinism" || normalizedInput === "runtime_determinism" ? "deterministic_runtime" : normalizedInput === "canvas_hash" || normalizedInput === "capture_canvas_hash" || normalizedInput === "capture_canvas_signature" || normalizedInput === "canvas_state_signature" ? "canvas_signature" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput === "window_call_until" || normalizedInput === "call_until" || normalizedInput === "window_call_repeat_until" || normalizedInput === "repeat_window_call_until" ? "window_call_until" : normalizedInput === "window_evaluate" || normalizedInput === "browser_eval" || normalizedInput === "browser_evaluate" || normalizedInput === "evaluate_script" || normalizedInput === "profile_script" ? "window_eval" : normalizedInput;
9657
9690
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
9658
9691
  return normalized;
9659
9692
  }
@@ -9735,8 +9768,8 @@ function normalizeSetupActionCoordinateMode(value, index) {
9735
9768
  }
9736
9769
  function normalizeSetupActionPointerType(value, type, index) {
9737
9770
  if (value === void 0 || value === null || value === "") return void 0;
9738
- if (type !== "drag" && type !== "tap") {
9739
- throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag/tap actions.`);
9771
+ if (type !== "drag" && type !== "tap" && type !== "tap_until") {
9772
+ throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag/tap/tap_until actions.`);
9740
9773
  }
9741
9774
  const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
9742
9775
  if (normalized === "mouse") return "mouse";
@@ -9815,11 +9848,11 @@ function normalizeSetupAction(input, index) {
9815
9848
  if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
9816
9849
  throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
9817
9850
  }
9818
- if ((type === "click" || type === "tap" || type === "drag" || type === "fill" || type === "set_input_value" || type === "set_range_value" || type === "canvas_signature" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
9851
+ if ((type === "click" || type === "tap" || type === "tap_until" || type === "drag" || type === "fill" || type === "set_input_value" || type === "set_range_value" || type === "canvas_signature" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
9819
9852
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
9820
9853
  }
9821
- const fromX = type === "click" || type === "tap" ? numberValue3(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue3(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
9822
- const fromY = type === "click" || type === "tap" ? numberValue3(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue3(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
9854
+ const fromX = type === "click" || type === "tap" || type === "tap_until" ? numberValue3(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue3(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
9855
+ const fromY = type === "click" || type === "tap" || type === "tap_until" ? numberValue3(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue3(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
9823
9856
  const toX = numberValue3(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
9824
9857
  const toY = numberValue3(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
9825
9858
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
@@ -9844,18 +9877,18 @@ function normalizeSetupAction(input, index) {
9844
9877
  }
9845
9878
  }
9846
9879
  }
9847
- if (type === "tap") {
9880
+ if (type === "tap" || type === "tap_until") {
9848
9881
  const hasTapCoordinate = fromX !== void 0 || fromY !== void 0;
9849
9882
  if (hasTapCoordinate && (fromX === void 0 || fromY === void 0)) {
9850
- throw new Error(`target.setup_actions[${index}] tap coordinates require both x and y.`);
9883
+ throw new Error(`target.setup_actions[${index}] ${type} coordinates require both x and y.`);
9851
9884
  }
9852
9885
  if (hasTapCoordinate && fromX !== void 0 && fromY !== void 0) {
9853
9886
  const tapCoordinates = [fromX, fromY];
9854
9887
  if (coordinateMode === "ratio" && tapCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
9855
- throw new Error(`target.setup_actions[${index}] tap ratio coordinates must be between 0 and 1.`);
9888
+ throw new Error(`target.setup_actions[${index}] ${type} ratio coordinates must be between 0 and 1.`);
9856
9889
  }
9857
9890
  if ((coordinateMode === void 0 || coordinateMode === "pixels") && tapCoordinates.some((value2) => value2 < 0)) {
9858
- throw new Error(`target.setup_actions[${index}] tap pixel coordinates must be non-negative.`);
9891
+ throw new Error(`target.setup_actions[${index}] ${type} pixel coordinates must be non-negative.`);
9859
9892
  }
9860
9893
  }
9861
9894
  }
@@ -9961,7 +9994,7 @@ function normalizeSetupAction(input, index) {
9961
9994
  const captureReturn = input.capture_return === false || input.captureReturn === false || input.include_return === false || input.includeReturn === false || input.omit_return === true || input.omitReturn === true ? false : void 0;
9962
9995
  const untilPath = stringFromOwn(input, "until_path", "untilPath", "until_state_path", "untilStatePath", "until_window_path", "untilWindowPath", "until");
9963
9996
  const hasUntilExpectedValue = hasOwn(input, "until_expected_value") || hasOwn(input, "untilExpectedValue") || hasOwn(input, "until_expected") || hasOwn(input, "untilExpected") || hasOwn(input, "until_value") || hasOwn(input, "untilValue") || hasOwn(input, "expected_value") || hasOwn(input, "expectedValue") || hasOwn(input, "expected");
9964
- if (type === "window_call_until") {
9997
+ if (type === "window_call_until" || type === "tap_until") {
9965
9998
  if (!untilPath) {
9966
9999
  throw new Error(`target.setup_actions[${index}] ${type} requires until_path.`);
9967
10000
  }
@@ -9969,12 +10002,12 @@ function normalizeSetupAction(input, index) {
9969
10002
  throw new Error(`target.setup_actions[${index}] ${type} requires until_expected_value.`);
9970
10003
  }
9971
10004
  }
9972
- const maxCalls = numberValue3(valueFromOwn(input, "max_calls", "maxCalls", "max_attempts", "maxAttempts", "attempts"));
9973
- if (type === "window_call_until" && (maxCalls === void 0 || !Number.isInteger(maxCalls) || maxCalls < 1 || maxCalls > 100)) {
10005
+ const maxCalls = numberValue3(valueFromOwn(input, "max_calls", "maxCalls", "max_attempts", "maxAttempts", "attempts", "max_taps", "maxTaps", "tap_limit", "tapLimit"));
10006
+ if ((type === "window_call_until" || type === "tap_until") && (maxCalls === void 0 || !Number.isInteger(maxCalls) || maxCalls < 1 || maxCalls > 100)) {
9974
10007
  throw new Error(`target.setup_actions[${index}].max_calls must be an integer from 1 to 100.`);
9975
10008
  }
9976
10009
  const intervalMs = numberValue3(valueFromOwn(input, "interval_ms", "intervalMs", "poll_ms", "pollMs", "call_interval_ms", "callIntervalMs"));
9977
- if (type === "window_call_until" && intervalMs !== void 0 && (!Number.isInteger(intervalMs) || intervalMs < 0 || intervalMs > 5e3)) {
10010
+ if ((type === "window_call_until" || type === "tap_until") && intervalMs !== void 0 && (!Number.isInteger(intervalMs) || intervalMs < 0 || intervalMs > 5e3)) {
9978
10011
  throw new Error(`target.setup_actions[${index}].interval_ms must be an integer from 0 to 5000.`);
9979
10012
  }
9980
10013
  const steps = numberValue3(input.steps);
@@ -13240,6 +13273,30 @@ function profileSetupTapReceipts(results) {
13240
13273
  reason: result.reason || result.error || null,
13241
13274
  }));
13242
13275
  }
13276
+ function profileSetupTapUntilReceipts(results) {
13277
+ return (results || [])
13278
+ .filter((result) => result && profileSetupResultAction(result) === "tap_until")
13279
+ .map((result) => ({
13280
+ ordinal: result.ordinal ?? null,
13281
+ ok: result.ok !== false,
13282
+ selector: result.selector ?? null,
13283
+ frame_selector: result.frame_selector ?? null,
13284
+ pointer_type: result.pointer_type ?? null,
13285
+ input_dispatch: result.input_dispatch ?? null,
13286
+ coordinate_mode: result.coordinate_mode ?? null,
13287
+ x: result.x ?? null,
13288
+ y: result.y ?? null,
13289
+ duration_ms: result.duration_ms ?? null,
13290
+ until_path: result.until_path ?? null,
13291
+ until_value: result.until_value ?? null,
13292
+ until_expected_value: result.until_expected_value ?? null,
13293
+ tap_count: result.tap_count ?? null,
13294
+ max_taps: result.max_taps ?? result.max_calls ?? null,
13295
+ interval_ms: result.interval_ms ?? null,
13296
+ timeout_ms: result.timeout_ms ?? null,
13297
+ reason: result.reason || result.error || null,
13298
+ }));
13299
+ }
13243
13300
  function profileSetupKeyboardReceipts(results) {
13244
13301
  return (results || [])
13245
13302
  .filter((result) => result && ["press", "key_down", "key_up"].includes(profileSetupResultAction(result)))
@@ -13442,6 +13499,11 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
13442
13499
  const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
13443
13500
  const tapReceipts = profileSetupTapReceipts(results);
13444
13501
  const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
13502
+ const tapUntilReceipts = profileSetupTapUntilReceipts(results);
13503
+ const tapUntilTapCounts = tapUntilReceipts
13504
+ .map((result) => typeof result.tap_count === "number" && Number.isFinite(result.tap_count) ? result.tap_count : undefined)
13505
+ .filter((value) => value !== undefined);
13506
+ const sampledTapUntilReceipts = sampleProfileSetupSummaryItems(tapUntilReceipts, 8);
13445
13507
  const keyboardReceipts = profileSetupKeyboardReceipts(results);
13446
13508
  const sampledKeyboardReceipts = sampleProfileSetupSummaryItems(keyboardReceipts, 8);
13447
13509
  const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
@@ -13455,6 +13517,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
13455
13517
  selector: result.selector ?? null,
13456
13518
  frame_selector: result.frame_selector ?? null,
13457
13519
  text: compactProfileSetupSummaryText(result.text),
13520
+ ...(result.fallback_to_tap === true ? { fallback_to_tap: true } : {}),
13521
+ ...(result.input_dispatch ? { input_dispatch: result.input_dispatch } : {}),
13522
+ ...(result.click_error ? { click_error: compactProfileSetupSummaryText(result.click_error) } : {}),
13458
13523
  ...(clickCount ? { click_count: clickCount } : {}),
13459
13524
  };
13460
13525
  });
@@ -13521,6 +13586,10 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
13521
13586
  tap_total: tapReceipts.length,
13522
13587
  tap_truncated: tapReceipts.length > sampledTapReceipts.length,
13523
13588
  tap: sampledTapReceipts,
13589
+ tap_until_total: tapUntilReceipts.length,
13590
+ tap_until_tap_total: tapUntilTapCounts.reduce((sum, value) => sum + value, 0),
13591
+ tap_until_truncated: tapUntilReceipts.length > sampledTapUntilReceipts.length,
13592
+ tap_until: sampledTapUntilReceipts,
13524
13593
  keyboard_total: keyboardReceipts.length,
13525
13594
  keyboard_truncated: keyboardReceipts.length > sampledKeyboardReceipts.length,
13526
13595
  keyboard: sampledKeyboardReceipts,
@@ -14467,6 +14536,108 @@ async function waitForAnyVisibleSelector(context, selector, timeout) {
14467
14536
  }
14468
14537
  throw new Error("No visible match for selector " + selector + ": " + lastReason);
14469
14538
  }
14539
+ async function dispatchSetupTapPoint(point, pointerType, durationMs) {
14540
+ if (pointerType === "touch" || pointerType === "pen") {
14541
+ const client = await page.context().newCDPSession(page);
14542
+ try {
14543
+ if (pointerType === "touch") {
14544
+ const touchPoint = {
14545
+ x: point.x,
14546
+ y: point.y,
14547
+ radiusX: 1,
14548
+ radiusY: 1,
14549
+ force: 1,
14550
+ id: 11,
14551
+ };
14552
+ await client.send("Input.dispatchTouchEvent", {
14553
+ type: "touchStart",
14554
+ touchPoints: [touchPoint],
14555
+ });
14556
+ if (durationMs) await page.waitForTimeout(durationMs);
14557
+ await client.send("Input.dispatchTouchEvent", {
14558
+ type: "touchEnd",
14559
+ touchPoints: [],
14560
+ });
14561
+ } else {
14562
+ await client.send("Input.dispatchMouseEvent", {
14563
+ type: "mousePressed",
14564
+ x: point.x,
14565
+ y: point.y,
14566
+ button: "left",
14567
+ buttons: 1,
14568
+ clickCount: 1,
14569
+ pointerType: "pen",
14570
+ });
14571
+ if (durationMs) await page.waitForTimeout(durationMs);
14572
+ await client.send("Input.dispatchMouseEvent", {
14573
+ type: "mouseReleased",
14574
+ x: point.x,
14575
+ y: point.y,
14576
+ button: "left",
14577
+ buttons: 0,
14578
+ clickCount: 1,
14579
+ pointerType: "pen",
14580
+ });
14581
+ }
14582
+ } finally {
14583
+ await client.detach().catch(() => {});
14584
+ }
14585
+ } else {
14586
+ await page.mouse.click(point.x, point.y);
14587
+ }
14588
+ }
14589
+ async function resolveSetupTapTarget(action, base, scope, timeout) {
14590
+ const locator = scope.context.locator(action.selector);
14591
+ const count = await locator.count();
14592
+ if (!count) return { result: { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count } };
14593
+ const targetIndex = Number.isInteger(action.index) ? action.index : 0;
14594
+ if (targetIndex < 0 || targetIndex >= count) return { result: { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex } };
14595
+ const target = locator.nth(targetIndex);
14596
+ await target.waitFor({ state: "visible", timeout });
14597
+ const box = await target.boundingBox();
14598
+ if (!box) return { result: { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex } };
14599
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
14600
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
14601
+ const hasTapPosition = fromX !== undefined || fromY !== undefined;
14602
+ if (hasTapPosition && (fromX === undefined || fromY === undefined)) return { result: { ...base, ...setupScopeEvidence(scope), reason: "missing_tap_coordinates", count, target_index: targetIndex } };
14603
+ const mode = String(action.coordinate_mode || action.coordinateMode || (hasTapPosition ? "pixels" : "ratio")).trim();
14604
+ if (hasTapPosition && mode === "ratio" && [fromX, fromY].some((value) => value < 0 || value > 1)) return { result: { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex } };
14605
+ if (hasTapPosition && mode !== "ratio" && [fromX, fromY].some((value) => value < 0)) return { result: { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex } };
14606
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
14607
+ const localX = hasTapPosition && fromX !== undefined ? fromX : 0.5;
14608
+ const localY = hasTapPosition && fromY !== undefined ? fromY : 0.5;
14609
+ const point = {
14610
+ x: box.x + coordinate(localX, box.width),
14611
+ y: box.y + coordinate(localY, box.height),
14612
+ };
14613
+ const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
14614
+ const pointerType = String(action.pointer_type || action.pointerType || "touch").trim().toLowerCase();
14615
+ return {
14616
+ target: {
14617
+ count,
14618
+ targetIndex,
14619
+ point,
14620
+ mode,
14621
+ fromX,
14622
+ fromY,
14623
+ hasTapPosition,
14624
+ pointerType,
14625
+ durationMs,
14626
+ },
14627
+ };
14628
+ }
14629
+ function setupTapTargetEvidence(tapTarget) {
14630
+ return {
14631
+ count: tapTarget.count,
14632
+ target_index: tapTarget.targetIndex,
14633
+ coordinate_mode: tapTarget.hasTapPosition ? tapTarget.mode : undefined,
14634
+ x: tapTarget.hasTapPosition ? tapTarget.fromX : undefined,
14635
+ y: tapTarget.hasTapPosition ? tapTarget.fromY : undefined,
14636
+ pointer_type: tapTarget.pointerType,
14637
+ input_dispatch: tapTarget.pointerType === "touch" || tapTarget.pointerType === "pen" ? "cdp" : "playwright_mouse",
14638
+ duration_ms: tapTarget.durationMs || undefined,
14639
+ };
14640
+ }
14470
14641
  function setupHasOwn(action, key) {
14471
14642
  return Boolean(action) && Object.keys(action).includes(key);
14472
14643
  }
@@ -15069,91 +15240,108 @@ async function executeSetupAction(action, ordinal, viewport) {
15069
15240
  if (type === "tap") {
15070
15241
  const scope = await setupActionScope(action, timeout);
15071
15242
  if (!scope.ok) return setupScopeFailure(base, scope);
15072
- const locator = scope.context.locator(action.selector);
15073
- const count = await locator.count();
15074
- if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
15075
- const targetIndex = Number.isInteger(action.index) ? action.index : 0;
15076
- if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
15077
- const target = locator.nth(targetIndex);
15078
- await target.waitFor({ state: "visible", timeout });
15079
- const box = await target.boundingBox();
15080
- if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
15081
- const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
15082
- const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
15083
- const hasTapPosition = fromX !== undefined || fromY !== undefined;
15084
- if (hasTapPosition && (fromX === undefined || fromY === undefined)) return { ...base, ...setupScopeEvidence(scope), reason: "missing_tap_coordinates", count, target_index: targetIndex };
15085
- const mode = String(action.coordinate_mode || action.coordinateMode || (hasTapPosition ? "pixels" : "ratio")).trim();
15086
- if (hasTapPosition && mode === "ratio" && [fromX, fromY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
15087
- if (hasTapPosition && mode !== "ratio" && [fromX, fromY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
15088
- const coordinate = (value, size) => mode === "ratio" ? value * size : value;
15089
- const localX = hasTapPosition && fromX !== undefined ? fromX : 0.5;
15090
- const localY = hasTapPosition && fromY !== undefined ? fromY : 0.5;
15091
- const point = {
15092
- x: box.x + coordinate(localX, box.width),
15093
- y: box.y + coordinate(localY, box.height),
15243
+ const prepared = await resolveSetupTapTarget(action, base, scope, timeout);
15244
+ if (prepared.result) return prepared.result;
15245
+ await dispatchSetupTapPoint(prepared.target.point, prepared.target.pointerType, prepared.target.durationMs);
15246
+ return {
15247
+ ...base,
15248
+ ...setupScopeEvidence(scope),
15249
+ ok: true,
15250
+ ...setupTapTargetEvidence(prepared.target),
15094
15251
  };
15095
- const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
15096
- const pointerType = String(action.pointer_type || action.pointerType || "touch").trim().toLowerCase();
15097
- if (pointerType === "touch" || pointerType === "pen") {
15098
- const client = await page.context().newCDPSession(page);
15099
- try {
15100
- if (pointerType === "touch") {
15101
- const touchPoint = {
15102
- x: point.x,
15103
- y: point.y,
15104
- radiusX: 1,
15105
- radiusY: 1,
15106
- force: 1,
15107
- id: 11,
15108
- };
15109
- await client.send("Input.dispatchTouchEvent", {
15110
- type: "touchStart",
15111
- touchPoints: [touchPoint],
15112
- });
15113
- if (durationMs) await page.waitForTimeout(durationMs);
15114
- await client.send("Input.dispatchTouchEvent", {
15115
- type: "touchEnd",
15116
- touchPoints: [],
15117
- });
15118
- } else {
15119
- await client.send("Input.dispatchMouseEvent", {
15120
- type: "mousePressed",
15121
- x: point.x,
15122
- y: point.y,
15123
- button: "left",
15124
- buttons: 1,
15125
- clickCount: 1,
15126
- pointerType: "pen",
15127
- });
15128
- if (durationMs) await page.waitForTimeout(durationMs);
15129
- await client.send("Input.dispatchMouseEvent", {
15130
- type: "mouseReleased",
15131
- x: point.x,
15132
- y: point.y,
15133
- button: "left",
15134
- buttons: 0,
15135
- clickCount: 1,
15136
- pointerType: "pen",
15137
- });
15138
- }
15139
- } finally {
15140
- await client.detach().catch(() => {});
15252
+ }
15253
+ if (type === "tap_until") {
15254
+ const untilPath = String(action.until_path || action.untilPath || action.until_state_path || action.untilStatePath || action.until_window_path || action.untilWindowPath || action.until || "");
15255
+ const hasUntilExpected = setupHasOwn(action, "until_expected_value")
15256
+ || setupHasOwn(action, "untilExpectedValue")
15257
+ || setupHasOwn(action, "until_expected")
15258
+ || setupHasOwn(action, "untilExpected")
15259
+ || setupHasOwn(action, "until_value")
15260
+ || setupHasOwn(action, "untilValue")
15261
+ || setupHasOwn(action, "expected_value")
15262
+ || setupHasOwn(action, "expectedValue")
15263
+ || setupHasOwn(action, "expected");
15264
+ const untilExpected = setupHasOwn(action, "until_expected_value")
15265
+ ? action.until_expected_value
15266
+ : setupHasOwn(action, "untilExpectedValue")
15267
+ ? action.untilExpectedValue
15268
+ : setupHasOwn(action, "until_expected")
15269
+ ? action.until_expected
15270
+ : setupHasOwn(action, "untilExpected")
15271
+ ? action.untilExpected
15272
+ : setupHasOwn(action, "until_value")
15273
+ ? action.until_value
15274
+ : setupHasOwn(action, "untilValue")
15275
+ ? action.untilValue
15276
+ : setupHasOwn(action, "expected_value")
15277
+ ? action.expected_value
15278
+ : setupHasOwn(action, "expectedValue")
15279
+ ? action.expectedValue
15280
+ : action.expected;
15281
+ if (!untilPath) return { ...base, reason: "missing_until_path" };
15282
+ if (!hasUntilExpected) return { ...base, until_path: untilPath, reason: "missing_until_expected_value" };
15283
+ const maxTaps = Math.min(100, Math.max(1, Math.floor(setupNumber(action.max_taps ?? action.maxTaps ?? action.tap_limit ?? action.tapLimit ?? action.max_calls ?? action.maxCalls ?? action.max_attempts ?? action.maxAttempts ?? action.attempts, 1) || 1)));
15284
+ const intervalMs = Math.min(5000, Math.max(0, Math.floor(setupNumber(action.interval_ms ?? action.intervalMs ?? action.poll_ms ?? action.pollMs ?? action.tap_interval_ms ?? action.tapIntervalMs, 100) || 0)));
15285
+ const scope = await setupActionScope(action, timeout);
15286
+ if (!scope.ok) return setupScopeFailure(base, scope);
15287
+ const prepared = await resolveSetupTapTarget(action, base, scope, timeout);
15288
+ if (prepared.result) return prepared.result;
15289
+ const startedAt = Date.now();
15290
+ let tapCount = 0;
15291
+ let lastPredicateResult = await setupReadWindowValue(scope.context, untilPath);
15292
+ const targetEvidence = setupTapTargetEvidence(prepared.target);
15293
+ if (lastPredicateResult.ok && setupValuesEqual(lastPredicateResult.value, untilExpected)) {
15294
+ return {
15295
+ ...base,
15296
+ ...setupScopeEvidence(scope),
15297
+ ok: true,
15298
+ ...targetEvidence,
15299
+ until_path: untilPath,
15300
+ until_value: setupJsonValue(lastPredicateResult.value),
15301
+ until_expected_value: setupJsonValue(untilExpected),
15302
+ tap_count: tapCount,
15303
+ max_taps: maxTaps,
15304
+ max_calls: maxTaps,
15305
+ interval_ms: intervalMs,
15306
+ timeout_ms: timeout,
15307
+ };
15308
+ }
15309
+ while (tapCount < maxTaps && Date.now() - startedAt <= timeout) {
15310
+ await dispatchSetupTapPoint(prepared.target.point, prepared.target.pointerType, prepared.target.durationMs);
15311
+ tapCount += 1;
15312
+ lastPredicateResult = await setupReadWindowValue(scope.context, untilPath);
15313
+ if (lastPredicateResult.ok && setupValuesEqual(lastPredicateResult.value, untilExpected)) {
15314
+ return {
15315
+ ...base,
15316
+ ...setupScopeEvidence(scope),
15317
+ ok: true,
15318
+ ...targetEvidence,
15319
+ until_path: untilPath,
15320
+ until_value: setupJsonValue(lastPredicateResult.value),
15321
+ until_expected_value: setupJsonValue(untilExpected),
15322
+ tap_count: tapCount,
15323
+ max_taps: maxTaps,
15324
+ max_calls: maxTaps,
15325
+ interval_ms: intervalMs,
15326
+ timeout_ms: timeout,
15327
+ };
15141
15328
  }
15142
- } else {
15143
- await page.mouse.click(point.x, point.y);
15329
+ if (tapCount < maxTaps && intervalMs) await page.waitForTimeout(intervalMs);
15144
15330
  }
15145
15331
  return {
15146
15332
  ...base,
15147
15333
  ...setupScopeEvidence(scope),
15148
- ok: true,
15149
- count,
15150
- target_index: targetIndex,
15151
- coordinate_mode: hasTapPosition ? mode : undefined,
15152
- x: hasTapPosition ? fromX : undefined,
15153
- y: hasTapPosition ? fromY : undefined,
15154
- pointer_type: pointerType,
15155
- input_dispatch: pointerType === "touch" || pointerType === "pen" ? "cdp" : "playwright_mouse",
15156
- duration_ms: durationMs || undefined,
15334
+ ...targetEvidence,
15335
+ until_path: untilPath,
15336
+ until_value: setupJsonValue(lastPredicateResult?.value),
15337
+ until_expected_value: setupJsonValue(untilExpected),
15338
+ tap_count: tapCount,
15339
+ max_taps: maxTaps,
15340
+ max_calls: maxTaps,
15341
+ interval_ms: intervalMs,
15342
+ timeout_ms: timeout,
15343
+ reason: Date.now() - startedAt > timeout ? "timeout" : "until_condition_not_met",
15344
+ missing_part: lastPredicateResult?.missing_part || undefined,
15157
15345
  };
15158
15346
  }
15159
15347
  if (type === "drag") {
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  resolveRiddleProofProfileTimeoutSec,
63
63
  slugifyRiddleProofProfileName,
64
64
  summarizeRiddleProofProfileResult
65
- } from "./chunk-WUOU5RB4.js";
65
+ } from "./chunk-DL6UB4N6.js";
66
66
  import {
67
67
  DEFAULT_RIDDLE_API_BASE_URL,
68
68
  DEFAULT_RIDDLE_API_KEY_FILE,