@riddledc/riddle-proof 0.7.60 → 0.7.61
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 +7 -1
- package/dist/{chunk-FLQ4HHTT.js → chunk-T66DWLBE.js} +102 -2
- package/dist/cli.cjs +102 -2
- package/dist/cli.js +1 -1
- package/dist/index.cjs +102 -2
- package/dist/index.js +1 -1
- package/dist/profile.cjs +102 -2
- package/dist/profile.d.cts +8 -1
- package/dist/profile.d.ts +8 -1
- package/dist/profile.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -240,7 +240,7 @@ where the second request must carry newer state.
|
|
|
240
240
|
`target.setup_actions` is optional. Use it when the meaningful proof surface
|
|
241
241
|
appears only after a picker, tab, login stub, storage seed, form fill,
|
|
242
242
|
transport control, or other bounded interaction. Supported setup actions are
|
|
243
|
-
`click`, `press`, `fill`, `set_input_value`, `assert_text_visible`,
|
|
243
|
+
`click`, `drag`, `press`, `fill`, `set_input_value`, `assert_text_visible`,
|
|
244
244
|
`assert_text_absent`, `assert_selector_count`, `assert_window_value`,
|
|
245
245
|
`assert_window_number`, `local_storage`, `session_storage`, `clear_storage`, `wait`,
|
|
246
246
|
`wait_for_selector`, `wait_for_text`, and `window_call`; a failed setup action
|
|
@@ -253,6 +253,12 @@ stable enough for Playwright's default click actionability checks. Use `press`
|
|
|
253
253
|
with a Playwright key name, such as `Enter`, `Space`, or `ArrowLeft`,
|
|
254
254
|
when a route's intended browser control is keyboard-driven; omit `selector` for
|
|
255
255
|
a page-level key press, or provide `selector` to press against a focused element.
|
|
256
|
+
Use `drag` for pointer-driven controls such as canvas launch areas, sliders, or
|
|
257
|
+
drag-to-aim games. Provide `selector`, `from_x`, `from_y`, `to_x`, and `to_y`;
|
|
258
|
+
coordinates are element-relative pixels by default. Set `coordinate_mode:
|
|
259
|
+
"ratio"` to make coordinates relative to the target element size, for example
|
|
260
|
+
`from_x: 0.5, from_y: 0.5, to_x: 0.2, to_y: 0.5`. Optional `steps` and
|
|
261
|
+
`duration_ms` control how gradually the pointer moves before release.
|
|
256
262
|
Use setup assertions when the pre-click or pre-navigation state is part of the contract,
|
|
257
263
|
for example a fresh row must be present, stale copy must be absent, exactly one
|
|
258
264
|
source link must exist before clicking into the final route, or a canvas app's
|
|
@@ -34,6 +34,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
34
34
|
];
|
|
35
35
|
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
36
36
|
"click",
|
|
37
|
+
"drag",
|
|
37
38
|
"press",
|
|
38
39
|
"fill",
|
|
39
40
|
"set_input_value",
|
|
@@ -204,7 +205,7 @@ function isSupportedCheckType(value) {
|
|
|
204
205
|
}
|
|
205
206
|
function normalizeSetupActionType(value, index) {
|
|
206
207
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
207
|
-
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
|
|
208
|
+
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
|
|
208
209
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
209
210
|
return normalized;
|
|
210
211
|
}
|
|
@@ -234,6 +235,13 @@ function normalizeSetupActionRepeat(input, index) {
|
|
|
234
235
|
}
|
|
235
236
|
return repeat;
|
|
236
237
|
}
|
|
238
|
+
function normalizeSetupActionCoordinateMode(value, index) {
|
|
239
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
240
|
+
const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
|
|
241
|
+
if (normalized === "pixels" || normalized === "pixel" || normalized === "px") return "pixels";
|
|
242
|
+
if (normalized === "ratio" || normalized === "relative" || normalized === "fraction") return "ratio";
|
|
243
|
+
throw new Error(`target.setup_actions[${index}].coordinate_mode ${String(value)} is not supported. Supported coordinate modes: pixels, ratio.`);
|
|
244
|
+
}
|
|
237
245
|
function normalizeSetupAction(input, index) {
|
|
238
246
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
239
247
|
const type = normalizeSetupActionType(stringValue(input.type), index);
|
|
@@ -243,9 +251,25 @@ function normalizeSetupAction(input, index) {
|
|
|
243
251
|
if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
|
|
244
252
|
throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
|
|
245
253
|
}
|
|
246
|
-
if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
|
|
254
|
+
if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
|
|
247
255
|
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
248
256
|
}
|
|
257
|
+
const fromX = numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
|
|
258
|
+
const fromY = numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
|
|
259
|
+
const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
|
|
260
|
+
const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
|
|
261
|
+
const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
|
|
262
|
+
if (type === "drag") {
|
|
263
|
+
if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
|
|
264
|
+
throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
|
|
265
|
+
}
|
|
266
|
+
if (coordinateMode === "ratio" && [fromX, fromY, toX, toY].some((value2) => value2 < 0 || value2 > 1)) {
|
|
267
|
+
throw new Error(`target.setup_actions[${index}] drag ratio coordinates must be between 0 and 1.`);
|
|
268
|
+
}
|
|
269
|
+
if ((coordinateMode === void 0 || coordinateMode === "pixels") && [fromX, fromY, toX, toY].some((value2) => value2 < 0)) {
|
|
270
|
+
throw new Error(`target.setup_actions[${index}] drag pixel coordinates must be non-negative.`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
249
273
|
if (type === "wait_for_text" && !stringValue(input.text) && !stringValue(input.pattern)) {
|
|
250
274
|
throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
|
|
251
275
|
}
|
|
@@ -292,12 +316,23 @@ function normalizeSetupAction(input, index) {
|
|
|
292
316
|
}
|
|
293
317
|
}
|
|
294
318
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
319
|
+
const steps = numberValue(input.steps);
|
|
320
|
+
if (type === "drag" && steps !== void 0 && (!Number.isInteger(steps) || steps < 1 || steps > 100)) {
|
|
321
|
+
throw new Error(`target.setup_actions[${index}].steps must be an integer from 1 to 100.`);
|
|
322
|
+
}
|
|
295
323
|
return {
|
|
296
324
|
type,
|
|
297
325
|
selector,
|
|
298
326
|
frame_selector: frameSelector,
|
|
299
327
|
frame_index: frameIndex,
|
|
300
328
|
force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
|
|
329
|
+
coordinate_mode: coordinateMode,
|
|
330
|
+
from_x: fromX,
|
|
331
|
+
from_y: fromY,
|
|
332
|
+
to_x: toX,
|
|
333
|
+
to_y: toY,
|
|
334
|
+
duration_ms: numberValue(input.duration_ms) ?? numberValue(input.durationMs),
|
|
335
|
+
steps,
|
|
301
336
|
key,
|
|
302
337
|
value,
|
|
303
338
|
value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
|
|
@@ -2505,6 +2540,71 @@ async function executeSetupAction(action, ordinal) {
|
|
|
2505
2540
|
await scope.context.waitForSelector(action.selector, { state: "visible", timeout });
|
|
2506
2541
|
return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
|
|
2507
2542
|
}
|
|
2543
|
+
if (type === "drag") {
|
|
2544
|
+
const scope = await setupActionScope(action, timeout);
|
|
2545
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
2546
|
+
const locator = scope.context.locator(action.selector);
|
|
2547
|
+
const count = await locator.count();
|
|
2548
|
+
if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
|
|
2549
|
+
const targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
2550
|
+
if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
|
|
2551
|
+
const target = locator.nth(targetIndex);
|
|
2552
|
+
await target.waitFor({ state: "visible", timeout });
|
|
2553
|
+
const box = await target.boundingBox();
|
|
2554
|
+
if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
|
|
2555
|
+
const mode = String(action.coordinate_mode || action.coordinateMode || "pixels").trim();
|
|
2556
|
+
const coordinate = (value, size) => mode === "ratio" ? value * size : value;
|
|
2557
|
+
const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.start_x ?? action.startX ?? action.x1);
|
|
2558
|
+
const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.start_y ?? action.startY ?? action.y1);
|
|
2559
|
+
const toX = setupFiniteNumber(action.to_x ?? action.toX ?? action.end_x ?? action.endX ?? action.x2);
|
|
2560
|
+
const toY = setupFiniteNumber(action.to_y ?? action.toY ?? action.end_y ?? action.endY ?? action.y2);
|
|
2561
|
+
if (fromX === undefined || fromY === undefined || toX === undefined || toY === undefined) return { ...base, ...setupScopeEvidence(scope), reason: "missing_drag_coordinates", count, target_index: targetIndex };
|
|
2562
|
+
if (mode === "ratio" && [fromX, fromY, toX, toY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
|
|
2563
|
+
if (mode !== "ratio" && [fromX, fromY, toX, toY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
|
|
2564
|
+
const start = {
|
|
2565
|
+
x: box.x + coordinate(fromX, box.width),
|
|
2566
|
+
y: box.y + coordinate(fromY, box.height),
|
|
2567
|
+
};
|
|
2568
|
+
const end = {
|
|
2569
|
+
x: box.x + coordinate(toX, box.width),
|
|
2570
|
+
y: box.y + coordinate(toY, box.height),
|
|
2571
|
+
};
|
|
2572
|
+
const requestedSteps = setupNumber(action.steps, 8);
|
|
2573
|
+
const steps = Math.min(100, Math.max(1, Math.floor(requestedSteps || 8)));
|
|
2574
|
+
const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
|
|
2575
|
+
await page.mouse.move(start.x, start.y);
|
|
2576
|
+
await page.mouse.down();
|
|
2577
|
+
try {
|
|
2578
|
+
if (durationMs && steps > 1) {
|
|
2579
|
+
for (let step = 1; step <= steps; step += 1) {
|
|
2580
|
+
const progress = step / steps;
|
|
2581
|
+
await page.mouse.move(
|
|
2582
|
+
start.x + (end.x - start.x) * progress,
|
|
2583
|
+
start.y + (end.y - start.y) * progress,
|
|
2584
|
+
);
|
|
2585
|
+
await page.waitForTimeout(durationMs / steps);
|
|
2586
|
+
}
|
|
2587
|
+
} else {
|
|
2588
|
+
await page.mouse.move(end.x, end.y, { steps });
|
|
2589
|
+
}
|
|
2590
|
+
} finally {
|
|
2591
|
+
await page.mouse.up().catch(() => {});
|
|
2592
|
+
}
|
|
2593
|
+
return {
|
|
2594
|
+
...base,
|
|
2595
|
+
...setupScopeEvidence(scope),
|
|
2596
|
+
ok: true,
|
|
2597
|
+
count,
|
|
2598
|
+
target_index: targetIndex,
|
|
2599
|
+
coordinate_mode: mode,
|
|
2600
|
+
from_x: fromX,
|
|
2601
|
+
from_y: fromY,
|
|
2602
|
+
to_x: toX,
|
|
2603
|
+
to_y: toY,
|
|
2604
|
+
steps,
|
|
2605
|
+
duration_ms: durationMs || undefined,
|
|
2606
|
+
};
|
|
2607
|
+
}
|
|
2508
2608
|
if (type === "press") {
|
|
2509
2609
|
const key = String(action.key || "").trim();
|
|
2510
2610
|
if (!key) return { ...base, reason: "missing_key" };
|
package/dist/cli.cjs
CHANGED
|
@@ -6907,6 +6907,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
6907
6907
|
];
|
|
6908
6908
|
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
6909
6909
|
"click",
|
|
6910
|
+
"drag",
|
|
6910
6911
|
"press",
|
|
6911
6912
|
"fill",
|
|
6912
6913
|
"set_input_value",
|
|
@@ -7077,7 +7078,7 @@ function isSupportedCheckType(value) {
|
|
|
7077
7078
|
}
|
|
7078
7079
|
function normalizeSetupActionType(value, index) {
|
|
7079
7080
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
7080
|
-
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
|
|
7081
|
+
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
|
|
7081
7082
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
7082
7083
|
return normalized;
|
|
7083
7084
|
}
|
|
@@ -7107,6 +7108,13 @@ function normalizeSetupActionRepeat(input, index) {
|
|
|
7107
7108
|
}
|
|
7108
7109
|
return repeat;
|
|
7109
7110
|
}
|
|
7111
|
+
function normalizeSetupActionCoordinateMode(value, index) {
|
|
7112
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
7113
|
+
const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
|
|
7114
|
+
if (normalized === "pixels" || normalized === "pixel" || normalized === "px") return "pixels";
|
|
7115
|
+
if (normalized === "ratio" || normalized === "relative" || normalized === "fraction") return "ratio";
|
|
7116
|
+
throw new Error(`target.setup_actions[${index}].coordinate_mode ${String(value)} is not supported. Supported coordinate modes: pixels, ratio.`);
|
|
7117
|
+
}
|
|
7110
7118
|
function normalizeSetupAction(input, index) {
|
|
7111
7119
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
7112
7120
|
const type = normalizeSetupActionType(stringValue2(input.type), index);
|
|
@@ -7116,9 +7124,25 @@ function normalizeSetupAction(input, index) {
|
|
|
7116
7124
|
if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
|
|
7117
7125
|
throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
|
|
7118
7126
|
}
|
|
7119
|
-
if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
|
|
7127
|
+
if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
|
|
7120
7128
|
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
7121
7129
|
}
|
|
7130
|
+
const fromX = numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
|
|
7131
|
+
const fromY = numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
|
|
7132
|
+
const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
|
|
7133
|
+
const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
|
|
7134
|
+
const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
|
|
7135
|
+
if (type === "drag") {
|
|
7136
|
+
if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
|
|
7137
|
+
throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
|
|
7138
|
+
}
|
|
7139
|
+
if (coordinateMode === "ratio" && [fromX, fromY, toX, toY].some((value2) => value2 < 0 || value2 > 1)) {
|
|
7140
|
+
throw new Error(`target.setup_actions[${index}] drag ratio coordinates must be between 0 and 1.`);
|
|
7141
|
+
}
|
|
7142
|
+
if ((coordinateMode === void 0 || coordinateMode === "pixels") && [fromX, fromY, toX, toY].some((value2) => value2 < 0)) {
|
|
7143
|
+
throw new Error(`target.setup_actions[${index}] drag pixel coordinates must be non-negative.`);
|
|
7144
|
+
}
|
|
7145
|
+
}
|
|
7122
7146
|
if (type === "wait_for_text" && !stringValue2(input.text) && !stringValue2(input.pattern)) {
|
|
7123
7147
|
throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
|
|
7124
7148
|
}
|
|
@@ -7165,12 +7189,23 @@ function normalizeSetupAction(input, index) {
|
|
|
7165
7189
|
}
|
|
7166
7190
|
}
|
|
7167
7191
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
7192
|
+
const steps = numberValue(input.steps);
|
|
7193
|
+
if (type === "drag" && steps !== void 0 && (!Number.isInteger(steps) || steps < 1 || steps > 100)) {
|
|
7194
|
+
throw new Error(`target.setup_actions[${index}].steps must be an integer from 1 to 100.`);
|
|
7195
|
+
}
|
|
7168
7196
|
return {
|
|
7169
7197
|
type,
|
|
7170
7198
|
selector,
|
|
7171
7199
|
frame_selector: frameSelector,
|
|
7172
7200
|
frame_index: frameIndex,
|
|
7173
7201
|
force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
|
|
7202
|
+
coordinate_mode: coordinateMode,
|
|
7203
|
+
from_x: fromX,
|
|
7204
|
+
from_y: fromY,
|
|
7205
|
+
to_x: toX,
|
|
7206
|
+
to_y: toY,
|
|
7207
|
+
duration_ms: numberValue(input.duration_ms) ?? numberValue(input.durationMs),
|
|
7208
|
+
steps,
|
|
7174
7209
|
key,
|
|
7175
7210
|
value,
|
|
7176
7211
|
value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
|
|
@@ -9362,6 +9397,71 @@ async function executeSetupAction(action, ordinal) {
|
|
|
9362
9397
|
await scope.context.waitForSelector(action.selector, { state: "visible", timeout });
|
|
9363
9398
|
return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
|
|
9364
9399
|
}
|
|
9400
|
+
if (type === "drag") {
|
|
9401
|
+
const scope = await setupActionScope(action, timeout);
|
|
9402
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
9403
|
+
const locator = scope.context.locator(action.selector);
|
|
9404
|
+
const count = await locator.count();
|
|
9405
|
+
if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
|
|
9406
|
+
const targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
9407
|
+
if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
|
|
9408
|
+
const target = locator.nth(targetIndex);
|
|
9409
|
+
await target.waitFor({ state: "visible", timeout });
|
|
9410
|
+
const box = await target.boundingBox();
|
|
9411
|
+
if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
|
|
9412
|
+
const mode = String(action.coordinate_mode || action.coordinateMode || "pixels").trim();
|
|
9413
|
+
const coordinate = (value, size) => mode === "ratio" ? value * size : value;
|
|
9414
|
+
const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.start_x ?? action.startX ?? action.x1);
|
|
9415
|
+
const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.start_y ?? action.startY ?? action.y1);
|
|
9416
|
+
const toX = setupFiniteNumber(action.to_x ?? action.toX ?? action.end_x ?? action.endX ?? action.x2);
|
|
9417
|
+
const toY = setupFiniteNumber(action.to_y ?? action.toY ?? action.end_y ?? action.endY ?? action.y2);
|
|
9418
|
+
if (fromX === undefined || fromY === undefined || toX === undefined || toY === undefined) return { ...base, ...setupScopeEvidence(scope), reason: "missing_drag_coordinates", count, target_index: targetIndex };
|
|
9419
|
+
if (mode === "ratio" && [fromX, fromY, toX, toY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
|
|
9420
|
+
if (mode !== "ratio" && [fromX, fromY, toX, toY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
|
|
9421
|
+
const start = {
|
|
9422
|
+
x: box.x + coordinate(fromX, box.width),
|
|
9423
|
+
y: box.y + coordinate(fromY, box.height),
|
|
9424
|
+
};
|
|
9425
|
+
const end = {
|
|
9426
|
+
x: box.x + coordinate(toX, box.width),
|
|
9427
|
+
y: box.y + coordinate(toY, box.height),
|
|
9428
|
+
};
|
|
9429
|
+
const requestedSteps = setupNumber(action.steps, 8);
|
|
9430
|
+
const steps = Math.min(100, Math.max(1, Math.floor(requestedSteps || 8)));
|
|
9431
|
+
const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
|
|
9432
|
+
await page.mouse.move(start.x, start.y);
|
|
9433
|
+
await page.mouse.down();
|
|
9434
|
+
try {
|
|
9435
|
+
if (durationMs && steps > 1) {
|
|
9436
|
+
for (let step = 1; step <= steps; step += 1) {
|
|
9437
|
+
const progress = step / steps;
|
|
9438
|
+
await page.mouse.move(
|
|
9439
|
+
start.x + (end.x - start.x) * progress,
|
|
9440
|
+
start.y + (end.y - start.y) * progress,
|
|
9441
|
+
);
|
|
9442
|
+
await page.waitForTimeout(durationMs / steps);
|
|
9443
|
+
}
|
|
9444
|
+
} else {
|
|
9445
|
+
await page.mouse.move(end.x, end.y, { steps });
|
|
9446
|
+
}
|
|
9447
|
+
} finally {
|
|
9448
|
+
await page.mouse.up().catch(() => {});
|
|
9449
|
+
}
|
|
9450
|
+
return {
|
|
9451
|
+
...base,
|
|
9452
|
+
...setupScopeEvidence(scope),
|
|
9453
|
+
ok: true,
|
|
9454
|
+
count,
|
|
9455
|
+
target_index: targetIndex,
|
|
9456
|
+
coordinate_mode: mode,
|
|
9457
|
+
from_x: fromX,
|
|
9458
|
+
from_y: fromY,
|
|
9459
|
+
to_x: toX,
|
|
9460
|
+
to_y: toY,
|
|
9461
|
+
steps,
|
|
9462
|
+
duration_ms: durationMs || undefined,
|
|
9463
|
+
};
|
|
9464
|
+
}
|
|
9365
9465
|
if (type === "press") {
|
|
9366
9466
|
const key = String(action.key || "").trim();
|
|
9367
9467
|
if (!key) return { ...base, reason: "missing_key" };
|
package/dist/cli.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -8748,6 +8748,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
8748
8748
|
];
|
|
8749
8749
|
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
8750
8750
|
"click",
|
|
8751
|
+
"drag",
|
|
8751
8752
|
"press",
|
|
8752
8753
|
"fill",
|
|
8753
8754
|
"set_input_value",
|
|
@@ -8918,7 +8919,7 @@ function isSupportedCheckType(value) {
|
|
|
8918
8919
|
}
|
|
8919
8920
|
function normalizeSetupActionType(value, index) {
|
|
8920
8921
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
8921
|
-
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
|
|
8922
|
+
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
|
|
8922
8923
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
8923
8924
|
return normalized;
|
|
8924
8925
|
}
|
|
@@ -8948,6 +8949,13 @@ function normalizeSetupActionRepeat(input, index) {
|
|
|
8948
8949
|
}
|
|
8949
8950
|
return repeat;
|
|
8950
8951
|
}
|
|
8952
|
+
function normalizeSetupActionCoordinateMode(value, index) {
|
|
8953
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
8954
|
+
const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
|
|
8955
|
+
if (normalized === "pixels" || normalized === "pixel" || normalized === "px") return "pixels";
|
|
8956
|
+
if (normalized === "ratio" || normalized === "relative" || normalized === "fraction") return "ratio";
|
|
8957
|
+
throw new Error(`target.setup_actions[${index}].coordinate_mode ${String(value)} is not supported. Supported coordinate modes: pixels, ratio.`);
|
|
8958
|
+
}
|
|
8951
8959
|
function normalizeSetupAction(input, index) {
|
|
8952
8960
|
if (!isRecord2(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
8953
8961
|
const type = normalizeSetupActionType(stringValue5(input.type), index);
|
|
@@ -8957,9 +8965,25 @@ function normalizeSetupAction(input, index) {
|
|
|
8957
8965
|
if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
|
|
8958
8966
|
throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
|
|
8959
8967
|
}
|
|
8960
|
-
if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
|
|
8968
|
+
if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
|
|
8961
8969
|
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
8962
8970
|
}
|
|
8971
|
+
const fromX = numberValue3(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
|
|
8972
|
+
const fromY = numberValue3(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
|
|
8973
|
+
const toX = numberValue3(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
|
|
8974
|
+
const toY = numberValue3(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
|
|
8975
|
+
const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
|
|
8976
|
+
if (type === "drag") {
|
|
8977
|
+
if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
|
|
8978
|
+
throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
|
|
8979
|
+
}
|
|
8980
|
+
if (coordinateMode === "ratio" && [fromX, fromY, toX, toY].some((value2) => value2 < 0 || value2 > 1)) {
|
|
8981
|
+
throw new Error(`target.setup_actions[${index}] drag ratio coordinates must be between 0 and 1.`);
|
|
8982
|
+
}
|
|
8983
|
+
if ((coordinateMode === void 0 || coordinateMode === "pixels") && [fromX, fromY, toX, toY].some((value2) => value2 < 0)) {
|
|
8984
|
+
throw new Error(`target.setup_actions[${index}] drag pixel coordinates must be non-negative.`);
|
|
8985
|
+
}
|
|
8986
|
+
}
|
|
8963
8987
|
if (type === "wait_for_text" && !stringValue5(input.text) && !stringValue5(input.pattern)) {
|
|
8964
8988
|
throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
|
|
8965
8989
|
}
|
|
@@ -9006,12 +9030,23 @@ function normalizeSetupAction(input, index) {
|
|
|
9006
9030
|
}
|
|
9007
9031
|
}
|
|
9008
9032
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
9033
|
+
const steps = numberValue3(input.steps);
|
|
9034
|
+
if (type === "drag" && steps !== void 0 && (!Number.isInteger(steps) || steps < 1 || steps > 100)) {
|
|
9035
|
+
throw new Error(`target.setup_actions[${index}].steps must be an integer from 1 to 100.`);
|
|
9036
|
+
}
|
|
9009
9037
|
return {
|
|
9010
9038
|
type,
|
|
9011
9039
|
selector,
|
|
9012
9040
|
frame_selector: frameSelector,
|
|
9013
9041
|
frame_index: frameIndex,
|
|
9014
9042
|
force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
|
|
9043
|
+
coordinate_mode: coordinateMode,
|
|
9044
|
+
from_x: fromX,
|
|
9045
|
+
from_y: fromY,
|
|
9046
|
+
to_x: toX,
|
|
9047
|
+
to_y: toY,
|
|
9048
|
+
duration_ms: numberValue3(input.duration_ms) ?? numberValue3(input.durationMs),
|
|
9049
|
+
steps,
|
|
9015
9050
|
key,
|
|
9016
9051
|
value,
|
|
9017
9052
|
value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
|
|
@@ -11219,6 +11254,71 @@ async function executeSetupAction(action, ordinal) {
|
|
|
11219
11254
|
await scope.context.waitForSelector(action.selector, { state: "visible", timeout });
|
|
11220
11255
|
return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
|
|
11221
11256
|
}
|
|
11257
|
+
if (type === "drag") {
|
|
11258
|
+
const scope = await setupActionScope(action, timeout);
|
|
11259
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
11260
|
+
const locator = scope.context.locator(action.selector);
|
|
11261
|
+
const count = await locator.count();
|
|
11262
|
+
if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
|
|
11263
|
+
const targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
11264
|
+
if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
|
|
11265
|
+
const target = locator.nth(targetIndex);
|
|
11266
|
+
await target.waitFor({ state: "visible", timeout });
|
|
11267
|
+
const box = await target.boundingBox();
|
|
11268
|
+
if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
|
|
11269
|
+
const mode = String(action.coordinate_mode || action.coordinateMode || "pixels").trim();
|
|
11270
|
+
const coordinate = (value, size) => mode === "ratio" ? value * size : value;
|
|
11271
|
+
const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.start_x ?? action.startX ?? action.x1);
|
|
11272
|
+
const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.start_y ?? action.startY ?? action.y1);
|
|
11273
|
+
const toX = setupFiniteNumber(action.to_x ?? action.toX ?? action.end_x ?? action.endX ?? action.x2);
|
|
11274
|
+
const toY = setupFiniteNumber(action.to_y ?? action.toY ?? action.end_y ?? action.endY ?? action.y2);
|
|
11275
|
+
if (fromX === undefined || fromY === undefined || toX === undefined || toY === undefined) return { ...base, ...setupScopeEvidence(scope), reason: "missing_drag_coordinates", count, target_index: targetIndex };
|
|
11276
|
+
if (mode === "ratio" && [fromX, fromY, toX, toY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
|
|
11277
|
+
if (mode !== "ratio" && [fromX, fromY, toX, toY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
|
|
11278
|
+
const start = {
|
|
11279
|
+
x: box.x + coordinate(fromX, box.width),
|
|
11280
|
+
y: box.y + coordinate(fromY, box.height),
|
|
11281
|
+
};
|
|
11282
|
+
const end = {
|
|
11283
|
+
x: box.x + coordinate(toX, box.width),
|
|
11284
|
+
y: box.y + coordinate(toY, box.height),
|
|
11285
|
+
};
|
|
11286
|
+
const requestedSteps = setupNumber(action.steps, 8);
|
|
11287
|
+
const steps = Math.min(100, Math.max(1, Math.floor(requestedSteps || 8)));
|
|
11288
|
+
const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
|
|
11289
|
+
await page.mouse.move(start.x, start.y);
|
|
11290
|
+
await page.mouse.down();
|
|
11291
|
+
try {
|
|
11292
|
+
if (durationMs && steps > 1) {
|
|
11293
|
+
for (let step = 1; step <= steps; step += 1) {
|
|
11294
|
+
const progress = step / steps;
|
|
11295
|
+
await page.mouse.move(
|
|
11296
|
+
start.x + (end.x - start.x) * progress,
|
|
11297
|
+
start.y + (end.y - start.y) * progress,
|
|
11298
|
+
);
|
|
11299
|
+
await page.waitForTimeout(durationMs / steps);
|
|
11300
|
+
}
|
|
11301
|
+
} else {
|
|
11302
|
+
await page.mouse.move(end.x, end.y, { steps });
|
|
11303
|
+
}
|
|
11304
|
+
} finally {
|
|
11305
|
+
await page.mouse.up().catch(() => {});
|
|
11306
|
+
}
|
|
11307
|
+
return {
|
|
11308
|
+
...base,
|
|
11309
|
+
...setupScopeEvidence(scope),
|
|
11310
|
+
ok: true,
|
|
11311
|
+
count,
|
|
11312
|
+
target_index: targetIndex,
|
|
11313
|
+
coordinate_mode: mode,
|
|
11314
|
+
from_x: fromX,
|
|
11315
|
+
from_y: fromY,
|
|
11316
|
+
to_x: toX,
|
|
11317
|
+
to_y: toY,
|
|
11318
|
+
steps,
|
|
11319
|
+
duration_ms: durationMs || undefined,
|
|
11320
|
+
};
|
|
11321
|
+
}
|
|
11222
11322
|
if (type === "press") {
|
|
11223
11323
|
const key = String(action.key || "").trim();
|
|
11224
11324
|
if (!key) return { ...base, reason: "missing_key" };
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
resolveRiddleProofProfileTimeoutSec,
|
|
59
59
|
slugifyRiddleProofProfileName,
|
|
60
60
|
summarizeRiddleProofProfileResult
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-T66DWLBE.js";
|
|
62
62
|
import {
|
|
63
63
|
DEFAULT_RIDDLE_API_BASE_URL,
|
|
64
64
|
DEFAULT_RIDDLE_API_KEY_FILE,
|
package/dist/profile.cjs
CHANGED
|
@@ -77,6 +77,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
77
77
|
];
|
|
78
78
|
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
79
79
|
"click",
|
|
80
|
+
"drag",
|
|
80
81
|
"press",
|
|
81
82
|
"fill",
|
|
82
83
|
"set_input_value",
|
|
@@ -247,7 +248,7 @@ function isSupportedCheckType(value) {
|
|
|
247
248
|
}
|
|
248
249
|
function normalizeSetupActionType(value, index) {
|
|
249
250
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
250
|
-
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
|
|
251
|
+
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
|
|
251
252
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
252
253
|
return normalized;
|
|
253
254
|
}
|
|
@@ -277,6 +278,13 @@ function normalizeSetupActionRepeat(input, index) {
|
|
|
277
278
|
}
|
|
278
279
|
return repeat;
|
|
279
280
|
}
|
|
281
|
+
function normalizeSetupActionCoordinateMode(value, index) {
|
|
282
|
+
if (value === void 0 || value === null || value === "") return void 0;
|
|
283
|
+
const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
|
|
284
|
+
if (normalized === "pixels" || normalized === "pixel" || normalized === "px") return "pixels";
|
|
285
|
+
if (normalized === "ratio" || normalized === "relative" || normalized === "fraction") return "ratio";
|
|
286
|
+
throw new Error(`target.setup_actions[${index}].coordinate_mode ${String(value)} is not supported. Supported coordinate modes: pixels, ratio.`);
|
|
287
|
+
}
|
|
280
288
|
function normalizeSetupAction(input, index) {
|
|
281
289
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
282
290
|
const type = normalizeSetupActionType(stringValue(input.type), index);
|
|
@@ -286,9 +294,25 @@ function normalizeSetupAction(input, index) {
|
|
|
286
294
|
if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
|
|
287
295
|
throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
|
|
288
296
|
}
|
|
289
|
-
if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
|
|
297
|
+
if ((type === "click" || type === "drag" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text" || type === "assert_text_visible" || type === "assert_text_absent" || type === "assert_selector_count") && !selector) {
|
|
290
298
|
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
291
299
|
}
|
|
300
|
+
const fromX = numberValue(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
|
|
301
|
+
const fromY = numberValue(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
|
|
302
|
+
const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
|
|
303
|
+
const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
|
|
304
|
+
const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
|
|
305
|
+
if (type === "drag") {
|
|
306
|
+
if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
|
|
307
|
+
throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
|
|
308
|
+
}
|
|
309
|
+
if (coordinateMode === "ratio" && [fromX, fromY, toX, toY].some((value2) => value2 < 0 || value2 > 1)) {
|
|
310
|
+
throw new Error(`target.setup_actions[${index}] drag ratio coordinates must be between 0 and 1.`);
|
|
311
|
+
}
|
|
312
|
+
if ((coordinateMode === void 0 || coordinateMode === "pixels") && [fromX, fromY, toX, toY].some((value2) => value2 < 0)) {
|
|
313
|
+
throw new Error(`target.setup_actions[${index}] drag pixel coordinates must be non-negative.`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
292
316
|
if (type === "wait_for_text" && !stringValue(input.text) && !stringValue(input.pattern)) {
|
|
293
317
|
throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
|
|
294
318
|
}
|
|
@@ -335,12 +359,23 @@ function normalizeSetupAction(input, index) {
|
|
|
335
359
|
}
|
|
336
360
|
}
|
|
337
361
|
const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
|
|
362
|
+
const steps = numberValue(input.steps);
|
|
363
|
+
if (type === "drag" && steps !== void 0 && (!Number.isInteger(steps) || steps < 1 || steps > 100)) {
|
|
364
|
+
throw new Error(`target.setup_actions[${index}].steps must be an integer from 1 to 100.`);
|
|
365
|
+
}
|
|
338
366
|
return {
|
|
339
367
|
type,
|
|
340
368
|
selector,
|
|
341
369
|
frame_selector: frameSelector,
|
|
342
370
|
frame_index: frameIndex,
|
|
343
371
|
force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
|
|
372
|
+
coordinate_mode: coordinateMode,
|
|
373
|
+
from_x: fromX,
|
|
374
|
+
from_y: fromY,
|
|
375
|
+
to_x: toX,
|
|
376
|
+
to_y: toY,
|
|
377
|
+
duration_ms: numberValue(input.duration_ms) ?? numberValue(input.durationMs),
|
|
378
|
+
steps,
|
|
344
379
|
key,
|
|
345
380
|
value,
|
|
346
381
|
value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
|
|
@@ -2548,6 +2583,71 @@ async function executeSetupAction(action, ordinal) {
|
|
|
2548
2583
|
await scope.context.waitForSelector(action.selector, { state: "visible", timeout });
|
|
2549
2584
|
return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
|
|
2550
2585
|
}
|
|
2586
|
+
if (type === "drag") {
|
|
2587
|
+
const scope = await setupActionScope(action, timeout);
|
|
2588
|
+
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
2589
|
+
const locator = scope.context.locator(action.selector);
|
|
2590
|
+
const count = await locator.count();
|
|
2591
|
+
if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
|
|
2592
|
+
const targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
2593
|
+
if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
|
|
2594
|
+
const target = locator.nth(targetIndex);
|
|
2595
|
+
await target.waitFor({ state: "visible", timeout });
|
|
2596
|
+
const box = await target.boundingBox();
|
|
2597
|
+
if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
|
|
2598
|
+
const mode = String(action.coordinate_mode || action.coordinateMode || "pixels").trim();
|
|
2599
|
+
const coordinate = (value, size) => mode === "ratio" ? value * size : value;
|
|
2600
|
+
const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.start_x ?? action.startX ?? action.x1);
|
|
2601
|
+
const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.start_y ?? action.startY ?? action.y1);
|
|
2602
|
+
const toX = setupFiniteNumber(action.to_x ?? action.toX ?? action.end_x ?? action.endX ?? action.x2);
|
|
2603
|
+
const toY = setupFiniteNumber(action.to_y ?? action.toY ?? action.end_y ?? action.endY ?? action.y2);
|
|
2604
|
+
if (fromX === undefined || fromY === undefined || toX === undefined || toY === undefined) return { ...base, ...setupScopeEvidence(scope), reason: "missing_drag_coordinates", count, target_index: targetIndex };
|
|
2605
|
+
if (mode === "ratio" && [fromX, fromY, toX, toY].some((value) => value < 0 || value > 1)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_ratio_coordinates", count, target_index: targetIndex };
|
|
2606
|
+
if (mode !== "ratio" && [fromX, fromY, toX, toY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
|
|
2607
|
+
const start = {
|
|
2608
|
+
x: box.x + coordinate(fromX, box.width),
|
|
2609
|
+
y: box.y + coordinate(fromY, box.height),
|
|
2610
|
+
};
|
|
2611
|
+
const end = {
|
|
2612
|
+
x: box.x + coordinate(toX, box.width),
|
|
2613
|
+
y: box.y + coordinate(toY, box.height),
|
|
2614
|
+
};
|
|
2615
|
+
const requestedSteps = setupNumber(action.steps, 8);
|
|
2616
|
+
const steps = Math.min(100, Math.max(1, Math.floor(requestedSteps || 8)));
|
|
2617
|
+
const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
|
|
2618
|
+
await page.mouse.move(start.x, start.y);
|
|
2619
|
+
await page.mouse.down();
|
|
2620
|
+
try {
|
|
2621
|
+
if (durationMs && steps > 1) {
|
|
2622
|
+
for (let step = 1; step <= steps; step += 1) {
|
|
2623
|
+
const progress = step / steps;
|
|
2624
|
+
await page.mouse.move(
|
|
2625
|
+
start.x + (end.x - start.x) * progress,
|
|
2626
|
+
start.y + (end.y - start.y) * progress,
|
|
2627
|
+
);
|
|
2628
|
+
await page.waitForTimeout(durationMs / steps);
|
|
2629
|
+
}
|
|
2630
|
+
} else {
|
|
2631
|
+
await page.mouse.move(end.x, end.y, { steps });
|
|
2632
|
+
}
|
|
2633
|
+
} finally {
|
|
2634
|
+
await page.mouse.up().catch(() => {});
|
|
2635
|
+
}
|
|
2636
|
+
return {
|
|
2637
|
+
...base,
|
|
2638
|
+
...setupScopeEvidence(scope),
|
|
2639
|
+
ok: true,
|
|
2640
|
+
count,
|
|
2641
|
+
target_index: targetIndex,
|
|
2642
|
+
coordinate_mode: mode,
|
|
2643
|
+
from_x: fromX,
|
|
2644
|
+
from_y: fromY,
|
|
2645
|
+
to_x: toX,
|
|
2646
|
+
to_y: toY,
|
|
2647
|
+
steps,
|
|
2648
|
+
duration_ms: durationMs || undefined,
|
|
2649
|
+
};
|
|
2650
|
+
}
|
|
2551
2651
|
if (type === "press") {
|
|
2552
2652
|
const key = String(action.key || "").trim();
|
|
2553
2653
|
if (!key) return { ...base, reason: "missing_key" };
|
package/dist/profile.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
|
|
|
5
5
|
declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
|
|
6
6
|
declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
|
|
7
7
|
declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
|
|
8
|
-
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
8
|
+
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
9
9
|
type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
|
|
10
10
|
type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
|
|
11
11
|
type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
|
|
@@ -23,6 +23,13 @@ interface RiddleProofProfileSetupAction {
|
|
|
23
23
|
frame_selector?: string;
|
|
24
24
|
frame_index?: number;
|
|
25
25
|
force?: boolean;
|
|
26
|
+
coordinate_mode?: "pixels" | "ratio";
|
|
27
|
+
from_x?: number;
|
|
28
|
+
from_y?: number;
|
|
29
|
+
to_x?: number;
|
|
30
|
+
to_y?: number;
|
|
31
|
+
duration_ms?: number;
|
|
32
|
+
steps?: number;
|
|
26
33
|
key?: string;
|
|
27
34
|
value?: string;
|
|
28
35
|
value_json?: JsonValue;
|
package/dist/profile.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
|
|
|
5
5
|
declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
|
|
6
6
|
declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
|
|
7
7
|
declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
|
|
8
|
-
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
8
|
+
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
9
9
|
type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
|
|
10
10
|
type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
|
|
11
11
|
type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
|
|
@@ -23,6 +23,13 @@ interface RiddleProofProfileSetupAction {
|
|
|
23
23
|
frame_selector?: string;
|
|
24
24
|
frame_index?: number;
|
|
25
25
|
force?: boolean;
|
|
26
|
+
coordinate_mode?: "pixels" | "ratio";
|
|
27
|
+
from_x?: number;
|
|
28
|
+
from_y?: number;
|
|
29
|
+
to_x?: number;
|
|
30
|
+
to_y?: number;
|
|
31
|
+
duration_ms?: number;
|
|
32
|
+
steps?: number;
|
|
26
33
|
key?: string;
|
|
27
34
|
value?: string;
|
|
28
35
|
value_json?: JsonValue;
|
package/dist/profile.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
resolveRiddleProofProfileTimeoutSec,
|
|
20
20
|
slugifyRiddleProofProfileName,
|
|
21
21
|
summarizeRiddleProofProfileResult
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-T66DWLBE.js";
|
|
23
23
|
export {
|
|
24
24
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
25
25
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|