@riddledc/riddle-proof 0.7.26 → 0.7.27

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.
@@ -119,6 +119,11 @@ function jsonRecord(value) {
119
119
  if (!isRecord(value)) return void 0;
120
120
  return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
121
121
  }
122
+ function stringRecord(value) {
123
+ if (!isRecord(value)) return void 0;
124
+ const entries = Object.entries(value).map(([key, child]) => [key, String(child)]).filter(([key]) => key.trim());
125
+ return entries.length ? Object.fromEntries(entries) : void 0;
126
+ }
122
127
  function toJsonValue(value) {
123
128
  if (value === null || value === void 0) return null;
124
129
  if (typeof value === "string" || typeof value === "boolean") return value;
@@ -190,6 +195,33 @@ function normalizeSetupActions(value) {
190
195
  if (!Array.isArray(value)) throw new Error("target.setup_actions must be an array.");
191
196
  return value.map(normalizeSetupAction);
192
197
  }
198
+ function normalizeNetworkMock(input, index) {
199
+ if (!isRecord(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
200
+ const url = stringValue(input.url) || stringValue(input.glob) || stringValue(input.pattern);
201
+ if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
202
+ const status = numberValue(input.status) ?? 200;
203
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
204
+ throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
205
+ }
206
+ const body = stringValue(input.body) ?? stringValue(input.body_text) ?? stringValue(input.bodyText);
207
+ const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
208
+ return {
209
+ label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
210
+ url,
211
+ method: stringValue(input.method)?.toUpperCase(),
212
+ status,
213
+ content_type: stringValue(input.content_type) || stringValue(input.contentType),
214
+ headers: stringRecord(input.headers),
215
+ body,
216
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
217
+ required: input.required === false ? false : true
218
+ };
219
+ }
220
+ function normalizeNetworkMocks(value) {
221
+ if (value === void 0) return void 0;
222
+ if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
223
+ return value.map(normalizeNetworkMock);
224
+ }
193
225
  function normalizeCheck(input, index) {
194
226
  if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
195
227
  const type = stringValue(input.type);
@@ -259,7 +291,8 @@ function normalizeRiddleProofProfile(input, options = {}) {
259
291
  timeout_sec: timeoutSecValue(targetInput.timeout_sec) ?? timeoutSecValue(targetInput.timeoutSec) ?? timeoutSecValue(targetInput.riddle_timeout_sec) ?? timeoutSecValue(targetInput.riddleTimeoutSec),
260
292
  wait_for_selector: stringValue(targetInput.wait_for_selector) || stringValue(targetInput.waitForSelector),
261
293
  wait_ms: numberValue(targetInput.wait_ms) ?? numberValue(targetInput.waitMs),
262
- setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions)
294
+ setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions),
295
+ network_mocks: normalizeNetworkMocks(targetInput.network_mocks ?? targetInput.networkMocks)
263
296
  },
264
297
  checks,
265
298
  artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
@@ -531,6 +564,50 @@ function assessSetupActionsFromEvidence(profile, evidence) {
531
564
  message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
532
565
  };
533
566
  }
567
+ function assessNetworkMocksFromEvidence(profile, evidence) {
568
+ const mocks = profile.target.network_mocks || [];
569
+ if (!mocks.length) return void 0;
570
+ const events = evidence.network_mocks || [];
571
+ const failed = [];
572
+ const requiredMocks = mocks.filter((mock) => mock.required !== false);
573
+ for (const mock of requiredMocks) {
574
+ const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
575
+ if (hits < 1) {
576
+ failed.push({
577
+ label: mock.label,
578
+ url: mock.url,
579
+ method: mock.method || null,
580
+ reason: "required_mock_not_hit"
581
+ });
582
+ }
583
+ }
584
+ for (const event of events) {
585
+ if (event.ok === false) {
586
+ failed.push({
587
+ label: event.label ?? null,
588
+ url: event.url ?? null,
589
+ method: event.method ?? null,
590
+ reason: event.reason ?? event.error ?? "mock_failed"
591
+ });
592
+ }
593
+ }
594
+ return {
595
+ type: "network_mocks_succeeded",
596
+ label: "network mocks succeeded",
597
+ status: failed.length ? "failed" : "passed",
598
+ evidence: {
599
+ mock_count: mocks.length,
600
+ required_count: requiredMocks.length,
601
+ hit_count: events.filter((event) => event.ok !== false).length,
602
+ hits_by_label: Object.fromEntries(mocks.map((mock) => [
603
+ mock.label,
604
+ events.filter((event) => event.label === mock.label && event.ok !== false).length
605
+ ])),
606
+ failed
607
+ },
608
+ message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
609
+ };
610
+ }
534
611
  function profileStatusFromEvidence(profile, evidence, checks) {
535
612
  if (!evidence) return "proof_insufficient";
536
613
  const viewports = evidence.viewports || [];
@@ -545,6 +622,7 @@ function profileStatusFromEvidence(profile, evidence, checks) {
545
622
  function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
546
623
  const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
547
624
  const checks = evidence ? [
625
+ assessNetworkMocksFromEvidence(profile, evidence),
548
626
  assessSetupActionsFromEvidence(profile, evidence),
549
627
  ...profile.checks.map((check) => assessCheckFromEvidence(check, evidence))
550
628
  ].filter((check) => Boolean(check)) : [];
@@ -761,6 +839,49 @@ function horizontalBoundsOverflowPx(value) {
761
839
  function assessProfile(profile, evidence) {
762
840
  const checks = [];
763
841
  const viewports = evidence.viewports || [];
842
+ if (profile.target && Array.isArray(profile.target.network_mocks) && profile.target.network_mocks.length) {
843
+ const events = evidence.network_mocks || [];
844
+ const requiredMocks = profile.target.network_mocks.filter((mock) => mock && mock.required !== false);
845
+ const failed = [];
846
+ for (const mock of requiredMocks) {
847
+ const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
848
+ if (hits < 1) {
849
+ failed.push({
850
+ label: mock.label,
851
+ url: mock.url,
852
+ method: mock.method || null,
853
+ reason: "required_mock_not_hit",
854
+ });
855
+ }
856
+ }
857
+ for (const event of events) {
858
+ if (event && event.ok === false) {
859
+ failed.push({
860
+ label: event.label || null,
861
+ url: event.url || null,
862
+ method: event.method || null,
863
+ reason: event.reason || event.error || "mock_failed",
864
+ });
865
+ }
866
+ }
867
+ const hitsByLabel = {};
868
+ for (const mock of profile.target.network_mocks) {
869
+ hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
870
+ }
871
+ checks.push({
872
+ type: "network_mocks_succeeded",
873
+ label: "network mocks succeeded",
874
+ status: failed.length ? "failed" : "passed",
875
+ evidence: {
876
+ mock_count: profile.target.network_mocks.length,
877
+ required_count: requiredMocks.length,
878
+ hit_count: events.filter((event) => event && event.ok !== false).length,
879
+ hits_by_label: hitsByLabel,
880
+ failed,
881
+ },
882
+ message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
883
+ });
884
+ }
764
885
  if (profile.target && Array.isArray(profile.target.setup_actions) && profile.target.setup_actions.length) {
765
886
  const actionCount = profile.target.setup_actions.length;
766
887
  const failed = [];
@@ -950,6 +1071,7 @@ const profileSlug = ${serializableSlug};
950
1071
  const capturedAt = new Date().toISOString();
951
1072
  const consoleEvents = [];
952
1073
  const pageErrors = [];
1074
+ const networkMockEvents = [];
953
1075
  page.on("console", (message) => {
954
1076
  const type = message.type();
955
1077
  if (type === "error" || type === "warning" || type === "assert") {
@@ -996,6 +1118,49 @@ function compactSetupResultText(value) {
996
1118
  async function setupLocatorVisible(locator, index) {
997
1119
  return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
998
1120
  }
1121
+ async function registerNetworkMocks(mocks) {
1122
+ for (const mock of mocks || []) {
1123
+ await page.route(mock.url, async (route) => {
1124
+ const request = route.request();
1125
+ const method = request.method ? request.method() : "";
1126
+ if (mock.method && method.toUpperCase() !== String(mock.method).toUpperCase()) {
1127
+ await route.continue();
1128
+ return;
1129
+ }
1130
+ try {
1131
+ const headers = { ...(mock.headers || {}) };
1132
+ let body = mock.body || "";
1133
+ let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
1134
+ if (mock.body_json !== undefined) {
1135
+ body = JSON.stringify(mock.body_json);
1136
+ contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
1137
+ }
1138
+ networkMockEvents.push({
1139
+ ok: true,
1140
+ label: mock.label,
1141
+ url: request.url(),
1142
+ method,
1143
+ status: mock.status || 200,
1144
+ });
1145
+ await route.fulfill({
1146
+ status: mock.status || 200,
1147
+ headers,
1148
+ contentType,
1149
+ body,
1150
+ });
1151
+ } catch (error) {
1152
+ networkMockEvents.push({
1153
+ ok: false,
1154
+ label: mock.label,
1155
+ url: request.url(),
1156
+ method,
1157
+ error: String(error && error.message ? error.message : error).slice(0, 1000),
1158
+ });
1159
+ throw error;
1160
+ }
1161
+ });
1162
+ }
1163
+ }
999
1164
  async function executeSetupAction(action, ordinal) {
1000
1165
  const type = setupActionType(action);
1001
1166
  const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
@@ -1257,6 +1422,7 @@ function buildProfileEvidence(currentViewports) {
1257
1422
  fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
1258
1423
  },
1259
1424
  page_errors: pageErrors,
1425
+ network_mocks: networkMockEvents.slice(),
1260
1426
  dom_summary: {
1261
1427
  expected_viewport_count: expectedViewportCount,
1262
1428
  viewport_count: currentViewports.length,
@@ -1266,6 +1432,8 @@ function buildProfileEvidence(currentViewports) {
1266
1432
  overflow_px: currentViewports.map((viewport) => viewport.overflow_px),
1267
1433
  bounds_overflow_px: currentViewports.map((viewport) => viewport.bounds_overflow_px),
1268
1434
  overflow_offender_counts: currentViewports.map((viewport) => (viewport.overflow_offenders || []).length),
1435
+ network_mock_count: (profile.target.network_mocks || []).length,
1436
+ network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
1269
1437
  },
1270
1438
  };
1271
1439
  }
@@ -1279,6 +1447,9 @@ async function saveProfileArtifacts(currentViewports) {
1279
1447
  }
1280
1448
  return result;
1281
1449
  }
1450
+ await registerNetworkMocks(profile.target.network_mocks || []);
1451
+ consoleEvents.length = 0;
1452
+ pageErrors.length = 0;
1282
1453
  let result = await saveProfileArtifacts(viewports);
1283
1454
  for (const viewport of profile.target.viewports || []) {
1284
1455
  viewports.push(await captureViewport(viewport));
package/dist/cli.cjs CHANGED
@@ -6992,6 +6992,11 @@ function jsonRecord(value) {
6992
6992
  if (!isRecord(value)) return void 0;
6993
6993
  return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
6994
6994
  }
6995
+ function stringRecord(value) {
6996
+ if (!isRecord(value)) return void 0;
6997
+ const entries = Object.entries(value).map(([key, child]) => [key, String(child)]).filter(([key]) => key.trim());
6998
+ return entries.length ? Object.fromEntries(entries) : void 0;
6999
+ }
6995
7000
  function toJsonValue(value) {
6996
7001
  if (value === null || value === void 0) return null;
6997
7002
  if (typeof value === "string" || typeof value === "boolean") return value;
@@ -7063,6 +7068,33 @@ function normalizeSetupActions(value) {
7063
7068
  if (!Array.isArray(value)) throw new Error("target.setup_actions must be an array.");
7064
7069
  return value.map(normalizeSetupAction);
7065
7070
  }
7071
+ function normalizeNetworkMock(input, index) {
7072
+ if (!isRecord(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
7073
+ const url = stringValue2(input.url) || stringValue2(input.glob) || stringValue2(input.pattern);
7074
+ if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
7075
+ const status = numberValue(input.status) ?? 200;
7076
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
7077
+ throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
7078
+ }
7079
+ const body = stringValue2(input.body) ?? stringValue2(input.body_text) ?? stringValue2(input.bodyText);
7080
+ const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
7081
+ return {
7082
+ label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
7083
+ url,
7084
+ method: stringValue2(input.method)?.toUpperCase(),
7085
+ status,
7086
+ content_type: stringValue2(input.content_type) || stringValue2(input.contentType),
7087
+ headers: stringRecord(input.headers),
7088
+ body,
7089
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
7090
+ required: input.required === false ? false : true
7091
+ };
7092
+ }
7093
+ function normalizeNetworkMocks(value) {
7094
+ if (value === void 0) return void 0;
7095
+ if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
7096
+ return value.map(normalizeNetworkMock);
7097
+ }
7066
7098
  function normalizeCheck(input, index) {
7067
7099
  if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
7068
7100
  const type = stringValue2(input.type);
@@ -7132,7 +7164,8 @@ function normalizeRiddleProofProfile(input, options = {}) {
7132
7164
  timeout_sec: timeoutSecValue(targetInput.timeout_sec) ?? timeoutSecValue(targetInput.timeoutSec) ?? timeoutSecValue(targetInput.riddle_timeout_sec) ?? timeoutSecValue(targetInput.riddleTimeoutSec),
7133
7165
  wait_for_selector: stringValue2(targetInput.wait_for_selector) || stringValue2(targetInput.waitForSelector),
7134
7166
  wait_ms: numberValue(targetInput.wait_ms) ?? numberValue(targetInput.waitMs),
7135
- setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions)
7167
+ setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions),
7168
+ network_mocks: normalizeNetworkMocks(targetInput.network_mocks ?? targetInput.networkMocks)
7136
7169
  },
7137
7170
  checks,
7138
7171
  artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
@@ -7404,6 +7437,50 @@ function assessSetupActionsFromEvidence(profile, evidence) {
7404
7437
  message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
7405
7438
  };
7406
7439
  }
7440
+ function assessNetworkMocksFromEvidence(profile, evidence) {
7441
+ const mocks = profile.target.network_mocks || [];
7442
+ if (!mocks.length) return void 0;
7443
+ const events = evidence.network_mocks || [];
7444
+ const failed = [];
7445
+ const requiredMocks = mocks.filter((mock) => mock.required !== false);
7446
+ for (const mock of requiredMocks) {
7447
+ const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
7448
+ if (hits < 1) {
7449
+ failed.push({
7450
+ label: mock.label,
7451
+ url: mock.url,
7452
+ method: mock.method || null,
7453
+ reason: "required_mock_not_hit"
7454
+ });
7455
+ }
7456
+ }
7457
+ for (const event of events) {
7458
+ if (event.ok === false) {
7459
+ failed.push({
7460
+ label: event.label ?? null,
7461
+ url: event.url ?? null,
7462
+ method: event.method ?? null,
7463
+ reason: event.reason ?? event.error ?? "mock_failed"
7464
+ });
7465
+ }
7466
+ }
7467
+ return {
7468
+ type: "network_mocks_succeeded",
7469
+ label: "network mocks succeeded",
7470
+ status: failed.length ? "failed" : "passed",
7471
+ evidence: {
7472
+ mock_count: mocks.length,
7473
+ required_count: requiredMocks.length,
7474
+ hit_count: events.filter((event) => event.ok !== false).length,
7475
+ hits_by_label: Object.fromEntries(mocks.map((mock) => [
7476
+ mock.label,
7477
+ events.filter((event) => event.label === mock.label && event.ok !== false).length
7478
+ ])),
7479
+ failed
7480
+ },
7481
+ message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
7482
+ };
7483
+ }
7407
7484
  function profileStatusFromEvidence(profile, evidence, checks) {
7408
7485
  if (!evidence) return "proof_insufficient";
7409
7486
  const viewports = evidence.viewports || [];
@@ -7418,6 +7495,7 @@ function profileStatusFromEvidence(profile, evidence, checks) {
7418
7495
  function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
7419
7496
  const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
7420
7497
  const checks = evidence ? [
7498
+ assessNetworkMocksFromEvidence(profile, evidence),
7421
7499
  assessSetupActionsFromEvidence(profile, evidence),
7422
7500
  ...profile.checks.map((check) => assessCheckFromEvidence(check, evidence))
7423
7501
  ].filter((check) => Boolean(check)) : [];
@@ -7618,6 +7696,49 @@ function horizontalBoundsOverflowPx(value) {
7618
7696
  function assessProfile(profile, evidence) {
7619
7697
  const checks = [];
7620
7698
  const viewports = evidence.viewports || [];
7699
+ if (profile.target && Array.isArray(profile.target.network_mocks) && profile.target.network_mocks.length) {
7700
+ const events = evidence.network_mocks || [];
7701
+ const requiredMocks = profile.target.network_mocks.filter((mock) => mock && mock.required !== false);
7702
+ const failed = [];
7703
+ for (const mock of requiredMocks) {
7704
+ const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
7705
+ if (hits < 1) {
7706
+ failed.push({
7707
+ label: mock.label,
7708
+ url: mock.url,
7709
+ method: mock.method || null,
7710
+ reason: "required_mock_not_hit",
7711
+ });
7712
+ }
7713
+ }
7714
+ for (const event of events) {
7715
+ if (event && event.ok === false) {
7716
+ failed.push({
7717
+ label: event.label || null,
7718
+ url: event.url || null,
7719
+ method: event.method || null,
7720
+ reason: event.reason || event.error || "mock_failed",
7721
+ });
7722
+ }
7723
+ }
7724
+ const hitsByLabel = {};
7725
+ for (const mock of profile.target.network_mocks) {
7726
+ hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
7727
+ }
7728
+ checks.push({
7729
+ type: "network_mocks_succeeded",
7730
+ label: "network mocks succeeded",
7731
+ status: failed.length ? "failed" : "passed",
7732
+ evidence: {
7733
+ mock_count: profile.target.network_mocks.length,
7734
+ required_count: requiredMocks.length,
7735
+ hit_count: events.filter((event) => event && event.ok !== false).length,
7736
+ hits_by_label: hitsByLabel,
7737
+ failed,
7738
+ },
7739
+ message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
7740
+ });
7741
+ }
7621
7742
  if (profile.target && Array.isArray(profile.target.setup_actions) && profile.target.setup_actions.length) {
7622
7743
  const actionCount = profile.target.setup_actions.length;
7623
7744
  const failed = [];
@@ -7807,6 +7928,7 @@ const profileSlug = ${serializableSlug};
7807
7928
  const capturedAt = new Date().toISOString();
7808
7929
  const consoleEvents = [];
7809
7930
  const pageErrors = [];
7931
+ const networkMockEvents = [];
7810
7932
  page.on("console", (message) => {
7811
7933
  const type = message.type();
7812
7934
  if (type === "error" || type === "warning" || type === "assert") {
@@ -7853,6 +7975,49 @@ function compactSetupResultText(value) {
7853
7975
  async function setupLocatorVisible(locator, index) {
7854
7976
  return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
7855
7977
  }
7978
+ async function registerNetworkMocks(mocks) {
7979
+ for (const mock of mocks || []) {
7980
+ await page.route(mock.url, async (route) => {
7981
+ const request = route.request();
7982
+ const method = request.method ? request.method() : "";
7983
+ if (mock.method && method.toUpperCase() !== String(mock.method).toUpperCase()) {
7984
+ await route.continue();
7985
+ return;
7986
+ }
7987
+ try {
7988
+ const headers = { ...(mock.headers || {}) };
7989
+ let body = mock.body || "";
7990
+ let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
7991
+ if (mock.body_json !== undefined) {
7992
+ body = JSON.stringify(mock.body_json);
7993
+ contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
7994
+ }
7995
+ networkMockEvents.push({
7996
+ ok: true,
7997
+ label: mock.label,
7998
+ url: request.url(),
7999
+ method,
8000
+ status: mock.status || 200,
8001
+ });
8002
+ await route.fulfill({
8003
+ status: mock.status || 200,
8004
+ headers,
8005
+ contentType,
8006
+ body,
8007
+ });
8008
+ } catch (error) {
8009
+ networkMockEvents.push({
8010
+ ok: false,
8011
+ label: mock.label,
8012
+ url: request.url(),
8013
+ method,
8014
+ error: String(error && error.message ? error.message : error).slice(0, 1000),
8015
+ });
8016
+ throw error;
8017
+ }
8018
+ });
8019
+ }
8020
+ }
7856
8021
  async function executeSetupAction(action, ordinal) {
7857
8022
  const type = setupActionType(action);
7858
8023
  const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
@@ -8114,6 +8279,7 @@ function buildProfileEvidence(currentViewports) {
8114
8279
  fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
8115
8280
  },
8116
8281
  page_errors: pageErrors,
8282
+ network_mocks: networkMockEvents.slice(),
8117
8283
  dom_summary: {
8118
8284
  expected_viewport_count: expectedViewportCount,
8119
8285
  viewport_count: currentViewports.length,
@@ -8123,6 +8289,8 @@ function buildProfileEvidence(currentViewports) {
8123
8289
  overflow_px: currentViewports.map((viewport) => viewport.overflow_px),
8124
8290
  bounds_overflow_px: currentViewports.map((viewport) => viewport.bounds_overflow_px),
8125
8291
  overflow_offender_counts: currentViewports.map((viewport) => (viewport.overflow_offenders || []).length),
8292
+ network_mock_count: (profile.target.network_mocks || []).length,
8293
+ network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
8126
8294
  },
8127
8295
  };
8128
8296
  }
@@ -8136,6 +8304,9 @@ async function saveProfileArtifacts(currentViewports) {
8136
8304
  }
8137
8305
  return result;
8138
8306
  }
8307
+ await registerNetworkMocks(profile.target.network_mocks || []);
8308
+ consoleEvents.length = 0;
8309
+ pageErrors.length = 0;
8139
8310
  let result = await saveProfileArtifacts(viewports);
8140
8311
  for (const viewport of profile.target.viewports || []) {
8141
8312
  viewports.push(await captureViewport(viewport));
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-SDSBS64X.js";
13
+ } from "./chunk-FUWINYNX.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport
package/dist/index.cjs CHANGED
@@ -8833,6 +8833,11 @@ function jsonRecord(value) {
8833
8833
  if (!isRecord2(value)) return void 0;
8834
8834
  return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
8835
8835
  }
8836
+ function stringRecord(value) {
8837
+ if (!isRecord2(value)) return void 0;
8838
+ const entries = Object.entries(value).map(([key, child]) => [key, String(child)]).filter(([key]) => key.trim());
8839
+ return entries.length ? Object.fromEntries(entries) : void 0;
8840
+ }
8836
8841
  function toJsonValue(value) {
8837
8842
  if (value === null || value === void 0) return null;
8838
8843
  if (typeof value === "string" || typeof value === "boolean") return value;
@@ -8904,6 +8909,33 @@ function normalizeSetupActions(value) {
8904
8909
  if (!Array.isArray(value)) throw new Error("target.setup_actions must be an array.");
8905
8910
  return value.map(normalizeSetupAction);
8906
8911
  }
8912
+ function normalizeNetworkMock(input, index) {
8913
+ if (!isRecord2(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
8914
+ const url = stringValue5(input.url) || stringValue5(input.glob) || stringValue5(input.pattern);
8915
+ if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
8916
+ const status = numberValue3(input.status) ?? 200;
8917
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
8918
+ throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
8919
+ }
8920
+ const body = stringValue5(input.body) ?? stringValue5(input.body_text) ?? stringValue5(input.bodyText);
8921
+ const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
8922
+ return {
8923
+ label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
8924
+ url,
8925
+ method: stringValue5(input.method)?.toUpperCase(),
8926
+ status,
8927
+ content_type: stringValue5(input.content_type) || stringValue5(input.contentType),
8928
+ headers: stringRecord(input.headers),
8929
+ body,
8930
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
8931
+ required: input.required === false ? false : true
8932
+ };
8933
+ }
8934
+ function normalizeNetworkMocks(value) {
8935
+ if (value === void 0) return void 0;
8936
+ if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
8937
+ return value.map(normalizeNetworkMock);
8938
+ }
8907
8939
  function normalizeCheck(input, index) {
8908
8940
  if (!isRecord2(input)) throw new Error(`checks[${index}] must be an object.`);
8909
8941
  const type = stringValue5(input.type);
@@ -8973,7 +9005,8 @@ function normalizeRiddleProofProfile(input, options = {}) {
8973
9005
  timeout_sec: timeoutSecValue(targetInput.timeout_sec) ?? timeoutSecValue(targetInput.timeoutSec) ?? timeoutSecValue(targetInput.riddle_timeout_sec) ?? timeoutSecValue(targetInput.riddleTimeoutSec),
8974
9006
  wait_for_selector: stringValue5(targetInput.wait_for_selector) || stringValue5(targetInput.waitForSelector),
8975
9007
  wait_ms: numberValue3(targetInput.wait_ms) ?? numberValue3(targetInput.waitMs),
8976
- setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions)
9008
+ setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions),
9009
+ network_mocks: normalizeNetworkMocks(targetInput.network_mocks ?? targetInput.networkMocks)
8977
9010
  },
8978
9011
  checks,
8979
9012
  artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
@@ -9245,6 +9278,50 @@ function assessSetupActionsFromEvidence(profile, evidence) {
9245
9278
  message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
9246
9279
  };
9247
9280
  }
9281
+ function assessNetworkMocksFromEvidence(profile, evidence) {
9282
+ const mocks = profile.target.network_mocks || [];
9283
+ if (!mocks.length) return void 0;
9284
+ const events = evidence.network_mocks || [];
9285
+ const failed = [];
9286
+ const requiredMocks = mocks.filter((mock) => mock.required !== false);
9287
+ for (const mock of requiredMocks) {
9288
+ const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
9289
+ if (hits < 1) {
9290
+ failed.push({
9291
+ label: mock.label,
9292
+ url: mock.url,
9293
+ method: mock.method || null,
9294
+ reason: "required_mock_not_hit"
9295
+ });
9296
+ }
9297
+ }
9298
+ for (const event of events) {
9299
+ if (event.ok === false) {
9300
+ failed.push({
9301
+ label: event.label ?? null,
9302
+ url: event.url ?? null,
9303
+ method: event.method ?? null,
9304
+ reason: event.reason ?? event.error ?? "mock_failed"
9305
+ });
9306
+ }
9307
+ }
9308
+ return {
9309
+ type: "network_mocks_succeeded",
9310
+ label: "network mocks succeeded",
9311
+ status: failed.length ? "failed" : "passed",
9312
+ evidence: {
9313
+ mock_count: mocks.length,
9314
+ required_count: requiredMocks.length,
9315
+ hit_count: events.filter((event) => event.ok !== false).length,
9316
+ hits_by_label: Object.fromEntries(mocks.map((mock) => [
9317
+ mock.label,
9318
+ events.filter((event) => event.label === mock.label && event.ok !== false).length
9319
+ ])),
9320
+ failed
9321
+ },
9322
+ message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
9323
+ };
9324
+ }
9248
9325
  function profileStatusFromEvidence(profile, evidence, checks) {
9249
9326
  if (!evidence) return "proof_insufficient";
9250
9327
  const viewports = evidence.viewports || [];
@@ -9259,6 +9336,7 @@ function profileStatusFromEvidence(profile, evidence, checks) {
9259
9336
  function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
9260
9337
  const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
9261
9338
  const checks = evidence ? [
9339
+ assessNetworkMocksFromEvidence(profile, evidence),
9262
9340
  assessSetupActionsFromEvidence(profile, evidence),
9263
9341
  ...profile.checks.map((check) => assessCheckFromEvidence(check, evidence))
9264
9342
  ].filter((check) => Boolean(check)) : [];
@@ -9475,6 +9553,49 @@ function horizontalBoundsOverflowPx(value) {
9475
9553
  function assessProfile(profile, evidence) {
9476
9554
  const checks = [];
9477
9555
  const viewports = evidence.viewports || [];
9556
+ if (profile.target && Array.isArray(profile.target.network_mocks) && profile.target.network_mocks.length) {
9557
+ const events = evidence.network_mocks || [];
9558
+ const requiredMocks = profile.target.network_mocks.filter((mock) => mock && mock.required !== false);
9559
+ const failed = [];
9560
+ for (const mock of requiredMocks) {
9561
+ const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
9562
+ if (hits < 1) {
9563
+ failed.push({
9564
+ label: mock.label,
9565
+ url: mock.url,
9566
+ method: mock.method || null,
9567
+ reason: "required_mock_not_hit",
9568
+ });
9569
+ }
9570
+ }
9571
+ for (const event of events) {
9572
+ if (event && event.ok === false) {
9573
+ failed.push({
9574
+ label: event.label || null,
9575
+ url: event.url || null,
9576
+ method: event.method || null,
9577
+ reason: event.reason || event.error || "mock_failed",
9578
+ });
9579
+ }
9580
+ }
9581
+ const hitsByLabel = {};
9582
+ for (const mock of profile.target.network_mocks) {
9583
+ hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
9584
+ }
9585
+ checks.push({
9586
+ type: "network_mocks_succeeded",
9587
+ label: "network mocks succeeded",
9588
+ status: failed.length ? "failed" : "passed",
9589
+ evidence: {
9590
+ mock_count: profile.target.network_mocks.length,
9591
+ required_count: requiredMocks.length,
9592
+ hit_count: events.filter((event) => event && event.ok !== false).length,
9593
+ hits_by_label: hitsByLabel,
9594
+ failed,
9595
+ },
9596
+ message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
9597
+ });
9598
+ }
9478
9599
  if (profile.target && Array.isArray(profile.target.setup_actions) && profile.target.setup_actions.length) {
9479
9600
  const actionCount = profile.target.setup_actions.length;
9480
9601
  const failed = [];
@@ -9664,6 +9785,7 @@ const profileSlug = ${serializableSlug};
9664
9785
  const capturedAt = new Date().toISOString();
9665
9786
  const consoleEvents = [];
9666
9787
  const pageErrors = [];
9788
+ const networkMockEvents = [];
9667
9789
  page.on("console", (message) => {
9668
9790
  const type = message.type();
9669
9791
  if (type === "error" || type === "warning" || type === "assert") {
@@ -9710,6 +9832,49 @@ function compactSetupResultText(value) {
9710
9832
  async function setupLocatorVisible(locator, index) {
9711
9833
  return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
9712
9834
  }
9835
+ async function registerNetworkMocks(mocks) {
9836
+ for (const mock of mocks || []) {
9837
+ await page.route(mock.url, async (route) => {
9838
+ const request = route.request();
9839
+ const method = request.method ? request.method() : "";
9840
+ if (mock.method && method.toUpperCase() !== String(mock.method).toUpperCase()) {
9841
+ await route.continue();
9842
+ return;
9843
+ }
9844
+ try {
9845
+ const headers = { ...(mock.headers || {}) };
9846
+ let body = mock.body || "";
9847
+ let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
9848
+ if (mock.body_json !== undefined) {
9849
+ body = JSON.stringify(mock.body_json);
9850
+ contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
9851
+ }
9852
+ networkMockEvents.push({
9853
+ ok: true,
9854
+ label: mock.label,
9855
+ url: request.url(),
9856
+ method,
9857
+ status: mock.status || 200,
9858
+ });
9859
+ await route.fulfill({
9860
+ status: mock.status || 200,
9861
+ headers,
9862
+ contentType,
9863
+ body,
9864
+ });
9865
+ } catch (error) {
9866
+ networkMockEvents.push({
9867
+ ok: false,
9868
+ label: mock.label,
9869
+ url: request.url(),
9870
+ method,
9871
+ error: String(error && error.message ? error.message : error).slice(0, 1000),
9872
+ });
9873
+ throw error;
9874
+ }
9875
+ });
9876
+ }
9877
+ }
9713
9878
  async function executeSetupAction(action, ordinal) {
9714
9879
  const type = setupActionType(action);
9715
9880
  const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
@@ -9971,6 +10136,7 @@ function buildProfileEvidence(currentViewports) {
9971
10136
  fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
9972
10137
  },
9973
10138
  page_errors: pageErrors,
10139
+ network_mocks: networkMockEvents.slice(),
9974
10140
  dom_summary: {
9975
10141
  expected_viewport_count: expectedViewportCount,
9976
10142
  viewport_count: currentViewports.length,
@@ -9980,6 +10146,8 @@ function buildProfileEvidence(currentViewports) {
9980
10146
  overflow_px: currentViewports.map((viewport) => viewport.overflow_px),
9981
10147
  bounds_overflow_px: currentViewports.map((viewport) => viewport.bounds_overflow_px),
9982
10148
  overflow_offender_counts: currentViewports.map((viewport) => (viewport.overflow_offenders || []).length),
10149
+ network_mock_count: (profile.target.network_mocks || []).length,
10150
+ network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
9983
10151
  },
9984
10152
  };
9985
10153
  }
@@ -9993,6 +10161,9 @@ async function saveProfileArtifacts(currentViewports) {
9993
10161
  }
9994
10162
  return result;
9995
10163
  }
10164
+ await registerNetworkMocks(profile.target.network_mocks || []);
10165
+ consoleEvents.length = 0;
10166
+ pageErrors.length = 0;
9996
10167
  let result = await saveProfileArtifacts(viewports);
9997
10168
  for (const viewport of profile.target.viewports || []) {
9998
10169
  viewports.push(await captureViewport(viewport));
package/dist/index.d.cts CHANGED
@@ -10,5 +10,5 @@ export { CreateCaptureDiagnosticInput, DEFAULT_DIAGNOSTIC_ARRAY_LIMIT, DEFAULT_D
10
10
  export { BuildVisualProofSessionInput, RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION, RIDDLE_PROOF_VISUAL_SESSION_VERSION, VisualProofSessionMismatch, buildVisualProofSession, compareVisualProofSessionFingerprint, parseVisualProofSession, visualSessionFingerprint, visualSessionFingerprintBasis } from './proof-session.cjs';
11
11
  export { AssessPlayabilityOptions, RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION, RIDDLE_PROOF_PLAYABILITY_VERSION, RiddleProofPlayabilityAssessment, RiddleProofPlayabilityEvidence, assessPlayabilityEvidence, extractPlayabilityEvidence, isRiddleProofPlayabilityMode } from './playability.cjs';
12
12
  export { AssessBasicGameplayOptions, AttachBasicGameplayArtifactOptions, BASIC_GAMEPLAY_ACTION_TYPES, BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES, BasicGameplayActionResult, BasicGameplayActionType, BasicGameplayArtifactResolution, BasicGameplayAssessmentSummary, BasicGameplayBoundsOffender, BasicGameplayCanvasState, BasicGameplayCatchRecord, BasicGameplayChangeSummary, BasicGameplayFailureCode, BasicGameplayFixReference, BasicGameplayMetric, BasicGameplayMobileEvidence, BasicGameplayProgressCheckType, BasicGameplayProgressionCheck, BasicGameplayProofArtifact, BasicGameplayResponsiveViewportEvidence, BasicGameplayRouteReference, BasicGameplaySnapshot, BasicGameplaySuiteFailure, BasicGameplayWarningCode, CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, RiddleProofBasicGameplayAssessment, RiddleProofBasicGameplayCatchSummary, RiddleProofBasicGameplayEvidence, RiddleProofBasicGameplayRouteAssessment, RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayProgressionCheck, assessBasicGameplayProgressionChecks, assessBasicGameplayRoute, attachBasicGameplayArtifactScreenshotHashes, augmentBasicGameplayAssessmentWithProgressionChecks, compactBasicGameplayText, createBasicGameplayCatchRecords, createBasicGameplayCatchSummary, extractBasicGameplayEvidence, resolveBasicGameplayProgressionCheckWithArtifactScreenshots, sanitizeBasicGameplayJsonString } from './basic-gameplay.cjs';
13
- export { 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, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.cjs';
13
+ export { 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, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileNetworkMock, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.cjs';
14
14
  export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleClientConfig, RiddleFetch, RiddlePollJobOptions, RiddlePollJobResult, RiddlePollProgressSnapshot, RiddlePollSummary, RiddlePreviewDeployResult, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.cjs';
package/dist/index.d.ts CHANGED
@@ -10,5 +10,5 @@ export { CreateCaptureDiagnosticInput, DEFAULT_DIAGNOSTIC_ARRAY_LIMIT, DEFAULT_D
10
10
  export { BuildVisualProofSessionInput, RIDDLE_PROOF_VISUAL_SESSION_FINGERPRINT_VERSION, RIDDLE_PROOF_VISUAL_SESSION_VERSION, VisualProofSessionMismatch, buildVisualProofSession, compareVisualProofSessionFingerprint, parseVisualProofSession, visualSessionFingerprint, visualSessionFingerprintBasis } from './proof-session.js';
11
11
  export { AssessPlayabilityOptions, RIDDLE_PROOF_PLAYABILITY_ASSESSMENT_VERSION, RIDDLE_PROOF_PLAYABILITY_VERSION, RiddleProofPlayabilityAssessment, RiddleProofPlayabilityEvidence, assessPlayabilityEvidence, extractPlayabilityEvidence, isRiddleProofPlayabilityMode } from './playability.js';
12
12
  export { AssessBasicGameplayOptions, AttachBasicGameplayArtifactOptions, BASIC_GAMEPLAY_ACTION_TYPES, BASIC_GAMEPLAY_PROGRESS_CHECK_TYPES, BasicGameplayActionResult, BasicGameplayActionType, BasicGameplayArtifactResolution, BasicGameplayAssessmentSummary, BasicGameplayBoundsOffender, BasicGameplayCanvasState, BasicGameplayCatchRecord, BasicGameplayChangeSummary, BasicGameplayFailureCode, BasicGameplayFixReference, BasicGameplayMetric, BasicGameplayMobileEvidence, BasicGameplayProgressCheckType, BasicGameplayProgressionCheck, BasicGameplayProofArtifact, BasicGameplayResponsiveViewportEvidence, BasicGameplayRouteReference, BasicGameplaySnapshot, BasicGameplaySuiteFailure, BasicGameplayWarningCode, CreateBasicGameplayCatchSummaryInput, RIDDLE_PROOF_BASIC_GAMEPLAY_ASSESSMENT_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_CATCH_VERSION, RIDDLE_PROOF_BASIC_GAMEPLAY_VERSION, RiddleProofBasicGameplayAssessment, RiddleProofBasicGameplayCatchSummary, RiddleProofBasicGameplayEvidence, RiddleProofBasicGameplayRouteAssessment, RiddleProofBasicGameplayRouteEvidence, assessBasicGameplayEvidence, assessBasicGameplayProgressionCheck, assessBasicGameplayProgressionChecks, assessBasicGameplayRoute, attachBasicGameplayArtifactScreenshotHashes, augmentBasicGameplayAssessmentWithProgressionChecks, compactBasicGameplayText, createBasicGameplayCatchRecords, createBasicGameplayCatchSummary, extractBasicGameplayEvidence, resolveBasicGameplayProgressionCheckWithArtifactScreenshots, sanitizeBasicGameplayJsonString } from './basic-gameplay.js';
13
- export { 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, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.js';
13
+ export { 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, RiddleProofProfile, RiddleProofProfileArtifactRef, RiddleProofProfileBaselinePolicy, RiddleProofProfileBoundsOffender, RiddleProofProfileCheck, RiddleProofProfileCheckResult, RiddleProofProfileCheckType, RiddleProofProfileEvidence, RiddleProofProfileFailureAction, RiddleProofProfileNetworkMock, RiddleProofProfileResult, RiddleProofProfileRouteEvidence, RiddleProofProfileRunner, RiddleProofProfileSetupAction, RiddleProofProfileSetupActionType, RiddleProofProfileStatus, RiddleProofProfileTarget, RiddleProofProfileViewport, RiddleProofProfileViewportEvidence, assessRiddleProofProfileEvidence, buildRiddleProofProfileScript, collectRiddleProfileArtifactRefs, createRiddleProofProfileConfigurationError, createRiddleProofProfileEnvironmentBlockedResult, createRiddleProofProfileInsufficientResult, extractRiddleProofProfileResult, normalizeRiddleProofProfile, profileStatusExitCode, resolveRiddleProofProfileRouteUrl, resolveRiddleProofProfileTargetUrl, resolveRiddleProofProfileTimeoutSec, slugifyRiddleProofProfileName, summarizeRiddleProofProfileResult } from './profile.js';
14
14
  export { DEFAULT_RIDDLE_API_BASE_URL, DEFAULT_RIDDLE_API_KEY_FILE, RiddleApiError, RiddleClientConfig, RiddleFetch, RiddlePollJobOptions, RiddlePollJobResult, RiddlePollProgressSnapshot, RiddlePollSummary, RiddlePreviewDeployResult, RiddleRunScriptInput, RiddleServerPreviewInput, RiddleServerPreviewResult, createRiddleApiClient, deployRiddleStaticPreview, isTerminalRiddleJobStatus, parseRiddleViewport, pollRiddleJob, resolveRiddleApiKey, riddleRequestJson, runRiddleScript, runRiddleServerPreview } from './riddle-client.js';
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-SDSBS64X.js";
61
+ } from "./chunk-FUWINYNX.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -162,6 +162,11 @@ function jsonRecord(value) {
162
162
  if (!isRecord(value)) return void 0;
163
163
  return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
164
164
  }
165
+ function stringRecord(value) {
166
+ if (!isRecord(value)) return void 0;
167
+ const entries = Object.entries(value).map(([key, child]) => [key, String(child)]).filter(([key]) => key.trim());
168
+ return entries.length ? Object.fromEntries(entries) : void 0;
169
+ }
165
170
  function toJsonValue(value) {
166
171
  if (value === null || value === void 0) return null;
167
172
  if (typeof value === "string" || typeof value === "boolean") return value;
@@ -233,6 +238,33 @@ function normalizeSetupActions(value) {
233
238
  if (!Array.isArray(value)) throw new Error("target.setup_actions must be an array.");
234
239
  return value.map(normalizeSetupAction);
235
240
  }
241
+ function normalizeNetworkMock(input, index) {
242
+ if (!isRecord(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
243
+ const url = stringValue(input.url) || stringValue(input.glob) || stringValue(input.pattern);
244
+ if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
245
+ const status = numberValue(input.status) ?? 200;
246
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
247
+ throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
248
+ }
249
+ const body = stringValue(input.body) ?? stringValue(input.body_text) ?? stringValue(input.bodyText);
250
+ const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
251
+ return {
252
+ label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
253
+ url,
254
+ method: stringValue(input.method)?.toUpperCase(),
255
+ status,
256
+ content_type: stringValue(input.content_type) || stringValue(input.contentType),
257
+ headers: stringRecord(input.headers),
258
+ body,
259
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
260
+ required: input.required === false ? false : true
261
+ };
262
+ }
263
+ function normalizeNetworkMocks(value) {
264
+ if (value === void 0) return void 0;
265
+ if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
266
+ return value.map(normalizeNetworkMock);
267
+ }
236
268
  function normalizeCheck(input, index) {
237
269
  if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
238
270
  const type = stringValue(input.type);
@@ -302,7 +334,8 @@ function normalizeRiddleProofProfile(input, options = {}) {
302
334
  timeout_sec: timeoutSecValue(targetInput.timeout_sec) ?? timeoutSecValue(targetInput.timeoutSec) ?? timeoutSecValue(targetInput.riddle_timeout_sec) ?? timeoutSecValue(targetInput.riddleTimeoutSec),
303
335
  wait_for_selector: stringValue(targetInput.wait_for_selector) || stringValue(targetInput.waitForSelector),
304
336
  wait_ms: numberValue(targetInput.wait_ms) ?? numberValue(targetInput.waitMs),
305
- setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions)
337
+ setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions),
338
+ network_mocks: normalizeNetworkMocks(targetInput.network_mocks ?? targetInput.networkMocks)
306
339
  },
307
340
  checks,
308
341
  artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
@@ -574,6 +607,50 @@ function assessSetupActionsFromEvidence(profile, evidence) {
574
607
  message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
575
608
  };
576
609
  }
610
+ function assessNetworkMocksFromEvidence(profile, evidence) {
611
+ const mocks = profile.target.network_mocks || [];
612
+ if (!mocks.length) return void 0;
613
+ const events = evidence.network_mocks || [];
614
+ const failed = [];
615
+ const requiredMocks = mocks.filter((mock) => mock.required !== false);
616
+ for (const mock of requiredMocks) {
617
+ const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
618
+ if (hits < 1) {
619
+ failed.push({
620
+ label: mock.label,
621
+ url: mock.url,
622
+ method: mock.method || null,
623
+ reason: "required_mock_not_hit"
624
+ });
625
+ }
626
+ }
627
+ for (const event of events) {
628
+ if (event.ok === false) {
629
+ failed.push({
630
+ label: event.label ?? null,
631
+ url: event.url ?? null,
632
+ method: event.method ?? null,
633
+ reason: event.reason ?? event.error ?? "mock_failed"
634
+ });
635
+ }
636
+ }
637
+ return {
638
+ type: "network_mocks_succeeded",
639
+ label: "network mocks succeeded",
640
+ status: failed.length ? "failed" : "passed",
641
+ evidence: {
642
+ mock_count: mocks.length,
643
+ required_count: requiredMocks.length,
644
+ hit_count: events.filter((event) => event.ok !== false).length,
645
+ hits_by_label: Object.fromEntries(mocks.map((mock) => [
646
+ mock.label,
647
+ events.filter((event) => event.label === mock.label && event.ok !== false).length
648
+ ])),
649
+ failed
650
+ },
651
+ message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
652
+ };
653
+ }
577
654
  function profileStatusFromEvidence(profile, evidence, checks) {
578
655
  if (!evidence) return "proof_insufficient";
579
656
  const viewports = evidence.viewports || [];
@@ -588,6 +665,7 @@ function profileStatusFromEvidence(profile, evidence, checks) {
588
665
  function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
589
666
  const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
590
667
  const checks = evidence ? [
668
+ assessNetworkMocksFromEvidence(profile, evidence),
591
669
  assessSetupActionsFromEvidence(profile, evidence),
592
670
  ...profile.checks.map((check) => assessCheckFromEvidence(check, evidence))
593
671
  ].filter((check) => Boolean(check)) : [];
@@ -804,6 +882,49 @@ function horizontalBoundsOverflowPx(value) {
804
882
  function assessProfile(profile, evidence) {
805
883
  const checks = [];
806
884
  const viewports = evidence.viewports || [];
885
+ if (profile.target && Array.isArray(profile.target.network_mocks) && profile.target.network_mocks.length) {
886
+ const events = evidence.network_mocks || [];
887
+ const requiredMocks = profile.target.network_mocks.filter((mock) => mock && mock.required !== false);
888
+ const failed = [];
889
+ for (const mock of requiredMocks) {
890
+ const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
891
+ if (hits < 1) {
892
+ failed.push({
893
+ label: mock.label,
894
+ url: mock.url,
895
+ method: mock.method || null,
896
+ reason: "required_mock_not_hit",
897
+ });
898
+ }
899
+ }
900
+ for (const event of events) {
901
+ if (event && event.ok === false) {
902
+ failed.push({
903
+ label: event.label || null,
904
+ url: event.url || null,
905
+ method: event.method || null,
906
+ reason: event.reason || event.error || "mock_failed",
907
+ });
908
+ }
909
+ }
910
+ const hitsByLabel = {};
911
+ for (const mock of profile.target.network_mocks) {
912
+ hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
913
+ }
914
+ checks.push({
915
+ type: "network_mocks_succeeded",
916
+ label: "network mocks succeeded",
917
+ status: failed.length ? "failed" : "passed",
918
+ evidence: {
919
+ mock_count: profile.target.network_mocks.length,
920
+ required_count: requiredMocks.length,
921
+ hit_count: events.filter((event) => event && event.ok !== false).length,
922
+ hits_by_label: hitsByLabel,
923
+ failed,
924
+ },
925
+ message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
926
+ });
927
+ }
807
928
  if (profile.target && Array.isArray(profile.target.setup_actions) && profile.target.setup_actions.length) {
808
929
  const actionCount = profile.target.setup_actions.length;
809
930
  const failed = [];
@@ -993,6 +1114,7 @@ const profileSlug = ${serializableSlug};
993
1114
  const capturedAt = new Date().toISOString();
994
1115
  const consoleEvents = [];
995
1116
  const pageErrors = [];
1117
+ const networkMockEvents = [];
996
1118
  page.on("console", (message) => {
997
1119
  const type = message.type();
998
1120
  if (type === "error" || type === "warning" || type === "assert") {
@@ -1039,6 +1161,49 @@ function compactSetupResultText(value) {
1039
1161
  async function setupLocatorVisible(locator, index) {
1040
1162
  return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
1041
1163
  }
1164
+ async function registerNetworkMocks(mocks) {
1165
+ for (const mock of mocks || []) {
1166
+ await page.route(mock.url, async (route) => {
1167
+ const request = route.request();
1168
+ const method = request.method ? request.method() : "";
1169
+ if (mock.method && method.toUpperCase() !== String(mock.method).toUpperCase()) {
1170
+ await route.continue();
1171
+ return;
1172
+ }
1173
+ try {
1174
+ const headers = { ...(mock.headers || {}) };
1175
+ let body = mock.body || "";
1176
+ let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
1177
+ if (mock.body_json !== undefined) {
1178
+ body = JSON.stringify(mock.body_json);
1179
+ contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
1180
+ }
1181
+ networkMockEvents.push({
1182
+ ok: true,
1183
+ label: mock.label,
1184
+ url: request.url(),
1185
+ method,
1186
+ status: mock.status || 200,
1187
+ });
1188
+ await route.fulfill({
1189
+ status: mock.status || 200,
1190
+ headers,
1191
+ contentType,
1192
+ body,
1193
+ });
1194
+ } catch (error) {
1195
+ networkMockEvents.push({
1196
+ ok: false,
1197
+ label: mock.label,
1198
+ url: request.url(),
1199
+ method,
1200
+ error: String(error && error.message ? error.message : error).slice(0, 1000),
1201
+ });
1202
+ throw error;
1203
+ }
1204
+ });
1205
+ }
1206
+ }
1042
1207
  async function executeSetupAction(action, ordinal) {
1043
1208
  const type = setupActionType(action);
1044
1209
  const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
@@ -1300,6 +1465,7 @@ function buildProfileEvidence(currentViewports) {
1300
1465
  fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
1301
1466
  },
1302
1467
  page_errors: pageErrors,
1468
+ network_mocks: networkMockEvents.slice(),
1303
1469
  dom_summary: {
1304
1470
  expected_viewport_count: expectedViewportCount,
1305
1471
  viewport_count: currentViewports.length,
@@ -1309,6 +1475,8 @@ function buildProfileEvidence(currentViewports) {
1309
1475
  overflow_px: currentViewports.map((viewport) => viewport.overflow_px),
1310
1476
  bounds_overflow_px: currentViewports.map((viewport) => viewport.bounds_overflow_px),
1311
1477
  overflow_offender_counts: currentViewports.map((viewport) => (viewport.overflow_offenders || []).length),
1478
+ network_mock_count: (profile.target.network_mocks || []).length,
1479
+ network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
1312
1480
  },
1313
1481
  };
1314
1482
  }
@@ -1322,6 +1490,9 @@ async function saveProfileArtifacts(currentViewports) {
1322
1490
  }
1323
1491
  return result;
1324
1492
  }
1493
+ await registerNetworkMocks(profile.target.network_mocks || []);
1494
+ consoleEvents.length = 0;
1495
+ pageErrors.length = 0;
1325
1496
  let result = await saveProfileArtifacts(viewports);
1326
1497
  for (const viewport of profile.target.viewports || []) {
1327
1498
  viewports.push(await captureViewport(viewport));
@@ -29,6 +29,17 @@ interface RiddleProofProfileSetupAction {
29
29
  after_ms?: number;
30
30
  continue_on_failure?: boolean;
31
31
  }
32
+ interface RiddleProofProfileNetworkMock {
33
+ label: string;
34
+ url: string;
35
+ method?: string;
36
+ status: number;
37
+ content_type?: string;
38
+ headers?: Record<string, string>;
39
+ body?: string;
40
+ body_json?: JsonValue;
41
+ required?: boolean;
42
+ }
32
43
  interface RiddleProofProfileTarget {
33
44
  url?: string;
34
45
  route?: string;
@@ -38,6 +49,7 @@ interface RiddleProofProfileTarget {
38
49
  wait_for_selector?: string;
39
50
  wait_ms?: number;
40
51
  setup_actions?: RiddleProofProfileSetupAction[];
52
+ network_mocks?: RiddleProofProfileNetworkMock[];
41
53
  }
42
54
  interface RiddleProofProfileCheck {
43
55
  type: RiddleProofProfileCheckType;
@@ -126,6 +138,7 @@ interface RiddleProofProfileEvidence {
126
138
  page_errors: Array<{
127
139
  message: string;
128
140
  }>;
141
+ network_mocks?: Array<Record<string, JsonValue>>;
129
142
  dom_summary?: Record<string, JsonValue>;
130
143
  }
131
144
  interface RiddleProofProfileCheckResult {
@@ -209,4 +222,4 @@ declare function buildRiddleProofProfileScript(profile: RiddleProofProfile): str
209
222
  declare function collectRiddleProfileArtifactRefs(input: unknown): RiddleProofProfileArtifactRef[];
210
223
  declare function extractRiddleProofProfileResult(input: unknown): RiddleProofProfileResult | undefined;
211
224
 
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 };
225
+ 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
@@ -29,6 +29,17 @@ interface RiddleProofProfileSetupAction {
29
29
  after_ms?: number;
30
30
  continue_on_failure?: boolean;
31
31
  }
32
+ interface RiddleProofProfileNetworkMock {
33
+ label: string;
34
+ url: string;
35
+ method?: string;
36
+ status: number;
37
+ content_type?: string;
38
+ headers?: Record<string, string>;
39
+ body?: string;
40
+ body_json?: JsonValue;
41
+ required?: boolean;
42
+ }
32
43
  interface RiddleProofProfileTarget {
33
44
  url?: string;
34
45
  route?: string;
@@ -38,6 +49,7 @@ interface RiddleProofProfileTarget {
38
49
  wait_for_selector?: string;
39
50
  wait_ms?: number;
40
51
  setup_actions?: RiddleProofProfileSetupAction[];
52
+ network_mocks?: RiddleProofProfileNetworkMock[];
41
53
  }
42
54
  interface RiddleProofProfileCheck {
43
55
  type: RiddleProofProfileCheckType;
@@ -126,6 +138,7 @@ interface RiddleProofProfileEvidence {
126
138
  page_errors: Array<{
127
139
  message: string;
128
140
  }>;
141
+ network_mocks?: Array<Record<string, JsonValue>>;
129
142
  dom_summary?: Record<string, JsonValue>;
130
143
  }
131
144
  interface RiddleProofProfileCheckResult {
@@ -209,4 +222,4 @@ declare function buildRiddleProofProfileScript(profile: RiddleProofProfile): str
209
222
  declare function collectRiddleProfileArtifactRefs(input: unknown): RiddleProofProfileArtifactRef[];
210
223
  declare function extractRiddleProofProfileResult(input: unknown): RiddleProofProfileResult | undefined;
211
224
 
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 };
225
+ 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-SDSBS64X.js";
22
+ } from "./chunk-FUWINYNX.js";
23
23
  export {
24
24
  RIDDLE_PROOF_PROFILE_CHECK_TYPES,
25
25
  RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.26",
3
+ "version": "0.7.27",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",