@riddledc/riddle-proof 0.7.60 → 0.7.62

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
@@ -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",
@@ -8888,6 +8889,78 @@ function toJsonValue(value) {
8888
8889
  if (isRecord2(value)) return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
8889
8890
  return String(value);
8890
8891
  }
8892
+ function compactProfileSetupSummaryText(value, limit = 160) {
8893
+ const text = typeof value === "string" ? value.replace(/\s+/g, " ").trim() : "";
8894
+ if (!text) return void 0;
8895
+ if (text.length <= limit) return text;
8896
+ return `${text.slice(0, Math.max(0, limit - 15)).trimEnd()}... (${text.length} chars)`;
8897
+ }
8898
+ function profileSetupResultAction(value) {
8899
+ const action = value.action ?? value.type;
8900
+ return typeof action === "string" && action ? action : "unknown";
8901
+ }
8902
+ function profileSetupFrameUrls(viewport) {
8903
+ const urls = [];
8904
+ const frames = viewport.frames || {};
8905
+ for (const container of Object.values(frames)) {
8906
+ if (!isRecord2(container) || !Array.isArray(container.frames)) continue;
8907
+ for (const frame of container.frames) {
8908
+ if (!isRecord2(frame)) continue;
8909
+ const url = typeof frame.url === "string" ? frame.url : void 0;
8910
+ if (url && !urls.includes(url)) urls.push(url);
8911
+ }
8912
+ }
8913
+ return urls.slice(0, 10);
8914
+ }
8915
+ function profileSetupActionCounts(results) {
8916
+ const counts = {};
8917
+ for (const result of results) {
8918
+ const action = profileSetupResultAction(result);
8919
+ counts[action] = (counts[action] || 0) + 1;
8920
+ }
8921
+ return toJsonValue(counts);
8922
+ }
8923
+ function profileSetupSummary(viewports, actionCount) {
8924
+ return toJsonValue({
8925
+ viewport_count: viewports.length,
8926
+ action_count: actionCount ?? null,
8927
+ viewports: viewports.map((viewport) => {
8928
+ const results = viewport.setup_action_results || [];
8929
+ const failed = results.filter((result) => result.ok === false);
8930
+ const clicked = results.filter((result) => profileSetupResultAction(result) === "click" && result.ok !== false).map((result) => ({
8931
+ ordinal: result.ordinal ?? null,
8932
+ selector: result.selector ?? null,
8933
+ frame_selector: result.frame_selector ?? null,
8934
+ text: compactProfileSetupSummaryText(result.text)
8935
+ })).slice(0, 8);
8936
+ const text_samples = results.filter((result) => result.ok !== false && typeof result.text === "string" && (profileSetupResultAction(result) === "assert_text_visible" || profileSetupResultAction(result) === "assert_text_absent" || profileSetupResultAction(result) === "wait_for_text")).map((result) => ({
8937
+ ordinal: result.ordinal ?? null,
8938
+ action: profileSetupResultAction(result),
8939
+ frame_selector: result.frame_selector ?? null,
8940
+ text: compactProfileSetupSummaryText(result.text)
8941
+ })).filter((item) => item.text).slice(-6);
8942
+ return {
8943
+ name: viewport.name,
8944
+ ok: (actionCount === void 0 ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
8945
+ result_count: results.length,
8946
+ observed_path: viewport.route?.observed ?? null,
8947
+ final_url: viewport.url ?? null,
8948
+ action_counts: profileSetupActionCounts(results),
8949
+ frame_action_count: results.filter((result) => result.frame_selector).length,
8950
+ frame_urls: profileSetupFrameUrls(viewport),
8951
+ clicked,
8952
+ text_samples,
8953
+ failed: failed.map((result) => ({
8954
+ ordinal: result.ordinal ?? null,
8955
+ action: profileSetupResultAction(result),
8956
+ selector: result.selector ?? null,
8957
+ frame_selector: result.frame_selector ?? null,
8958
+ reason: result.reason ?? result.error ?? null
8959
+ }))
8960
+ };
8961
+ })
8962
+ });
8963
+ }
8891
8964
  function normalizeName(value, fallback) {
8892
8965
  const name = stringValue5(value) || fallback;
8893
8966
  return name.replace(/\s+/g, " ").trim();
@@ -8918,7 +8991,7 @@ function isSupportedCheckType(value) {
8918
8991
  }
8919
8992
  function normalizeSetupActionType(value, index) {
8920
8993
  const normalizedInput = String(value || "").trim().replace(/-/g, "_");
8921
- const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput;
8994
+ 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
8995
  if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
8923
8996
  return normalized;
8924
8997
  }
@@ -8948,6 +9021,13 @@ function normalizeSetupActionRepeat(input, index) {
8948
9021
  }
8949
9022
  return repeat;
8950
9023
  }
9024
+ function normalizeSetupActionCoordinateMode(value, index) {
9025
+ if (value === void 0 || value === null || value === "") return void 0;
9026
+ const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
9027
+ if (normalized === "pixels" || normalized === "pixel" || normalized === "px") return "pixels";
9028
+ if (normalized === "ratio" || normalized === "relative" || normalized === "fraction") return "ratio";
9029
+ throw new Error(`target.setup_actions[${index}].coordinate_mode ${String(value)} is not supported. Supported coordinate modes: pixels, ratio.`);
9030
+ }
8951
9031
  function normalizeSetupAction(input, index) {
8952
9032
  if (!isRecord2(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
8953
9033
  const type = normalizeSetupActionType(stringValue5(input.type), index);
@@ -8957,9 +9037,25 @@ function normalizeSetupAction(input, index) {
8957
9037
  if (frameIndex !== void 0 && (!Number.isInteger(frameIndex) || frameIndex < 0)) {
8958
9038
  throw new Error(`target.setup_actions[${index}].frame_index must be a non-negative integer.`);
8959
9039
  }
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) {
9040
+ 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
9041
  throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
8962
9042
  }
9043
+ const fromX = numberValue3(valueFromOwn(input, "from_x", "fromX", "start_x", "startX", "x1"));
9044
+ const fromY = numberValue3(valueFromOwn(input, "from_y", "fromY", "start_y", "startY", "y1"));
9045
+ const toX = numberValue3(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
9046
+ const toY = numberValue3(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
9047
+ const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
9048
+ if (type === "drag") {
9049
+ if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
9050
+ throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
9051
+ }
9052
+ if (coordinateMode === "ratio" && [fromX, fromY, toX, toY].some((value2) => value2 < 0 || value2 > 1)) {
9053
+ throw new Error(`target.setup_actions[${index}] drag ratio coordinates must be between 0 and 1.`);
9054
+ }
9055
+ if ((coordinateMode === void 0 || coordinateMode === "pixels") && [fromX, fromY, toX, toY].some((value2) => value2 < 0)) {
9056
+ throw new Error(`target.setup_actions[${index}] drag pixel coordinates must be non-negative.`);
9057
+ }
9058
+ }
8963
9059
  if (type === "wait_for_text" && !stringValue5(input.text) && !stringValue5(input.pattern)) {
8964
9060
  throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
8965
9061
  }
@@ -9006,12 +9102,23 @@ function normalizeSetupAction(input, index) {
9006
9102
  }
9007
9103
  }
9008
9104
  const hasExpectedReturn = hasOwn(input, "expect_return") || hasOwn(input, "expectReturn") || hasOwn(input, "expected_return") || hasOwn(input, "expectedReturn");
9105
+ const steps = numberValue3(input.steps);
9106
+ if (type === "drag" && steps !== void 0 && (!Number.isInteger(steps) || steps < 1 || steps > 100)) {
9107
+ throw new Error(`target.setup_actions[${index}].steps must be an integer from 1 to 100.`);
9108
+ }
9009
9109
  return {
9010
9110
  type,
9011
9111
  selector,
9012
9112
  frame_selector: frameSelector,
9013
9113
  frame_index: frameIndex,
9014
9114
  force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
9115
+ coordinate_mode: coordinateMode,
9116
+ from_x: fromX,
9117
+ from_y: fromY,
9118
+ to_x: toX,
9119
+ to_y: toY,
9120
+ duration_ms: numberValue3(input.duration_ms) ?? numberValue3(input.durationMs),
9121
+ steps,
9015
9122
  key,
9016
9123
  value,
9017
9124
  value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
@@ -9960,6 +10067,7 @@ function assessSetupActionsFromEvidence(profile, evidence) {
9960
10067
  ok: (viewport.setup_action_results || []).length >= actionCount && (viewport.setup_action_results || []).every((result) => result.ok !== false),
9961
10068
  result_count: (viewport.setup_action_results || []).length
9962
10069
  })),
10070
+ setup_summary: profileSetupSummary(viewports, actionCount),
9963
10071
  failed
9964
10072
  },
9965
10073
  message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
@@ -10373,6 +10481,90 @@ function requiredNetworkMockHitCount(mock) {
10373
10481
  if (Array.isArray(mock.responses) && mock.responses.length) return mock.responses.length;
10374
10482
  return 1;
10375
10483
  }
10484
+ function compactProfileSetupSummaryText(value, limit) {
10485
+ limit = limit || 160;
10486
+ const text = typeof value === "string" ? value.replace(/\\s+/g, " ").trim() : "";
10487
+ if (!text) return undefined;
10488
+ if (text.length <= limit) return text;
10489
+ return text.slice(0, Math.max(0, limit - 15)).trimEnd() + "... (" + text.length + " chars)";
10490
+ }
10491
+ function profileSetupResultAction(result) {
10492
+ const action = result && (result.action || result.type);
10493
+ return typeof action === "string" && action ? action : "unknown";
10494
+ }
10495
+ function profileSetupFrameUrls(viewport) {
10496
+ const urls = [];
10497
+ const frames = viewport && viewport.frames || {};
10498
+ for (const container of Object.values(frames)) {
10499
+ if (!container || typeof container !== "object" || Array.isArray(container) || !Array.isArray(container.frames)) continue;
10500
+ for (const frame of container.frames) {
10501
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) continue;
10502
+ const url = typeof frame.url === "string" ? frame.url : null;
10503
+ if (url && !urls.includes(url)) urls.push(url);
10504
+ }
10505
+ }
10506
+ return urls.slice(0, 10);
10507
+ }
10508
+ function profileSetupActionCounts(results) {
10509
+ const counts = {};
10510
+ for (const result of results || []) {
10511
+ const action = profileSetupResultAction(result);
10512
+ counts[action] = (counts[action] || 0) + 1;
10513
+ }
10514
+ return counts;
10515
+ }
10516
+ function profileSetupSummary(viewports, actionCount) {
10517
+ return {
10518
+ viewport_count: (viewports || []).length,
10519
+ action_count: actionCount ?? null,
10520
+ viewports: (viewports || []).map((viewport) => {
10521
+ const results = viewport.setup_action_results || [];
10522
+ const failed = results.filter((result) => result && result.ok === false);
10523
+ const clicked = results
10524
+ .filter((result) => result && profileSetupResultAction(result) === "click" && result.ok !== false)
10525
+ .map((result) => ({
10526
+ ordinal: result.ordinal ?? null,
10527
+ selector: result.selector ?? null,
10528
+ frame_selector: result.frame_selector ?? null,
10529
+ text: compactProfileSetupSummaryText(result.text),
10530
+ }))
10531
+ .slice(0, 8);
10532
+ const textSamples = results
10533
+ .filter((result) => result && result.ok !== false && typeof result.text === "string" && (
10534
+ profileSetupResultAction(result) === "assert_text_visible"
10535
+ || profileSetupResultAction(result) === "assert_text_absent"
10536
+ || profileSetupResultAction(result) === "wait_for_text"
10537
+ ))
10538
+ .map((result) => ({
10539
+ ordinal: result.ordinal ?? null,
10540
+ action: profileSetupResultAction(result),
10541
+ frame_selector: result.frame_selector ?? null,
10542
+ text: compactProfileSetupSummaryText(result.text),
10543
+ }))
10544
+ .filter((item) => item.text)
10545
+ .slice(-6);
10546
+ return {
10547
+ name: viewport.name,
10548
+ ok: (actionCount === undefined ? results.length > 0 : results.length >= actionCount) && failed.length === 0,
10549
+ result_count: results.length,
10550
+ observed_path: viewport.route && viewport.route.observed || null,
10551
+ final_url: viewport.url || null,
10552
+ action_counts: profileSetupActionCounts(results),
10553
+ frame_action_count: results.filter((result) => result && result.frame_selector).length,
10554
+ frame_urls: profileSetupFrameUrls(viewport),
10555
+ clicked,
10556
+ text_samples: textSamples,
10557
+ failed: failed.map((result) => ({
10558
+ ordinal: result.ordinal ?? null,
10559
+ action: profileSetupResultAction(result),
10560
+ selector: result.selector ?? null,
10561
+ frame_selector: result.frame_selector ?? null,
10562
+ reason: result.reason || result.error || null,
10563
+ })),
10564
+ };
10565
+ }),
10566
+ };
10567
+ }
10376
10568
  function assessProfile(profile, evidence) {
10377
10569
  const checks = [];
10378
10570
  const viewports = evidence.viewports || [];
@@ -10477,6 +10669,7 @@ function assessProfile(profile, evidence) {
10477
10669
  && (viewport.setup_action_results || []).every((result) => !result || result.ok !== false),
10478
10670
  result_count: (viewport.setup_action_results || []).length,
10479
10671
  })),
10672
+ setup_summary: profileSetupSummary(viewports, actionCount),
10480
10673
  failed,
10481
10674
  },
10482
10675
  message: failed.length ? "Setup actions failed in " + failed.length + " viewport action(s)." : undefined,
@@ -11219,6 +11412,71 @@ async function executeSetupAction(action, ordinal) {
11219
11412
  await scope.context.waitForSelector(action.selector, { state: "visible", timeout });
11220
11413
  return { ...base, ...setupScopeEvidence(scope), ok: true, timeout_ms: timeout };
11221
11414
  }
11415
+ if (type === "drag") {
11416
+ const scope = await setupActionScope(action, timeout);
11417
+ if (!scope.ok) return setupScopeFailure(base, scope);
11418
+ const locator = scope.context.locator(action.selector);
11419
+ const count = await locator.count();
11420
+ if (!count) return { ...base, ...setupScopeEvidence(scope), reason: "selector_not_found", count };
11421
+ const targetIndex = Number.isInteger(action.index) ? action.index : 0;
11422
+ if (targetIndex < 0 || targetIndex >= count) return { ...base, ...setupScopeEvidence(scope), reason: "index_out_of_range", count, target_index: targetIndex };
11423
+ const target = locator.nth(targetIndex);
11424
+ await target.waitFor({ state: "visible", timeout });
11425
+ const box = await target.boundingBox();
11426
+ if (!box) return { ...base, ...setupScopeEvidence(scope), reason: "bounding_box_unavailable", count, target_index: targetIndex };
11427
+ const mode = String(action.coordinate_mode || action.coordinateMode || "pixels").trim();
11428
+ const coordinate = (value, size) => mode === "ratio" ? value * size : value;
11429
+ const fromX = setupFiniteNumber(action.from_x ?? action.fromX ?? action.start_x ?? action.startX ?? action.x1);
11430
+ const fromY = setupFiniteNumber(action.from_y ?? action.fromY ?? action.start_y ?? action.startY ?? action.y1);
11431
+ const toX = setupFiniteNumber(action.to_x ?? action.toX ?? action.end_x ?? action.endX ?? action.x2);
11432
+ const toY = setupFiniteNumber(action.to_y ?? action.toY ?? action.end_y ?? action.endY ?? action.y2);
11433
+ if (fromX === undefined || fromY === undefined || toX === undefined || toY === undefined) return { ...base, ...setupScopeEvidence(scope), reason: "missing_drag_coordinates", count, target_index: targetIndex };
11434
+ 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 };
11435
+ if (mode !== "ratio" && [fromX, fromY, toX, toY].some((value) => value < 0)) return { ...base, ...setupScopeEvidence(scope), reason: "invalid_pixel_coordinates", count, target_index: targetIndex };
11436
+ const start = {
11437
+ x: box.x + coordinate(fromX, box.width),
11438
+ y: box.y + coordinate(fromY, box.height),
11439
+ };
11440
+ const end = {
11441
+ x: box.x + coordinate(toX, box.width),
11442
+ y: box.y + coordinate(toY, box.height),
11443
+ };
11444
+ const requestedSteps = setupNumber(action.steps, 8);
11445
+ const steps = Math.min(100, Math.max(1, Math.floor(requestedSteps || 8)));
11446
+ const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
11447
+ await page.mouse.move(start.x, start.y);
11448
+ await page.mouse.down();
11449
+ try {
11450
+ if (durationMs && steps > 1) {
11451
+ for (let step = 1; step <= steps; step += 1) {
11452
+ const progress = step / steps;
11453
+ await page.mouse.move(
11454
+ start.x + (end.x - start.x) * progress,
11455
+ start.y + (end.y - start.y) * progress,
11456
+ );
11457
+ await page.waitForTimeout(durationMs / steps);
11458
+ }
11459
+ } else {
11460
+ await page.mouse.move(end.x, end.y, { steps });
11461
+ }
11462
+ } finally {
11463
+ await page.mouse.up().catch(() => {});
11464
+ }
11465
+ return {
11466
+ ...base,
11467
+ ...setupScopeEvidence(scope),
11468
+ ok: true,
11469
+ count,
11470
+ target_index: targetIndex,
11471
+ coordinate_mode: mode,
11472
+ from_x: fromX,
11473
+ from_y: fromY,
11474
+ to_x: toX,
11475
+ to_y: toY,
11476
+ steps,
11477
+ duration_ms: durationMs || undefined,
11478
+ };
11479
+ }
11222
11480
  if (type === "press") {
11223
11481
  const key = String(action.key || "").trim();
11224
11482
  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-FLQ4HHTT.js";
61
+ } from "./chunk-MIHU2AWC.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,