@riddledc/riddle-proof 0.7.129 → 0.7.131

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
@@ -9340,6 +9340,17 @@ function normalizeSetupActionCoordinateMode(value, index) {
9340
9340
  if (normalized === "ratio" || normalized === "relative" || normalized === "fraction") return "ratio";
9341
9341
  throw new Error(`target.setup_actions[${index}].coordinate_mode ${String(value)} is not supported. Supported coordinate modes: pixels, ratio.`);
9342
9342
  }
9343
+ function normalizeSetupActionPointerType(value, type, index) {
9344
+ if (value === void 0 || value === null || value === "") return void 0;
9345
+ if (type !== "drag") {
9346
+ throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag actions.`);
9347
+ }
9348
+ const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
9349
+ if (normalized === "mouse") return "mouse";
9350
+ if (normalized === "touch" || normalized === "finger") return "touch";
9351
+ if (normalized === "pen" || normalized === "stylus") return "pen";
9352
+ throw new Error(`target.setup_actions[${index}].pointer_type ${String(value)} is not supported. Supported pointer types: mouse, touch, pen.`);
9353
+ }
9343
9354
  function normalizeSetupAction(input, index) {
9344
9355
  if (!isRecord2(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
9345
9356
  const type = normalizeSetupActionType(stringValue5(input.type), index);
@@ -9358,6 +9369,7 @@ function normalizeSetupAction(input, index) {
9358
9369
  const toX = numberValue3(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
9359
9370
  const toY = numberValue3(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
9360
9371
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
9372
+ const pointerType = normalizeSetupActionPointerType(valueFromOwn(input, "pointer_type", "pointerType", "input_type", "inputType"), type, index);
9361
9373
  if (type === "drag") {
9362
9374
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
9363
9375
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -9442,6 +9454,7 @@ function normalizeSetupAction(input, index) {
9442
9454
  force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
9443
9455
  click_count: normalizeSetupActionClickCount(input, type, index),
9444
9456
  coordinate_mode: coordinateMode,
9457
+ pointer_type: pointerType,
9445
9458
  from_x: fromX,
9446
9459
  from_y: fromY,
9447
9460
  to_x: toX,
@@ -10620,6 +10633,27 @@ function textMatchSamples(sample, check) {
10620
10633
  const sampleText = textSampleAroundMatch(source, index, text.length);
10621
10634
  return sampleText ? [sampleText] : [];
10622
10635
  }
10636
+ function textCaseInsensitiveSamples(sample, check) {
10637
+ const source = String(sample || "");
10638
+ const text = check.pattern ? "" : check.text || "";
10639
+ if (!source || !text) return [];
10640
+ const index = source.toLowerCase().indexOf(text.toLowerCase());
10641
+ const sampleText = textSampleAroundMatch(source, index, text.length);
10642
+ return sampleText ? [sampleText] : [];
10643
+ }
10644
+ function textCaseInsensitiveSequenceSamples(texts, check) {
10645
+ const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
10646
+ if (!text) return [];
10647
+ const expected = text.toLowerCase();
10648
+ return texts.map((candidate) => compactTextEvidenceSample(candidate)).filter((candidate) => candidate && candidate.toLowerCase().includes(expected)).slice(0, 3).map((candidate) => candidate.slice(0, 240));
10649
+ }
10650
+ function textCaseInsensitiveFailureSamples(viewport, check) {
10651
+ const key = textKey(check);
10652
+ const captured = viewport.text_case_insensitive_samples?.[key] || [];
10653
+ const capturedSamples = captured.map((sample) => compactTextEvidenceSample(sample).slice(0, 240)).filter(Boolean);
10654
+ if (capturedSamples.length) return capturedSamples.slice(0, 3);
10655
+ return textCaseInsensitiveSamples(viewport.body_text_sample || "", check).slice(0, 3);
10656
+ }
10623
10657
  function textCheckFailureSamples(viewport, check) {
10624
10658
  const key = textKey(check);
10625
10659
  const captured = viewport.text_match_samples?.[key] || [];
@@ -10932,13 +10966,15 @@ function assessCheckFromEvidence(check, evidence) {
10932
10966
  const matched = matches.length > 0;
10933
10967
  const failedAgainstExpectation = matched !== expectedVisible;
10934
10968
  const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
10969
+ const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveSequenceSamples(texts, check) : [];
10935
10970
  return {
10936
10971
  viewport: viewport.name,
10937
10972
  selector_count: viewport.selectors?.[key]?.count || 0,
10938
10973
  visible_count: viewport.selectors?.[key]?.visible_count || 0,
10939
10974
  matched_count: matches.length,
10940
10975
  matched,
10941
- samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240))
10976
+ samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
10977
+ case_insensitive_samples: caseInsensitiveSamples
10942
10978
  };
10943
10979
  });
10944
10980
  const failed = results.filter((result) => result.matched !== expectedVisible).length;
@@ -11081,7 +11117,8 @@ function assessCheckFromEvidence(check, evidence) {
11081
11117
  return {
11082
11118
  viewport: viewport.name,
11083
11119
  matched,
11084
- samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : []
11120
+ samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
11121
+ case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveFailureSamples(viewport, check) : []
11085
11122
  };
11086
11123
  });
11087
11124
  const matches = results.map((result) => result.matched);
@@ -11711,6 +11748,32 @@ function textMatchSamples(sample, check) {
11711
11748
  const sampleText = textSampleAroundMatch(source, source.indexOf(text), text.length);
11712
11749
  return sampleText ? [sampleText] : [];
11713
11750
  }
11751
+ function textCaseInsensitiveSamples(sample, check) {
11752
+ const source = String(sample || "");
11753
+ const text = check.pattern ? "" : check.text || "";
11754
+ if (!source || !text) return [];
11755
+ const sampleText = textSampleAroundMatch(source, source.toLowerCase().indexOf(text.toLowerCase()), text.length);
11756
+ return sampleText ? [sampleText] : [];
11757
+ }
11758
+ function textCaseInsensitiveSequenceSamples(texts, check) {
11759
+ const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
11760
+ if (!text) return [];
11761
+ const expected = text.toLowerCase();
11762
+ return (texts || [])
11763
+ .map((candidate) => compactTextEvidenceSample(candidate))
11764
+ .filter((candidate) => candidate && candidate.toLowerCase().includes(expected))
11765
+ .slice(0, 3)
11766
+ .map((candidate) => candidate.slice(0, 240));
11767
+ }
11768
+ function textCaseInsensitiveFailureSamples(viewport, check) {
11769
+ const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
11770
+ const captured = viewport && viewport.text_case_insensitive_samples && Array.isArray(viewport.text_case_insensitive_samples[key]) ? viewport.text_case_insensitive_samples[key] : [];
11771
+ const capturedSamples = captured
11772
+ .map((sample) => compactTextEvidenceSample(sample).slice(0, 240))
11773
+ .filter(Boolean);
11774
+ if (capturedSamples.length) return capturedSamples.slice(0, 3);
11775
+ return textCaseInsensitiveSamples(viewport && viewport.body_text_sample || "", check).slice(0, 3);
11776
+ }
11714
11777
  function textCheckFailureSamples(viewport, check) {
11715
11778
  const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
11716
11779
  const captured = viewport && viewport.text_match_samples && Array.isArray(viewport.text_match_samples[key]) ? viewport.text_match_samples[key] : [];
@@ -12669,6 +12732,9 @@ function assessProfile(profile, evidence) {
12669
12732
  const matched = matches.length > 0;
12670
12733
  const failedAgainstExpectation = matched !== expectedVisible;
12671
12734
  const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
12735
+ const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched
12736
+ ? textCaseInsensitiveSequenceSamples(texts, check)
12737
+ : [];
12672
12738
  return {
12673
12739
  viewport: viewport.name,
12674
12740
  selector_count: viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].count : 0,
@@ -12676,6 +12742,7 @@ function assessProfile(profile, evidence) {
12676
12742
  matched_count: matches.length,
12677
12743
  matched,
12678
12744
  samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
12745
+ case_insensitive_samples: caseInsensitiveSamples,
12679
12746
  };
12680
12747
  });
12681
12748
  const failed = results.filter((result) => result.matched !== expectedVisible).length;
@@ -12807,6 +12874,9 @@ function assessProfile(profile, evidence) {
12807
12874
  viewport: viewport.name,
12808
12875
  matched,
12809
12876
  samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
12877
+ case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched
12878
+ ? textCaseInsensitiveFailureSamples(viewport, check)
12879
+ : [],
12810
12880
  };
12811
12881
  });
12812
12882
  const matches = results.map((result) => result.matched);
@@ -13196,6 +13266,14 @@ function setupTextMatches(sample, action) {
13196
13266
  return rawSample.includes(expected)
13197
13267
  || normalizeSetupMatchText(rawSample).includes(normalizeSetupMatchText(expected));
13198
13268
  }
13269
+ function setupCaseInsensitiveTextSample(sample, action) {
13270
+ if (!action || action.pattern || !action.text) return "";
13271
+ const normalizedSample = normalizeSetupMatchText(sample);
13272
+ const normalizedExpected = normalizeSetupMatchText(action.text);
13273
+ if (!normalizedSample || !normalizedExpected) return "";
13274
+ if (!normalizedSample.toLowerCase().includes(normalizedExpected.toLowerCase())) return "";
13275
+ return compactSetupResultText(normalizedSample);
13276
+ }
13199
13277
  async function waitForAnyVisibleSelector(context, selector, timeout) {
13200
13278
  const deadline = Date.now() + setupNumber(timeout, 15000);
13201
13279
  let lastReason = "selector_not_found";
@@ -13642,23 +13720,75 @@ async function executeSetupAction(action, ordinal, viewport) {
13642
13720
  const requestedSteps = setupNumber(action.steps, 8);
13643
13721
  const steps = Math.min(100, Math.max(1, Math.floor(requestedSteps || 8)));
13644
13722
  const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
13645
- await page.mouse.move(start.x, start.y);
13646
- await page.mouse.down();
13647
- try {
13648
- if (durationMs && steps > 1) {
13649
- for (let step = 1; step <= steps; step += 1) {
13650
- const progress = step / steps;
13651
- await page.mouse.move(
13652
- start.x + (end.x - start.x) * progress,
13653
- start.y + (end.y - start.y) * progress,
13654
- );
13655
- await page.waitForTimeout(durationMs / steps);
13723
+ const pointerType = String(action.pointer_type || action.pointerType || "mouse").trim().toLowerCase();
13724
+ if (pointerType === "touch" || pointerType === "pen") {
13725
+ const localStart = {
13726
+ x: coordinate(fromX, box.width),
13727
+ y: coordinate(fromY, box.height),
13728
+ };
13729
+ const localEnd = {
13730
+ x: coordinate(toX, box.width),
13731
+ y: coordinate(toY, box.height),
13732
+ };
13733
+ await target.evaluate(async (element, payload) => {
13734
+ const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
13735
+ const rect = element.getBoundingClientRect();
13736
+ const pointerId = payload.pointerType === "touch" ? 11 : 12;
13737
+ const point = (progress) => ({
13738
+ clientX: rect.left + payload.start.x + (payload.end.x - payload.start.x) * progress,
13739
+ clientY: rect.top + payload.start.y + (payload.end.y - payload.start.y) * progress,
13740
+ });
13741
+ const dispatch = (type, progress) => {
13742
+ const coords = point(progress);
13743
+ element.dispatchEvent(new PointerEvent(type, {
13744
+ bubbles: true,
13745
+ cancelable: true,
13746
+ composed: true,
13747
+ pointerId,
13748
+ pointerType: payload.pointerType,
13749
+ isPrimary: true,
13750
+ buttons: type === "pointerup" ? 0 : 1,
13751
+ button: type === "pointerup" ? 0 : 0,
13752
+ clientX: coords.clientX,
13753
+ clientY: coords.clientY,
13754
+ }));
13755
+ };
13756
+ dispatch("pointerover", 0);
13757
+ dispatch("pointerenter", 0);
13758
+ dispatch("pointerdown", 0);
13759
+ for (let step = 1; step <= payload.steps; step += 1) {
13760
+ dispatch("pointermove", step / payload.steps);
13761
+ if (payload.durationMs && payload.steps > 1) await wait(payload.durationMs / payload.steps);
13656
13762
  }
13657
- } else {
13658
- await page.mouse.move(end.x, end.y, { steps });
13763
+ dispatch("pointerup", 1);
13764
+ dispatch("pointerout", 1);
13765
+ dispatch("pointerleave", 1);
13766
+ }, {
13767
+ pointerType,
13768
+ start: localStart,
13769
+ end: localEnd,
13770
+ steps,
13771
+ durationMs,
13772
+ });
13773
+ } else {
13774
+ await page.mouse.move(start.x, start.y);
13775
+ await page.mouse.down();
13776
+ try {
13777
+ if (durationMs && steps > 1) {
13778
+ for (let step = 1; step <= steps; step += 1) {
13779
+ const progress = step / steps;
13780
+ await page.mouse.move(
13781
+ start.x + (end.x - start.x) * progress,
13782
+ start.y + (end.y - start.y) * progress,
13783
+ );
13784
+ await page.waitForTimeout(durationMs / steps);
13785
+ }
13786
+ } else {
13787
+ await page.mouse.move(end.x, end.y, { steps });
13788
+ }
13789
+ } finally {
13790
+ await page.mouse.up().catch(() => {});
13659
13791
  }
13660
- } finally {
13661
- await page.mouse.up().catch(() => {});
13662
13792
  }
13663
13793
  return {
13664
13794
  ...base,
@@ -13671,6 +13801,7 @@ async function executeSetupAction(action, ordinal, viewport) {
13671
13801
  from_y: fromY,
13672
13802
  to_x: toX,
13673
13803
  to_y: toY,
13804
+ pointer_type: pointerType,
13674
13805
  steps,
13675
13806
  duration_ms: durationMs || undefined,
13676
13807
  };
@@ -13893,6 +14024,7 @@ async function executeSetupAction(action, ordinal, viewport) {
13893
14024
  if (!count) return { ...base, reason: "selector_not_found", count };
13894
14025
  let targetIndex = Number.isInteger(action.index) ? action.index : 0;
13895
14026
  let matchedText = null;
14027
+ let caseInsensitiveText = null;
13896
14028
  let hiddenMatchIndex = -1;
13897
14029
  let hiddenMatchedText = null;
13898
14030
  if (action.text || action.pattern) {
@@ -13910,10 +14042,12 @@ async function executeSetupAction(action, ordinal, viewport) {
13910
14042
  hiddenMatchIndex = index;
13911
14043
  hiddenMatchedText = compactSetupResultText(text);
13912
14044
  }
14045
+ } else if (!caseInsensitiveText) {
14046
+ caseInsensitiveText = setupCaseInsensitiveTextSample(text, action) || null;
13913
14047
  }
13914
14048
  }
13915
14049
  if (targetIndex < 0 && hiddenMatchIndex >= 0) return { ...base, reason: "matching_element_not_visible", count, target_index: hiddenMatchIndex, text: hiddenMatchedText };
13916
- if (targetIndex < 0) return { ...base, reason: "text_not_found", count };
14050
+ if (targetIndex < 0) return { ...base, reason: "text_not_found", count, case_insensitive_text: caseInsensitiveText || undefined };
13917
14051
  }
13918
14052
  if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
13919
14053
  const clickOptions = action.force === true
@@ -13957,6 +14091,7 @@ async function executeSetupAction(action, ordinal, viewport) {
13957
14091
  const locator = scope.context.locator(action.selector);
13958
14092
  const startedAt = Date.now();
13959
14093
  let lastText = "";
14094
+ let caseInsensitiveText = "";
13960
14095
  while (Date.now() - startedAt <= timeout) {
13961
14096
  const count = await locator.count().catch(() => 0);
13962
14097
  for (let index = 0; index < count; index += 1) {
@@ -13965,10 +14100,11 @@ async function executeSetupAction(action, ordinal, viewport) {
13965
14100
  if (setupTextMatches(text, action)) {
13966
14101
  return { ...base, ...setupScopeEvidence(scope), ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
13967
14102
  }
14103
+ caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
13968
14104
  }
13969
14105
  await page.waitForTimeout(100);
13970
14106
  }
13971
- return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
14107
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
13972
14108
  }
13973
14109
  if (type === "assert_text_visible" || type === "assert_text_absent") {
13974
14110
  const scope = await setupActionScope(action, timeout);
@@ -13977,6 +14113,7 @@ async function executeSetupAction(action, ordinal, viewport) {
13977
14113
  const startedAt = Date.now();
13978
14114
  let lastText = "";
13979
14115
  let matchedText = "";
14116
+ let caseInsensitiveText = "";
13980
14117
  let hiddenMatch = false;
13981
14118
  while (Date.now() - startedAt <= timeout) {
13982
14119
  const count = await locator.count().catch(() => 0);
@@ -13999,6 +14136,7 @@ async function executeSetupAction(action, ordinal, viewport) {
13999
14136
  }
14000
14137
  break;
14001
14138
  }
14139
+ caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
14002
14140
  }
14003
14141
  if (type === "assert_text_absent" && !matched) {
14004
14142
  return { ...base, ...setupScopeEvidence(scope), ok: true, count, timeout_ms: timeout };
@@ -14009,7 +14147,7 @@ async function executeSetupAction(action, ordinal, viewport) {
14009
14147
  if (hiddenMatch) {
14010
14148
  return { ...base, ...setupScopeEvidence(scope), reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
14011
14149
  }
14012
- return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
14150
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
14013
14151
  }
14014
14152
  return { ...base, ...setupScopeEvidence(scope), reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
14015
14153
  }
@@ -15117,6 +15255,7 @@ async function captureViewport(viewport) {
15117
15255
  const text_sequences = {};
15118
15256
  const text_matches = {};
15119
15257
  const text_match_samples = {};
15258
+ const text_case_insensitive_samples = {};
15120
15259
  const http_statuses = {};
15121
15260
  const link_statuses = {};
15122
15261
  for (const check of profile.checks || []) {
@@ -15142,6 +15281,7 @@ async function captureViewport(viewport) {
15142
15281
  const sample = dom.body_text || dom.body_text_sample || "";
15143
15282
  text_matches[key] = textMatches(sample, check);
15144
15283
  text_match_samples[key] = textMatchSamples(sample, check);
15284
+ text_case_insensitive_samples[key] = textCaseInsensitiveSamples(sample, check);
15145
15285
  }
15146
15286
  if ((check.type === "frame_text_visible" || check.type === "frame_url_equals" || check.type === "frame_url_matches" || check.type === "frame_no_horizontal_overflow") && check.selector) {
15147
15287
  selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
@@ -15219,6 +15359,7 @@ async function captureViewport(viewport) {
15219
15359
  text_sequences,
15220
15360
  text_matches,
15221
15361
  text_match_samples,
15362
+ text_case_insensitive_samples,
15222
15363
  http_statuses,
15223
15364
  link_statuses,
15224
15365
  route_inventory: routeInventory,
package/dist/index.js CHANGED
@@ -62,7 +62,7 @@ import {
62
62
  resolveRiddleProofProfileTimeoutSec,
63
63
  slugifyRiddleProofProfileName,
64
64
  summarizeRiddleProofProfileResult
65
- } from "./chunk-TDK6WFH3.js";
65
+ } from "./chunk-ZYD2SGEM.js";
66
66
  import {
67
67
  DEFAULT_RIDDLE_API_BASE_URL,
68
68
  DEFAULT_RIDDLE_API_KEY_FILE,