@riddledc/riddle-proof 0.7.124 → 0.7.126
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 +10 -0
- package/dist/{chunk-JVZWSI55.js → chunk-55KDZEB3.js} +29 -3
- package/dist/cli.cjs +60 -6
- package/dist/cli.js +32 -4
- package/dist/index.cjs +29 -3
- package/dist/index.js +1 -1
- package/dist/profile.cjs +29 -3
- package/dist/profile.d.cts +1 -0
- package/dist/profile.d.ts +1 -0
- package/dist/profile.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -346,6 +346,16 @@ cycle instead of reusing the final response, for example to repeat a fail-then-
|
|
|
346
346
|
success pair across multiple viewports. Repeated sequences also record
|
|
347
347
|
`sequence_cycle: true` after the first cycle.
|
|
348
348
|
|
|
349
|
+
For full viewport-matrix retry profiles, set `sequence_scope: "viewport"` when
|
|
350
|
+
each viewport should get its own first response, second response, and so on.
|
|
351
|
+
This keeps a fail-then-success retry sequence from being consumed by the first
|
|
352
|
+
viewport before phone or tablet runs begin. The mock evidence records both the
|
|
353
|
+
global `hit_index` and viewport-local `sequence_hit_index`, plus the active
|
|
354
|
+
`viewport`, so a run can show that each viewport exercised the same sequence.
|
|
355
|
+
Use `required_hit_count` when the total expected calls matter, such as
|
|
356
|
+
`responses.length * viewports.length` for a two-step retry across four
|
|
357
|
+
viewports.
|
|
358
|
+
|
|
349
359
|
Use `max_hit_count` / `max_hits` when a profile needs to prove a request does
|
|
350
360
|
not run too many times. Use `forbidden: true` as shorthand for
|
|
351
361
|
`max_hit_count: 0` and `required: false`, for example when a chat failure must
|
|
@@ -596,6 +596,20 @@ function normalizeNetworkMock(input, index) {
|
|
|
596
596
|
if (maxHitCount !== void 0 && effectiveRequiredHitCount > maxHitCount) {
|
|
597
597
|
throw new Error(`target.network_mocks[${index}].max_hit_count cannot be less than its required hit count.`);
|
|
598
598
|
}
|
|
599
|
+
const sequenceScopeInput = stringValue(
|
|
600
|
+
input.sequence_scope ?? input.sequenceScope ?? input.response_sequence_scope ?? input.responseSequenceScope
|
|
601
|
+
);
|
|
602
|
+
let sequenceScope;
|
|
603
|
+
if (sequenceScopeInput) {
|
|
604
|
+
const normalizedScope = sequenceScopeInput.toLowerCase().replace(/[-\s]+/g, "_");
|
|
605
|
+
if (normalizedScope === "global" || normalizedScope === "profile" || normalizedScope === "run") {
|
|
606
|
+
sequenceScope = "global";
|
|
607
|
+
} else if (normalizedScope === "viewport" || normalizedScope === "per_viewport" || normalizedScope === "viewport_scoped") {
|
|
608
|
+
sequenceScope = "viewport";
|
|
609
|
+
} else {
|
|
610
|
+
throw new Error(`target.network_mocks[${index}].sequence_scope must be "global" or "viewport".`);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
599
613
|
return {
|
|
600
614
|
...payload,
|
|
601
615
|
label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
|
|
@@ -603,6 +617,7 @@ function normalizeNetworkMock(input, index) {
|
|
|
603
617
|
method: stringValue(input.method)?.toUpperCase(),
|
|
604
618
|
responses,
|
|
605
619
|
repeat_responses: input.repeat_responses === true || input.repeatResponses === true || input.cycle_responses === true || input.cycleResponses === true,
|
|
620
|
+
sequence_scope: sequenceScope,
|
|
606
621
|
required_hit_count: requiredHitCount,
|
|
607
622
|
max_hit_count: maxHitCount,
|
|
608
623
|
forbidden,
|
|
@@ -4254,6 +4269,7 @@ async function setupLocatorVisible(locator, index) {
|
|
|
4254
4269
|
async function registerNetworkMocks(mocks) {
|
|
4255
4270
|
for (const mock of mocks || []) {
|
|
4256
4271
|
let hitCount = 0;
|
|
4272
|
+
const scopedHitCounts = {};
|
|
4257
4273
|
await page.route(mock.url, async (route) => {
|
|
4258
4274
|
const request = route.request();
|
|
4259
4275
|
const method = request.method ? request.method() : "";
|
|
@@ -4269,8 +4285,13 @@ async function registerNetworkMocks(mocks) {
|
|
|
4269
4285
|
const responses = Array.isArray(mock.responses) ? mock.responses : [];
|
|
4270
4286
|
const hitIndex = hitCount;
|
|
4271
4287
|
hitCount += 1;
|
|
4288
|
+
const sequenceScope = mock.sequence_scope === "viewport" ? "viewport" : "global";
|
|
4289
|
+
const viewportName = activeViewportName || null;
|
|
4290
|
+
const sequenceScopeKey = sequenceScope === "viewport" ? (viewportName || "__unknown_viewport__") : "__global__";
|
|
4291
|
+
const sequenceHitIndex = sequenceScope === "viewport" ? (scopedHitCounts[sequenceScopeKey] || 0) : hitIndex;
|
|
4292
|
+
if (sequenceScope === "viewport") scopedHitCounts[sequenceScopeKey] = sequenceHitIndex + 1;
|
|
4272
4293
|
const sequenceResponseIndex = responses.length
|
|
4273
|
-
? (mock.repeat_responses ?
|
|
4294
|
+
? (mock.repeat_responses ? sequenceHitIndex % responses.length : Math.min(sequenceHitIndex, responses.length - 1))
|
|
4274
4295
|
: null;
|
|
4275
4296
|
let responseIndex = sequenceResponseIndex;
|
|
4276
4297
|
let responseSelection = responseIndex === null ? "mock" : "sequence";
|
|
@@ -4305,11 +4326,14 @@ async function registerNetworkMocks(mocks) {
|
|
|
4305
4326
|
label: mock.label,
|
|
4306
4327
|
response_label: response.label || null,
|
|
4307
4328
|
hit_index: hitIndex,
|
|
4329
|
+
sequence_hit_index: responseIndex === null ? undefined : sequenceHitIndex,
|
|
4330
|
+
sequence_scope: responseIndex === null ? undefined : sequenceScope,
|
|
4331
|
+
viewport: viewportName,
|
|
4308
4332
|
response_index: responseIndex,
|
|
4309
4333
|
sequence_response_index: responseSelection === "request_body" ? sequenceResponseIndex : undefined,
|
|
4310
4334
|
response_selection: responseIndex === null ? null : responseSelection,
|
|
4311
|
-
sequence_reused: responseSelection === "sequence" && responseIndex !== null && !mock.repeat_responses &&
|
|
4312
|
-
sequence_cycle: responseSelection === "sequence" && responseIndex !== null && mock.repeat_responses === true &&
|
|
4335
|
+
sequence_reused: responseSelection === "sequence" && responseIndex !== null && !mock.repeat_responses && sequenceHitIndex >= responses.length,
|
|
4336
|
+
sequence_cycle: responseSelection === "sequence" && responseIndex !== null && mock.repeat_responses === true && sequenceHitIndex >= responses.length,
|
|
4313
4337
|
url: request.url(),
|
|
4314
4338
|
method,
|
|
4315
4339
|
};
|
|
@@ -4351,6 +4375,7 @@ async function registerNetworkMocks(mocks) {
|
|
|
4351
4375
|
});
|
|
4352
4376
|
}
|
|
4353
4377
|
}
|
|
4378
|
+
let activeViewportName = null;
|
|
4354
4379
|
async function executeSetupAction(action, ordinal, viewport) {
|
|
4355
4380
|
const type = setupActionType(action);
|
|
4356
4381
|
const frameSelector = setupFrameSelector(action);
|
|
@@ -5613,6 +5638,7 @@ async function collectRouteInventory(check, viewport) {
|
|
|
5613
5638
|
};
|
|
5614
5639
|
}
|
|
5615
5640
|
async function captureViewport(viewport) {
|
|
5641
|
+
activeViewportName = viewport && viewport.name ? viewport.name : null;
|
|
5616
5642
|
await page.setViewportSize({ width: viewport.width, height: viewport.height });
|
|
5617
5643
|
let httpStatus = null;
|
|
5618
5644
|
let navigationError;
|
package/dist/cli.cjs
CHANGED
|
@@ -7533,6 +7533,20 @@ function normalizeNetworkMock(input, index) {
|
|
|
7533
7533
|
if (maxHitCount !== void 0 && effectiveRequiredHitCount > maxHitCount) {
|
|
7534
7534
|
throw new Error(`target.network_mocks[${index}].max_hit_count cannot be less than its required hit count.`);
|
|
7535
7535
|
}
|
|
7536
|
+
const sequenceScopeInput = stringValue2(
|
|
7537
|
+
input.sequence_scope ?? input.sequenceScope ?? input.response_sequence_scope ?? input.responseSequenceScope
|
|
7538
|
+
);
|
|
7539
|
+
let sequenceScope;
|
|
7540
|
+
if (sequenceScopeInput) {
|
|
7541
|
+
const normalizedScope = sequenceScopeInput.toLowerCase().replace(/[-\s]+/g, "_");
|
|
7542
|
+
if (normalizedScope === "global" || normalizedScope === "profile" || normalizedScope === "run") {
|
|
7543
|
+
sequenceScope = "global";
|
|
7544
|
+
} else if (normalizedScope === "viewport" || normalizedScope === "per_viewport" || normalizedScope === "viewport_scoped") {
|
|
7545
|
+
sequenceScope = "viewport";
|
|
7546
|
+
} else {
|
|
7547
|
+
throw new Error(`target.network_mocks[${index}].sequence_scope must be "global" or "viewport".`);
|
|
7548
|
+
}
|
|
7549
|
+
}
|
|
7536
7550
|
return {
|
|
7537
7551
|
...payload,
|
|
7538
7552
|
label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
|
|
@@ -7540,6 +7554,7 @@ function normalizeNetworkMock(input, index) {
|
|
|
7540
7554
|
method: stringValue2(input.method)?.toUpperCase(),
|
|
7541
7555
|
responses,
|
|
7542
7556
|
repeat_responses: input.repeat_responses === true || input.repeatResponses === true || input.cycle_responses === true || input.cycleResponses === true,
|
|
7557
|
+
sequence_scope: sequenceScope,
|
|
7543
7558
|
required_hit_count: requiredHitCount,
|
|
7544
7559
|
max_hit_count: maxHitCount,
|
|
7545
7560
|
forbidden,
|
|
@@ -11175,6 +11190,7 @@ async function setupLocatorVisible(locator, index) {
|
|
|
11175
11190
|
async function registerNetworkMocks(mocks) {
|
|
11176
11191
|
for (const mock of mocks || []) {
|
|
11177
11192
|
let hitCount = 0;
|
|
11193
|
+
const scopedHitCounts = {};
|
|
11178
11194
|
await page.route(mock.url, async (route) => {
|
|
11179
11195
|
const request = route.request();
|
|
11180
11196
|
const method = request.method ? request.method() : "";
|
|
@@ -11190,8 +11206,13 @@ async function registerNetworkMocks(mocks) {
|
|
|
11190
11206
|
const responses = Array.isArray(mock.responses) ? mock.responses : [];
|
|
11191
11207
|
const hitIndex = hitCount;
|
|
11192
11208
|
hitCount += 1;
|
|
11209
|
+
const sequenceScope = mock.sequence_scope === "viewport" ? "viewport" : "global";
|
|
11210
|
+
const viewportName = activeViewportName || null;
|
|
11211
|
+
const sequenceScopeKey = sequenceScope === "viewport" ? (viewportName || "__unknown_viewport__") : "__global__";
|
|
11212
|
+
const sequenceHitIndex = sequenceScope === "viewport" ? (scopedHitCounts[sequenceScopeKey] || 0) : hitIndex;
|
|
11213
|
+
if (sequenceScope === "viewport") scopedHitCounts[sequenceScopeKey] = sequenceHitIndex + 1;
|
|
11193
11214
|
const sequenceResponseIndex = responses.length
|
|
11194
|
-
? (mock.repeat_responses ?
|
|
11215
|
+
? (mock.repeat_responses ? sequenceHitIndex % responses.length : Math.min(sequenceHitIndex, responses.length - 1))
|
|
11195
11216
|
: null;
|
|
11196
11217
|
let responseIndex = sequenceResponseIndex;
|
|
11197
11218
|
let responseSelection = responseIndex === null ? "mock" : "sequence";
|
|
@@ -11226,11 +11247,14 @@ async function registerNetworkMocks(mocks) {
|
|
|
11226
11247
|
label: mock.label,
|
|
11227
11248
|
response_label: response.label || null,
|
|
11228
11249
|
hit_index: hitIndex,
|
|
11250
|
+
sequence_hit_index: responseIndex === null ? undefined : sequenceHitIndex,
|
|
11251
|
+
sequence_scope: responseIndex === null ? undefined : sequenceScope,
|
|
11252
|
+
viewport: viewportName,
|
|
11229
11253
|
response_index: responseIndex,
|
|
11230
11254
|
sequence_response_index: responseSelection === "request_body" ? sequenceResponseIndex : undefined,
|
|
11231
11255
|
response_selection: responseIndex === null ? null : responseSelection,
|
|
11232
|
-
sequence_reused: responseSelection === "sequence" && responseIndex !== null && !mock.repeat_responses &&
|
|
11233
|
-
sequence_cycle: responseSelection === "sequence" && responseIndex !== null && mock.repeat_responses === true &&
|
|
11256
|
+
sequence_reused: responseSelection === "sequence" && responseIndex !== null && !mock.repeat_responses && sequenceHitIndex >= responses.length,
|
|
11257
|
+
sequence_cycle: responseSelection === "sequence" && responseIndex !== null && mock.repeat_responses === true && sequenceHitIndex >= responses.length,
|
|
11234
11258
|
url: request.url(),
|
|
11235
11259
|
method,
|
|
11236
11260
|
};
|
|
@@ -11272,6 +11296,7 @@ async function registerNetworkMocks(mocks) {
|
|
|
11272
11296
|
});
|
|
11273
11297
|
}
|
|
11274
11298
|
}
|
|
11299
|
+
let activeViewportName = null;
|
|
11275
11300
|
async function executeSetupAction(action, ordinal, viewport) {
|
|
11276
11301
|
const type = setupActionType(action);
|
|
11277
11302
|
const frameSelector = setupFrameSelector(action);
|
|
@@ -12534,6 +12559,7 @@ async function collectRouteInventory(check, viewport) {
|
|
|
12534
12559
|
};
|
|
12535
12560
|
}
|
|
12536
12561
|
async function captureViewport(viewport) {
|
|
12562
|
+
activeViewportName = viewport && viewport.name ? viewport.name : null;
|
|
12537
12563
|
await page.setViewportSize({ width: viewport.width, height: viewport.height });
|
|
12538
12564
|
let httpStatus = null;
|
|
12539
12565
|
let navigationError;
|
|
@@ -13646,6 +13672,19 @@ function profileHttpStatusAssertionCount(viewports, field, expected, passValue)
|
|
|
13646
13672
|
}
|
|
13647
13673
|
return { passed, total: expected.length * viewports.length };
|
|
13648
13674
|
}
|
|
13675
|
+
function profileHttpStatusAssertionKeys(evidence, viewports, field) {
|
|
13676
|
+
const explicit = cliStringArray(evidence[field]);
|
|
13677
|
+
if (explicit.length) return explicit;
|
|
13678
|
+
const keys = /* @__PURE__ */ new Set();
|
|
13679
|
+
for (const viewport of viewports) {
|
|
13680
|
+
const observed = cliRecord(viewport[field]);
|
|
13681
|
+
if (!observed) continue;
|
|
13682
|
+
for (const key of Object.keys(observed)) {
|
|
13683
|
+
if (key) keys.add(key);
|
|
13684
|
+
}
|
|
13685
|
+
}
|
|
13686
|
+
return [...keys];
|
|
13687
|
+
}
|
|
13649
13688
|
function profileHttpStatusSummaryMarkdown(result) {
|
|
13650
13689
|
const httpStatusChecks = result.checks.filter((check) => check.type === "http_status");
|
|
13651
13690
|
const lines = [];
|
|
@@ -13658,9 +13697,24 @@ function profileHttpStatusSummaryMarkdown(result) {
|
|
|
13658
13697
|
const viewports = Array.isArray(evidence.viewports) ? evidence.viewports.map(cliRecord).filter((viewport) => Boolean(viewport)) : [];
|
|
13659
13698
|
const statuses = viewports.map((viewport) => cliFiniteNumber(viewport.status)).map((status) => status === void 0 ? "error" : String(status));
|
|
13660
13699
|
const failedTotal = Array.isArray(evidence.failures) ? evidence.failures.length : 0;
|
|
13661
|
-
const bodyContains = profileHttpStatusAssertionCount(
|
|
13662
|
-
|
|
13663
|
-
|
|
13700
|
+
const bodyContains = profileHttpStatusAssertionCount(
|
|
13701
|
+
viewports,
|
|
13702
|
+
"body_contains",
|
|
13703
|
+
profileHttpStatusAssertionKeys(evidence, viewports, "body_contains"),
|
|
13704
|
+
true
|
|
13705
|
+
);
|
|
13706
|
+
const bodyNotContains = profileHttpStatusAssertionCount(
|
|
13707
|
+
viewports,
|
|
13708
|
+
"body_not_contains",
|
|
13709
|
+
profileHttpStatusAssertionKeys(evidence, viewports, "body_not_contains"),
|
|
13710
|
+
false
|
|
13711
|
+
);
|
|
13712
|
+
const bodyNotPatterns = profileHttpStatusAssertionCount(
|
|
13713
|
+
viewports,
|
|
13714
|
+
"body_not_patterns",
|
|
13715
|
+
profileHttpStatusAssertionKeys(evidence, viewports, "body_not_patterns"),
|
|
13716
|
+
false
|
|
13717
|
+
);
|
|
13664
13718
|
const bodyParts = [
|
|
13665
13719
|
bodyContains ? `body_contains ${bodyContains.passed}/${bodyContains.total}` : "",
|
|
13666
13720
|
bodyNotContains ? `body_not_contains clean ${bodyNotContains.passed}/${bodyNotContains.total}` : "",
|
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
profileStatusExitCode,
|
|
13
13
|
resolveRiddleProofProfileTargetUrl,
|
|
14
14
|
resolveRiddleProofProfileTimeoutSec
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-55KDZEB3.js";
|
|
16
16
|
import {
|
|
17
17
|
createRiddleApiClient,
|
|
18
18
|
parseRiddleViewport
|
|
@@ -728,6 +728,19 @@ function profileHttpStatusAssertionCount(viewports, field, expected, passValue)
|
|
|
728
728
|
}
|
|
729
729
|
return { passed, total: expected.length * viewports.length };
|
|
730
730
|
}
|
|
731
|
+
function profileHttpStatusAssertionKeys(evidence, viewports, field) {
|
|
732
|
+
const explicit = cliStringArray(evidence[field]);
|
|
733
|
+
if (explicit.length) return explicit;
|
|
734
|
+
const keys = /* @__PURE__ */ new Set();
|
|
735
|
+
for (const viewport of viewports) {
|
|
736
|
+
const observed = cliRecord(viewport[field]);
|
|
737
|
+
if (!observed) continue;
|
|
738
|
+
for (const key of Object.keys(observed)) {
|
|
739
|
+
if (key) keys.add(key);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
return [...keys];
|
|
743
|
+
}
|
|
731
744
|
function profileHttpStatusSummaryMarkdown(result) {
|
|
732
745
|
const httpStatusChecks = result.checks.filter((check) => check.type === "http_status");
|
|
733
746
|
const lines = [];
|
|
@@ -740,9 +753,24 @@ function profileHttpStatusSummaryMarkdown(result) {
|
|
|
740
753
|
const viewports = Array.isArray(evidence.viewports) ? evidence.viewports.map(cliRecord).filter((viewport) => Boolean(viewport)) : [];
|
|
741
754
|
const statuses = viewports.map((viewport) => cliFiniteNumber(viewport.status)).map((status) => status === void 0 ? "error" : String(status));
|
|
742
755
|
const failedTotal = Array.isArray(evidence.failures) ? evidence.failures.length : 0;
|
|
743
|
-
const bodyContains = profileHttpStatusAssertionCount(
|
|
744
|
-
|
|
745
|
-
|
|
756
|
+
const bodyContains = profileHttpStatusAssertionCount(
|
|
757
|
+
viewports,
|
|
758
|
+
"body_contains",
|
|
759
|
+
profileHttpStatusAssertionKeys(evidence, viewports, "body_contains"),
|
|
760
|
+
true
|
|
761
|
+
);
|
|
762
|
+
const bodyNotContains = profileHttpStatusAssertionCount(
|
|
763
|
+
viewports,
|
|
764
|
+
"body_not_contains",
|
|
765
|
+
profileHttpStatusAssertionKeys(evidence, viewports, "body_not_contains"),
|
|
766
|
+
false
|
|
767
|
+
);
|
|
768
|
+
const bodyNotPatterns = profileHttpStatusAssertionCount(
|
|
769
|
+
viewports,
|
|
770
|
+
"body_not_patterns",
|
|
771
|
+
profileHttpStatusAssertionKeys(evidence, viewports, "body_not_patterns"),
|
|
772
|
+
false
|
|
773
|
+
);
|
|
746
774
|
const bodyParts = [
|
|
747
775
|
bodyContains ? `body_contains ${bodyContains.passed}/${bodyContains.total}` : "",
|
|
748
776
|
bodyNotContains ? `body_not_contains clean ${bodyNotContains.passed}/${bodyNotContains.total}` : "",
|
package/dist/index.cjs
CHANGED
|
@@ -9329,6 +9329,20 @@ function normalizeNetworkMock(input, index) {
|
|
|
9329
9329
|
if (maxHitCount !== void 0 && effectiveRequiredHitCount > maxHitCount) {
|
|
9330
9330
|
throw new Error(`target.network_mocks[${index}].max_hit_count cannot be less than its required hit count.`);
|
|
9331
9331
|
}
|
|
9332
|
+
const sequenceScopeInput = stringValue5(
|
|
9333
|
+
input.sequence_scope ?? input.sequenceScope ?? input.response_sequence_scope ?? input.responseSequenceScope
|
|
9334
|
+
);
|
|
9335
|
+
let sequenceScope;
|
|
9336
|
+
if (sequenceScopeInput) {
|
|
9337
|
+
const normalizedScope = sequenceScopeInput.toLowerCase().replace(/[-\s]+/g, "_");
|
|
9338
|
+
if (normalizedScope === "global" || normalizedScope === "profile" || normalizedScope === "run") {
|
|
9339
|
+
sequenceScope = "global";
|
|
9340
|
+
} else if (normalizedScope === "viewport" || normalizedScope === "per_viewport" || normalizedScope === "viewport_scoped") {
|
|
9341
|
+
sequenceScope = "viewport";
|
|
9342
|
+
} else {
|
|
9343
|
+
throw new Error(`target.network_mocks[${index}].sequence_scope must be "global" or "viewport".`);
|
|
9344
|
+
}
|
|
9345
|
+
}
|
|
9332
9346
|
return {
|
|
9333
9347
|
...payload,
|
|
9334
9348
|
label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
|
|
@@ -9336,6 +9350,7 @@ function normalizeNetworkMock(input, index) {
|
|
|
9336
9350
|
method: stringValue5(input.method)?.toUpperCase(),
|
|
9337
9351
|
responses,
|
|
9338
9352
|
repeat_responses: input.repeat_responses === true || input.repeatResponses === true || input.cycle_responses === true || input.cycleResponses === true,
|
|
9353
|
+
sequence_scope: sequenceScope,
|
|
9339
9354
|
required_hit_count: requiredHitCount,
|
|
9340
9355
|
max_hit_count: maxHitCount,
|
|
9341
9356
|
forbidden,
|
|
@@ -12987,6 +13002,7 @@ async function setupLocatorVisible(locator, index) {
|
|
|
12987
13002
|
async function registerNetworkMocks(mocks) {
|
|
12988
13003
|
for (const mock of mocks || []) {
|
|
12989
13004
|
let hitCount = 0;
|
|
13005
|
+
const scopedHitCounts = {};
|
|
12990
13006
|
await page.route(mock.url, async (route) => {
|
|
12991
13007
|
const request = route.request();
|
|
12992
13008
|
const method = request.method ? request.method() : "";
|
|
@@ -13002,8 +13018,13 @@ async function registerNetworkMocks(mocks) {
|
|
|
13002
13018
|
const responses = Array.isArray(mock.responses) ? mock.responses : [];
|
|
13003
13019
|
const hitIndex = hitCount;
|
|
13004
13020
|
hitCount += 1;
|
|
13021
|
+
const sequenceScope = mock.sequence_scope === "viewport" ? "viewport" : "global";
|
|
13022
|
+
const viewportName = activeViewportName || null;
|
|
13023
|
+
const sequenceScopeKey = sequenceScope === "viewport" ? (viewportName || "__unknown_viewport__") : "__global__";
|
|
13024
|
+
const sequenceHitIndex = sequenceScope === "viewport" ? (scopedHitCounts[sequenceScopeKey] || 0) : hitIndex;
|
|
13025
|
+
if (sequenceScope === "viewport") scopedHitCounts[sequenceScopeKey] = sequenceHitIndex + 1;
|
|
13005
13026
|
const sequenceResponseIndex = responses.length
|
|
13006
|
-
? (mock.repeat_responses ?
|
|
13027
|
+
? (mock.repeat_responses ? sequenceHitIndex % responses.length : Math.min(sequenceHitIndex, responses.length - 1))
|
|
13007
13028
|
: null;
|
|
13008
13029
|
let responseIndex = sequenceResponseIndex;
|
|
13009
13030
|
let responseSelection = responseIndex === null ? "mock" : "sequence";
|
|
@@ -13038,11 +13059,14 @@ async function registerNetworkMocks(mocks) {
|
|
|
13038
13059
|
label: mock.label,
|
|
13039
13060
|
response_label: response.label || null,
|
|
13040
13061
|
hit_index: hitIndex,
|
|
13062
|
+
sequence_hit_index: responseIndex === null ? undefined : sequenceHitIndex,
|
|
13063
|
+
sequence_scope: responseIndex === null ? undefined : sequenceScope,
|
|
13064
|
+
viewport: viewportName,
|
|
13041
13065
|
response_index: responseIndex,
|
|
13042
13066
|
sequence_response_index: responseSelection === "request_body" ? sequenceResponseIndex : undefined,
|
|
13043
13067
|
response_selection: responseIndex === null ? null : responseSelection,
|
|
13044
|
-
sequence_reused: responseSelection === "sequence" && responseIndex !== null && !mock.repeat_responses &&
|
|
13045
|
-
sequence_cycle: responseSelection === "sequence" && responseIndex !== null && mock.repeat_responses === true &&
|
|
13068
|
+
sequence_reused: responseSelection === "sequence" && responseIndex !== null && !mock.repeat_responses && sequenceHitIndex >= responses.length,
|
|
13069
|
+
sequence_cycle: responseSelection === "sequence" && responseIndex !== null && mock.repeat_responses === true && sequenceHitIndex >= responses.length,
|
|
13046
13070
|
url: request.url(),
|
|
13047
13071
|
method,
|
|
13048
13072
|
};
|
|
@@ -13084,6 +13108,7 @@ async function registerNetworkMocks(mocks) {
|
|
|
13084
13108
|
});
|
|
13085
13109
|
}
|
|
13086
13110
|
}
|
|
13111
|
+
let activeViewportName = null;
|
|
13087
13112
|
async function executeSetupAction(action, ordinal, viewport) {
|
|
13088
13113
|
const type = setupActionType(action);
|
|
13089
13114
|
const frameSelector = setupFrameSelector(action);
|
|
@@ -14346,6 +14371,7 @@ async function collectRouteInventory(check, viewport) {
|
|
|
14346
14371
|
};
|
|
14347
14372
|
}
|
|
14348
14373
|
async function captureViewport(viewport) {
|
|
14374
|
+
activeViewportName = viewport && viewport.name ? viewport.name : null;
|
|
14349
14375
|
await page.setViewportSize({ width: viewport.width, height: viewport.height });
|
|
14350
14376
|
let httpStatus = null;
|
|
14351
14377
|
let navigationError;
|
package/dist/index.js
CHANGED
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
resolveRiddleProofProfileTimeoutSec,
|
|
63
63
|
slugifyRiddleProofProfileName,
|
|
64
64
|
summarizeRiddleProofProfileResult
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-55KDZEB3.js";
|
|
66
66
|
import {
|
|
67
67
|
DEFAULT_RIDDLE_API_BASE_URL,
|
|
68
68
|
DEFAULT_RIDDLE_API_KEY_FILE,
|
package/dist/profile.cjs
CHANGED
|
@@ -643,6 +643,20 @@ function normalizeNetworkMock(input, index) {
|
|
|
643
643
|
if (maxHitCount !== void 0 && effectiveRequiredHitCount > maxHitCount) {
|
|
644
644
|
throw new Error(`target.network_mocks[${index}].max_hit_count cannot be less than its required hit count.`);
|
|
645
645
|
}
|
|
646
|
+
const sequenceScopeInput = stringValue(
|
|
647
|
+
input.sequence_scope ?? input.sequenceScope ?? input.response_sequence_scope ?? input.responseSequenceScope
|
|
648
|
+
);
|
|
649
|
+
let sequenceScope;
|
|
650
|
+
if (sequenceScopeInput) {
|
|
651
|
+
const normalizedScope = sequenceScopeInput.toLowerCase().replace(/[-\s]+/g, "_");
|
|
652
|
+
if (normalizedScope === "global" || normalizedScope === "profile" || normalizedScope === "run") {
|
|
653
|
+
sequenceScope = "global";
|
|
654
|
+
} else if (normalizedScope === "viewport" || normalizedScope === "per_viewport" || normalizedScope === "viewport_scoped") {
|
|
655
|
+
sequenceScope = "viewport";
|
|
656
|
+
} else {
|
|
657
|
+
throw new Error(`target.network_mocks[${index}].sequence_scope must be "global" or "viewport".`);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
646
660
|
return {
|
|
647
661
|
...payload,
|
|
648
662
|
label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
|
|
@@ -650,6 +664,7 @@ function normalizeNetworkMock(input, index) {
|
|
|
650
664
|
method: stringValue(input.method)?.toUpperCase(),
|
|
651
665
|
responses,
|
|
652
666
|
repeat_responses: input.repeat_responses === true || input.repeatResponses === true || input.cycle_responses === true || input.cycleResponses === true,
|
|
667
|
+
sequence_scope: sequenceScope,
|
|
653
668
|
required_hit_count: requiredHitCount,
|
|
654
669
|
max_hit_count: maxHitCount,
|
|
655
670
|
forbidden,
|
|
@@ -4301,6 +4316,7 @@ async function setupLocatorVisible(locator, index) {
|
|
|
4301
4316
|
async function registerNetworkMocks(mocks) {
|
|
4302
4317
|
for (const mock of mocks || []) {
|
|
4303
4318
|
let hitCount = 0;
|
|
4319
|
+
const scopedHitCounts = {};
|
|
4304
4320
|
await page.route(mock.url, async (route) => {
|
|
4305
4321
|
const request = route.request();
|
|
4306
4322
|
const method = request.method ? request.method() : "";
|
|
@@ -4316,8 +4332,13 @@ async function registerNetworkMocks(mocks) {
|
|
|
4316
4332
|
const responses = Array.isArray(mock.responses) ? mock.responses : [];
|
|
4317
4333
|
const hitIndex = hitCount;
|
|
4318
4334
|
hitCount += 1;
|
|
4335
|
+
const sequenceScope = mock.sequence_scope === "viewport" ? "viewport" : "global";
|
|
4336
|
+
const viewportName = activeViewportName || null;
|
|
4337
|
+
const sequenceScopeKey = sequenceScope === "viewport" ? (viewportName || "__unknown_viewport__") : "__global__";
|
|
4338
|
+
const sequenceHitIndex = sequenceScope === "viewport" ? (scopedHitCounts[sequenceScopeKey] || 0) : hitIndex;
|
|
4339
|
+
if (sequenceScope === "viewport") scopedHitCounts[sequenceScopeKey] = sequenceHitIndex + 1;
|
|
4319
4340
|
const sequenceResponseIndex = responses.length
|
|
4320
|
-
? (mock.repeat_responses ?
|
|
4341
|
+
? (mock.repeat_responses ? sequenceHitIndex % responses.length : Math.min(sequenceHitIndex, responses.length - 1))
|
|
4321
4342
|
: null;
|
|
4322
4343
|
let responseIndex = sequenceResponseIndex;
|
|
4323
4344
|
let responseSelection = responseIndex === null ? "mock" : "sequence";
|
|
@@ -4352,11 +4373,14 @@ async function registerNetworkMocks(mocks) {
|
|
|
4352
4373
|
label: mock.label,
|
|
4353
4374
|
response_label: response.label || null,
|
|
4354
4375
|
hit_index: hitIndex,
|
|
4376
|
+
sequence_hit_index: responseIndex === null ? undefined : sequenceHitIndex,
|
|
4377
|
+
sequence_scope: responseIndex === null ? undefined : sequenceScope,
|
|
4378
|
+
viewport: viewportName,
|
|
4355
4379
|
response_index: responseIndex,
|
|
4356
4380
|
sequence_response_index: responseSelection === "request_body" ? sequenceResponseIndex : undefined,
|
|
4357
4381
|
response_selection: responseIndex === null ? null : responseSelection,
|
|
4358
|
-
sequence_reused: responseSelection === "sequence" && responseIndex !== null && !mock.repeat_responses &&
|
|
4359
|
-
sequence_cycle: responseSelection === "sequence" && responseIndex !== null && mock.repeat_responses === true &&
|
|
4382
|
+
sequence_reused: responseSelection === "sequence" && responseIndex !== null && !mock.repeat_responses && sequenceHitIndex >= responses.length,
|
|
4383
|
+
sequence_cycle: responseSelection === "sequence" && responseIndex !== null && mock.repeat_responses === true && sequenceHitIndex >= responses.length,
|
|
4360
4384
|
url: request.url(),
|
|
4361
4385
|
method,
|
|
4362
4386
|
};
|
|
@@ -4398,6 +4422,7 @@ async function registerNetworkMocks(mocks) {
|
|
|
4398
4422
|
});
|
|
4399
4423
|
}
|
|
4400
4424
|
}
|
|
4425
|
+
let activeViewportName = null;
|
|
4401
4426
|
async function executeSetupAction(action, ordinal, viewport) {
|
|
4402
4427
|
const type = setupActionType(action);
|
|
4403
4428
|
const frameSelector = setupFrameSelector(action);
|
|
@@ -5660,6 +5685,7 @@ async function collectRouteInventory(check, viewport) {
|
|
|
5660
5685
|
};
|
|
5661
5686
|
}
|
|
5662
5687
|
async function captureViewport(viewport) {
|
|
5688
|
+
activeViewportName = viewport && viewport.name ? viewport.name : null;
|
|
5663
5689
|
await page.setViewportSize({ width: viewport.width, height: viewport.height });
|
|
5664
5690
|
let httpStatus = null;
|
|
5665
5691
|
let navigationError;
|
package/dist/profile.d.cts
CHANGED
|
@@ -142,6 +142,7 @@ interface RiddleProofProfileNetworkMock extends RiddleProofProfileNetworkMockRes
|
|
|
142
142
|
method?: string;
|
|
143
143
|
responses?: RiddleProofProfileNetworkMockResponse[];
|
|
144
144
|
repeat_responses?: boolean;
|
|
145
|
+
sequence_scope?: "global" | "viewport";
|
|
145
146
|
required_hit_count?: number;
|
|
146
147
|
max_hit_count?: number;
|
|
147
148
|
forbidden?: boolean;
|
package/dist/profile.d.ts
CHANGED
|
@@ -142,6 +142,7 @@ interface RiddleProofProfileNetworkMock extends RiddleProofProfileNetworkMockRes
|
|
|
142
142
|
method?: string;
|
|
143
143
|
responses?: RiddleProofProfileNetworkMockResponse[];
|
|
144
144
|
repeat_responses?: boolean;
|
|
145
|
+
sequence_scope?: "global" | "viewport";
|
|
145
146
|
required_hit_count?: number;
|
|
146
147
|
max_hit_count?: number;
|
|
147
148
|
forbidden?: boolean;
|
package/dist/profile.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
resolveRiddleProofProfileTimeoutSec,
|
|
24
24
|
slugifyRiddleProofProfileName,
|
|
25
25
|
summarizeRiddleProofProfileResult
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-55KDZEB3.js";
|
|
27
27
|
export {
|
|
28
28
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
29
29
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|