@riddledc/riddle-proof 0.7.46 → 0.7.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -229,7 +229,10 @@ mock hits. Add `request_body_contains` / `request_body_patterns` or
229
229
  is part of the contract, such as proving that a save request references the
230
230
  current build ID returned by a prior mocked build response and not a stale one.
231
231
  Body assertions use the full request body for matching and store only length
232
- plus a compact sample in the proof evidence.
232
+ plus a compact sample in the proof evidence. For sequenced mocks, the same
233
+ request-body fields may also be placed on individual `responses[]` entries when
234
+ each step has a different request contract, such as a fail-then-success retry
235
+ where the second request must carry newer state.
233
236
 
234
237
  `target.setup_actions` is optional. Use it when the meaningful proof surface
235
238
  appears only after a picker, tab, login stub, storage seed, form fill,
@@ -253,24 +253,7 @@ function normalizeNetworkMock(input, index) {
253
253
  const payload = normalizeNetworkMockResponsePayload(input, `target.network_mocks[${index}]`);
254
254
  const responsesInput = input.responses ?? input.sequence;
255
255
  const responses = normalizeNetworkMockResponses(responsesInput, index, payload);
256
- const requestBodyContains = normalizeStringList(
257
- input.request_body_contains ?? input.requestBodyContains ?? input.body_contains ?? input.bodyContains,
258
- `target.network_mocks[${index}].request_body_contains`
259
- );
260
- const requestBodyPatterns = normalizeStringList(
261
- input.request_body_patterns ?? input.requestBodyPatterns ?? input.body_patterns ?? input.bodyPatterns,
262
- `target.network_mocks[${index}].request_body_patterns`
263
- );
264
- validateRegexPatterns(requestBodyPatterns, `target.network_mocks[${index}].request_body_patterns`);
265
- const requestBodyNotContains = normalizeStringList(
266
- input.request_body_not_contains ?? input.requestBodyNotContains ?? input.request_body_absent ?? input.requestBodyAbsent ?? input.body_not_contains ?? input.bodyNotContains ?? input.body_absent ?? input.bodyAbsent,
267
- `target.network_mocks[${index}].request_body_not_contains`
268
- );
269
- const requestBodyNotPatterns = normalizeStringList(
270
- input.request_body_not_patterns ?? input.requestBodyNotPatterns ?? input.request_body_forbidden_patterns ?? input.requestBodyForbiddenPatterns ?? input.body_not_patterns ?? input.bodyNotPatterns ?? input.body_forbidden_patterns ?? input.bodyForbiddenPatterns,
271
- `target.network_mocks[${index}].request_body_not_patterns`
272
- );
273
- validateRegexPatterns(requestBodyNotPatterns, `target.network_mocks[${index}].request_body_not_patterns`);
256
+ const requestBody = normalizeNetworkMockRequestBodyConstraints(input, `target.network_mocks[${index}]`);
274
257
  const requiredHitCount = numberValue(
275
258
  input.required_hit_count ?? input.requiredHitCount ?? input.required_hits ?? input.requiredHits ?? input.min_hits ?? input.minHits
276
259
  );
@@ -286,6 +269,33 @@ function normalizeNetworkMock(input, index) {
286
269
  repeat_responses: input.repeat_responses === true || input.repeatResponses === true || input.cycle_responses === true || input.cycleResponses === true,
287
270
  required_hit_count: requiredHitCount,
288
271
  required: input.required === false ? false : true,
272
+ capture_request_body: requestBody.capture_request_body,
273
+ request_body_contains: requestBody.request_body_contains,
274
+ request_body_patterns: requestBody.request_body_patterns,
275
+ request_body_not_contains: requestBody.request_body_not_contains,
276
+ request_body_not_patterns: requestBody.request_body_not_patterns
277
+ };
278
+ }
279
+ function normalizeNetworkMockRequestBodyConstraints(input, label) {
280
+ const requestBodyContains = normalizeStringList(
281
+ input.request_body_contains ?? input.requestBodyContains ?? input.body_contains ?? input.bodyContains,
282
+ `${label}.request_body_contains`
283
+ );
284
+ const requestBodyPatterns = normalizeStringList(
285
+ input.request_body_patterns ?? input.requestBodyPatterns ?? input.body_patterns ?? input.bodyPatterns,
286
+ `${label}.request_body_patterns`
287
+ );
288
+ validateRegexPatterns(requestBodyPatterns, `${label}.request_body_patterns`);
289
+ const requestBodyNotContains = normalizeStringList(
290
+ input.request_body_not_contains ?? input.requestBodyNotContains ?? input.request_body_absent ?? input.requestBodyAbsent ?? input.body_not_contains ?? input.bodyNotContains ?? input.body_absent ?? input.bodyAbsent,
291
+ `${label}.request_body_not_contains`
292
+ );
293
+ const requestBodyNotPatterns = normalizeStringList(
294
+ input.request_body_not_patterns ?? input.requestBodyNotPatterns ?? input.request_body_forbidden_patterns ?? input.requestBodyForbiddenPatterns ?? input.body_not_patterns ?? input.bodyNotPatterns ?? input.body_forbidden_patterns ?? input.bodyForbiddenPatterns,
295
+ `${label}.request_body_not_patterns`
296
+ );
297
+ validateRegexPatterns(requestBodyNotPatterns, `${label}.request_body_not_patterns`);
298
+ return {
289
299
  capture_request_body: input.capture_request_body === true || input.captureRequestBody === true || Boolean(requestBodyContains?.length) || Boolean(requestBodyPatterns?.length) || Boolean(requestBodyNotContains?.length) || Boolean(requestBodyNotPatterns?.length),
290
300
  request_body_contains: requestBodyContains,
291
301
  request_body_patterns: requestBodyPatterns,
@@ -300,20 +310,33 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
300
310
  }
301
311
  const body = stringValue(input.body) ?? stringValue(input.body_text) ?? stringValue(input.bodyText) ?? defaults.body;
302
312
  const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
313
+ const requestBody = normalizeNetworkMockRequestBodyConstraints(input, label);
303
314
  return {
304
315
  label: stringValue(input.label) || stringValue(input.name) || defaults.label,
305
316
  status,
306
317
  content_type: stringValue(input.content_type) || stringValue(input.contentType) || defaults.content_type,
307
318
  headers: stringRecord(input.headers) || defaults.headers,
308
319
  body,
309
- body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json
320
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json,
321
+ capture_request_body: requestBody.capture_request_body,
322
+ request_body_contains: requestBody.request_body_contains,
323
+ request_body_patterns: requestBody.request_body_patterns,
324
+ request_body_not_contains: requestBody.request_body_not_contains,
325
+ request_body_not_patterns: requestBody.request_body_not_patterns
310
326
  };
311
327
  }
312
328
  function normalizeNetworkMockResponses(value, mockIndex, defaults) {
313
329
  if (value === void 0) return void 0;
314
330
  if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
315
331
  if (!value.length) throw new Error(`target.network_mocks[${mockIndex}].responses must not be empty.`);
316
- const responseDefaults = { ...defaults, label: void 0 };
332
+ const responseDefaults = {
333
+ label: void 0,
334
+ status: defaults.status,
335
+ content_type: defaults.content_type,
336
+ headers: defaults.headers,
337
+ body: defaults.body,
338
+ body_json: defaults.body_json
339
+ };
317
340
  return value.map((response, responseIndex) => {
318
341
  if (!isRecord(response)) {
319
342
  throw new Error(`target.network_mocks[${mockIndex}].responses[${responseIndex}] must be an object.`);
@@ -1056,6 +1079,9 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
1056
1079
  if (event.request_body_matches === false) {
1057
1080
  failed.push({
1058
1081
  label: event.label ?? null,
1082
+ response_label: event.response_label ?? null,
1083
+ hit_index: event.hit_index ?? null,
1084
+ response_index: event.response_index ?? null,
1059
1085
  url: event.url ?? null,
1060
1086
  method: event.method ?? null,
1061
1087
  reason: "request_body_mismatch",
@@ -1439,6 +1465,9 @@ function assessProfile(profile, evidence) {
1439
1465
  if (event && event.request_body_matches === false) {
1440
1466
  failed.push({
1441
1467
  label: event.label || null,
1468
+ response_label: event.response_label || null,
1469
+ hit_index: event.hit_index ?? null,
1470
+ response_index: event.response_index ?? null,
1442
1471
  url: event.url || null,
1443
1472
  method: event.method || null,
1444
1473
  reason: "request_body_mismatch",
@@ -1903,20 +1932,21 @@ function compactNetworkMockRequestBody(value) {
1903
1932
  function networkMockStringList(value) {
1904
1933
  return Array.isArray(value) ? value.map((item) => String(item)).filter(Boolean) : [];
1905
1934
  }
1906
- function networkMockShouldCaptureRequestBody(mock) {
1907
- return mock && (
1908
- mock.capture_request_body === true
1909
- || networkMockStringList(mock.request_body_contains).length > 0
1910
- || networkMockStringList(mock.request_body_patterns).length > 0
1911
- || networkMockStringList(mock.request_body_not_contains).length > 0
1912
- || networkMockStringList(mock.request_body_not_patterns).length > 0
1913
- );
1935
+ function networkMockShouldCaptureRequestBody(...sources) {
1936
+ return sources.some((source) => source && (
1937
+ source.capture_request_body === true
1938
+ || networkMockStringList(source.request_body_contains).length > 0
1939
+ || networkMockStringList(source.request_body_patterns).length > 0
1940
+ || networkMockStringList(source.request_body_not_contains).length > 0
1941
+ || networkMockStringList(source.request_body_not_patterns).length > 0
1942
+ ));
1914
1943
  }
1915
- function networkMockRequestBodyFailures(body, mock) {
1944
+ function networkMockRequestBodyFailuresForSource(body, source) {
1916
1945
  const failures = [];
1946
+ if (!source) return failures;
1917
1947
  const rawBody = String(body || "");
1918
1948
  const compactBody = compactNetworkMockRequestBody(rawBody);
1919
- for (const expected of networkMockStringList(mock.request_body_contains)) {
1949
+ for (const expected of networkMockStringList(source.request_body_contains)) {
1920
1950
  if (!rawBody.includes(expected) && !compactBody.includes(expected)) {
1921
1951
  failures.push({
1922
1952
  type: "request_body_missing_text",
@@ -1924,7 +1954,7 @@ function networkMockRequestBodyFailures(body, mock) {
1924
1954
  });
1925
1955
  }
1926
1956
  }
1927
- for (const pattern of networkMockStringList(mock.request_body_patterns)) {
1957
+ for (const pattern of networkMockStringList(source.request_body_patterns)) {
1928
1958
  try {
1929
1959
  const regex = new RegExp(pattern);
1930
1960
  if (!regex.test(rawBody) && !regex.test(compactBody)) {
@@ -1941,7 +1971,7 @@ function networkMockRequestBodyFailures(body, mock) {
1941
1971
  });
1942
1972
  }
1943
1973
  }
1944
- for (const forbidden of networkMockStringList(mock.request_body_not_contains)) {
1974
+ for (const forbidden of networkMockStringList(source.request_body_not_contains)) {
1945
1975
  if (rawBody.includes(forbidden) || compactBody.includes(forbidden)) {
1946
1976
  failures.push({
1947
1977
  type: "request_body_forbidden_text",
@@ -1949,7 +1979,7 @@ function networkMockRequestBodyFailures(body, mock) {
1949
1979
  });
1950
1980
  }
1951
1981
  }
1952
- for (const pattern of networkMockStringList(mock.request_body_not_patterns)) {
1982
+ for (const pattern of networkMockStringList(source.request_body_not_patterns)) {
1953
1983
  try {
1954
1984
  const regex = new RegExp(pattern);
1955
1985
  if (regex.test(rawBody) || regex.test(compactBody)) {
@@ -1968,6 +1998,9 @@ function networkMockRequestBodyFailures(body, mock) {
1968
1998
  }
1969
1999
  return failures;
1970
2000
  }
2001
+ function networkMockRequestBodyFailures(body, ...sources) {
2002
+ return sources.flatMap((source) => networkMockRequestBodyFailuresForSource(body, source));
2003
+ }
1971
2004
  async function setupLocatorVisible(locator, index) {
1972
2005
  return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
1973
2006
  }
@@ -1996,9 +2029,10 @@ async function registerNetworkMocks(mocks) {
1996
2029
  body = JSON.stringify(response.body_json);
1997
2030
  contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
1998
2031
  }
1999
- const shouldCaptureRequestBody = networkMockShouldCaptureRequestBody(mock);
2032
+ const responseBodyContract = responseIndex === null ? null : response;
2033
+ const shouldCaptureRequestBody = networkMockShouldCaptureRequestBody(mock, responseBodyContract);
2000
2034
  const requestBody = shouldCaptureRequestBody && request.postData ? request.postData() || "" : "";
2001
- const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock) : [];
2035
+ const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock, responseBodyContract) : [];
2002
2036
  const status = response.status || mock.status || 200;
2003
2037
  const event = {
2004
2038
  ok: true,
package/dist/cli.cjs CHANGED
@@ -7126,24 +7126,7 @@ function normalizeNetworkMock(input, index) {
7126
7126
  const payload = normalizeNetworkMockResponsePayload(input, `target.network_mocks[${index}]`);
7127
7127
  const responsesInput = input.responses ?? input.sequence;
7128
7128
  const responses = normalizeNetworkMockResponses(responsesInput, index, payload);
7129
- const requestBodyContains = normalizeStringList(
7130
- input.request_body_contains ?? input.requestBodyContains ?? input.body_contains ?? input.bodyContains,
7131
- `target.network_mocks[${index}].request_body_contains`
7132
- );
7133
- const requestBodyPatterns = normalizeStringList(
7134
- input.request_body_patterns ?? input.requestBodyPatterns ?? input.body_patterns ?? input.bodyPatterns,
7135
- `target.network_mocks[${index}].request_body_patterns`
7136
- );
7137
- validateRegexPatterns(requestBodyPatterns, `target.network_mocks[${index}].request_body_patterns`);
7138
- const requestBodyNotContains = normalizeStringList(
7139
- input.request_body_not_contains ?? input.requestBodyNotContains ?? input.request_body_absent ?? input.requestBodyAbsent ?? input.body_not_contains ?? input.bodyNotContains ?? input.body_absent ?? input.bodyAbsent,
7140
- `target.network_mocks[${index}].request_body_not_contains`
7141
- );
7142
- const requestBodyNotPatterns = normalizeStringList(
7143
- input.request_body_not_patterns ?? input.requestBodyNotPatterns ?? input.request_body_forbidden_patterns ?? input.requestBodyForbiddenPatterns ?? input.body_not_patterns ?? input.bodyNotPatterns ?? input.body_forbidden_patterns ?? input.bodyForbiddenPatterns,
7144
- `target.network_mocks[${index}].request_body_not_patterns`
7145
- );
7146
- validateRegexPatterns(requestBodyNotPatterns, `target.network_mocks[${index}].request_body_not_patterns`);
7129
+ const requestBody = normalizeNetworkMockRequestBodyConstraints(input, `target.network_mocks[${index}]`);
7147
7130
  const requiredHitCount = numberValue(
7148
7131
  input.required_hit_count ?? input.requiredHitCount ?? input.required_hits ?? input.requiredHits ?? input.min_hits ?? input.minHits
7149
7132
  );
@@ -7159,6 +7142,33 @@ function normalizeNetworkMock(input, index) {
7159
7142
  repeat_responses: input.repeat_responses === true || input.repeatResponses === true || input.cycle_responses === true || input.cycleResponses === true,
7160
7143
  required_hit_count: requiredHitCount,
7161
7144
  required: input.required === false ? false : true,
7145
+ capture_request_body: requestBody.capture_request_body,
7146
+ request_body_contains: requestBody.request_body_contains,
7147
+ request_body_patterns: requestBody.request_body_patterns,
7148
+ request_body_not_contains: requestBody.request_body_not_contains,
7149
+ request_body_not_patterns: requestBody.request_body_not_patterns
7150
+ };
7151
+ }
7152
+ function normalizeNetworkMockRequestBodyConstraints(input, label) {
7153
+ const requestBodyContains = normalizeStringList(
7154
+ input.request_body_contains ?? input.requestBodyContains ?? input.body_contains ?? input.bodyContains,
7155
+ `${label}.request_body_contains`
7156
+ );
7157
+ const requestBodyPatterns = normalizeStringList(
7158
+ input.request_body_patterns ?? input.requestBodyPatterns ?? input.body_patterns ?? input.bodyPatterns,
7159
+ `${label}.request_body_patterns`
7160
+ );
7161
+ validateRegexPatterns(requestBodyPatterns, `${label}.request_body_patterns`);
7162
+ const requestBodyNotContains = normalizeStringList(
7163
+ input.request_body_not_contains ?? input.requestBodyNotContains ?? input.request_body_absent ?? input.requestBodyAbsent ?? input.body_not_contains ?? input.bodyNotContains ?? input.body_absent ?? input.bodyAbsent,
7164
+ `${label}.request_body_not_contains`
7165
+ );
7166
+ const requestBodyNotPatterns = normalizeStringList(
7167
+ input.request_body_not_patterns ?? input.requestBodyNotPatterns ?? input.request_body_forbidden_patterns ?? input.requestBodyForbiddenPatterns ?? input.body_not_patterns ?? input.bodyNotPatterns ?? input.body_forbidden_patterns ?? input.bodyForbiddenPatterns,
7168
+ `${label}.request_body_not_patterns`
7169
+ );
7170
+ validateRegexPatterns(requestBodyNotPatterns, `${label}.request_body_not_patterns`);
7171
+ return {
7162
7172
  capture_request_body: input.capture_request_body === true || input.captureRequestBody === true || Boolean(requestBodyContains?.length) || Boolean(requestBodyPatterns?.length) || Boolean(requestBodyNotContains?.length) || Boolean(requestBodyNotPatterns?.length),
7163
7173
  request_body_contains: requestBodyContains,
7164
7174
  request_body_patterns: requestBodyPatterns,
@@ -7173,20 +7183,33 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
7173
7183
  }
7174
7184
  const body = stringValue2(input.body) ?? stringValue2(input.body_text) ?? stringValue2(input.bodyText) ?? defaults.body;
7175
7185
  const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
7186
+ const requestBody = normalizeNetworkMockRequestBodyConstraints(input, label);
7176
7187
  return {
7177
7188
  label: stringValue2(input.label) || stringValue2(input.name) || defaults.label,
7178
7189
  status,
7179
7190
  content_type: stringValue2(input.content_type) || stringValue2(input.contentType) || defaults.content_type,
7180
7191
  headers: stringRecord(input.headers) || defaults.headers,
7181
7192
  body,
7182
- body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json
7193
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json,
7194
+ capture_request_body: requestBody.capture_request_body,
7195
+ request_body_contains: requestBody.request_body_contains,
7196
+ request_body_patterns: requestBody.request_body_patterns,
7197
+ request_body_not_contains: requestBody.request_body_not_contains,
7198
+ request_body_not_patterns: requestBody.request_body_not_patterns
7183
7199
  };
7184
7200
  }
7185
7201
  function normalizeNetworkMockResponses(value, mockIndex, defaults) {
7186
7202
  if (value === void 0) return void 0;
7187
7203
  if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
7188
7204
  if (!value.length) throw new Error(`target.network_mocks[${mockIndex}].responses must not be empty.`);
7189
- const responseDefaults = { ...defaults, label: void 0 };
7205
+ const responseDefaults = {
7206
+ label: void 0,
7207
+ status: defaults.status,
7208
+ content_type: defaults.content_type,
7209
+ headers: defaults.headers,
7210
+ body: defaults.body,
7211
+ body_json: defaults.body_json
7212
+ };
7190
7213
  return value.map((response, responseIndex) => {
7191
7214
  if (!isRecord(response)) {
7192
7215
  throw new Error(`target.network_mocks[${mockIndex}].responses[${responseIndex}] must be an object.`);
@@ -7929,6 +7952,9 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
7929
7952
  if (event.request_body_matches === false) {
7930
7953
  failed.push({
7931
7954
  label: event.label ?? null,
7955
+ response_label: event.response_label ?? null,
7956
+ hit_index: event.hit_index ?? null,
7957
+ response_index: event.response_index ?? null,
7932
7958
  url: event.url ?? null,
7933
7959
  method: event.method ?? null,
7934
7960
  reason: "request_body_mismatch",
@@ -8296,6 +8322,9 @@ function assessProfile(profile, evidence) {
8296
8322
  if (event && event.request_body_matches === false) {
8297
8323
  failed.push({
8298
8324
  label: event.label || null,
8325
+ response_label: event.response_label || null,
8326
+ hit_index: event.hit_index ?? null,
8327
+ response_index: event.response_index ?? null,
8299
8328
  url: event.url || null,
8300
8329
  method: event.method || null,
8301
8330
  reason: "request_body_mismatch",
@@ -8760,20 +8789,21 @@ function compactNetworkMockRequestBody(value) {
8760
8789
  function networkMockStringList(value) {
8761
8790
  return Array.isArray(value) ? value.map((item) => String(item)).filter(Boolean) : [];
8762
8791
  }
8763
- function networkMockShouldCaptureRequestBody(mock) {
8764
- return mock && (
8765
- mock.capture_request_body === true
8766
- || networkMockStringList(mock.request_body_contains).length > 0
8767
- || networkMockStringList(mock.request_body_patterns).length > 0
8768
- || networkMockStringList(mock.request_body_not_contains).length > 0
8769
- || networkMockStringList(mock.request_body_not_patterns).length > 0
8770
- );
8792
+ function networkMockShouldCaptureRequestBody(...sources) {
8793
+ return sources.some((source) => source && (
8794
+ source.capture_request_body === true
8795
+ || networkMockStringList(source.request_body_contains).length > 0
8796
+ || networkMockStringList(source.request_body_patterns).length > 0
8797
+ || networkMockStringList(source.request_body_not_contains).length > 0
8798
+ || networkMockStringList(source.request_body_not_patterns).length > 0
8799
+ ));
8771
8800
  }
8772
- function networkMockRequestBodyFailures(body, mock) {
8801
+ function networkMockRequestBodyFailuresForSource(body, source) {
8773
8802
  const failures = [];
8803
+ if (!source) return failures;
8774
8804
  const rawBody = String(body || "");
8775
8805
  const compactBody = compactNetworkMockRequestBody(rawBody);
8776
- for (const expected of networkMockStringList(mock.request_body_contains)) {
8806
+ for (const expected of networkMockStringList(source.request_body_contains)) {
8777
8807
  if (!rawBody.includes(expected) && !compactBody.includes(expected)) {
8778
8808
  failures.push({
8779
8809
  type: "request_body_missing_text",
@@ -8781,7 +8811,7 @@ function networkMockRequestBodyFailures(body, mock) {
8781
8811
  });
8782
8812
  }
8783
8813
  }
8784
- for (const pattern of networkMockStringList(mock.request_body_patterns)) {
8814
+ for (const pattern of networkMockStringList(source.request_body_patterns)) {
8785
8815
  try {
8786
8816
  const regex = new RegExp(pattern);
8787
8817
  if (!regex.test(rawBody) && !regex.test(compactBody)) {
@@ -8798,7 +8828,7 @@ function networkMockRequestBodyFailures(body, mock) {
8798
8828
  });
8799
8829
  }
8800
8830
  }
8801
- for (const forbidden of networkMockStringList(mock.request_body_not_contains)) {
8831
+ for (const forbidden of networkMockStringList(source.request_body_not_contains)) {
8802
8832
  if (rawBody.includes(forbidden) || compactBody.includes(forbidden)) {
8803
8833
  failures.push({
8804
8834
  type: "request_body_forbidden_text",
@@ -8806,7 +8836,7 @@ function networkMockRequestBodyFailures(body, mock) {
8806
8836
  });
8807
8837
  }
8808
8838
  }
8809
- for (const pattern of networkMockStringList(mock.request_body_not_patterns)) {
8839
+ for (const pattern of networkMockStringList(source.request_body_not_patterns)) {
8810
8840
  try {
8811
8841
  const regex = new RegExp(pattern);
8812
8842
  if (regex.test(rawBody) || regex.test(compactBody)) {
@@ -8825,6 +8855,9 @@ function networkMockRequestBodyFailures(body, mock) {
8825
8855
  }
8826
8856
  return failures;
8827
8857
  }
8858
+ function networkMockRequestBodyFailures(body, ...sources) {
8859
+ return sources.flatMap((source) => networkMockRequestBodyFailuresForSource(body, source));
8860
+ }
8828
8861
  async function setupLocatorVisible(locator, index) {
8829
8862
  return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
8830
8863
  }
@@ -8853,9 +8886,10 @@ async function registerNetworkMocks(mocks) {
8853
8886
  body = JSON.stringify(response.body_json);
8854
8887
  contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
8855
8888
  }
8856
- const shouldCaptureRequestBody = networkMockShouldCaptureRequestBody(mock);
8889
+ const responseBodyContract = responseIndex === null ? null : response;
8890
+ const shouldCaptureRequestBody = networkMockShouldCaptureRequestBody(mock, responseBodyContract);
8857
8891
  const requestBody = shouldCaptureRequestBody && request.postData ? request.postData() || "" : "";
8858
- const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock) : [];
8892
+ const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock, responseBodyContract) : [];
8859
8893
  const status = response.status || mock.status || 200;
8860
8894
  const event = {
8861
8895
  ok: true,
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  profileStatusExitCode,
11
11
  resolveRiddleProofProfileTargetUrl,
12
12
  resolveRiddleProofProfileTimeoutSec
13
- } from "./chunk-WSZ5AVKX.js";
13
+ } from "./chunk-NJDY7HYE.js";
14
14
  import {
15
15
  createRiddleApiClient,
16
16
  parseRiddleViewport
package/dist/index.cjs CHANGED
@@ -8967,24 +8967,7 @@ function normalizeNetworkMock(input, index) {
8967
8967
  const payload = normalizeNetworkMockResponsePayload(input, `target.network_mocks[${index}]`);
8968
8968
  const responsesInput = input.responses ?? input.sequence;
8969
8969
  const responses = normalizeNetworkMockResponses(responsesInput, index, payload);
8970
- const requestBodyContains = normalizeStringList(
8971
- input.request_body_contains ?? input.requestBodyContains ?? input.body_contains ?? input.bodyContains,
8972
- `target.network_mocks[${index}].request_body_contains`
8973
- );
8974
- const requestBodyPatterns = normalizeStringList(
8975
- input.request_body_patterns ?? input.requestBodyPatterns ?? input.body_patterns ?? input.bodyPatterns,
8976
- `target.network_mocks[${index}].request_body_patterns`
8977
- );
8978
- validateRegexPatterns(requestBodyPatterns, `target.network_mocks[${index}].request_body_patterns`);
8979
- const requestBodyNotContains = normalizeStringList(
8980
- input.request_body_not_contains ?? input.requestBodyNotContains ?? input.request_body_absent ?? input.requestBodyAbsent ?? input.body_not_contains ?? input.bodyNotContains ?? input.body_absent ?? input.bodyAbsent,
8981
- `target.network_mocks[${index}].request_body_not_contains`
8982
- );
8983
- const requestBodyNotPatterns = normalizeStringList(
8984
- input.request_body_not_patterns ?? input.requestBodyNotPatterns ?? input.request_body_forbidden_patterns ?? input.requestBodyForbiddenPatterns ?? input.body_not_patterns ?? input.bodyNotPatterns ?? input.body_forbidden_patterns ?? input.bodyForbiddenPatterns,
8985
- `target.network_mocks[${index}].request_body_not_patterns`
8986
- );
8987
- validateRegexPatterns(requestBodyNotPatterns, `target.network_mocks[${index}].request_body_not_patterns`);
8970
+ const requestBody = normalizeNetworkMockRequestBodyConstraints(input, `target.network_mocks[${index}]`);
8988
8971
  const requiredHitCount = numberValue3(
8989
8972
  input.required_hit_count ?? input.requiredHitCount ?? input.required_hits ?? input.requiredHits ?? input.min_hits ?? input.minHits
8990
8973
  );
@@ -9000,6 +8983,33 @@ function normalizeNetworkMock(input, index) {
9000
8983
  repeat_responses: input.repeat_responses === true || input.repeatResponses === true || input.cycle_responses === true || input.cycleResponses === true,
9001
8984
  required_hit_count: requiredHitCount,
9002
8985
  required: input.required === false ? false : true,
8986
+ capture_request_body: requestBody.capture_request_body,
8987
+ request_body_contains: requestBody.request_body_contains,
8988
+ request_body_patterns: requestBody.request_body_patterns,
8989
+ request_body_not_contains: requestBody.request_body_not_contains,
8990
+ request_body_not_patterns: requestBody.request_body_not_patterns
8991
+ };
8992
+ }
8993
+ function normalizeNetworkMockRequestBodyConstraints(input, label) {
8994
+ const requestBodyContains = normalizeStringList(
8995
+ input.request_body_contains ?? input.requestBodyContains ?? input.body_contains ?? input.bodyContains,
8996
+ `${label}.request_body_contains`
8997
+ );
8998
+ const requestBodyPatterns = normalizeStringList(
8999
+ input.request_body_patterns ?? input.requestBodyPatterns ?? input.body_patterns ?? input.bodyPatterns,
9000
+ `${label}.request_body_patterns`
9001
+ );
9002
+ validateRegexPatterns(requestBodyPatterns, `${label}.request_body_patterns`);
9003
+ const requestBodyNotContains = normalizeStringList(
9004
+ input.request_body_not_contains ?? input.requestBodyNotContains ?? input.request_body_absent ?? input.requestBodyAbsent ?? input.body_not_contains ?? input.bodyNotContains ?? input.body_absent ?? input.bodyAbsent,
9005
+ `${label}.request_body_not_contains`
9006
+ );
9007
+ const requestBodyNotPatterns = normalizeStringList(
9008
+ input.request_body_not_patterns ?? input.requestBodyNotPatterns ?? input.request_body_forbidden_patterns ?? input.requestBodyForbiddenPatterns ?? input.body_not_patterns ?? input.bodyNotPatterns ?? input.body_forbidden_patterns ?? input.bodyForbiddenPatterns,
9009
+ `${label}.request_body_not_patterns`
9010
+ );
9011
+ validateRegexPatterns(requestBodyNotPatterns, `${label}.request_body_not_patterns`);
9012
+ return {
9003
9013
  capture_request_body: input.capture_request_body === true || input.captureRequestBody === true || Boolean(requestBodyContains?.length) || Boolean(requestBodyPatterns?.length) || Boolean(requestBodyNotContains?.length) || Boolean(requestBodyNotPatterns?.length),
9004
9014
  request_body_contains: requestBodyContains,
9005
9015
  request_body_patterns: requestBodyPatterns,
@@ -9014,20 +9024,33 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
9014
9024
  }
9015
9025
  const body = stringValue5(input.body) ?? stringValue5(input.body_text) ?? stringValue5(input.bodyText) ?? defaults.body;
9016
9026
  const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
9027
+ const requestBody = normalizeNetworkMockRequestBodyConstraints(input, label);
9017
9028
  return {
9018
9029
  label: stringValue5(input.label) || stringValue5(input.name) || defaults.label,
9019
9030
  status,
9020
9031
  content_type: stringValue5(input.content_type) || stringValue5(input.contentType) || defaults.content_type,
9021
9032
  headers: stringRecord(input.headers) || defaults.headers,
9022
9033
  body,
9023
- body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json
9034
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json,
9035
+ capture_request_body: requestBody.capture_request_body,
9036
+ request_body_contains: requestBody.request_body_contains,
9037
+ request_body_patterns: requestBody.request_body_patterns,
9038
+ request_body_not_contains: requestBody.request_body_not_contains,
9039
+ request_body_not_patterns: requestBody.request_body_not_patterns
9024
9040
  };
9025
9041
  }
9026
9042
  function normalizeNetworkMockResponses(value, mockIndex, defaults) {
9027
9043
  if (value === void 0) return void 0;
9028
9044
  if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
9029
9045
  if (!value.length) throw new Error(`target.network_mocks[${mockIndex}].responses must not be empty.`);
9030
- const responseDefaults = { ...defaults, label: void 0 };
9046
+ const responseDefaults = {
9047
+ label: void 0,
9048
+ status: defaults.status,
9049
+ content_type: defaults.content_type,
9050
+ headers: defaults.headers,
9051
+ body: defaults.body,
9052
+ body_json: defaults.body_json
9053
+ };
9031
9054
  return value.map((response, responseIndex) => {
9032
9055
  if (!isRecord2(response)) {
9033
9056
  throw new Error(`target.network_mocks[${mockIndex}].responses[${responseIndex}] must be an object.`);
@@ -9770,6 +9793,9 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
9770
9793
  if (event.request_body_matches === false) {
9771
9794
  failed.push({
9772
9795
  label: event.label ?? null,
9796
+ response_label: event.response_label ?? null,
9797
+ hit_index: event.hit_index ?? null,
9798
+ response_index: event.response_index ?? null,
9773
9799
  url: event.url ?? null,
9774
9800
  method: event.method ?? null,
9775
9801
  reason: "request_body_mismatch",
@@ -10153,6 +10179,9 @@ function assessProfile(profile, evidence) {
10153
10179
  if (event && event.request_body_matches === false) {
10154
10180
  failed.push({
10155
10181
  label: event.label || null,
10182
+ response_label: event.response_label || null,
10183
+ hit_index: event.hit_index ?? null,
10184
+ response_index: event.response_index ?? null,
10156
10185
  url: event.url || null,
10157
10186
  method: event.method || null,
10158
10187
  reason: "request_body_mismatch",
@@ -10617,20 +10646,21 @@ function compactNetworkMockRequestBody(value) {
10617
10646
  function networkMockStringList(value) {
10618
10647
  return Array.isArray(value) ? value.map((item) => String(item)).filter(Boolean) : [];
10619
10648
  }
10620
- function networkMockShouldCaptureRequestBody(mock) {
10621
- return mock && (
10622
- mock.capture_request_body === true
10623
- || networkMockStringList(mock.request_body_contains).length > 0
10624
- || networkMockStringList(mock.request_body_patterns).length > 0
10625
- || networkMockStringList(mock.request_body_not_contains).length > 0
10626
- || networkMockStringList(mock.request_body_not_patterns).length > 0
10627
- );
10649
+ function networkMockShouldCaptureRequestBody(...sources) {
10650
+ return sources.some((source) => source && (
10651
+ source.capture_request_body === true
10652
+ || networkMockStringList(source.request_body_contains).length > 0
10653
+ || networkMockStringList(source.request_body_patterns).length > 0
10654
+ || networkMockStringList(source.request_body_not_contains).length > 0
10655
+ || networkMockStringList(source.request_body_not_patterns).length > 0
10656
+ ));
10628
10657
  }
10629
- function networkMockRequestBodyFailures(body, mock) {
10658
+ function networkMockRequestBodyFailuresForSource(body, source) {
10630
10659
  const failures = [];
10660
+ if (!source) return failures;
10631
10661
  const rawBody = String(body || "");
10632
10662
  const compactBody = compactNetworkMockRequestBody(rawBody);
10633
- for (const expected of networkMockStringList(mock.request_body_contains)) {
10663
+ for (const expected of networkMockStringList(source.request_body_contains)) {
10634
10664
  if (!rawBody.includes(expected) && !compactBody.includes(expected)) {
10635
10665
  failures.push({
10636
10666
  type: "request_body_missing_text",
@@ -10638,7 +10668,7 @@ function networkMockRequestBodyFailures(body, mock) {
10638
10668
  });
10639
10669
  }
10640
10670
  }
10641
- for (const pattern of networkMockStringList(mock.request_body_patterns)) {
10671
+ for (const pattern of networkMockStringList(source.request_body_patterns)) {
10642
10672
  try {
10643
10673
  const regex = new RegExp(pattern);
10644
10674
  if (!regex.test(rawBody) && !regex.test(compactBody)) {
@@ -10655,7 +10685,7 @@ function networkMockRequestBodyFailures(body, mock) {
10655
10685
  });
10656
10686
  }
10657
10687
  }
10658
- for (const forbidden of networkMockStringList(mock.request_body_not_contains)) {
10688
+ for (const forbidden of networkMockStringList(source.request_body_not_contains)) {
10659
10689
  if (rawBody.includes(forbidden) || compactBody.includes(forbidden)) {
10660
10690
  failures.push({
10661
10691
  type: "request_body_forbidden_text",
@@ -10663,7 +10693,7 @@ function networkMockRequestBodyFailures(body, mock) {
10663
10693
  });
10664
10694
  }
10665
10695
  }
10666
- for (const pattern of networkMockStringList(mock.request_body_not_patterns)) {
10696
+ for (const pattern of networkMockStringList(source.request_body_not_patterns)) {
10667
10697
  try {
10668
10698
  const regex = new RegExp(pattern);
10669
10699
  if (regex.test(rawBody) || regex.test(compactBody)) {
@@ -10682,6 +10712,9 @@ function networkMockRequestBodyFailures(body, mock) {
10682
10712
  }
10683
10713
  return failures;
10684
10714
  }
10715
+ function networkMockRequestBodyFailures(body, ...sources) {
10716
+ return sources.flatMap((source) => networkMockRequestBodyFailuresForSource(body, source));
10717
+ }
10685
10718
  async function setupLocatorVisible(locator, index) {
10686
10719
  return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
10687
10720
  }
@@ -10710,9 +10743,10 @@ async function registerNetworkMocks(mocks) {
10710
10743
  body = JSON.stringify(response.body_json);
10711
10744
  contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
10712
10745
  }
10713
- const shouldCaptureRequestBody = networkMockShouldCaptureRequestBody(mock);
10746
+ const responseBodyContract = responseIndex === null ? null : response;
10747
+ const shouldCaptureRequestBody = networkMockShouldCaptureRequestBody(mock, responseBodyContract);
10714
10748
  const requestBody = shouldCaptureRequestBody && request.postData ? request.postData() || "" : "";
10715
- const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock) : [];
10749
+ const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock, responseBodyContract) : [];
10716
10750
  const status = response.status || mock.status || 200;
10717
10751
  const event = {
10718
10752
  ok: true,
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ import {
58
58
  resolveRiddleProofProfileTimeoutSec,
59
59
  slugifyRiddleProofProfileName,
60
60
  summarizeRiddleProofProfileResult
61
- } from "./chunk-WSZ5AVKX.js";
61
+ } from "./chunk-NJDY7HYE.js";
62
62
  import {
63
63
  DEFAULT_RIDDLE_API_BASE_URL,
64
64
  DEFAULT_RIDDLE_API_KEY_FILE,
package/dist/profile.cjs CHANGED
@@ -296,24 +296,7 @@ function normalizeNetworkMock(input, index) {
296
296
  const payload = normalizeNetworkMockResponsePayload(input, `target.network_mocks[${index}]`);
297
297
  const responsesInput = input.responses ?? input.sequence;
298
298
  const responses = normalizeNetworkMockResponses(responsesInput, index, payload);
299
- const requestBodyContains = normalizeStringList(
300
- input.request_body_contains ?? input.requestBodyContains ?? input.body_contains ?? input.bodyContains,
301
- `target.network_mocks[${index}].request_body_contains`
302
- );
303
- const requestBodyPatterns = normalizeStringList(
304
- input.request_body_patterns ?? input.requestBodyPatterns ?? input.body_patterns ?? input.bodyPatterns,
305
- `target.network_mocks[${index}].request_body_patterns`
306
- );
307
- validateRegexPatterns(requestBodyPatterns, `target.network_mocks[${index}].request_body_patterns`);
308
- const requestBodyNotContains = normalizeStringList(
309
- input.request_body_not_contains ?? input.requestBodyNotContains ?? input.request_body_absent ?? input.requestBodyAbsent ?? input.body_not_contains ?? input.bodyNotContains ?? input.body_absent ?? input.bodyAbsent,
310
- `target.network_mocks[${index}].request_body_not_contains`
311
- );
312
- const requestBodyNotPatterns = normalizeStringList(
313
- input.request_body_not_patterns ?? input.requestBodyNotPatterns ?? input.request_body_forbidden_patterns ?? input.requestBodyForbiddenPatterns ?? input.body_not_patterns ?? input.bodyNotPatterns ?? input.body_forbidden_patterns ?? input.bodyForbiddenPatterns,
314
- `target.network_mocks[${index}].request_body_not_patterns`
315
- );
316
- validateRegexPatterns(requestBodyNotPatterns, `target.network_mocks[${index}].request_body_not_patterns`);
299
+ const requestBody = normalizeNetworkMockRequestBodyConstraints(input, `target.network_mocks[${index}]`);
317
300
  const requiredHitCount = numberValue(
318
301
  input.required_hit_count ?? input.requiredHitCount ?? input.required_hits ?? input.requiredHits ?? input.min_hits ?? input.minHits
319
302
  );
@@ -329,6 +312,33 @@ function normalizeNetworkMock(input, index) {
329
312
  repeat_responses: input.repeat_responses === true || input.repeatResponses === true || input.cycle_responses === true || input.cycleResponses === true,
330
313
  required_hit_count: requiredHitCount,
331
314
  required: input.required === false ? false : true,
315
+ capture_request_body: requestBody.capture_request_body,
316
+ request_body_contains: requestBody.request_body_contains,
317
+ request_body_patterns: requestBody.request_body_patterns,
318
+ request_body_not_contains: requestBody.request_body_not_contains,
319
+ request_body_not_patterns: requestBody.request_body_not_patterns
320
+ };
321
+ }
322
+ function normalizeNetworkMockRequestBodyConstraints(input, label) {
323
+ const requestBodyContains = normalizeStringList(
324
+ input.request_body_contains ?? input.requestBodyContains ?? input.body_contains ?? input.bodyContains,
325
+ `${label}.request_body_contains`
326
+ );
327
+ const requestBodyPatterns = normalizeStringList(
328
+ input.request_body_patterns ?? input.requestBodyPatterns ?? input.body_patterns ?? input.bodyPatterns,
329
+ `${label}.request_body_patterns`
330
+ );
331
+ validateRegexPatterns(requestBodyPatterns, `${label}.request_body_patterns`);
332
+ const requestBodyNotContains = normalizeStringList(
333
+ input.request_body_not_contains ?? input.requestBodyNotContains ?? input.request_body_absent ?? input.requestBodyAbsent ?? input.body_not_contains ?? input.bodyNotContains ?? input.body_absent ?? input.bodyAbsent,
334
+ `${label}.request_body_not_contains`
335
+ );
336
+ const requestBodyNotPatterns = normalizeStringList(
337
+ input.request_body_not_patterns ?? input.requestBodyNotPatterns ?? input.request_body_forbidden_patterns ?? input.requestBodyForbiddenPatterns ?? input.body_not_patterns ?? input.bodyNotPatterns ?? input.body_forbidden_patterns ?? input.bodyForbiddenPatterns,
338
+ `${label}.request_body_not_patterns`
339
+ );
340
+ validateRegexPatterns(requestBodyNotPatterns, `${label}.request_body_not_patterns`);
341
+ return {
332
342
  capture_request_body: input.capture_request_body === true || input.captureRequestBody === true || Boolean(requestBodyContains?.length) || Boolean(requestBodyPatterns?.length) || Boolean(requestBodyNotContains?.length) || Boolean(requestBodyNotPatterns?.length),
333
343
  request_body_contains: requestBodyContains,
334
344
  request_body_patterns: requestBodyPatterns,
@@ -343,20 +353,33 @@ function normalizeNetworkMockResponsePayload(input, label, defaults = {}) {
343
353
  }
344
354
  const body = stringValue(input.body) ?? stringValue(input.body_text) ?? stringValue(input.bodyText) ?? defaults.body;
345
355
  const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
356
+ const requestBody = normalizeNetworkMockRequestBodyConstraints(input, label);
346
357
  return {
347
358
  label: stringValue(input.label) || stringValue(input.name) || defaults.label,
348
359
  status,
349
360
  content_type: stringValue(input.content_type) || stringValue(input.contentType) || defaults.content_type,
350
361
  headers: stringRecord(input.headers) || defaults.headers,
351
362
  body,
352
- body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json
363
+ body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : defaults.body_json,
364
+ capture_request_body: requestBody.capture_request_body,
365
+ request_body_contains: requestBody.request_body_contains,
366
+ request_body_patterns: requestBody.request_body_patterns,
367
+ request_body_not_contains: requestBody.request_body_not_contains,
368
+ request_body_not_patterns: requestBody.request_body_not_patterns
353
369
  };
354
370
  }
355
371
  function normalizeNetworkMockResponses(value, mockIndex, defaults) {
356
372
  if (value === void 0) return void 0;
357
373
  if (!Array.isArray(value)) throw new Error(`target.network_mocks[${mockIndex}].responses must be an array.`);
358
374
  if (!value.length) throw new Error(`target.network_mocks[${mockIndex}].responses must not be empty.`);
359
- const responseDefaults = { ...defaults, label: void 0 };
375
+ const responseDefaults = {
376
+ label: void 0,
377
+ status: defaults.status,
378
+ content_type: defaults.content_type,
379
+ headers: defaults.headers,
380
+ body: defaults.body,
381
+ body_json: defaults.body_json
382
+ };
360
383
  return value.map((response, responseIndex) => {
361
384
  if (!isRecord(response)) {
362
385
  throw new Error(`target.network_mocks[${mockIndex}].responses[${responseIndex}] must be an object.`);
@@ -1099,6 +1122,9 @@ function assessNetworkMocksFromEvidence(profile, evidence) {
1099
1122
  if (event.request_body_matches === false) {
1100
1123
  failed.push({
1101
1124
  label: event.label ?? null,
1125
+ response_label: event.response_label ?? null,
1126
+ hit_index: event.hit_index ?? null,
1127
+ response_index: event.response_index ?? null,
1102
1128
  url: event.url ?? null,
1103
1129
  method: event.method ?? null,
1104
1130
  reason: "request_body_mismatch",
@@ -1482,6 +1508,9 @@ function assessProfile(profile, evidence) {
1482
1508
  if (event && event.request_body_matches === false) {
1483
1509
  failed.push({
1484
1510
  label: event.label || null,
1511
+ response_label: event.response_label || null,
1512
+ hit_index: event.hit_index ?? null,
1513
+ response_index: event.response_index ?? null,
1485
1514
  url: event.url || null,
1486
1515
  method: event.method || null,
1487
1516
  reason: "request_body_mismatch",
@@ -1946,20 +1975,21 @@ function compactNetworkMockRequestBody(value) {
1946
1975
  function networkMockStringList(value) {
1947
1976
  return Array.isArray(value) ? value.map((item) => String(item)).filter(Boolean) : [];
1948
1977
  }
1949
- function networkMockShouldCaptureRequestBody(mock) {
1950
- return mock && (
1951
- mock.capture_request_body === true
1952
- || networkMockStringList(mock.request_body_contains).length > 0
1953
- || networkMockStringList(mock.request_body_patterns).length > 0
1954
- || networkMockStringList(mock.request_body_not_contains).length > 0
1955
- || networkMockStringList(mock.request_body_not_patterns).length > 0
1956
- );
1978
+ function networkMockShouldCaptureRequestBody(...sources) {
1979
+ return sources.some((source) => source && (
1980
+ source.capture_request_body === true
1981
+ || networkMockStringList(source.request_body_contains).length > 0
1982
+ || networkMockStringList(source.request_body_patterns).length > 0
1983
+ || networkMockStringList(source.request_body_not_contains).length > 0
1984
+ || networkMockStringList(source.request_body_not_patterns).length > 0
1985
+ ));
1957
1986
  }
1958
- function networkMockRequestBodyFailures(body, mock) {
1987
+ function networkMockRequestBodyFailuresForSource(body, source) {
1959
1988
  const failures = [];
1989
+ if (!source) return failures;
1960
1990
  const rawBody = String(body || "");
1961
1991
  const compactBody = compactNetworkMockRequestBody(rawBody);
1962
- for (const expected of networkMockStringList(mock.request_body_contains)) {
1992
+ for (const expected of networkMockStringList(source.request_body_contains)) {
1963
1993
  if (!rawBody.includes(expected) && !compactBody.includes(expected)) {
1964
1994
  failures.push({
1965
1995
  type: "request_body_missing_text",
@@ -1967,7 +1997,7 @@ function networkMockRequestBodyFailures(body, mock) {
1967
1997
  });
1968
1998
  }
1969
1999
  }
1970
- for (const pattern of networkMockStringList(mock.request_body_patterns)) {
2000
+ for (const pattern of networkMockStringList(source.request_body_patterns)) {
1971
2001
  try {
1972
2002
  const regex = new RegExp(pattern);
1973
2003
  if (!regex.test(rawBody) && !regex.test(compactBody)) {
@@ -1984,7 +2014,7 @@ function networkMockRequestBodyFailures(body, mock) {
1984
2014
  });
1985
2015
  }
1986
2016
  }
1987
- for (const forbidden of networkMockStringList(mock.request_body_not_contains)) {
2017
+ for (const forbidden of networkMockStringList(source.request_body_not_contains)) {
1988
2018
  if (rawBody.includes(forbidden) || compactBody.includes(forbidden)) {
1989
2019
  failures.push({
1990
2020
  type: "request_body_forbidden_text",
@@ -1992,7 +2022,7 @@ function networkMockRequestBodyFailures(body, mock) {
1992
2022
  });
1993
2023
  }
1994
2024
  }
1995
- for (const pattern of networkMockStringList(mock.request_body_not_patterns)) {
2025
+ for (const pattern of networkMockStringList(source.request_body_not_patterns)) {
1996
2026
  try {
1997
2027
  const regex = new RegExp(pattern);
1998
2028
  if (regex.test(rawBody) || regex.test(compactBody)) {
@@ -2011,6 +2041,9 @@ function networkMockRequestBodyFailures(body, mock) {
2011
2041
  }
2012
2042
  return failures;
2013
2043
  }
2044
+ function networkMockRequestBodyFailures(body, ...sources) {
2045
+ return sources.flatMap((source) => networkMockRequestBodyFailuresForSource(body, source));
2046
+ }
2014
2047
  async function setupLocatorVisible(locator, index) {
2015
2048
  return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
2016
2049
  }
@@ -2039,9 +2072,10 @@ async function registerNetworkMocks(mocks) {
2039
2072
  body = JSON.stringify(response.body_json);
2040
2073
  contentType = response.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
2041
2074
  }
2042
- const shouldCaptureRequestBody = networkMockShouldCaptureRequestBody(mock);
2075
+ const responseBodyContract = responseIndex === null ? null : response;
2076
+ const shouldCaptureRequestBody = networkMockShouldCaptureRequestBody(mock, responseBodyContract);
2043
2077
  const requestBody = shouldCaptureRequestBody && request.postData ? request.postData() || "" : "";
2044
- const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock) : [];
2078
+ const requestBodyFailures = shouldCaptureRequestBody ? networkMockRequestBodyFailures(requestBody, mock, responseBodyContract) : [];
2045
2079
  const status = response.status || mock.status || 200;
2046
2080
  const event = {
2047
2081
  ok: true,
@@ -41,6 +41,11 @@ interface RiddleProofProfileNetworkMockResponse {
41
41
  headers?: Record<string, string>;
42
42
  body?: string;
43
43
  body_json?: JsonValue;
44
+ capture_request_body?: boolean;
45
+ request_body_contains?: string[];
46
+ request_body_patterns?: string[];
47
+ request_body_not_contains?: string[];
48
+ request_body_not_patterns?: string[];
44
49
  }
45
50
  interface RiddleProofProfileNetworkMock extends RiddleProofProfileNetworkMockResponse {
46
51
  label: string;
package/dist/profile.d.ts CHANGED
@@ -41,6 +41,11 @@ interface RiddleProofProfileNetworkMockResponse {
41
41
  headers?: Record<string, string>;
42
42
  body?: string;
43
43
  body_json?: JsonValue;
44
+ capture_request_body?: boolean;
45
+ request_body_contains?: string[];
46
+ request_body_patterns?: string[];
47
+ request_body_not_contains?: string[];
48
+ request_body_not_patterns?: string[];
44
49
  }
45
50
  interface RiddleProofProfileNetworkMock extends RiddleProofProfileNetworkMockResponse {
46
51
  label: string;
package/dist/profile.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  resolveRiddleProofProfileTimeoutSec,
20
20
  slugifyRiddleProofProfileName,
21
21
  summarizeRiddleProofProfileResult
22
- } from "./chunk-WSZ5AVKX.js";
22
+ } from "./chunk-NJDY7HYE.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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
295
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
385
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
662
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
295
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
385
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "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: "author" | "recon" | "ship" | "implement" | "verify" | "setup" | "run";
662
+ action: "setup" | "recon" | "author" | "implement" | "verify" | "ship" | "run";
663
663
  state_path: string;
664
664
  stage: any;
665
665
  summary: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riddledc/riddle-proof",
3
- "version": "0.7.46",
3
+ "version": "0.7.47",
4
4
  "description": "Reusable Riddle Proof contracts and helpers for evidence-backed agent changes.",
5
5
  "license": "MIT",
6
6
  "author": "RiddleDC",