@riddledc/riddle-proof 0.7.26 → 0.7.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-SDSBS64X.js → chunk-NUGGW7NX.js} +232 -2
- package/dist/cli.cjs +232 -2
- package/dist/cli.js +1 -1
- package/dist/index.cjs +232 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/profile.cjs +232 -2
- package/dist/profile.d.cts +19 -2
- package/dist/profile.d.ts +19 -2
- package/dist/profile.js +1 -1
- package/dist/proof-run-engine.d.cts +3 -3
- package/dist/proof-run-engine.d.ts +3 -3
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -6895,6 +6895,9 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
6895
6895
|
];
|
|
6896
6896
|
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
6897
6897
|
"click",
|
|
6898
|
+
"fill",
|
|
6899
|
+
"set_input_value",
|
|
6900
|
+
"local_storage",
|
|
6898
6901
|
"wait",
|
|
6899
6902
|
"wait_for_selector",
|
|
6900
6903
|
"wait_for_text"
|
|
@@ -6908,6 +6911,18 @@ function isRecord(value) {
|
|
|
6908
6911
|
function stringValue2(value) {
|
|
6909
6912
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
6910
6913
|
}
|
|
6914
|
+
function hasOwn(value, key) {
|
|
6915
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
6916
|
+
}
|
|
6917
|
+
function stringFromOwn(input, ...keys) {
|
|
6918
|
+
for (const key of keys) {
|
|
6919
|
+
if (hasOwn(input, key)) {
|
|
6920
|
+
const value = input[key];
|
|
6921
|
+
if (value !== void 0 && value !== null) return String(value);
|
|
6922
|
+
}
|
|
6923
|
+
}
|
|
6924
|
+
return void 0;
|
|
6925
|
+
}
|
|
6911
6926
|
function numberValue(value) {
|
|
6912
6927
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
6913
6928
|
}
|
|
@@ -6992,6 +7007,11 @@ function jsonRecord(value) {
|
|
|
6992
7007
|
if (!isRecord(value)) return void 0;
|
|
6993
7008
|
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, toJsonValue(child)]));
|
|
6994
7009
|
}
|
|
7010
|
+
function stringRecord(value) {
|
|
7011
|
+
if (!isRecord(value)) return void 0;
|
|
7012
|
+
const entries = Object.entries(value).map(([key, child]) => [key, String(child)]).filter(([key]) => key.trim());
|
|
7013
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
7014
|
+
}
|
|
6995
7015
|
function toJsonValue(value) {
|
|
6996
7016
|
if (value === null || value === void 0) return null;
|
|
6997
7017
|
if (typeof value === "string" || typeof value === "boolean") return value;
|
|
@@ -7039,15 +7059,30 @@ function normalizeSetupAction(input, index) {
|
|
|
7039
7059
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
7040
7060
|
const type = normalizeSetupActionType(stringValue2(input.type), index);
|
|
7041
7061
|
const selector = stringValue2(input.selector);
|
|
7042
|
-
if ((type === "click" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
|
|
7062
|
+
if ((type === "click" || type === "fill" || type === "set_input_value" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
|
|
7043
7063
|
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
7044
7064
|
}
|
|
7045
7065
|
if (type === "wait_for_text" && !stringValue2(input.text) && !stringValue2(input.pattern)) {
|
|
7046
7066
|
throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
|
|
7047
7067
|
}
|
|
7068
|
+
const value = stringFromOwn(input, "value", "input_value", "inputValue");
|
|
7069
|
+
const hasJsonValue = hasOwn(input, "value_json") || hasOwn(input, "valueJson") || hasOwn(input, "json");
|
|
7070
|
+
if ((type === "fill" || type === "set_input_value") && value === void 0 && !hasJsonValue) {
|
|
7071
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
7072
|
+
}
|
|
7073
|
+
const key = stringValue2(input.key);
|
|
7074
|
+
if (type === "local_storage" && !key) {
|
|
7075
|
+
throw new Error(`target.setup_actions[${index}] local_storage requires key.`);
|
|
7076
|
+
}
|
|
7077
|
+
if (type === "local_storage" && value === void 0 && !hasJsonValue) {
|
|
7078
|
+
throw new Error(`target.setup_actions[${index}] local_storage requires value.`);
|
|
7079
|
+
}
|
|
7048
7080
|
return {
|
|
7049
7081
|
type,
|
|
7050
7082
|
selector,
|
|
7083
|
+
key,
|
|
7084
|
+
value,
|
|
7085
|
+
value_json: hasJsonValue ? toJsonValue(input.value_json ?? input.valueJson ?? input.json) : void 0,
|
|
7051
7086
|
text: stringValue2(input.text),
|
|
7052
7087
|
pattern: stringValue2(input.pattern),
|
|
7053
7088
|
flags: stringValue2(input.flags),
|
|
@@ -7055,6 +7090,7 @@ function normalizeSetupAction(input, index) {
|
|
|
7055
7090
|
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
7056
7091
|
timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
|
|
7057
7092
|
after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
|
|
7093
|
+
reload: input.reload === true,
|
|
7058
7094
|
continue_on_failure: input.continue_on_failure === true || input.continueOnFailure === true
|
|
7059
7095
|
};
|
|
7060
7096
|
}
|
|
@@ -7063,6 +7099,33 @@ function normalizeSetupActions(value) {
|
|
|
7063
7099
|
if (!Array.isArray(value)) throw new Error("target.setup_actions must be an array.");
|
|
7064
7100
|
return value.map(normalizeSetupAction);
|
|
7065
7101
|
}
|
|
7102
|
+
function normalizeNetworkMock(input, index) {
|
|
7103
|
+
if (!isRecord(input)) throw new Error(`target.network_mocks[${index}] must be an object.`);
|
|
7104
|
+
const url = stringValue2(input.url) || stringValue2(input.glob) || stringValue2(input.pattern);
|
|
7105
|
+
if (!url) throw new Error(`target.network_mocks[${index}] requires url.`);
|
|
7106
|
+
const status = numberValue(input.status) ?? 200;
|
|
7107
|
+
if (!Number.isInteger(status) || status < 100 || status > 599) {
|
|
7108
|
+
throw new Error(`target.network_mocks[${index}].status must be an HTTP status code.`);
|
|
7109
|
+
}
|
|
7110
|
+
const body = stringValue2(input.body) ?? stringValue2(input.body_text) ?? stringValue2(input.bodyText);
|
|
7111
|
+
const hasJsonBody = Object.prototype.hasOwnProperty.call(input, "body_json") || Object.prototype.hasOwnProperty.call(input, "bodyJson") || Object.prototype.hasOwnProperty.call(input, "json");
|
|
7112
|
+
return {
|
|
7113
|
+
label: normalizeName(input.label || input.name, `network-mock-${index + 1}`),
|
|
7114
|
+
url,
|
|
7115
|
+
method: stringValue2(input.method)?.toUpperCase(),
|
|
7116
|
+
status,
|
|
7117
|
+
content_type: stringValue2(input.content_type) || stringValue2(input.contentType),
|
|
7118
|
+
headers: stringRecord(input.headers),
|
|
7119
|
+
body,
|
|
7120
|
+
body_json: hasJsonBody ? toJsonValue(input.body_json ?? input.bodyJson ?? input.json) : void 0,
|
|
7121
|
+
required: input.required === false ? false : true
|
|
7122
|
+
};
|
|
7123
|
+
}
|
|
7124
|
+
function normalizeNetworkMocks(value) {
|
|
7125
|
+
if (value === void 0) return void 0;
|
|
7126
|
+
if (!Array.isArray(value)) throw new Error("target.network_mocks must be an array.");
|
|
7127
|
+
return value.map(normalizeNetworkMock);
|
|
7128
|
+
}
|
|
7066
7129
|
function normalizeCheck(input, index) {
|
|
7067
7130
|
if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
7068
7131
|
const type = stringValue2(input.type);
|
|
@@ -7132,7 +7195,8 @@ function normalizeRiddleProofProfile(input, options = {}) {
|
|
|
7132
7195
|
timeout_sec: timeoutSecValue(targetInput.timeout_sec) ?? timeoutSecValue(targetInput.timeoutSec) ?? timeoutSecValue(targetInput.riddle_timeout_sec) ?? timeoutSecValue(targetInput.riddleTimeoutSec),
|
|
7133
7196
|
wait_for_selector: stringValue2(targetInput.wait_for_selector) || stringValue2(targetInput.waitForSelector),
|
|
7134
7197
|
wait_ms: numberValue(targetInput.wait_ms) ?? numberValue(targetInput.waitMs),
|
|
7135
|
-
setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions)
|
|
7198
|
+
setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions),
|
|
7199
|
+
network_mocks: normalizeNetworkMocks(targetInput.network_mocks ?? targetInput.networkMocks)
|
|
7136
7200
|
},
|
|
7137
7201
|
checks,
|
|
7138
7202
|
artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
|
|
@@ -7404,6 +7468,50 @@ function assessSetupActionsFromEvidence(profile, evidence) {
|
|
|
7404
7468
|
message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
|
|
7405
7469
|
};
|
|
7406
7470
|
}
|
|
7471
|
+
function assessNetworkMocksFromEvidence(profile, evidence) {
|
|
7472
|
+
const mocks = profile.target.network_mocks || [];
|
|
7473
|
+
if (!mocks.length) return void 0;
|
|
7474
|
+
const events = evidence.network_mocks || [];
|
|
7475
|
+
const failed = [];
|
|
7476
|
+
const requiredMocks = mocks.filter((mock) => mock.required !== false);
|
|
7477
|
+
for (const mock of requiredMocks) {
|
|
7478
|
+
const hits = events.filter((event) => event.label === mock.label && event.ok !== false).length;
|
|
7479
|
+
if (hits < 1) {
|
|
7480
|
+
failed.push({
|
|
7481
|
+
label: mock.label,
|
|
7482
|
+
url: mock.url,
|
|
7483
|
+
method: mock.method || null,
|
|
7484
|
+
reason: "required_mock_not_hit"
|
|
7485
|
+
});
|
|
7486
|
+
}
|
|
7487
|
+
}
|
|
7488
|
+
for (const event of events) {
|
|
7489
|
+
if (event.ok === false) {
|
|
7490
|
+
failed.push({
|
|
7491
|
+
label: event.label ?? null,
|
|
7492
|
+
url: event.url ?? null,
|
|
7493
|
+
method: event.method ?? null,
|
|
7494
|
+
reason: event.reason ?? event.error ?? "mock_failed"
|
|
7495
|
+
});
|
|
7496
|
+
}
|
|
7497
|
+
}
|
|
7498
|
+
return {
|
|
7499
|
+
type: "network_mocks_succeeded",
|
|
7500
|
+
label: "network mocks succeeded",
|
|
7501
|
+
status: failed.length ? "failed" : "passed",
|
|
7502
|
+
evidence: {
|
|
7503
|
+
mock_count: mocks.length,
|
|
7504
|
+
required_count: requiredMocks.length,
|
|
7505
|
+
hit_count: events.filter((event) => event.ok !== false).length,
|
|
7506
|
+
hits_by_label: Object.fromEntries(mocks.map((mock) => [
|
|
7507
|
+
mock.label,
|
|
7508
|
+
events.filter((event) => event.label === mock.label && event.ok !== false).length
|
|
7509
|
+
])),
|
|
7510
|
+
failed
|
|
7511
|
+
},
|
|
7512
|
+
message: failed.length ? `Network mocks failed or were not hit for ${failed.length} mock(s).` : void 0
|
|
7513
|
+
};
|
|
7514
|
+
}
|
|
7407
7515
|
function profileStatusFromEvidence(profile, evidence, checks) {
|
|
7408
7516
|
if (!evidence) return "proof_insufficient";
|
|
7409
7517
|
const viewports = evidence.viewports || [];
|
|
@@ -7418,6 +7526,7 @@ function profileStatusFromEvidence(profile, evidence, checks) {
|
|
|
7418
7526
|
function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
|
|
7419
7527
|
const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
|
|
7420
7528
|
const checks = evidence ? [
|
|
7529
|
+
assessNetworkMocksFromEvidence(profile, evidence),
|
|
7421
7530
|
assessSetupActionsFromEvidence(profile, evidence),
|
|
7422
7531
|
...profile.checks.map((check) => assessCheckFromEvidence(check, evidence))
|
|
7423
7532
|
].filter((check) => Boolean(check)) : [];
|
|
@@ -7618,6 +7727,49 @@ function horizontalBoundsOverflowPx(value) {
|
|
|
7618
7727
|
function assessProfile(profile, evidence) {
|
|
7619
7728
|
const checks = [];
|
|
7620
7729
|
const viewports = evidence.viewports || [];
|
|
7730
|
+
if (profile.target && Array.isArray(profile.target.network_mocks) && profile.target.network_mocks.length) {
|
|
7731
|
+
const events = evidence.network_mocks || [];
|
|
7732
|
+
const requiredMocks = profile.target.network_mocks.filter((mock) => mock && mock.required !== false);
|
|
7733
|
+
const failed = [];
|
|
7734
|
+
for (const mock of requiredMocks) {
|
|
7735
|
+
const hits = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
|
|
7736
|
+
if (hits < 1) {
|
|
7737
|
+
failed.push({
|
|
7738
|
+
label: mock.label,
|
|
7739
|
+
url: mock.url,
|
|
7740
|
+
method: mock.method || null,
|
|
7741
|
+
reason: "required_mock_not_hit",
|
|
7742
|
+
});
|
|
7743
|
+
}
|
|
7744
|
+
}
|
|
7745
|
+
for (const event of events) {
|
|
7746
|
+
if (event && event.ok === false) {
|
|
7747
|
+
failed.push({
|
|
7748
|
+
label: event.label || null,
|
|
7749
|
+
url: event.url || null,
|
|
7750
|
+
method: event.method || null,
|
|
7751
|
+
reason: event.reason || event.error || "mock_failed",
|
|
7752
|
+
});
|
|
7753
|
+
}
|
|
7754
|
+
}
|
|
7755
|
+
const hitsByLabel = {};
|
|
7756
|
+
for (const mock of profile.target.network_mocks) {
|
|
7757
|
+
hitsByLabel[mock.label] = events.filter((event) => event && event.label === mock.label && event.ok !== false).length;
|
|
7758
|
+
}
|
|
7759
|
+
checks.push({
|
|
7760
|
+
type: "network_mocks_succeeded",
|
|
7761
|
+
label: "network mocks succeeded",
|
|
7762
|
+
status: failed.length ? "failed" : "passed",
|
|
7763
|
+
evidence: {
|
|
7764
|
+
mock_count: profile.target.network_mocks.length,
|
|
7765
|
+
required_count: requiredMocks.length,
|
|
7766
|
+
hit_count: events.filter((event) => event && event.ok !== false).length,
|
|
7767
|
+
hits_by_label: hitsByLabel,
|
|
7768
|
+
failed,
|
|
7769
|
+
},
|
|
7770
|
+
message: failed.length ? "Network mocks failed or were not hit for " + failed.length + " mock(s)." : undefined,
|
|
7771
|
+
});
|
|
7772
|
+
}
|
|
7621
7773
|
if (profile.target && Array.isArray(profile.target.setup_actions) && profile.target.setup_actions.length) {
|
|
7622
7774
|
const actionCount = profile.target.setup_actions.length;
|
|
7623
7775
|
const failed = [];
|
|
@@ -7807,6 +7959,7 @@ const profileSlug = ${serializableSlug};
|
|
|
7807
7959
|
const capturedAt = new Date().toISOString();
|
|
7808
7960
|
const consoleEvents = [];
|
|
7809
7961
|
const pageErrors = [];
|
|
7962
|
+
const networkMockEvents = [];
|
|
7810
7963
|
page.on("console", (message) => {
|
|
7811
7964
|
const type = message.type();
|
|
7812
7965
|
if (type === "error" || type === "warning" || type === "assert") {
|
|
@@ -7842,6 +7995,14 @@ function setupTextMatches(sample, action) {
|
|
|
7842
7995
|
}
|
|
7843
7996
|
return String(sample || "").includes(action.text || "");
|
|
7844
7997
|
}
|
|
7998
|
+
function setupHasOwn(action, key) {
|
|
7999
|
+
return Boolean(action) && Object.keys(action).includes(key);
|
|
8000
|
+
}
|
|
8001
|
+
function setupActionValue(action) {
|
|
8002
|
+
if (setupHasOwn(action, "value_json")) return JSON.stringify(action.value_json);
|
|
8003
|
+
if (setupHasOwn(action, "value")) return String(action.value ?? "");
|
|
8004
|
+
return "";
|
|
8005
|
+
}
|
|
7845
8006
|
async function setupLocatorText(locator, index) {
|
|
7846
8007
|
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
7847
8008
|
}
|
|
@@ -7853,6 +8014,49 @@ function compactSetupResultText(value) {
|
|
|
7853
8014
|
async function setupLocatorVisible(locator, index) {
|
|
7854
8015
|
return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
|
|
7855
8016
|
}
|
|
8017
|
+
async function registerNetworkMocks(mocks) {
|
|
8018
|
+
for (const mock of mocks || []) {
|
|
8019
|
+
await page.route(mock.url, async (route) => {
|
|
8020
|
+
const request = route.request();
|
|
8021
|
+
const method = request.method ? request.method() : "";
|
|
8022
|
+
if (mock.method && method.toUpperCase() !== String(mock.method).toUpperCase()) {
|
|
8023
|
+
await route.continue();
|
|
8024
|
+
return;
|
|
8025
|
+
}
|
|
8026
|
+
try {
|
|
8027
|
+
const headers = { ...(mock.headers || {}) };
|
|
8028
|
+
let body = mock.body || "";
|
|
8029
|
+
let contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "text/plain";
|
|
8030
|
+
if (mock.body_json !== undefined) {
|
|
8031
|
+
body = JSON.stringify(mock.body_json);
|
|
8032
|
+
contentType = mock.content_type || headers["content-type"] || headers["Content-Type"] || "application/json";
|
|
8033
|
+
}
|
|
8034
|
+
networkMockEvents.push({
|
|
8035
|
+
ok: true,
|
|
8036
|
+
label: mock.label,
|
|
8037
|
+
url: request.url(),
|
|
8038
|
+
method,
|
|
8039
|
+
status: mock.status || 200,
|
|
8040
|
+
});
|
|
8041
|
+
await route.fulfill({
|
|
8042
|
+
status: mock.status || 200,
|
|
8043
|
+
headers,
|
|
8044
|
+
contentType,
|
|
8045
|
+
body,
|
|
8046
|
+
});
|
|
8047
|
+
} catch (error) {
|
|
8048
|
+
networkMockEvents.push({
|
|
8049
|
+
ok: false,
|
|
8050
|
+
label: mock.label,
|
|
8051
|
+
url: request.url(),
|
|
8052
|
+
method,
|
|
8053
|
+
error: String(error && error.message ? error.message : error).slice(0, 1000),
|
|
8054
|
+
});
|
|
8055
|
+
throw error;
|
|
8056
|
+
}
|
|
8057
|
+
});
|
|
8058
|
+
}
|
|
8059
|
+
}
|
|
7856
8060
|
async function executeSetupAction(action, ordinal) {
|
|
7857
8061
|
const type = setupActionType(action);
|
|
7858
8062
|
const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
|
|
@@ -7867,6 +8071,16 @@ async function executeSetupAction(action, ordinal) {
|
|
|
7867
8071
|
await page.waitForSelector(action.selector, { state: "visible", timeout });
|
|
7868
8072
|
return { ...base, ok: true, timeout_ms: timeout };
|
|
7869
8073
|
}
|
|
8074
|
+
if (type === "local_storage") {
|
|
8075
|
+
const value = setupActionValue(action);
|
|
8076
|
+
await page.evaluate(({ key, value }) => {
|
|
8077
|
+
window.localStorage.setItem(key, value);
|
|
8078
|
+
}, { key: action.key, value });
|
|
8079
|
+
if (action.reload === true) {
|
|
8080
|
+
await page.reload({ waitUntil: "domcontentloaded", timeout: 45000 });
|
|
8081
|
+
}
|
|
8082
|
+
return { ...base, ok: true, key: action.key, value_length: value.length, reload: action.reload === true };
|
|
8083
|
+
}
|
|
7870
8084
|
if (type === "click") {
|
|
7871
8085
|
const locator = page.locator(action.selector);
|
|
7872
8086
|
const count = await locator.count();
|
|
@@ -7899,6 +8113,16 @@ async function executeSetupAction(action, ordinal) {
|
|
|
7899
8113
|
await locator.nth(targetIndex).click({ timeout });
|
|
7900
8114
|
return { ...base, ok: true, count, target_index: targetIndex, text: matchedText };
|
|
7901
8115
|
}
|
|
8116
|
+
if (type === "fill" || type === "set_input_value") {
|
|
8117
|
+
const locator = page.locator(action.selector);
|
|
8118
|
+
const count = await locator.count();
|
|
8119
|
+
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
8120
|
+
const targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
8121
|
+
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
|
|
8122
|
+
const value = setupActionValue(action);
|
|
8123
|
+
await locator.nth(targetIndex).fill(value, { timeout });
|
|
8124
|
+
return { ...base, ok: true, count, target_index: targetIndex, value_length: value.length };
|
|
8125
|
+
}
|
|
7902
8126
|
if (type === "wait_for_text") {
|
|
7903
8127
|
const locator = page.locator(action.selector);
|
|
7904
8128
|
const startedAt = Date.now();
|
|
@@ -8114,6 +8338,7 @@ function buildProfileEvidence(currentViewports) {
|
|
|
8114
8338
|
fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
|
|
8115
8339
|
},
|
|
8116
8340
|
page_errors: pageErrors,
|
|
8341
|
+
network_mocks: networkMockEvents.slice(),
|
|
8117
8342
|
dom_summary: {
|
|
8118
8343
|
expected_viewport_count: expectedViewportCount,
|
|
8119
8344
|
viewport_count: currentViewports.length,
|
|
@@ -8123,6 +8348,8 @@ function buildProfileEvidence(currentViewports) {
|
|
|
8123
8348
|
overflow_px: currentViewports.map((viewport) => viewport.overflow_px),
|
|
8124
8349
|
bounds_overflow_px: currentViewports.map((viewport) => viewport.bounds_overflow_px),
|
|
8125
8350
|
overflow_offender_counts: currentViewports.map((viewport) => (viewport.overflow_offenders || []).length),
|
|
8351
|
+
network_mock_count: (profile.target.network_mocks || []).length,
|
|
8352
|
+
network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
|
|
8126
8353
|
},
|
|
8127
8354
|
};
|
|
8128
8355
|
}
|
|
@@ -8136,6 +8363,9 @@ async function saveProfileArtifacts(currentViewports) {
|
|
|
8136
8363
|
}
|
|
8137
8364
|
return result;
|
|
8138
8365
|
}
|
|
8366
|
+
await registerNetworkMocks(profile.target.network_mocks || []);
|
|
8367
|
+
consoleEvents.length = 0;
|
|
8368
|
+
pageErrors.length = 0;
|
|
8139
8369
|
let result = await saveProfileArtifacts(viewports);
|
|
8140
8370
|
for (const viewport of profile.target.viewports || []) {
|
|
8141
8371
|
viewports.push(await captureViewport(viewport));
|
package/dist/cli.js
CHANGED