@riddledc/riddle-proof 0.7.8 → 0.7.10
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 +14 -1
- package/dist/{chunk-7NMAU4DP.js → chunk-A7RJZD4I.js} +263 -8
- package/dist/cli.cjs +262 -8
- package/dist/cli.js +1 -1
- package/dist/index.cjs +264 -8
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/profile.cjs +264 -8
- package/dist/profile.d.cts +17 -1
- package/dist/profile.d.ts +17 -1
- package/dist/profile.js +3 -1
- package/dist/proof-run-engine.d.cts +3 -3
- package/dist/proof-run-engine.d.ts +3 -3
- package/examples/profiles/page-content-basic.json +4 -1
- package/package.json +1 -1
package/dist/profile.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(profile_exports, {
|
|
|
23
23
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES: () => RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
24
24
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: () => RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|
|
25
25
|
RIDDLE_PROOF_PROFILE_RESULT_VERSION: () => RIDDLE_PROOF_PROFILE_RESULT_VERSION,
|
|
26
|
+
RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: () => RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES,
|
|
26
27
|
RIDDLE_PROOF_PROFILE_STATUSES: () => RIDDLE_PROOF_PROFILE_STATUSES,
|
|
27
28
|
RIDDLE_PROOF_PROFILE_VERSION: () => RIDDLE_PROOF_PROFILE_VERSION,
|
|
28
29
|
assessRiddleProofProfileEvidence: () => assessRiddleProofProfileEvidence,
|
|
@@ -60,6 +61,12 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
60
61
|
"no_mobile_horizontal_overflow",
|
|
61
62
|
"no_fatal_console_errors"
|
|
62
63
|
];
|
|
64
|
+
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
65
|
+
"click",
|
|
66
|
+
"wait",
|
|
67
|
+
"wait_for_selector",
|
|
68
|
+
"wait_for_text"
|
|
69
|
+
];
|
|
63
70
|
var DEFAULT_VIEWPORTS = [
|
|
64
71
|
{ name: "desktop", width: 1280, height: 800 }
|
|
65
72
|
];
|
|
@@ -112,6 +119,41 @@ function normalizeViewports(value) {
|
|
|
112
119
|
function isSupportedCheckType(value) {
|
|
113
120
|
return RIDDLE_PROOF_PROFILE_CHECK_TYPES.includes(value);
|
|
114
121
|
}
|
|
122
|
+
function normalizeSetupActionType(value, index) {
|
|
123
|
+
const normalized = String(value || "").trim().replace(/-/g, "_");
|
|
124
|
+
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
125
|
+
return normalized;
|
|
126
|
+
}
|
|
127
|
+
throw new Error(`target.setup_actions[${index}].type ${value || "(missing)"} is not supported. Supported actions: ${RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.join(", ")}`);
|
|
128
|
+
}
|
|
129
|
+
function normalizeSetupAction(input, index) {
|
|
130
|
+
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
131
|
+
const type = normalizeSetupActionType(stringValue(input.type), index);
|
|
132
|
+
const selector = stringValue(input.selector);
|
|
133
|
+
if ((type === "click" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
|
|
134
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
135
|
+
}
|
|
136
|
+
if (type === "wait_for_text" && !stringValue(input.text) && !stringValue(input.pattern)) {
|
|
137
|
+
throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
type,
|
|
141
|
+
selector,
|
|
142
|
+
text: stringValue(input.text),
|
|
143
|
+
pattern: stringValue(input.pattern),
|
|
144
|
+
flags: stringValue(input.flags),
|
|
145
|
+
index: numberValue(input.index),
|
|
146
|
+
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
147
|
+
timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
|
|
148
|
+
after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
|
|
149
|
+
continue_on_failure: input.continue_on_failure === true || input.continueOnFailure === true
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function normalizeSetupActions(value) {
|
|
153
|
+
if (value === void 0) return void 0;
|
|
154
|
+
if (!Array.isArray(value)) throw new Error("target.setup_actions must be an array.");
|
|
155
|
+
return value.map(normalizeSetupAction);
|
|
156
|
+
}
|
|
115
157
|
function normalizeCheck(input, index) {
|
|
116
158
|
if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
117
159
|
const type = stringValue(input.type);
|
|
@@ -179,7 +221,8 @@ function normalizeRiddleProofProfile(input, options = {}) {
|
|
|
179
221
|
viewports: options.viewports?.length ? options.viewports : normalizeViewports(targetInput.viewports),
|
|
180
222
|
auth: stringValue(targetInput.auth) || "none",
|
|
181
223
|
wait_for_selector: stringValue(targetInput.wait_for_selector) || stringValue(targetInput.waitForSelector),
|
|
182
|
-
wait_ms: numberValue(targetInput.wait_ms) ?? numberValue(targetInput.waitMs)
|
|
224
|
+
wait_ms: numberValue(targetInput.wait_ms) ?? numberValue(targetInput.waitMs),
|
|
225
|
+
setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions)
|
|
183
226
|
},
|
|
184
227
|
checks,
|
|
185
228
|
artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
|
|
@@ -197,7 +240,13 @@ function resolveRiddleProofProfileTargetUrl(profile) {
|
|
|
197
240
|
throw new Error("profile target URL could not be resolved.");
|
|
198
241
|
}
|
|
199
242
|
function routeForViewport(viewport) {
|
|
200
|
-
|
|
243
|
+
if (viewport?.route) {
|
|
244
|
+
return {
|
|
245
|
+
...viewport.route,
|
|
246
|
+
matched: viewport.route.matched || routePathMatches(viewport.route.observed, viewport.route.expected_path)
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
201
250
|
requested: "",
|
|
202
251
|
observed: "",
|
|
203
252
|
matched: false,
|
|
@@ -223,8 +272,17 @@ function matchText(sample, check) {
|
|
|
223
272
|
}
|
|
224
273
|
return sample.includes(check.text || "");
|
|
225
274
|
}
|
|
275
|
+
function normalizeRoutePath(path) {
|
|
276
|
+
const value = path || "/";
|
|
277
|
+
if (value === "/") return "/";
|
|
278
|
+
return value.replace(/\/+$/, "") || "/";
|
|
279
|
+
}
|
|
280
|
+
function routePathMatches(observed, expected) {
|
|
281
|
+
return normalizeRoutePath(observed) === normalizeRoutePath(expected);
|
|
282
|
+
}
|
|
226
283
|
function successfulRoute(route) {
|
|
227
|
-
|
|
284
|
+
const matched = route.matched || routePathMatches(route.observed, route.expected_path);
|
|
285
|
+
return matched && !route.error && (route.http_status === null || route.http_status === void 0 || route.http_status < 400);
|
|
228
286
|
}
|
|
229
287
|
function assessCheckFromEvidence(check, evidence) {
|
|
230
288
|
const viewports = evidence.viewports || [];
|
|
@@ -242,7 +300,7 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
242
300
|
const failed = viewports.filter((viewport) => !successfulRoute({
|
|
243
301
|
...viewport.route,
|
|
244
302
|
expected_path: expectedPath,
|
|
245
|
-
matched: viewport.route.observed
|
|
303
|
+
matched: routePathMatches(viewport.route.observed, expectedPath) || viewport.route.matched
|
|
246
304
|
}));
|
|
247
305
|
return {
|
|
248
306
|
type: check.type,
|
|
@@ -352,6 +410,48 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
352
410
|
message: "Unsupported check type."
|
|
353
411
|
};
|
|
354
412
|
}
|
|
413
|
+
function assessSetupActionsFromEvidence(profile, evidence) {
|
|
414
|
+
if (!profile.target.setup_actions?.length) return void 0;
|
|
415
|
+
const actionCount = profile.target.setup_actions.length;
|
|
416
|
+
const failed = [];
|
|
417
|
+
const viewports = evidence.viewports || [];
|
|
418
|
+
for (const viewport of viewports) {
|
|
419
|
+
const results = viewport.setup_action_results || [];
|
|
420
|
+
for (const result of results) {
|
|
421
|
+
if (result.ok === false) {
|
|
422
|
+
failed.push({
|
|
423
|
+
viewport: viewport.name,
|
|
424
|
+
action: result.action ?? result.type ?? null,
|
|
425
|
+
selector: result.selector ?? null,
|
|
426
|
+
reason: result.reason ?? result.error ?? null
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (results.length < actionCount && results.every((result) => result.ok !== false)) {
|
|
431
|
+
failed.push({
|
|
432
|
+
viewport: viewport.name,
|
|
433
|
+
action: "setup_actions",
|
|
434
|
+
selector: null,
|
|
435
|
+
reason: `missing setup action results: ${results.length}/${actionCount}`
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
type: "setup_actions_succeeded",
|
|
441
|
+
label: "setup actions succeeded",
|
|
442
|
+
status: failed.length ? "failed" : "passed",
|
|
443
|
+
evidence: {
|
|
444
|
+
action_count: actionCount,
|
|
445
|
+
viewports: viewports.map((viewport) => ({
|
|
446
|
+
name: viewport.name,
|
|
447
|
+
ok: (viewport.setup_action_results || []).length >= actionCount && (viewport.setup_action_results || []).every((result) => result.ok !== false),
|
|
448
|
+
result_count: (viewport.setup_action_results || []).length
|
|
449
|
+
})),
|
|
450
|
+
failed
|
|
451
|
+
},
|
|
452
|
+
message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
|
|
453
|
+
};
|
|
454
|
+
}
|
|
355
455
|
function profileStatusFromEvidence(evidence, checks) {
|
|
356
456
|
if (!evidence) return "proof_insufficient";
|
|
357
457
|
const viewports = evidence.viewports || [];
|
|
@@ -363,7 +463,10 @@ function profileStatusFromEvidence(evidence, checks) {
|
|
|
363
463
|
}
|
|
364
464
|
function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
|
|
365
465
|
const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
|
|
366
|
-
const checks = evidence ?
|
|
466
|
+
const checks = evidence ? [
|
|
467
|
+
assessSetupActionsFromEvidence(profile, evidence),
|
|
468
|
+
...profile.checks.map((check) => assessCheckFromEvidence(check, evidence))
|
|
469
|
+
].filter((check) => Boolean(check)) : [];
|
|
367
470
|
const status = profileStatusFromEvidence(evidence, checks);
|
|
368
471
|
const firstViewport = evidence?.viewports?.[0];
|
|
369
472
|
const screenshots = (evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => Boolean(label));
|
|
@@ -465,8 +568,16 @@ function createRiddleProofProfileInsufficientResult(input) {
|
|
|
465
568
|
}
|
|
466
569
|
function runtimeScriptAssessmentSource() {
|
|
467
570
|
return String.raw`
|
|
571
|
+
function normalizeRoutePath(path) {
|
|
572
|
+
const value = path || "/";
|
|
573
|
+
if (value === "/") return "/";
|
|
574
|
+
return value.replace(/\/+$/, "") || "/";
|
|
575
|
+
}
|
|
576
|
+
function routePathMatches(observed, expected) {
|
|
577
|
+
return normalizeRoutePath(observed) === normalizeRoutePath(expected);
|
|
578
|
+
}
|
|
468
579
|
function routeOk(route) {
|
|
469
|
-
return Boolean(route && route.matched && !route.error && (route.http_status == null || route.http_status < 400));
|
|
580
|
+
return Boolean(route && (route.matched || routePathMatches(route.observed, route.expected_path)) && !route.error && (route.http_status == null || route.http_status < 400));
|
|
470
581
|
}
|
|
471
582
|
function textMatches(sample, check) {
|
|
472
583
|
if (check.pattern) {
|
|
@@ -477,12 +588,53 @@ function textMatches(sample, check) {
|
|
|
477
588
|
function assessProfile(profile, evidence) {
|
|
478
589
|
const checks = [];
|
|
479
590
|
const viewports = evidence.viewports || [];
|
|
591
|
+
if (profile.target && Array.isArray(profile.target.setup_actions) && profile.target.setup_actions.length) {
|
|
592
|
+
const actionCount = profile.target.setup_actions.length;
|
|
593
|
+
const failed = [];
|
|
594
|
+
for (const viewport of viewports) {
|
|
595
|
+
const results = viewport.setup_action_results || [];
|
|
596
|
+
for (const result of results) {
|
|
597
|
+
if (result && result.ok === false) {
|
|
598
|
+
failed.push({
|
|
599
|
+
viewport: viewport.name,
|
|
600
|
+
action: result.action || result.type || null,
|
|
601
|
+
selector: result.selector || null,
|
|
602
|
+
reason: result.reason || result.error || null,
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if (results.length < actionCount && results.every((result) => !result || result.ok !== false)) {
|
|
607
|
+
failed.push({
|
|
608
|
+
viewport: viewport.name,
|
|
609
|
+
action: "setup_actions",
|
|
610
|
+
selector: null,
|
|
611
|
+
reason: "missing setup action results: " + results.length + "/" + actionCount,
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
checks.push({
|
|
616
|
+
type: "setup_actions_succeeded",
|
|
617
|
+
label: "setup actions succeeded",
|
|
618
|
+
status: failed.length ? "failed" : "passed",
|
|
619
|
+
evidence: {
|
|
620
|
+
action_count: actionCount,
|
|
621
|
+
viewports: viewports.map((viewport) => ({
|
|
622
|
+
name: viewport.name,
|
|
623
|
+
ok: (viewport.setup_action_results || []).length >= actionCount
|
|
624
|
+
&& (viewport.setup_action_results || []).every((result) => !result || result.ok !== false),
|
|
625
|
+
result_count: (viewport.setup_action_results || []).length,
|
|
626
|
+
})),
|
|
627
|
+
failed,
|
|
628
|
+
},
|
|
629
|
+
message: failed.length ? "Setup actions failed in " + failed.length + " viewport action(s)." : undefined,
|
|
630
|
+
});
|
|
631
|
+
}
|
|
480
632
|
for (const check of profile.checks || []) {
|
|
481
633
|
if (check.type === "route_loaded") {
|
|
482
634
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
483
635
|
const failed = viewports.filter((viewport) => {
|
|
484
636
|
const route = { ...(viewport.route || {}), expected_path: expectedPath };
|
|
485
|
-
route.matched = route.observed
|
|
637
|
+
route.matched = routePathMatches(route.observed, expectedPath) || route.matched;
|
|
486
638
|
return !routeOk(route);
|
|
487
639
|
});
|
|
488
640
|
checks.push({
|
|
@@ -639,6 +791,105 @@ function textMatches(sample, check) {
|
|
|
639
791
|
}
|
|
640
792
|
return String(sample || "").includes(check.text || "");
|
|
641
793
|
}
|
|
794
|
+
function setupActionType(action) {
|
|
795
|
+
return String(action && action.type ? action.type : "").replace(/-/g, "_");
|
|
796
|
+
}
|
|
797
|
+
function setupNumber(value, fallback) {
|
|
798
|
+
const number = Number(value);
|
|
799
|
+
return Number.isFinite(number) && number >= 0 ? number : fallback;
|
|
800
|
+
}
|
|
801
|
+
function setupTextMatches(sample, action) {
|
|
802
|
+
if (action.pattern) {
|
|
803
|
+
try { return new RegExp(action.pattern, action.flags || "").test(sample || ""); } catch { return false; }
|
|
804
|
+
}
|
|
805
|
+
return String(sample || "").includes(action.text || "");
|
|
806
|
+
}
|
|
807
|
+
async function setupLocatorText(locator, index) {
|
|
808
|
+
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
809
|
+
}
|
|
810
|
+
async function setupLocatorVisible(locator, index) {
|
|
811
|
+
return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
|
|
812
|
+
}
|
|
813
|
+
async function executeSetupAction(action, ordinal) {
|
|
814
|
+
const type = setupActionType(action);
|
|
815
|
+
const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
|
|
816
|
+
const timeout = setupNumber(action.timeout_ms, 5000);
|
|
817
|
+
try {
|
|
818
|
+
if (type === "wait") {
|
|
819
|
+
const ms = setupNumber(action.ms, 500);
|
|
820
|
+
await page.waitForTimeout(ms);
|
|
821
|
+
return { ...base, ok: true, ms };
|
|
822
|
+
}
|
|
823
|
+
if (type === "wait_for_selector") {
|
|
824
|
+
await page.waitForSelector(action.selector, { state: "visible", timeout });
|
|
825
|
+
return { ...base, ok: true, timeout_ms: timeout };
|
|
826
|
+
}
|
|
827
|
+
if (type === "click") {
|
|
828
|
+
const locator = page.locator(action.selector);
|
|
829
|
+
const count = await locator.count();
|
|
830
|
+
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
831
|
+
let targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
832
|
+
let matchedText = null;
|
|
833
|
+
let hiddenMatchIndex = -1;
|
|
834
|
+
let hiddenMatchedText = null;
|
|
835
|
+
if (action.text || action.pattern) {
|
|
836
|
+
targetIndex = -1;
|
|
837
|
+
for (let index = 0; index < count; index += 1) {
|
|
838
|
+
const text = await setupLocatorText(locator, index);
|
|
839
|
+
if (setupTextMatches(text, action)) {
|
|
840
|
+
const visible = await setupLocatorVisible(locator, index);
|
|
841
|
+
if (visible) {
|
|
842
|
+
targetIndex = index;
|
|
843
|
+
matchedText = text;
|
|
844
|
+
break;
|
|
845
|
+
}
|
|
846
|
+
if (hiddenMatchIndex < 0) {
|
|
847
|
+
hiddenMatchIndex = index;
|
|
848
|
+
hiddenMatchedText = text;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
if (targetIndex < 0 && hiddenMatchIndex >= 0) return { ...base, reason: "matching_element_not_visible", count, target_index: hiddenMatchIndex, text: hiddenMatchedText };
|
|
853
|
+
if (targetIndex < 0) return { ...base, reason: "text_not_found", count };
|
|
854
|
+
}
|
|
855
|
+
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
|
|
856
|
+
await locator.nth(targetIndex).click({ timeout });
|
|
857
|
+
return { ...base, ok: true, count, target_index: targetIndex, text: matchedText };
|
|
858
|
+
}
|
|
859
|
+
if (type === "wait_for_text") {
|
|
860
|
+
const locator = page.locator(action.selector);
|
|
861
|
+
const startedAt = Date.now();
|
|
862
|
+
let lastText = "";
|
|
863
|
+
while (Date.now() - startedAt <= timeout) {
|
|
864
|
+
const count = await locator.count().catch(() => 0);
|
|
865
|
+
for (let index = 0; index < count; index += 1) {
|
|
866
|
+
const text = await setupLocatorText(locator, index);
|
|
867
|
+
lastText = text || lastText;
|
|
868
|
+
if (setupTextMatches(text, action)) {
|
|
869
|
+
return { ...base, ok: true, text, target_index: index, timeout_ms: timeout };
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
await page.waitForTimeout(100);
|
|
873
|
+
}
|
|
874
|
+
return { ...base, reason: "text_not_found", text: lastText, timeout_ms: timeout };
|
|
875
|
+
}
|
|
876
|
+
return { ...base, reason: "unsupported_action" };
|
|
877
|
+
} catch (error) {
|
|
878
|
+
return { ...base, error: String(error && error.message ? error.message : error).slice(0, 1000) };
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
async function executeSetupActions(actions) {
|
|
882
|
+
const results = [];
|
|
883
|
+
for (let index = 0; index < (actions || []).length; index += 1) {
|
|
884
|
+
const action = actions[index] || {};
|
|
885
|
+
const result = await executeSetupAction(action, index);
|
|
886
|
+
results.push(result);
|
|
887
|
+
const afterMs = setupNumber(action.after_ms, 0);
|
|
888
|
+
if (afterMs) await page.waitForTimeout(afterMs);
|
|
889
|
+
if (result.ok === false && action.continue_on_failure !== true) break;
|
|
890
|
+
}
|
|
891
|
+
return results;
|
|
892
|
+
}
|
|
642
893
|
function expectedPathFor(check) {
|
|
643
894
|
return check.expected_path || new URL(targetUrl).pathname || "/";
|
|
644
895
|
}
|
|
@@ -673,6 +924,9 @@ async function captureViewport(viewport) {
|
|
|
673
924
|
if (!navigationError && profile.target.wait_ms) {
|
|
674
925
|
await page.waitForTimeout(profile.target.wait_ms);
|
|
675
926
|
}
|
|
927
|
+
const setupActionResults = (!navigationError && !waitError)
|
|
928
|
+
? await executeSetupActions(profile.target.setup_actions || [])
|
|
929
|
+
: [];
|
|
676
930
|
const dom = await page.evaluate(() => {
|
|
677
931
|
const body = document.body;
|
|
678
932
|
const documentElement = document.documentElement;
|
|
@@ -722,7 +976,7 @@ async function captureViewport(viewport) {
|
|
|
722
976
|
requested: targetUrl,
|
|
723
977
|
observed: dom.pathname,
|
|
724
978
|
expected_path: expectedPath,
|
|
725
|
-
matched: dom.pathname
|
|
979
|
+
matched: routePathMatches(dom.pathname, expectedPath),
|
|
726
980
|
http_status: httpStatus,
|
|
727
981
|
error: navigationError || waitError || undefined,
|
|
728
982
|
},
|
|
@@ -734,6 +988,7 @@ async function captureViewport(viewport) {
|
|
|
734
988
|
overflow_px: Math.max(0, (dom.scroll_width || 0) - (dom.client_width || viewport.width)),
|
|
735
989
|
selectors,
|
|
736
990
|
text_matches,
|
|
991
|
+
setup_action_results: setupActionResults,
|
|
737
992
|
screenshot_label: screenshotLabel,
|
|
738
993
|
navigation_error: navigationError,
|
|
739
994
|
wait_error: waitError,
|
|
@@ -831,6 +1086,7 @@ function extractRiddleProofProfileResult(input) {
|
|
|
831
1086
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
832
1087
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|
|
833
1088
|
RIDDLE_PROOF_PROFILE_RESULT_VERSION,
|
|
1089
|
+
RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES,
|
|
834
1090
|
RIDDLE_PROOF_PROFILE_STATUSES,
|
|
835
1091
|
RIDDLE_PROOF_PROFILE_VERSION,
|
|
836
1092
|
assessRiddleProofProfileEvidence,
|
package/dist/profile.d.cts
CHANGED
|
@@ -5,8 +5,10 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
|
|
|
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
7
|
declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "selector_visible", "selector_count_at_least", "text_visible", "text_absent", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
|
|
8
|
+
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "wait", "wait_for_selector", "wait_for_text"];
|
|
8
9
|
type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
|
|
9
10
|
type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
|
|
11
|
+
type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
|
|
10
12
|
type RiddleProofProfileRunner = "riddle" | "local-playwright" | "browserless" | "github-actions" | (string & {});
|
|
11
13
|
type RiddleProofProfileFailureAction = "fail" | "neutral" | "review";
|
|
12
14
|
type RiddleProofProfileBaselinePolicy = "invariant_only" | "production_comparison" | "last_accepted_artifact" | "golden_reference_artifact" | (string & {});
|
|
@@ -15,6 +17,18 @@ interface RiddleProofProfileViewport {
|
|
|
15
17
|
width: number;
|
|
16
18
|
height: number;
|
|
17
19
|
}
|
|
20
|
+
interface RiddleProofProfileSetupAction {
|
|
21
|
+
type: RiddleProofProfileSetupActionType;
|
|
22
|
+
selector?: string;
|
|
23
|
+
text?: string;
|
|
24
|
+
pattern?: string;
|
|
25
|
+
flags?: string;
|
|
26
|
+
index?: number;
|
|
27
|
+
ms?: number;
|
|
28
|
+
timeout_ms?: number;
|
|
29
|
+
after_ms?: number;
|
|
30
|
+
continue_on_failure?: boolean;
|
|
31
|
+
}
|
|
18
32
|
interface RiddleProofProfileTarget {
|
|
19
33
|
url?: string;
|
|
20
34
|
route?: string;
|
|
@@ -22,6 +36,7 @@ interface RiddleProofProfileTarget {
|
|
|
22
36
|
auth?: "none" | (string & {});
|
|
23
37
|
wait_for_selector?: string;
|
|
24
38
|
wait_ms?: number;
|
|
39
|
+
setup_actions?: RiddleProofProfileSetupAction[];
|
|
25
40
|
}
|
|
26
41
|
interface RiddleProofProfileCheck {
|
|
27
42
|
type: RiddleProofProfileCheckType;
|
|
@@ -69,6 +84,7 @@ interface RiddleProofProfileViewportEvidence {
|
|
|
69
84
|
visible_count: number;
|
|
70
85
|
}>;
|
|
71
86
|
text_matches?: Record<string, boolean>;
|
|
87
|
+
setup_action_results?: Array<Record<string, JsonValue>>;
|
|
72
88
|
screenshot_label?: string;
|
|
73
89
|
navigation_error?: string;
|
|
74
90
|
wait_error?: string;
|
|
@@ -172,4 +188,4 @@ declare function buildRiddleProofProfileScript(profile: RiddleProofProfile): str
|
|
|
172
188
|
declare function collectRiddleProfileArtifactRefs(input: unknown): RiddleProofProfileArtifactRef[];
|
|
173
189
|
declare function extractRiddleProofProfileResult(input: unknown): RiddleProofProfileResult | undefined;
|
|
174
190
|
|
|
175
|
-
export { type NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, type RiddleProofProfile, type RiddleProofProfileArtifactRef, type RiddleProofProfileBaselinePolicy, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileResult, type RiddleProofProfileRouteEvidence, type RiddleProofProfileRunner, type RiddleProofProfileStatus, type RiddleProofProfileTarget, type RiddleProofProfileViewport, type RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileTargetUrl, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
|
|
191
|
+
export { type NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, type RiddleProofProfile, type RiddleProofProfileArtifactRef, type RiddleProofProfileBaselinePolicy, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileResult, type RiddleProofProfileRouteEvidence, type RiddleProofProfileRunner, type RiddleProofProfileSetupAction, type RiddleProofProfileSetupActionType, type RiddleProofProfileStatus, type RiddleProofProfileTarget, type RiddleProofProfileViewport, type RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileTargetUrl, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
|
package/dist/profile.d.ts
CHANGED
|
@@ -5,8 +5,10 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
|
|
|
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
7
|
declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "selector_visible", "selector_count_at_least", "text_visible", "text_absent", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
|
|
8
|
+
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "wait", "wait_for_selector", "wait_for_text"];
|
|
8
9
|
type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
|
|
9
10
|
type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
|
|
11
|
+
type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
|
|
10
12
|
type RiddleProofProfileRunner = "riddle" | "local-playwright" | "browserless" | "github-actions" | (string & {});
|
|
11
13
|
type RiddleProofProfileFailureAction = "fail" | "neutral" | "review";
|
|
12
14
|
type RiddleProofProfileBaselinePolicy = "invariant_only" | "production_comparison" | "last_accepted_artifact" | "golden_reference_artifact" | (string & {});
|
|
@@ -15,6 +17,18 @@ interface RiddleProofProfileViewport {
|
|
|
15
17
|
width: number;
|
|
16
18
|
height: number;
|
|
17
19
|
}
|
|
20
|
+
interface RiddleProofProfileSetupAction {
|
|
21
|
+
type: RiddleProofProfileSetupActionType;
|
|
22
|
+
selector?: string;
|
|
23
|
+
text?: string;
|
|
24
|
+
pattern?: string;
|
|
25
|
+
flags?: string;
|
|
26
|
+
index?: number;
|
|
27
|
+
ms?: number;
|
|
28
|
+
timeout_ms?: number;
|
|
29
|
+
after_ms?: number;
|
|
30
|
+
continue_on_failure?: boolean;
|
|
31
|
+
}
|
|
18
32
|
interface RiddleProofProfileTarget {
|
|
19
33
|
url?: string;
|
|
20
34
|
route?: string;
|
|
@@ -22,6 +36,7 @@ interface RiddleProofProfileTarget {
|
|
|
22
36
|
auth?: "none" | (string & {});
|
|
23
37
|
wait_for_selector?: string;
|
|
24
38
|
wait_ms?: number;
|
|
39
|
+
setup_actions?: RiddleProofProfileSetupAction[];
|
|
25
40
|
}
|
|
26
41
|
interface RiddleProofProfileCheck {
|
|
27
42
|
type: RiddleProofProfileCheckType;
|
|
@@ -69,6 +84,7 @@ interface RiddleProofProfileViewportEvidence {
|
|
|
69
84
|
visible_count: number;
|
|
70
85
|
}>;
|
|
71
86
|
text_matches?: Record<string, boolean>;
|
|
87
|
+
setup_action_results?: Array<Record<string, JsonValue>>;
|
|
72
88
|
screenshot_label?: string;
|
|
73
89
|
navigation_error?: string;
|
|
74
90
|
wait_error?: string;
|
|
@@ -172,4 +188,4 @@ declare function buildRiddleProofProfileScript(profile: RiddleProofProfile): str
|
|
|
172
188
|
declare function collectRiddleProfileArtifactRefs(input: unknown): RiddleProofProfileArtifactRef[];
|
|
173
189
|
declare function extractRiddleProofProfileResult(input: unknown): RiddleProofProfileResult | undefined;
|
|
174
190
|
|
|
175
|
-
export { type NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, type RiddleProofProfile, type RiddleProofProfileArtifactRef, type RiddleProofProfileBaselinePolicy, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileResult, type RiddleProofProfileRouteEvidence, type RiddleProofProfileRunner, type RiddleProofProfileStatus, type RiddleProofProfileTarget, type RiddleProofProfileViewport, type RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileTargetUrl, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
|
|
191
|
+
export { type NormalizeRiddleProofProfileOptions, RIDDLE_PROOF_PROFILE_CHECK_TYPES, RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION, RIDDLE_PROOF_PROFILE_RESULT_VERSION, RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES, RIDDLE_PROOF_PROFILE_STATUSES, RIDDLE_PROOF_PROFILE_VERSION, type RiddleProofProfile, type RiddleProofProfileArtifactRef, type RiddleProofProfileBaselinePolicy, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileResult, type RiddleProofProfileRouteEvidence, type RiddleProofProfileRunner, type RiddleProofProfileSetupAction, type RiddleProofProfileSetupActionType, type RiddleProofProfileStatus, type RiddleProofProfileTarget, type RiddleProofProfileViewport, type RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileTargetUrl, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
|
package/dist/profile.js
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
3
3
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|
|
4
4
|
RIDDLE_PROOF_PROFILE_RESULT_VERSION,
|
|
5
|
+
RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES,
|
|
5
6
|
RIDDLE_PROOF_PROFILE_STATUSES,
|
|
6
7
|
RIDDLE_PROOF_PROFILE_VERSION,
|
|
7
8
|
assessRiddleProofProfileEvidence,
|
|
@@ -16,11 +17,12 @@ import {
|
|
|
16
17
|
resolveRiddleProofProfileTargetUrl,
|
|
17
18
|
slugifyRiddleProofProfileName,
|
|
18
19
|
summarizeRiddleProofProfileResult
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-A7RJZD4I.js";
|
|
20
21
|
export {
|
|
21
22
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
22
23
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|
|
23
24
|
RIDDLE_PROOF_PROFILE_RESULT_VERSION,
|
|
25
|
+
RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES,
|
|
24
26
|
RIDDLE_PROOF_PROFILE_STATUSES,
|
|
25
27
|
RIDDLE_PROOF_PROFILE_VERSION,
|
|
26
28
|
assessRiddleProofProfileEvidence,
|
|
@@ -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: "recon" | "author" | "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: "recon" | "author" | "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: "recon" | "author" | "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: "recon" | "author" | "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: "recon" | "author" | "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: "recon" | "author" | "ship" | "implement" | "verify" | "setup" | "run";
|
|
663
663
|
state_path: string;
|
|
664
664
|
stage: any;
|
|
665
665
|
summary: string;
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
{ "name": "desktop", "width": 1440, "height": 1000 }
|
|
9
9
|
],
|
|
10
10
|
"auth": "none",
|
|
11
|
-
"wait_for_selector": "body"
|
|
11
|
+
"wait_for_selector": "body",
|
|
12
|
+
"setup_actions": [
|
|
13
|
+
{ "type": "wait", "ms": 250 }
|
|
14
|
+
]
|
|
12
15
|
},
|
|
13
16
|
"checks": [
|
|
14
17
|
{ "type": "route_loaded", "expected_path": "/" },
|