@riddledc/riddle-proof 0.7.197 → 0.7.199
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -5
- package/dist/{chunk-EYLIXKE2.js → chunk-EXFYPLP2.js} +297 -93
- package/dist/cli.cjs +347 -96
- package/dist/cli.js +51 -4
- package/dist/index.cjs +297 -93
- package/dist/index.js +1 -1
- package/dist/profile.cjs +297 -93
- package/dist/profile.d.cts +2 -1
- package/dist/profile.d.ts +2 -1
- package/dist/profile.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -406,7 +406,7 @@ when body matching overrides sequence order.
|
|
|
406
406
|
`target.setup_actions` is optional. Use it when the meaningful proof surface
|
|
407
407
|
appears only after a picker, tab, login stub, storage seed, form fill,
|
|
408
408
|
transport control, or other bounded interaction. Supported setup actions are
|
|
409
|
-
`click`, `tap`, `drag`, `press`, `key_down`, `key_up`, `fill`, `set_input_value`, `set_range_value`,
|
|
409
|
+
`click`, `tap`, `tap_until`, `drag`, `press`, `key_down`, `key_up`, `fill`, `set_input_value`, `set_range_value`,
|
|
410
410
|
`deterministic_runtime`, `canvas_signature`, `assert_text_visible`, `assert_text_absent`,
|
|
411
411
|
`assert_selector_count`, `assert_window_value`, `assert_window_number`,
|
|
412
412
|
`local_storage`, `session_storage`, `clear_storage`, `clear_console`,
|
|
@@ -436,6 +436,15 @@ It requires `selector`, defaults to a touch tap at the target center, and
|
|
|
436
436
|
accepts `x` / `y` or `from_x` / `from_y` plus `coordinate_mode: "ratio"` for
|
|
437
437
|
element-relative coordinates. Set `pointer_type` to `mouse`, `touch`, or `pen`
|
|
438
438
|
when the proof must distinguish input modality.
|
|
439
|
+
Use `tap_until` for gameplay loops where the proof should tap a visible target
|
|
440
|
+
until a browser-state predicate is satisfied. It accepts the same selector,
|
|
441
|
+
coordinate, and pointer options as `tap`, plus `until_path`,
|
|
442
|
+
`until_expected_value`, `max_taps` / `max_calls` from 1 to 100, and optional
|
|
443
|
+
`interval_ms`. Set `tap_burst_size` from 1 to 100 when gameplay needs several
|
|
444
|
+
fast taps before the next predicate check. The action stops early when the
|
|
445
|
+
predicate matches and records one compact receipt with `tap_count`,
|
|
446
|
+
`condition_check_count`, final `until_value`, and input dispatch details, so
|
|
447
|
+
long canvas interaction loops do not need dozens of repeated setup actions.
|
|
439
448
|
Use `set_range_value` for HTML range inputs and React-controlled sliders. It
|
|
440
449
|
accepts aliases such as `set-slider-value`, requires `selector` plus `value`,
|
|
441
450
|
uses the native input value setter, dispatches bubbling `input` and `change`
|
|
@@ -531,10 +540,12 @@ actions stay visible. Click actions with `click_count` greater than `1` are
|
|
|
531
540
|
included in clicked-target evidence and rolled up as `click_count_action_total`
|
|
532
541
|
and `click_count_value_total`. Repeated selector runs such as long gameplay
|
|
533
542
|
button loops are also grouped as compact `same-selector` click-sequence
|
|
534
|
-
receipts with click totals and ordinals.
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
543
|
+
receipts with click totals and ordinals. `tap_until` actions are summarized as
|
|
544
|
+
one compact receipt with total taps, optional burst size, predicate-check count,
|
|
545
|
+
and the final predicate value, which is the preferred shape for long canvas
|
|
546
|
+
gameplay loops. Setup receipt sampling favors both first and last per-viewport
|
|
547
|
+
receipts before filling remaining space, so late lifecycle phases such as
|
|
548
|
+
terminal or restart remain visible in compact summaries.
|
|
538
549
|
|
|
539
550
|
`target.timeout_sec` is optional. Use it for known-heavy profile targets so the
|
|
540
551
|
profile carries its own hosted Riddle worker budget; an explicit CLI `--timeout`
|
|
@@ -45,6 +45,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
45
45
|
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
46
46
|
"click",
|
|
47
47
|
"tap",
|
|
48
|
+
"tap_until",
|
|
48
49
|
"drag",
|
|
49
50
|
"press",
|
|
50
51
|
"key_down",
|
|
@@ -615,6 +616,30 @@ function profileSetupTapReceipts(results) {
|
|
|
615
616
|
reason: result.reason ?? result.error ?? null
|
|
616
617
|
}));
|
|
617
618
|
}
|
|
619
|
+
function profileSetupTapUntilReceipts(results) {
|
|
620
|
+
return results.filter((result) => profileSetupResultAction(result) === "tap_until").map((result) => ({
|
|
621
|
+
ordinal: result.ordinal ?? null,
|
|
622
|
+
ok: result.ok !== false,
|
|
623
|
+
selector: result.selector ?? null,
|
|
624
|
+
frame_selector: result.frame_selector ?? null,
|
|
625
|
+
pointer_type: result.pointer_type ?? null,
|
|
626
|
+
input_dispatch: result.input_dispatch ?? null,
|
|
627
|
+
coordinate_mode: result.coordinate_mode ?? null,
|
|
628
|
+
x: result.x ?? null,
|
|
629
|
+
y: result.y ?? null,
|
|
630
|
+
duration_ms: result.duration_ms ?? null,
|
|
631
|
+
until_path: result.until_path ?? null,
|
|
632
|
+
until_value: result.until_value ?? null,
|
|
633
|
+
until_expected_value: result.until_expected_value ?? null,
|
|
634
|
+
tap_count: result.tap_count ?? null,
|
|
635
|
+
max_taps: result.max_taps ?? result.max_calls ?? null,
|
|
636
|
+
tap_burst_size: result.tap_burst_size ?? null,
|
|
637
|
+
condition_check_count: result.condition_check_count ?? null,
|
|
638
|
+
interval_ms: result.interval_ms ?? null,
|
|
639
|
+
timeout_ms: result.timeout_ms ?? null,
|
|
640
|
+
reason: result.reason ?? result.error ?? null
|
|
641
|
+
}));
|
|
642
|
+
}
|
|
618
643
|
function profileSetupKeyboardReceipts(results) {
|
|
619
644
|
return results.filter((result) => ["press", "key_down", "key_up"].includes(profileSetupResultAction(result))).map((result) => ({
|
|
620
645
|
action: profileSetupResultAction(result),
|
|
@@ -790,6 +815,9 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
|
|
|
790
815
|
const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
|
|
791
816
|
const tapReceipts = profileSetupTapReceipts(results);
|
|
792
817
|
const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
|
|
818
|
+
const tapUntilReceipts = profileSetupTapUntilReceipts(results);
|
|
819
|
+
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);
|
|
820
|
+
const sampledTapUntilReceipts = sampleProfileSetupSummaryItems(tapUntilReceipts, 8);
|
|
793
821
|
const keyboardReceipts = profileSetupKeyboardReceipts(results);
|
|
794
822
|
const sampledKeyboardReceipts = sampleProfileSetupSummaryItems(keyboardReceipts, 8);
|
|
795
823
|
const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
|
|
@@ -862,6 +890,10 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
|
|
|
862
890
|
tap_total: tapReceipts.length,
|
|
863
891
|
tap_truncated: tapReceipts.length > sampledTapReceipts.length,
|
|
864
892
|
tap: sampledTapReceipts,
|
|
893
|
+
tap_until_total: tapUntilReceipts.length,
|
|
894
|
+
tap_until_tap_total: tapUntilTapCounts.reduce((sum, value) => sum + value, 0),
|
|
895
|
+
tap_until_truncated: tapUntilReceipts.length > sampledTapUntilReceipts.length,
|
|
896
|
+
tap_until: sampledTapUntilReceipts,
|
|
865
897
|
keyboard_total: keyboardReceipts.length,
|
|
866
898
|
keyboard_truncated: keyboardReceipts.length > sampledKeyboardReceipts.length,
|
|
867
899
|
keyboard: sampledKeyboardReceipts,
|
|
@@ -923,7 +955,7 @@ function isSupportedCheckType(value) {
|
|
|
923
955
|
}
|
|
924
956
|
function normalizeSetupActionType(value, index) {
|
|
925
957
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
926
|
-
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;
|
|
958
|
+
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;
|
|
927
959
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
928
960
|
return normalized;
|
|
929
961
|
}
|
|
@@ -1005,8 +1037,8 @@ function normalizeSetupActionCoordinateMode(value, index) {
|
|
|
1005
1037
|
}
|
|
1006
1038
|
function normalizeSetupActionPointerType(value, type, index) {
|
|
1007
1039
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
1008
|
-
if (type !== "drag" && type !== "tap") {
|
|
1009
|
-
throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag/tap actions.`);
|
|
1040
|
+
if (type !== "drag" && type !== "tap" && type !== "tap_until") {
|
|
1041
|
+
throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag/tap/tap_until actions.`);
|
|
1010
1042
|
}
|
|
1011
1043
|
const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
|
|
1012
1044
|
if (normalized === "mouse") return "mouse";
|
|
@@ -1085,11 +1117,11 @@ function normalizeSetupAction(input, index) {
|
|
|
1085
1117
|
if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
|
|
1086
1118
|
throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
|
|
1087
1119
|
}
|
|
1088
|
-
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) {
|
|
1120
|
+
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) {
|
|
1089
1121
|
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
1090
1122
|
}
|
|
1091
|
-
const fromX = type === "click" || type === "tap" ? numberValue(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
|
|
1092
|
-
const fromY = type === "click" || type === "tap" ? numberValue(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
|
|
1123
|
+
const fromX = type === "click" || type === "tap" || type === "tap_until" ? numberValue(valueFromOwn(input, "from_x", "fromX", "x", "click_x", "clickX", "start_x", "startX", "x1")) : numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
|
|
1124
|
+
const fromY = type === "click" || type === "tap" || type === "tap_until" ? numberValue(valueFromOwn(input, "from_y", "fromY", "y", "click_y", "clickY", "start_y", "startY", "y1")) : numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
|
|
1093
1125
|
const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
|
|
1094
1126
|
const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
|
|
1095
1127
|
const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
|
|
@@ -1114,18 +1146,18 @@ function normalizeSetupAction(input, index) {
|
|
|
1114
1146
|
}
|
|
1115
1147
|
}
|
|
1116
1148
|
}
|
|
1117
|
-
if (type === "tap") {
|
|
1149
|
+
if (type === "tap" || type === "tap_until") {
|
|
1118
1150
|
const hasTapCoordinate = fromX !== void 0 || fromY !== void 0;
|
|
1119
1151
|
if (hasTapCoordinate && (fromX === void 0 || fromY === void 0)) {
|
|
1120
|
-
throw new Error(`target.setup_actions[${index}]
|
|
1152
|
+
throw new Error(`target.setup_actions[${index}] ${type} coordinates require both x and y.`);
|
|
1121
1153
|
}
|
|
1122
1154
|
if (hasTapCoordinate && fromX !== void 0 && fromY !== void 0) {
|
|
1123
1155
|
const tapCoordinates = [fromX, fromY];
|
|
1124
1156
|
if (coordinateMode === "ratio" && tapCoordinates.some((value2) => value2 < 0 || value2 > 1)) {
|
|
1125
|
-
throw new Error(`target.setup_actions[${index}]
|
|
1157
|
+
throw new Error(`target.setup_actions[${index}] ${type} ratio coordinates must be between 0 and 1.`);
|
|
1126
1158
|
}
|
|
1127
1159
|
if ((coordinateMode === void 0 || coordinateMode === "pixels") && tapCoordinates.some((value2) => value2 < 0)) {
|
|
1128
|
-
throw new Error(`target.setup_actions[${index}]
|
|
1160
|
+
throw new Error(`target.setup_actions[${index}] ${type} pixel coordinates must be non-negative.`);
|
|
1129
1161
|
}
|
|
1130
1162
|
}
|
|
1131
1163
|
}
|
|
@@ -1231,7 +1263,7 @@ function normalizeSetupAction(input, index) {
|
|
|
1231
1263
|
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;
|
|
1232
1264
|
const untilPath = stringFromOwn(input, "until_path", "untilPath", "until_state_path", "untilStatePath", "until_window_path", "untilWindowPath", "until");
|
|
1233
1265
|
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");
|
|
1234
|
-
if (type === "window_call_until") {
|
|
1266
|
+
if (type === "window_call_until" || type === "tap_until") {
|
|
1235
1267
|
if (!untilPath) {
|
|
1236
1268
|
throw new Error(`target.setup_actions[${index}] ${type} requires until_path.`);
|
|
1237
1269
|
}
|
|
@@ -1239,12 +1271,16 @@ function normalizeSetupAction(input, index) {
|
|
|
1239
1271
|
throw new Error(`target.setup_actions[${index}] ${type} requires until_expected_value.`);
|
|
1240
1272
|
}
|
|
1241
1273
|
}
|
|
1242
|
-
const maxCalls = numberValue(valueFromOwn(input, "max_calls", "maxCalls", "max_attempts", "maxAttempts", "attempts"));
|
|
1243
|
-
if (type === "window_call_until" && (maxCalls === void 0 || !Number.isInteger(maxCalls) || maxCalls < 1 || maxCalls > 100)) {
|
|
1274
|
+
const maxCalls = numberValue(valueFromOwn(input, "max_calls", "maxCalls", "max_attempts", "maxAttempts", "attempts", "max_taps", "maxTaps", "tap_limit", "tapLimit"));
|
|
1275
|
+
if ((type === "window_call_until" || type === "tap_until") && (maxCalls === void 0 || !Number.isInteger(maxCalls) || maxCalls < 1 || maxCalls > 100)) {
|
|
1244
1276
|
throw new Error(`target.setup_actions[${index}].max_calls must be an integer from 1 to 100.`);
|
|
1245
1277
|
}
|
|
1278
|
+
const tapBurstSize = type === "tap_until" ? numberValue(valueFromOwn(input, "tap_burst_size", "tapBurstSize", "burst_size", "burstSize", "check_every_taps", "checkEveryTaps", "predicate_interval_taps", "predicateIntervalTaps")) : void 0;
|
|
1279
|
+
if (type === "tap_until" && tapBurstSize !== void 0 && (!Number.isInteger(tapBurstSize) || tapBurstSize < 1 || tapBurstSize > 100)) {
|
|
1280
|
+
throw new Error(`target.setup_actions[${index}].tap_burst_size must be an integer from 1 to 100.`);
|
|
1281
|
+
}
|
|
1246
1282
|
const intervalMs = numberValue(valueFromOwn(input, "interval_ms", "intervalMs", "poll_ms", "pollMs", "call_interval_ms", "callIntervalMs"));
|
|
1247
|
-
if (type === "window_call_until" && intervalMs !== void 0 && (!Number.isInteger(intervalMs) || intervalMs < 0 || intervalMs > 5e3)) {
|
|
1283
|
+
if ((type === "window_call_until" || type === "tap_until") && intervalMs !== void 0 && (!Number.isInteger(intervalMs) || intervalMs < 0 || intervalMs > 5e3)) {
|
|
1248
1284
|
throw new Error(`target.setup_actions[${index}].interval_ms must be an integer from 0 to 5000.`);
|
|
1249
1285
|
}
|
|
1250
1286
|
const steps = numberValue(input.steps);
|
|
@@ -1290,6 +1326,7 @@ function normalizeSetupAction(input, index) {
|
|
|
1290
1326
|
until_path: untilPath,
|
|
1291
1327
|
until_expected_value: hasUntilExpectedValue ? toJsonValue(valueFromOwn(input, "until_expected_value", "untilExpectedValue", "until_expected", "untilExpected", "until_value", "untilValue", "expected_value", "expectedValue", "expected")) : void 0,
|
|
1292
1328
|
max_calls: maxCalls,
|
|
1329
|
+
tap_burst_size: tapBurstSize,
|
|
1293
1330
|
interval_ms: intervalMs,
|
|
1294
1331
|
expected_value: hasExpectedValue ? toJsonValue(rawExpectedValue) : void 0,
|
|
1295
1332
|
min_value: minValue,
|
|
@@ -4510,6 +4547,32 @@ function profileSetupTapReceipts(results) {
|
|
|
4510
4547
|
reason: result.reason || result.error || null,
|
|
4511
4548
|
}));
|
|
4512
4549
|
}
|
|
4550
|
+
function profileSetupTapUntilReceipts(results) {
|
|
4551
|
+
return (results || [])
|
|
4552
|
+
.filter((result) => result && profileSetupResultAction(result) === "tap_until")
|
|
4553
|
+
.map((result) => ({
|
|
4554
|
+
ordinal: result.ordinal ?? null,
|
|
4555
|
+
ok: result.ok !== false,
|
|
4556
|
+
selector: result.selector ?? null,
|
|
4557
|
+
frame_selector: result.frame_selector ?? null,
|
|
4558
|
+
pointer_type: result.pointer_type ?? null,
|
|
4559
|
+
input_dispatch: result.input_dispatch ?? null,
|
|
4560
|
+
coordinate_mode: result.coordinate_mode ?? null,
|
|
4561
|
+
x: result.x ?? null,
|
|
4562
|
+
y: result.y ?? null,
|
|
4563
|
+
duration_ms: result.duration_ms ?? null,
|
|
4564
|
+
until_path: result.until_path ?? null,
|
|
4565
|
+
until_value: result.until_value ?? null,
|
|
4566
|
+
until_expected_value: result.until_expected_value ?? null,
|
|
4567
|
+
tap_count: result.tap_count ?? null,
|
|
4568
|
+
max_taps: result.max_taps ?? result.max_calls ?? null,
|
|
4569
|
+
tap_burst_size: result.tap_burst_size ?? null,
|
|
4570
|
+
condition_check_count: result.condition_check_count ?? null,
|
|
4571
|
+
interval_ms: result.interval_ms ?? null,
|
|
4572
|
+
timeout_ms: result.timeout_ms ?? null,
|
|
4573
|
+
reason: result.reason || result.error || null,
|
|
4574
|
+
}));
|
|
4575
|
+
}
|
|
4513
4576
|
function profileSetupKeyboardReceipts(results) {
|
|
4514
4577
|
return (results || [])
|
|
4515
4578
|
.filter((result) => result && ["press", "key_down", "key_up"].includes(profileSetupResultAction(result)))
|
|
@@ -4712,6 +4775,11 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
4712
4775
|
const sampledDragReceipts = sampleProfileSetupSummaryItems(dragReceipts, 8);
|
|
4713
4776
|
const tapReceipts = profileSetupTapReceipts(results);
|
|
4714
4777
|
const sampledTapReceipts = sampleProfileSetupSummaryItems(tapReceipts, 8);
|
|
4778
|
+
const tapUntilReceipts = profileSetupTapUntilReceipts(results);
|
|
4779
|
+
const tapUntilTapCounts = tapUntilReceipts
|
|
4780
|
+
.map((result) => typeof result.tap_count === "number" && Number.isFinite(result.tap_count) ? result.tap_count : undefined)
|
|
4781
|
+
.filter((value) => value !== undefined);
|
|
4782
|
+
const sampledTapUntilReceipts = sampleProfileSetupSummaryItems(tapUntilReceipts, 8);
|
|
4715
4783
|
const keyboardReceipts = profileSetupKeyboardReceipts(results);
|
|
4716
4784
|
const sampledKeyboardReceipts = sampleProfileSetupSummaryItems(keyboardReceipts, 8);
|
|
4717
4785
|
const canvasSignatureReceipts = profileSetupCanvasSignatureReceipts(results);
|
|
@@ -4794,6 +4862,10 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
4794
4862
|
tap_total: tapReceipts.length,
|
|
4795
4863
|
tap_truncated: tapReceipts.length > sampledTapReceipts.length,
|
|
4796
4864
|
tap: sampledTapReceipts,
|
|
4865
|
+
tap_until_total: tapUntilReceipts.length,
|
|
4866
|
+
tap_until_tap_total: tapUntilTapCounts.reduce((sum, value) => sum + value, 0),
|
|
4867
|
+
tap_until_truncated: tapUntilReceipts.length > sampledTapUntilReceipts.length,
|
|
4868
|
+
tap_until: sampledTapUntilReceipts,
|
|
4797
4869
|
keyboard_total: keyboardReceipts.length,
|
|
4798
4870
|
keyboard_truncated: keyboardReceipts.length > sampledKeyboardReceipts.length,
|
|
4799
4871
|
keyboard: sampledKeyboardReceipts,
|
|
@@ -5740,6 +5812,108 @@ async function waitForAnyVisibleSelector(context, selector, timeout) {
|
|
|
5740
5812
|
}
|
|
5741
5813
|
throw new Error("No visible match for selector " + selector + ": " + lastReason);
|
|
5742
5814
|
}
|
|
5815
|
+
async function dispatchSetupTapPoint(point, pointerType, durationMs) {
|
|
5816
|
+
if (pointerType === "touch" || pointerType === "pen") {
|
|
5817
|
+
const client = await page.context().newCDPSession(page);
|
|
5818
|
+
try {
|
|
5819
|
+
if (pointerType === "touch") {
|
|
5820
|
+
const touchPoint = {
|
|
5821
|
+
x: point.x,
|
|
5822
|
+
y: point.y,
|
|
5823
|
+
radiusX: 1,
|
|
5824
|
+
radiusY: 1,
|
|
5825
|
+
force: 1,
|
|
5826
|
+
id: 11,
|
|
5827
|
+
};
|
|
5828
|
+
await client.send("Input.dispatchTouchEvent", {
|
|
5829
|
+
type: "touchStart",
|
|
5830
|
+
touchPoints: [touchPoint],
|
|
5831
|
+
});
|
|
5832
|
+
if (durationMs) await page.waitForTimeout(durationMs);
|
|
5833
|
+
await client.send("Input.dispatchTouchEvent", {
|
|
5834
|
+
type: "touchEnd",
|
|
5835
|
+
touchPoints: [],
|
|
5836
|
+
});
|
|
5837
|
+
} else {
|
|
5838
|
+
await client.send("Input.dispatchMouseEvent", {
|
|
5839
|
+
type: "mousePressed",
|
|
5840
|
+
x: point.x,
|
|
5841
|
+
y: point.y,
|
|
5842
|
+
button: "left",
|
|
5843
|
+
buttons: 1,
|
|
5844
|
+
clickCount: 1,
|
|
5845
|
+
pointerType: "pen",
|
|
5846
|
+
});
|
|
5847
|
+
if (durationMs) await page.waitForTimeout(durationMs);
|
|
5848
|
+
await client.send("Input.dispatchMouseEvent", {
|
|
5849
|
+
type: "mouseReleased",
|
|
5850
|
+
x: point.x,
|
|
5851
|
+
y: point.y,
|
|
5852
|
+
button: "left",
|
|
5853
|
+
buttons: 0,
|
|
5854
|
+
clickCount: 1,
|
|
5855
|
+
pointerType: "pen",
|
|
5856
|
+
});
|
|
5857
|
+
}
|
|
5858
|
+
} finally {
|
|
5859
|
+
await client.detach().catch(() => {});
|
|
5860
|
+
}
|
|
5861
|
+
} else {
|
|
5862
|
+
await page.mouse.click(point.x, point.y);
|
|
5863
|
+
}
|
|
5864
|
+
}
|
|
5865
|
+
async function resolveSetupTapTarget(action, base, scope, timeout) {
|
|
5866
|
+
const locator = scope.context.locator(action.selector);
|
|
5867
|
+
const count = await locator.count();
|
|
5868
|
+
if (!count) return { result: { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count } };
|
|
5869
|
+
const targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
5870
|
+
if (targetIndex < 0 || targetIndex >= count) return { result: { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex } };
|
|
5871
|
+
const target = locator.nth(targetIndex);
|
|
5872
|
+
await target.waitFor({ state: "visible", timeout });
|
|
5873
|
+
const box = await target.boundingBox();
|
|
5874
|
+
if (!box) return { result: { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex } };
|
|
5875
|
+
const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
|
|
5876
|
+
const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
|
|
5877
|
+
const hasTapPosition = fromX !== undefined || fromY !== undefined;
|
|
5878
|
+
if (hasTapPosition && (fromX === undefined || fromY === undefined)) return { result: { ...base, ...setupScopeEvidence(scope), reason: "missing_tap_coordinates", count, target_index: targetIndex } };
|
|
5879
|
+
const mode = String(action.coordinate_mode || action.coordinateMode || (hasTapPosition ? "pixels" : "ratio")).trim();
|
|
5880
|
+
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 } };
|
|
5881
|
+
if (hasTapPosition && mode !== "ratio" && [fromX, fromY].some((value) => value < 0)) return { result: { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex } };
|
|
5882
|
+
const coordinate = (value, size) => mode === "ratio" ? value * size : value;
|
|
5883
|
+
const localX = hasTapPosition && fromX !== undefined ? fromX : 0.5;
|
|
5884
|
+
const localY = hasTapPosition && fromY !== undefined ? fromY : 0.5;
|
|
5885
|
+
const point = {
|
|
5886
|
+
x: box.x + coordinate(localX, box.width),
|
|
5887
|
+
y: box.y + coordinate(localY, box.height),
|
|
5888
|
+
};
|
|
5889
|
+
const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
|
|
5890
|
+
const pointerType = String(action.pointer_type || action.pointerType || "touch").trim().toLowerCase();
|
|
5891
|
+
return {
|
|
5892
|
+
target: {
|
|
5893
|
+
count,
|
|
5894
|
+
targetIndex,
|
|
5895
|
+
point,
|
|
5896
|
+
mode,
|
|
5897
|
+
fromX,
|
|
5898
|
+
fromY,
|
|
5899
|
+
hasTapPosition,
|
|
5900
|
+
pointerType,
|
|
5901
|
+
durationMs,
|
|
5902
|
+
},
|
|
5903
|
+
};
|
|
5904
|
+
}
|
|
5905
|
+
function setupTapTargetEvidence(tapTarget) {
|
|
5906
|
+
return {
|
|
5907
|
+
count: tapTarget.count,
|
|
5908
|
+
target_index: tapTarget.targetIndex,
|
|
5909
|
+
coordinate_mode: tapTarget.hasTapPosition ? tapTarget.mode : undefined,
|
|
5910
|
+
x: tapTarget.hasTapPosition ? tapTarget.fromX : undefined,
|
|
5911
|
+
y: tapTarget.hasTapPosition ? tapTarget.fromY : undefined,
|
|
5912
|
+
pointer_type: tapTarget.pointerType,
|
|
5913
|
+
input_dispatch: tapTarget.pointerType === "touch" || tapTarget.pointerType === "pen" ? "cdp" : "playwright_mouse",
|
|
5914
|
+
duration_ms: tapTarget.durationMs || undefined,
|
|
5915
|
+
};
|
|
5916
|
+
}
|
|
5743
5917
|
function setupHasOwn(action, key) {
|
|
5744
5918
|
return Boolean(action) && Object.keys(action).includes(key);
|
|
5745
5919
|
}
|
|
@@ -6342,91 +6516,121 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
6342
6516
|
if (type === "tap") {
|
|
6343
6517
|
const scope = await setupActionScope(action, timeout);
|
|
6344
6518
|
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
6345
|
-
const
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
|
|
6354
|
-
const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.x ?? action.click_x ?? action.clickX);
|
|
6355
|
-
const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.y ?? action.click_y ?? action.clickY);
|
|
6356
|
-
const hasTapPosition = fromX !== undefined || fromY !== undefined;
|
|
6357
|
-
if (hasTapPosition && (fromX === undefined || fromY === undefined)) return { ...base, ...setupScopeEvidence(scope), reason: "missing_tap_coordinates", count, target_index: targetIndex };
|
|
6358
|
-
const mode = String(action.coordinate_mode || action.coordinateMode || (hasTapPosition ? "pixels" : "ratio")).trim();
|
|
6359
|
-
if (hasTapPosition && mode === "ratio" && [fromX, fromY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
|
|
6360
|
-
if (hasTapPosition && mode !== "ratio" && [fromX, fromY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
|
|
6361
|
-
const coordinate = (value, size) => mode === "ratio" ? value * size : value;
|
|
6362
|
-
const localX = hasTapPosition && fromX !== undefined ? fromX : 0.5;
|
|
6363
|
-
const localY = hasTapPosition && fromY !== undefined ? fromY : 0.5;
|
|
6364
|
-
const point = {
|
|
6365
|
-
x: box.x + coordinate(localX, box.width),
|
|
6366
|
-
y: box.y + coordinate(localY, box.height),
|
|
6519
|
+
const prepared = await resolveSetupTapTarget(action, base, scope, timeout);
|
|
6520
|
+
if (prepared.result) return prepared.result;
|
|
6521
|
+
await dispatchSetupTapPoint(prepared.target.point, prepared.target.pointerType, prepared.target.durationMs);
|
|
6522
|
+
return {
|
|
6523
|
+
...base,
|
|
6524
|
+
...setupScopeEvidence(scope),
|
|
6525
|
+
ok: true,
|
|
6526
|
+
...setupTapTargetEvidence(prepared.target),
|
|
6367
6527
|
};
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
|
|
6404
|
-
|
|
6405
|
-
|
|
6406
|
-
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6528
|
+
}
|
|
6529
|
+
if (type === "tap_until") {
|
|
6530
|
+
const untilPath = String(action.until_path || action.untilPath || action.until_state_path || action.untilStatePath || action.until_window_path || action.untilWindowPath || action.until || "");
|
|
6531
|
+
const hasUntilExpected = setupHasOwn(action, "until_expected_value")
|
|
6532
|
+
|| setupHasOwn(action, "untilExpectedValue")
|
|
6533
|
+
|| setupHasOwn(action, "until_expected")
|
|
6534
|
+
|| setupHasOwn(action, "untilExpected")
|
|
6535
|
+
|| setupHasOwn(action, "until_value")
|
|
6536
|
+
|| setupHasOwn(action, "untilValue")
|
|
6537
|
+
|| setupHasOwn(action, "expected_value")
|
|
6538
|
+
|| setupHasOwn(action, "expectedValue")
|
|
6539
|
+
|| setupHasOwn(action, "expected");
|
|
6540
|
+
const untilExpected = setupHasOwn(action, "until_expected_value")
|
|
6541
|
+
? action.until_expected_value
|
|
6542
|
+
: setupHasOwn(action, "untilExpectedValue")
|
|
6543
|
+
? action.untilExpectedValue
|
|
6544
|
+
: setupHasOwn(action, "until_expected")
|
|
6545
|
+
? action.until_expected
|
|
6546
|
+
: setupHasOwn(action, "untilExpected")
|
|
6547
|
+
? action.untilExpected
|
|
6548
|
+
: setupHasOwn(action, "until_value")
|
|
6549
|
+
? action.until_value
|
|
6550
|
+
: setupHasOwn(action, "untilValue")
|
|
6551
|
+
? action.untilValue
|
|
6552
|
+
: setupHasOwn(action, "expected_value")
|
|
6553
|
+
? action.expected_value
|
|
6554
|
+
: setupHasOwn(action, "expectedValue")
|
|
6555
|
+
? action.expectedValue
|
|
6556
|
+
: action.expected;
|
|
6557
|
+
if (!untilPath) return { ...base, reason: "missing_until_path" };
|
|
6558
|
+
if (!hasUntilExpected) return { ...base, until_path: untilPath, reason: "missing_until_expected_value" };
|
|
6559
|
+
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)));
|
|
6560
|
+
const tapBurstSize = Math.min(maxTaps, Math.min(100, Math.max(1, Math.floor(setupNumber(action.tap_burst_size ?? action.tapBurstSize ?? action.burst_size ?? action.burstSize ?? action.check_every_taps ?? action.checkEveryTaps ?? action.predicate_interval_taps ?? action.predicateIntervalTaps, 1) || 1))));
|
|
6561
|
+
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)));
|
|
6562
|
+
const scope = await setupActionScope(action, timeout);
|
|
6563
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
6564
|
+
const prepared = await resolveSetupTapTarget(action, base, scope, timeout);
|
|
6565
|
+
if (prepared.result) return prepared.result;
|
|
6566
|
+
const startedAt = Date.now();
|
|
6567
|
+
let tapCount = 0;
|
|
6568
|
+
let conditionCheckCount = 1;
|
|
6569
|
+
let lastPredicateResult = await setupReadWindowValue(scope.context, untilPath);
|
|
6570
|
+
const targetEvidence = setupTapTargetEvidence(prepared.target);
|
|
6571
|
+
if (lastPredicateResult.ok && setupValuesEqual(lastPredicateResult.value, untilExpected)) {
|
|
6572
|
+
return {
|
|
6573
|
+
...base,
|
|
6574
|
+
...setupScopeEvidence(scope),
|
|
6575
|
+
ok: true,
|
|
6576
|
+
...targetEvidence,
|
|
6577
|
+
until_path: untilPath,
|
|
6578
|
+
until_value: setupJsonValue(lastPredicateResult.value),
|
|
6579
|
+
until_expected_value: setupJsonValue(untilExpected),
|
|
6580
|
+
tap_count: tapCount,
|
|
6581
|
+
max_taps: maxTaps,
|
|
6582
|
+
max_calls: maxTaps,
|
|
6583
|
+
tap_burst_size: tapBurstSize,
|
|
6584
|
+
condition_check_count: conditionCheckCount,
|
|
6585
|
+
interval_ms: intervalMs,
|
|
6586
|
+
timeout_ms: timeout,
|
|
6587
|
+
};
|
|
6588
|
+
}
|
|
6589
|
+
while (tapCount < maxTaps && Date.now() - startedAt <= timeout) {
|
|
6590
|
+
const burstCount = Math.min(tapBurstSize, maxTaps - tapCount);
|
|
6591
|
+
for (let burstIndex = 0; burstIndex < burstCount && Date.now() - startedAt <= timeout; burstIndex += 1) {
|
|
6592
|
+
await dispatchSetupTapPoint(prepared.target.point, prepared.target.pointerType, prepared.target.durationMs);
|
|
6593
|
+
tapCount += 1;
|
|
6594
|
+
if (tapCount < maxTaps && burstIndex < burstCount - 1 && intervalMs) await page.waitForTimeout(intervalMs);
|
|
6414
6595
|
}
|
|
6415
|
-
|
|
6416
|
-
|
|
6596
|
+
lastPredicateResult = await setupReadWindowValue(scope.context, untilPath);
|
|
6597
|
+
conditionCheckCount += 1;
|
|
6598
|
+
if (lastPredicateResult.ok && setupValuesEqual(lastPredicateResult.value, untilExpected)) {
|
|
6599
|
+
return {
|
|
6600
|
+
...base,
|
|
6601
|
+
...setupScopeEvidence(scope),
|
|
6602
|
+
ok: true,
|
|
6603
|
+
...targetEvidence,
|
|
6604
|
+
until_path: untilPath,
|
|
6605
|
+
until_value: setupJsonValue(lastPredicateResult.value),
|
|
6606
|
+
until_expected_value: setupJsonValue(untilExpected),
|
|
6607
|
+
tap_count: tapCount,
|
|
6608
|
+
max_taps: maxTaps,
|
|
6609
|
+
max_calls: maxTaps,
|
|
6610
|
+
tap_burst_size: tapBurstSize,
|
|
6611
|
+
condition_check_count: conditionCheckCount,
|
|
6612
|
+
interval_ms: intervalMs,
|
|
6613
|
+
timeout_ms: timeout,
|
|
6614
|
+
};
|
|
6615
|
+
}
|
|
6616
|
+
if (tapCount < maxTaps && intervalMs) await page.waitForTimeout(intervalMs);
|
|
6417
6617
|
}
|
|
6418
6618
|
return {
|
|
6419
6619
|
...base,
|
|
6420
6620
|
...setupScopeEvidence(scope),
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6621
|
+
...targetEvidence,
|
|
6622
|
+
until_path: untilPath,
|
|
6623
|
+
until_value: setupJsonValue(lastPredicateResult?.value),
|
|
6624
|
+
until_expected_value: setupJsonValue(untilExpected),
|
|
6625
|
+
tap_count: tapCount,
|
|
6626
|
+
max_taps: maxTaps,
|
|
6627
|
+
max_calls: maxTaps,
|
|
6628
|
+
tap_burst_size: tapBurstSize,
|
|
6629
|
+
condition_check_count: conditionCheckCount,
|
|
6630
|
+
interval_ms: intervalMs,
|
|
6631
|
+
timeout_ms: timeout,
|
|
6632
|
+
reason: Date.now() - startedAt > timeout ? "timeout" : "until_condition_not_met",
|
|
6633
|
+
missing_part: lastPredicateResult?.missing_part || undefined,
|
|
6430
6634
|
};
|
|
6431
6635
|
}
|
|
6432
6636
|
if (type === "drag") {
|