@riddledc/riddle-proof 0.7.26 → 0.7.28
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-SDSBS64X.js → chunk-NUGGW7NX.js} +232 -2
- package/dist/cli.cjs +232 -2
- package/dist/cli.js +1 -1
- package/dist/index.cjs +232 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/profile.cjs +232 -2
- package/dist/profile.d.cts +19 -2
- package/dist/profile.d.ts +19 -2
- 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
package/dist/profile.cjs
CHANGED
|
@@ -65,6 +65,9 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
65
65
|
];
|
|
66
66
|
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
67
67
|
"click",
|
|
68
|
+
"fill",
|
|
69
|
+
"set_input_value",
|
|
70
|
+
"local_storage",
|
|
68
71
|
"wait",
|
|
69
72
|
"wait_for_selector",
|
|
70
73
|
"wait_for_text"
|
|
@@ -78,6 +81,18 @@ function isRecord(value) {
|
|
|
78
81
|
function stringValue(value) {
|
|
79
82
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
80
83
|
}
|
|
84
|
+
function hasOwn(value, key) {
|
|
85
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
86
|
+
}
|
|
87
|
+
function stringFromOwn(input, ...keys) {
|
|
88
|
+
for (const key of keys) {
|
|
89
|
+
if (hasOwn(input, key)) {
|
|
90
|
+
const value = input[key];
|
|
91
|
+
if (value !== void 0 && value !== null) return String(value);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return void 0;
|
|
95
|
+
}
|
|
81
96
|
function numberValue(value) {
|
|
82
97
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
83
98
|
}
|
|
@@ -162,6 +177,11 @@ function jsonRecord(value) {
|
|
|
162
177
|
if (!isRecord(value)) return void 0;
|
|
163
178
|
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
164
179
|
}
|
|
180
|
+
function stringRecord(value) {
|
|
181
|
+
if (!isRecord(value)) return void 0;
|
|
182
|
+
const entries = Object.entries(value).map(([key, child]) => [key, String(child)]).filter(([key]) => key.trim());
|
|
183
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
184
|
+
}
|
|
165
185
|
function toJsonValue(value) {
|
|
166
186
|
if (value === null || value === void 0) return null;
|
|
167
187
|
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
@@ -209,15 +229,30 @@ function normalizeSetupAction(input, index) {
|
|
|
209
229
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
210
230
|
const type = normalizeSetupActionType(stringValue(input.type), index);
|
|
211
231
|
const selector = stringValue(input.selector);
|
|
212
|
-
if ((type === "click" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
|
|
232
|
+
if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
|
|
213
233
|
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
214
234
|
}
|
|
215
235
|
if (type === "wait_for_text" && !stringValue(input.text) && !stringValue(input.pattern)) {
|
|
216
236
|
throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
|
|
217
237
|
}
|
|
238
|
+
const value = stringFromOwn(input, "value", "input_value", "inputValue");
|
|
239
|
+
const hasJsonValue = hasOwn(input, "value_json") || hasOwn(input, "valueJson") || hasOwn(input, "json");
|
|
240
|
+
if ((type === "fill" || type === "set_input_value") && value === void 0 && !hasJsonValue) {
|
|
241
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
242
|
+
}
|
|
243
|
+
const key = stringValue(input.key);
|
|
244
|
+
if (type === "local_storage" && !key) {
|
|
245
|
+
throw new Error(`target.setup_actions[${index}] local_storage requires key.`);
|
|
246
|
+
}
|
|
247
|
+
if (type === "local_storage" && value === void 0 && !hasJsonValue) {
|
|
248
|
+
throw new Error(`target.setup_actions[${index}] local_storage requires value.`);
|
|
249
|
+
}
|
|
218
250
|
return {
|
|
219
251
|
type,
|
|
220
252
|
selector,
|
|
253
|
+
key,
|
|
254
|
+
value,
|
|
255
|
+
value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
|
|
221
256
|
text: stringValue(input.text),
|
|
222
257
|
pattern: stringValue(input.pattern),
|
|
223
258
|
flags: stringValue(input.flags),
|
|
@@ -225,6 +260,7 @@ function normalizeSetupAction(input, index) {
|
|
|
225
260
|
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
226
261
|
timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
|
|
227
262
|
after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
|
|
263
|
+
reload: input.reload === true,
|
|
228
264
|
continue_on_failure: input.continue_on_failure === true || input.continueOnFailure === true
|
|
229
265
|
};
|
|
230
266
|
}
|
|
@@ -233,6 +269,33 @@ function normalizeSetupActions(value) {
|
|
|
233
269
|
if (!Array.isArray(value)) throw new Error("target.setup_actions must be an array.");
|
|
234
270
|
return value.map(normalizeSetupAction);
|
|
235
271
|
}
|
|
272
|
+
function normalizeNetworkMock(input, index) {
|
|
273
|
+
if (!isRecord(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
|
|
274
|
+
const url = stringValue(input.url) || stringValue(input.glob) || stringValue(input.pattern);
|
|
275
|
+
if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
|
|
276
|
+
const status = numberValue(input.status) ?? 200;
|
|
277
|
+
if (!Number.isInteger(status) || status < 100 || status > 599) {
|
|
278
|
+
throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
|
|
279
|
+
}
|
|
280
|
+
const body = stringValue(input.body) ?? stringValue(input.body_text) ?? stringValue(input.bodyText);
|
|
281
|
+
const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
|
|
282
|
+
return {
|
|
283
|
+
label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
|
|
284
|
+
url,
|
|
285
|
+
method: stringValue(input.method)?.toUpperCase(),
|
|
286
|
+
status,
|
|
287
|
+
content_type: stringValue(input.content_type) || stringValue(input.contentType),
|
|
288
|
+
headers: stringRecord(input.headers),
|
|
289
|
+
body,
|
|
290
|
+
body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
|
|
291
|
+
required: input.required === false ? false : true
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function normalizeNetworkMocks(value) {
|
|
295
|
+
if (value === void 0) return void 0;
|
|
296
|
+
if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
|
|
297
|
+
return value.map(normalizeNetworkMock);
|
|
298
|
+
}
|
|
236
299
|
function normalizeCheck(input, index) {
|
|
237
300
|
if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
238
301
|
const type = stringValue(input.type);
|
|
@@ -302,7 +365,8 @@ function normalizeRiddleProofProfile(input, options = {}) {
|
|
|
302
365
|
timeout_sec: timeoutSecValue(targetInput.timeout_sec) ?? timeoutSecValue(targetInput.timeoutSec) ?? timeoutSecValue(targetInput.riddle_timeout_sec) ?? timeoutSecValue(targetInput.riddleTimeoutSec),
|
|
303
366
|
wait_for_selector: stringValue(targetInput.wait_for_selector) || stringValue(targetInput.waitForSelector),
|
|
304
367
|
wait_ms: numberValue(targetInput.wait_ms) ?? numberValue(targetInput.waitMs),
|
|
305
|
-
setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions)
|
|
368
|
+
setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions),
|
|
369
|
+
network_mocks: normalizeNetworkMocks(targetInput.network_mocks ?? targetInput.networkMocks)
|
|
306
370
|
},
|
|
307
371
|
checks,
|
|
308
372
|
artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
|
|
@@ -574,6 +638,50 @@ function assessSetupActionsFromEvidence(profile, evidence) {
|
|
|
574
638
|
message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
|
|
575
639
|
};
|
|
576
640
|
}
|
|
641
|
+
function assessNetworkMocksFromEvidence(profile, evidence) {
|
|
642
|
+
const mocks = profile.target.network_mocks || [];
|
|
643
|
+
if (!mocks.length) return void 0;
|
|
644
|
+
const events = evidence.network_mocks || [];
|
|
645
|
+
const failed = [];
|
|
646
|
+
const requiredMocks = mocks.filter((mock) => mock.required !== false);
|
|
647
|
+
for (const mock of requiredMocks) {
|
|
648
|
+
const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
|
|
649
|
+
if (hits < 1) {
|
|
650
|
+
failed.push({
|
|
651
|
+
label: mock.label,
|
|
652
|
+
url: mock.url,
|
|
653
|
+
method: mock.method || null,
|
|
654
|
+
reason: "required_mock_not_hit"
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
for (const event of events) {
|
|
659
|
+
if (event.ok === false) {
|
|
660
|
+
failed.push({
|
|
661
|
+
label: event.label ?? null,
|
|
662
|
+
url: event.url ?? null,
|
|
663
|
+
method: event.method ?? null,
|
|
664
|
+
reason: event.reason ?? event.error ?? "mock_failed"
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
return {
|
|
669
|
+
type: "network_mocks_succeeded",
|
|
670
|
+
label: "network mocks succeeded",
|
|
671
|
+
status: failed.length ? "failed" : "passed",
|
|
672
|
+
evidence: {
|
|
673
|
+
mock_count: mocks.length,
|
|
674
|
+
required_count: requiredMocks.length,
|
|
675
|
+
hit_count: events.filter((event) => event.ok !== false).length,
|
|
676
|
+
hits_by_label: Object.fromEntries(mocks.map((mock) => [
|
|
677
|
+
mock.label,
|
|
678
|
+
events.filter((event) => event.label === mock.label && event.ok !== false).length
|
|
679
|
+
])),
|
|
680
|
+
failed
|
|
681
|
+
},
|
|
682
|
+
message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
|
|
683
|
+
};
|
|
684
|
+
}
|
|
577
685
|
function profileStatusFromEvidence(profile, evidence, checks) {
|
|
578
686
|
if (!evidence) return "proof_insufficient";
|
|
579
687
|
const viewports = evidence.viewports || [];
|
|
@@ -588,6 +696,7 @@ function profileStatusFromEvidence(profile, evidence, checks) {
|
|
|
588
696
|
function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
|
|
589
697
|
const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
|
|
590
698
|
const checks = evidence ? [
|
|
699
|
+
assessNetworkMocksFromEvidence(profile, evidence),
|
|
591
700
|
assessSetupActionsFromEvidence(profile, evidence),
|
|
592
701
|
...profile.checks.map((check) => assessCheckFromEvidence(check, evidence))
|
|
593
702
|
].filter((check) => Boolean(check)) : [];
|
|
@@ -804,6 +913,49 @@ function horizontalBoundsOverflowPx(value) {
|
|
|
804
913
|
function assessProfile(profile, evidence) {
|
|
805
914
|
const checks = [];
|
|
806
915
|
const viewports = evidence.viewports || [];
|
|
916
|
+
if (profile.target && Array.isArray(profile.target.network_mocks) && profile.target.network_mocks.length) {
|
|
917
|
+
const events = evidence.network_mocks || [];
|
|
918
|
+
const requiredMocks = profile.target.network_mocks.filter((mock) => mock && mock.required !== false);
|
|
919
|
+
const failed = [];
|
|
920
|
+
for (const mock of requiredMocks) {
|
|
921
|
+
const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
|
|
922
|
+
if (hits < 1) {
|
|
923
|
+
failed.push({
|
|
924
|
+
label: mock.label,
|
|
925
|
+
url: mock.url,
|
|
926
|
+
method: mock.method || null,
|
|
927
|
+
reason: "required_mock_not_hit",
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
for (const event of events) {
|
|
932
|
+
if (event && event.ok === false) {
|
|
933
|
+
failed.push({
|
|
934
|
+
label: event.label || null,
|
|
935
|
+
url: event.url || null,
|
|
936
|
+
method: event.method || null,
|
|
937
|
+
reason: event.reason || event.error || "mock_failed",
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
const hitsByLabel = {};
|
|
942
|
+
for (const mock of profile.target.network_mocks) {
|
|
943
|
+
hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
|
|
944
|
+
}
|
|
945
|
+
checks.push({
|
|
946
|
+
type: "network_mocks_succeeded",
|
|
947
|
+
label: "network mocks succeeded",
|
|
948
|
+
status: failed.length ? "failed" : "passed",
|
|
949
|
+
evidence: {
|
|
950
|
+
mock_count: profile.target.network_mocks.length,
|
|
951
|
+
required_count: requiredMocks.length,
|
|
952
|
+
hit_count: events.filter((event) => event && event.ok !== false).length,
|
|
953
|
+
hits_by_label: hitsByLabel,
|
|
954
|
+
failed,
|
|
955
|
+
},
|
|
956
|
+
message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
|
|
957
|
+
});
|
|
958
|
+
}
|
|
807
959
|
if (profile.target && Array.isArray(profile.target.setup_actions) && profile.target.setup_actions.length) {
|
|
808
960
|
const actionCount = profile.target.setup_actions.length;
|
|
809
961
|
const failed = [];
|
|
@@ -993,6 +1145,7 @@ const profileSlug = ${serializableSlug};
|
|
|
993
1145
|
const capturedAt = new Date().toISOString();
|
|
994
1146
|
const consoleEvents = [];
|
|
995
1147
|
const pageErrors = [];
|
|
1148
|
+
const networkMockEvents = [];
|
|
996
1149
|
page.on("console", (message) => {
|
|
997
1150
|
const type = message.type();
|
|
998
1151
|
if (type === "error" || type === "warning" || type === "assert") {
|
|
@@ -1028,6 +1181,14 @@ function setupTextMatches(sample, action) {
|
|
|
1028
1181
|
}
|
|
1029
1182
|
return String(sample || "").includes(action.text || "");
|
|
1030
1183
|
}
|
|
1184
|
+
function setupHasOwn(action, key) {
|
|
1185
|
+
return Boolean(action) && Object.keys(action).includes(key);
|
|
1186
|
+
}
|
|
1187
|
+
function setupActionValue(action) {
|
|
1188
|
+
if (setupHasOwn(action, "value_json")) return JSON.stringify(action.value_json);
|
|
1189
|
+
if (setupHasOwn(action, "value")) return String(action.value ?? "");
|
|
1190
|
+
return "";
|
|
1191
|
+
}
|
|
1031
1192
|
async function setupLocatorText(locator, index) {
|
|
1032
1193
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
1033
1194
|
}
|
|
@@ -1039,6 +1200,49 @@ function compactSetupResultText(value) {
|
|
|
1039
1200
|
async function setupLocatorVisible(locator, index) {
|
|
1040
1201
|
return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
|
|
1041
1202
|
}
|
|
1203
|
+
async function registerNetworkMocks(mocks) {
|
|
1204
|
+
for (const mock of mocks || []) {
|
|
1205
|
+
await page.route(mock.url, async (route) => {
|
|
1206
|
+
const request = route.request();
|
|
1207
|
+
const method = request.method ? request.method() : "";
|
|
1208
|
+
if (mock.method && method.toUpperCase() !== String(mock.method).toUpperCase()) {
|
|
1209
|
+
await route.continue();
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
try {
|
|
1213
|
+
const headers = { ...(mock.headers || {}) };
|
|
1214
|
+
let body = mock.body || "";
|
|
1215
|
+
let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
|
|
1216
|
+
if (mock.body_json !== undefined) {
|
|
1217
|
+
body = JSON.stringify(mock.body_json);
|
|
1218
|
+
contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
|
|
1219
|
+
}
|
|
1220
|
+
networkMockEvents.push({
|
|
1221
|
+
ok: true,
|
|
1222
|
+
label: mock.label,
|
|
1223
|
+
url: request.url(),
|
|
1224
|
+
method,
|
|
1225
|
+
status: mock.status || 200,
|
|
1226
|
+
});
|
|
1227
|
+
await route.fulfill({
|
|
1228
|
+
status: mock.status || 200,
|
|
1229
|
+
headers,
|
|
1230
|
+
contentType,
|
|
1231
|
+
body,
|
|
1232
|
+
});
|
|
1233
|
+
} catch (error) {
|
|
1234
|
+
networkMockEvents.push({
|
|
1235
|
+
ok: false,
|
|
1236
|
+
label: mock.label,
|
|
1237
|
+
url: request.url(),
|
|
1238
|
+
method,
|
|
1239
|
+
error: String(error && error.message ? error.message : error).slice(0, 1000),
|
|
1240
|
+
});
|
|
1241
|
+
throw error;
|
|
1242
|
+
}
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1042
1246
|
async function executeSetupAction(action, ordinal) {
|
|
1043
1247
|
const type = setupActionType(action);
|
|
1044
1248
|
const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
|
|
@@ -1053,6 +1257,16 @@ async function executeSetupAction(action, ordinal) {
|
|
|
1053
1257
|
await page.waitForSelector(action.selector, { state: "visible", timeout });
|
|
1054
1258
|
return { ...base, ok: true, timeout_ms: timeout };
|
|
1055
1259
|
}
|
|
1260
|
+
if (type === "local_storage") {
|
|
1261
|
+
const value = setupActionValue(action);
|
|
1262
|
+
await page.evaluate(({ key, value }) => {
|
|
1263
|
+
window.localStorage.setItem(key, value);
|
|
1264
|
+
}, { key: action.key, value });
|
|
1265
|
+
if (action.reload === true) {
|
|
1266
|
+
await page.reload({ waitUntil: "domcontentloaded", timeout: 45000 });
|
|
1267
|
+
}
|
|
1268
|
+
return { ...base, ok: true, key: action.key, value_length: value.length, reload: action.reload === true };
|
|
1269
|
+
}
|
|
1056
1270
|
if (type === "click") {
|
|
1057
1271
|
const locator = page.locator(action.selector);
|
|
1058
1272
|
const count = await locator.count();
|
|
@@ -1085,6 +1299,16 @@ async function executeSetupAction(action, ordinal) {
|
|
|
1085
1299
|
await locator.nth(targetIndex).click({ timeout });
|
|
1086
1300
|
return { ...base, ok: true, count, target_index: targetIndex, text: matchedText };
|
|
1087
1301
|
}
|
|
1302
|
+
if (type === "fill" || type === "set_input_value") {
|
|
1303
|
+
const locator = page.locator(action.selector);
|
|
1304
|
+
const count = await locator.count();
|
|
1305
|
+
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
1306
|
+
const targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
1307
|
+
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
|
|
1308
|
+
const value = setupActionValue(action);
|
|
1309
|
+
await locator.nth(targetIndex).fill(value, { timeout });
|
|
1310
|
+
return { ...base, ok: true, count, target_index: targetIndex, value_length: value.length };
|
|
1311
|
+
}
|
|
1088
1312
|
if (type === "wait_for_text") {
|
|
1089
1313
|
const locator = page.locator(action.selector);
|
|
1090
1314
|
const startedAt = Date.now();
|
|
@@ -1300,6 +1524,7 @@ function buildProfileEvidence(currentViewports) {
|
|
|
1300
1524
|
fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
|
|
1301
1525
|
},
|
|
1302
1526
|
page_errors: pageErrors,
|
|
1527
|
+
network_mocks: networkMockEvents.slice(),
|
|
1303
1528
|
dom_summary: {
|
|
1304
1529
|
expected_viewport_count: expectedViewportCount,
|
|
1305
1530
|
viewport_count: currentViewports.length,
|
|
@@ -1309,6 +1534,8 @@ function buildProfileEvidence(currentViewports) {
|
|
|
1309
1534
|
overflow_px: currentViewports.map((viewport) => viewport.overflow_px),
|
|
1310
1535
|
bounds_overflow_px: currentViewports.map((viewport) => viewport.bounds_overflow_px),
|
|
1311
1536
|
overflow_offender_counts: currentViewports.map((viewport) => (viewport.overflow_offenders || []).length),
|
|
1537
|
+
network_mock_count: (profile.target.network_mocks || []).length,
|
|
1538
|
+
network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
|
|
1312
1539
|
},
|
|
1313
1540
|
};
|
|
1314
1541
|
}
|
|
@@ -1322,6 +1549,9 @@ async function saveProfileArtifacts(currentViewports) {
|
|
|
1322
1549
|
}
|
|
1323
1550
|
return result;
|
|
1324
1551
|
}
|
|
1552
|
+
await registerNetworkMocks(profile.target.network_mocks || []);
|
|
1553
|
+
consoleEvents.length = 0;
|
|
1554
|
+
pageErrors.length = 0;
|
|
1325
1555
|
let result = await saveProfileArtifacts(viewports);
|
|
1326
1556
|
for (const viewport of profile.target.viewports || []) {
|
|
1327
1557
|
viewports.push(await captureViewport(viewport));
|
package/dist/profile.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ 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
|
+
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "local_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];
|
|
11
11
|
type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
|
|
@@ -20,6 +20,9 @@ interface RiddleProofProfileViewport {
|
|
|
20
20
|
interface RiddleProofProfileSetupAction {
|
|
21
21
|
type: RiddleProofProfileSetupActionType;
|
|
22
22
|
selector?: string;
|
|
23
|
+
key?: string;
|
|
24
|
+
value?: string;
|
|
25
|
+
value_json?: JsonValue;
|
|
23
26
|
text?: string;
|
|
24
27
|
pattern?: string;
|
|
25
28
|
flags?: string;
|
|
@@ -27,8 +30,20 @@ interface RiddleProofProfileSetupAction {
|
|
|
27
30
|
ms?: number;
|
|
28
31
|
timeout_ms?: number;
|
|
29
32
|
after_ms?: number;
|
|
33
|
+
reload?: boolean;
|
|
30
34
|
continue_on_failure?: boolean;
|
|
31
35
|
}
|
|
36
|
+
interface RiddleProofProfileNetworkMock {
|
|
37
|
+
label: string;
|
|
38
|
+
url: string;
|
|
39
|
+
method?: string;
|
|
40
|
+
status: number;
|
|
41
|
+
content_type?: string;
|
|
42
|
+
headers?: Record<string, string>;
|
|
43
|
+
body?: string;
|
|
44
|
+
body_json?: JsonValue;
|
|
45
|
+
required?: boolean;
|
|
46
|
+
}
|
|
32
47
|
interface RiddleProofProfileTarget {
|
|
33
48
|
url?: string;
|
|
34
49
|
route?: string;
|
|
@@ -38,6 +53,7 @@ interface RiddleProofProfileTarget {
|
|
|
38
53
|
wait_for_selector?: string;
|
|
39
54
|
wait_ms?: number;
|
|
40
55
|
setup_actions?: RiddleProofProfileSetupAction[];
|
|
56
|
+
network_mocks?: RiddleProofProfileNetworkMock[];
|
|
41
57
|
}
|
|
42
58
|
interface RiddleProofProfileCheck {
|
|
43
59
|
type: RiddleProofProfileCheckType;
|
|
@@ -126,6 +142,7 @@ interface RiddleProofProfileEvidence {
|
|
|
126
142
|
page_errors: Array<{
|
|
127
143
|
message: string;
|
|
128
144
|
}>;
|
|
145
|
+
network_mocks?: Array<Record<string, JsonValue>>;
|
|
129
146
|
dom_summary?: Record<string, JsonValue>;
|
|
130
147
|
}
|
|
131
148
|
interface RiddleProofProfileCheckResult {
|
|
@@ -209,4 +226,4 @@ declare function buildRiddleProofProfileScript(profile: RiddleProofProfile): str
|
|
|
209
226
|
declare function collectRiddleProfileArtifactRefs(input: unknown): RiddleProofProfileArtifactRef[];
|
|
210
227
|
declare function extractRiddleProofProfileResult(input: unknown): RiddleProofProfileResult | undefined;
|
|
211
228
|
|
|
212
|
-
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 RiddleProofProfileBoundsOffender, 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, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
|
|
229
|
+
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 RiddleProofProfileBoundsOffender, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileNetworkMock, 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, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
|
package/dist/profile.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ 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
|
+
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "fill", "set_input_value", "local_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];
|
|
11
11
|
type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
|
|
@@ -20,6 +20,9 @@ interface RiddleProofProfileViewport {
|
|
|
20
20
|
interface RiddleProofProfileSetupAction {
|
|
21
21
|
type: RiddleProofProfileSetupActionType;
|
|
22
22
|
selector?: string;
|
|
23
|
+
key?: string;
|
|
24
|
+
value?: string;
|
|
25
|
+
value_json?: JsonValue;
|
|
23
26
|
text?: string;
|
|
24
27
|
pattern?: string;
|
|
25
28
|
flags?: string;
|
|
@@ -27,8 +30,20 @@ interface RiddleProofProfileSetupAction {
|
|
|
27
30
|
ms?: number;
|
|
28
31
|
timeout_ms?: number;
|
|
29
32
|
after_ms?: number;
|
|
33
|
+
reload?: boolean;
|
|
30
34
|
continue_on_failure?: boolean;
|
|
31
35
|
}
|
|
36
|
+
interface RiddleProofProfileNetworkMock {
|
|
37
|
+
label: string;
|
|
38
|
+
url: string;
|
|
39
|
+
method?: string;
|
|
40
|
+
status: number;
|
|
41
|
+
content_type?: string;
|
|
42
|
+
headers?: Record<string, string>;
|
|
43
|
+
body?: string;
|
|
44
|
+
body_json?: JsonValue;
|
|
45
|
+
required?: boolean;
|
|
46
|
+
}
|
|
32
47
|
interface RiddleProofProfileTarget {
|
|
33
48
|
url?: string;
|
|
34
49
|
route?: string;
|
|
@@ -38,6 +53,7 @@ interface RiddleProofProfileTarget {
|
|
|
38
53
|
wait_for_selector?: string;
|
|
39
54
|
wait_ms?: number;
|
|
40
55
|
setup_actions?: RiddleProofProfileSetupAction[];
|
|
56
|
+
network_mocks?: RiddleProofProfileNetworkMock[];
|
|
41
57
|
}
|
|
42
58
|
interface RiddleProofProfileCheck {
|
|
43
59
|
type: RiddleProofProfileCheckType;
|
|
@@ -126,6 +142,7 @@ interface RiddleProofProfileEvidence {
|
|
|
126
142
|
page_errors: Array<{
|
|
127
143
|
message: string;
|
|
128
144
|
}>;
|
|
145
|
+
network_mocks?: Array<Record<string, JsonValue>>;
|
|
129
146
|
dom_summary?: Record<string, JsonValue>;
|
|
130
147
|
}
|
|
131
148
|
interface RiddleProofProfileCheckResult {
|
|
@@ -209,4 +226,4 @@ declare function buildRiddleProofProfileScript(profile: RiddleProofProfile): str
|
|
|
209
226
|
declare function collectRiddleProfileArtifactRefs(input: unknown): RiddleProofProfileArtifactRef[];
|
|
210
227
|
declare function extractRiddleProofProfileResult(input: unknown): RiddleProofProfileResult | undefined;
|
|
211
228
|
|
|
212
|
-
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 RiddleProofProfileBoundsOffender, 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, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
|
|
229
|
+
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 RiddleProofProfileBoundsOffender, type RiddleProofProfileCheck, type RiddleProofProfileCheckResult, type RiddleProofProfileCheckType, type RiddleProofProfileEvidence, type RiddleProofProfileFailureAction, type RiddleProofProfileNetworkMock, 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, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult };
|
package/dist/profile.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
resolveRiddleProofProfileTimeoutSec,
|
|
20
20
|
slugifyRiddleProofProfileName,
|
|
21
21
|
summarizeRiddleProofProfileResult
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-NUGGW7NX.js";
|
|
23
23
|
export {
|
|
24
24
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
25
25
|
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;
|