@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/cli.cjs CHANGED
@@ -7544,6 +7544,17 @@ function normalizeSetupActionCoordinateMode(value, index) {
7544
7544
  if (normalized === "ratio" || normalized === "relative" || normalized === "fraction") return "ratio";
7545
7545
  throw new Error(`target.setup_actions[${index}].coordinate_mode ${String(value)} is not supported. Supported coordinate modes: pixels, ratio.`);
7546
7546
  }
7547
+ function normalizeSetupActionPointerType(value, type, index) {
7548
+ if (value === void 0 || value === null || value === "") return void 0;
7549
+ if (type !== "drag") {
7550
+ throw new Error(`target.setup_actions[${index}].pointer_type is only supported for drag actions.`);
7551
+ }
7552
+ const normalized = String(value).trim().replace(/-/g, "_").toLowerCase();
7553
+ if (normalized === "mouse") return "mouse";
7554
+ if (normalized === "touch" || normalized === "finger") return "touch";
7555
+ if (normalized === "pen" || normalized === "stylus") return "pen";
7556
+ throw new Error(`target.setup_actions[${index}].pointer_type ${String(value)} is not supported. Supported pointer types: mouse, touch, pen.`);
7557
+ }
7547
7558
  function normalizeSetupAction(input, index) {
7548
7559
  if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
7549
7560
  const type = normalizeSetupActionType(stringValue2(input.type), index);
@@ -7562,6 +7573,7 @@ function normalizeSetupAction(input, index) {
7562
7573
  const toX = numberValue(valueFromOwn(input, "to_x", "toX", "end_x", "endX", "x2"));
7563
7574
  const toY = numberValue(valueFromOwn(input, "to_y", "toY", "end_y", "endY", "y2"));
7564
7575
  const coordinateMode = normalizeSetupActionCoordinateMode(valueFromOwn(input, "coordinate_mode", "coordinateMode", "coords", "units"), index);
7576
+ const pointerType = normalizeSetupActionPointerType(valueFromOwn(input, "pointer_type", "pointerType", "input_type", "inputType"), type, index);
7565
7577
  if (type === "drag") {
7566
7578
  if (fromX === void 0 || fromY === void 0 || toX === void 0 || toY === void 0) {
7567
7579
  throw new Error(`target.setup_actions[${index}] drag requires from_x, from_y, to_x, and to_y.`);
@@ -7646,6 +7658,7 @@ function normalizeSetupAction(input, index) {
7646
7658
  force: type === "click" && (input.force === true || input.force_click === true || input.forceClick === true),
7647
7659
  click_count: normalizeSetupActionClickCount(input, type, index),
7648
7660
  coordinate_mode: coordinateMode,
7661
+ pointer_type: pointerType,
7649
7662
  from_x: fromX,
7650
7663
  from_y: fromY,
7651
7664
  to_x: toX,
@@ -8824,6 +8837,27 @@ function textMatchSamples(sample, check) {
8824
8837
  const sampleText = textSampleAroundMatch(source, index, text.length);
8825
8838
  return sampleText ? [sampleText] : [];
8826
8839
  }
8840
+ function textCaseInsensitiveSamples(sample, check) {
8841
+ const source = String(sample || "");
8842
+ const text = check.pattern ? "" : check.text || "";
8843
+ if (!source || !text) return [];
8844
+ const index = source.toLowerCase().indexOf(text.toLowerCase());
8845
+ const sampleText = textSampleAroundMatch(source, index, text.length);
8846
+ return sampleText ? [sampleText] : [];
8847
+ }
8848
+ function textCaseInsensitiveSequenceSamples(texts, check) {
8849
+ const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
8850
+ if (!text) return [];
8851
+ const expected = text.toLowerCase();
8852
+ return texts.map((candidate) => compactTextEvidenceSample(candidate)).filter((candidate) => candidate && candidate.toLowerCase().includes(expected)).slice(0, 3).map((candidate) => candidate.slice(0, 240));
8853
+ }
8854
+ function textCaseInsensitiveFailureSamples(viewport, check) {
8855
+ const key = textKey(check);
8856
+ const captured = viewport.text_case_insensitive_samples?.[key] || [];
8857
+ const capturedSamples = captured.map((sample) => compactTextEvidenceSample(sample).slice(0, 240)).filter(Boolean);
8858
+ if (capturedSamples.length) return capturedSamples.slice(0, 3);
8859
+ return textCaseInsensitiveSamples(viewport.body_text_sample || "", check).slice(0, 3);
8860
+ }
8827
8861
  function textCheckFailureSamples(viewport, check) {
8828
8862
  const key = textKey(check);
8829
8863
  const captured = viewport.text_match_samples?.[key] || [];
@@ -9136,13 +9170,15 @@ function assessCheckFromEvidence(check, evidence) {
9136
9170
  const matched = matches.length > 0;
9137
9171
  const failedAgainstExpectation = matched !== expectedVisible;
9138
9172
  const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
9173
+ const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveSequenceSamples(texts, check) : [];
9139
9174
  return {
9140
9175
  viewport: viewport.name,
9141
9176
  selector_count: viewport.selectors?.[key]?.count || 0,
9142
9177
  visible_count: viewport.selectors?.[key]?.visible_count || 0,
9143
9178
  matched_count: matches.length,
9144
9179
  matched,
9145
- samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240))
9180
+ samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
9181
+ case_insensitive_samples: caseInsensitiveSamples
9146
9182
  };
9147
9183
  });
9148
9184
  const failed = results.filter((result) => result.matched !== expectedVisible).length;
@@ -9285,7 +9321,8 @@ function assessCheckFromEvidence(check, evidence) {
9285
9321
  return {
9286
9322
  viewport: viewport.name,
9287
9323
  matched,
9288
- samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : []
9324
+ samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
9325
+ case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveFailureSamples(viewport, check) : []
9289
9326
  };
9290
9327
  });
9291
9328
  const matches = results.map((result) => result.matched);
@@ -9899,6 +9936,32 @@ function textMatchSamples(sample, check) {
9899
9936
  const sampleText = textSampleAroundMatch(source, source.indexOf(text), text.length);
9900
9937
  return sampleText ? [sampleText] : [];
9901
9938
  }
9939
+ function textCaseInsensitiveSamples(sample, check) {
9940
+ const source = String(sample || "");
9941
+ const text = check.pattern ? "" : check.text || "";
9942
+ if (!source || !text) return [];
9943
+ const sampleText = textSampleAroundMatch(source, source.toLowerCase().indexOf(text.toLowerCase()), text.length);
9944
+ return sampleText ? [sampleText] : [];
9945
+ }
9946
+ function textCaseInsensitiveSequenceSamples(texts, check) {
9947
+ const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
9948
+ if (!text) return [];
9949
+ const expected = text.toLowerCase();
9950
+ return (texts || [])
9951
+ .map((candidate) => compactTextEvidenceSample(candidate))
9952
+ .filter((candidate) => candidate && candidate.toLowerCase().includes(expected))
9953
+ .slice(0, 3)
9954
+ .map((candidate) => candidate.slice(0, 240));
9955
+ }
9956
+ function textCaseInsensitiveFailureSamples(viewport, check) {
9957
+ const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
9958
+ const captured = viewport && viewport.text_case_insensitive_samples && Array.isArray(viewport.text_case_insensitive_samples[key]) ? viewport.text_case_insensitive_samples[key] : [];
9959
+ const capturedSamples = captured
9960
+ .map((sample) => compactTextEvidenceSample(sample).slice(0, 240))
9961
+ .filter(Boolean);
9962
+ if (capturedSamples.length) return capturedSamples.slice(0, 3);
9963
+ return textCaseInsensitiveSamples(viewport && viewport.body_text_sample || "", check).slice(0, 3);
9964
+ }
9902
9965
  function textCheckFailureSamples(viewport, check) {
9903
9966
  const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
9904
9967
  const captured = viewport && viewport.text_match_samples && Array.isArray(viewport.text_match_samples[key]) ? viewport.text_match_samples[key] : [];
@@ -10857,6 +10920,9 @@ function assessProfile(profile, evidence) {
10857
10920
  const matched = matches.length > 0;
10858
10921
  const failedAgainstExpectation = matched !== expectedVisible;
10859
10922
  const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
10923
+ const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched
10924
+ ? textCaseInsensitiveSequenceSamples(texts, check)
10925
+ : [];
10860
10926
  return {
10861
10927
  viewport: viewport.name,
10862
10928
  selector_count: viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].count : 0,
@@ -10864,6 +10930,7 @@ function assessProfile(profile, evidence) {
10864
10930
  matched_count: matches.length,
10865
10931
  matched,
10866
10932
  samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
10933
+ case_insensitive_samples: caseInsensitiveSamples,
10867
10934
  };
10868
10935
  });
10869
10936
  const failed = results.filter((result) => result.matched !== expectedVisible).length;
@@ -10995,6 +11062,9 @@ function assessProfile(profile, evidence) {
10995
11062
  viewport: viewport.name,
10996
11063
  matched,
10997
11064
  samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
11065
+ case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched
11066
+ ? textCaseInsensitiveFailureSamples(viewport, check)
11067
+ : [],
10998
11068
  };
10999
11069
  });
11000
11070
  const matches = results.map((result) => result.matched);
@@ -11384,6 +11454,14 @@ function setupTextMatches(sample, action) {
11384
11454
  return rawSample.includes(expected)
11385
11455
  || normalizeSetupMatchText(rawSample).includes(normalizeSetupMatchText(expected));
11386
11456
  }
11457
+ function setupCaseInsensitiveTextSample(sample, action) {
11458
+ if (!action || action.pattern || !action.text) return "";
11459
+ const normalizedSample = normalizeSetupMatchText(sample);
11460
+ const normalizedExpected = normalizeSetupMatchText(action.text);
11461
+ if (!normalizedSample || !normalizedExpected) return "";
11462
+ if (!normalizedSample.toLowerCase().includes(normalizedExpected.toLowerCase())) return "";
11463
+ return compactSetupResultText(normalizedSample);
11464
+ }
11387
11465
  async function waitForAnyVisibleSelector(context, selector, timeout) {
11388
11466
  const deadline = Date.now() + setupNumber(timeout, 15000);
11389
11467
  let lastReason = "selector_not_found";
@@ -11830,23 +11908,75 @@ async function executeSetupAction(action, ordinal, viewport) {
11830
11908
  const requestedSteps = setupNumber(action.steps, 8);
11831
11909
  const steps = Math.min(100, Math.max(1, Math.floor(requestedSteps || 8)));
11832
11910
  const durationMs = setupNumber(action.duration_ms ?? action.durationMs, 0);
11833
- await page.mouse.move(start.x, start.y);
11834
- await page.mouse.down();
11835
- try {
11836
- if (durationMs && steps > 1) {
11837
- for (let step = 1; step <= steps; step += 1) {
11838
- const progress = step / steps;
11839
- await page.mouse.move(
11840
- start.x + (end.x - start.x) * progress,
11841
- start.y + (end.y - start.y) * progress,
11842
- );
11843
- await page.waitForTimeout(durationMs / steps);
11911
+ const pointerType = String(action.pointer_type || action.pointerType || "mouse").trim().toLowerCase();
11912
+ if (pointerType === "touch" || pointerType === "pen") {
11913
+ const localStart = {
11914
+ x: coordinate(fromX, box.width),
11915
+ y: coordinate(fromY, box.height),
11916
+ };
11917
+ const localEnd = {
11918
+ x: coordinate(toX, box.width),
11919
+ y: coordinate(toY, box.height),
11920
+ };
11921
+ await target.evaluate(async (element, payload) => {
11922
+ const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
11923
+ const rect = element.getBoundingClientRect();
11924
+ const pointerId = payload.pointerType === "touch" ? 11 : 12;
11925
+ const point = (progress) => ({
11926
+ clientX: rect.left + payload.start.x + (payload.end.x - payload.start.x) * progress,
11927
+ clientY: rect.top + payload.start.y + (payload.end.y - payload.start.y) * progress,
11928
+ });
11929
+ const dispatch = (type, progress) => {
11930
+ const coords = point(progress);
11931
+ element.dispatchEvent(new PointerEvent(type, {
11932
+ bubbles: true,
11933
+ cancelable: true,
11934
+ composed: true,
11935
+ pointerId,
11936
+ pointerType: payload.pointerType,
11937
+ isPrimary: true,
11938
+ buttons: type === "pointerup" ? 0 : 1,
11939
+ button: type === "pointerup" ? 0 : 0,
11940
+ clientX: coords.clientX,
11941
+ clientY: coords.clientY,
11942
+ }));
11943
+ };
11944
+ dispatch("pointerover", 0);
11945
+ dispatch("pointerenter", 0);
11946
+ dispatch("pointerdown", 0);
11947
+ for (let step = 1; step <= payload.steps; step += 1) {
11948
+ dispatch("pointermove", step / payload.steps);
11949
+ if (payload.durationMs && payload.steps > 1) await wait(payload.durationMs / payload.steps);
11844
11950
  }
11845
- } else {
11846
- await page.mouse.move(end.x, end.y, { steps });
11951
+ dispatch("pointerup", 1);
11952
+ dispatch("pointerout", 1);
11953
+ dispatch("pointerleave", 1);
11954
+ }, {
11955
+ pointerType,
11956
+ start: localStart,
11957
+ end: localEnd,
11958
+ steps,
11959
+ durationMs,
11960
+ });
11961
+ } else {
11962
+ await page.mouse.move(start.x, start.y);
11963
+ await page.mouse.down();
11964
+ try {
11965
+ if (durationMs && steps > 1) {
11966
+ for (let step = 1; step <= steps; step += 1) {
11967
+ const progress = step / steps;
11968
+ await page.mouse.move(
11969
+ start.x + (end.x - start.x) * progress,
11970
+ start.y + (end.y - start.y) * progress,
11971
+ );
11972
+ await page.waitForTimeout(durationMs / steps);
11973
+ }
11974
+ } else {
11975
+ await page.mouse.move(end.x, end.y, { steps });
11976
+ }
11977
+ } finally {
11978
+ await page.mouse.up().catch(() => {});
11847
11979
  }
11848
- } finally {
11849
- await page.mouse.up().catch(() => {});
11850
11980
  }
11851
11981
  return {
11852
11982
  ...base,
@@ -11859,6 +11989,7 @@ async function executeSetupAction(action, ordinal, viewport) {
11859
11989
  from_y: fromY,
11860
11990
  to_x: toX,
11861
11991
  to_y: toY,
11992
+ pointer_type: pointerType,
11862
11993
  steps,
11863
11994
  duration_ms: durationMs || undefined,
11864
11995
  };
@@ -12081,6 +12212,7 @@ async function executeSetupAction(action, ordinal, viewport) {
12081
12212
  if (!count) return { ...base, reason: "selector_not_found", count };
12082
12213
  let targetIndex = Number.isInteger(action.index) ? action.index : 0;
12083
12214
  let matchedText = null;
12215
+ let caseInsensitiveText = null;
12084
12216
  let hiddenMatchIndex = -1;
12085
12217
  let hiddenMatchedText = null;
12086
12218
  if (action.text || action.pattern) {
@@ -12098,10 +12230,12 @@ async function executeSetupAction(action, ordinal, viewport) {
12098
12230
  hiddenMatchIndex = index;
12099
12231
  hiddenMatchedText = compactSetupResultText(text);
12100
12232
  }
12233
+ } else if (!caseInsensitiveText) {
12234
+ caseInsensitiveText = setupCaseInsensitiveTextSample(text, action) || null;
12101
12235
  }
12102
12236
  }
12103
12237
  if (targetIndex < 0 && hiddenMatchIndex >= 0) return { ...base, reason: "matching_element_not_visible", count, target_index: hiddenMatchIndex, text: hiddenMatchedText };
12104
- if (targetIndex < 0) return { ...base, reason: "text_not_found", count };
12238
+ if (targetIndex < 0) return { ...base, reason: "text_not_found", count, case_insensitive_text: caseInsensitiveText || undefined };
12105
12239
  }
12106
12240
  if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
12107
12241
  const clickOptions = action.force === true
@@ -12145,6 +12279,7 @@ async function executeSetupAction(action, ordinal, viewport) {
12145
12279
  const locator = scope.context.locator(action.selector);
12146
12280
  const startedAt = Date.now();
12147
12281
  let lastText = "";
12282
+ let caseInsensitiveText = "";
12148
12283
  while (Date.now() - startedAt <= timeout) {
12149
12284
  const count = await locator.count().catch(() => 0);
12150
12285
  for (let index = 0; index < count; index += 1) {
@@ -12153,10 +12288,11 @@ async function executeSetupAction(action, ordinal, viewport) {
12153
12288
  if (setupTextMatches(text, action)) {
12154
12289
  return { ...base, ...setupScopeEvidence(scope), ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
12155
12290
  }
12291
+ caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
12156
12292
  }
12157
12293
  await page.waitForTimeout(100);
12158
12294
  }
12159
- return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
12295
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
12160
12296
  }
12161
12297
  if (type === "assert_text_visible" || type === "assert_text_absent") {
12162
12298
  const scope = await setupActionScope(action, timeout);
@@ -12165,6 +12301,7 @@ async function executeSetupAction(action, ordinal, viewport) {
12165
12301
  const startedAt = Date.now();
12166
12302
  let lastText = "";
12167
12303
  let matchedText = "";
12304
+ let caseInsensitiveText = "";
12168
12305
  let hiddenMatch = false;
12169
12306
  while (Date.now() - startedAt <= timeout) {
12170
12307
  const count = await locator.count().catch(() => 0);
@@ -12187,6 +12324,7 @@ async function executeSetupAction(action, ordinal, viewport) {
12187
12324
  }
12188
12325
  break;
12189
12326
  }
12327
+ caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
12190
12328
  }
12191
12329
  if (type === "assert_text_absent" && !matched) {
12192
12330
  return { ...base, ...setupScopeEvidence(scope), ok: true, count, timeout_ms: timeout };
@@ -12197,7 +12335,7 @@ async function executeSetupAction(action, ordinal, viewport) {
12197
12335
  if (hiddenMatch) {
12198
12336
  return { ...base, ...setupScopeEvidence(scope), reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
12199
12337
  }
12200
- return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
12338
+ return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
12201
12339
  }
12202
12340
  return { ...base, ...setupScopeEvidence(scope), reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
12203
12341
  }
@@ -13305,6 +13443,7 @@ async function captureViewport(viewport) {
13305
13443
  const text_sequences = {};
13306
13444
  const text_matches = {};
13307
13445
  const text_match_samples = {};
13446
+ const text_case_insensitive_samples = {};
13308
13447
  const http_statuses = {};
13309
13448
  const link_statuses = {};
13310
13449
  for (const check of profile.checks || []) {
@@ -13330,6 +13469,7 @@ async function captureViewport(viewport) {
13330
13469
  const sample = dom.body_text || dom.body_text_sample || "";
13331
13470
  text_matches[key] = textMatches(sample, check);
13332
13471
  text_match_samples[key] = textMatchSamples(sample, check);
13472
+ text_case_insensitive_samples[key] = textCaseInsensitiveSamples(sample, check);
13333
13473
  }
13334
13474
  if ((check.type === "frame_text_visible" || check.type === "frame_url_equals" || check.type === "frame_url_matches" || check.type === "frame_no_horizontal_overflow") && check.selector) {
13335
13475
  selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
@@ -13407,6 +13547,7 @@ async function captureViewport(viewport) {
13407
13547
  text_sequences,
13408
13548
  text_matches,
13409
13549
  text_match_samples,
13550
+ text_case_insensitive_samples,
13410
13551
  http_statuses,
13411
13552
  link_statuses,
13412
13553
  route_inventory: routeInventory,
package/dist/cli.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  profileStatusExitCode,
13
13
  resolveRiddleProofProfileTargetUrl,
14
14
  resolveRiddleProofProfileTimeoutSec
15
- } from "./chunk-TDK6WFH3.js";
15
+ } from "./chunk-ZYD2SGEM.js";
16
16
  import {
17
17
  createRiddleApiClient,
18
18
  parseRiddleViewport