@riddledc/riddle-proof 0.7.130 → 0.7.132
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/{chunk-ZJNM3YAB.js → chunk-PKE223TX.js} +86 -7
- package/dist/cli.cjs +99 -7
- package/dist/cli.js +14 -1
- package/dist/index.cjs +86 -7
- package/dist/index.js +1 -1
- package/dist/profile.cjs +86 -7
- package/dist/profile.d.cts +1 -0
- package/dist/profile.d.ts +1 -0
- package/dist/profile.js +1 -1
- package/dist/proof-run-engine.d.cts +3 -3
- package/dist/proof-run-engine.d.ts +3 -3
- package/package.json +1 -1
|
@@ -515,14 +515,16 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
|
|
|
515
515
|
action: profileSetupResultAction(result),
|
|
516
516
|
selector: result.selector ?? null,
|
|
517
517
|
frame_selector: result.frame_selector ?? null,
|
|
518
|
-
reason: result.reason ?? result.error ?? null
|
|
518
|
+
reason: result.reason ?? result.error ?? null,
|
|
519
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text)
|
|
519
520
|
})),
|
|
520
521
|
optional_failed: optionalFailed.map((result) => ({
|
|
521
522
|
ordinal: result.ordinal ?? null,
|
|
522
523
|
action: profileSetupResultAction(result),
|
|
523
524
|
selector: result.selector ?? null,
|
|
524
525
|
frame_selector: result.frame_selector ?? null,
|
|
525
|
-
reason: result.reason ?? result.error ?? null
|
|
526
|
+
reason: result.reason ?? result.error ?? null,
|
|
527
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text)
|
|
526
528
|
}))
|
|
527
529
|
};
|
|
528
530
|
})
|
|
@@ -1900,6 +1902,27 @@ function textMatchSamples(sample, check) {
|
|
|
1900
1902
|
const sampleText = textSampleAroundMatch(source, index, text.length);
|
|
1901
1903
|
return sampleText ? [sampleText] : [];
|
|
1902
1904
|
}
|
|
1905
|
+
function textCaseInsensitiveSamples(sample, check) {
|
|
1906
|
+
const source = String(sample || "");
|
|
1907
|
+
const text = check.pattern ? "" : check.text || "";
|
|
1908
|
+
if (!source || !text) return [];
|
|
1909
|
+
const index = source.toLowerCase().indexOf(text.toLowerCase());
|
|
1910
|
+
const sampleText = textSampleAroundMatch(source, index, text.length);
|
|
1911
|
+
return sampleText ? [sampleText] : [];
|
|
1912
|
+
}
|
|
1913
|
+
function textCaseInsensitiveSequenceSamples(texts, check) {
|
|
1914
|
+
const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
|
|
1915
|
+
if (!text) return [];
|
|
1916
|
+
const expected = text.toLowerCase();
|
|
1917
|
+
return texts.map((candidate) => compactTextEvidenceSample(candidate)).filter((candidate) => candidate && candidate.toLowerCase().includes(expected)).slice(0, 3).map((candidate) => candidate.slice(0, 240));
|
|
1918
|
+
}
|
|
1919
|
+
function textCaseInsensitiveFailureSamples(viewport, check) {
|
|
1920
|
+
const key = textKey(check);
|
|
1921
|
+
const captured = viewport.text_case_insensitive_samples?.[key] || [];
|
|
1922
|
+
const capturedSamples = captured.map((sample) => compactTextEvidenceSample(sample).slice(0, 240)).filter(Boolean);
|
|
1923
|
+
if (capturedSamples.length) return capturedSamples.slice(0, 3);
|
|
1924
|
+
return textCaseInsensitiveSamples(viewport.body_text_sample || "", check).slice(0, 3);
|
|
1925
|
+
}
|
|
1903
1926
|
function textCheckFailureSamples(viewport, check) {
|
|
1904
1927
|
const key = textKey(check);
|
|
1905
1928
|
const captured = viewport.text_match_samples?.[key] || [];
|
|
@@ -2212,13 +2235,15 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
2212
2235
|
const matched = matches.length > 0;
|
|
2213
2236
|
const failedAgainstExpectation = matched !== expectedVisible;
|
|
2214
2237
|
const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
|
|
2238
|
+
const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveSequenceSamples(texts, check) : [];
|
|
2215
2239
|
return {
|
|
2216
2240
|
viewport: viewport.name,
|
|
2217
2241
|
selector_count: viewport.selectors?.[key]?.count || 0,
|
|
2218
2242
|
visible_count: viewport.selectors?.[key]?.visible_count || 0,
|
|
2219
2243
|
matched_count: matches.length,
|
|
2220
2244
|
matched,
|
|
2221
|
-
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240))
|
|
2245
|
+
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
|
|
2246
|
+
case_insensitive_samples: caseInsensitiveSamples
|
|
2222
2247
|
};
|
|
2223
2248
|
});
|
|
2224
2249
|
const failed = results.filter((result) => result.matched !== expectedVisible).length;
|
|
@@ -2361,7 +2386,8 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
2361
2386
|
return {
|
|
2362
2387
|
viewport: viewport.name,
|
|
2363
2388
|
matched,
|
|
2364
|
-
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : []
|
|
2389
|
+
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
|
|
2390
|
+
case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveFailureSamples(viewport, check) : []
|
|
2365
2391
|
};
|
|
2366
2392
|
});
|
|
2367
2393
|
const matches = results.map((result) => result.matched);
|
|
@@ -2991,6 +3017,32 @@ function textMatchSamples(sample, check) {
|
|
|
2991
3017
|
const sampleText = textSampleAroundMatch(source, source.indexOf(text), text.length);
|
|
2992
3018
|
return sampleText ? [sampleText] : [];
|
|
2993
3019
|
}
|
|
3020
|
+
function textCaseInsensitiveSamples(sample, check) {
|
|
3021
|
+
const source = String(sample || "");
|
|
3022
|
+
const text = check.pattern ? "" : check.text || "";
|
|
3023
|
+
if (!source || !text) return [];
|
|
3024
|
+
const sampleText = textSampleAroundMatch(source, source.toLowerCase().indexOf(text.toLowerCase()), text.length);
|
|
3025
|
+
return sampleText ? [sampleText] : [];
|
|
3026
|
+
}
|
|
3027
|
+
function textCaseInsensitiveSequenceSamples(texts, check) {
|
|
3028
|
+
const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
|
|
3029
|
+
if (!text) return [];
|
|
3030
|
+
const expected = text.toLowerCase();
|
|
3031
|
+
return (texts || [])
|
|
3032
|
+
.map((candidate) => compactTextEvidenceSample(candidate))
|
|
3033
|
+
.filter((candidate) => candidate && candidate.toLowerCase().includes(expected))
|
|
3034
|
+
.slice(0, 3)
|
|
3035
|
+
.map((candidate) => candidate.slice(0, 240));
|
|
3036
|
+
}
|
|
3037
|
+
function textCaseInsensitiveFailureSamples(viewport, check) {
|
|
3038
|
+
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
3039
|
+
const captured = viewport && viewport.text_case_insensitive_samples && Array.isArray(viewport.text_case_insensitive_samples[key]) ? viewport.text_case_insensitive_samples[key] : [];
|
|
3040
|
+
const capturedSamples = captured
|
|
3041
|
+
.map((sample) => compactTextEvidenceSample(sample).slice(0, 240))
|
|
3042
|
+
.filter(Boolean);
|
|
3043
|
+
if (capturedSamples.length) return capturedSamples.slice(0, 3);
|
|
3044
|
+
return textCaseInsensitiveSamples(viewport && viewport.body_text_sample || "", check).slice(0, 3);
|
|
3045
|
+
}
|
|
2994
3046
|
function textCheckFailureSamples(viewport, check) {
|
|
2995
3047
|
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
2996
3048
|
const captured = viewport && viewport.text_match_samples && Array.isArray(viewport.text_match_samples[key]) ? viewport.text_match_samples[key] : [];
|
|
@@ -3637,6 +3689,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
3637
3689
|
selector: result.selector ?? null,
|
|
3638
3690
|
frame_selector: result.frame_selector ?? null,
|
|
3639
3691
|
reason: result.reason || result.error || null,
|
|
3692
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text),
|
|
3640
3693
|
})),
|
|
3641
3694
|
optional_failed: optionalFailed.map((result) => ({
|
|
3642
3695
|
ordinal: result.ordinal ?? null,
|
|
@@ -3644,6 +3697,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
3644
3697
|
selector: result.selector ?? null,
|
|
3645
3698
|
frame_selector: result.frame_selector ?? null,
|
|
3646
3699
|
reason: result.reason || result.error || null,
|
|
3700
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text),
|
|
3647
3701
|
})),
|
|
3648
3702
|
};
|
|
3649
3703
|
}),
|
|
@@ -3949,6 +4003,9 @@ function assessProfile(profile, evidence) {
|
|
|
3949
4003
|
const matched = matches.length > 0;
|
|
3950
4004
|
const failedAgainstExpectation = matched !== expectedVisible;
|
|
3951
4005
|
const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
|
|
4006
|
+
const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched
|
|
4007
|
+
? textCaseInsensitiveSequenceSamples(texts, check)
|
|
4008
|
+
: [];
|
|
3952
4009
|
return {
|
|
3953
4010
|
viewport: viewport.name,
|
|
3954
4011
|
selector_count: viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].count : 0,
|
|
@@ -3956,6 +4013,7 @@ function assessProfile(profile, evidence) {
|
|
|
3956
4013
|
matched_count: matches.length,
|
|
3957
4014
|
matched,
|
|
3958
4015
|
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
|
|
4016
|
+
case_insensitive_samples: caseInsensitiveSamples,
|
|
3959
4017
|
};
|
|
3960
4018
|
});
|
|
3961
4019
|
const failed = results.filter((result) => result.matched !== expectedVisible).length;
|
|
@@ -4087,6 +4145,9 @@ function assessProfile(profile, evidence) {
|
|
|
4087
4145
|
viewport: viewport.name,
|
|
4088
4146
|
matched,
|
|
4089
4147
|
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
|
|
4148
|
+
case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched
|
|
4149
|
+
? textCaseInsensitiveFailureSamples(viewport, check)
|
|
4150
|
+
: [],
|
|
4090
4151
|
};
|
|
4091
4152
|
});
|
|
4092
4153
|
const matches = results.map((result) => result.matched);
|
|
@@ -4476,6 +4537,14 @@ function setupTextMatches(sample, action) {
|
|
|
4476
4537
|
return rawSample.includes(expected)
|
|
4477
4538
|
|| normalizeSetupMatchText(rawSample).includes(normalizeSetupMatchText(expected));
|
|
4478
4539
|
}
|
|
4540
|
+
function setupCaseInsensitiveTextSample(sample, action) {
|
|
4541
|
+
if (!action || action.pattern || !action.text) return "";
|
|
4542
|
+
const normalizedSample = normalizeSetupMatchText(sample);
|
|
4543
|
+
const normalizedExpected = normalizeSetupMatchText(action.text);
|
|
4544
|
+
if (!normalizedSample || !normalizedExpected) return "";
|
|
4545
|
+
if (!normalizedSample.toLowerCase().includes(normalizedExpected.toLowerCase())) return "";
|
|
4546
|
+
return compactSetupResultText(normalizedSample);
|
|
4547
|
+
}
|
|
4479
4548
|
async function waitForAnyVisibleSelector(context, selector, timeout) {
|
|
4480
4549
|
const deadline = Date.now() + setupNumber(timeout, 15000);
|
|
4481
4550
|
let lastReason = "selector_not_found";
|
|
@@ -5226,6 +5295,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5226
5295
|
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
5227
5296
|
let targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
5228
5297
|
let matchedText = null;
|
|
5298
|
+
let caseInsensitiveText = null;
|
|
5229
5299
|
let hiddenMatchIndex = -1;
|
|
5230
5300
|
let hiddenMatchedText = null;
|
|
5231
5301
|
if (action.text || action.pattern) {
|
|
@@ -5243,10 +5313,12 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5243
5313
|
hiddenMatchIndex = index;
|
|
5244
5314
|
hiddenMatchedText = compactSetupResultText(text);
|
|
5245
5315
|
}
|
|
5316
|
+
} else if (!caseInsensitiveText) {
|
|
5317
|
+
caseInsensitiveText = setupCaseInsensitiveTextSample(text, action) || null;
|
|
5246
5318
|
}
|
|
5247
5319
|
}
|
|
5248
5320
|
if (targetIndex < 0 && hiddenMatchIndex >= 0) return { ...base, reason: "matching_element_not_visible", count, target_index: hiddenMatchIndex, text: hiddenMatchedText };
|
|
5249
|
-
if (targetIndex < 0) return { ...base, reason: "text_not_found", count };
|
|
5321
|
+
if (targetIndex < 0) return { ...base, reason: "text_not_found", count, case_insensitive_text: caseInsensitiveText || undefined };
|
|
5250
5322
|
}
|
|
5251
5323
|
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
|
|
5252
5324
|
const clickOptions = action.force === true
|
|
@@ -5290,6 +5362,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5290
5362
|
const locator = scope.context.locator(action.selector);
|
|
5291
5363
|
const startedAt = Date.now();
|
|
5292
5364
|
let lastText = "";
|
|
5365
|
+
let caseInsensitiveText = "";
|
|
5293
5366
|
while (Date.now() - startedAt <= timeout) {
|
|
5294
5367
|
const count = await locator.count().catch(() => 0);
|
|
5295
5368
|
for (let index = 0; index < count; index += 1) {
|
|
@@ -5298,10 +5371,11 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5298
5371
|
if (setupTextMatches(text, action)) {
|
|
5299
5372
|
return { ...base, ...setupScopeEvidence(scope), ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
|
|
5300
5373
|
}
|
|
5374
|
+
caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
|
|
5301
5375
|
}
|
|
5302
5376
|
await page.waitForTimeout(100);
|
|
5303
5377
|
}
|
|
5304
|
-
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
|
|
5378
|
+
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
|
|
5305
5379
|
}
|
|
5306
5380
|
if (type === "assert_text_visible" || type === "assert_text_absent") {
|
|
5307
5381
|
const scope = await setupActionScope(action, timeout);
|
|
@@ -5310,6 +5384,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5310
5384
|
const startedAt = Date.now();
|
|
5311
5385
|
let lastText = "";
|
|
5312
5386
|
let matchedText = "";
|
|
5387
|
+
let caseInsensitiveText = "";
|
|
5313
5388
|
let hiddenMatch = false;
|
|
5314
5389
|
while (Date.now() - startedAt <= timeout) {
|
|
5315
5390
|
const count = await locator.count().catch(() => 0);
|
|
@@ -5332,6 +5407,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5332
5407
|
}
|
|
5333
5408
|
break;
|
|
5334
5409
|
}
|
|
5410
|
+
caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
|
|
5335
5411
|
}
|
|
5336
5412
|
if (type === "assert_text_absent" && !matched) {
|
|
5337
5413
|
return { ...base, ...setupScopeEvidence(scope), ok: true, count, timeout_ms: timeout };
|
|
@@ -5342,7 +5418,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5342
5418
|
if (hiddenMatch) {
|
|
5343
5419
|
return { ...base, ...setupScopeEvidence(scope), reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
|
|
5344
5420
|
}
|
|
5345
|
-
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
|
|
5421
|
+
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
|
|
5346
5422
|
}
|
|
5347
5423
|
return { ...base, ...setupScopeEvidence(scope), reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
|
|
5348
5424
|
}
|
|
@@ -6450,6 +6526,7 @@ async function captureViewport(viewport) {
|
|
|
6450
6526
|
const text_sequences = {};
|
|
6451
6527
|
const text_matches = {};
|
|
6452
6528
|
const text_match_samples = {};
|
|
6529
|
+
const text_case_insensitive_samples = {};
|
|
6453
6530
|
const http_statuses = {};
|
|
6454
6531
|
const link_statuses = {};
|
|
6455
6532
|
for (const check of profile.checks || []) {
|
|
@@ -6475,6 +6552,7 @@ async function captureViewport(viewport) {
|
|
|
6475
6552
|
const sample = dom.body_text || dom.body_text_sample || "";
|
|
6476
6553
|
text_matches[key] = textMatches(sample, check);
|
|
6477
6554
|
text_match_samples[key] = textMatchSamples(sample, check);
|
|
6555
|
+
text_case_insensitive_samples[key] = textCaseInsensitiveSamples(sample, check);
|
|
6478
6556
|
}
|
|
6479
6557
|
if ((check.type === "frame_text_visible" || check.type === "frame_url_equals" || check.type === "frame_url_matches" || check.type === "frame_no_horizontal_overflow") && check.selector) {
|
|
6480
6558
|
selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
|
|
@@ -6552,6 +6630,7 @@ async function captureViewport(viewport) {
|
|
|
6552
6630
|
text_sequences,
|
|
6553
6631
|
text_matches,
|
|
6554
6632
|
text_match_samples,
|
|
6633
|
+
text_case_insensitive_samples,
|
|
6555
6634
|
http_statuses,
|
|
6556
6635
|
link_statuses,
|
|
6557
6636
|
route_inventory: routeInventory,
|
package/dist/cli.cjs
CHANGED
|
@@ -7452,14 +7452,16 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
|
|
|
7452
7452
|
action: profileSetupResultAction(result),
|
|
7453
7453
|
selector: result.selector ?? null,
|
|
7454
7454
|
frame_selector: result.frame_selector ?? null,
|
|
7455
|
-
reason: result.reason ?? result.error ?? null
|
|
7455
|
+
reason: result.reason ?? result.error ?? null,
|
|
7456
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text)
|
|
7456
7457
|
})),
|
|
7457
7458
|
optional_failed: optionalFailed.map((result) => ({
|
|
7458
7459
|
ordinal: result.ordinal ?? null,
|
|
7459
7460
|
action: profileSetupResultAction(result),
|
|
7460
7461
|
selector: result.selector ?? null,
|
|
7461
7462
|
frame_selector: result.frame_selector ?? null,
|
|
7462
|
-
reason: result.reason ?? result.error ?? null
|
|
7463
|
+
reason: result.reason ?? result.error ?? null,
|
|
7464
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text)
|
|
7463
7465
|
}))
|
|
7464
7466
|
};
|
|
7465
7467
|
})
|
|
@@ -8837,6 +8839,27 @@ function textMatchSamples(sample, check) {
|
|
|
8837
8839
|
const sampleText = textSampleAroundMatch(source, index, text.length);
|
|
8838
8840
|
return sampleText ? [sampleText] : [];
|
|
8839
8841
|
}
|
|
8842
|
+
function textCaseInsensitiveSamples(sample, check) {
|
|
8843
|
+
const source = String(sample || "");
|
|
8844
|
+
const text = check.pattern ? "" : check.text || "";
|
|
8845
|
+
if (!source || !text) return [];
|
|
8846
|
+
const index = source.toLowerCase().indexOf(text.toLowerCase());
|
|
8847
|
+
const sampleText = textSampleAroundMatch(source, index, text.length);
|
|
8848
|
+
return sampleText ? [sampleText] : [];
|
|
8849
|
+
}
|
|
8850
|
+
function textCaseInsensitiveSequenceSamples(texts, check) {
|
|
8851
|
+
const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
|
|
8852
|
+
if (!text) return [];
|
|
8853
|
+
const expected = text.toLowerCase();
|
|
8854
|
+
return texts.map((candidate) => compactTextEvidenceSample(candidate)).filter((candidate) => candidate && candidate.toLowerCase().includes(expected)).slice(0, 3).map((candidate) => candidate.slice(0, 240));
|
|
8855
|
+
}
|
|
8856
|
+
function textCaseInsensitiveFailureSamples(viewport, check) {
|
|
8857
|
+
const key = textKey(check);
|
|
8858
|
+
const captured = viewport.text_case_insensitive_samples?.[key] || [];
|
|
8859
|
+
const capturedSamples = captured.map((sample) => compactTextEvidenceSample(sample).slice(0, 240)).filter(Boolean);
|
|
8860
|
+
if (capturedSamples.length) return capturedSamples.slice(0, 3);
|
|
8861
|
+
return textCaseInsensitiveSamples(viewport.body_text_sample || "", check).slice(0, 3);
|
|
8862
|
+
}
|
|
8840
8863
|
function textCheckFailureSamples(viewport, check) {
|
|
8841
8864
|
const key = textKey(check);
|
|
8842
8865
|
const captured = viewport.text_match_samples?.[key] || [];
|
|
@@ -9149,13 +9172,15 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
9149
9172
|
const matched = matches.length > 0;
|
|
9150
9173
|
const failedAgainstExpectation = matched !== expectedVisible;
|
|
9151
9174
|
const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
|
|
9175
|
+
const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveSequenceSamples(texts, check) : [];
|
|
9152
9176
|
return {
|
|
9153
9177
|
viewport: viewport.name,
|
|
9154
9178
|
selector_count: viewport.selectors?.[key]?.count || 0,
|
|
9155
9179
|
visible_count: viewport.selectors?.[key]?.visible_count || 0,
|
|
9156
9180
|
matched_count: matches.length,
|
|
9157
9181
|
matched,
|
|
9158
|
-
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240))
|
|
9182
|
+
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
|
|
9183
|
+
case_insensitive_samples: caseInsensitiveSamples
|
|
9159
9184
|
};
|
|
9160
9185
|
});
|
|
9161
9186
|
const failed = results.filter((result) => result.matched !== expectedVisible).length;
|
|
@@ -9298,7 +9323,8 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
9298
9323
|
return {
|
|
9299
9324
|
viewport: viewport.name,
|
|
9300
9325
|
matched,
|
|
9301
|
-
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : []
|
|
9326
|
+
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
|
|
9327
|
+
case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveFailureSamples(viewport, check) : []
|
|
9302
9328
|
};
|
|
9303
9329
|
});
|
|
9304
9330
|
const matches = results.map((result) => result.matched);
|
|
@@ -9912,6 +9938,32 @@ function textMatchSamples(sample, check) {
|
|
|
9912
9938
|
const sampleText = textSampleAroundMatch(source, source.indexOf(text), text.length);
|
|
9913
9939
|
return sampleText ? [sampleText] : [];
|
|
9914
9940
|
}
|
|
9941
|
+
function textCaseInsensitiveSamples(sample, check) {
|
|
9942
|
+
const source = String(sample || "");
|
|
9943
|
+
const text = check.pattern ? "" : check.text || "";
|
|
9944
|
+
if (!source || !text) return [];
|
|
9945
|
+
const sampleText = textSampleAroundMatch(source, source.toLowerCase().indexOf(text.toLowerCase()), text.length);
|
|
9946
|
+
return sampleText ? [sampleText] : [];
|
|
9947
|
+
}
|
|
9948
|
+
function textCaseInsensitiveSequenceSamples(texts, check) {
|
|
9949
|
+
const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
|
|
9950
|
+
if (!text) return [];
|
|
9951
|
+
const expected = text.toLowerCase();
|
|
9952
|
+
return (texts || [])
|
|
9953
|
+
.map((candidate) => compactTextEvidenceSample(candidate))
|
|
9954
|
+
.filter((candidate) => candidate && candidate.toLowerCase().includes(expected))
|
|
9955
|
+
.slice(0, 3)
|
|
9956
|
+
.map((candidate) => candidate.slice(0, 240));
|
|
9957
|
+
}
|
|
9958
|
+
function textCaseInsensitiveFailureSamples(viewport, check) {
|
|
9959
|
+
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
9960
|
+
const captured = viewport && viewport.text_case_insensitive_samples && Array.isArray(viewport.text_case_insensitive_samples[key]) ? viewport.text_case_insensitive_samples[key] : [];
|
|
9961
|
+
const capturedSamples = captured
|
|
9962
|
+
.map((sample) => compactTextEvidenceSample(sample).slice(0, 240))
|
|
9963
|
+
.filter(Boolean);
|
|
9964
|
+
if (capturedSamples.length) return capturedSamples.slice(0, 3);
|
|
9965
|
+
return textCaseInsensitiveSamples(viewport && viewport.body_text_sample || "", check).slice(0, 3);
|
|
9966
|
+
}
|
|
9915
9967
|
function textCheckFailureSamples(viewport, check) {
|
|
9916
9968
|
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
9917
9969
|
const captured = viewport && viewport.text_match_samples && Array.isArray(viewport.text_match_samples[key]) ? viewport.text_match_samples[key] : [];
|
|
@@ -10558,6 +10610,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
10558
10610
|
selector: result.selector ?? null,
|
|
10559
10611
|
frame_selector: result.frame_selector ?? null,
|
|
10560
10612
|
reason: result.reason || result.error || null,
|
|
10613
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text),
|
|
10561
10614
|
})),
|
|
10562
10615
|
optional_failed: optionalFailed.map((result) => ({
|
|
10563
10616
|
ordinal: result.ordinal ?? null,
|
|
@@ -10565,6 +10618,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
10565
10618
|
selector: result.selector ?? null,
|
|
10566
10619
|
frame_selector: result.frame_selector ?? null,
|
|
10567
10620
|
reason: result.reason || result.error || null,
|
|
10621
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text),
|
|
10568
10622
|
})),
|
|
10569
10623
|
};
|
|
10570
10624
|
}),
|
|
@@ -10870,6 +10924,9 @@ function assessProfile(profile, evidence) {
|
|
|
10870
10924
|
const matched = matches.length > 0;
|
|
10871
10925
|
const failedAgainstExpectation = matched !== expectedVisible;
|
|
10872
10926
|
const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
|
|
10927
|
+
const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched
|
|
10928
|
+
? textCaseInsensitiveSequenceSamples(texts, check)
|
|
10929
|
+
: [];
|
|
10873
10930
|
return {
|
|
10874
10931
|
viewport: viewport.name,
|
|
10875
10932
|
selector_count: viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].count : 0,
|
|
@@ -10877,6 +10934,7 @@ function assessProfile(profile, evidence) {
|
|
|
10877
10934
|
matched_count: matches.length,
|
|
10878
10935
|
matched,
|
|
10879
10936
|
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
|
|
10937
|
+
case_insensitive_samples: caseInsensitiveSamples,
|
|
10880
10938
|
};
|
|
10881
10939
|
});
|
|
10882
10940
|
const failed = results.filter((result) => result.matched !== expectedVisible).length;
|
|
@@ -11008,6 +11066,9 @@ function assessProfile(profile, evidence) {
|
|
|
11008
11066
|
viewport: viewport.name,
|
|
11009
11067
|
matched,
|
|
11010
11068
|
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
|
|
11069
|
+
case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched
|
|
11070
|
+
? textCaseInsensitiveFailureSamples(viewport, check)
|
|
11071
|
+
: [],
|
|
11011
11072
|
};
|
|
11012
11073
|
});
|
|
11013
11074
|
const matches = results.map((result) => result.matched);
|
|
@@ -11397,6 +11458,14 @@ function setupTextMatches(sample, action) {
|
|
|
11397
11458
|
return rawSample.includes(expected)
|
|
11398
11459
|
|| normalizeSetupMatchText(rawSample).includes(normalizeSetupMatchText(expected));
|
|
11399
11460
|
}
|
|
11461
|
+
function setupCaseInsensitiveTextSample(sample, action) {
|
|
11462
|
+
if (!action || action.pattern || !action.text) return "";
|
|
11463
|
+
const normalizedSample = normalizeSetupMatchText(sample);
|
|
11464
|
+
const normalizedExpected = normalizeSetupMatchText(action.text);
|
|
11465
|
+
if (!normalizedSample || !normalizedExpected) return "";
|
|
11466
|
+
if (!normalizedSample.toLowerCase().includes(normalizedExpected.toLowerCase())) return "";
|
|
11467
|
+
return compactSetupResultText(normalizedSample);
|
|
11468
|
+
}
|
|
11400
11469
|
async function waitForAnyVisibleSelector(context, selector, timeout) {
|
|
11401
11470
|
const deadline = Date.now() + setupNumber(timeout, 15000);
|
|
11402
11471
|
let lastReason = "selector_not_found";
|
|
@@ -12147,6 +12216,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
12147
12216
|
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
12148
12217
|
let targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
12149
12218
|
let matchedText = null;
|
|
12219
|
+
let caseInsensitiveText = null;
|
|
12150
12220
|
let hiddenMatchIndex = -1;
|
|
12151
12221
|
let hiddenMatchedText = null;
|
|
12152
12222
|
if (action.text || action.pattern) {
|
|
@@ -12164,10 +12234,12 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
12164
12234
|
hiddenMatchIndex = index;
|
|
12165
12235
|
hiddenMatchedText = compactSetupResultText(text);
|
|
12166
12236
|
}
|
|
12237
|
+
} else if (!caseInsensitiveText) {
|
|
12238
|
+
caseInsensitiveText = setupCaseInsensitiveTextSample(text, action) || null;
|
|
12167
12239
|
}
|
|
12168
12240
|
}
|
|
12169
12241
|
if (targetIndex < 0 && hiddenMatchIndex >= 0) return { ...base, reason: "matching_element_not_visible", count, target_index: hiddenMatchIndex, text: hiddenMatchedText };
|
|
12170
|
-
if (targetIndex < 0) return { ...base, reason: "text_not_found", count };
|
|
12242
|
+
if (targetIndex < 0) return { ...base, reason: "text_not_found", count, case_insensitive_text: caseInsensitiveText || undefined };
|
|
12171
12243
|
}
|
|
12172
12244
|
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
|
|
12173
12245
|
const clickOptions = action.force === true
|
|
@@ -12211,6 +12283,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
12211
12283
|
const locator = scope.context.locator(action.selector);
|
|
12212
12284
|
const startedAt = Date.now();
|
|
12213
12285
|
let lastText = "";
|
|
12286
|
+
let caseInsensitiveText = "";
|
|
12214
12287
|
while (Date.now() - startedAt <= timeout) {
|
|
12215
12288
|
const count = await locator.count().catch(() => 0);
|
|
12216
12289
|
for (let index = 0; index < count; index += 1) {
|
|
@@ -12219,10 +12292,11 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
12219
12292
|
if (setupTextMatches(text, action)) {
|
|
12220
12293
|
return { ...base, ...setupScopeEvidence(scope), ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
|
|
12221
12294
|
}
|
|
12295
|
+
caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
|
|
12222
12296
|
}
|
|
12223
12297
|
await page.waitForTimeout(100);
|
|
12224
12298
|
}
|
|
12225
|
-
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
|
|
12299
|
+
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
|
|
12226
12300
|
}
|
|
12227
12301
|
if (type === "assert_text_visible" || type === "assert_text_absent") {
|
|
12228
12302
|
const scope = await setupActionScope(action, timeout);
|
|
@@ -12231,6 +12305,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
12231
12305
|
const startedAt = Date.now();
|
|
12232
12306
|
let lastText = "";
|
|
12233
12307
|
let matchedText = "";
|
|
12308
|
+
let caseInsensitiveText = "";
|
|
12234
12309
|
let hiddenMatch = false;
|
|
12235
12310
|
while (Date.now() - startedAt <= timeout) {
|
|
12236
12311
|
const count = await locator.count().catch(() => 0);
|
|
@@ -12253,6 +12328,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
12253
12328
|
}
|
|
12254
12329
|
break;
|
|
12255
12330
|
}
|
|
12331
|
+
caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
|
|
12256
12332
|
}
|
|
12257
12333
|
if (type === "assert_text_absent" && !matched) {
|
|
12258
12334
|
return { ...base, ...setupScopeEvidence(scope), ok: true, count, timeout_ms: timeout };
|
|
@@ -12263,7 +12339,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
12263
12339
|
if (hiddenMatch) {
|
|
12264
12340
|
return { ...base, ...setupScopeEvidence(scope), reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
|
|
12265
12341
|
}
|
|
12266
|
-
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
|
|
12342
|
+
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
|
|
12267
12343
|
}
|
|
12268
12344
|
return { ...base, ...setupScopeEvidence(scope), reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
|
|
12269
12345
|
}
|
|
@@ -13371,6 +13447,7 @@ async function captureViewport(viewport) {
|
|
|
13371
13447
|
const text_sequences = {};
|
|
13372
13448
|
const text_matches = {};
|
|
13373
13449
|
const text_match_samples = {};
|
|
13450
|
+
const text_case_insensitive_samples = {};
|
|
13374
13451
|
const http_statuses = {};
|
|
13375
13452
|
const link_statuses = {};
|
|
13376
13453
|
for (const check of profile.checks || []) {
|
|
@@ -13396,6 +13473,7 @@ async function captureViewport(viewport) {
|
|
|
13396
13473
|
const sample = dom.body_text || dom.body_text_sample || "";
|
|
13397
13474
|
text_matches[key] = textMatches(sample, check);
|
|
13398
13475
|
text_match_samples[key] = textMatchSamples(sample, check);
|
|
13476
|
+
text_case_insensitive_samples[key] = textCaseInsensitiveSamples(sample, check);
|
|
13399
13477
|
}
|
|
13400
13478
|
if ((check.type === "frame_text_visible" || check.type === "frame_url_equals" || check.type === "frame_url_matches" || check.type === "frame_no_horizontal_overflow") && check.selector) {
|
|
13401
13479
|
selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
|
|
@@ -13473,6 +13551,7 @@ async function captureViewport(viewport) {
|
|
|
13473
13551
|
text_sequences,
|
|
13474
13552
|
text_matches,
|
|
13475
13553
|
text_match_samples,
|
|
13554
|
+
text_case_insensitive_samples,
|
|
13476
13555
|
http_statuses,
|
|
13477
13556
|
link_statuses,
|
|
13478
13557
|
route_inventory: routeInventory,
|
|
@@ -14250,6 +14329,19 @@ function profileSetupSummaryMarkdown(result) {
|
|
|
14250
14329
|
const observedPath = cliString(viewport.observed_path);
|
|
14251
14330
|
lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(s)${clickCountActions ? `, ${clickCountActions} click_count action(s)` : ""}${observedPath ? `, path ${observedPath}` : ""}`);
|
|
14252
14331
|
}
|
|
14332
|
+
const failedDetails = viewports.flatMap((viewport) => {
|
|
14333
|
+
const name = cliString(viewport.name) || "viewport";
|
|
14334
|
+
const failed = Array.isArray(viewport.failed) ? viewport.failed.map(cliRecord).filter((item) => Boolean(item)) : [];
|
|
14335
|
+
return failed.map((failure) => ({ name, failure }));
|
|
14336
|
+
});
|
|
14337
|
+
for (const { name, failure } of failedDetails.slice(0, 8)) {
|
|
14338
|
+
const action = cliString(failure.action) || "setup_action";
|
|
14339
|
+
const selector = cliString(failure.selector);
|
|
14340
|
+
const reason = cliString(failure.reason);
|
|
14341
|
+
const caseInsensitiveText = cliString(failure.case_insensitive_text);
|
|
14342
|
+
lines.push(`- failed ${name}: ${action}${selector ? ` ${markdownInlineCode(selector)}` : ""}${reason ? ` reason ${markdownInlineCode(reason)}` : ""}${caseInsensitiveText ? `; case-insensitive sample ${markdownInlineCode(caseInsensitiveText, 140)}` : ""}`);
|
|
14343
|
+
}
|
|
14344
|
+
if (failedDetails.length > 8) lines.push(`- ${failedDetails.length - 8} additional failed setup action(s) omitted.`);
|
|
14253
14345
|
if (viewports.length > 8) lines.push(`- ${viewports.length - 8} additional viewport(s) omitted from setup summary.`);
|
|
14254
14346
|
return lines;
|
|
14255
14347
|
}
|
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
profileStatusExitCode,
|
|
13
13
|
resolveRiddleProofProfileTargetUrl,
|
|
14
14
|
resolveRiddleProofProfileTimeoutSec
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-PKE223TX.js";
|
|
16
16
|
import {
|
|
17
17
|
createRiddleApiClient,
|
|
18
18
|
parseRiddleViewport
|
|
@@ -605,6 +605,19 @@ function profileSetupSummaryMarkdown(result) {
|
|
|
605
605
|
const observedPath = cliString(viewport.observed_path);
|
|
606
606
|
lines.push(`- ${name}: ${ok}, ${resultCount} result(s), ${screenshotCount} setup screenshot(s), ${clicked} click(s)${clickCountActions ? `, ${clickCountActions} click_count action(s)` : ""}${observedPath ? `, path ${observedPath}` : ""}`);
|
|
607
607
|
}
|
|
608
|
+
const failedDetails = viewports.flatMap((viewport) => {
|
|
609
|
+
const name = cliString(viewport.name) || "viewport";
|
|
610
|
+
const failed = Array.isArray(viewport.failed) ? viewport.failed.map(cliRecord).filter((item) => Boolean(item)) : [];
|
|
611
|
+
return failed.map((failure) => ({ name, failure }));
|
|
612
|
+
});
|
|
613
|
+
for (const { name, failure } of failedDetails.slice(0, 8)) {
|
|
614
|
+
const action = cliString(failure.action) || "setup_action";
|
|
615
|
+
const selector = cliString(failure.selector);
|
|
616
|
+
const reason = cliString(failure.reason);
|
|
617
|
+
const caseInsensitiveText = cliString(failure.case_insensitive_text);
|
|
618
|
+
lines.push(`- failed ${name}: ${action}${selector ? ` ${markdownInlineCode(selector)}` : ""}${reason ? ` reason ${markdownInlineCode(reason)}` : ""}${caseInsensitiveText ? `; case-insensitive sample ${markdownInlineCode(caseInsensitiveText, 140)}` : ""}`);
|
|
619
|
+
}
|
|
620
|
+
if (failedDetails.length > 8) lines.push(`- ${failedDetails.length - 8} additional failed setup action(s) omitted.`);
|
|
608
621
|
if (viewports.length > 8) lines.push(`- ${viewports.length - 8} additional viewport(s) omitted from setup summary.`);
|
|
609
622
|
return lines;
|
|
610
623
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -9248,14 +9248,16 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
|
|
|
9248
9248
|
action: profileSetupResultAction(result),
|
|
9249
9249
|
selector: result.selector ?? null,
|
|
9250
9250
|
frame_selector: result.frame_selector ?? null,
|
|
9251
|
-
reason: result.reason ?? result.error ?? null
|
|
9251
|
+
reason: result.reason ?? result.error ?? null,
|
|
9252
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text)
|
|
9252
9253
|
})),
|
|
9253
9254
|
optional_failed: optionalFailed.map((result) => ({
|
|
9254
9255
|
ordinal: result.ordinal ?? null,
|
|
9255
9256
|
action: profileSetupResultAction(result),
|
|
9256
9257
|
selector: result.selector ?? null,
|
|
9257
9258
|
frame_selector: result.frame_selector ?? null,
|
|
9258
|
-
reason: result.reason ?? result.error ?? null
|
|
9259
|
+
reason: result.reason ?? result.error ?? null,
|
|
9260
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text)
|
|
9259
9261
|
}))
|
|
9260
9262
|
};
|
|
9261
9263
|
})
|
|
@@ -10633,6 +10635,27 @@ function textMatchSamples(sample, check) {
|
|
|
10633
10635
|
const sampleText = textSampleAroundMatch(source, index, text.length);
|
|
10634
10636
|
return sampleText ? [sampleText] : [];
|
|
10635
10637
|
}
|
|
10638
|
+
function textCaseInsensitiveSamples(sample, check) {
|
|
10639
|
+
const source = String(sample || "");
|
|
10640
|
+
const text = check.pattern ? "" : check.text || "";
|
|
10641
|
+
if (!source || !text) return [];
|
|
10642
|
+
const index = source.toLowerCase().indexOf(text.toLowerCase());
|
|
10643
|
+
const sampleText = textSampleAroundMatch(source, index, text.length);
|
|
10644
|
+
return sampleText ? [sampleText] : [];
|
|
10645
|
+
}
|
|
10646
|
+
function textCaseInsensitiveSequenceSamples(texts, check) {
|
|
10647
|
+
const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
|
|
10648
|
+
if (!text) return [];
|
|
10649
|
+
const expected = text.toLowerCase();
|
|
10650
|
+
return texts.map((candidate) => compactTextEvidenceSample(candidate)).filter((candidate) => candidate && candidate.toLowerCase().includes(expected)).slice(0, 3).map((candidate) => candidate.slice(0, 240));
|
|
10651
|
+
}
|
|
10652
|
+
function textCaseInsensitiveFailureSamples(viewport, check) {
|
|
10653
|
+
const key = textKey(check);
|
|
10654
|
+
const captured = viewport.text_case_insensitive_samples?.[key] || [];
|
|
10655
|
+
const capturedSamples = captured.map((sample) => compactTextEvidenceSample(sample).slice(0, 240)).filter(Boolean);
|
|
10656
|
+
if (capturedSamples.length) return capturedSamples.slice(0, 3);
|
|
10657
|
+
return textCaseInsensitiveSamples(viewport.body_text_sample || "", check).slice(0, 3);
|
|
10658
|
+
}
|
|
10636
10659
|
function textCheckFailureSamples(viewport, check) {
|
|
10637
10660
|
const key = textKey(check);
|
|
10638
10661
|
const captured = viewport.text_match_samples?.[key] || [];
|
|
@@ -10945,13 +10968,15 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
10945
10968
|
const matched = matches.length > 0;
|
|
10946
10969
|
const failedAgainstExpectation = matched !== expectedVisible;
|
|
10947
10970
|
const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
|
|
10971
|
+
const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveSequenceSamples(texts, check) : [];
|
|
10948
10972
|
return {
|
|
10949
10973
|
viewport: viewport.name,
|
|
10950
10974
|
selector_count: viewport.selectors?.[key]?.count || 0,
|
|
10951
10975
|
visible_count: viewport.selectors?.[key]?.visible_count || 0,
|
|
10952
10976
|
matched_count: matches.length,
|
|
10953
10977
|
matched,
|
|
10954
|
-
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240))
|
|
10978
|
+
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
|
|
10979
|
+
case_insensitive_samples: caseInsensitiveSamples
|
|
10955
10980
|
};
|
|
10956
10981
|
});
|
|
10957
10982
|
const failed = results.filter((result) => result.matched !== expectedVisible).length;
|
|
@@ -11094,7 +11119,8 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
11094
11119
|
return {
|
|
11095
11120
|
viewport: viewport.name,
|
|
11096
11121
|
matched,
|
|
11097
|
-
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : []
|
|
11122
|
+
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
|
|
11123
|
+
case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveFailureSamples(viewport, check) : []
|
|
11098
11124
|
};
|
|
11099
11125
|
});
|
|
11100
11126
|
const matches = results.map((result) => result.matched);
|
|
@@ -11724,6 +11750,32 @@ function textMatchSamples(sample, check) {
|
|
|
11724
11750
|
const sampleText = textSampleAroundMatch(source, source.indexOf(text), text.length);
|
|
11725
11751
|
return sampleText ? [sampleText] : [];
|
|
11726
11752
|
}
|
|
11753
|
+
function textCaseInsensitiveSamples(sample, check) {
|
|
11754
|
+
const source = String(sample || "");
|
|
11755
|
+
const text = check.pattern ? "" : check.text || "";
|
|
11756
|
+
if (!source || !text) return [];
|
|
11757
|
+
const sampleText = textSampleAroundMatch(source, source.toLowerCase().indexOf(text.toLowerCase()), text.length);
|
|
11758
|
+
return sampleText ? [sampleText] : [];
|
|
11759
|
+
}
|
|
11760
|
+
function textCaseInsensitiveSequenceSamples(texts, check) {
|
|
11761
|
+
const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
|
|
11762
|
+
if (!text) return [];
|
|
11763
|
+
const expected = text.toLowerCase();
|
|
11764
|
+
return (texts || [])
|
|
11765
|
+
.map((candidate) => compactTextEvidenceSample(candidate))
|
|
11766
|
+
.filter((candidate) => candidate && candidate.toLowerCase().includes(expected))
|
|
11767
|
+
.slice(0, 3)
|
|
11768
|
+
.map((candidate) => candidate.slice(0, 240));
|
|
11769
|
+
}
|
|
11770
|
+
function textCaseInsensitiveFailureSamples(viewport, check) {
|
|
11771
|
+
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
11772
|
+
const captured = viewport && viewport.text_case_insensitive_samples && Array.isArray(viewport.text_case_insensitive_samples[key]) ? viewport.text_case_insensitive_samples[key] : [];
|
|
11773
|
+
const capturedSamples = captured
|
|
11774
|
+
.map((sample) => compactTextEvidenceSample(sample).slice(0, 240))
|
|
11775
|
+
.filter(Boolean);
|
|
11776
|
+
if (capturedSamples.length) return capturedSamples.slice(0, 3);
|
|
11777
|
+
return textCaseInsensitiveSamples(viewport && viewport.body_text_sample || "", check).slice(0, 3);
|
|
11778
|
+
}
|
|
11727
11779
|
function textCheckFailureSamples(viewport, check) {
|
|
11728
11780
|
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
11729
11781
|
const captured = viewport && viewport.text_match_samples && Array.isArray(viewport.text_match_samples[key]) ? viewport.text_match_samples[key] : [];
|
|
@@ -12370,6 +12422,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
12370
12422
|
selector: result.selector ?? null,
|
|
12371
12423
|
frame_selector: result.frame_selector ?? null,
|
|
12372
12424
|
reason: result.reason || result.error || null,
|
|
12425
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text),
|
|
12373
12426
|
})),
|
|
12374
12427
|
optional_failed: optionalFailed.map((result) => ({
|
|
12375
12428
|
ordinal: result.ordinal ?? null,
|
|
@@ -12377,6 +12430,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
12377
12430
|
selector: result.selector ?? null,
|
|
12378
12431
|
frame_selector: result.frame_selector ?? null,
|
|
12379
12432
|
reason: result.reason || result.error || null,
|
|
12433
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text),
|
|
12380
12434
|
})),
|
|
12381
12435
|
};
|
|
12382
12436
|
}),
|
|
@@ -12682,6 +12736,9 @@ function assessProfile(profile, evidence) {
|
|
|
12682
12736
|
const matched = matches.length > 0;
|
|
12683
12737
|
const failedAgainstExpectation = matched !== expectedVisible;
|
|
12684
12738
|
const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
|
|
12739
|
+
const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched
|
|
12740
|
+
? textCaseInsensitiveSequenceSamples(texts, check)
|
|
12741
|
+
: [];
|
|
12685
12742
|
return {
|
|
12686
12743
|
viewport: viewport.name,
|
|
12687
12744
|
selector_count: viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].count : 0,
|
|
@@ -12689,6 +12746,7 @@ function assessProfile(profile, evidence) {
|
|
|
12689
12746
|
matched_count: matches.length,
|
|
12690
12747
|
matched,
|
|
12691
12748
|
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
|
|
12749
|
+
case_insensitive_samples: caseInsensitiveSamples,
|
|
12692
12750
|
};
|
|
12693
12751
|
});
|
|
12694
12752
|
const failed = results.filter((result) => result.matched !== expectedVisible).length;
|
|
@@ -12820,6 +12878,9 @@ function assessProfile(profile, evidence) {
|
|
|
12820
12878
|
viewport: viewport.name,
|
|
12821
12879
|
matched,
|
|
12822
12880
|
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
|
|
12881
|
+
case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched
|
|
12882
|
+
? textCaseInsensitiveFailureSamples(viewport, check)
|
|
12883
|
+
: [],
|
|
12823
12884
|
};
|
|
12824
12885
|
});
|
|
12825
12886
|
const matches = results.map((result) => result.matched);
|
|
@@ -13209,6 +13270,14 @@ function setupTextMatches(sample, action) {
|
|
|
13209
13270
|
return rawSample.includes(expected)
|
|
13210
13271
|
|| normalizeSetupMatchText(rawSample).includes(normalizeSetupMatchText(expected));
|
|
13211
13272
|
}
|
|
13273
|
+
function setupCaseInsensitiveTextSample(sample, action) {
|
|
13274
|
+
if (!action || action.pattern || !action.text) return "";
|
|
13275
|
+
const normalizedSample = normalizeSetupMatchText(sample);
|
|
13276
|
+
const normalizedExpected = normalizeSetupMatchText(action.text);
|
|
13277
|
+
if (!normalizedSample || !normalizedExpected) return "";
|
|
13278
|
+
if (!normalizedSample.toLowerCase().includes(normalizedExpected.toLowerCase())) return "";
|
|
13279
|
+
return compactSetupResultText(normalizedSample);
|
|
13280
|
+
}
|
|
13212
13281
|
async function waitForAnyVisibleSelector(context, selector, timeout) {
|
|
13213
13282
|
const deadline = Date.now() + setupNumber(timeout, 15000);
|
|
13214
13283
|
let lastReason = "selector_not_found";
|
|
@@ -13959,6 +14028,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
13959
14028
|
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
13960
14029
|
let targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
13961
14030
|
let matchedText = null;
|
|
14031
|
+
let caseInsensitiveText = null;
|
|
13962
14032
|
let hiddenMatchIndex = -1;
|
|
13963
14033
|
let hiddenMatchedText = null;
|
|
13964
14034
|
if (action.text || action.pattern) {
|
|
@@ -13976,10 +14046,12 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
13976
14046
|
hiddenMatchIndex = index;
|
|
13977
14047
|
hiddenMatchedText = compactSetupResultText(text);
|
|
13978
14048
|
}
|
|
14049
|
+
} else if (!caseInsensitiveText) {
|
|
14050
|
+
caseInsensitiveText = setupCaseInsensitiveTextSample(text, action) || null;
|
|
13979
14051
|
}
|
|
13980
14052
|
}
|
|
13981
14053
|
if (targetIndex < 0 && hiddenMatchIndex >= 0) return { ...base, reason: "matching_element_not_visible", count, target_index: hiddenMatchIndex, text: hiddenMatchedText };
|
|
13982
|
-
if (targetIndex < 0) return { ...base, reason: "text_not_found", count };
|
|
14054
|
+
if (targetIndex < 0) return { ...base, reason: "text_not_found", count, case_insensitive_text: caseInsensitiveText || undefined };
|
|
13983
14055
|
}
|
|
13984
14056
|
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
|
|
13985
14057
|
const clickOptions = action.force === true
|
|
@@ -14023,6 +14095,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
14023
14095
|
const locator = scope.context.locator(action.selector);
|
|
14024
14096
|
const startedAt = Date.now();
|
|
14025
14097
|
let lastText = "";
|
|
14098
|
+
let caseInsensitiveText = "";
|
|
14026
14099
|
while (Date.now() - startedAt <= timeout) {
|
|
14027
14100
|
const count = await locator.count().catch(() => 0);
|
|
14028
14101
|
for (let index = 0; index < count; index += 1) {
|
|
@@ -14031,10 +14104,11 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
14031
14104
|
if (setupTextMatches(text, action)) {
|
|
14032
14105
|
return { ...base, ...setupScopeEvidence(scope), ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
|
|
14033
14106
|
}
|
|
14107
|
+
caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
|
|
14034
14108
|
}
|
|
14035
14109
|
await page.waitForTimeout(100);
|
|
14036
14110
|
}
|
|
14037
|
-
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
|
|
14111
|
+
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
|
|
14038
14112
|
}
|
|
14039
14113
|
if (type === "assert_text_visible" || type === "assert_text_absent") {
|
|
14040
14114
|
const scope = await setupActionScope(action, timeout);
|
|
@@ -14043,6 +14117,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
14043
14117
|
const startedAt = Date.now();
|
|
14044
14118
|
let lastText = "";
|
|
14045
14119
|
let matchedText = "";
|
|
14120
|
+
let caseInsensitiveText = "";
|
|
14046
14121
|
let hiddenMatch = false;
|
|
14047
14122
|
while (Date.now() - startedAt <= timeout) {
|
|
14048
14123
|
const count = await locator.count().catch(() => 0);
|
|
@@ -14065,6 +14140,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
14065
14140
|
}
|
|
14066
14141
|
break;
|
|
14067
14142
|
}
|
|
14143
|
+
caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
|
|
14068
14144
|
}
|
|
14069
14145
|
if (type === "assert_text_absent" && !matched) {
|
|
14070
14146
|
return { ...base, ...setupScopeEvidence(scope), ok: true, count, timeout_ms: timeout };
|
|
@@ -14075,7 +14151,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
14075
14151
|
if (hiddenMatch) {
|
|
14076
14152
|
return { ...base, ...setupScopeEvidence(scope), reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
|
|
14077
14153
|
}
|
|
14078
|
-
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
|
|
14154
|
+
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
|
|
14079
14155
|
}
|
|
14080
14156
|
return { ...base, ...setupScopeEvidence(scope), reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
|
|
14081
14157
|
}
|
|
@@ -15183,6 +15259,7 @@ async function captureViewport(viewport) {
|
|
|
15183
15259
|
const text_sequences = {};
|
|
15184
15260
|
const text_matches = {};
|
|
15185
15261
|
const text_match_samples = {};
|
|
15262
|
+
const text_case_insensitive_samples = {};
|
|
15186
15263
|
const http_statuses = {};
|
|
15187
15264
|
const link_statuses = {};
|
|
15188
15265
|
for (const check of profile.checks || []) {
|
|
@@ -15208,6 +15285,7 @@ async function captureViewport(viewport) {
|
|
|
15208
15285
|
const sample = dom.body_text || dom.body_text_sample || "";
|
|
15209
15286
|
text_matches[key] = textMatches(sample, check);
|
|
15210
15287
|
text_match_samples[key] = textMatchSamples(sample, check);
|
|
15288
|
+
text_case_insensitive_samples[key] = textCaseInsensitiveSamples(sample, check);
|
|
15211
15289
|
}
|
|
15212
15290
|
if ((check.type === "frame_text_visible" || check.type === "frame_url_equals" || check.type === "frame_url_matches" || check.type === "frame_no_horizontal_overflow") && check.selector) {
|
|
15213
15291
|
selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
|
|
@@ -15285,6 +15363,7 @@ async function captureViewport(viewport) {
|
|
|
15285
15363
|
text_sequences,
|
|
15286
15364
|
text_matches,
|
|
15287
15365
|
text_match_samples,
|
|
15366
|
+
text_case_insensitive_samples,
|
|
15288
15367
|
http_statuses,
|
|
15289
15368
|
link_statuses,
|
|
15290
15369
|
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-
|
|
65
|
+
} from "./chunk-PKE223TX.js";
|
|
66
66
|
import {
|
|
67
67
|
DEFAULT_RIDDLE_API_BASE_URL,
|
|
68
68
|
DEFAULT_RIDDLE_API_KEY_FILE,
|
package/dist/profile.cjs
CHANGED
|
@@ -562,14 +562,16 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountByViewpo
|
|
|
562
562
|
action: profileSetupResultAction(result),
|
|
563
563
|
selector: result.selector ?? null,
|
|
564
564
|
frame_selector: result.frame_selector ?? null,
|
|
565
|
-
reason: result.reason ?? result.error ?? null
|
|
565
|
+
reason: result.reason ?? result.error ?? null,
|
|
566
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text)
|
|
566
567
|
})),
|
|
567
568
|
optional_failed: optionalFailed.map((result) => ({
|
|
568
569
|
ordinal: result.ordinal ?? null,
|
|
569
570
|
action: profileSetupResultAction(result),
|
|
570
571
|
selector: result.selector ?? null,
|
|
571
572
|
frame_selector: result.frame_selector ?? null,
|
|
572
|
-
reason: result.reason ?? result.error ?? null
|
|
573
|
+
reason: result.reason ?? result.error ?? null,
|
|
574
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text)
|
|
573
575
|
}))
|
|
574
576
|
};
|
|
575
577
|
})
|
|
@@ -1947,6 +1949,27 @@ function textMatchSamples(sample, check) {
|
|
|
1947
1949
|
const sampleText = textSampleAroundMatch(source, index, text.length);
|
|
1948
1950
|
return sampleText ? [sampleText] : [];
|
|
1949
1951
|
}
|
|
1952
|
+
function textCaseInsensitiveSamples(sample, check) {
|
|
1953
|
+
const source = String(sample || "");
|
|
1954
|
+
const text = check.pattern ? "" : check.text || "";
|
|
1955
|
+
if (!source || !text) return [];
|
|
1956
|
+
const index = source.toLowerCase().indexOf(text.toLowerCase());
|
|
1957
|
+
const sampleText = textSampleAroundMatch(source, index, text.length);
|
|
1958
|
+
return sampleText ? [sampleText] : [];
|
|
1959
|
+
}
|
|
1960
|
+
function textCaseInsensitiveSequenceSamples(texts, check) {
|
|
1961
|
+
const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
|
|
1962
|
+
if (!text) return [];
|
|
1963
|
+
const expected = text.toLowerCase();
|
|
1964
|
+
return texts.map((candidate) => compactTextEvidenceSample(candidate)).filter((candidate) => candidate && candidate.toLowerCase().includes(expected)).slice(0, 3).map((candidate) => candidate.slice(0, 240));
|
|
1965
|
+
}
|
|
1966
|
+
function textCaseInsensitiveFailureSamples(viewport, check) {
|
|
1967
|
+
const key = textKey(check);
|
|
1968
|
+
const captured = viewport.text_case_insensitive_samples?.[key] || [];
|
|
1969
|
+
const capturedSamples = captured.map((sample) => compactTextEvidenceSample(sample).slice(0, 240)).filter(Boolean);
|
|
1970
|
+
if (capturedSamples.length) return capturedSamples.slice(0, 3);
|
|
1971
|
+
return textCaseInsensitiveSamples(viewport.body_text_sample || "", check).slice(0, 3);
|
|
1972
|
+
}
|
|
1950
1973
|
function textCheckFailureSamples(viewport, check) {
|
|
1951
1974
|
const key = textKey(check);
|
|
1952
1975
|
const captured = viewport.text_match_samples?.[key] || [];
|
|
@@ -2259,13 +2282,15 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
2259
2282
|
const matched = matches.length > 0;
|
|
2260
2283
|
const failedAgainstExpectation = matched !== expectedVisible;
|
|
2261
2284
|
const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
|
|
2285
|
+
const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveSequenceSamples(texts, check) : [];
|
|
2262
2286
|
return {
|
|
2263
2287
|
viewport: viewport.name,
|
|
2264
2288
|
selector_count: viewport.selectors?.[key]?.count || 0,
|
|
2265
2289
|
visible_count: viewport.selectors?.[key]?.visible_count || 0,
|
|
2266
2290
|
matched_count: matches.length,
|
|
2267
2291
|
matched,
|
|
2268
|
-
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240))
|
|
2292
|
+
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
|
|
2293
|
+
case_insensitive_samples: caseInsensitiveSamples
|
|
2269
2294
|
};
|
|
2270
2295
|
});
|
|
2271
2296
|
const failed = results.filter((result) => result.matched !== expectedVisible).length;
|
|
@@ -2408,7 +2433,8 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
2408
2433
|
return {
|
|
2409
2434
|
viewport: viewport.name,
|
|
2410
2435
|
matched,
|
|
2411
|
-
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : []
|
|
2436
|
+
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
|
|
2437
|
+
case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched ? textCaseInsensitiveFailureSamples(viewport, check) : []
|
|
2412
2438
|
};
|
|
2413
2439
|
});
|
|
2414
2440
|
const matches = results.map((result) => result.matched);
|
|
@@ -3038,6 +3064,32 @@ function textMatchSamples(sample, check) {
|
|
|
3038
3064
|
const sampleText = textSampleAroundMatch(source, source.indexOf(text), text.length);
|
|
3039
3065
|
return sampleText ? [sampleText] : [];
|
|
3040
3066
|
}
|
|
3067
|
+
function textCaseInsensitiveSamples(sample, check) {
|
|
3068
|
+
const source = String(sample || "");
|
|
3069
|
+
const text = check.pattern ? "" : check.text || "";
|
|
3070
|
+
if (!source || !text) return [];
|
|
3071
|
+
const sampleText = textSampleAroundMatch(source, source.toLowerCase().indexOf(text.toLowerCase()), text.length);
|
|
3072
|
+
return sampleText ? [sampleText] : [];
|
|
3073
|
+
}
|
|
3074
|
+
function textCaseInsensitiveSequenceSamples(texts, check) {
|
|
3075
|
+
const text = check.pattern ? "" : compactTextEvidenceSample(check.text || "");
|
|
3076
|
+
if (!text) return [];
|
|
3077
|
+
const expected = text.toLowerCase();
|
|
3078
|
+
return (texts || [])
|
|
3079
|
+
.map((candidate) => compactTextEvidenceSample(candidate))
|
|
3080
|
+
.filter((candidate) => candidate && candidate.toLowerCase().includes(expected))
|
|
3081
|
+
.slice(0, 3)
|
|
3082
|
+
.map((candidate) => candidate.slice(0, 240));
|
|
3083
|
+
}
|
|
3084
|
+
function textCaseInsensitiveFailureSamples(viewport, check) {
|
|
3085
|
+
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
3086
|
+
const captured = viewport && viewport.text_case_insensitive_samples && Array.isArray(viewport.text_case_insensitive_samples[key]) ? viewport.text_case_insensitive_samples[key] : [];
|
|
3087
|
+
const capturedSamples = captured
|
|
3088
|
+
.map((sample) => compactTextEvidenceSample(sample).slice(0, 240))
|
|
3089
|
+
.filter(Boolean);
|
|
3090
|
+
if (capturedSamples.length) return capturedSamples.slice(0, 3);
|
|
3091
|
+
return textCaseInsensitiveSamples(viewport && viewport.body_text_sample || "", check).slice(0, 3);
|
|
3092
|
+
}
|
|
3041
3093
|
function textCheckFailureSamples(viewport, check) {
|
|
3042
3094
|
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
3043
3095
|
const captured = viewport && viewport.text_match_samples && Array.isArray(viewport.text_match_samples[key]) ? viewport.text_match_samples[key] : [];
|
|
@@ -3684,6 +3736,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
3684
3736
|
selector: result.selector ?? null,
|
|
3685
3737
|
frame_selector: result.frame_selector ?? null,
|
|
3686
3738
|
reason: result.reason || result.error || null,
|
|
3739
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text),
|
|
3687
3740
|
})),
|
|
3688
3741
|
optional_failed: optionalFailed.map((result) => ({
|
|
3689
3742
|
ordinal: result.ordinal ?? null,
|
|
@@ -3691,6 +3744,7 @@ function profileSetupSummary(viewports, actionCount, expectedActionCountsByViewp
|
|
|
3691
3744
|
selector: result.selector ?? null,
|
|
3692
3745
|
frame_selector: result.frame_selector ?? null,
|
|
3693
3746
|
reason: result.reason || result.error || null,
|
|
3747
|
+
case_insensitive_text: compactProfileSetupSummaryText(result.case_insensitive_text),
|
|
3694
3748
|
})),
|
|
3695
3749
|
};
|
|
3696
3750
|
}),
|
|
@@ -3996,6 +4050,9 @@ function assessProfile(profile, evidence) {
|
|
|
3996
4050
|
const matched = matches.length > 0;
|
|
3997
4051
|
const failedAgainstExpectation = matched !== expectedVisible;
|
|
3998
4052
|
const sampleTexts = matches.length ? matches : failedAgainstExpectation ? texts : [];
|
|
4053
|
+
const caseInsensitiveSamples = failedAgainstExpectation && expectedVisible && !matched
|
|
4054
|
+
? textCaseInsensitiveSequenceSamples(texts, check)
|
|
4055
|
+
: [];
|
|
3999
4056
|
return {
|
|
4000
4057
|
viewport: viewport.name,
|
|
4001
4058
|
selector_count: viewport.selectors && viewport.selectors[selector] ? viewport.selectors[selector].count : 0,
|
|
@@ -4003,6 +4060,7 @@ function assessProfile(profile, evidence) {
|
|
|
4003
4060
|
matched_count: matches.length,
|
|
4004
4061
|
matched,
|
|
4005
4062
|
samples: sampleTexts.slice(0, 3).map((text) => text.slice(0, 240)),
|
|
4063
|
+
case_insensitive_samples: caseInsensitiveSamples,
|
|
4006
4064
|
};
|
|
4007
4065
|
});
|
|
4008
4066
|
const failed = results.filter((result) => result.matched !== expectedVisible).length;
|
|
@@ -4134,6 +4192,9 @@ function assessProfile(profile, evidence) {
|
|
|
4134
4192
|
viewport: viewport.name,
|
|
4135
4193
|
matched,
|
|
4136
4194
|
samples: failedAgainstExpectation ? textCheckFailureSamples(viewport, check) : [],
|
|
4195
|
+
case_insensitive_samples: failedAgainstExpectation && expectedVisible && !matched
|
|
4196
|
+
? textCaseInsensitiveFailureSamples(viewport, check)
|
|
4197
|
+
: [],
|
|
4137
4198
|
};
|
|
4138
4199
|
});
|
|
4139
4200
|
const matches = results.map((result) => result.matched);
|
|
@@ -4523,6 +4584,14 @@ function setupTextMatches(sample, action) {
|
|
|
4523
4584
|
return rawSample.includes(expected)
|
|
4524
4585
|
|| normalizeSetupMatchText(rawSample).includes(normalizeSetupMatchText(expected));
|
|
4525
4586
|
}
|
|
4587
|
+
function setupCaseInsensitiveTextSample(sample, action) {
|
|
4588
|
+
if (!action || action.pattern || !action.text) return "";
|
|
4589
|
+
const normalizedSample = normalizeSetupMatchText(sample);
|
|
4590
|
+
const normalizedExpected = normalizeSetupMatchText(action.text);
|
|
4591
|
+
if (!normalizedSample || !normalizedExpected) return "";
|
|
4592
|
+
if (!normalizedSample.toLowerCase().includes(normalizedExpected.toLowerCase())) return "";
|
|
4593
|
+
return compactSetupResultText(normalizedSample);
|
|
4594
|
+
}
|
|
4526
4595
|
async function waitForAnyVisibleSelector(context, selector, timeout) {
|
|
4527
4596
|
const deadline = Date.now() + setupNumber(timeout, 15000);
|
|
4528
4597
|
let lastReason = "selector_not_found";
|
|
@@ -5273,6 +5342,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5273
5342
|
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
5274
5343
|
let targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
5275
5344
|
let matchedText = null;
|
|
5345
|
+
let caseInsensitiveText = null;
|
|
5276
5346
|
let hiddenMatchIndex = -1;
|
|
5277
5347
|
let hiddenMatchedText = null;
|
|
5278
5348
|
if (action.text || action.pattern) {
|
|
@@ -5290,10 +5360,12 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5290
5360
|
hiddenMatchIndex = index;
|
|
5291
5361
|
hiddenMatchedText = compactSetupResultText(text);
|
|
5292
5362
|
}
|
|
5363
|
+
} else if (!caseInsensitiveText) {
|
|
5364
|
+
caseInsensitiveText = setupCaseInsensitiveTextSample(text, action) || null;
|
|
5293
5365
|
}
|
|
5294
5366
|
}
|
|
5295
5367
|
if (targetIndex < 0 && hiddenMatchIndex >= 0) return { ...base, reason: "matching_element_not_visible", count, target_index: hiddenMatchIndex, text: hiddenMatchedText };
|
|
5296
|
-
if (targetIndex < 0) return { ...base, reason: "text_not_found", count };
|
|
5368
|
+
if (targetIndex < 0) return { ...base, reason: "text_not_found", count, case_insensitive_text: caseInsensitiveText || undefined };
|
|
5297
5369
|
}
|
|
5298
5370
|
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
|
|
5299
5371
|
const clickOptions = action.force === true
|
|
@@ -5337,6 +5409,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5337
5409
|
const locator = scope.context.locator(action.selector);
|
|
5338
5410
|
const startedAt = Date.now();
|
|
5339
5411
|
let lastText = "";
|
|
5412
|
+
let caseInsensitiveText = "";
|
|
5340
5413
|
while (Date.now() - startedAt <= timeout) {
|
|
5341
5414
|
const count = await locator.count().catch(() => 0);
|
|
5342
5415
|
for (let index = 0; index < count; index += 1) {
|
|
@@ -5345,10 +5418,11 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5345
5418
|
if (setupTextMatches(text, action)) {
|
|
5346
5419
|
return { ...base, ...setupScopeEvidence(scope), ok: true, text: compactSetupResultText(text), target_index: index, timeout_ms: timeout };
|
|
5347
5420
|
}
|
|
5421
|
+
caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
|
|
5348
5422
|
}
|
|
5349
5423
|
await page.waitForTimeout(100);
|
|
5350
5424
|
}
|
|
5351
|
-
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
|
|
5425
|
+
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
|
|
5352
5426
|
}
|
|
5353
5427
|
if (type === "assert_text_visible" || type === "assert_text_absent") {
|
|
5354
5428
|
const scope = await setupActionScope(action, timeout);
|
|
@@ -5357,6 +5431,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5357
5431
|
const startedAt = Date.now();
|
|
5358
5432
|
let lastText = "";
|
|
5359
5433
|
let matchedText = "";
|
|
5434
|
+
let caseInsensitiveText = "";
|
|
5360
5435
|
let hiddenMatch = false;
|
|
5361
5436
|
while (Date.now() - startedAt <= timeout) {
|
|
5362
5437
|
const count = await locator.count().catch(() => 0);
|
|
@@ -5379,6 +5454,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5379
5454
|
}
|
|
5380
5455
|
break;
|
|
5381
5456
|
}
|
|
5457
|
+
caseInsensitiveText = caseInsensitiveText || setupCaseInsensitiveTextSample(text, action);
|
|
5382
5458
|
}
|
|
5383
5459
|
if (type === "assert_text_absent" && !matched) {
|
|
5384
5460
|
return { ...base, ...setupScopeEvidence(scope), ok: true, count, timeout_ms: timeout };
|
|
@@ -5389,7 +5465,7 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
5389
5465
|
if (hiddenMatch) {
|
|
5390
5466
|
return { ...base, ...setupScopeEvidence(scope), reason: "matching_element_not_visible", text: compactSetupResultText(matchedText), timeout_ms: timeout };
|
|
5391
5467
|
}
|
|
5392
|
-
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), timeout_ms: timeout };
|
|
5468
|
+
return { ...base, ...setupScopeEvidence(scope), reason: "text_not_found", text: compactSetupResultText(lastText), case_insensitive_text: caseInsensitiveText || undefined, timeout_ms: timeout };
|
|
5393
5469
|
}
|
|
5394
5470
|
return { ...base, ...setupScopeEvidence(scope), reason: "text_still_present", text: compactSetupResultText(matchedText || lastText), timeout_ms: timeout };
|
|
5395
5471
|
}
|
|
@@ -6497,6 +6573,7 @@ async function captureViewport(viewport) {
|
|
|
6497
6573
|
const text_sequences = {};
|
|
6498
6574
|
const text_matches = {};
|
|
6499
6575
|
const text_match_samples = {};
|
|
6576
|
+
const text_case_insensitive_samples = {};
|
|
6500
6577
|
const http_statuses = {};
|
|
6501
6578
|
const link_statuses = {};
|
|
6502
6579
|
for (const check of profile.checks || []) {
|
|
@@ -6522,6 +6599,7 @@ async function captureViewport(viewport) {
|
|
|
6522
6599
|
const sample = dom.body_text || dom.body_text_sample || "";
|
|
6523
6600
|
text_matches[key] = textMatches(sample, check);
|
|
6524
6601
|
text_match_samples[key] = textMatchSamples(sample, check);
|
|
6602
|
+
text_case_insensitive_samples[key] = textCaseInsensitiveSamples(sample, check);
|
|
6525
6603
|
}
|
|
6526
6604
|
if ((check.type === "frame_text_visible" || check.type === "frame_url_equals" || check.type === "frame_url_matches" || check.type === "frame_no_horizontal_overflow") && check.selector) {
|
|
6527
6605
|
selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
|
|
@@ -6599,6 +6677,7 @@ async function captureViewport(viewport) {
|
|
|
6599
6677
|
text_sequences,
|
|
6600
6678
|
text_matches,
|
|
6601
6679
|
text_match_samples,
|
|
6680
|
+
text_case_insensitive_samples,
|
|
6602
6681
|
http_statuses,
|
|
6603
6682
|
link_statuses,
|
|
6604
6683
|
route_inventory: routeInventory,
|
package/dist/profile.d.cts
CHANGED
|
@@ -309,6 +309,7 @@ interface RiddleProofProfileViewportEvidence {
|
|
|
309
309
|
text_sequences?: Record<string, Record<string, JsonValue>>;
|
|
310
310
|
text_matches?: Record<string, boolean>;
|
|
311
311
|
text_match_samples?: Record<string, string[]>;
|
|
312
|
+
text_case_insensitive_samples?: Record<string, string[]>;
|
|
312
313
|
http_statuses?: Record<string, Record<string, JsonValue>>;
|
|
313
314
|
link_statuses?: Record<string, Record<string, JsonValue>>;
|
|
314
315
|
route_inventory?: Record<string, JsonValue>;
|
package/dist/profile.d.ts
CHANGED
|
@@ -309,6 +309,7 @@ interface RiddleProofProfileViewportEvidence {
|
|
|
309
309
|
text_sequences?: Record<string, Record<string, JsonValue>>;
|
|
310
310
|
text_matches?: Record<string, boolean>;
|
|
311
311
|
text_match_samples?: Record<string, string[]>;
|
|
312
|
+
text_case_insensitive_samples?: Record<string, string[]>;
|
|
312
313
|
http_statuses?: Record<string, Record<string, JsonValue>>;
|
|
313
314
|
link_statuses?: Record<string, Record<string, JsonValue>>;
|
|
314
315
|
route_inventory?: Record<string, JsonValue>;
|
package/dist/profile.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
resolveRiddleProofProfileTimeoutSec,
|
|
24
24
|
slugifyRiddleProofProfileName,
|
|
25
25
|
summarizeRiddleProofProfileResult
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-PKE223TX.js";
|
|
27
27
|
export {
|
|
28
28
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
29
29
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|
|
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
292
292
|
blocking?: boolean;
|
|
293
293
|
details?: Record<string, unknown>;
|
|
294
294
|
ok: boolean;
|
|
295
|
-
action: "
|
|
295
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
296
296
|
state_path: string;
|
|
297
297
|
stage: any;
|
|
298
298
|
summary: string;
|
|
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
382
382
|
continueWithStage?: WorkflowStage | null;
|
|
383
383
|
blocking?: boolean;
|
|
384
384
|
details?: Record<string, unknown>;
|
|
385
|
-
action: "
|
|
385
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
386
386
|
state_path: string;
|
|
387
387
|
stage: any;
|
|
388
388
|
checkpoint: string;
|
|
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
659
659
|
error?: undefined;
|
|
660
660
|
} | {
|
|
661
661
|
ok: boolean;
|
|
662
|
-
action: "
|
|
662
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
663
663
|
state_path: string;
|
|
664
664
|
stage: any;
|
|
665
665
|
summary: string;
|
|
@@ -292,7 +292,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
292
292
|
blocking?: boolean;
|
|
293
293
|
details?: Record<string, unknown>;
|
|
294
294
|
ok: boolean;
|
|
295
|
-
action: "
|
|
295
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
296
296
|
state_path: string;
|
|
297
297
|
stage: any;
|
|
298
298
|
summary: string;
|
|
@@ -382,7 +382,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
382
382
|
continueWithStage?: WorkflowStage | null;
|
|
383
383
|
blocking?: boolean;
|
|
384
384
|
details?: Record<string, unknown>;
|
|
385
|
-
action: "
|
|
385
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
386
386
|
state_path: string;
|
|
387
387
|
stage: any;
|
|
388
388
|
checkpoint: string;
|
|
@@ -659,7 +659,7 @@ declare function executeWorkflow(params: WorkflowParams, pluginConfig: any, reso
|
|
|
659
659
|
error?: undefined;
|
|
660
660
|
} | {
|
|
661
661
|
ok: boolean;
|
|
662
|
-
action: "
|
|
662
|
+
action: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
663
663
|
state_path: string;
|
|
664
664
|
stage: any;
|
|
665
665
|
summary: string;
|