@riddledc/riddle-proof 0.7.77 → 0.7.79
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-RBZ4A5M4.js → chunk-3RUIKF4C.js} +188 -6
- package/dist/cli.cjs +188 -6
- package/dist/cli.js +1 -1
- package/dist/index.cjs +188 -6
- package/dist/index.js +1 -1
- package/dist/profile.cjs +188 -6
- package/dist/profile.d.cts +5 -1
- package/dist/profile.d.ts +5 -1
- package/dist/profile.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8761,6 +8761,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
|
8761
8761
|
"session_storage",
|
|
8762
8762
|
"clear_storage",
|
|
8763
8763
|
"clear_console",
|
|
8764
|
+
"dialog_response",
|
|
8764
8765
|
"screenshot",
|
|
8765
8766
|
"wait",
|
|
8766
8767
|
"wait_for_selector",
|
|
@@ -9022,7 +9023,7 @@ function isSupportedCheckType(value) {
|
|
|
9022
9023
|
}
|
|
9023
9024
|
function normalizeSetupActionType(value, index) {
|
|
9024
9025
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
9025
|
-
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput;
|
|
9026
|
+
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput;
|
|
9026
9027
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
9027
9028
|
return normalized;
|
|
9028
9029
|
}
|
|
@@ -9074,6 +9075,7 @@ function normalizeSetupActionCoordinateMode(value, index) {
|
|
|
9074
9075
|
function normalizeSetupAction(input, index) {
|
|
9075
9076
|
if (!isRecord2(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
9076
9077
|
const type = normalizeSetupActionType(stringValue5(input.type), index);
|
|
9078
|
+
const rawType = String(input.type || "").trim().replace(/-/g, "_").toLowerCase();
|
|
9077
9079
|
const selector = stringValue5(input.selector);
|
|
9078
9080
|
const frameSelector = stringFromOwn(input, "frame_selector", "frameSelector", "iframe_selector", "iframeSelector");
|
|
9079
9081
|
const frameIndex = numberValue3(valueFromOwn(input, "frame_index", "frameIndex", "iframe_index", "iframeIndex"));
|
|
@@ -9115,6 +9117,21 @@ function normalizeSetupAction(input, index) {
|
|
|
9115
9117
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
9116
9118
|
}
|
|
9117
9119
|
const key = stringValue5(input.key);
|
|
9120
|
+
let dialogAccept;
|
|
9121
|
+
if (type === "dialog_response") {
|
|
9122
|
+
const acceptInput = valueFromOwn(input, "accept", "accepted", "should_accept", "shouldAccept");
|
|
9123
|
+
const responseInput = stringFromOwn(input, "response", "dialog_response", "dialogResponse", "mode");
|
|
9124
|
+
const response = String(responseInput || "").trim().toLowerCase().replace(/-/g, "_");
|
|
9125
|
+
if (acceptInput !== void 0) {
|
|
9126
|
+
dialogAccept = acceptInput !== false && String(acceptInput).toLowerCase() !== "false";
|
|
9127
|
+
} else if (rawType === "dismiss_dialog" || rawType === "dismiss_dialogs" || rawType === "cancel_dialog") {
|
|
9128
|
+
dialogAccept = false;
|
|
9129
|
+
} else if (response === "dismiss" || response === "cancel" || response === "reject" || response === "no" || response === "false") {
|
|
9130
|
+
dialogAccept = false;
|
|
9131
|
+
} else {
|
|
9132
|
+
dialogAccept = true;
|
|
9133
|
+
}
|
|
9134
|
+
}
|
|
9118
9135
|
if (type === "press" && !key) {
|
|
9119
9136
|
throw new Error(`target.setup_actions[${index}] ${type} requires key.`);
|
|
9120
9137
|
}
|
|
@@ -9176,6 +9193,10 @@ function normalizeSetupAction(input, index) {
|
|
|
9176
9193
|
text: stringValue5(input.text),
|
|
9177
9194
|
pattern: stringValue5(input.pattern),
|
|
9178
9195
|
flags: stringValue5(input.flags),
|
|
9196
|
+
accept: dialogAccept,
|
|
9197
|
+
prompt_text: stringFromOwn(input, "prompt_text", "promptText", "prompt_value", "promptValue"),
|
|
9198
|
+
message_text: stringFromOwn(input, "message_text", "messageText", "dialog_text", "dialogText"),
|
|
9199
|
+
message_pattern: stringFromOwn(input, "message_pattern", "messagePattern", "dialog_pattern", "dialogPattern"),
|
|
9179
9200
|
index: numberValue3(input.index),
|
|
9180
9201
|
expected_count: expectedCount,
|
|
9181
9202
|
ms: numberValue3(input.ms) ?? numberValue3(input.wait_ms) ?? numberValue3(input.waitMs),
|
|
@@ -9641,6 +9662,41 @@ function matchesAllowedMessage(input, texts, patterns) {
|
|
|
9641
9662
|
}
|
|
9642
9663
|
return false;
|
|
9643
9664
|
}
|
|
9665
|
+
function consoleEventLocationUrl(input) {
|
|
9666
|
+
if (!isRecord2(input) || !isRecord2(input.location)) return void 0;
|
|
9667
|
+
return stringValue5(input.location.url);
|
|
9668
|
+
}
|
|
9669
|
+
function expectedFailedNetworkMockEvents(evidence) {
|
|
9670
|
+
return (evidence.network_mocks || []).filter((event) => {
|
|
9671
|
+
if (!isRecord2(event) || event.ok === false) return false;
|
|
9672
|
+
const status = numberValue3(event.status);
|
|
9673
|
+
return status !== void 0 && status >= 400 && Boolean(stringValue5(event.url));
|
|
9674
|
+
});
|
|
9675
|
+
}
|
|
9676
|
+
function matchingExpectedFailedNetworkMockConsoleEvent(event, evidence) {
|
|
9677
|
+
const sample = allowedMessageSample(event);
|
|
9678
|
+
if (!/Failed to load resource/i.test(sample)) return void 0;
|
|
9679
|
+
const eventUrl = consoleEventLocationUrl(event);
|
|
9680
|
+
if (!eventUrl) return void 0;
|
|
9681
|
+
return expectedFailedNetworkMockEvents(evidence).find((mockEvent) => {
|
|
9682
|
+
const status = numberValue3(mockEvent.status);
|
|
9683
|
+
return stringValue5(mockEvent.url) === eventUrl && status !== void 0 && sample.includes(String(status));
|
|
9684
|
+
});
|
|
9685
|
+
}
|
|
9686
|
+
function isExpectedFailedNetworkMockConsoleEvent(event, evidence) {
|
|
9687
|
+
return Boolean(matchingExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
9688
|
+
}
|
|
9689
|
+
function expectedFailedNetworkMockConsoleEventSummary(event, evidence) {
|
|
9690
|
+
const match = matchingExpectedFailedNetworkMockConsoleEvent(event, evidence);
|
|
9691
|
+
const sample = allowedMessageSample(event);
|
|
9692
|
+
return {
|
|
9693
|
+
url: consoleEventLocationUrl(event) ?? null,
|
|
9694
|
+
status: match ? numberValue3(match.status) ?? null : null,
|
|
9695
|
+
label: match ? stringValue5(match.label) ?? null : null,
|
|
9696
|
+
response_label: match ? stringValue5(match.response_label) ?? null : null,
|
|
9697
|
+
text: isRecord2(event) && typeof event.text === "string" ? event.text.slice(0, 300) : sample.slice(0, 300)
|
|
9698
|
+
};
|
|
9699
|
+
}
|
|
9644
9700
|
function normalizeRoutePath(path6) {
|
|
9645
9701
|
const value = path6 || "/";
|
|
9646
9702
|
if (value === "/") return "/";
|
|
@@ -10058,8 +10114,10 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
10058
10114
|
}
|
|
10059
10115
|
if (check.type === "no_fatal_console_errors") {
|
|
10060
10116
|
const fatalConsoleEvents = (evidence.console?.events || []).filter((event) => event.type === "error" || event.type === "assert");
|
|
10061
|
-
const
|
|
10062
|
-
const
|
|
10117
|
+
const explicitlyAllowedConsoleEvents = fatalConsoleEvents.filter((event) => matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns));
|
|
10118
|
+
const expectedNetworkMockConsoleEvents = fatalConsoleEvents.filter((event) => !matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns) && isExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
10119
|
+
const allowedConsoleEvents = fatalConsoleEvents.filter((event) => matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns) || isExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
10120
|
+
const unallowedConsoleEvents = fatalConsoleEvents.filter((event) => !matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns) && !isExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
10063
10121
|
const pageErrors = evidence.page_errors || [];
|
|
10064
10122
|
const allowedPageErrors = pageErrors.filter((error) => matchesAllowedMessage(error, check.allowed_page_error_texts, check.allowed_page_error_patterns));
|
|
10065
10123
|
const unallowedPageErrors = pageErrors.filter((error) => !matchesAllowedMessage(error, check.allowed_page_error_texts, check.allowed_page_error_patterns));
|
|
@@ -10074,6 +10132,9 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
10074
10132
|
total_console_fatal_count: fatalConsoleEvents.length,
|
|
10075
10133
|
total_page_error_count: pageErrors.length,
|
|
10076
10134
|
allowed_console_fatal_count: allowedConsoleEvents.length,
|
|
10135
|
+
explicitly_allowed_console_fatal_count: explicitlyAllowedConsoleEvents.length,
|
|
10136
|
+
allowed_expected_network_mock_console_count: expectedNetworkMockConsoleEvents.length,
|
|
10137
|
+
allowed_expected_network_mock_console_events: expectedNetworkMockConsoleEvents.slice(0, 5).map((event) => expectedFailedNetworkMockConsoleEventSummary(event, evidence)),
|
|
10077
10138
|
allowed_page_error_count: allowedPageErrors.length,
|
|
10078
10139
|
allowed_console_texts: check.allowed_console_texts || [],
|
|
10079
10140
|
allowed_console_patterns: check.allowed_console_patterns || [],
|
|
@@ -10436,6 +10497,44 @@ function matchesAllowedMessage(input, texts, patterns) {
|
|
|
10436
10497
|
}
|
|
10437
10498
|
return false;
|
|
10438
10499
|
}
|
|
10500
|
+
function consoleEventLocationUrl(input) {
|
|
10501
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return undefined;
|
|
10502
|
+
if (!input.location || typeof input.location !== "object" || Array.isArray(input.location)) return undefined;
|
|
10503
|
+
return typeof input.location.url === "string" && input.location.url.trim() ? input.location.url.trim() : undefined;
|
|
10504
|
+
}
|
|
10505
|
+
function expectedFailedNetworkMockEvents(evidence) {
|
|
10506
|
+
return ((evidence && evidence.network_mocks) || []).filter((event) => {
|
|
10507
|
+
if (!event || typeof event !== "object" || Array.isArray(event) || event.ok === false) return false;
|
|
10508
|
+
const status = typeof event.status === "number" && Number.isFinite(event.status) ? event.status : undefined;
|
|
10509
|
+
const url = typeof event.url === "string" && event.url.trim() ? event.url.trim() : undefined;
|
|
10510
|
+
return status !== undefined && status >= 400 && Boolean(url);
|
|
10511
|
+
});
|
|
10512
|
+
}
|
|
10513
|
+
function matchingExpectedFailedNetworkMockConsoleEvent(event, evidence) {
|
|
10514
|
+
const sample = allowedMessageSample(event);
|
|
10515
|
+
if (!/Failed to load resource/i.test(sample)) return undefined;
|
|
10516
|
+
const eventUrl = consoleEventLocationUrl(event);
|
|
10517
|
+
if (!eventUrl) return undefined;
|
|
10518
|
+
return expectedFailedNetworkMockEvents(evidence).find((mockEvent) => {
|
|
10519
|
+
const status = typeof mockEvent.status === "number" && Number.isFinite(mockEvent.status) ? mockEvent.status : undefined;
|
|
10520
|
+
const mockUrl = typeof mockEvent.url === "string" && mockEvent.url.trim() ? mockEvent.url.trim() : undefined;
|
|
10521
|
+
return mockUrl === eventUrl && status !== undefined && sample.includes(String(status));
|
|
10522
|
+
});
|
|
10523
|
+
}
|
|
10524
|
+
function isExpectedFailedNetworkMockConsoleEvent(event, evidence) {
|
|
10525
|
+
return Boolean(matchingExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
10526
|
+
}
|
|
10527
|
+
function expectedFailedNetworkMockConsoleEventSummary(event, evidence) {
|
|
10528
|
+
const match = matchingExpectedFailedNetworkMockConsoleEvent(event, evidence);
|
|
10529
|
+
const sample = allowedMessageSample(event);
|
|
10530
|
+
return {
|
|
10531
|
+
url: consoleEventLocationUrl(event) || null,
|
|
10532
|
+
status: match && typeof match.status === "number" && Number.isFinite(match.status) ? match.status : null,
|
|
10533
|
+
label: match && typeof match.label === "string" && match.label.trim() ? match.label.trim() : null,
|
|
10534
|
+
response_label: match && typeof match.response_label === "string" && match.response_label.trim() ? match.response_label.trim() : null,
|
|
10535
|
+
text: event && typeof event === "object" && !Array.isArray(event) && typeof event.text === "string" ? event.text.slice(0, 300) : sample.slice(0, 300),
|
|
10536
|
+
};
|
|
10537
|
+
}
|
|
10439
10538
|
function textSequenceForCheck(viewport, check) {
|
|
10440
10539
|
const key = check.selector || "";
|
|
10441
10540
|
const sequence = viewport.text_sequences && viewport.text_sequences[key];
|
|
@@ -11159,8 +11258,19 @@ function assessProfile(profile, evidence) {
|
|
|
11159
11258
|
}
|
|
11160
11259
|
if (check.type === "no_fatal_console_errors") {
|
|
11161
11260
|
const fatalConsoleEvents = ((evidence.console && evidence.console.events) || []).filter((event) => event && (event.type === "error" || event.type === "assert"));
|
|
11162
|
-
const
|
|
11163
|
-
const
|
|
11261
|
+
const explicitlyAllowedConsoleEvents = fatalConsoleEvents.filter((event) => matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns));
|
|
11262
|
+
const expectedNetworkMockConsoleEvents = fatalConsoleEvents.filter((event) => (
|
|
11263
|
+
!matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns)
|
|
11264
|
+
&& isExpectedFailedNetworkMockConsoleEvent(event, evidence)
|
|
11265
|
+
));
|
|
11266
|
+
const allowedConsoleEvents = fatalConsoleEvents.filter((event) => (
|
|
11267
|
+
matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns)
|
|
11268
|
+
|| isExpectedFailedNetworkMockConsoleEvent(event, evidence)
|
|
11269
|
+
));
|
|
11270
|
+
const unallowedConsoleEvents = fatalConsoleEvents.filter((event) => (
|
|
11271
|
+
!matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns)
|
|
11272
|
+
&& !isExpectedFailedNetworkMockConsoleEvent(event, evidence)
|
|
11273
|
+
));
|
|
11164
11274
|
const pageErrors = evidence.page_errors || [];
|
|
11165
11275
|
const allowedPageErrors = pageErrors.filter((error) => matchesAllowedMessage(error, check.allowed_page_error_texts, check.allowed_page_error_patterns));
|
|
11166
11276
|
const unallowedPageErrors = pageErrors.filter((error) => !matchesAllowedMessage(error, check.allowed_page_error_texts, check.allowed_page_error_patterns));
|
|
@@ -11175,6 +11285,9 @@ function assessProfile(profile, evidence) {
|
|
|
11175
11285
|
total_console_fatal_count: fatalConsoleEvents.length,
|
|
11176
11286
|
total_page_error_count: pageErrors.length,
|
|
11177
11287
|
allowed_console_fatal_count: allowedConsoleEvents.length,
|
|
11288
|
+
explicitly_allowed_console_fatal_count: explicitlyAllowedConsoleEvents.length,
|
|
11289
|
+
allowed_expected_network_mock_console_count: expectedNetworkMockConsoleEvents.length,
|
|
11290
|
+
allowed_expected_network_mock_console_events: expectedNetworkMockConsoleEvents.slice(0, 5).map((event) => expectedFailedNetworkMockConsoleEventSummary(event, evidence)),
|
|
11178
11291
|
allowed_page_error_count: allowedPageErrors.length,
|
|
11179
11292
|
allowed_console_texts: check.allowed_console_texts || [],
|
|
11180
11293
|
allowed_console_patterns: check.allowed_console_patterns || [],
|
|
@@ -11234,6 +11347,9 @@ const capturedAt = new Date().toISOString();
|
|
|
11234
11347
|
const consoleEvents = [];
|
|
11235
11348
|
const pageErrors = [];
|
|
11236
11349
|
const networkMockEvents = [];
|
|
11350
|
+
const dialogEvents = [];
|
|
11351
|
+
let dialogResponseConfig = null;
|
|
11352
|
+
let dialogHandlerInstalled = false;
|
|
11237
11353
|
page.on("console", (message) => {
|
|
11238
11354
|
const type = message.type();
|
|
11239
11355
|
if (type === "error" || type === "warning" || type === "assert") {
|
|
@@ -11247,6 +11363,50 @@ page.on("console", (message) => {
|
|
|
11247
11363
|
page.on("pageerror", (error) => {
|
|
11248
11364
|
pageErrors.push({ message: String(error && error.message ? error.message : error).slice(0, 1000) });
|
|
11249
11365
|
});
|
|
11366
|
+
function setupDialogMessageMatches(message, config) {
|
|
11367
|
+
if (!config) return true;
|
|
11368
|
+
if (config.message_pattern) {
|
|
11369
|
+
try { return new RegExp(config.message_pattern, config.flags || "").test(message || ""); } catch { return false; }
|
|
11370
|
+
}
|
|
11371
|
+
if (config.message_text) return String(message || "").includes(config.message_text);
|
|
11372
|
+
return true;
|
|
11373
|
+
}
|
|
11374
|
+
function ensureDialogHandler() {
|
|
11375
|
+
if (dialogHandlerInstalled) return;
|
|
11376
|
+
dialogHandlerInstalled = true;
|
|
11377
|
+
page.on("dialog", async (dialog) => {
|
|
11378
|
+
const config = dialogResponseConfig || { accept: false };
|
|
11379
|
+
const message = typeof dialog.message === "function" ? dialog.message() : "";
|
|
11380
|
+
const type = typeof dialog.type === "function" ? dialog.type() : "dialog";
|
|
11381
|
+
const defaultValue = typeof dialog.defaultValue === "function" ? dialog.defaultValue() : "";
|
|
11382
|
+
const accept = config.accept !== false;
|
|
11383
|
+
const event = {
|
|
11384
|
+
type,
|
|
11385
|
+
message: String(message || "").slice(0, 1000),
|
|
11386
|
+
default_value: String(defaultValue || "").slice(0, 500),
|
|
11387
|
+
configured: Boolean(dialogResponseConfig),
|
|
11388
|
+
response: accept ? "accept" : "dismiss",
|
|
11389
|
+
message_matches: setupDialogMessageMatches(message, config),
|
|
11390
|
+
expected_message_text: config.message_text || undefined,
|
|
11391
|
+
expected_message_pattern: config.message_pattern || undefined,
|
|
11392
|
+
};
|
|
11393
|
+
try {
|
|
11394
|
+
if (accept) {
|
|
11395
|
+
const promptText = config.prompt_text === undefined ? undefined : String(config.prompt_text);
|
|
11396
|
+
await dialog.accept(promptText);
|
|
11397
|
+
} else {
|
|
11398
|
+
await dialog.dismiss();
|
|
11399
|
+
}
|
|
11400
|
+
dialogEvents.push({ ...event, ok: true });
|
|
11401
|
+
} catch (error) {
|
|
11402
|
+
dialogEvents.push({
|
|
11403
|
+
...event,
|
|
11404
|
+
ok: false,
|
|
11405
|
+
error: String(error && error.message ? error.message : error).slice(0, 1000),
|
|
11406
|
+
});
|
|
11407
|
+
}
|
|
11408
|
+
});
|
|
11409
|
+
}
|
|
11250
11410
|
function textKey(check) {
|
|
11251
11411
|
return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
11252
11412
|
}
|
|
@@ -11585,6 +11745,24 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
11585
11745
|
pageErrors.length = 0;
|
|
11586
11746
|
return { ...base, ok: true, cleared_console_event_count, cleared_page_error_count };
|
|
11587
11747
|
}
|
|
11748
|
+
if (type === "dialog_response") {
|
|
11749
|
+
ensureDialogHandler();
|
|
11750
|
+
dialogResponseConfig = {
|
|
11751
|
+
accept: action.accept !== false,
|
|
11752
|
+
prompt_text: action.prompt_text,
|
|
11753
|
+
message_text: action.message_text,
|
|
11754
|
+
message_pattern: action.message_pattern,
|
|
11755
|
+
flags: action.flags || "",
|
|
11756
|
+
};
|
|
11757
|
+
return {
|
|
11758
|
+
...base,
|
|
11759
|
+
ok: true,
|
|
11760
|
+
response: dialogResponseConfig.accept ? "accept" : "dismiss",
|
|
11761
|
+
message_text: dialogResponseConfig.message_text || undefined,
|
|
11762
|
+
message_pattern: dialogResponseConfig.message_pattern || undefined,
|
|
11763
|
+
prompt_text_length: dialogResponseConfig.prompt_text === undefined ? undefined : String(dialogResponseConfig.prompt_text).length,
|
|
11764
|
+
};
|
|
11765
|
+
}
|
|
11588
11766
|
if (type === "wait_for_selector") {
|
|
11589
11767
|
const scope = await setupActionScope(action, timeout);
|
|
11590
11768
|
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
@@ -12685,6 +12863,7 @@ function buildProfileEvidence(currentViewports) {
|
|
|
12685
12863
|
fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
|
|
12686
12864
|
},
|
|
12687
12865
|
page_errors: pageErrors,
|
|
12866
|
+
dialogs: dialogEvents.slice(),
|
|
12688
12867
|
network_mocks: networkMockEvents.slice(),
|
|
12689
12868
|
dom_summary: {
|
|
12690
12869
|
expected_viewport_count: expectedViewportCount,
|
|
@@ -12724,6 +12903,9 @@ function buildProfileEvidence(currentViewports) {
|
|
|
12724
12903
|
})),
|
|
12725
12904
|
network_mock_count: (profile.target.network_mocks || []).length,
|
|
12726
12905
|
network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
|
|
12906
|
+
dialog_count: dialogEvents.length,
|
|
12907
|
+
dialog_accept_count: dialogEvents.filter((event) => event.response === "accept" && event.ok !== false).length,
|
|
12908
|
+
dialog_dismiss_count: dialogEvents.filter((event) => event.response === "dismiss" && event.ok !== false).length,
|
|
12727
12909
|
},
|
|
12728
12910
|
};
|
|
12729
12911
|
}
|
|
@@ -12732,7 +12914,7 @@ async function saveProfileArtifacts(currentViewports) {
|
|
|
12732
12914
|
const result = assessProfile(profile, evidence);
|
|
12733
12915
|
if (typeof saveJson === "function") {
|
|
12734
12916
|
await saveJson("proof.json", result);
|
|
12735
|
-
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors });
|
|
12917
|
+
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors, dialogs: dialogEvents });
|
|
12736
12918
|
await saveJson("dom-summary.json", evidence.dom_summary);
|
|
12737
12919
|
}
|
|
12738
12920
|
return result;
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
resolveRiddleProofProfileTimeoutSec,
|
|
59
59
|
slugifyRiddleProofProfileName,
|
|
60
60
|
summarizeRiddleProofProfileResult
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-3RUIKF4C.js";
|
|
62
62
|
import {
|
|
63
63
|
DEFAULT_RIDDLE_API_BASE_URL,
|
|
64
64
|
DEFAULT_RIDDLE_API_KEY_FILE,
|
package/dist/profile.cjs
CHANGED
|
@@ -90,6 +90,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
|
90
90
|
"session_storage",
|
|
91
91
|
"clear_storage",
|
|
92
92
|
"clear_console",
|
|
93
|
+
"dialog_response",
|
|
93
94
|
"screenshot",
|
|
94
95
|
"wait",
|
|
95
96
|
"wait_for_selector",
|
|
@@ -351,7 +352,7 @@ function isSupportedCheckType(value) {
|
|
|
351
352
|
}
|
|
352
353
|
function normalizeSetupActionType(value, index) {
|
|
353
354
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
354
|
-
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput;
|
|
355
|
+
const normalized = normalizedInput === "clear_browser_storage" ? "clear_storage" : normalizedInput === "reset_console" || normalizedInput === "clear_browser_console" || normalizedInput === "reset_browser_console" ? "clear_console" : normalizedInput === "pointer_drag" || normalizedInput === "mouse_drag" || normalizedInput === "drag_to" ? "drag" : normalizedInput === "keyboard_press" || normalizedInput === "key_press" ? "press" : normalizedInput === "capture_screenshot" || normalizedInput === "save_screenshot" || normalizedInput === "setup_screenshot" ? "screenshot" : normalizedInput === "accept_dialog" || normalizedInput === "accept_dialogs" || normalizedInput === "confirm_dialog" || normalizedInput === "set_dialog_response" ? "dialog_response" : normalizedInput === "dismiss_dialog" || normalizedInput === "dismiss_dialogs" || normalizedInput === "cancel_dialog" ? "dialog_response" : normalizedInput;
|
|
355
356
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
356
357
|
return normalized;
|
|
357
358
|
}
|
|
@@ -403,6 +404,7 @@ function normalizeSetupActionCoordinateMode(value, index) {
|
|
|
403
404
|
function normalizeSetupAction(input, index) {
|
|
404
405
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
405
406
|
const type = normalizeSetupActionType(stringValue(input.type), index);
|
|
407
|
+
const rawType = String(input.type || "").trim().replace(/-/g, "_").toLowerCase();
|
|
406
408
|
const selector = stringValue(input.selector);
|
|
407
409
|
const frameSelector = stringFromOwn(input, "frame_selector", "frameSelector", "iframe_selector", "iframeSelector");
|
|
408
410
|
const frameIndex = numberValue(valueFromOwn(input, "frame_index", "frameIndex", "iframe_index", "iframeIndex"));
|
|
@@ -444,6 +446,21 @@ function normalizeSetupAction(input, index) {
|
|
|
444
446
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
445
447
|
}
|
|
446
448
|
const key = stringValue(input.key);
|
|
449
|
+
let dialogAccept;
|
|
450
|
+
if (type === "dialog_response") {
|
|
451
|
+
const acceptInput = valueFromOwn(input, "accept", "accepted", "should_accept", "shouldAccept");
|
|
452
|
+
const responseInput = stringFromOwn(input, "response", "dialog_response", "dialogResponse", "mode");
|
|
453
|
+
const response = String(responseInput || "").trim().toLowerCase().replace(/-/g, "_");
|
|
454
|
+
if (acceptInput !== void 0) {
|
|
455
|
+
dialogAccept = acceptInput !== false && String(acceptInput).toLowerCase() !== "false";
|
|
456
|
+
} else if (rawType === "dismiss_dialog" || rawType === "dismiss_dialogs" || rawType === "cancel_dialog") {
|
|
457
|
+
dialogAccept = false;
|
|
458
|
+
} else if (response === "dismiss" || response === "cancel" || response === "reject" || response === "no" || response === "false") {
|
|
459
|
+
dialogAccept = false;
|
|
460
|
+
} else {
|
|
461
|
+
dialogAccept = true;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
447
464
|
if (type === "press" && !key) {
|
|
448
465
|
throw new Error(`target.setup_actions[${index}] ${type} requires key.`);
|
|
449
466
|
}
|
|
@@ -505,6 +522,10 @@ function normalizeSetupAction(input, index) {
|
|
|
505
522
|
text: stringValue(input.text),
|
|
506
523
|
pattern: stringValue(input.pattern),
|
|
507
524
|
flags: stringValue(input.flags),
|
|
525
|
+
accept: dialogAccept,
|
|
526
|
+
prompt_text: stringFromOwn(input, "prompt_text", "promptText", "prompt_value", "promptValue"),
|
|
527
|
+
message_text: stringFromOwn(input, "message_text", "messageText", "dialog_text", "dialogText"),
|
|
528
|
+
message_pattern: stringFromOwn(input, "message_pattern", "messagePattern", "dialog_pattern", "dialogPattern"),
|
|
508
529
|
index: numberValue(input.index),
|
|
509
530
|
expected_count: expectedCount,
|
|
510
531
|
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
@@ -970,6 +991,41 @@ function matchesAllowedMessage(input, texts, patterns) {
|
|
|
970
991
|
}
|
|
971
992
|
return false;
|
|
972
993
|
}
|
|
994
|
+
function consoleEventLocationUrl(input) {
|
|
995
|
+
if (!isRecord(input) || !isRecord(input.location)) return void 0;
|
|
996
|
+
return stringValue(input.location.url);
|
|
997
|
+
}
|
|
998
|
+
function expectedFailedNetworkMockEvents(evidence) {
|
|
999
|
+
return (evidence.network_mocks || []).filter((event) => {
|
|
1000
|
+
if (!isRecord(event) || event.ok === false) return false;
|
|
1001
|
+
const status = numberValue(event.status);
|
|
1002
|
+
return status !== void 0 && status >= 400 && Boolean(stringValue(event.url));
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
function matchingExpectedFailedNetworkMockConsoleEvent(event, evidence) {
|
|
1006
|
+
const sample = allowedMessageSample(event);
|
|
1007
|
+
if (!/Failed to load resource/i.test(sample)) return void 0;
|
|
1008
|
+
const eventUrl = consoleEventLocationUrl(event);
|
|
1009
|
+
if (!eventUrl) return void 0;
|
|
1010
|
+
return expectedFailedNetworkMockEvents(evidence).find((mockEvent) => {
|
|
1011
|
+
const status = numberValue(mockEvent.status);
|
|
1012
|
+
return stringValue(mockEvent.url) === eventUrl && status !== void 0 && sample.includes(String(status));
|
|
1013
|
+
});
|
|
1014
|
+
}
|
|
1015
|
+
function isExpectedFailedNetworkMockConsoleEvent(event, evidence) {
|
|
1016
|
+
return Boolean(matchingExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
1017
|
+
}
|
|
1018
|
+
function expectedFailedNetworkMockConsoleEventSummary(event, evidence) {
|
|
1019
|
+
const match = matchingExpectedFailedNetworkMockConsoleEvent(event, evidence);
|
|
1020
|
+
const sample = allowedMessageSample(event);
|
|
1021
|
+
return {
|
|
1022
|
+
url: consoleEventLocationUrl(event) ?? null,
|
|
1023
|
+
status: match ? numberValue(match.status) ?? null : null,
|
|
1024
|
+
label: match ? stringValue(match.label) ?? null : null,
|
|
1025
|
+
response_label: match ? stringValue(match.response_label) ?? null : null,
|
|
1026
|
+
text: isRecord(event) && typeof event.text === "string" ? event.text.slice(0, 300) : sample.slice(0, 300)
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
973
1029
|
function normalizeRoutePath(path) {
|
|
974
1030
|
const value = path || "/";
|
|
975
1031
|
if (value === "/") return "/";
|
|
@@ -1387,8 +1443,10 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
1387
1443
|
}
|
|
1388
1444
|
if (check.type === "no_fatal_console_errors") {
|
|
1389
1445
|
const fatalConsoleEvents = (evidence.console?.events || []).filter((event) => event.type === "error" || event.type === "assert");
|
|
1390
|
-
const
|
|
1391
|
-
const
|
|
1446
|
+
const explicitlyAllowedConsoleEvents = fatalConsoleEvents.filter((event) => matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns));
|
|
1447
|
+
const expectedNetworkMockConsoleEvents = fatalConsoleEvents.filter((event) => !matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns) && isExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
1448
|
+
const allowedConsoleEvents = fatalConsoleEvents.filter((event) => matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns) || isExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
1449
|
+
const unallowedConsoleEvents = fatalConsoleEvents.filter((event) => !matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns) && !isExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
1392
1450
|
const pageErrors = evidence.page_errors || [];
|
|
1393
1451
|
const allowedPageErrors = pageErrors.filter((error) => matchesAllowedMessage(error, check.allowed_page_error_texts, check.allowed_page_error_patterns));
|
|
1394
1452
|
const unallowedPageErrors = pageErrors.filter((error) => !matchesAllowedMessage(error, check.allowed_page_error_texts, check.allowed_page_error_patterns));
|
|
@@ -1403,6 +1461,9 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
1403
1461
|
total_console_fatal_count: fatalConsoleEvents.length,
|
|
1404
1462
|
total_page_error_count: pageErrors.length,
|
|
1405
1463
|
allowed_console_fatal_count: allowedConsoleEvents.length,
|
|
1464
|
+
explicitly_allowed_console_fatal_count: explicitlyAllowedConsoleEvents.length,
|
|
1465
|
+
allowed_expected_network_mock_console_count: expectedNetworkMockConsoleEvents.length,
|
|
1466
|
+
allowed_expected_network_mock_console_events: expectedNetworkMockConsoleEvents.slice(0, 5).map((event) => expectedFailedNetworkMockConsoleEventSummary(event, evidence)),
|
|
1406
1467
|
allowed_page_error_count: allowedPageErrors.length,
|
|
1407
1468
|
allowed_console_texts: check.allowed_console_texts || [],
|
|
1408
1469
|
allowed_console_patterns: check.allowed_console_patterns || [],
|
|
@@ -1765,6 +1826,44 @@ function matchesAllowedMessage(input, texts, patterns) {
|
|
|
1765
1826
|
}
|
|
1766
1827
|
return false;
|
|
1767
1828
|
}
|
|
1829
|
+
function consoleEventLocationUrl(input) {
|
|
1830
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return undefined;
|
|
1831
|
+
if (!input.location || typeof input.location !== "object" || Array.isArray(input.location)) return undefined;
|
|
1832
|
+
return typeof input.location.url === "string" && input.location.url.trim() ? input.location.url.trim() : undefined;
|
|
1833
|
+
}
|
|
1834
|
+
function expectedFailedNetworkMockEvents(evidence) {
|
|
1835
|
+
return ((evidence && evidence.network_mocks) || []).filter((event) => {
|
|
1836
|
+
if (!event || typeof event !== "object" || Array.isArray(event) || event.ok === false) return false;
|
|
1837
|
+
const status = typeof event.status === "number" && Number.isFinite(event.status) ? event.status : undefined;
|
|
1838
|
+
const url = typeof event.url === "string" && event.url.trim() ? event.url.trim() : undefined;
|
|
1839
|
+
return status !== undefined && status >= 400 && Boolean(url);
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
function matchingExpectedFailedNetworkMockConsoleEvent(event, evidence) {
|
|
1843
|
+
const sample = allowedMessageSample(event);
|
|
1844
|
+
if (!/Failed to load resource/i.test(sample)) return undefined;
|
|
1845
|
+
const eventUrl = consoleEventLocationUrl(event);
|
|
1846
|
+
if (!eventUrl) return undefined;
|
|
1847
|
+
return expectedFailedNetworkMockEvents(evidence).find((mockEvent) => {
|
|
1848
|
+
const status = typeof mockEvent.status === "number" && Number.isFinite(mockEvent.status) ? mockEvent.status : undefined;
|
|
1849
|
+
const mockUrl = typeof mockEvent.url === "string" && mockEvent.url.trim() ? mockEvent.url.trim() : undefined;
|
|
1850
|
+
return mockUrl === eventUrl && status !== undefined && sample.includes(String(status));
|
|
1851
|
+
});
|
|
1852
|
+
}
|
|
1853
|
+
function isExpectedFailedNetworkMockConsoleEvent(event, evidence) {
|
|
1854
|
+
return Boolean(matchingExpectedFailedNetworkMockConsoleEvent(event, evidence));
|
|
1855
|
+
}
|
|
1856
|
+
function expectedFailedNetworkMockConsoleEventSummary(event, evidence) {
|
|
1857
|
+
const match = matchingExpectedFailedNetworkMockConsoleEvent(event, evidence);
|
|
1858
|
+
const sample = allowedMessageSample(event);
|
|
1859
|
+
return {
|
|
1860
|
+
url: consoleEventLocationUrl(event) || null,
|
|
1861
|
+
status: match && typeof match.status === "number" && Number.isFinite(match.status) ? match.status : null,
|
|
1862
|
+
label: match && typeof match.label === "string" && match.label.trim() ? match.label.trim() : null,
|
|
1863
|
+
response_label: match && typeof match.response_label === "string" && match.response_label.trim() ? match.response_label.trim() : null,
|
|
1864
|
+
text: event && typeof event === "object" && !Array.isArray(event) && typeof event.text === "string" ? event.text.slice(0, 300) : sample.slice(0, 300),
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1768
1867
|
function textSequenceForCheck(viewport, check) {
|
|
1769
1868
|
const key = check.selector || "";
|
|
1770
1869
|
const sequence = viewport.text_sequences && viewport.text_sequences[key];
|
|
@@ -2488,8 +2587,19 @@ function assessProfile(profile, evidence) {
|
|
|
2488
2587
|
}
|
|
2489
2588
|
if (check.type === "no_fatal_console_errors") {
|
|
2490
2589
|
const fatalConsoleEvents = ((evidence.console && evidence.console.events) || []).filter((event) => event && (event.type === "error" || event.type === "assert"));
|
|
2491
|
-
const
|
|
2492
|
-
const
|
|
2590
|
+
const explicitlyAllowedConsoleEvents = fatalConsoleEvents.filter((event) => matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns));
|
|
2591
|
+
const expectedNetworkMockConsoleEvents = fatalConsoleEvents.filter((event) => (
|
|
2592
|
+
!matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns)
|
|
2593
|
+
&& isExpectedFailedNetworkMockConsoleEvent(event, evidence)
|
|
2594
|
+
));
|
|
2595
|
+
const allowedConsoleEvents = fatalConsoleEvents.filter((event) => (
|
|
2596
|
+
matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns)
|
|
2597
|
+
|| isExpectedFailedNetworkMockConsoleEvent(event, evidence)
|
|
2598
|
+
));
|
|
2599
|
+
const unallowedConsoleEvents = fatalConsoleEvents.filter((event) => (
|
|
2600
|
+
!matchesAllowedMessage(event, check.allowed_console_texts, check.allowed_console_patterns)
|
|
2601
|
+
&& !isExpectedFailedNetworkMockConsoleEvent(event, evidence)
|
|
2602
|
+
));
|
|
2493
2603
|
const pageErrors = evidence.page_errors || [];
|
|
2494
2604
|
const allowedPageErrors = pageErrors.filter((error) => matchesAllowedMessage(error, check.allowed_page_error_texts, check.allowed_page_error_patterns));
|
|
2495
2605
|
const unallowedPageErrors = pageErrors.filter((error) => !matchesAllowedMessage(error, check.allowed_page_error_texts, check.allowed_page_error_patterns));
|
|
@@ -2504,6 +2614,9 @@ function assessProfile(profile, evidence) {
|
|
|
2504
2614
|
total_console_fatal_count: fatalConsoleEvents.length,
|
|
2505
2615
|
total_page_error_count: pageErrors.length,
|
|
2506
2616
|
allowed_console_fatal_count: allowedConsoleEvents.length,
|
|
2617
|
+
explicitly_allowed_console_fatal_count: explicitlyAllowedConsoleEvents.length,
|
|
2618
|
+
allowed_expected_network_mock_console_count: expectedNetworkMockConsoleEvents.length,
|
|
2619
|
+
allowed_expected_network_mock_console_events: expectedNetworkMockConsoleEvents.slice(0, 5).map((event) => expectedFailedNetworkMockConsoleEventSummary(event, evidence)),
|
|
2507
2620
|
allowed_page_error_count: allowedPageErrors.length,
|
|
2508
2621
|
allowed_console_texts: check.allowed_console_texts || [],
|
|
2509
2622
|
allowed_console_patterns: check.allowed_console_patterns || [],
|
|
@@ -2563,6 +2676,9 @@ const capturedAt = new Date().toISOString();
|
|
|
2563
2676
|
const consoleEvents = [];
|
|
2564
2677
|
const pageErrors = [];
|
|
2565
2678
|
const networkMockEvents = [];
|
|
2679
|
+
const dialogEvents = [];
|
|
2680
|
+
let dialogResponseConfig = null;
|
|
2681
|
+
let dialogHandlerInstalled = false;
|
|
2566
2682
|
page.on("console", (message) => {
|
|
2567
2683
|
const type = message.type();
|
|
2568
2684
|
if (type === "error" || type === "warning" || type === "assert") {
|
|
@@ -2576,6 +2692,50 @@ page.on("console", (message) => {
|
|
|
2576
2692
|
page.on("pageerror", (error) => {
|
|
2577
2693
|
pageErrors.push({ message: String(error && error.message ? error.message : error).slice(0, 1000) });
|
|
2578
2694
|
});
|
|
2695
|
+
function setupDialogMessageMatches(message, config) {
|
|
2696
|
+
if (!config) return true;
|
|
2697
|
+
if (config.message_pattern) {
|
|
2698
|
+
try { return new RegExp(config.message_pattern, config.flags || "").test(message || ""); } catch { return false; }
|
|
2699
|
+
}
|
|
2700
|
+
if (config.message_text) return String(message || "").includes(config.message_text);
|
|
2701
|
+
return true;
|
|
2702
|
+
}
|
|
2703
|
+
function ensureDialogHandler() {
|
|
2704
|
+
if (dialogHandlerInstalled) return;
|
|
2705
|
+
dialogHandlerInstalled = true;
|
|
2706
|
+
page.on("dialog", async (dialog) => {
|
|
2707
|
+
const config = dialogResponseConfig || { accept: false };
|
|
2708
|
+
const message = typeof dialog.message === "function" ? dialog.message() : "";
|
|
2709
|
+
const type = typeof dialog.type === "function" ? dialog.type() : "dialog";
|
|
2710
|
+
const defaultValue = typeof dialog.defaultValue === "function" ? dialog.defaultValue() : "";
|
|
2711
|
+
const accept = config.accept !== false;
|
|
2712
|
+
const event = {
|
|
2713
|
+
type,
|
|
2714
|
+
message: String(message || "").slice(0, 1000),
|
|
2715
|
+
default_value: String(defaultValue || "").slice(0, 500),
|
|
2716
|
+
configured: Boolean(dialogResponseConfig),
|
|
2717
|
+
response: accept ? "accept" : "dismiss",
|
|
2718
|
+
message_matches: setupDialogMessageMatches(message, config),
|
|
2719
|
+
expected_message_text: config.message_text || undefined,
|
|
2720
|
+
expected_message_pattern: config.message_pattern || undefined,
|
|
2721
|
+
};
|
|
2722
|
+
try {
|
|
2723
|
+
if (accept) {
|
|
2724
|
+
const promptText = config.prompt_text === undefined ? undefined : String(config.prompt_text);
|
|
2725
|
+
await dialog.accept(promptText);
|
|
2726
|
+
} else {
|
|
2727
|
+
await dialog.dismiss();
|
|
2728
|
+
}
|
|
2729
|
+
dialogEvents.push({ ...event, ok: true });
|
|
2730
|
+
} catch (error) {
|
|
2731
|
+
dialogEvents.push({
|
|
2732
|
+
...event,
|
|
2733
|
+
ok: false,
|
|
2734
|
+
error: String(error && error.message ? error.message : error).slice(0, 1000),
|
|
2735
|
+
});
|
|
2736
|
+
}
|
|
2737
|
+
});
|
|
2738
|
+
}
|
|
2579
2739
|
function textKey(check) {
|
|
2580
2740
|
return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
2581
2741
|
}
|
|
@@ -2914,6 +3074,24 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
2914
3074
|
pageErrors.length = 0;
|
|
2915
3075
|
return { ...base, ok: true, cleared_console_event_count, cleared_page_error_count };
|
|
2916
3076
|
}
|
|
3077
|
+
if (type === "dialog_response") {
|
|
3078
|
+
ensureDialogHandler();
|
|
3079
|
+
dialogResponseConfig = {
|
|
3080
|
+
accept: action.accept !== false,
|
|
3081
|
+
prompt_text: action.prompt_text,
|
|
3082
|
+
message_text: action.message_text,
|
|
3083
|
+
message_pattern: action.message_pattern,
|
|
3084
|
+
flags: action.flags || "",
|
|
3085
|
+
};
|
|
3086
|
+
return {
|
|
3087
|
+
...base,
|
|
3088
|
+
ok: true,
|
|
3089
|
+
response: dialogResponseConfig.accept ? "accept" : "dismiss",
|
|
3090
|
+
message_text: dialogResponseConfig.message_text || undefined,
|
|
3091
|
+
message_pattern: dialogResponseConfig.message_pattern || undefined,
|
|
3092
|
+
prompt_text_length: dialogResponseConfig.prompt_text === undefined ? undefined : String(dialogResponseConfig.prompt_text).length,
|
|
3093
|
+
};
|
|
3094
|
+
}
|
|
2917
3095
|
if (type === "wait_for_selector") {
|
|
2918
3096
|
const scope = await setupActionScope(action, timeout);
|
|
2919
3097
|
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
@@ -4014,6 +4192,7 @@ function buildProfileEvidence(currentViewports) {
|
|
|
4014
4192
|
fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
|
|
4015
4193
|
},
|
|
4016
4194
|
page_errors: pageErrors,
|
|
4195
|
+
dialogs: dialogEvents.slice(),
|
|
4017
4196
|
network_mocks: networkMockEvents.slice(),
|
|
4018
4197
|
dom_summary: {
|
|
4019
4198
|
expected_viewport_count: expectedViewportCount,
|
|
@@ -4053,6 +4232,9 @@ function buildProfileEvidence(currentViewports) {
|
|
|
4053
4232
|
})),
|
|
4054
4233
|
network_mock_count: (profile.target.network_mocks || []).length,
|
|
4055
4234
|
network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
|
|
4235
|
+
dialog_count: dialogEvents.length,
|
|
4236
|
+
dialog_accept_count: dialogEvents.filter((event) => event.response === "accept" && event.ok !== false).length,
|
|
4237
|
+
dialog_dismiss_count: dialogEvents.filter((event) => event.response === "dismiss" && event.ok !== false).length,
|
|
4056
4238
|
},
|
|
4057
4239
|
};
|
|
4058
4240
|
}
|
|
@@ -4061,7 +4243,7 @@ async function saveProfileArtifacts(currentViewports) {
|
|
|
4061
4243
|
const result = assessProfile(profile, evidence);
|
|
4062
4244
|
if (typeof saveJson === "function") {
|
|
4063
4245
|
await saveJson("proof.json", result);
|
|
4064
|
-
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors });
|
|
4246
|
+
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors, dialogs: dialogEvents });
|
|
4065
4247
|
await saveJson("dom-summary.json", evidence.dom_summary);
|
|
4066
4248
|
}
|
|
4067
4249
|
return result;
|
package/dist/profile.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evide
|
|
|
5
5
|
declare const RIDDLE_PROOF_PROFILE_RESULT_VERSION: "riddle-proof.profile-result.v1";
|
|
6
6
|
declare const RIDDLE_PROOF_PROFILE_STATUSES: readonly ["passed", "product_regression", "proof_insufficient", "environment_blocked", "configuration_error", "needs_human_review"];
|
|
7
7
|
declare const RIDDLE_PROOF_PROFILE_CHECK_TYPES: readonly ["route_loaded", "url_search_param_equals", "url_search_param_absent", "selector_visible", "selector_absent", "selector_count_at_least", "selector_count_equals", "selector_count_equal", "selector_count_eq", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors"];
|
|
8
|
-
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
8
|
+
declare const RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES: readonly ["click", "drag", "press", "fill", "set_input_value", "assert_text_visible", "assert_text_absent", "assert_selector_count", "assert_window_value", "assert_window_number", "local_storage", "session_storage", "clear_storage", "clear_console", "dialog_response", "screenshot", "wait", "wait_for_selector", "wait_for_text", "window_call"];
|
|
9
9
|
type RiddleProofProfileStatus = typeof RIDDLE_PROOF_PROFILE_STATUSES[number];
|
|
10
10
|
type RiddleProofProfileCheckType = typeof RIDDLE_PROOF_PROFILE_CHECK_TYPES[number];
|
|
11
11
|
type RiddleProofProfileSetupActionType = typeof RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES[number];
|
|
@@ -44,6 +44,10 @@ interface RiddleProofProfileSetupAction {
|
|
|
44
44
|
text?: string;
|
|
45
45
|
pattern?: string;
|
|
46
46
|
flags?: string;
|
|
47
|
+
accept?: boolean;
|
|
48
|
+
prompt_text?: string;
|
|
49
|
+
message_text?: string;
|
|
50
|
+
message_pattern?: string;
|
|
47
51
|
index?: number;
|
|
48
52
|
expected_count?: number;
|
|
49
53
|
ms?: number;
|