@riddledc/riddle-proof 0.7.114 → 0.7.115
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 +13 -0
- package/dist/{chunk-3CND75DM.js → chunk-QOOPPRYK.js} +55 -1
- package/dist/cli.cjs +55 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +55 -1
- package/dist/index.js +1 -1
- package/dist/profile.cjs +55 -1
- package/dist/profile.d.cts +1 -1
- package/dist/profile.d.ts +1 -1
- package/dist/profile.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -406,6 +406,19 @@ These checks are useful for audit/no-diff profiles where the product should
|
|
|
406
406
|
show a fallback state and avoid rendering stale loaders, duplicate rows, or
|
|
407
407
|
missing-resource iframes.
|
|
408
408
|
|
|
409
|
+
Use `dialog_count_equals`, `dialog_accept_count_equals`, and
|
|
410
|
+
`dialog_dismiss_count_equals` when destructive-action profiles need to prove
|
|
411
|
+
browser confirm/prompt handling directly. The counts come from the captured
|
|
412
|
+
dialog summary and use `expected_count`:
|
|
413
|
+
|
|
414
|
+
```json
|
|
415
|
+
[
|
|
416
|
+
{ "type": "dialog_count_equals", "expected_count": 2 },
|
|
417
|
+
{ "type": "dialog_accept_count_equals", "expected_count": 1 },
|
|
418
|
+
{ "type": "dialog_dismiss_count_equals", "expected_count": 1 }
|
|
419
|
+
]
|
|
420
|
+
```
|
|
421
|
+
|
|
409
422
|
Use `url_search_param_equals` and `url_search_param_absent` when the final URL
|
|
410
423
|
is part of the contract, such as deep-link recovery that must drop a stale
|
|
411
424
|
local identifier while preserving shareable query state:
|
|
@@ -20,6 +20,9 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
20
20
|
"selector_count_equals",
|
|
21
21
|
"selector_count_equal",
|
|
22
22
|
"selector_count_eq",
|
|
23
|
+
"dialog_count_equals",
|
|
24
|
+
"dialog_accept_count_equals",
|
|
25
|
+
"dialog_dismiss_count_equals",
|
|
23
26
|
"selector_text_visible",
|
|
24
27
|
"selector_text_absent",
|
|
25
28
|
"selector_text_order",
|
|
@@ -772,6 +775,14 @@ function validateRegexPatterns(patterns, label) {
|
|
|
772
775
|
}
|
|
773
776
|
}
|
|
774
777
|
}
|
|
778
|
+
function isDialogCountCheckType(type) {
|
|
779
|
+
return type === "dialog_count_equals" || type === "dialog_accept_count_equals" || type === "dialog_dismiss_count_equals";
|
|
780
|
+
}
|
|
781
|
+
function dialogCountFieldForCheckType(type) {
|
|
782
|
+
if (type === "dialog_accept_count_equals") return "dialog_accept_count";
|
|
783
|
+
if (type === "dialog_dismiss_count_equals") return "dialog_dismiss_count";
|
|
784
|
+
return "dialog_count";
|
|
785
|
+
}
|
|
775
786
|
function normalizeCheck(input, index) {
|
|
776
787
|
if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
777
788
|
const type = stringValue(input.type);
|
|
@@ -779,6 +790,7 @@ function normalizeCheck(input, index) {
|
|
|
779
790
|
if (!isSupportedCheckType(type)) {
|
|
780
791
|
throw new Error(`checks[${index}].type ${type} is not supported. Supported checks: ${RIDDLE_PROOF_PROFILE_CHECK_TYPES.join(", ")}`);
|
|
781
792
|
}
|
|
793
|
+
const isDialogCountCheck = isDialogCountCheckType(type);
|
|
782
794
|
if ((type === "selector_visible" || type === "selector_absent" || type === "selector_count_at_least" || type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || type === "selector_text_visible" || type === "selector_text_absent") && !stringValue(input.selector)) {
|
|
783
795
|
throw new Error(`checks[${index}] ${type} requires selector.`);
|
|
784
796
|
}
|
|
@@ -810,9 +822,12 @@ function normalizeCheck(input, index) {
|
|
|
810
822
|
throw new Error(`checks[${index}] selector_count_at_least requires min_count.`);
|
|
811
823
|
}
|
|
812
824
|
const expectedCount = numberValue(input.expected_count) ?? numberValue(input.expectedCount) ?? numberValue(input.count);
|
|
813
|
-
if ((type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq") && expectedCount === void 0) {
|
|
825
|
+
if ((type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || isDialogCountCheck) && expectedCount === void 0) {
|
|
814
826
|
throw new Error(`checks[${index}] ${type} requires expected_count.`);
|
|
815
827
|
}
|
|
828
|
+
if (isDialogCountCheck && (expectedCount === void 0 || !Number.isInteger(expectedCount) || expectedCount < 0)) {
|
|
829
|
+
throw new Error(`checks[${index}] ${type} expected_count must be a non-negative integer.`);
|
|
830
|
+
}
|
|
816
831
|
const expectedTexts = normalizeExpectedTexts(input.expected_texts ?? input.expectedTexts, index);
|
|
817
832
|
if (type === "selector_text_order") {
|
|
818
833
|
if (!stringValue(input.selector)) throw new Error(`checks[${index}] selector_text_order requires selector.`);
|
|
@@ -1482,6 +1497,22 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
1482
1497
|
message: check.viewports?.length ? `No matching viewport evidence was captured for ${check.viewports.join(", ")}.` : "No viewport evidence was captured."
|
|
1483
1498
|
};
|
|
1484
1499
|
}
|
|
1500
|
+
if (isDialogCountCheckType(check.type)) {
|
|
1501
|
+
const field = dialogCountFieldForCheckType(check.type);
|
|
1502
|
+
const expectedCount = check.expected_count ?? 0;
|
|
1503
|
+
const actualCount = numberValue(evidence.dom_summary?.[field]) ?? 0;
|
|
1504
|
+
return {
|
|
1505
|
+
type: check.type,
|
|
1506
|
+
label: checkLabel(check),
|
|
1507
|
+
status: actualCount === expectedCount ? "passed" : "failed",
|
|
1508
|
+
evidence: {
|
|
1509
|
+
field,
|
|
1510
|
+
expected_count: expectedCount,
|
|
1511
|
+
count: actualCount
|
|
1512
|
+
},
|
|
1513
|
+
message: actualCount === expectedCount ? void 0 : `${field} did not equal ${expectedCount}; observed ${actualCount}.`
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1485
1516
|
if (check.type === "route_loaded") {
|
|
1486
1517
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
1487
1518
|
const failed = viewports.filter((viewport) => !successfulRoute({
|
|
@@ -2733,6 +2764,16 @@ function summarizeRouteInventory(viewport, inventory) {
|
|
|
2733
2764
|
function numberValue(value) {
|
|
2734
2765
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
2735
2766
|
}
|
|
2767
|
+
function isDialogCountCheckType(type) {
|
|
2768
|
+
return type === "dialog_count_equals"
|
|
2769
|
+
|| type === "dialog_accept_count_equals"
|
|
2770
|
+
|| type === "dialog_dismiss_count_equals";
|
|
2771
|
+
}
|
|
2772
|
+
function dialogCountFieldForCheckType(type) {
|
|
2773
|
+
if (type === "dialog_accept_count_equals") return "dialog_accept_count";
|
|
2774
|
+
if (type === "dialog_dismiss_count_equals") return "dialog_dismiss_count";
|
|
2775
|
+
return "dialog_count";
|
|
2776
|
+
}
|
|
2736
2777
|
function maxPositiveNumber() {
|
|
2737
2778
|
let max = 0;
|
|
2738
2779
|
for (const value of arguments) {
|
|
@@ -3104,6 +3145,19 @@ function assessProfile(profile, evidence) {
|
|
|
3104
3145
|
});
|
|
3105
3146
|
continue;
|
|
3106
3147
|
}
|
|
3148
|
+
if (isDialogCountCheckType(check.type)) {
|
|
3149
|
+
const field = dialogCountFieldForCheckType(check.type);
|
|
3150
|
+
const expectedCount = check.expected_count == null ? 0 : check.expected_count;
|
|
3151
|
+
const actualCount = numberValue(evidence.dom_summary && evidence.dom_summary[field]) ?? 0;
|
|
3152
|
+
checks.push({
|
|
3153
|
+
type: check.type,
|
|
3154
|
+
label: check.label || check.type,
|
|
3155
|
+
status: actualCount === expectedCount ? "passed" : "failed",
|
|
3156
|
+
evidence: { field, expected_count: expectedCount, count: actualCount },
|
|
3157
|
+
message: actualCount === expectedCount ? undefined : field + " did not equal " + expectedCount + "; observed " + actualCount + ".",
|
|
3158
|
+
});
|
|
3159
|
+
continue;
|
|
3160
|
+
}
|
|
3107
3161
|
if (check.type === "route_loaded") {
|
|
3108
3162
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
3109
3163
|
const failed = checkViewports.filter((viewport) => {
|
package/dist/cli.cjs
CHANGED
|
@@ -6957,6 +6957,9 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
6957
6957
|
"selector_count_equals",
|
|
6958
6958
|
"selector_count_equal",
|
|
6959
6959
|
"selector_count_eq",
|
|
6960
|
+
"dialog_count_equals",
|
|
6961
|
+
"dialog_accept_count_equals",
|
|
6962
|
+
"dialog_dismiss_count_equals",
|
|
6960
6963
|
"selector_text_visible",
|
|
6961
6964
|
"selector_text_absent",
|
|
6962
6965
|
"selector_text_order",
|
|
@@ -7709,6 +7712,14 @@ function validateRegexPatterns(patterns, label) {
|
|
|
7709
7712
|
}
|
|
7710
7713
|
}
|
|
7711
7714
|
}
|
|
7715
|
+
function isDialogCountCheckType(type) {
|
|
7716
|
+
return type === "dialog_count_equals" || type === "dialog_accept_count_equals" || type === "dialog_dismiss_count_equals";
|
|
7717
|
+
}
|
|
7718
|
+
function dialogCountFieldForCheckType(type) {
|
|
7719
|
+
if (type === "dialog_accept_count_equals") return "dialog_accept_count";
|
|
7720
|
+
if (type === "dialog_dismiss_count_equals") return "dialog_dismiss_count";
|
|
7721
|
+
return "dialog_count";
|
|
7722
|
+
}
|
|
7712
7723
|
function normalizeCheck(input, index) {
|
|
7713
7724
|
if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
7714
7725
|
const type = stringValue2(input.type);
|
|
@@ -7716,6 +7727,7 @@ function normalizeCheck(input, index) {
|
|
|
7716
7727
|
if (!isSupportedCheckType(type)) {
|
|
7717
7728
|
throw new Error(`checks[${index}].type ${type} is not supported. Supported checks: ${RIDDLE_PROOF_PROFILE_CHECK_TYPES.join(", ")}`);
|
|
7718
7729
|
}
|
|
7730
|
+
const isDialogCountCheck = isDialogCountCheckType(type);
|
|
7719
7731
|
if ((type === "selector_visible" || type === "selector_absent" || type === "selector_count_at_least" || type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || type === "selector_text_visible" || type === "selector_text_absent") && !stringValue2(input.selector)) {
|
|
7720
7732
|
throw new Error(`checks[${index}] ${type} requires selector.`);
|
|
7721
7733
|
}
|
|
@@ -7747,9 +7759,12 @@ function normalizeCheck(input, index) {
|
|
|
7747
7759
|
throw new Error(`checks[${index}] selector_count_at_least requires min_count.`);
|
|
7748
7760
|
}
|
|
7749
7761
|
const expectedCount = numberValue(input.expected_count) ?? numberValue(input.expectedCount) ?? numberValue(input.count);
|
|
7750
|
-
if ((type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq") && expectedCount === void 0) {
|
|
7762
|
+
if ((type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || isDialogCountCheck) && expectedCount === void 0) {
|
|
7751
7763
|
throw new Error(`checks[${index}] ${type} requires expected_count.`);
|
|
7752
7764
|
}
|
|
7765
|
+
if (isDialogCountCheck && (expectedCount === void 0 || !Number.isInteger(expectedCount) || expectedCount < 0)) {
|
|
7766
|
+
throw new Error(`checks[${index}] ${type} expected_count must be a non-negative integer.`);
|
|
7767
|
+
}
|
|
7753
7768
|
const expectedTexts = normalizeExpectedTexts(input.expected_texts ?? input.expectedTexts, index);
|
|
7754
7769
|
if (type === "selector_text_order") {
|
|
7755
7770
|
if (!stringValue2(input.selector)) throw new Error(`checks[${index}] selector_text_order requires selector.`);
|
|
@@ -8419,6 +8434,22 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
8419
8434
|
message: check.viewports?.length ? `No matching viewport evidence was captured for ${check.viewports.join(", ")}.` : "No viewport evidence was captured."
|
|
8420
8435
|
};
|
|
8421
8436
|
}
|
|
8437
|
+
if (isDialogCountCheckType(check.type)) {
|
|
8438
|
+
const field = dialogCountFieldForCheckType(check.type);
|
|
8439
|
+
const expectedCount = check.expected_count ?? 0;
|
|
8440
|
+
const actualCount = numberValue(evidence.dom_summary?.[field]) ?? 0;
|
|
8441
|
+
return {
|
|
8442
|
+
type: check.type,
|
|
8443
|
+
label: checkLabel(check),
|
|
8444
|
+
status: actualCount === expectedCount ? "passed" : "failed",
|
|
8445
|
+
evidence: {
|
|
8446
|
+
field,
|
|
8447
|
+
expected_count: expectedCount,
|
|
8448
|
+
count: actualCount
|
|
8449
|
+
},
|
|
8450
|
+
message: actualCount === expectedCount ? void 0 : `${field} did not equal ${expectedCount}; observed ${actualCount}.`
|
|
8451
|
+
};
|
|
8452
|
+
}
|
|
8422
8453
|
if (check.type === "route_loaded") {
|
|
8423
8454
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
8424
8455
|
const failed = viewports.filter((viewport) => !successfulRoute({
|
|
@@ -9654,6 +9685,16 @@ function summarizeRouteInventory(viewport, inventory) {
|
|
|
9654
9685
|
function numberValue(value) {
|
|
9655
9686
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
9656
9687
|
}
|
|
9688
|
+
function isDialogCountCheckType(type) {
|
|
9689
|
+
return type === "dialog_count_equals"
|
|
9690
|
+
|| type === "dialog_accept_count_equals"
|
|
9691
|
+
|| type === "dialog_dismiss_count_equals";
|
|
9692
|
+
}
|
|
9693
|
+
function dialogCountFieldForCheckType(type) {
|
|
9694
|
+
if (type === "dialog_accept_count_equals") return "dialog_accept_count";
|
|
9695
|
+
if (type === "dialog_dismiss_count_equals") return "dialog_dismiss_count";
|
|
9696
|
+
return "dialog_count";
|
|
9697
|
+
}
|
|
9657
9698
|
function maxPositiveNumber() {
|
|
9658
9699
|
let max = 0;
|
|
9659
9700
|
for (const value of arguments) {
|
|
@@ -10025,6 +10066,19 @@ function assessProfile(profile, evidence) {
|
|
|
10025
10066
|
});
|
|
10026
10067
|
continue;
|
|
10027
10068
|
}
|
|
10069
|
+
if (isDialogCountCheckType(check.type)) {
|
|
10070
|
+
const field = dialogCountFieldForCheckType(check.type);
|
|
10071
|
+
const expectedCount = check.expected_count == null ? 0 : check.expected_count;
|
|
10072
|
+
const actualCount = numberValue(evidence.dom_summary && evidence.dom_summary[field]) ?? 0;
|
|
10073
|
+
checks.push({
|
|
10074
|
+
type: check.type,
|
|
10075
|
+
label: check.label || check.type,
|
|
10076
|
+
status: actualCount === expectedCount ? "passed" : "failed",
|
|
10077
|
+
evidence: { field, expected_count: expectedCount, count: actualCount },
|
|
10078
|
+
message: actualCount === expectedCount ? undefined : field + " did not equal " + expectedCount + "; observed " + actualCount + ".",
|
|
10079
|
+
});
|
|
10080
|
+
continue;
|
|
10081
|
+
}
|
|
10028
10082
|
if (check.type === "route_loaded") {
|
|
10029
10083
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
10030
10084
|
const failed = checkViewports.filter((viewport) => {
|
package/dist/cli.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -8750,6 +8750,9 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
8750
8750
|
"selector_count_equals",
|
|
8751
8751
|
"selector_count_equal",
|
|
8752
8752
|
"selector_count_eq",
|
|
8753
|
+
"dialog_count_equals",
|
|
8754
|
+
"dialog_accept_count_equals",
|
|
8755
|
+
"dialog_dismiss_count_equals",
|
|
8753
8756
|
"selector_text_visible",
|
|
8754
8757
|
"selector_text_absent",
|
|
8755
8758
|
"selector_text_order",
|
|
@@ -9502,6 +9505,14 @@ function validateRegexPatterns(patterns, label) {
|
|
|
9502
9505
|
}
|
|
9503
9506
|
}
|
|
9504
9507
|
}
|
|
9508
|
+
function isDialogCountCheckType(type) {
|
|
9509
|
+
return type === "dialog_count_equals" || type === "dialog_accept_count_equals" || type === "dialog_dismiss_count_equals";
|
|
9510
|
+
}
|
|
9511
|
+
function dialogCountFieldForCheckType(type) {
|
|
9512
|
+
if (type === "dialog_accept_count_equals") return "dialog_accept_count";
|
|
9513
|
+
if (type === "dialog_dismiss_count_equals") return "dialog_dismiss_count";
|
|
9514
|
+
return "dialog_count";
|
|
9515
|
+
}
|
|
9505
9516
|
function normalizeCheck(input, index) {
|
|
9506
9517
|
if (!isRecord2(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
9507
9518
|
const type = stringValue5(input.type);
|
|
@@ -9509,6 +9520,7 @@ function normalizeCheck(input, index) {
|
|
|
9509
9520
|
if (!isSupportedCheckType(type)) {
|
|
9510
9521
|
throw new Error(`checks[${index}].type ${type} is not supported. Supported checks: ${RIDDLE_PROOF_PROFILE_CHECK_TYPES.join(", ")}`);
|
|
9511
9522
|
}
|
|
9523
|
+
const isDialogCountCheck = isDialogCountCheckType(type);
|
|
9512
9524
|
if ((type === "selector_visible" || type === "selector_absent" || type === "selector_count_at_least" || type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || type === "selector_text_visible" || type === "selector_text_absent") && !stringValue5(input.selector)) {
|
|
9513
9525
|
throw new Error(`checks[${index}] ${type} requires selector.`);
|
|
9514
9526
|
}
|
|
@@ -9540,9 +9552,12 @@ function normalizeCheck(input, index) {
|
|
|
9540
9552
|
throw new Error(`checks[${index}] selector_count_at_least requires min_count.`);
|
|
9541
9553
|
}
|
|
9542
9554
|
const expectedCount = numberValue3(input.expected_count) ?? numberValue3(input.expectedCount) ?? numberValue3(input.count);
|
|
9543
|
-
if ((type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq") && expectedCount === void 0) {
|
|
9555
|
+
if ((type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || isDialogCountCheck) && expectedCount === void 0) {
|
|
9544
9556
|
throw new Error(`checks[${index}] ${type} requires expected_count.`);
|
|
9545
9557
|
}
|
|
9558
|
+
if (isDialogCountCheck && (expectedCount === void 0 || !Number.isInteger(expectedCount) || expectedCount < 0)) {
|
|
9559
|
+
throw new Error(`checks[${index}] ${type} expected_count must be a non-negative integer.`);
|
|
9560
|
+
}
|
|
9546
9561
|
const expectedTexts = normalizeExpectedTexts(input.expected_texts ?? input.expectedTexts, index);
|
|
9547
9562
|
if (type === "selector_text_order") {
|
|
9548
9563
|
if (!stringValue5(input.selector)) throw new Error(`checks[${index}] selector_text_order requires selector.`);
|
|
@@ -10212,6 +10227,22 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
10212
10227
|
message: check.viewports?.length ? `No matching viewport evidence was captured for ${check.viewports.join(", ")}.` : "No viewport evidence was captured."
|
|
10213
10228
|
};
|
|
10214
10229
|
}
|
|
10230
|
+
if (isDialogCountCheckType(check.type)) {
|
|
10231
|
+
const field = dialogCountFieldForCheckType(check.type);
|
|
10232
|
+
const expectedCount = check.expected_count ?? 0;
|
|
10233
|
+
const actualCount = numberValue3(evidence.dom_summary?.[field]) ?? 0;
|
|
10234
|
+
return {
|
|
10235
|
+
type: check.type,
|
|
10236
|
+
label: checkLabel(check),
|
|
10237
|
+
status: actualCount === expectedCount ? "passed" : "failed",
|
|
10238
|
+
evidence: {
|
|
10239
|
+
field,
|
|
10240
|
+
expected_count: expectedCount,
|
|
10241
|
+
count: actualCount
|
|
10242
|
+
},
|
|
10243
|
+
message: actualCount === expectedCount ? void 0 : `${field} did not equal ${expectedCount}; observed ${actualCount}.`
|
|
10244
|
+
};
|
|
10245
|
+
}
|
|
10215
10246
|
if (check.type === "route_loaded") {
|
|
10216
10247
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
10217
10248
|
const failed = viewports.filter((viewport) => !successfulRoute({
|
|
@@ -11463,6 +11494,16 @@ function summarizeRouteInventory(viewport, inventory) {
|
|
|
11463
11494
|
function numberValue(value) {
|
|
11464
11495
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
11465
11496
|
}
|
|
11497
|
+
function isDialogCountCheckType(type) {
|
|
11498
|
+
return type === "dialog_count_equals"
|
|
11499
|
+
|| type === "dialog_accept_count_equals"
|
|
11500
|
+
|| type === "dialog_dismiss_count_equals";
|
|
11501
|
+
}
|
|
11502
|
+
function dialogCountFieldForCheckType(type) {
|
|
11503
|
+
if (type === "dialog_accept_count_equals") return "dialog_accept_count";
|
|
11504
|
+
if (type === "dialog_dismiss_count_equals") return "dialog_dismiss_count";
|
|
11505
|
+
return "dialog_count";
|
|
11506
|
+
}
|
|
11466
11507
|
function maxPositiveNumber() {
|
|
11467
11508
|
let max = 0;
|
|
11468
11509
|
for (const value of arguments) {
|
|
@@ -11834,6 +11875,19 @@ function assessProfile(profile, evidence) {
|
|
|
11834
11875
|
});
|
|
11835
11876
|
continue;
|
|
11836
11877
|
}
|
|
11878
|
+
if (isDialogCountCheckType(check.type)) {
|
|
11879
|
+
const field = dialogCountFieldForCheckType(check.type);
|
|
11880
|
+
const expectedCount = check.expected_count == null ? 0 : check.expected_count;
|
|
11881
|
+
const actualCount = numberValue(evidence.dom_summary && evidence.dom_summary[field]) ?? 0;
|
|
11882
|
+
checks.push({
|
|
11883
|
+
type: check.type,
|
|
11884
|
+
label: check.label || check.type,
|
|
11885
|
+
status: actualCount === expectedCount ? "passed" : "failed",
|
|
11886
|
+
evidence: { field, expected_count: expectedCount, count: actualCount },
|
|
11887
|
+
message: actualCount === expectedCount ? undefined : field + " did not equal " + expectedCount + "; observed " + actualCount + ".",
|
|
11888
|
+
});
|
|
11889
|
+
continue;
|
|
11890
|
+
}
|
|
11837
11891
|
if (check.type === "route_loaded") {
|
|
11838
11892
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
11839
11893
|
const failed = checkViewports.filter((viewport) => {
|
package/dist/index.js
CHANGED
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
resolveRiddleProofProfileTimeoutSec,
|
|
60
60
|
slugifyRiddleProofProfileName,
|
|
61
61
|
summarizeRiddleProofProfileResult
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-QOOPPRYK.js";
|
|
63
63
|
import {
|
|
64
64
|
DEFAULT_RIDDLE_API_BASE_URL,
|
|
65
65
|
DEFAULT_RIDDLE_API_KEY_FILE,
|
package/dist/profile.cjs
CHANGED
|
@@ -64,6 +64,9 @@ var RIDDLE_PROOF_PROFILE_CHECK_TYPES = [
|
|
|
64
64
|
"selector_count_equals",
|
|
65
65
|
"selector_count_equal",
|
|
66
66
|
"selector_count_eq",
|
|
67
|
+
"dialog_count_equals",
|
|
68
|
+
"dialog_accept_count_equals",
|
|
69
|
+
"dialog_dismiss_count_equals",
|
|
67
70
|
"selector_text_visible",
|
|
68
71
|
"selector_text_absent",
|
|
69
72
|
"selector_text_order",
|
|
@@ -816,6 +819,14 @@ function validateRegexPatterns(patterns, label) {
|
|
|
816
819
|
}
|
|
817
820
|
}
|
|
818
821
|
}
|
|
822
|
+
function isDialogCountCheckType(type) {
|
|
823
|
+
return type === "dialog_count_equals" || type === "dialog_accept_count_equals" || type === "dialog_dismiss_count_equals";
|
|
824
|
+
}
|
|
825
|
+
function dialogCountFieldForCheckType(type) {
|
|
826
|
+
if (type === "dialog_accept_count_equals") return "dialog_accept_count";
|
|
827
|
+
if (type === "dialog_dismiss_count_equals") return "dialog_dismiss_count";
|
|
828
|
+
return "dialog_count";
|
|
829
|
+
}
|
|
819
830
|
function normalizeCheck(input, index) {
|
|
820
831
|
if (!isRecord(input)) throw new Error(`checks[${index}] must be an object.`);
|
|
821
832
|
const type = stringValue(input.type);
|
|
@@ -823,6 +834,7 @@ function normalizeCheck(input, index) {
|
|
|
823
834
|
if (!isSupportedCheckType(type)) {
|
|
824
835
|
throw new Error(`checks[${index}].type ${type} is not supported. Supported checks: ${RIDDLE_PROOF_PROFILE_CHECK_TYPES.join(", ")}`);
|
|
825
836
|
}
|
|
837
|
+
const isDialogCountCheck = isDialogCountCheckType(type);
|
|
826
838
|
if ((type === "selector_visible" || type === "selector_absent" || type === "selector_count_at_least" || type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || type === "selector_text_visible" || type === "selector_text_absent") && !stringValue(input.selector)) {
|
|
827
839
|
throw new Error(`checks[${index}] ${type} requires selector.`);
|
|
828
840
|
}
|
|
@@ -854,9 +866,12 @@ function normalizeCheck(input, index) {
|
|
|
854
866
|
throw new Error(`checks[${index}] selector_count_at_least requires min_count.`);
|
|
855
867
|
}
|
|
856
868
|
const expectedCount = numberValue(input.expected_count) ?? numberValue(input.expectedCount) ?? numberValue(input.count);
|
|
857
|
-
if ((type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq") && expectedCount === void 0) {
|
|
869
|
+
if ((type === "selector_count_equals" || type === "selector_count_equal" || type === "selector_count_eq" || isDialogCountCheck) && expectedCount === void 0) {
|
|
858
870
|
throw new Error(`checks[${index}] ${type} requires expected_count.`);
|
|
859
871
|
}
|
|
872
|
+
if (isDialogCountCheck && (expectedCount === void 0 || !Number.isInteger(expectedCount) || expectedCount < 0)) {
|
|
873
|
+
throw new Error(`checks[${index}] ${type} expected_count must be a non-negative integer.`);
|
|
874
|
+
}
|
|
860
875
|
const expectedTexts = normalizeExpectedTexts(input.expected_texts ?? input.expectedTexts, index);
|
|
861
876
|
if (type === "selector_text_order") {
|
|
862
877
|
if (!stringValue(input.selector)) throw new Error(`checks[${index}] selector_text_order requires selector.`);
|
|
@@ -1526,6 +1541,22 @@ function assessCheckFromEvidence(check, evidence) {
|
|
|
1526
1541
|
message: check.viewports?.length ? `No matching viewport evidence was captured for ${check.viewports.join(", ")}.` : "No viewport evidence was captured."
|
|
1527
1542
|
};
|
|
1528
1543
|
}
|
|
1544
|
+
if (isDialogCountCheckType(check.type)) {
|
|
1545
|
+
const field = dialogCountFieldForCheckType(check.type);
|
|
1546
|
+
const expectedCount = check.expected_count ?? 0;
|
|
1547
|
+
const actualCount = numberValue(evidence.dom_summary?.[field]) ?? 0;
|
|
1548
|
+
return {
|
|
1549
|
+
type: check.type,
|
|
1550
|
+
label: checkLabel(check),
|
|
1551
|
+
status: actualCount === expectedCount ? "passed" : "failed",
|
|
1552
|
+
evidence: {
|
|
1553
|
+
field,
|
|
1554
|
+
expected_count: expectedCount,
|
|
1555
|
+
count: actualCount
|
|
1556
|
+
},
|
|
1557
|
+
message: actualCount === expectedCount ? void 0 : `${field} did not equal ${expectedCount}; observed ${actualCount}.`
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1529
1560
|
if (check.type === "route_loaded") {
|
|
1530
1561
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
1531
1562
|
const failed = viewports.filter((viewport) => !successfulRoute({
|
|
@@ -2777,6 +2808,16 @@ function summarizeRouteInventory(viewport, inventory) {
|
|
|
2777
2808
|
function numberValue(value) {
|
|
2778
2809
|
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
2779
2810
|
}
|
|
2811
|
+
function isDialogCountCheckType(type) {
|
|
2812
|
+
return type === "dialog_count_equals"
|
|
2813
|
+
|| type === "dialog_accept_count_equals"
|
|
2814
|
+
|| type === "dialog_dismiss_count_equals";
|
|
2815
|
+
}
|
|
2816
|
+
function dialogCountFieldForCheckType(type) {
|
|
2817
|
+
if (type === "dialog_accept_count_equals") return "dialog_accept_count";
|
|
2818
|
+
if (type === "dialog_dismiss_count_equals") return "dialog_dismiss_count";
|
|
2819
|
+
return "dialog_count";
|
|
2820
|
+
}
|
|
2780
2821
|
function maxPositiveNumber() {
|
|
2781
2822
|
let max = 0;
|
|
2782
2823
|
for (const value of arguments) {
|
|
@@ -3148,6 +3189,19 @@ function assessProfile(profile, evidence) {
|
|
|
3148
3189
|
});
|
|
3149
3190
|
continue;
|
|
3150
3191
|
}
|
|
3192
|
+
if (isDialogCountCheckType(check.type)) {
|
|
3193
|
+
const field = dialogCountFieldForCheckType(check.type);
|
|
3194
|
+
const expectedCount = check.expected_count == null ? 0 : check.expected_count;
|
|
3195
|
+
const actualCount = numberValue(evidence.dom_summary && evidence.dom_summary[field]) ?? 0;
|
|
3196
|
+
checks.push({
|
|
3197
|
+
type: check.type,
|
|
3198
|
+
label: check.label || check.type,
|
|
3199
|
+
status: actualCount === expectedCount ? "passed" : "failed",
|
|
3200
|
+
evidence: { field, expected_count: expectedCount, count: actualCount },
|
|
3201
|
+
message: actualCount === expectedCount ? undefined : field + " did not equal " + expectedCount + "; observed " + actualCount + ".",
|
|
3202
|
+
});
|
|
3203
|
+
continue;
|
|
3204
|
+
}
|
|
3151
3205
|
if (check.type === "route_loaded") {
|
|
3152
3206
|
const expectedPath = check.expected_path || new URL(evidence.target_url).pathname || "/";
|
|
3153
3207
|
const failed = checkViewports.filter((viewport) => {
|
package/dist/profile.d.cts
CHANGED
|
@@ -4,7 +4,7 @@ declare const RIDDLE_PROOF_PROFILE_VERSION: "riddle-proof.profile.v1";
|
|
|
4
4
|
declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evidence.v1";
|
|
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
|
-
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_visible", "selector_text_absent", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
|
|
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", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
|
|
8
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];
|
package/dist/profile.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ declare const RIDDLE_PROOF_PROFILE_VERSION: "riddle-proof.profile.v1";
|
|
|
4
4
|
declare const RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION: "riddle-proof.profile-evidence.v1";
|
|
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
|
-
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_visible", "selector_text_absent", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
|
|
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", "dialog_count_equals", "dialog_accept_count_equals", "dialog_dismiss_count_equals", "selector_text_visible", "selector_text_absent", "selector_text_order", "frame_text_visible", "frame_url_equals", "frame_url_matches", "frame_no_horizontal_overflow", "text_visible", "text_absent", "http_status", "link_status", "artifact_link_status", "route_inventory", "no_horizontal_overflow", "no_mobile_horizontal_overflow", "no_fatal_console_errors", "no_console_warnings"];
|
|
8
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];
|
package/dist/profile.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
resolveRiddleProofProfileTimeoutSec,
|
|
21
21
|
slugifyRiddleProofProfileName,
|
|
22
22
|
summarizeRiddleProofProfileResult
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-QOOPPRYK.js";
|
|
24
24
|
export {
|
|
25
25
|
RIDDLE_PROOF_PROFILE_CHECK_TYPES,
|
|
26
26
|
RIDDLE_PROOF_PROFILE_EVIDENCE_VERSION,
|