@riddledc/riddle-proof 0.7.33 → 0.7.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -7
- package/dist/{chunk-COUZXKGM.js → chunk-VCINQE5O.js} +173 -5
- package/dist/cli.cjs +173 -5
- package/dist/cli.js +1 -1
- package/dist/index.cjs +173 -5
- package/dist/index.js +1 -1
- package/dist/profile.cjs +173 -5
- package/dist/profile.d.cts +3 -1
- package/dist/profile.d.ts +3 -1
- package/dist/profile.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -8728,6 +8728,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
8728
8728
|
"route_loaded",
|
|
8729
8729
|
"selector_visible",
|
|
8730
8730
|
"selector_count_at_least",
|
|
8731
|
+
"selector_text_order",
|
|
8731
8732
|
"text_visible",
|
|
8732
8733
|
"text_absent",
|
|
8733
8734
|
"route_inventory",
|
|
@@ -9007,6 +9008,15 @@ function normalizeRouteInventoryRoutes(value, index) {
|
|
|
9007
9008
|
}
|
|
9008
9009
|
return routes;
|
|
9009
9010
|
}
|
|
9011
|
+
function normalizeExpectedTexts(value, index) {
|
|
9012
|
+
if (value === void 0) return void 0;
|
|
9013
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
9014
|
+
throw new Error(`checks[${index}] selector_text_order expected_texts must be a non-empty array.`);
|
|
9015
|
+
}
|
|
9016
|
+
const texts = value.map((item) => String(item).replace(/\s+/g, " ").trim()).filter(Boolean);
|
|
9017
|
+
if (!texts.length) throw new Error(`checks[${index}] selector_text_order expected_texts must contain non-empty strings.`);
|
|
9018
|
+
return texts;
|
|
9019
|
+
}
|
|
9010
9020
|
function normalizeCheck(input, index) {
|
|
9011
9021
|
if (!isRecord2(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
9012
9022
|
const type = stringValue5(input.type);
|
|
@@ -9023,6 +9033,11 @@ function normalizeCheck(input, index) {
|
|
|
9023
9033
|
if (type === "selector_count_at_least" && numberValue3(input.min_count) === void 0) {
|
|
9024
9034
|
throw new Error(`checks[${index}] selector_count_at_least requires min_count.`);
|
|
9025
9035
|
}
|
|
9036
|
+
const expectedTexts = normalizeExpectedTexts(input.expected_texts ?? input.expectedTexts, index);
|
|
9037
|
+
if (type === "selector_text_order") {
|
|
9038
|
+
if (!stringValue5(input.selector)) throw new Error(`checks[${index}] selector_text_order requires selector.`);
|
|
9039
|
+
if (!expectedTexts?.length) throw new Error(`checks[${index}] selector_text_order requires expected_texts.`);
|
|
9040
|
+
}
|
|
9026
9041
|
const expectedRoutes = normalizeRouteInventoryRoutes(input.expected_routes ?? input.expectedRoutes, index);
|
|
9027
9042
|
if (type === "route_inventory" && !expectedRoutes?.length) {
|
|
9028
9043
|
throw new Error(`checks[${index}] route_inventory requires expected_routes.`);
|
|
@@ -9033,6 +9048,7 @@ function normalizeCheck(input, index) {
|
|
|
9033
9048
|
expected_path: stringValue5(input.expected_path),
|
|
9034
9049
|
expected_routes: expectedRoutes,
|
|
9035
9050
|
selector: stringValue5(input.selector),
|
|
9051
|
+
expected_texts: expectedTexts,
|
|
9036
9052
|
link_selector: stringValue5(input.link_selector) || stringValue5(input.linkSelector),
|
|
9037
9053
|
source_selector: stringValue5(input.source_selector) || stringValue5(input.sourceSelector),
|
|
9038
9054
|
route_path_prefix: stringValue5(input.route_path_prefix) || stringValue5(input.routePathPrefix),
|
|
@@ -9138,6 +9154,28 @@ function selectorKey(check) {
|
|
|
9138
9154
|
function textKey(check) {
|
|
9139
9155
|
return check.pattern ? `pattern:${check.pattern}/${check.flags || ""}` : `text:${check.text || ""}`;
|
|
9140
9156
|
}
|
|
9157
|
+
function textSequenceForCheck(viewport, check) {
|
|
9158
|
+
const key = selectorKey(check);
|
|
9159
|
+
const sequence = viewport.text_sequences?.[key];
|
|
9160
|
+
if (isRecord2(sequence)) {
|
|
9161
|
+
const visibleTexts = Array.isArray(sequence.visible_texts) ? sequence.visible_texts : [];
|
|
9162
|
+
const texts = Array.isArray(sequence.texts) ? sequence.texts : [];
|
|
9163
|
+
const candidates = visibleTexts.length ? visibleTexts : texts;
|
|
9164
|
+
return candidates.map((text) => String(text).replace(/\s+/g, " ").trim()).filter(Boolean);
|
|
9165
|
+
}
|
|
9166
|
+
return [];
|
|
9167
|
+
}
|
|
9168
|
+
function textOrderMatch(texts, expectedTexts) {
|
|
9169
|
+
const positions = [];
|
|
9170
|
+
let startAt = 0;
|
|
9171
|
+
for (const expected of expectedTexts) {
|
|
9172
|
+
const index = texts.findIndex((text, offset) => offset >= startAt && text.includes(expected));
|
|
9173
|
+
if (index < 0) return { matched: false, positions };
|
|
9174
|
+
positions.push(index);
|
|
9175
|
+
startAt = index + 1;
|
|
9176
|
+
}
|
|
9177
|
+
return { matched: true, positions };
|
|
9178
|
+
}
|
|
9141
9179
|
function matchText(sample, check) {
|
|
9142
9180
|
if (check.pattern) {
|
|
9143
9181
|
try {
|
|
@@ -9257,6 +9295,32 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
9257
9295
|
message: failed.length ? `Selector ${key} count was below ${minCount} in ${failed.length} viewport(s).` : void 0
|
|
9258
9296
|
};
|
|
9259
9297
|
}
|
|
9298
|
+
if (check.type === "selector_text_order") {
|
|
9299
|
+
const key = selectorKey(check);
|
|
9300
|
+
const expectedTexts = check.expected_texts || [];
|
|
9301
|
+
const results = viewports.map((viewport) => {
|
|
9302
|
+
const texts = textSequenceForCheck(viewport, check);
|
|
9303
|
+
const match = textOrderMatch(texts, expectedTexts);
|
|
9304
|
+
return {
|
|
9305
|
+
viewport: viewport.name,
|
|
9306
|
+
matched: match.matched,
|
|
9307
|
+
matched_positions: match.positions,
|
|
9308
|
+
visible_texts: texts.slice(0, 20)
|
|
9309
|
+
};
|
|
9310
|
+
});
|
|
9311
|
+
const failed = results.filter((result) => !result.matched).length;
|
|
9312
|
+
return {
|
|
9313
|
+
type: check.type,
|
|
9314
|
+
label: checkLabel(check),
|
|
9315
|
+
status: failed ? "failed" : "passed",
|
|
9316
|
+
evidence: {
|
|
9317
|
+
selector: key,
|
|
9318
|
+
expected_texts: expectedTexts,
|
|
9319
|
+
viewports: results.map((result) => toJsonValue(result))
|
|
9320
|
+
},
|
|
9321
|
+
message: failed ? `Selector ${key} text order failed in ${failed} viewport(s).` : void 0
|
|
9322
|
+
};
|
|
9323
|
+
}
|
|
9260
9324
|
if (check.type === "text_visible" || check.type === "text_absent") {
|
|
9261
9325
|
const key = textKey(check);
|
|
9262
9326
|
const expectedVisible = check.type === "text_visible";
|
|
@@ -9292,14 +9356,23 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
9292
9356
|
const first = inventories[0]?.inventory;
|
|
9293
9357
|
const directRoutes = Array.isArray(first?.direct_routes) ? first.direct_routes : [];
|
|
9294
9358
|
const clickthroughs = Array.isArray(first?.clickthroughs) ? first.clickthroughs : [];
|
|
9359
|
+
const sourceLinkCount = numberValue3(first?.source_link_count) ?? numberValue3(first?.home_game_link_count) ?? null;
|
|
9360
|
+
const sourceUniqueLinkCount = numberValue3(first?.source_unique_link_count) ?? numberValue3(first?.home_unique_game_link_count) ?? null;
|
|
9361
|
+
const duplicateSourceLinks = Array.isArray(first?.duplicate_source_link_paths) ? first.duplicate_source_link_paths.map((path6) => String(path6)) : [];
|
|
9362
|
+
const duplicateSourceLinkCount = numberValue3(first?.duplicate_source_link_count) ?? (sourceLinkCount !== null && sourceUniqueLinkCount !== null ? Math.max(0, sourceLinkCount - sourceUniqueLinkCount) : null);
|
|
9295
9363
|
return {
|
|
9296
9364
|
type: check.type,
|
|
9297
9365
|
label: checkLabel(check),
|
|
9298
9366
|
status: failures.length ? "failed" : "passed",
|
|
9299
9367
|
evidence: {
|
|
9300
9368
|
expected_count: check.expected_routes?.length || 0,
|
|
9301
|
-
|
|
9302
|
-
|
|
9369
|
+
source_link_count: sourceLinkCount,
|
|
9370
|
+
source_unique_link_count: sourceUniqueLinkCount,
|
|
9371
|
+
duplicate_source_link_count: duplicateSourceLinkCount,
|
|
9372
|
+
duplicate_source_links: duplicateSourceLinks,
|
|
9373
|
+
duplicates_allowed: check.require_unique_routes === false,
|
|
9374
|
+
homepage_link_count: numberValue3(first?.home_game_link_count) ?? sourceLinkCount,
|
|
9375
|
+
homepage_unique_link_count: numberValue3(first?.home_unique_game_link_count) ?? sourceUniqueLinkCount,
|
|
9303
9376
|
direct_route_count: directRoutes.length,
|
|
9304
9377
|
clickthrough_count: clickthroughs.length,
|
|
9305
9378
|
failures
|
|
@@ -9598,6 +9671,28 @@ function textMatches(sample, check) {
|
|
|
9598
9671
|
}
|
|
9599
9672
|
return String(sample || "").includes(check.text || "");
|
|
9600
9673
|
}
|
|
9674
|
+
function textSequenceForCheck(viewport, check) {
|
|
9675
|
+
const key = check.selector || "";
|
|
9676
|
+
const sequence = viewport.text_sequences && viewport.text_sequences[key];
|
|
9677
|
+
if (sequence && typeof sequence === "object") {
|
|
9678
|
+
const visibleTexts = Array.isArray(sequence.visible_texts) ? sequence.visible_texts : [];
|
|
9679
|
+
const texts = Array.isArray(sequence.texts) ? sequence.texts : [];
|
|
9680
|
+
const candidates = visibleTexts.length ? visibleTexts : texts;
|
|
9681
|
+
return candidates.map((text) => String(text || "").replace(/\s+/g, " ").trim()).filter(Boolean);
|
|
9682
|
+
}
|
|
9683
|
+
return [];
|
|
9684
|
+
}
|
|
9685
|
+
function textOrderMatch(texts, expectedTexts) {
|
|
9686
|
+
const positions = [];
|
|
9687
|
+
let startAt = 0;
|
|
9688
|
+
for (const expected of expectedTexts || []) {
|
|
9689
|
+
const index = texts.findIndex((text, offset) => offset >= startAt && text.includes(expected));
|
|
9690
|
+
if (index < 0) return { matched: false, positions };
|
|
9691
|
+
positions.push(index);
|
|
9692
|
+
startAt = index + 1;
|
|
9693
|
+
}
|
|
9694
|
+
return { matched: true, positions };
|
|
9695
|
+
}
|
|
9601
9696
|
function numberValue(value) {
|
|
9602
9697
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
9603
9698
|
}
|
|
@@ -9802,6 +9897,29 @@ function assessProfile(profile, evidence) {
|
|
|
9802
9897
|
});
|
|
9803
9898
|
continue;
|
|
9804
9899
|
}
|
|
9900
|
+
if (check.type === "selector_text_order") {
|
|
9901
|
+
const selector = check.selector || "";
|
|
9902
|
+
const expectedTexts = check.expected_texts || [];
|
|
9903
|
+
const results = viewports.map((viewport) => {
|
|
9904
|
+
const texts = textSequenceForCheck(viewport, check);
|
|
9905
|
+
const match = textOrderMatch(texts, expectedTexts);
|
|
9906
|
+
return {
|
|
9907
|
+
viewport: viewport.name,
|
|
9908
|
+
matched: match.matched,
|
|
9909
|
+
matched_positions: match.positions,
|
|
9910
|
+
visible_texts: texts.slice(0, 20),
|
|
9911
|
+
};
|
|
9912
|
+
});
|
|
9913
|
+
const failed = results.filter((result) => !result.matched).length;
|
|
9914
|
+
checks.push({
|
|
9915
|
+
type: check.type,
|
|
9916
|
+
label: check.label || check.type,
|
|
9917
|
+
status: failed ? "failed" : "passed",
|
|
9918
|
+
evidence: { selector, expected_texts: expectedTexts, viewports: results },
|
|
9919
|
+
message: failed ? "Selector " + selector + " text order failed in " + failed + " viewport(s)." : undefined,
|
|
9920
|
+
});
|
|
9921
|
+
continue;
|
|
9922
|
+
}
|
|
9805
9923
|
if (check.type === "text_visible" || check.type === "text_absent") {
|
|
9806
9924
|
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
9807
9925
|
const expectedVisible = check.type === "text_visible";
|
|
@@ -9839,14 +9957,23 @@ function assessProfile(profile, evidence) {
|
|
|
9839
9957
|
const first = inventories[0].inventory || {};
|
|
9840
9958
|
const directRoutes = Array.isArray(first.direct_routes) ? first.direct_routes : [];
|
|
9841
9959
|
const clickthroughs = Array.isArray(first.clickthroughs) ? first.clickthroughs : [];
|
|
9960
|
+
const sourceLinkCount = typeof first.source_link_count === "number" ? first.source_link_count : typeof first.home_game_link_count === "number" ? first.home_game_link_count : null;
|
|
9961
|
+
const sourceUniqueLinkCount = typeof first.source_unique_link_count === "number" ? first.source_unique_link_count : typeof first.home_unique_game_link_count === "number" ? first.home_unique_game_link_count : null;
|
|
9962
|
+
const duplicateSourceLinks = Array.isArray(first.duplicate_source_link_paths) ? first.duplicate_source_link_paths.map((path) => String(path)) : [];
|
|
9963
|
+
const duplicateSourceLinkCount = typeof first.duplicate_source_link_count === "number" ? first.duplicate_source_link_count : sourceLinkCount !== null && sourceUniqueLinkCount !== null ? Math.max(0, sourceLinkCount - sourceUniqueLinkCount) : null;
|
|
9842
9964
|
checks.push({
|
|
9843
9965
|
type: check.type,
|
|
9844
9966
|
label: check.label || check.type,
|
|
9845
9967
|
status: failures.length ? "failed" : "passed",
|
|
9846
9968
|
evidence: {
|
|
9847
9969
|
expected_count: (check.expected_routes || []).length,
|
|
9848
|
-
|
|
9849
|
-
|
|
9970
|
+
source_link_count: sourceLinkCount,
|
|
9971
|
+
source_unique_link_count: sourceUniqueLinkCount,
|
|
9972
|
+
duplicate_source_link_count: duplicateSourceLinkCount,
|
|
9973
|
+
duplicate_source_links: duplicateSourceLinks,
|
|
9974
|
+
duplicates_allowed: check.require_unique_routes === false,
|
|
9975
|
+
homepage_link_count: typeof first.home_game_link_count === "number" ? first.home_game_link_count : sourceLinkCount,
|
|
9976
|
+
homepage_unique_link_count: typeof first.home_unique_game_link_count === "number" ? first.home_unique_game_link_count : sourceUniqueLinkCount,
|
|
9850
9977
|
direct_route_count: directRoutes.length,
|
|
9851
9978
|
clickthrough_count: clickthroughs.length,
|
|
9852
9979
|
failures,
|
|
@@ -10166,6 +10293,27 @@ async function selectorStats(selector) {
|
|
|
10166
10293
|
return { count: elements.length, visible_count: elements.filter(isVisible).length };
|
|
10167
10294
|
}).catch((error) => ({ count: 0, visible_count: 0, error: String(error && error.message ? error.message : error).slice(0, 500) }));
|
|
10168
10295
|
}
|
|
10296
|
+
async function selectorTextSequence(selector) {
|
|
10297
|
+
return page.locator(selector).evaluateAll((elements) => {
|
|
10298
|
+
const compact = (value) => String(value || "").replace(/\s+/g, " ").trim().slice(0, 240);
|
|
10299
|
+
const isVisible = (element) => {
|
|
10300
|
+
const style = window.getComputedStyle(element);
|
|
10301
|
+
const rect = element.getBoundingClientRect();
|
|
10302
|
+
return style && style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
|
|
10303
|
+
};
|
|
10304
|
+
const rows = elements.map((element, index) => ({
|
|
10305
|
+
index,
|
|
10306
|
+
text: compact(element.innerText || element.textContent || ""),
|
|
10307
|
+
visible: isVisible(element),
|
|
10308
|
+
}));
|
|
10309
|
+
return {
|
|
10310
|
+
count: rows.length,
|
|
10311
|
+
visible_count: rows.filter((row) => row.visible).length,
|
|
10312
|
+
texts: rows.map((row) => row.text).filter(Boolean).slice(0, 40),
|
|
10313
|
+
visible_texts: rows.filter((row) => row.visible).map((row) => row.text).filter(Boolean).slice(0, 40),
|
|
10314
|
+
};
|
|
10315
|
+
}).catch((error) => ({ count: 0, visible_count: 0, texts: [], visible_texts: [], error: String(error && error.message ? error.message : error).slice(0, 500) }));
|
|
10316
|
+
}
|
|
10169
10317
|
function inventoryAppPathFromUrl(urlLike) {
|
|
10170
10318
|
const url = new URL(String(urlLike), targetUrl);
|
|
10171
10319
|
const mountPrefix = previewMountPrefix(new URL(targetUrl).pathname);
|
|
@@ -10365,8 +10513,9 @@ async function collectRouteInventory(check, viewport) {
|
|
|
10365
10513
|
const homeLinkPaths = homeLinks.map((link) => link.app_path);
|
|
10366
10514
|
const uniqueHomeLinkPaths = Array.from(new Set(homeLinkPaths));
|
|
10367
10515
|
const duplicateHomeLinkPaths = homeLinkPaths.filter((path, index) => homeLinkPaths.indexOf(path) !== index);
|
|
10516
|
+
const duplicateHomeLinkPathSet = Array.from(new Set(duplicateHomeLinkPaths));
|
|
10368
10517
|
if (check.require_unique_routes !== false && duplicateHomeLinkPaths.length) {
|
|
10369
|
-
failures.push({ code: "duplicate_source_links", paths:
|
|
10518
|
+
failures.push({ code: "duplicate_source_links", paths: duplicateHomeLinkPathSet });
|
|
10370
10519
|
}
|
|
10371
10520
|
for (const route of expectedRoutes) {
|
|
10372
10521
|
if (!homeLinkPaths.includes(normalizeRoutePath(route.path))) {
|
|
@@ -10442,6 +10591,11 @@ async function collectRouteInventory(check, viewport) {
|
|
|
10442
10591
|
expected_routes: expectedRoutes,
|
|
10443
10592
|
link_selector: check.link_selector || "a[href]",
|
|
10444
10593
|
source_selector: check.source_selector || null,
|
|
10594
|
+
source_link_count: homeLinkPaths.length,
|
|
10595
|
+
source_unique_link_count: uniqueHomeLinkPaths.length,
|
|
10596
|
+
duplicate_source_link_count: duplicateHomeLinkPaths.length,
|
|
10597
|
+
duplicate_source_link_paths: duplicateHomeLinkPathSet,
|
|
10598
|
+
duplicates_allowed: check.require_unique_routes === false,
|
|
10445
10599
|
home_game_link_count: homeLinkPaths.length,
|
|
10446
10600
|
home_unique_game_link_count: uniqueHomeLinkPaths.length,
|
|
10447
10601
|
home_links: homeLinks,
|
|
@@ -10557,11 +10711,16 @@ async function captureViewport(viewport) {
|
|
|
10557
10711
|
evaluation_error: String(error && error.message ? error.message : error).slice(0, 1000),
|
|
10558
10712
|
}));
|
|
10559
10713
|
const selectors = {};
|
|
10714
|
+
const text_sequences = {};
|
|
10560
10715
|
const text_matches = {};
|
|
10561
10716
|
for (const check of profile.checks || []) {
|
|
10562
10717
|
if ((check.type === "selector_visible" || check.type === "selector_count_at_least") && check.selector) {
|
|
10563
10718
|
selectors[check.selector] = await selectorStats(check.selector);
|
|
10564
10719
|
}
|
|
10720
|
+
if (check.type === "selector_text_order" && check.selector) {
|
|
10721
|
+
selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
|
|
10722
|
+
text_sequences[check.selector] = await selectorTextSequence(check.selector);
|
|
10723
|
+
}
|
|
10565
10724
|
if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
|
|
10566
10725
|
text_matches[textKey(check)] = textMatches(dom.body_text || dom.body_text_sample || "", check);
|
|
10567
10726
|
}
|
|
@@ -10585,6 +10744,11 @@ async function captureViewport(viewport) {
|
|
|
10585
10744
|
expected_routes: routeInventoryCheck.expected_routes || [],
|
|
10586
10745
|
link_selector: routeInventoryCheck.link_selector || "a[href]",
|
|
10587
10746
|
source_selector: routeInventoryCheck.source_selector || null,
|
|
10747
|
+
source_link_count: 0,
|
|
10748
|
+
source_unique_link_count: 0,
|
|
10749
|
+
duplicate_source_link_count: 0,
|
|
10750
|
+
duplicate_source_link_paths: [],
|
|
10751
|
+
duplicates_allowed: routeInventoryCheck.require_unique_routes === false,
|
|
10588
10752
|
home_game_link_count: 0,
|
|
10589
10753
|
home_unique_game_link_count: 0,
|
|
10590
10754
|
home_links: [],
|
|
@@ -10620,6 +10784,7 @@ async function captureViewport(viewport) {
|
|
|
10620
10784
|
bounds_overflow_px: dom.bounds_overflow_px,
|
|
10621
10785
|
overflow_offenders: dom.overflow_offenders || [],
|
|
10622
10786
|
selectors,
|
|
10787
|
+
text_sequences,
|
|
10623
10788
|
text_matches,
|
|
10624
10789
|
route_inventory: routeInventory,
|
|
10625
10790
|
setup_action_results: setupActionResults,
|
|
@@ -10659,6 +10824,9 @@ function buildProfileEvidence(currentViewports) {
|
|
|
10659
10824
|
.map((viewport) => ({
|
|
10660
10825
|
viewport: viewport.name,
|
|
10661
10826
|
expected_count: (viewport.route_inventory.expected_routes || []).length,
|
|
10827
|
+
source_link_count: viewport.route_inventory.source_link_count == null ? viewport.route_inventory.home_game_link_count : viewport.route_inventory.source_link_count,
|
|
10828
|
+
source_unique_link_count: viewport.route_inventory.source_unique_link_count == null ? viewport.route_inventory.home_unique_game_link_count : viewport.route_inventory.source_unique_link_count,
|
|
10829
|
+
duplicate_source_link_count: viewport.route_inventory.duplicate_source_link_count,
|
|
10662
10830
|
home_unique_game_link_count: viewport.route_inventory.home_unique_game_link_count,
|
|
10663
10831
|
direct_route_count: (viewport.route_inventory.direct_routes || []).length,
|
|
10664
10832
|
clickthrough_count: (viewport.route_inventory.clickthroughs || []).length,
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
resolveRiddleProofProfileTimeoutSec,
|
|
59
59
|
slugifyRiddleProofProfileName,
|
|
60
60
|
summarizeRiddleProofProfileResult
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-VCINQE5O.js";
|
|
62
62
|
import {
|
|
63
63
|
DEFAULT_RIDDLE_API_BASE_URL,
|
|
64
64
|
DEFAULT_RIDDLE_API_KEY_FILE,
|
package/dist/profile.cjs
CHANGED
|
@@ -57,6 +57,7 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
57
57
|
"route_loaded",
|
|
58
58
|
"selector_visible",
|
|
59
59
|
"selector_count_at_least",
|
|
60
|
+
"selector_text_order",
|
|
60
61
|
"text_visible",
|
|
61
62
|
"text_absent",
|
|
62
63
|
"route_inventory",
|
|
@@ -336,6 +337,15 @@ function normalizeRouteInventoryRoutes(value, index) {
|
|
|
336
337
|
}
|
|
337
338
|
return routes;
|
|
338
339
|
}
|
|
340
|
+
function normalizeExpectedTexts(value, index) {
|
|
341
|
+
if (value === void 0) return void 0;
|
|
342
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
343
|
+
throw new Error(`checks[${index}] selector_text_order expected_texts must be a non-empty array.`);
|
|
344
|
+
}
|
|
345
|
+
const texts = value.map((item) => String(item).replace(/\s+/g, " ").trim()).filter(Boolean);
|
|
346
|
+
if (!texts.length) throw new Error(`checks[${index}] selector_text_order expected_texts must contain non-empty strings.`);
|
|
347
|
+
return texts;
|
|
348
|
+
}
|
|
339
349
|
function normalizeCheck(input, index) {
|
|
340
350
|
if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
341
351
|
const type = stringValue(input.type);
|
|
@@ -352,6 +362,11 @@ function normalizeCheck(input, index) {
|
|
|
352
362
|
if (type === "selector_count_at_least" && numberValue(input.min_count) === void 0) {
|
|
353
363
|
throw new Error(`checks[${index}] selector_count_at_least requires min_count.`);
|
|
354
364
|
}
|
|
365
|
+
const expectedTexts = normalizeExpectedTexts(input.expected_texts ?? input.expectedTexts, index);
|
|
366
|
+
if (type === "selector_text_order") {
|
|
367
|
+
if (!stringValue(input.selector)) throw new Error(`checks[${index}] selector_text_order requires selector.`);
|
|
368
|
+
if (!expectedTexts?.length) throw new Error(`checks[${index}] selector_text_order requires expected_texts.`);
|
|
369
|
+
}
|
|
355
370
|
const expectedRoutes = normalizeRouteInventoryRoutes(input.expected_routes ?? input.expectedRoutes, index);
|
|
356
371
|
if (type === "route_inventory" && !expectedRoutes?.length) {
|
|
357
372
|
throw new Error(`checks[${index}] route_inventory requires expected_routes.`);
|
|
@@ -362,6 +377,7 @@ function normalizeCheck(input, index) {
|
|
|
362
377
|
expected_path: stringValue(input.expected_path),
|
|
363
378
|
expected_routes: expectedRoutes,
|
|
364
379
|
selector: stringValue(input.selector),
|
|
380
|
+
expected_texts: expectedTexts,
|
|
365
381
|
link_selector: stringValue(input.link_selector) || stringValue(input.linkSelector),
|
|
366
382
|
source_selector: stringValue(input.source_selector) || stringValue(input.sourceSelector),
|
|
367
383
|
route_path_prefix: stringValue(input.route_path_prefix) || stringValue(input.routePathPrefix),
|
|
@@ -467,6 +483,28 @@ function selectorKey(check) {
|
|
|
467
483
|
function textKey(check) {
|
|
468
484
|
return check.pattern ? `pattern:${check.pattern}/${check.flags || ""}` : `text:${check.text || ""}`;
|
|
469
485
|
}
|
|
486
|
+
function textSequenceForCheck(viewport, check) {
|
|
487
|
+
const key = selectorKey(check);
|
|
488
|
+
const sequence = viewport.text_sequences?.[key];
|
|
489
|
+
if (isRecord(sequence)) {
|
|
490
|
+
const visibleTexts = Array.isArray(sequence.visible_texts) ? sequence.visible_texts : [];
|
|
491
|
+
const texts = Array.isArray(sequence.texts) ? sequence.texts : [];
|
|
492
|
+
const candidates = visibleTexts.length ? visibleTexts : texts;
|
|
493
|
+
return candidates.map((text) => String(text).replace(/\s+/g, " ").trim()).filter(Boolean);
|
|
494
|
+
}
|
|
495
|
+
return [];
|
|
496
|
+
}
|
|
497
|
+
function textOrderMatch(texts, expectedTexts) {
|
|
498
|
+
const positions = [];
|
|
499
|
+
let startAt = 0;
|
|
500
|
+
for (const expected of expectedTexts) {
|
|
501
|
+
const index = texts.findIndex((text, offset) => offset >= startAt && text.includes(expected));
|
|
502
|
+
if (index < 0) return { matched: false, positions };
|
|
503
|
+
positions.push(index);
|
|
504
|
+
startAt = index + 1;
|
|
505
|
+
}
|
|
506
|
+
return { matched: true, positions };
|
|
507
|
+
}
|
|
470
508
|
function matchText(sample, check) {
|
|
471
509
|
if (check.pattern) {
|
|
472
510
|
try {
|
|
@@ -586,6 +624,32 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
586
624
|
message: failed.length ? `Selector ${key} count was below ${minCount} in ${failed.length} viewport(s).` : void 0
|
|
587
625
|
};
|
|
588
626
|
}
|
|
627
|
+
if (check.type === "selector_text_order") {
|
|
628
|
+
const key = selectorKey(check);
|
|
629
|
+
const expectedTexts = check.expected_texts || [];
|
|
630
|
+
const results = viewports.map((viewport) => {
|
|
631
|
+
const texts = textSequenceForCheck(viewport, check);
|
|
632
|
+
const match = textOrderMatch(texts, expectedTexts);
|
|
633
|
+
return {
|
|
634
|
+
viewport: viewport.name,
|
|
635
|
+
matched: match.matched,
|
|
636
|
+
matched_positions: match.positions,
|
|
637
|
+
visible_texts: texts.slice(0, 20)
|
|
638
|
+
};
|
|
639
|
+
});
|
|
640
|
+
const failed = results.filter((result) => !result.matched).length;
|
|
641
|
+
return {
|
|
642
|
+
type: check.type,
|
|
643
|
+
label: checkLabel(check),
|
|
644
|
+
status: failed ? "failed" : "passed",
|
|
645
|
+
evidence: {
|
|
646
|
+
selector: key,
|
|
647
|
+
expected_texts: expectedTexts,
|
|
648
|
+
viewports: results.map((result) => toJsonValue(result))
|
|
649
|
+
},
|
|
650
|
+
message: failed ? `Selector ${key} text order failed in ${failed} viewport(s).` : void 0
|
|
651
|
+
};
|
|
652
|
+
}
|
|
589
653
|
if (check.type === "text_visible" || check.type === "text_absent") {
|
|
590
654
|
const key = textKey(check);
|
|
591
655
|
const expectedVisible = check.type === "text_visible";
|
|
@@ -621,14 +685,23 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
621
685
|
const first = inventories[0]?.inventory;
|
|
622
686
|
const directRoutes = Array.isArray(first?.direct_routes) ? first.direct_routes : [];
|
|
623
687
|
const clickthroughs = Array.isArray(first?.clickthroughs) ? first.clickthroughs : [];
|
|
688
|
+
const sourceLinkCount = numberValue(first?.source_link_count) ?? numberValue(first?.home_game_link_count) ?? null;
|
|
689
|
+
const sourceUniqueLinkCount = numberValue(first?.source_unique_link_count) ?? numberValue(first?.home_unique_game_link_count) ?? null;
|
|
690
|
+
const duplicateSourceLinks = Array.isArray(first?.duplicate_source_link_paths) ? first.duplicate_source_link_paths.map((path) => String(path)) : [];
|
|
691
|
+
const duplicateSourceLinkCount = numberValue(first?.duplicate_source_link_count) ?? (sourceLinkCount !== null && sourceUniqueLinkCount !== null ? Math.max(0, sourceLinkCount - sourceUniqueLinkCount) : null);
|
|
624
692
|
return {
|
|
625
693
|
type: check.type,
|
|
626
694
|
label: checkLabel(check),
|
|
627
695
|
status: failures.length ? "failed" : "passed",
|
|
628
696
|
evidence: {
|
|
629
697
|
expected_count: check.expected_routes?.length || 0,
|
|
630
|
-
|
|
631
|
-
|
|
698
|
+
source_link_count: sourceLinkCount,
|
|
699
|
+
source_unique_link_count: sourceUniqueLinkCount,
|
|
700
|
+
duplicate_source_link_count: duplicateSourceLinkCount,
|
|
701
|
+
duplicate_source_links: duplicateSourceLinks,
|
|
702
|
+
duplicates_allowed: check.require_unique_routes === false,
|
|
703
|
+
homepage_link_count: numberValue(first?.home_game_link_count) ?? sourceLinkCount,
|
|
704
|
+
homepage_unique_link_count: numberValue(first?.home_unique_game_link_count) ?? sourceUniqueLinkCount,
|
|
632
705
|
direct_route_count: directRoutes.length,
|
|
633
706
|
clickthrough_count: clickthroughs.length,
|
|
634
707
|
failures
|
|
@@ -927,6 +1000,28 @@ function textMatches(sample, check) {
|
|
|
927
1000
|
}
|
|
928
1001
|
return String(sample || "").includes(check.text || "");
|
|
929
1002
|
}
|
|
1003
|
+
function textSequenceForCheck(viewport, check) {
|
|
1004
|
+
const key = check.selector || "";
|
|
1005
|
+
const sequence = viewport.text_sequences && viewport.text_sequences[key];
|
|
1006
|
+
if (sequence && typeof sequence === "object") {
|
|
1007
|
+
const visibleTexts = Array.isArray(sequence.visible_texts) ? sequence.visible_texts : [];
|
|
1008
|
+
const texts = Array.isArray(sequence.texts) ? sequence.texts : [];
|
|
1009
|
+
const candidates = visibleTexts.length ? visibleTexts : texts;
|
|
1010
|
+
return candidates.map((text) => String(text || "").replace(/\s+/g, " ").trim()).filter(Boolean);
|
|
1011
|
+
}
|
|
1012
|
+
return [];
|
|
1013
|
+
}
|
|
1014
|
+
function textOrderMatch(texts, expectedTexts) {
|
|
1015
|
+
const positions = [];
|
|
1016
|
+
let startAt = 0;
|
|
1017
|
+
for (const expected of expectedTexts || []) {
|
|
1018
|
+
const index = texts.findIndex((text, offset) => offset >= startAt && text.includes(expected));
|
|
1019
|
+
if (index < 0) return { matched: false, positions };
|
|
1020
|
+
positions.push(index);
|
|
1021
|
+
startAt = index + 1;
|
|
1022
|
+
}
|
|
1023
|
+
return { matched: true, positions };
|
|
1024
|
+
}
|
|
930
1025
|
function numberValue(value) {
|
|
931
1026
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
932
1027
|
}
|
|
@@ -1131,6 +1226,29 @@ function assessProfile(profile, evidence) {
|
|
|
1131
1226
|
});
|
|
1132
1227
|
continue;
|
|
1133
1228
|
}
|
|
1229
|
+
if (check.type === "selector_text_order") {
|
|
1230
|
+
const selector = check.selector || "";
|
|
1231
|
+
const expectedTexts = check.expected_texts || [];
|
|
1232
|
+
const results = viewports.map((viewport) => {
|
|
1233
|
+
const texts = textSequenceForCheck(viewport, check);
|
|
1234
|
+
const match = textOrderMatch(texts, expectedTexts);
|
|
1235
|
+
return {
|
|
1236
|
+
viewport: viewport.name,
|
|
1237
|
+
matched: match.matched,
|
|
1238
|
+
matched_positions: match.positions,
|
|
1239
|
+
visible_texts: texts.slice(0, 20),
|
|
1240
|
+
};
|
|
1241
|
+
});
|
|
1242
|
+
const failed = results.filter((result) => !result.matched).length;
|
|
1243
|
+
checks.push({
|
|
1244
|
+
type: check.type,
|
|
1245
|
+
label: check.label || check.type,
|
|
1246
|
+
status: failed ? "failed" : "passed",
|
|
1247
|
+
evidence: { selector, expected_texts: expectedTexts, viewports: results },
|
|
1248
|
+
message: failed ? "Selector " + selector + " text order failed in " + failed + " viewport(s)." : undefined,
|
|
1249
|
+
});
|
|
1250
|
+
continue;
|
|
1251
|
+
}
|
|
1134
1252
|
if (check.type === "text_visible" || check.type === "text_absent") {
|
|
1135
1253
|
const key = check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
1136
1254
|
const expectedVisible = check.type === "text_visible";
|
|
@@ -1168,14 +1286,23 @@ function assessProfile(profile, evidence) {
|
|
|
1168
1286
|
const first = inventories[0].inventory || {};
|
|
1169
1287
|
const directRoutes = Array.isArray(first.direct_routes) ? first.direct_routes : [];
|
|
1170
1288
|
const clickthroughs = Array.isArray(first.clickthroughs) ? first.clickthroughs : [];
|
|
1289
|
+
const sourceLinkCount = typeof first.source_link_count === "number" ? first.source_link_count : typeof first.home_game_link_count === "number" ? first.home_game_link_count : null;
|
|
1290
|
+
const sourceUniqueLinkCount = typeof first.source_unique_link_count === "number" ? first.source_unique_link_count : typeof first.home_unique_game_link_count === "number" ? first.home_unique_game_link_count : null;
|
|
1291
|
+
const duplicateSourceLinks = Array.isArray(first.duplicate_source_link_paths) ? first.duplicate_source_link_paths.map((path) => String(path)) : [];
|
|
1292
|
+
const duplicateSourceLinkCount = typeof first.duplicate_source_link_count === "number" ? first.duplicate_source_link_count : sourceLinkCount !== null && sourceUniqueLinkCount !== null ? Math.max(0, sourceLinkCount - sourceUniqueLinkCount) : null;
|
|
1171
1293
|
checks.push({
|
|
1172
1294
|
type: check.type,
|
|
1173
1295
|
label: check.label || check.type,
|
|
1174
1296
|
status: failures.length ? "failed" : "passed",
|
|
1175
1297
|
evidence: {
|
|
1176
1298
|
expected_count: (check.expected_routes || []).length,
|
|
1177
|
-
|
|
1178
|
-
|
|
1299
|
+
source_link_count: sourceLinkCount,
|
|
1300
|
+
source_unique_link_count: sourceUniqueLinkCount,
|
|
1301
|
+
duplicate_source_link_count: duplicateSourceLinkCount,
|
|
1302
|
+
duplicate_source_links: duplicateSourceLinks,
|
|
1303
|
+
duplicates_allowed: check.require_unique_routes === false,
|
|
1304
|
+
homepage_link_count: typeof first.home_game_link_count === "number" ? first.home_game_link_count : sourceLinkCount,
|
|
1305
|
+
homepage_unique_link_count: typeof first.home_unique_game_link_count === "number" ? first.home_unique_game_link_count : sourceUniqueLinkCount,
|
|
1179
1306
|
direct_route_count: directRoutes.length,
|
|
1180
1307
|
clickthrough_count: clickthroughs.length,
|
|
1181
1308
|
failures,
|
|
@@ -1495,6 +1622,27 @@ async function selectorStats(selector) {
|
|
|
1495
1622
|
return { count: elements.length, visible_count: elements.filter(isVisible).length };
|
|
1496
1623
|
}).catch((error) => ({ count: 0, visible_count: 0, error: String(error && error.message ? error.message : error).slice(0, 500) }));
|
|
1497
1624
|
}
|
|
1625
|
+
async function selectorTextSequence(selector) {
|
|
1626
|
+
return page.locator(selector).evaluateAll((elements) => {
|
|
1627
|
+
const compact = (value) => String(value || "").replace(/\s+/g, " ").trim().slice(0, 240);
|
|
1628
|
+
const isVisible = (element) => {
|
|
1629
|
+
const style = window.getComputedStyle(element);
|
|
1630
|
+
const rect = element.getBoundingClientRect();
|
|
1631
|
+
return style && style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
|
|
1632
|
+
};
|
|
1633
|
+
const rows = elements.map((element, index) => ({
|
|
1634
|
+
index,
|
|
1635
|
+
text: compact(element.innerText || element.textContent || ""),
|
|
1636
|
+
visible: isVisible(element),
|
|
1637
|
+
}));
|
|
1638
|
+
return {
|
|
1639
|
+
count: rows.length,
|
|
1640
|
+
visible_count: rows.filter((row) => row.visible).length,
|
|
1641
|
+
texts: rows.map((row) => row.text).filter(Boolean).slice(0, 40),
|
|
1642
|
+
visible_texts: rows.filter((row) => row.visible).map((row) => row.text).filter(Boolean).slice(0, 40),
|
|
1643
|
+
};
|
|
1644
|
+
}).catch((error) => ({ count: 0, visible_count: 0, texts: [], visible_texts: [], error: String(error && error.message ? error.message : error).slice(0, 500) }));
|
|
1645
|
+
}
|
|
1498
1646
|
function inventoryAppPathFromUrl(urlLike) {
|
|
1499
1647
|
const url = new URL(String(urlLike), targetUrl);
|
|
1500
1648
|
const mountPrefix = previewMountPrefix(new URL(targetUrl).pathname);
|
|
@@ -1694,8 +1842,9 @@ async function collectRouteInventory(check, viewport) {
|
|
|
1694
1842
|
const homeLinkPaths = homeLinks.map((link) => link.app_path);
|
|
1695
1843
|
const uniqueHomeLinkPaths = Array.from(new Set(homeLinkPaths));
|
|
1696
1844
|
const duplicateHomeLinkPaths = homeLinkPaths.filter((path, index) => homeLinkPaths.indexOf(path) !== index);
|
|
1845
|
+
const duplicateHomeLinkPathSet = Array.from(new Set(duplicateHomeLinkPaths));
|
|
1697
1846
|
if (check.require_unique_routes !== false && duplicateHomeLinkPaths.length) {
|
|
1698
|
-
failures.push({ code: "duplicate_source_links", paths:
|
|
1847
|
+
failures.push({ code: "duplicate_source_links", paths: duplicateHomeLinkPathSet });
|
|
1699
1848
|
}
|
|
1700
1849
|
for (const route of expectedRoutes) {
|
|
1701
1850
|
if (!homeLinkPaths.includes(normalizeRoutePath(route.path))) {
|
|
@@ -1771,6 +1920,11 @@ async function collectRouteInventory(check, viewport) {
|
|
|
1771
1920
|
expected_routes: expectedRoutes,
|
|
1772
1921
|
link_selector: check.link_selector || "a[href]",
|
|
1773
1922
|
source_selector: check.source_selector || null,
|
|
1923
|
+
source_link_count: homeLinkPaths.length,
|
|
1924
|
+
source_unique_link_count: uniqueHomeLinkPaths.length,
|
|
1925
|
+
duplicate_source_link_count: duplicateHomeLinkPaths.length,
|
|
1926
|
+
duplicate_source_link_paths: duplicateHomeLinkPathSet,
|
|
1927
|
+
duplicates_allowed: check.require_unique_routes === false,
|
|
1774
1928
|
home_game_link_count: homeLinkPaths.length,
|
|
1775
1929
|
home_unique_game_link_count: uniqueHomeLinkPaths.length,
|
|
1776
1930
|
home_links: homeLinks,
|
|
@@ -1886,11 +2040,16 @@ async function captureViewport(viewport) {
|
|
|
1886
2040
|
evaluation_error: String(error && error.message ? error.message : error).slice(0, 1000),
|
|
1887
2041
|
}));
|
|
1888
2042
|
const selectors = {};
|
|
2043
|
+
const text_sequences = {};
|
|
1889
2044
|
const text_matches = {};
|
|
1890
2045
|
for (const check of profile.checks || []) {
|
|
1891
2046
|
if ((check.type === "selector_visible" || check.type === "selector_count_at_least") && check.selector) {
|
|
1892
2047
|
selectors[check.selector] = await selectorStats(check.selector);
|
|
1893
2048
|
}
|
|
2049
|
+
if (check.type === "selector_text_order" && check.selector) {
|
|
2050
|
+
selectors[check.selector] = selectors[check.selector] || await selectorStats(check.selector);
|
|
2051
|
+
text_sequences[check.selector] = await selectorTextSequence(check.selector);
|
|
2052
|
+
}
|
|
1894
2053
|
if ((check.type === "text_visible" || check.type === "text_absent") && (check.text || check.pattern)) {
|
|
1895
2054
|
text_matches[textKey(check)] = textMatches(dom.body_text || dom.body_text_sample || "", check);
|
|
1896
2055
|
}
|
|
@@ -1914,6 +2073,11 @@ async function captureViewport(viewport) {
|
|
|
1914
2073
|
expected_routes: routeInventoryCheck.expected_routes || [],
|
|
1915
2074
|
link_selector: routeInventoryCheck.link_selector || "a[href]",
|
|
1916
2075
|
source_selector: routeInventoryCheck.source_selector || null,
|
|
2076
|
+
source_link_count: 0,
|
|
2077
|
+
source_unique_link_count: 0,
|
|
2078
|
+
duplicate_source_link_count: 0,
|
|
2079
|
+
duplicate_source_link_paths: [],
|
|
2080
|
+
duplicates_allowed: routeInventoryCheck.require_unique_routes === false,
|
|
1917
2081
|
home_game_link_count: 0,
|
|
1918
2082
|
home_unique_game_link_count: 0,
|
|
1919
2083
|
home_links: [],
|
|
@@ -1949,6 +2113,7 @@ async function captureViewport(viewport) {
|
|
|
1949
2113
|
bounds_overflow_px: dom.bounds_overflow_px,
|
|
1950
2114
|
overflow_offenders: dom.overflow_offenders || [],
|
|
1951
2115
|
selectors,
|
|
2116
|
+
text_sequences,
|
|
1952
2117
|
text_matches,
|
|
1953
2118
|
route_inventory: routeInventory,
|
|
1954
2119
|
setup_action_results: setupActionResults,
|
|
@@ -1988,6 +2153,9 @@ function buildProfileEvidence(currentViewports) {
|
|
|
1988
2153
|
.map((viewport) => ({
|
|
1989
2154
|
viewport: viewport.name,
|
|
1990
2155
|
expected_count: (viewport.route_inventory.expected_routes || []).length,
|
|
2156
|
+
source_link_count: viewport.route_inventory.source_link_count == null ? viewport.route_inventory.home_game_link_count : viewport.route_inventory.source_link_count,
|
|
2157
|
+
source_unique_link_count: viewport.route_inventory.source_unique_link_count == null ? viewport.route_inventory.home_unique_game_link_count : viewport.route_inventory.source_unique_link_count,
|
|
2158
|
+
duplicate_source_link_count: viewport.route_inventory.duplicate_source_link_count,
|
|
1991
2159
|
home_unique_game_link_count: viewport.route_inventory.home_unique_game_link_count,
|
|
1992
2160
|
direct_route_count: (viewport.route_inventory.direct_routes || []).length,
|
|
1993
2161
|
clickthrough_count: (viewport.route_inventory.clickthroughs || []).length,
|
package/dist/profile.d.cts
CHANGED
|
@@ -4,7 +4,7 @@ declare const RIDDLE_PROOF_PROFILE_VERSION: "riddle-proof.profile.v1";
|
|
|
4
4
|
declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evidence.v1";
|
|
5
5
|
declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
|
|
6
6
|
declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
|
|
7
|
-
declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "selector_visible", "selector_count_at_least", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
|
|
7
|
+
declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "selector_visible", "selector_count_at_least", "selector_text_order", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
|
|
8
8
|
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "local_storage", "session_storage", "clear_storage", "wait", "wait_for_selector", "wait_for_text"];
|
|
9
9
|
type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
|
|
10
10
|
type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
|
|
@@ -66,6 +66,7 @@ interface RiddleProofProfileCheck {
|
|
|
66
66
|
expected_path?: string;
|
|
67
67
|
expected_routes?: RiddleProofProfileRouteInventoryRoute[];
|
|
68
68
|
selector?: string;
|
|
69
|
+
expected_texts?: string[];
|
|
69
70
|
link_selector?: string;
|
|
70
71
|
source_selector?: string;
|
|
71
72
|
route_path_prefix?: string;
|
|
@@ -137,6 +138,7 @@ interface RiddleProofProfileViewportEvidence {
|
|
|
137
138
|
count: number;
|
|
138
139
|
visible_count: number;
|
|
139
140
|
}>;
|
|
141
|
+
text_sequences?: Record<string, Record<string, JsonValue>>;
|
|
140
142
|
text_matches?: Record<string, boolean>;
|
|
141
143
|
route_inventory?: Record<string, JsonValue>;
|
|
142
144
|
setup_action_results?: Array<Record<string, JsonValue>>;
|