@riddledc/riddle-proof 0.7.8 → 0.7.10
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 +14 -1
- package/dist/{chunk-7NMAU4DP.js → chunk-A7RJZD4I.js} +263 -8
- package/dist/cli.cjs +262 -8
- package/dist/cli.js +1 -1
- package/dist/index.cjs +264 -8
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/profile.cjs +264 -8
- package/dist/profile.d.cts +17 -1
- package/dist/profile.d.ts +17 -1
- package/dist/profile.js +3 -1
- package/dist/proof-run-engine.d.cts +3 -3
- package/dist/proof-run-engine.d.ts +3 -3
- package/examples/profiles/page-content-basic.json +4 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -6799,6 +6799,12 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
6799
6799
|
"no_mobile_horizontal_overflow",
|
|
6800
6800
|
"no_fatal_console_errors"
|
|
6801
6801
|
];
|
|
6802
|
+
var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
6803
|
+
"click",
|
|
6804
|
+
"wait",
|
|
6805
|
+
"wait_for_selector",
|
|
6806
|
+
"wait_for_text"
|
|
6807
|
+
];
|
|
6802
6808
|
var DEFAULT_VIEWPORTS = [
|
|
6803
6809
|
{ name: "desktop", width: 1280, height: 800 }
|
|
6804
6810
|
];
|
|
@@ -6851,6 +6857,41 @@ function normalizeViewports(value) {
|
|
|
6851
6857
|
function isSupportedCheckType(value) {
|
|
6852
6858
|
return RIDDLE_PROOF_PROFILE_CHECK_TYPES.includes(value);
|
|
6853
6859
|
}
|
|
6860
|
+
function normalizeSetupActionType(value, index) {
|
|
6861
|
+
const normalized = String(value || "").trim().replace(/-/g, "_");
|
|
6862
|
+
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
6863
|
+
return normalized;
|
|
6864
|
+
}
|
|
6865
|
+
throw new Error(`target.setup_actions[${index}].type ${value || "(missing)"} is not supported. Supported actions: ${RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.join(", ")}`);
|
|
6866
|
+
}
|
|
6867
|
+
function normalizeSetupAction(input, index) {
|
|
6868
|
+
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
6869
|
+
const type = normalizeSetupActionType(stringValue2(input.type), index);
|
|
6870
|
+
const selector = stringValue2(input.selector);
|
|
6871
|
+
if ((type === "click" || type === "wait_for_selector" || type === "wait_for_text") && !selector) {
|
|
6872
|
+
throw new Error(`target.setup_actions[${index}] ${type} requires selector.`);
|
|
6873
|
+
}
|
|
6874
|
+
if (type === "wait_for_text" && !stringValue2(input.text) && !stringValue2(input.pattern)) {
|
|
6875
|
+
throw new Error(`target.setup_actions[${index}] wait_for_text requires text or pattern.`);
|
|
6876
|
+
}
|
|
6877
|
+
return {
|
|
6878
|
+
type,
|
|
6879
|
+
selector,
|
|
6880
|
+
text: stringValue2(input.text),
|
|
6881
|
+
pattern: stringValue2(input.pattern),
|
|
6882
|
+
flags: stringValue2(input.flags),
|
|
6883
|
+
index: numberValue(input.index),
|
|
6884
|
+
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
6885
|
+
timeout_ms: numberValue(input.timeout_ms) ?? numberValue(input.timeoutMs),
|
|
6886
|
+
after_ms: numberValue(input.after_ms) ?? numberValue(input.afterMs),
|
|
6887
|
+
continue_on_failure: input.continue_on_failure === true || input.continueOnFailure === true
|
|
6888
|
+
};
|
|
6889
|
+
}
|
|
6890
|
+
function normalizeSetupActions(value) {
|
|
6891
|
+
if (value === void 0) return void 0;
|
|
6892
|
+
if (!Array.isArray(value)) throw new Error("target.setup_actions must be an array.");
|
|
6893
|
+
return value.map(normalizeSetupAction);
|
|
6894
|
+
}
|
|
6854
6895
|
function normalizeCheck(input, index) {
|
|
6855
6896
|
if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
6856
6897
|
const type = stringValue2(input.type);
|
|
@@ -6918,7 +6959,8 @@ function normalizeRiddleProofProfile(input, options = {}) {
|
|
|
6918
6959
|
viewports: options.viewports?.length ? options.viewports : normalizeViewports(targetInput.viewports),
|
|
6919
6960
|
auth: stringValue2(targetInput.auth) || "none",
|
|
6920
6961
|
wait_for_selector: stringValue2(targetInput.wait_for_selector) || stringValue2(targetInput.waitForSelector),
|
|
6921
|
-
wait_ms: numberValue(targetInput.wait_ms) ?? numberValue(targetInput.waitMs)
|
|
6962
|
+
wait_ms: numberValue(targetInput.wait_ms) ?? numberValue(targetInput.waitMs),
|
|
6963
|
+
setup_actions: normalizeSetupActions(targetInput.setup_actions ?? targetInput.setupActions)
|
|
6922
6964
|
},
|
|
6923
6965
|
checks,
|
|
6924
6966
|
artifacts: Array.isArray(input.artifacts) ? input.artifacts.map((item) => String(item)).filter(Boolean) : ["screenshot", "console", "dom_summary", "proof_json"],
|
|
@@ -6936,7 +6978,13 @@ function resolveRiddleProofProfileTargetUrl(profile) {
|
|
|
6936
6978
|
throw new Error("profile target URL could not be resolved.");
|
|
6937
6979
|
}
|
|
6938
6980
|
function routeForViewport(viewport) {
|
|
6939
|
-
|
|
6981
|
+
if (viewport?.route) {
|
|
6982
|
+
return {
|
|
6983
|
+
...viewport.route,
|
|
6984
|
+
matched: viewport.route.matched || routePathMatches(viewport.route.observed, viewport.route.expected_path)
|
|
6985
|
+
};
|
|
6986
|
+
}
|
|
6987
|
+
return {
|
|
6940
6988
|
requested: "",
|
|
6941
6989
|
observed: "",
|
|
6942
6990
|
matched: false,
|
|
@@ -6962,8 +7010,17 @@ function matchText(sample, check) {
|
|
|
6962
7010
|
}
|
|
6963
7011
|
return sample.includes(check.text || "");
|
|
6964
7012
|
}
|
|
7013
|
+
function normalizeRoutePath(path7) {
|
|
7014
|
+
const value = path7 || "/";
|
|
7015
|
+
if (value === "/") return "/";
|
|
7016
|
+
return value.replace(/\/+$/, "") || "/";
|
|
7017
|
+
}
|
|
7018
|
+
function routePathMatches(observed, expected) {
|
|
7019
|
+
return normalizeRoutePath(observed) === normalizeRoutePath(expected);
|
|
7020
|
+
}
|
|
6965
7021
|
function successfulRoute(route) {
|
|
6966
|
-
|
|
7022
|
+
const matched = route.matched || routePathMatches(route.observed, route.expected_path);
|
|
7023
|
+
return matched && !route.error && (route.http_status === null || route.http_status === void 0 || route.http_status < 400);
|
|
6967
7024
|
}
|
|
6968
7025
|
function assessCheckFromEvidence(check, evidence) {
|
|
6969
7026
|
const viewports = evidence.viewports || [];
|
|
@@ -6981,7 +7038,7 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
6981
7038
|
const failed = viewports.filter((viewport) => !successfulRoute({
|
|
6982
7039
|
...viewport.route,
|
|
6983
7040
|
expected_path: expectedPath,
|
|
6984
|
-
matched: viewport.route.observed
|
|
7041
|
+
matched: routePathMatches(viewport.route.observed, expectedPath) || viewport.route.matched
|
|
6985
7042
|
}));
|
|
6986
7043
|
return {
|
|
6987
7044
|
type: check.type,
|
|
@@ -7091,6 +7148,48 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
7091
7148
|
message: "Unsupported check type."
|
|
7092
7149
|
};
|
|
7093
7150
|
}
|
|
7151
|
+
function assessSetupActionsFromEvidence(profile, evidence) {
|
|
7152
|
+
if (!profile.target.setup_actions?.length) return void 0;
|
|
7153
|
+
const actionCount = profile.target.setup_actions.length;
|
|
7154
|
+
const failed = [];
|
|
7155
|
+
const viewports = evidence.viewports || [];
|
|
7156
|
+
for (const viewport of viewports) {
|
|
7157
|
+
const results = viewport.setup_action_results || [];
|
|
7158
|
+
for (const result of results) {
|
|
7159
|
+
if (result.ok === false) {
|
|
7160
|
+
failed.push({
|
|
7161
|
+
viewport: viewport.name,
|
|
7162
|
+
action: result.action ?? result.type ?? null,
|
|
7163
|
+
selector: result.selector ?? null,
|
|
7164
|
+
reason: result.reason ?? result.error ?? null
|
|
7165
|
+
});
|
|
7166
|
+
}
|
|
7167
|
+
}
|
|
7168
|
+
if (results.length < actionCount && results.every((result) => result.ok !== false)) {
|
|
7169
|
+
failed.push({
|
|
7170
|
+
viewport: viewport.name,
|
|
7171
|
+
action: "setup_actions",
|
|
7172
|
+
selector: null,
|
|
7173
|
+
reason: `missing setup action results: ${results.length}/${actionCount}`
|
|
7174
|
+
});
|
|
7175
|
+
}
|
|
7176
|
+
}
|
|
7177
|
+
return {
|
|
7178
|
+
type: "setup_actions_succeeded",
|
|
7179
|
+
label: "setup actions succeeded",
|
|
7180
|
+
status: failed.length ? "failed" : "passed",
|
|
7181
|
+
evidence: {
|
|
7182
|
+
action_count: actionCount,
|
|
7183
|
+
viewports: viewports.map((viewport) => ({
|
|
7184
|
+
name: viewport.name,
|
|
7185
|
+
ok: (viewport.setup_action_results || []).length >= actionCount && (viewport.setup_action_results || []).every((result) => result.ok !== false),
|
|
7186
|
+
result_count: (viewport.setup_action_results || []).length
|
|
7187
|
+
})),
|
|
7188
|
+
failed
|
|
7189
|
+
},
|
|
7190
|
+
message: failed.length ? `Setup actions failed in ${failed.length} viewport action(s).` : void 0
|
|
7191
|
+
};
|
|
7192
|
+
}
|
|
7094
7193
|
function profileStatusFromEvidence(evidence, checks) {
|
|
7095
7194
|
if (!evidence) return "proof_insufficient";
|
|
7096
7195
|
const viewports = evidence.viewports || [];
|
|
@@ -7102,7 +7201,10 @@ function profileStatusFromEvidence(evidence, checks) {
|
|
|
7102
7201
|
}
|
|
7103
7202
|
function assessRiddleProofProfileEvidence(profile, evidence, options = {}) {
|
|
7104
7203
|
const capturedAt = evidence?.captured_at || (/* @__PURE__ */ new Date()).toISOString();
|
|
7105
|
-
const checks = evidence ?
|
|
7204
|
+
const checks = evidence ? [
|
|
7205
|
+
assessSetupActionsFromEvidence(profile, evidence),
|
|
7206
|
+
...profile.checks.map((check) => assessCheckFromEvidence(check, evidence))
|
|
7207
|
+
].filter((check) => Boolean(check)) : [];
|
|
7106
7208
|
const status = profileStatusFromEvidence(evidence, checks);
|
|
7107
7209
|
const firstViewport = evidence?.viewports?.[0];
|
|
7108
7210
|
const screenshots = (evidence?.viewports || []).map((viewport) => viewport.screenshot_label).filter((label) => Boolean(label));
|
|
@@ -7188,8 +7290,16 @@ function createRiddleProofProfileInsufficientResult(input) {
|
|
|
7188
7290
|
}
|
|
7189
7291
|
function runtimeScriptAssessmentSource() {
|
|
7190
7292
|
return String.raw`
|
|
7293
|
+
function normalizeRoutePath(path) {
|
|
7294
|
+
const value = path || "/";
|
|
7295
|
+
if (value === "/") return "/";
|
|
7296
|
+
return value.replace(/\/+$/, "") || "/";
|
|
7297
|
+
}
|
|
7298
|
+
function routePathMatches(observed, expected) {
|
|
7299
|
+
return normalizeRoutePath(observed) === normalizeRoutePath(expected);
|
|
7300
|
+
}
|
|
7191
7301
|
function routeOk(route) {
|
|
7192
|
-
return Boolean(route && route.matched && !route.error && (route.http_status == null || route.http_status < 400));
|
|
7302
|
+
return Boolean(route && (route.matched || routePathMatches(route.observed, route.expected_path)) && !route.error && (route.http_status == null || route.http_status < 400));
|
|
7193
7303
|
}
|
|
7194
7304
|
function textMatches(sample, check) {
|
|
7195
7305
|
if (check.pattern) {
|
|
@@ -7200,12 +7310,53 @@ function textMatches(sample, check) {
|
|
|
7200
7310
|
function assessProfile(profile, evidence) {
|
|
7201
7311
|
const checks = [];
|
|
7202
7312
|
const viewports = evidence.viewports || [];
|
|
7313
|
+
if (profile.target && Array.isArray(profile.target.setup_actions) && profile.target.setup_actions.length) {
|
|
7314
|
+
const actionCount = profile.target.setup_actions.length;
|
|
7315
|
+
const failed = [];
|
|
7316
|
+
for (const viewport of viewports) {
|
|
7317
|
+
const results = viewport.setup_action_results || [];
|
|
7318
|
+
for (const result of results) {
|
|
7319
|
+
if (result && result.ok === false) {
|
|
7320
|
+
failed.push({
|
|
7321
|
+
viewport: viewport.name,
|
|
7322
|
+
action: result.action || result.type || null,
|
|
7323
|
+
selector: result.selector || null,
|
|
7324
|
+
reason: result.reason || result.error || null,
|
|
7325
|
+
});
|
|
7326
|
+
}
|
|
7327
|
+
}
|
|
7328
|
+
if (results.length < actionCount && results.every((result) => !result || result.ok !== false)) {
|
|
7329
|
+
failed.push({
|
|
7330
|
+
viewport: viewport.name,
|
|
7331
|
+
action: "setup_actions",
|
|
7332
|
+
selector: null,
|
|
7333
|
+
reason: "missing setup action results: " + results.length + "/" + actionCount,
|
|
7334
|
+
});
|
|
7335
|
+
}
|
|
7336
|
+
}
|
|
7337
|
+
checks.push({
|
|
7338
|
+
type: "setup_actions_succeeded",
|
|
7339
|
+
label: "setup actions succeeded",
|
|
7340
|
+
status: failed.length ? "failed" : "passed",
|
|
7341
|
+
evidence: {
|
|
7342
|
+
action_count: actionCount,
|
|
7343
|
+
viewports: viewports.map((viewport) => ({
|
|
7344
|
+
name: viewport.name,
|
|
7345
|
+
ok: (viewport.setup_action_results || []).length >= actionCount
|
|
7346
|
+
&& (viewport.setup_action_results || []).every((result) => !result || result.ok !== false),
|
|
7347
|
+
result_count: (viewport.setup_action_results || []).length,
|
|
7348
|
+
})),
|
|
7349
|
+
failed,
|
|
7350
|
+
},
|
|
7351
|
+
message: failed.length ? "Setup actions failed in " + failed.length + " viewport action(s)." : undefined,
|
|
7352
|
+
});
|
|
7353
|
+
}
|
|
7203
7354
|
for (const check of profile.checks || []) {
|
|
7204
7355
|
if (check.type === "route_loaded") {
|
|
7205
7356
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
7206
7357
|
const failed = viewports.filter((viewport) => {
|
|
7207
7358
|
const route = { ...(viewport.route || {}), expected_path: expectedPath };
|
|
7208
|
-
route.matched = route.observed
|
|
7359
|
+
route.matched = routePathMatches(route.observed, expectedPath) || route.matched;
|
|
7209
7360
|
return !routeOk(route);
|
|
7210
7361
|
});
|
|
7211
7362
|
checks.push({
|
|
@@ -7362,6 +7513,105 @@ function textMatches(sample, check) {
|
|
|
7362
7513
|
}
|
|
7363
7514
|
return String(sample || "").includes(check.text || "");
|
|
7364
7515
|
}
|
|
7516
|
+
function setupActionType(action) {
|
|
7517
|
+
return String(action && action.type ? action.type : "").replace(/-/g, "_");
|
|
7518
|
+
}
|
|
7519
|
+
function setupNumber(value, fallback) {
|
|
7520
|
+
const number = Number(value);
|
|
7521
|
+
return Number.isFinite(number) && number >= 0 ? number : fallback;
|
|
7522
|
+
}
|
|
7523
|
+
function setupTextMatches(sample, action) {
|
|
7524
|
+
if (action.pattern) {
|
|
7525
|
+
try { return new RegExp(action.pattern, action.flags || "").test(sample || ""); } catch { return false; }
|
|
7526
|
+
}
|
|
7527
|
+
return String(sample || "").includes(action.text || "");
|
|
7528
|
+
}
|
|
7529
|
+
async function setupLocatorText(locator, index) {
|
|
7530
|
+
return await locator.nth(index).textContent({ timeout: 1000 }).catch(() => "");
|
|
7531
|
+
}
|
|
7532
|
+
async function setupLocatorVisible(locator, index) {
|
|
7533
|
+
return await locator.nth(index).isVisible({ timeout: 1000 }).catch(() => false);
|
|
7534
|
+
}
|
|
7535
|
+
async function executeSetupAction(action, ordinal) {
|
|
7536
|
+
const type = setupActionType(action);
|
|
7537
|
+
const base = { ok: false, action: type || "unknown", ordinal, selector: action.selector || null };
|
|
7538
|
+
const timeout = setupNumber(action.timeout_ms, 5000);
|
|
7539
|
+
try {
|
|
7540
|
+
if (type === "wait") {
|
|
7541
|
+
const ms = setupNumber(action.ms, 500);
|
|
7542
|
+
await page.waitForTimeout(ms);
|
|
7543
|
+
return { ...base, ok: true, ms };
|
|
7544
|
+
}
|
|
7545
|
+
if (type === "wait_for_selector") {
|
|
7546
|
+
await page.waitForSelector(action.selector, { state: "visible", timeout });
|
|
7547
|
+
return { ...base, ok: true, timeout_ms: timeout };
|
|
7548
|
+
}
|
|
7549
|
+
if (type === "click") {
|
|
7550
|
+
const locator = page.locator(action.selector);
|
|
7551
|
+
const count = await locator.count();
|
|
7552
|
+
if (!count) return { ...base, reason: "selector_not_found", count };
|
|
7553
|
+
let targetIndex = Number.isInteger(action.index) ? action.index : 0;
|
|
7554
|
+
let matchedText = null;
|
|
7555
|
+
let hiddenMatchIndex = -1;
|
|
7556
|
+
let hiddenMatchedText = null;
|
|
7557
|
+
if (action.text || action.pattern) {
|
|
7558
|
+
targetIndex = -1;
|
|
7559
|
+
for (let index = 0; index < count; index += 1) {
|
|
7560
|
+
const text = await setupLocatorText(locator, index);
|
|
7561
|
+
if (setupTextMatches(text, action)) {
|
|
7562
|
+
const visible = await setupLocatorVisible(locator, index);
|
|
7563
|
+
if (visible) {
|
|
7564
|
+
targetIndex = index;
|
|
7565
|
+
matchedText = text;
|
|
7566
|
+
break;
|
|
7567
|
+
}
|
|
7568
|
+
if (hiddenMatchIndex < 0) {
|
|
7569
|
+
hiddenMatchIndex = index;
|
|
7570
|
+
hiddenMatchedText = text;
|
|
7571
|
+
}
|
|
7572
|
+
}
|
|
7573
|
+
}
|
|
7574
|
+
if (targetIndex < 0 && hiddenMatchIndex >= 0) return { ...base, reason: "matching_element_not_visible", count, target_index: hiddenMatchIndex, text: hiddenMatchedText };
|
|
7575
|
+
if (targetIndex < 0) return { ...base, reason: "text_not_found", count };
|
|
7576
|
+
}
|
|
7577
|
+
if (targetIndex < 0 || targetIndex >= count) return { ...base, reason: "index_out_of_range", count, target_index: targetIndex };
|
|
7578
|
+
await locator.nth(targetIndex).click({ timeout });
|
|
7579
|
+
return { ...base, ok: true, count, target_index: targetIndex, text: matchedText };
|
|
7580
|
+
}
|
|
7581
|
+
if (type === "wait_for_text") {
|
|
7582
|
+
const locator = page.locator(action.selector);
|
|
7583
|
+
const startedAt = Date.now();
|
|
7584
|
+
let lastText = "";
|
|
7585
|
+
while (Date.now() - startedAt <= timeout) {
|
|
7586
|
+
const count = await locator.count().catch(() => 0);
|
|
7587
|
+
for (let index = 0; index < count; index += 1) {
|
|
7588
|
+
const text = await setupLocatorText(locator, index);
|
|
7589
|
+
lastText = text || lastText;
|
|
7590
|
+
if (setupTextMatches(text, action)) {
|
|
7591
|
+
return { ...base, ok: true, text, target_index: index, timeout_ms: timeout };
|
|
7592
|
+
}
|
|
7593
|
+
}
|
|
7594
|
+
await page.waitForTimeout(100);
|
|
7595
|
+
}
|
|
7596
|
+
return { ...base, reason: "text_not_found", text: lastText, timeout_ms: timeout };
|
|
7597
|
+
}
|
|
7598
|
+
return { ...base, reason: "unsupported_action" };
|
|
7599
|
+
} catch (error) {
|
|
7600
|
+
return { ...base, error: String(error && error.message ? error.message : error).slice(0, 1000) };
|
|
7601
|
+
}
|
|
7602
|
+
}
|
|
7603
|
+
async function executeSetupActions(actions) {
|
|
7604
|
+
const results = [];
|
|
7605
|
+
for (let index = 0; index < (actions || []).length; index += 1) {
|
|
7606
|
+
const action = actions[index] || {};
|
|
7607
|
+
const result = await executeSetupAction(action, index);
|
|
7608
|
+
results.push(result);
|
|
7609
|
+
const afterMs = setupNumber(action.after_ms, 0);
|
|
7610
|
+
if (afterMs) await page.waitForTimeout(afterMs);
|
|
7611
|
+
if (result.ok === false && action.continue_on_failure !== true) break;
|
|
7612
|
+
}
|
|
7613
|
+
return results;
|
|
7614
|
+
}
|
|
7365
7615
|
function expectedPathFor(check) {
|
|
7366
7616
|
return check.expected_path || new URL(targetUrl).pathname || "/";
|
|
7367
7617
|
}
|
|
@@ -7396,6 +7646,9 @@ async function captureViewport(viewport) {
|
|
|
7396
7646
|
if (!navigationError && profile.target.wait_ms) {
|
|
7397
7647
|
await page.waitForTimeout(profile.target.wait_ms);
|
|
7398
7648
|
}
|
|
7649
|
+
const setupActionResults = (!navigationError && !waitError)
|
|
7650
|
+
? await executeSetupActions(profile.target.setup_actions || [])
|
|
7651
|
+
: [];
|
|
7399
7652
|
const dom = await page.evaluate(() => {
|
|
7400
7653
|
const body = document.body;
|
|
7401
7654
|
const documentElement = document.documentElement;
|
|
@@ -7445,7 +7698,7 @@ async function captureViewport(viewport) {
|
|
|
7445
7698
|
requested: targetUrl,
|
|
7446
7699
|
observed: dom.pathname,
|
|
7447
7700
|
expected_path: expectedPath,
|
|
7448
|
-
matched: dom.pathname
|
|
7701
|
+
matched: routePathMatches(dom.pathname, expectedPath),
|
|
7449
7702
|
http_status: httpStatus,
|
|
7450
7703
|
error: navigationError || waitError || undefined,
|
|
7451
7704
|
},
|
|
@@ -7457,6 +7710,7 @@ async function captureViewport(viewport) {
|
|
|
7457
7710
|
overflow_px: Math.max(0, (dom.scroll_width || 0) - (dom.client_width || viewport.width)),
|
|
7458
7711
|
selectors,
|
|
7459
7712
|
text_matches,
|
|
7713
|
+
setup_action_results: setupActionResults,
|
|
7460
7714
|
screenshot_label: screenshotLabel,
|
|
7461
7715
|
navigation_error: navigationError,
|
|
7462
7716
|
wait_error: waitError,
|