@riddledc/riddle-proof 0.7.177 → 0.7.179
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 -0
- package/dist/cli.cjs +13 -0
- package/dist/cli.js +13 -0
- package/examples/profiles/gameplay-window-call-until.json +101 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -240,6 +240,7 @@ The package includes generic starter profiles:
|
|
|
240
240
|
- `examples/profiles/handled-recovery-list-load.json` for failed or malformed list-load recovery profiles.
|
|
241
241
|
- `examples/profiles/handled-recovery-action-malformed-success.json` for action recovery profiles where the request succeeds at HTTP level but returns an unusable body.
|
|
242
242
|
- `examples/profiles/terminal-result-partial-evidence.json` for API-console terminal error or timeout receipts that preserve partial screenshot, console, and HAR evidence.
|
|
243
|
+
- `examples/profiles/gameplay-window-call-until.json` for gameplay profiles that wait on a runtime state contract instead of a fixed sleep.
|
|
243
244
|
|
|
244
245
|
Copy one of those shapes into a repository profile directory and replace the
|
|
245
246
|
routes, selectors, mock URLs, and text checks with app-specific invariants.
|
|
@@ -487,6 +488,10 @@ progressive state until a window-state receipt is true. It accepts `path` plus
|
|
|
487
488
|
optional `args`, `until_path`, `until_expected_value`, `max_calls` from 1 to
|
|
488
489
|
100, and optional `interval_ms`; the action stops early when the predicate is
|
|
489
490
|
met and records `call_count`, final `returned`, and final `until_value`.
|
|
491
|
+
For gameplay progression, prefer this to a fixed `wait` when frame cadence or
|
|
492
|
+
hosted-runner timing can vary by viewport; install a small `window` helper that
|
|
493
|
+
returns JSON-safe state, stores the latest receipt, and makes the pass condition
|
|
494
|
+
explicit. See `examples/profiles/gameplay-window-call-until.json`.
|
|
490
495
|
Use `screenshot` with an optional `label` to capture durable Riddle screenshots
|
|
491
496
|
at important setup milestones, such as after a route switch, terminal state, or
|
|
492
497
|
reset. These labels are recorded in setup evidence and included in profile
|
package/dist/cli.cjs
CHANGED
|
@@ -16646,6 +16646,19 @@ function profileSetupSummaryMarkdown(result) {
|
|
|
16646
16646
|
return receipts.map((receipt) => ({ name, receipt }));
|
|
16647
16647
|
});
|
|
16648
16648
|
const pressDetails = pressGroups.flat();
|
|
16649
|
+
for (const group of pressGroups.slice(0, 8)) {
|
|
16650
|
+
if (!group.length) continue;
|
|
16651
|
+
const name = group[0].name;
|
|
16652
|
+
const keys = group.map(({ receipt }) => cliString(receipt.key) || "key").filter(Boolean);
|
|
16653
|
+
const ordinals = group.map(({ receipt }) => cliFiniteNumber(receipt.ordinal)).filter((value) => value !== void 0);
|
|
16654
|
+
const visibleKeys = keys.slice(0, 16);
|
|
16655
|
+
const omittedKeyCount = Math.max(0, keys.length - visibleKeys.length);
|
|
16656
|
+
const visibleOrdinals = ordinals.slice(0, 16);
|
|
16657
|
+
const omittedOrdinalCount = Math.max(0, ordinals.length - visibleOrdinals.length);
|
|
16658
|
+
const keyText = visibleKeys.join(",");
|
|
16659
|
+
const ordinalText = visibleOrdinals.join(",");
|
|
16660
|
+
lines.push(`- ${name} press_sequence: keys ${markdownInlineCode(keyText, 200)}${omittedKeyCount ? ` (+${omittedKeyCount} omitted)` : ""}${ordinalText ? `, ordinals ${markdownInlineCode(ordinalText, 120)}${omittedOrdinalCount ? ` (+${omittedOrdinalCount} omitted)` : ""}` : ""}`);
|
|
16661
|
+
}
|
|
16649
16662
|
const sampledPressDetails = balancedSetupReceiptDetails(pressGroups, 12);
|
|
16650
16663
|
for (const { name, receipt } of sampledPressDetails) {
|
|
16651
16664
|
const key = cliString(receipt.key) || "key";
|
package/dist/cli.js
CHANGED
|
@@ -929,6 +929,19 @@ function profileSetupSummaryMarkdown(result) {
|
|
|
929
929
|
return receipts.map((receipt) => ({ name, receipt }));
|
|
930
930
|
});
|
|
931
931
|
const pressDetails = pressGroups.flat();
|
|
932
|
+
for (const group of pressGroups.slice(0, 8)) {
|
|
933
|
+
if (!group.length) continue;
|
|
934
|
+
const name = group[0].name;
|
|
935
|
+
const keys = group.map(({ receipt }) => cliString(receipt.key) || "key").filter(Boolean);
|
|
936
|
+
const ordinals = group.map(({ receipt }) => cliFiniteNumber(receipt.ordinal)).filter((value) => value !== void 0);
|
|
937
|
+
const visibleKeys = keys.slice(0, 16);
|
|
938
|
+
const omittedKeyCount = Math.max(0, keys.length - visibleKeys.length);
|
|
939
|
+
const visibleOrdinals = ordinals.slice(0, 16);
|
|
940
|
+
const omittedOrdinalCount = Math.max(0, ordinals.length - visibleOrdinals.length);
|
|
941
|
+
const keyText = visibleKeys.join(",");
|
|
942
|
+
const ordinalText = visibleOrdinals.join(",");
|
|
943
|
+
lines.push(`- ${name} press_sequence: keys ${markdownInlineCode(keyText, 200)}${omittedKeyCount ? ` (+${omittedKeyCount} omitted)` : ""}${ordinalText ? `, ordinals ${markdownInlineCode(ordinalText, 120)}${omittedOrdinalCount ? ` (+${omittedOrdinalCount} omitted)` : ""}` : ""}`);
|
|
944
|
+
}
|
|
932
945
|
const sampledPressDetails = balancedSetupReceiptDetails(pressGroups, 12);
|
|
933
946
|
for (const { name, receipt } of sampledPressDetails) {
|
|
934
947
|
const key = cliString(receipt.key) || "key";
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "riddle-proof.profile.v1",
|
|
3
|
+
"name": "gameplay-window-call-until",
|
|
4
|
+
"target": {
|
|
5
|
+
"route": "/games/example",
|
|
6
|
+
"viewports": [
|
|
7
|
+
{ "name": "mobile", "width": 390, "height": 844 },
|
|
8
|
+
{ "name": "tablet", "width": 820, "height": 1180 },
|
|
9
|
+
{ "name": "desktop", "width": 1440, "height": 1000 }
|
|
10
|
+
],
|
|
11
|
+
"timeout_sec": 300,
|
|
12
|
+
"wait_for_selector": "#game-root canvas",
|
|
13
|
+
"screenshot_mode": "viewport",
|
|
14
|
+
"setup_actions": [
|
|
15
|
+
{ "type": "clear_storage", "storage": "both", "reload": true },
|
|
16
|
+
{ "type": "wait_for_selector", "selector": "#game-root", "timeout_ms": 20000 },
|
|
17
|
+
{ "type": "wait_for_selector", "selector": "#game-root canvas", "timeout_ms": 20000 },
|
|
18
|
+
{
|
|
19
|
+
"type": "window_eval",
|
|
20
|
+
"label": "install-gameplay-proof-reader",
|
|
21
|
+
"timeout_ms": 10000,
|
|
22
|
+
"store_return_to": "__gameplayProof.ready",
|
|
23
|
+
"script": "window.__riddleGameplayStep=()=>{const api=window.__exampleGameProof;const state=api?.step?.()||api?.read?.()||{};const out={ready:state.ready===true,inputAccepted:state.inputAccepted===true,gameOver:state.gameOver===true,distance:Number(state.distance||0),score:Number(state.score||0),level:Number(state.level||0)};out.ok=out.ready&&out.inputAccepted&&out.gameOver===false&&out.distance>=2&&out.score>=10;window.__gameplayProof={...(window.__gameplayProof||{}),running:out};return out;};const api=window.__exampleGameProof;const initial=api?.read?.()||{};const out={ready:initial.ready===true,inputAccepted:initial.inputAccepted===true,gameOver:initial.gameOver===true,distance:Number(initial.distance||0),score:Number(initial.score||0),level:Number(initial.level||0)};window.__gameplayProof={...(window.__gameplayProof||{}),ready:out};return out;",
|
|
24
|
+
"return_summary_fields": [
|
|
25
|
+
{ "path": "ready" },
|
|
26
|
+
{ "path": "inputAccepted" },
|
|
27
|
+
{ "path": "distance" },
|
|
28
|
+
{ "path": "score" },
|
|
29
|
+
{ "path": "gameOver" }
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{ "type": "assert_window_value", "path": "__gameplayProof.ready.ready", "expected": true, "timeout_ms": 10000 },
|
|
33
|
+
{
|
|
34
|
+
"type": "canvas_signature",
|
|
35
|
+
"selector": "#game-root canvas",
|
|
36
|
+
"label": "ready",
|
|
37
|
+
"store_signature_to": "__gameplayProof.readyCanvas",
|
|
38
|
+
"timeout_ms": 10000
|
|
39
|
+
},
|
|
40
|
+
{ "type": "screenshot", "label": "ready", "mode": "viewport" },
|
|
41
|
+
{ "type": "press", "key": "Space", "after_ms": 120 },
|
|
42
|
+
{ "type": "press", "key": "ArrowRight", "after_ms": 120 },
|
|
43
|
+
{
|
|
44
|
+
"type": "window_call_until",
|
|
45
|
+
"path": "__riddleGameplayStep",
|
|
46
|
+
"until_path": "__gameplayProof.running.ok",
|
|
47
|
+
"until_expected_value": true,
|
|
48
|
+
"max_calls": 36,
|
|
49
|
+
"interval_ms": 250,
|
|
50
|
+
"timeout_ms": 15000
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"type": "window_eval",
|
|
54
|
+
"label": "capture-running-proof",
|
|
55
|
+
"timeout_ms": 10000,
|
|
56
|
+
"store_return_to": "__gameplayProof.running",
|
|
57
|
+
"script": "return window.__riddleGameplayStep?.()||{};",
|
|
58
|
+
"return_summary_fields": [
|
|
59
|
+
{ "path": "ok" },
|
|
60
|
+
{ "path": "distance" },
|
|
61
|
+
{ "path": "score" },
|
|
62
|
+
{ "path": "inputAccepted" },
|
|
63
|
+
{ "path": "gameOver" }
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
{ "type": "assert_window_value", "path": "__gameplayProof.running.ok", "expected": true, "timeout_ms": 10000 },
|
|
67
|
+
{ "type": "assert_window_value", "path": "__gameplayProof.running.gameOver", "expected": false, "timeout_ms": 10000 },
|
|
68
|
+
{ "type": "assert_window_number", "path": "__gameplayProof.running.distance", "min_value": 2, "timeout_ms": 10000 },
|
|
69
|
+
{ "type": "assert_window_number", "path": "__gameplayProof.running.score", "min_value": 10, "timeout_ms": 10000 },
|
|
70
|
+
{
|
|
71
|
+
"type": "canvas_signature",
|
|
72
|
+
"selector": "#game-root canvas",
|
|
73
|
+
"label": "running",
|
|
74
|
+
"store_signature_to": "__gameplayProof.runningCanvas",
|
|
75
|
+
"timeout_ms": 10000
|
|
76
|
+
},
|
|
77
|
+
{ "type": "screenshot", "label": "running", "mode": "viewport" }
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
"checks": [
|
|
81
|
+
{ "type": "route_loaded", "expected_path": "/games/example" },
|
|
82
|
+
{ "type": "selector_visible", "selector": "#game-root" },
|
|
83
|
+
{ "type": "selector_visible", "selector": "#game-root canvas" },
|
|
84
|
+
{ "type": "selector_count_equals", "selector": "#game-root canvas", "expected_count": 1 },
|
|
85
|
+
{ "type": "text_absent", "pattern": "\\bNaN\\b" },
|
|
86
|
+
{ "type": "text_absent", "pattern": "undefined", "flags": "i" },
|
|
87
|
+
{ "type": "no_horizontal_overflow", "max_overflow_px": 1 },
|
|
88
|
+
{ "type": "no_fatal_console_errors" },
|
|
89
|
+
{ "type": "no_console_warnings" }
|
|
90
|
+
],
|
|
91
|
+
"artifacts": ["screenshot", "console", "dom_summary", "proof_json"],
|
|
92
|
+
"baseline_policy": "invariant_only",
|
|
93
|
+
"failure_policy": {
|
|
94
|
+
"environment_blocked": "neutral",
|
|
95
|
+
"proof_insufficient": "fail",
|
|
96
|
+
"product_regression": "fail"
|
|
97
|
+
},
|
|
98
|
+
"metadata": {
|
|
99
|
+
"purpose": "Template for gameplay profiles where a route exposes window.__exampleGameProof.read() and optionally step(). Use window_call_until to wait for runtime state such as accepted input, distance, score, or level completion instead of relying on fixed sleeps that vary across hosted browser frame cadence."
|
|
100
|
+
}
|
|
101
|
+
}
|