@riddledc/riddle-proof 0.7.78 → 0.7.80
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 +5 -3
- package/dist/{chunk-3K5AFX6X.js → chunk-3RUIKF4C.js} +92 -2
- package/dist/cli.cjs +96 -3
- package/dist/cli.js +5 -2
- package/dist/index.cjs +92 -2
- package/dist/index.js +1 -1
- package/dist/profile.cjs +92 -2
- 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/README.md
CHANGED
|
@@ -174,9 +174,11 @@ riddle-proof-loop run-profile \
|
|
|
174
174
|
Hosted profile runs emit Riddle poll progress to stderr while waiting. Use
|
|
175
175
|
`--quiet` to suppress progress lines, or `--progress-every-ms` to tune the
|
|
176
176
|
heartbeat cadence for long route-inventory or workflow profiles.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
Hosted `run-profile` submits package-generated profile scripts with
|
|
178
|
+
`strict=false` by default because the generated runner is larger than Riddle's
|
|
179
|
+
generic inline-script warning threshold. Use `--strict=true` when you
|
|
180
|
+
deliberately want Riddle's non-critical script-safety warnings to block the run.
|
|
181
|
+
Critical script-safety violations remain blocked by Riddle either way.
|
|
180
182
|
|
|
181
183
|
The package includes a generic starter profile at
|
|
182
184
|
`examples/profiles/page-content-basic.json`; copy that shape into a repository
|
|
@@ -47,6 +47,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
|
47
47
|
"session_storage",
|
|
48
48
|
"clear_storage",
|
|
49
49
|
"clear_console",
|
|
50
|
+
"dialog_response",
|
|
50
51
|
"screenshot",
|
|
51
52
|
"wait",
|
|
52
53
|
"wait_for_selector",
|
|
@@ -308,7 +309,7 @@ function isSupportedCheckType(value) {
|
|
|
308
309
|
}
|
|
309
310
|
function normalizeSetupActionType(value, index) {
|
|
310
311
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
311
|
-
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;
|
|
312
|
+
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;
|
|
312
313
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
313
314
|
return normalized;
|
|
314
315
|
}
|
|
@@ -360,6 +361,7 @@ function normalizeSetupActionCoordinateMode(value, index) {
|
|
|
360
361
|
function normalizeSetupAction(input, index) {
|
|
361
362
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
362
363
|
const type = normalizeSetupActionType(stringValue(input.type), index);
|
|
364
|
+
const rawType = String(input.type || "").trim().replace(/-/g, "_").toLowerCase();
|
|
363
365
|
const selector = stringValue(input.selector);
|
|
364
366
|
const frameSelector = stringFromOwn(input, "frame_selector", "frameSelector", "iframe_selector", "iframeSelector");
|
|
365
367
|
const frameIndex = numberValue(valueFromOwn(input, "frame_index", "frameIndex", "iframe_index", "iframeIndex"));
|
|
@@ -401,6 +403,21 @@ function normalizeSetupAction(input, index) {
|
|
|
401
403
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
402
404
|
}
|
|
403
405
|
const key = stringValue(input.key);
|
|
406
|
+
let dialogAccept;
|
|
407
|
+
if (type === "dialog_response") {
|
|
408
|
+
const acceptInput = valueFromOwn(input, "accept", "accepted", "should_accept", "shouldAccept");
|
|
409
|
+
const responseInput = stringFromOwn(input, "response", "dialog_response", "dialogResponse", "mode");
|
|
410
|
+
const response = String(responseInput || "").trim().toLowerCase().replace(/-/g, "_");
|
|
411
|
+
if (acceptInput !== void 0) {
|
|
412
|
+
dialogAccept = acceptInput !== false && String(acceptInput).toLowerCase() !== "false";
|
|
413
|
+
} else if (rawType === "dismiss_dialog" || rawType === "dismiss_dialogs" || rawType === "cancel_dialog") {
|
|
414
|
+
dialogAccept = false;
|
|
415
|
+
} else if (response === "dismiss" || response === "cancel" || response === "reject" || response === "no" || response === "false") {
|
|
416
|
+
dialogAccept = false;
|
|
417
|
+
} else {
|
|
418
|
+
dialogAccept = true;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
404
421
|
if (type === "press" && !key) {
|
|
405
422
|
throw new Error(`target.setup_actions[${index}] ${type} requires key.`);
|
|
406
423
|
}
|
|
@@ -462,6 +479,10 @@ function normalizeSetupAction(input, index) {
|
|
|
462
479
|
text: stringValue(input.text),
|
|
463
480
|
pattern: stringValue(input.pattern),
|
|
464
481
|
flags: stringValue(input.flags),
|
|
482
|
+
accept: dialogAccept,
|
|
483
|
+
prompt_text: stringFromOwn(input, "prompt_text", "promptText", "prompt_value", "promptValue"),
|
|
484
|
+
message_text: stringFromOwn(input, "message_text", "messageText", "dialog_text", "dialogText"),
|
|
485
|
+
message_pattern: stringFromOwn(input, "message_pattern", "messagePattern", "dialog_pattern", "dialogPattern"),
|
|
465
486
|
index: numberValue(input.index),
|
|
466
487
|
expected_count: expectedCount,
|
|
467
488
|
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
@@ -2612,6 +2633,9 @@ const capturedAt = new Date().toISOString();
|
|
|
2612
2633
|
const consoleEvents = [];
|
|
2613
2634
|
const pageErrors = [];
|
|
2614
2635
|
const networkMockEvents = [];
|
|
2636
|
+
const dialogEvents = [];
|
|
2637
|
+
let dialogResponseConfig = null;
|
|
2638
|
+
let dialogHandlerInstalled = false;
|
|
2615
2639
|
page.on("console", (message) => {
|
|
2616
2640
|
const type = message.type();
|
|
2617
2641
|
if (type === "error" || type === "warning" || type === "assert") {
|
|
@@ -2625,6 +2649,50 @@ page.on("console", (message) => {
|
|
|
2625
2649
|
page.on("pageerror", (error) => {
|
|
2626
2650
|
pageErrors.push({ message: String(error && error.message ? error.message : error).slice(0, 1000) });
|
|
2627
2651
|
});
|
|
2652
|
+
function setupDialogMessageMatches(message, config) {
|
|
2653
|
+
if (!config) return true;
|
|
2654
|
+
if (config.message_pattern) {
|
|
2655
|
+
try { return new RegExp(config.message_pattern, config.flags || "").test(message || ""); } catch { return false; }
|
|
2656
|
+
}
|
|
2657
|
+
if (config.message_text) return String(message || "").includes(config.message_text);
|
|
2658
|
+
return true;
|
|
2659
|
+
}
|
|
2660
|
+
function ensureDialogHandler() {
|
|
2661
|
+
if (dialogHandlerInstalled) return;
|
|
2662
|
+
dialogHandlerInstalled = true;
|
|
2663
|
+
page.on("dialog", async (dialog) => {
|
|
2664
|
+
const config = dialogResponseConfig || { accept: false };
|
|
2665
|
+
const message = typeof dialog.message === "function" ? dialog.message() : "";
|
|
2666
|
+
const type = typeof dialog.type === "function" ? dialog.type() : "dialog";
|
|
2667
|
+
const defaultValue = typeof dialog.defaultValue === "function" ? dialog.defaultValue() : "";
|
|
2668
|
+
const accept = config.accept !== false;
|
|
2669
|
+
const event = {
|
|
2670
|
+
type,
|
|
2671
|
+
message: String(message || "").slice(0, 1000),
|
|
2672
|
+
default_value: String(defaultValue || "").slice(0, 500),
|
|
2673
|
+
configured: Boolean(dialogResponseConfig),
|
|
2674
|
+
response: accept ? "accept" : "dismiss",
|
|
2675
|
+
message_matches: setupDialogMessageMatches(message, config),
|
|
2676
|
+
expected_message_text: config.message_text || undefined,
|
|
2677
|
+
expected_message_pattern: config.message_pattern || undefined,
|
|
2678
|
+
};
|
|
2679
|
+
try {
|
|
2680
|
+
if (accept) {
|
|
2681
|
+
const promptText = config.prompt_text === undefined ? undefined : String(config.prompt_text);
|
|
2682
|
+
await dialog.accept(promptText);
|
|
2683
|
+
} else {
|
|
2684
|
+
await dialog.dismiss();
|
|
2685
|
+
}
|
|
2686
|
+
dialogEvents.push({ ...event, ok: true });
|
|
2687
|
+
} catch (error) {
|
|
2688
|
+
dialogEvents.push({
|
|
2689
|
+
...event,
|
|
2690
|
+
ok: false,
|
|
2691
|
+
error: String(error && error.message ? error.message : error).slice(0, 1000),
|
|
2692
|
+
});
|
|
2693
|
+
}
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
2628
2696
|
function textKey(check) {
|
|
2629
2697
|
return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
2630
2698
|
}
|
|
@@ -2963,6 +3031,24 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
2963
3031
|
pageErrors.length = 0;
|
|
2964
3032
|
return { ...base, ok: true, cleared_console_event_count, cleared_page_error_count };
|
|
2965
3033
|
}
|
|
3034
|
+
if (type === "dialog_response") {
|
|
3035
|
+
ensureDialogHandler();
|
|
3036
|
+
dialogResponseConfig = {
|
|
3037
|
+
accept: action.accept !== false,
|
|
3038
|
+
prompt_text: action.prompt_text,
|
|
3039
|
+
message_text: action.message_text,
|
|
3040
|
+
message_pattern: action.message_pattern,
|
|
3041
|
+
flags: action.flags || "",
|
|
3042
|
+
};
|
|
3043
|
+
return {
|
|
3044
|
+
...base,
|
|
3045
|
+
ok: true,
|
|
3046
|
+
response: dialogResponseConfig.accept ? "accept" : "dismiss",
|
|
3047
|
+
message_text: dialogResponseConfig.message_text || undefined,
|
|
3048
|
+
message_pattern: dialogResponseConfig.message_pattern || undefined,
|
|
3049
|
+
prompt_text_length: dialogResponseConfig.prompt_text === undefined ? undefined : String(dialogResponseConfig.prompt_text).length,
|
|
3050
|
+
};
|
|
3051
|
+
}
|
|
2966
3052
|
if (type === "wait_for_selector") {
|
|
2967
3053
|
const scope = await setupActionScope(action, timeout);
|
|
2968
3054
|
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
@@ -4063,6 +4149,7 @@ function buildProfileEvidence(currentViewports) {
|
|
|
4063
4149
|
fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
|
|
4064
4150
|
},
|
|
4065
4151
|
page_errors: pageErrors,
|
|
4152
|
+
dialogs: dialogEvents.slice(),
|
|
4066
4153
|
network_mocks: networkMockEvents.slice(),
|
|
4067
4154
|
dom_summary: {
|
|
4068
4155
|
expected_viewport_count: expectedViewportCount,
|
|
@@ -4102,6 +4189,9 @@ function buildProfileEvidence(currentViewports) {
|
|
|
4102
4189
|
})),
|
|
4103
4190
|
network_mock_count: (profile.target.network_mocks || []).length,
|
|
4104
4191
|
network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
|
|
4192
|
+
dialog_count: dialogEvents.length,
|
|
4193
|
+
dialog_accept_count: dialogEvents.filter((event) => event.response === "accept" && event.ok !== false).length,
|
|
4194
|
+
dialog_dismiss_count: dialogEvents.filter((event) => event.response === "dismiss" && event.ok !== false).length,
|
|
4105
4195
|
},
|
|
4106
4196
|
};
|
|
4107
4197
|
}
|
|
@@ -4110,7 +4200,7 @@ async function saveProfileArtifacts(currentViewports) {
|
|
|
4110
4200
|
const result = assessProfile(profile, evidence);
|
|
4111
4201
|
if (typeof saveJson === "function") {
|
|
4112
4202
|
await saveJson("proof.json", result);
|
|
4113
|
-
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors });
|
|
4203
|
+
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors, dialogs: dialogEvents });
|
|
4114
4204
|
await saveJson("dom-summary.json", evidence.dom_summary);
|
|
4115
4205
|
}
|
|
4116
4206
|
return result;
|
package/dist/cli.cjs
CHANGED
|
@@ -6920,6 +6920,7 @@ var RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES = [
|
|
|
6920
6920
|
"session_storage",
|
|
6921
6921
|
"clear_storage",
|
|
6922
6922
|
"clear_console",
|
|
6923
|
+
"dialog_response",
|
|
6923
6924
|
"screenshot",
|
|
6924
6925
|
"wait",
|
|
6925
6926
|
"wait_for_selector",
|
|
@@ -7181,7 +7182,7 @@ function isSupportedCheckType(value) {
|
|
|
7181
7182
|
}
|
|
7182
7183
|
function normalizeSetupActionType(value, index) {
|
|
7183
7184
|
const normalizedInput = String(value || "").trim().replace(/-/g, "_");
|
|
7184
|
-
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;
|
|
7185
|
+
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;
|
|
7185
7186
|
if (RIDDLE_PROOF_PROFILE_SETUP_ACTION_TYPES.includes(normalized)) {
|
|
7186
7187
|
return normalized;
|
|
7187
7188
|
}
|
|
@@ -7233,6 +7234,7 @@ function normalizeSetupActionCoordinateMode(value, index) {
|
|
|
7233
7234
|
function normalizeSetupAction(input, index) {
|
|
7234
7235
|
if (!isRecord(input)) throw new Error(`target.setup_actions[${index}] must be an object.`);
|
|
7235
7236
|
const type = normalizeSetupActionType(stringValue2(input.type), index);
|
|
7237
|
+
const rawType = String(input.type || "").trim().replace(/-/g, "_").toLowerCase();
|
|
7236
7238
|
const selector = stringValue2(input.selector);
|
|
7237
7239
|
const frameSelector = stringFromOwn(input, "frame_selector", "frameSelector", "iframe_selector", "iframeSelector");
|
|
7238
7240
|
const frameIndex = numberValue(valueFromOwn(input, "frame_index", "frameIndex", "iframe_index", "iframeIndex"));
|
|
@@ -7274,6 +7276,21 @@ function normalizeSetupAction(input, index) {
|
|
|
7274
7276
|
throw new Error(`target.setup_actions[${index}] ${type} requires value.`);
|
|
7275
7277
|
}
|
|
7276
7278
|
const key = stringValue2(input.key);
|
|
7279
|
+
let dialogAccept;
|
|
7280
|
+
if (type === "dialog_response") {
|
|
7281
|
+
const acceptInput = valueFromOwn(input, "accept", "accepted", "should_accept", "shouldAccept");
|
|
7282
|
+
const responseInput = stringFromOwn(input, "response", "dialog_response", "dialogResponse", "mode");
|
|
7283
|
+
const response = String(responseInput || "").trim().toLowerCase().replace(/-/g, "_");
|
|
7284
|
+
if (acceptInput !== void 0) {
|
|
7285
|
+
dialogAccept = acceptInput !== false && String(acceptInput).toLowerCase() !== "false";
|
|
7286
|
+
} else if (rawType === "dismiss_dialog" || rawType === "dismiss_dialogs" || rawType === "cancel_dialog") {
|
|
7287
|
+
dialogAccept = false;
|
|
7288
|
+
} else if (response === "dismiss" || response === "cancel" || response === "reject" || response === "no" || response === "false") {
|
|
7289
|
+
dialogAccept = false;
|
|
7290
|
+
} else {
|
|
7291
|
+
dialogAccept = true;
|
|
7292
|
+
}
|
|
7293
|
+
}
|
|
7277
7294
|
if (type === "press" && !key) {
|
|
7278
7295
|
throw new Error(`target.setup_actions[${index}] ${type} requires key.`);
|
|
7279
7296
|
}
|
|
@@ -7335,6 +7352,10 @@ function normalizeSetupAction(input, index) {
|
|
|
7335
7352
|
text: stringValue2(input.text),
|
|
7336
7353
|
pattern: stringValue2(input.pattern),
|
|
7337
7354
|
flags: stringValue2(input.flags),
|
|
7355
|
+
accept: dialogAccept,
|
|
7356
|
+
prompt_text: stringFromOwn(input, "prompt_text", "promptText", "prompt_value", "promptValue"),
|
|
7357
|
+
message_text: stringFromOwn(input, "message_text", "messageText", "dialog_text", "dialogText"),
|
|
7358
|
+
message_pattern: stringFromOwn(input, "message_pattern", "messagePattern", "dialog_pattern", "dialogPattern"),
|
|
7338
7359
|
index: numberValue(input.index),
|
|
7339
7360
|
expected_count: expectedCount,
|
|
7340
7361
|
ms: numberValue(input.ms) ?? numberValue(input.wait_ms) ?? numberValue(input.waitMs),
|
|
@@ -9469,6 +9490,9 @@ const capturedAt = new Date().toISOString();
|
|
|
9469
9490
|
const consoleEvents = [];
|
|
9470
9491
|
const pageErrors = [];
|
|
9471
9492
|
const networkMockEvents = [];
|
|
9493
|
+
const dialogEvents = [];
|
|
9494
|
+
let dialogResponseConfig = null;
|
|
9495
|
+
let dialogHandlerInstalled = false;
|
|
9472
9496
|
page.on("console", (message) => {
|
|
9473
9497
|
const type = message.type();
|
|
9474
9498
|
if (type === "error" || type === "warning" || type === "assert") {
|
|
@@ -9482,6 +9506,50 @@ page.on("console", (message) => {
|
|
|
9482
9506
|
page.on("pageerror", (error) => {
|
|
9483
9507
|
pageErrors.push({ message: String(error && error.message ? error.message : error).slice(0, 1000) });
|
|
9484
9508
|
});
|
|
9509
|
+
function setupDialogMessageMatches(message, config) {
|
|
9510
|
+
if (!config) return true;
|
|
9511
|
+
if (config.message_pattern) {
|
|
9512
|
+
try { return new RegExp(config.message_pattern, config.flags || "").test(message || ""); } catch { return false; }
|
|
9513
|
+
}
|
|
9514
|
+
if (config.message_text) return String(message || "").includes(config.message_text);
|
|
9515
|
+
return true;
|
|
9516
|
+
}
|
|
9517
|
+
function ensureDialogHandler() {
|
|
9518
|
+
if (dialogHandlerInstalled) return;
|
|
9519
|
+
dialogHandlerInstalled = true;
|
|
9520
|
+
page.on("dialog", async (dialog) => {
|
|
9521
|
+
const config = dialogResponseConfig || { accept: false };
|
|
9522
|
+
const message = typeof dialog.message === "function" ? dialog.message() : "";
|
|
9523
|
+
const type = typeof dialog.type === "function" ? dialog.type() : "dialog";
|
|
9524
|
+
const defaultValue = typeof dialog.defaultValue === "function" ? dialog.defaultValue() : "";
|
|
9525
|
+
const accept = config.accept !== false;
|
|
9526
|
+
const event = {
|
|
9527
|
+
type,
|
|
9528
|
+
message: String(message || "").slice(0, 1000),
|
|
9529
|
+
default_value: String(defaultValue || "").slice(0, 500),
|
|
9530
|
+
configured: Boolean(dialogResponseConfig),
|
|
9531
|
+
response: accept ? "accept" : "dismiss",
|
|
9532
|
+
message_matches: setupDialogMessageMatches(message, config),
|
|
9533
|
+
expected_message_text: config.message_text || undefined,
|
|
9534
|
+
expected_message_pattern: config.message_pattern || undefined,
|
|
9535
|
+
};
|
|
9536
|
+
try {
|
|
9537
|
+
if (accept) {
|
|
9538
|
+
const promptText = config.prompt_text === undefined ? undefined : String(config.prompt_text);
|
|
9539
|
+
await dialog.accept(promptText);
|
|
9540
|
+
} else {
|
|
9541
|
+
await dialog.dismiss();
|
|
9542
|
+
}
|
|
9543
|
+
dialogEvents.push({ ...event, ok: true });
|
|
9544
|
+
} catch (error) {
|
|
9545
|
+
dialogEvents.push({
|
|
9546
|
+
...event,
|
|
9547
|
+
ok: false,
|
|
9548
|
+
error: String(error && error.message ? error.message : error).slice(0, 1000),
|
|
9549
|
+
});
|
|
9550
|
+
}
|
|
9551
|
+
});
|
|
9552
|
+
}
|
|
9485
9553
|
function textKey(check) {
|
|
9486
9554
|
return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
9487
9555
|
}
|
|
@@ -9820,6 +9888,24 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
9820
9888
|
pageErrors.length = 0;
|
|
9821
9889
|
return { ...base, ok: true, cleared_console_event_count, cleared_page_error_count };
|
|
9822
9890
|
}
|
|
9891
|
+
if (type === "dialog_response") {
|
|
9892
|
+
ensureDialogHandler();
|
|
9893
|
+
dialogResponseConfig = {
|
|
9894
|
+
accept: action.accept !== false,
|
|
9895
|
+
prompt_text: action.prompt_text,
|
|
9896
|
+
message_text: action.message_text,
|
|
9897
|
+
message_pattern: action.message_pattern,
|
|
9898
|
+
flags: action.flags || "",
|
|
9899
|
+
};
|
|
9900
|
+
return {
|
|
9901
|
+
...base,
|
|
9902
|
+
ok: true,
|
|
9903
|
+
response: dialogResponseConfig.accept ? "accept" : "dismiss",
|
|
9904
|
+
message_text: dialogResponseConfig.message_text || undefined,
|
|
9905
|
+
message_pattern: dialogResponseConfig.message_pattern || undefined,
|
|
9906
|
+
prompt_text_length: dialogResponseConfig.prompt_text === undefined ? undefined : String(dialogResponseConfig.prompt_text).length,
|
|
9907
|
+
};
|
|
9908
|
+
}
|
|
9823
9909
|
if (type === "wait_for_selector") {
|
|
9824
9910
|
const scope = await setupActionScope(action, timeout);
|
|
9825
9911
|
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
@@ -10920,6 +11006,7 @@ function buildProfileEvidence(currentViewports) {
|
|
|
10920
11006
|
fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
|
|
10921
11007
|
},
|
|
10922
11008
|
page_errors: pageErrors,
|
|
11009
|
+
dialogs: dialogEvents.slice(),
|
|
10923
11010
|
network_mocks: networkMockEvents.slice(),
|
|
10924
11011
|
dom_summary: {
|
|
10925
11012
|
expected_viewport_count: expectedViewportCount,
|
|
@@ -10959,6 +11046,9 @@ function buildProfileEvidence(currentViewports) {
|
|
|
10959
11046
|
})),
|
|
10960
11047
|
network_mock_count: (profile.target.network_mocks || []).length,
|
|
10961
11048
|
network_mock_hit_count: networkMockEvents.filter((event) => event.ok !== false).length,
|
|
11049
|
+
dialog_count: dialogEvents.length,
|
|
11050
|
+
dialog_accept_count: dialogEvents.filter((event) => event.response === "accept" && event.ok !== false).length,
|
|
11051
|
+
dialog_dismiss_count: dialogEvents.filter((event) => event.response === "dismiss" && event.ok !== false).length,
|
|
10962
11052
|
},
|
|
10963
11053
|
};
|
|
10964
11054
|
}
|
|
@@ -10967,7 +11057,7 @@ async function saveProfileArtifacts(currentViewports) {
|
|
|
10967
11057
|
const result = assessProfile(profile, evidence);
|
|
10968
11058
|
if (typeof saveJson === "function") {
|
|
10969
11059
|
await saveJson("proof.json", result);
|
|
10970
|
-
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors });
|
|
11060
|
+
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors, dialogs: dialogEvents });
|
|
10971
11061
|
await saveJson("dom-summary.json", evidence.dom_summary);
|
|
10972
11062
|
}
|
|
10973
11063
|
return result;
|
|
@@ -11136,6 +11226,9 @@ function optionBoolean(options, key) {
|
|
|
11136
11226
|
const flag = key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
11137
11227
|
throw new Error(`--${flag} must be true or false.`);
|
|
11138
11228
|
}
|
|
11229
|
+
function runProfileStrictOption(options) {
|
|
11230
|
+
return optionBoolean(options, "strict") ?? false;
|
|
11231
|
+
}
|
|
11139
11232
|
function optionNumber(options, ...keys) {
|
|
11140
11233
|
for (const key of keys) {
|
|
11141
11234
|
const value = optionString(options, key);
|
|
@@ -11664,7 +11757,7 @@ async function runProfileForCli(profile, options) {
|
|
|
11664
11757
|
profile,
|
|
11665
11758
|
optionString(options, "timeout") ? Number(optionString(options, "timeout")) : void 0
|
|
11666
11759
|
),
|
|
11667
|
-
strict:
|
|
11760
|
+
strict: runProfileStrictOption(options),
|
|
11668
11761
|
sync: options.sync === true ? true : void 0
|
|
11669
11762
|
});
|
|
11670
11763
|
} catch (error) {
|
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
profileStatusExitCode,
|
|
11
11
|
resolveRiddleProofProfileTargetUrl,
|
|
12
12
|
resolveRiddleProofProfileTimeoutSec
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-3RUIKF4C.js";
|
|
14
14
|
import {
|
|
15
15
|
createRiddleApiClient,
|
|
16
16
|
parseRiddleViewport
|
|
@@ -96,6 +96,9 @@ function optionBoolean(options, key) {
|
|
|
96
96
|
const flag = key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
97
97
|
throw new Error(`--${flag} must be true or false.`);
|
|
98
98
|
}
|
|
99
|
+
function runProfileStrictOption(options) {
|
|
100
|
+
return optionBoolean(options, "strict") ?? false;
|
|
101
|
+
}
|
|
99
102
|
function optionNumber(options, ...keys) {
|
|
100
103
|
for (const key of keys) {
|
|
101
104
|
const value = optionString(options, key);
|
|
@@ -624,7 +627,7 @@ async function runProfileForCli(profile, options) {
|
|
|
624
627
|
profile,
|
|
625
628
|
optionString(options, "timeout") ? Number(optionString(options, "timeout")) : void 0
|
|
626
629
|
),
|
|
627
|
-
strict:
|
|
630
|
+
strict: runProfileStrictOption(options),
|
|
628
631
|
sync: options.sync === true ? true : void 0
|
|
629
632
|
});
|
|
630
633
|
} catch (error) {
|
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),
|
|
@@ -11326,6 +11347,9 @@ const capturedAt = new Date().toISOString();
|
|
|
11326
11347
|
const consoleEvents = [];
|
|
11327
11348
|
const pageErrors = [];
|
|
11328
11349
|
const networkMockEvents = [];
|
|
11350
|
+
const dialogEvents = [];
|
|
11351
|
+
let dialogResponseConfig = null;
|
|
11352
|
+
let dialogHandlerInstalled = false;
|
|
11329
11353
|
page.on("console", (message) => {
|
|
11330
11354
|
const type = message.type();
|
|
11331
11355
|
if (type === "error" || type === "warning" || type === "assert") {
|
|
@@ -11339,6 +11363,50 @@ page.on("console", (message) => {
|
|
|
11339
11363
|
page.on("pageerror", (error) => {
|
|
11340
11364
|
pageErrors.push({ message: String(error && error.message ? error.message : error).slice(0, 1000) });
|
|
11341
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
|
+
}
|
|
11342
11410
|
function textKey(check) {
|
|
11343
11411
|
return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
11344
11412
|
}
|
|
@@ -11677,6 +11745,24 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
11677
11745
|
pageErrors.length = 0;
|
|
11678
11746
|
return { ...base, ok: true, cleared_console_event_count, cleared_page_error_count };
|
|
11679
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
|
+
}
|
|
11680
11766
|
if (type === "wait_for_selector") {
|
|
11681
11767
|
const scope = await setupActionScope(action, timeout);
|
|
11682
11768
|
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
@@ -12777,6 +12863,7 @@ function buildProfileEvidence(currentViewports) {
|
|
|
12777
12863
|
fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
|
|
12778
12864
|
},
|
|
12779
12865
|
page_errors: pageErrors,
|
|
12866
|
+
dialogs: dialogEvents.slice(),
|
|
12780
12867
|
network_mocks: networkMockEvents.slice(),
|
|
12781
12868
|
dom_summary: {
|
|
12782
12869
|
expected_viewport_count: expectedViewportCount,
|
|
@@ -12816,6 +12903,9 @@ function buildProfileEvidence(currentViewports) {
|
|
|
12816
12903
|
})),
|
|
12817
12904
|
network_mock_count: (profile.target.network_mocks || []).length,
|
|
12818
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,
|
|
12819
12909
|
},
|
|
12820
12910
|
};
|
|
12821
12911
|
}
|
|
@@ -12824,7 +12914,7 @@ async function saveProfileArtifacts(currentViewports) {
|
|
|
12824
12914
|
const result = assessProfile(profile, evidence);
|
|
12825
12915
|
if (typeof saveJson === "function") {
|
|
12826
12916
|
await saveJson("proof.json", result);
|
|
12827
|
-
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors });
|
|
12917
|
+
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors, dialogs: dialogEvents });
|
|
12828
12918
|
await saveJson("dom-summary.json", evidence.dom_summary);
|
|
12829
12919
|
}
|
|
12830
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),
|
|
@@ -2655,6 +2676,9 @@ const capturedAt = new Date().toISOString();
|
|
|
2655
2676
|
const consoleEvents = [];
|
|
2656
2677
|
const pageErrors = [];
|
|
2657
2678
|
const networkMockEvents = [];
|
|
2679
|
+
const dialogEvents = [];
|
|
2680
|
+
let dialogResponseConfig = null;
|
|
2681
|
+
let dialogHandlerInstalled = false;
|
|
2658
2682
|
page.on("console", (message) => {
|
|
2659
2683
|
const type = message.type();
|
|
2660
2684
|
if (type === "error" || type === "warning" || type === "assert") {
|
|
@@ -2668,6 +2692,50 @@ page.on("console", (message) => {
|
|
|
2668
2692
|
page.on("pageerror", (error) => {
|
|
2669
2693
|
pageErrors.push({ message: String(error && error.message ? error.message : error).slice(0, 1000) });
|
|
2670
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
|
+
}
|
|
2671
2739
|
function textKey(check) {
|
|
2672
2740
|
return check.pattern ? "pattern:" + check.pattern + "/" + (check.flags || "") : "text:" + (check.text || "");
|
|
2673
2741
|
}
|
|
@@ -3006,6 +3074,24 @@ async function executeSetupAction(action, ordinal, viewport) {
|
|
|
3006
3074
|
pageErrors.length = 0;
|
|
3007
3075
|
return { ...base, ok: true, cleared_console_event_count, cleared_page_error_count };
|
|
3008
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
|
+
}
|
|
3009
3095
|
if (type === "wait_for_selector") {
|
|
3010
3096
|
const scope = await setupActionScope(action, timeout);
|
|
3011
3097
|
if (!scope.ok) return setupScopeFailure(base, scope);
|
|
@@ -4106,6 +4192,7 @@ function buildProfileEvidence(currentViewports) {
|
|
|
4106
4192
|
fatal_count: consoleEvents.filter((event) => event.type === "error" || event.type === "assert").length,
|
|
4107
4193
|
},
|
|
4108
4194
|
page_errors: pageErrors,
|
|
4195
|
+
dialogs: dialogEvents.slice(),
|
|
4109
4196
|
network_mocks: networkMockEvents.slice(),
|
|
4110
4197
|
dom_summary: {
|
|
4111
4198
|
expected_viewport_count: expectedViewportCount,
|
|
@@ -4145,6 +4232,9 @@ function buildProfileEvidence(currentViewports) {
|
|
|
4145
4232
|
})),
|
|
4146
4233
|
network_mock_count: (profile.target.network_mocks || []).length,
|
|
4147
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,
|
|
4148
4238
|
},
|
|
4149
4239
|
};
|
|
4150
4240
|
}
|
|
@@ -4153,7 +4243,7 @@ async function saveProfileArtifacts(currentViewports) {
|
|
|
4153
4243
|
const result = assessProfile(profile, evidence);
|
|
4154
4244
|
if (typeof saveJson === "function") {
|
|
4155
4245
|
await saveJson("proof.json", result);
|
|
4156
|
-
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors });
|
|
4246
|
+
await saveJson("console.json", { events: consoleEvents, page_errors: pageErrors, dialogs: dialogEvents });
|
|
4157
4247
|
await saveJson("dom-summary.json", evidence.dom_summary);
|
|
4158
4248
|
}
|
|
4159
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;
|
package/dist/profile.d.ts
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;
|
package/dist/profile.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
resolveRiddleProofProfileTimeoutSec,
|
|
20
20
|
slugifyRiddleProofProfileName,
|
|
21
21
|
summarizeRiddleProofProfileResult
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-3RUIKF4C.js";
|
|
23
23
|
export {
|
|
24
24
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
25
25
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|