@riddledc/riddle-proof-packs 0.2.0
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/LICENSE +21 -0
- package/README.md +107 -0
- package/dist/index.cjs +1131 -0
- package/dist/index.d.cts +62 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.js +1095 -0
- package/package.json +47 -0
- package/packs/auth-smoke/README.md +21 -0
- package/packs/auth-smoke/profile.json +65 -0
- package/packs/canvas-gameplay/README.md +21 -0
- package/packs/canvas-gameplay/profile.json +225 -0
- package/packs/gameplay-window-call-until/README.md +21 -0
- package/packs/gameplay-window-call-until/profile.json +101 -0
- package/packs/handled-recovery-action-malformed-success/README.md +21 -0
- package/packs/handled-recovery-action-malformed-success/profile.json +126 -0
- package/packs/handled-recovery-list-load/README.md +21 -0
- package/packs/handled-recovery-list-load/profile.json +101 -0
- package/packs/mobile-layout-smoke/README.md +21 -0
- package/packs/mobile-layout-smoke/profile.json +64 -0
- package/packs/page-content-basic/README.md +21 -0
- package/packs/page-content-basic/profile.json +29 -0
- package/packs/route-inventory-basic/README.md +21 -0
- package/packs/route-inventory-basic/profile.json +29 -0
- package/packs/spa-route-exit-state-hygiene/README.md +21 -0
- package/packs/spa-route-exit-state-hygiene/profile.json +87 -0
- package/packs/terminal-result-partial-evidence/README.md +21 -0
- package/packs/terminal-result-partial-evidence/profile.json +122 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1095 @@
|
|
|
1
|
+
// src/pack-data.ts
|
|
2
|
+
import { normalizeRiddleProofProfile } from "@riddledc/riddle-proof";
|
|
3
|
+
|
|
4
|
+
// packs/auth-smoke/profile.json
|
|
5
|
+
var profile_default = {
|
|
6
|
+
version: "riddle-proof.profile.v1",
|
|
7
|
+
name: "auth-smoke",
|
|
8
|
+
target: {
|
|
9
|
+
route: "/",
|
|
10
|
+
viewports: [
|
|
11
|
+
{
|
|
12
|
+
name: "mobile",
|
|
13
|
+
width: 390,
|
|
14
|
+
height: 844
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: "desktop",
|
|
18
|
+
width: 1440,
|
|
19
|
+
height: 1e3
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
auth: "none",
|
|
23
|
+
wait_for_selector: "body",
|
|
24
|
+
setup_actions: [
|
|
25
|
+
{
|
|
26
|
+
type: "wait",
|
|
27
|
+
ms: 250
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
checks: [
|
|
32
|
+
{
|
|
33
|
+
type: "selector_visible",
|
|
34
|
+
selector: "body"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: "text_visible",
|
|
38
|
+
text: "Example"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: "no_mobile_horizontal_overflow"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: "no_fatal_console_errors"
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
artifacts: [
|
|
48
|
+
"screenshot",
|
|
49
|
+
"console",
|
|
50
|
+
"dom_summary",
|
|
51
|
+
"proof_json"
|
|
52
|
+
],
|
|
53
|
+
failure_policy: {
|
|
54
|
+
environment_blocked: "neutral",
|
|
55
|
+
proof_insufficient: "review",
|
|
56
|
+
product_regression: "fail"
|
|
57
|
+
},
|
|
58
|
+
metadata: {
|
|
59
|
+
pack_id: "auth_smoke",
|
|
60
|
+
pack_public_name: "Auth Smoke Pack",
|
|
61
|
+
purpose: "Template for baseline page smoke checks where the entry route is publicly reachable.",
|
|
62
|
+
required_receipts: [
|
|
63
|
+
"entry/home route is reachable",
|
|
64
|
+
"visible route baseline content",
|
|
65
|
+
"overflow and console noise are clean",
|
|
66
|
+
"no-console-error baseline"
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// packs/canvas-gameplay/profile.json
|
|
72
|
+
var profile_default2 = {
|
|
73
|
+
version: "riddle-proof.profile.v1",
|
|
74
|
+
name: "canvas-gameplay",
|
|
75
|
+
target: {
|
|
76
|
+
route: "/",
|
|
77
|
+
viewports: [
|
|
78
|
+
{
|
|
79
|
+
name: "mobile",
|
|
80
|
+
width: 390,
|
|
81
|
+
height: 844
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "tablet",
|
|
85
|
+
width: 820,
|
|
86
|
+
height: 1180
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "desktop",
|
|
90
|
+
width: 1440,
|
|
91
|
+
height: 1e3
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
timeout_sec: 300,
|
|
95
|
+
wait_for_selector: "#game-root canvas",
|
|
96
|
+
screenshot_mode: "viewport",
|
|
97
|
+
setup_actions: [
|
|
98
|
+
{
|
|
99
|
+
type: "clear_storage",
|
|
100
|
+
storage: "both",
|
|
101
|
+
reload: true
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
type: "wait_for_selector",
|
|
105
|
+
selector: "#game-root",
|
|
106
|
+
timeout_ms: 2e4
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
type: "wait_for_selector",
|
|
110
|
+
selector: "#game-root canvas",
|
|
111
|
+
timeout_ms: 2e4
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
type: "window_eval",
|
|
115
|
+
label: "install-gameplay-proof-reader",
|
|
116
|
+
timeout_ms: 1e4,
|
|
117
|
+
store_return_to: "__gameplayProof.ready",
|
|
118
|
+
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;",
|
|
119
|
+
return_summary_fields: [
|
|
120
|
+
{
|
|
121
|
+
path: "ready"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
path: "inputAccepted"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
path: "distance"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
path: "score"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
path: "gameOver"
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: "assert_window_value",
|
|
139
|
+
path: "__gameplayProof.ready.ready",
|
|
140
|
+
expected: true,
|
|
141
|
+
timeout_ms: 1e4
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: "canvas_signature",
|
|
145
|
+
selector: "#game-root canvas",
|
|
146
|
+
label: "ready",
|
|
147
|
+
store_signature_to: "__gameplayProof.readyCanvas",
|
|
148
|
+
timeout_ms: 1e4
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
type: "screenshot",
|
|
152
|
+
label: "ready",
|
|
153
|
+
mode: "viewport"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
type: "press",
|
|
157
|
+
key: "Space",
|
|
158
|
+
after_ms: 120
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
type: "press",
|
|
162
|
+
key: "ArrowRight",
|
|
163
|
+
after_ms: 120
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
type: "window_call_until",
|
|
167
|
+
path: "__riddleGameplayStep",
|
|
168
|
+
until_path: "__gameplayProof.running.ok",
|
|
169
|
+
until_expected_value: true,
|
|
170
|
+
max_calls: 36,
|
|
171
|
+
interval_ms: 250,
|
|
172
|
+
timeout_ms: 15e3
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: "window_eval",
|
|
176
|
+
label: "capture-running-proof",
|
|
177
|
+
timeout_ms: 1e4,
|
|
178
|
+
store_return_to: "__gameplayProof.running",
|
|
179
|
+
script: "return window.__riddleGameplayStep?.()||{};",
|
|
180
|
+
return_summary_fields: [
|
|
181
|
+
{
|
|
182
|
+
path: "ok"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
path: "distance"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
path: "score"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
path: "inputAccepted"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
path: "gameOver"
|
|
195
|
+
}
|
|
196
|
+
]
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
type: "assert_window_value",
|
|
200
|
+
path: "__gameplayProof.running.ok",
|
|
201
|
+
expected: true,
|
|
202
|
+
timeout_ms: 1e4
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
type: "assert_window_value",
|
|
206
|
+
path: "__gameplayProof.running.gameOver",
|
|
207
|
+
expected: false,
|
|
208
|
+
timeout_ms: 1e4
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
type: "assert_window_number",
|
|
212
|
+
path: "__gameplayProof.running.distance",
|
|
213
|
+
min_value: 2,
|
|
214
|
+
timeout_ms: 1e4
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
type: "assert_window_number",
|
|
218
|
+
path: "__gameplayProof.running.score",
|
|
219
|
+
min_value: 10,
|
|
220
|
+
timeout_ms: 1e4
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
type: "canvas_signature",
|
|
224
|
+
selector: "#game-root canvas",
|
|
225
|
+
label: "running",
|
|
226
|
+
store_signature_to: "__gameplayProof.runningCanvas",
|
|
227
|
+
timeout_ms: 1e4
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
type: "screenshot",
|
|
231
|
+
label: "running",
|
|
232
|
+
mode: "viewport"
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
},
|
|
236
|
+
checks: [
|
|
237
|
+
{
|
|
238
|
+
type: "route_loaded",
|
|
239
|
+
expected_path: "/games/example"
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
type: "selector_visible",
|
|
243
|
+
selector: "#game-root"
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
type: "selector_visible",
|
|
247
|
+
selector: "#game-root canvas"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
type: "selector_count_equals",
|
|
251
|
+
selector: "#game-root canvas",
|
|
252
|
+
expected_count: 1
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
type: "text_absent",
|
|
256
|
+
pattern: "\\bNaN\\b"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
type: "text_absent",
|
|
260
|
+
pattern: "undefined",
|
|
261
|
+
flags: "i"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
type: "no_horizontal_overflow",
|
|
265
|
+
max_overflow_px: 1
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
type: "no_fatal_console_errors"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
type: "no_console_warnings"
|
|
272
|
+
}
|
|
273
|
+
],
|
|
274
|
+
artifacts: [
|
|
275
|
+
"screenshot",
|
|
276
|
+
"console",
|
|
277
|
+
"dom_summary",
|
|
278
|
+
"proof_json"
|
|
279
|
+
],
|
|
280
|
+
baseline_policy: "invariant_only",
|
|
281
|
+
failure_policy: {
|
|
282
|
+
environment_blocked: "neutral",
|
|
283
|
+
proof_insufficient: "fail",
|
|
284
|
+
product_regression: "fail"
|
|
285
|
+
},
|
|
286
|
+
metadata: {
|
|
287
|
+
purpose: "Template for gameplay routes where gameplay evidence is primarily rendered through canvas.",
|
|
288
|
+
pack_id: "canvas_gameplay",
|
|
289
|
+
pack_public_name: "Canvas Gameplay Pack",
|
|
290
|
+
required_receipts: [
|
|
291
|
+
"canvas mount and signature capture",
|
|
292
|
+
"route loaded on gameplay path",
|
|
293
|
+
"non-fatal browser evidence"
|
|
294
|
+
]
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
// packs/gameplay-window-call-until/profile.json
|
|
299
|
+
var profile_default3 = {
|
|
300
|
+
version: "riddle-proof.profile.v1",
|
|
301
|
+
name: "gameplay-window-call-until",
|
|
302
|
+
target: {
|
|
303
|
+
route: "/games/example",
|
|
304
|
+
viewports: [
|
|
305
|
+
{ name: "mobile", width: 390, height: 844 },
|
|
306
|
+
{ name: "tablet", width: 820, height: 1180 },
|
|
307
|
+
{ name: "desktop", width: 1440, height: 1e3 }
|
|
308
|
+
],
|
|
309
|
+
timeout_sec: 300,
|
|
310
|
+
wait_for_selector: "#game-root canvas",
|
|
311
|
+
screenshot_mode: "viewport",
|
|
312
|
+
setup_actions: [
|
|
313
|
+
{ type: "clear_storage", storage: "both", reload: true },
|
|
314
|
+
{ type: "wait_for_selector", selector: "#game-root", timeout_ms: 2e4 },
|
|
315
|
+
{ type: "wait_for_selector", selector: "#game-root canvas", timeout_ms: 2e4 },
|
|
316
|
+
{
|
|
317
|
+
type: "window_eval",
|
|
318
|
+
label: "install-gameplay-proof-reader",
|
|
319
|
+
timeout_ms: 1e4,
|
|
320
|
+
store_return_to: "__gameplayProof.ready",
|
|
321
|
+
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;",
|
|
322
|
+
return_summary_fields: [
|
|
323
|
+
{ path: "ready" },
|
|
324
|
+
{ path: "inputAccepted" },
|
|
325
|
+
{ path: "distance" },
|
|
326
|
+
{ path: "score" },
|
|
327
|
+
{ path: "gameOver" }
|
|
328
|
+
]
|
|
329
|
+
},
|
|
330
|
+
{ type: "assert_window_value", path: "__gameplayProof.ready.ready", expected: true, timeout_ms: 1e4 },
|
|
331
|
+
{
|
|
332
|
+
type: "canvas_signature",
|
|
333
|
+
selector: "#game-root canvas",
|
|
334
|
+
label: "ready",
|
|
335
|
+
store_signature_to: "__gameplayProof.readyCanvas",
|
|
336
|
+
timeout_ms: 1e4
|
|
337
|
+
},
|
|
338
|
+
{ type: "screenshot", label: "ready", mode: "viewport" },
|
|
339
|
+
{ type: "press", key: "Space", after_ms: 120 },
|
|
340
|
+
{ type: "press", key: "ArrowRight", after_ms: 120 },
|
|
341
|
+
{
|
|
342
|
+
type: "window_call_until",
|
|
343
|
+
path: "__riddleGameplayStep",
|
|
344
|
+
until_path: "__gameplayProof.running.ok",
|
|
345
|
+
until_expected_value: true,
|
|
346
|
+
max_calls: 36,
|
|
347
|
+
interval_ms: 250,
|
|
348
|
+
timeout_ms: 15e3
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
type: "window_eval",
|
|
352
|
+
label: "capture-running-proof",
|
|
353
|
+
timeout_ms: 1e4,
|
|
354
|
+
store_return_to: "__gameplayProof.running",
|
|
355
|
+
script: "return window.__riddleGameplayStep?.()||{};",
|
|
356
|
+
return_summary_fields: [
|
|
357
|
+
{ path: "ok" },
|
|
358
|
+
{ path: "distance" },
|
|
359
|
+
{ path: "score" },
|
|
360
|
+
{ path: "inputAccepted" },
|
|
361
|
+
{ path: "gameOver" }
|
|
362
|
+
]
|
|
363
|
+
},
|
|
364
|
+
{ type: "assert_window_value", path: "__gameplayProof.running.ok", expected: true, timeout_ms: 1e4 },
|
|
365
|
+
{ type: "assert_window_value", path: "__gameplayProof.running.gameOver", expected: false, timeout_ms: 1e4 },
|
|
366
|
+
{ type: "assert_window_number", path: "__gameplayProof.running.distance", min_value: 2, timeout_ms: 1e4 },
|
|
367
|
+
{ type: "assert_window_number", path: "__gameplayProof.running.score", min_value: 10, timeout_ms: 1e4 },
|
|
368
|
+
{
|
|
369
|
+
type: "canvas_signature",
|
|
370
|
+
selector: "#game-root canvas",
|
|
371
|
+
label: "running",
|
|
372
|
+
store_signature_to: "__gameplayProof.runningCanvas",
|
|
373
|
+
timeout_ms: 1e4
|
|
374
|
+
},
|
|
375
|
+
{ type: "screenshot", label: "running", mode: "viewport" }
|
|
376
|
+
]
|
|
377
|
+
},
|
|
378
|
+
checks: [
|
|
379
|
+
{ type: "route_loaded", expected_path: "/games/example" },
|
|
380
|
+
{ type: "selector_visible", selector: "#game-root" },
|
|
381
|
+
{ type: "selector_visible", selector: "#game-root canvas" },
|
|
382
|
+
{ type: "selector_count_equals", selector: "#game-root canvas", expected_count: 1 },
|
|
383
|
+
{ type: "text_absent", pattern: "\\bNaN\\b" },
|
|
384
|
+
{ type: "text_absent", pattern: "undefined", flags: "i" },
|
|
385
|
+
{ type: "no_horizontal_overflow", max_overflow_px: 1 },
|
|
386
|
+
{ type: "no_fatal_console_errors" },
|
|
387
|
+
{ type: "no_console_warnings" }
|
|
388
|
+
],
|
|
389
|
+
artifacts: ["screenshot", "console", "dom_summary", "proof_json"],
|
|
390
|
+
baseline_policy: "invariant_only",
|
|
391
|
+
failure_policy: {
|
|
392
|
+
environment_blocked: "neutral",
|
|
393
|
+
proof_insufficient: "fail",
|
|
394
|
+
product_regression: "fail"
|
|
395
|
+
},
|
|
396
|
+
metadata: {
|
|
397
|
+
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."
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
// packs/handled-recovery-action-malformed-success/profile.json
|
|
402
|
+
var profile_default4 = {
|
|
403
|
+
version: "riddle-proof.profile.v1",
|
|
404
|
+
name: "handled-recovery-action-malformed-success",
|
|
405
|
+
target: {
|
|
406
|
+
route: "/account",
|
|
407
|
+
viewports: [
|
|
408
|
+
{ name: "mobile", width: 390, height: 844 },
|
|
409
|
+
{ name: "tablet", width: 820, height: 1180 },
|
|
410
|
+
{ name: "desktop", width: 1440, height: 1e3 }
|
|
411
|
+
],
|
|
412
|
+
timeout_sec: 300,
|
|
413
|
+
wait_ms: 800,
|
|
414
|
+
network_mocks: [
|
|
415
|
+
{
|
|
416
|
+
label: "account-summary",
|
|
417
|
+
url: "**/api/account/summary",
|
|
418
|
+
method: "GET",
|
|
419
|
+
status: 200,
|
|
420
|
+
content_type: "application/json",
|
|
421
|
+
required_hit_count: 3,
|
|
422
|
+
json: {
|
|
423
|
+
available_time: "4h 0m",
|
|
424
|
+
active_jobs: 2
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
label: "recent-jobs",
|
|
429
|
+
url: "**/api/jobs?limit=10",
|
|
430
|
+
method: "GET",
|
|
431
|
+
status: 200,
|
|
432
|
+
content_type: "application/json",
|
|
433
|
+
required_hit_count: 3,
|
|
434
|
+
json: {
|
|
435
|
+
jobs: [
|
|
436
|
+
{
|
|
437
|
+
id: "job_action_template_survives",
|
|
438
|
+
status: "completed"
|
|
439
|
+
}
|
|
440
|
+
]
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
label: "existing-api-keys",
|
|
445
|
+
url: "**/api/api-keys",
|
|
446
|
+
method: "GET",
|
|
447
|
+
status: 200,
|
|
448
|
+
content_type: "application/json",
|
|
449
|
+
required_hit_count: 3,
|
|
450
|
+
json: {
|
|
451
|
+
keys: [
|
|
452
|
+
{
|
|
453
|
+
id: "key_action_template_existing",
|
|
454
|
+
name: "Existing action template key",
|
|
455
|
+
last4: "0001",
|
|
456
|
+
status: "active"
|
|
457
|
+
}
|
|
458
|
+
]
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
label: "create-api-key-malformed-success",
|
|
463
|
+
url: "**/api/api-keys",
|
|
464
|
+
method: "POST",
|
|
465
|
+
status: 200,
|
|
466
|
+
content_type: "application/json",
|
|
467
|
+
required_hit_count: 3,
|
|
468
|
+
max_hit_count: 3,
|
|
469
|
+
capture_request_body: true,
|
|
470
|
+
request_body_contains: ["Action template malformed success key"],
|
|
471
|
+
body: "{not valid create success json"
|
|
472
|
+
}
|
|
473
|
+
],
|
|
474
|
+
setup_actions: [
|
|
475
|
+
{ type: "clear_storage", storage: "both", reload: true },
|
|
476
|
+
{ type: "wait_for_selector", selector: "[data-testid='account-page']", timeout_ms: 3e4 },
|
|
477
|
+
{ type: "wait_for_text", selector: "body", text: "4h 0m", timeout_ms: 3e4 },
|
|
478
|
+
{ type: "wait_for_text", selector: "body", text: "job_action_template_survives", timeout_ms: 3e4 },
|
|
479
|
+
{ type: "wait_for_text", selector: "body", text: "Existing action template key", timeout_ms: 3e4 },
|
|
480
|
+
{ type: "fill", selector: "[data-testid='new-key-name']", value: "Action template malformed success key" },
|
|
481
|
+
{ type: "clear_console" },
|
|
482
|
+
{ type: "screenshot", label: "before-malformed-success-action" },
|
|
483
|
+
{ type: "click", selector: "[data-testid='create-key-button']", text: "Create API key" },
|
|
484
|
+
{ type: "wait_for_text", selector: "body", text: "Failed to create API key", timeout_ms: 3e4 },
|
|
485
|
+
{ type: "assert_text_visible", selector: "body", text: "Existing action template key", timeout_ms: 5e3 },
|
|
486
|
+
{ type: "assert_text_visible", selector: "body", text: "Active", timeout_ms: 5e3 },
|
|
487
|
+
{ type: "assert_text_absent", selector: "body", text: "API Key Created!", timeout_ms: 1e3 },
|
|
488
|
+
{ type: "assert_text_absent", selector: "body", text: "Expected property name", timeout_ms: 1e3 },
|
|
489
|
+
{ type: "assert_text_absent", selector: "body", text: "SyntaxError", timeout_ms: 1e3 },
|
|
490
|
+
{ type: "assert_text_absent", selector: "body", text: "[object Object]", timeout_ms: 1e3 },
|
|
491
|
+
{ type: "screenshot", label: "malformed-success-action-visible-recovery" }
|
|
492
|
+
]
|
|
493
|
+
},
|
|
494
|
+
checks: [
|
|
495
|
+
{ type: "route_loaded", expected_path: "/account" },
|
|
496
|
+
{ type: "selector_visible", selector: "[data-testid='account-page']" },
|
|
497
|
+
{ type: "selector_visible", selector: "[data-testid='api-key-create-error']" },
|
|
498
|
+
{ type: "text_visible", text: "4h 0m" },
|
|
499
|
+
{ type: "text_visible", text: "2 active" },
|
|
500
|
+
{ type: "text_visible", text: "job_action_template_survives" },
|
|
501
|
+
{ type: "text_visible", text: "Existing action template key" },
|
|
502
|
+
{ type: "text_visible", text: "Failed to create API key" },
|
|
503
|
+
{ type: "text_visible", text: "Active" },
|
|
504
|
+
{ type: "text_absent", text: "API Key Created!" },
|
|
505
|
+
{ type: "text_absent", text: "Expected property name" },
|
|
506
|
+
{ type: "text_absent", text: "SyntaxError" },
|
|
507
|
+
{ type: "text_absent", text: "[object Object]" },
|
|
508
|
+
{ type: "text_absent", text: "Application error" },
|
|
509
|
+
{ type: "selector_count_equals", selector: "[data-testid='api-key-create-error']", expected_count: 1 },
|
|
510
|
+
{ type: "selector_count_equals", selector: "[data-testid='recent-job-row']", expected_count: 1 },
|
|
511
|
+
{ type: "selector_count_equals", selector: "[data-testid='api-key-row']", expected_count: 1 },
|
|
512
|
+
{ type: "selector_count_equals", selector: "[data-testid='created-key-modal']", expected_count: 0 },
|
|
513
|
+
{ type: "no_horizontal_overflow", max_overflow_px: 1 },
|
|
514
|
+
{ type: "no_fatal_console_errors" },
|
|
515
|
+
{ type: "no_console_warnings" }
|
|
516
|
+
],
|
|
517
|
+
artifacts: ["screenshot", "console", "dom_summary", "proof_json"],
|
|
518
|
+
baseline_policy: "invariant_only",
|
|
519
|
+
failure_policy: {
|
|
520
|
+
environment_blocked: "neutral",
|
|
521
|
+
proof_insufficient: "fail",
|
|
522
|
+
product_regression: "fail"
|
|
523
|
+
},
|
|
524
|
+
metadata: {
|
|
525
|
+
purpose: "Template for handled malformed action-success recovery: prove surrounding state still renders, the failed action shows one recovery message, success UI and raw parser text stay absent, the action request body is captured, and browser console evidence remains clean."
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
|
|
529
|
+
// packs/handled-recovery-list-load/profile.json
|
|
530
|
+
var profile_default5 = {
|
|
531
|
+
version: "riddle-proof.profile.v1",
|
|
532
|
+
name: "handled-recovery-list-load",
|
|
533
|
+
target: {
|
|
534
|
+
route: "/account",
|
|
535
|
+
viewports: [
|
|
536
|
+
{ name: "mobile", width: 390, height: 844 },
|
|
537
|
+
{ name: "tablet", width: 820, height: 1180 },
|
|
538
|
+
{ name: "desktop", width: 1440, height: 1e3 }
|
|
539
|
+
],
|
|
540
|
+
timeout_sec: 300,
|
|
541
|
+
wait_ms: 800,
|
|
542
|
+
network_mocks: [
|
|
543
|
+
{
|
|
544
|
+
label: "account-summary",
|
|
545
|
+
url: "**/api/account/summary",
|
|
546
|
+
method: "GET",
|
|
547
|
+
status: 200,
|
|
548
|
+
content_type: "application/json",
|
|
549
|
+
required_hit_count: 3,
|
|
550
|
+
json: {
|
|
551
|
+
available_time: "4h 0m",
|
|
552
|
+
active_jobs: 2
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
label: "recent-jobs",
|
|
557
|
+
url: "**/api/jobs?limit=10",
|
|
558
|
+
method: "GET",
|
|
559
|
+
status: 200,
|
|
560
|
+
content_type: "application/json",
|
|
561
|
+
required_hit_count: 3,
|
|
562
|
+
json: {
|
|
563
|
+
jobs: [
|
|
564
|
+
{
|
|
565
|
+
id: "job_recovery_template_survives",
|
|
566
|
+
status: "completed"
|
|
567
|
+
}
|
|
568
|
+
]
|
|
569
|
+
}
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
label: "saved-items-unavailable-load",
|
|
573
|
+
url: "**/api/saved-items",
|
|
574
|
+
method: "GET",
|
|
575
|
+
status: 503,
|
|
576
|
+
content_type: "application/json",
|
|
577
|
+
required_hit_count: 3,
|
|
578
|
+
json: {
|
|
579
|
+
error: "Synthetic saved items unavailable"
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
],
|
|
583
|
+
setup_actions: [
|
|
584
|
+
{ type: "clear_storage", storage: "both", reload: true },
|
|
585
|
+
{ type: "wait_for_selector", selector: "[data-testid='account-page']", timeout_ms: 3e4 },
|
|
586
|
+
{ type: "wait_for_text", selector: "body", text: "4h 0m", timeout_ms: 3e4 },
|
|
587
|
+
{ type: "wait_for_text", selector: "body", text: "job_recovery_template_survives", timeout_ms: 3e4 },
|
|
588
|
+
{ type: "wait_for_text", selector: "body", text: "Failed to load saved items", timeout_ms: 3e4 },
|
|
589
|
+
{ type: "screenshot", label: "saved-items-malformed-load-visible-recovery" },
|
|
590
|
+
{ type: "assert_text_absent", selector: "body", text: "No saved items yet", timeout_ms: 1e3 },
|
|
591
|
+
{ type: "assert_text_absent", selector: "body", text: "Synthetic saved items unavailable", timeout_ms: 1e3 },
|
|
592
|
+
{ type: "assert_text_absent", selector: "body", text: "saved_items_temporarily_unavailable", timeout_ms: 1e3 },
|
|
593
|
+
{ type: "assert_text_absent", selector: "body", text: "Expected property name", timeout_ms: 1e3 },
|
|
594
|
+
{ type: "assert_text_absent", selector: "body", text: "SyntaxError", timeout_ms: 1e3 },
|
|
595
|
+
{ type: "assert_text_absent", selector: "body", text: "[object Object]", timeout_ms: 1e3 }
|
|
596
|
+
]
|
|
597
|
+
},
|
|
598
|
+
checks: [
|
|
599
|
+
{ type: "route_loaded", expected_path: "/account" },
|
|
600
|
+
{ type: "selector_visible", selector: "[data-testid='account-page']" },
|
|
601
|
+
{ type: "selector_visible", selector: "[data-testid='saved-items-error']" },
|
|
602
|
+
{ type: "text_visible", text: "4h 0m" },
|
|
603
|
+
{ type: "text_visible", text: "2 active" },
|
|
604
|
+
{ type: "text_visible", text: "job_recovery_template_survives" },
|
|
605
|
+
{ type: "text_visible", text: "Failed to load saved items" },
|
|
606
|
+
{ type: "text_absent", text: "No saved items yet" },
|
|
607
|
+
{ type: "text_absent", text: "Synthetic saved items unavailable" },
|
|
608
|
+
{ type: "text_absent", text: "saved_items_temporarily_unavailable" },
|
|
609
|
+
{ type: "text_absent", text: "Expected property name" },
|
|
610
|
+
{ type: "text_absent", text: "SyntaxError" },
|
|
611
|
+
{ type: "text_absent", text: "[object Object]" },
|
|
612
|
+
{ type: "text_absent", text: "Application error" },
|
|
613
|
+
{ type: "selector_count_equals", selector: "[data-testid='saved-items-error']", expected_count: 1 },
|
|
614
|
+
{ type: "selector_count_equals", selector: "[data-testid='recent-job-row']", expected_count: 1 },
|
|
615
|
+
{ type: "selector_count_equals", selector: "[data-testid='saved-item-row']", expected_count: 0 },
|
|
616
|
+
{ type: "no_horizontal_overflow", max_overflow_px: 1 },
|
|
617
|
+
{ type: "no_fatal_console_errors" },
|
|
618
|
+
{ type: "no_console_warnings" }
|
|
619
|
+
],
|
|
620
|
+
artifacts: ["screenshot", "console", "dom_summary", "proof_json"],
|
|
621
|
+
baseline_policy: "invariant_only",
|
|
622
|
+
failure_policy: {
|
|
623
|
+
environment_blocked: "neutral",
|
|
624
|
+
proof_insufficient: "fail",
|
|
625
|
+
product_regression: "fail"
|
|
626
|
+
},
|
|
627
|
+
metadata: {
|
|
628
|
+
purpose: "Template for handled list-load recovery: prove independent page data still renders, the failed list shows one recovery message, contradictory empty-state copy, raw backend text, parser text, and object leakage stay absent, and browser console evidence remains clean. Do not add max_hit_count to idempotent GET mocks unless exact call count is the product contract."
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
// packs/mobile-layout-smoke/profile.json
|
|
633
|
+
var profile_default6 = {
|
|
634
|
+
version: "riddle-proof.profile.v1",
|
|
635
|
+
name: "mobile-layout-smoke",
|
|
636
|
+
target: {
|
|
637
|
+
route: "/",
|
|
638
|
+
viewports: [
|
|
639
|
+
{
|
|
640
|
+
name: "mobile",
|
|
641
|
+
width: 390,
|
|
642
|
+
height: 844
|
|
643
|
+
}
|
|
644
|
+
],
|
|
645
|
+
auth: "none",
|
|
646
|
+
wait_for_selector: "body",
|
|
647
|
+
setup_actions: [
|
|
648
|
+
{
|
|
649
|
+
type: "wait",
|
|
650
|
+
ms: 250
|
|
651
|
+
}
|
|
652
|
+
]
|
|
653
|
+
},
|
|
654
|
+
checks: [
|
|
655
|
+
{
|
|
656
|
+
type: "route_loaded",
|
|
657
|
+
expected_path: "/"
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
type: "selector_visible",
|
|
661
|
+
selector: "body"
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
type: "text_visible",
|
|
665
|
+
text: "Example"
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
type: "no_mobile_horizontal_overflow"
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
type: "no_fatal_console_errors"
|
|
672
|
+
}
|
|
673
|
+
],
|
|
674
|
+
artifacts: [
|
|
675
|
+
"screenshot",
|
|
676
|
+
"console",
|
|
677
|
+
"dom_summary",
|
|
678
|
+
"proof_json"
|
|
679
|
+
],
|
|
680
|
+
failure_policy: {
|
|
681
|
+
environment_blocked: "neutral",
|
|
682
|
+
proof_insufficient: "fail",
|
|
683
|
+
product_regression: "fail"
|
|
684
|
+
},
|
|
685
|
+
metadata: {
|
|
686
|
+
pack_id: "layout_mobile",
|
|
687
|
+
pack_public_name: "Mobile Layout Pack",
|
|
688
|
+
purpose: "Template for high-signal mobile layout smoke checks.",
|
|
689
|
+
required_receipts: [
|
|
690
|
+
"primary visible root on mobile viewport",
|
|
691
|
+
"no horizontal overflow",
|
|
692
|
+
"critical copy presence",
|
|
693
|
+
"clean browser console"
|
|
694
|
+
]
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
// packs/page-content-basic/profile.json
|
|
699
|
+
var profile_default7 = {
|
|
700
|
+
version: "riddle-proof.profile.v1",
|
|
701
|
+
name: "page-content-basic",
|
|
702
|
+
target: {
|
|
703
|
+
route: "/",
|
|
704
|
+
viewports: [
|
|
705
|
+
{ name: "mobile", width: 390, height: 844 },
|
|
706
|
+
{ name: "desktop", width: 1440, height: 1e3 }
|
|
707
|
+
],
|
|
708
|
+
auth: "none",
|
|
709
|
+
wait_for_selector: "body",
|
|
710
|
+
setup_actions: [
|
|
711
|
+
{ type: "wait", ms: 250 }
|
|
712
|
+
]
|
|
713
|
+
},
|
|
714
|
+
checks: [
|
|
715
|
+
{ type: "route_loaded", expected_path: "/" },
|
|
716
|
+
{ type: "selector_visible", selector: "body" },
|
|
717
|
+
{ type: "text_visible", text: "Example" },
|
|
718
|
+
{ type: "no_mobile_horizontal_overflow" },
|
|
719
|
+
{ type: "no_fatal_console_errors" }
|
|
720
|
+
],
|
|
721
|
+
artifacts: ["screenshot", "console", "dom_summary", "proof_json"],
|
|
722
|
+
failure_policy: {
|
|
723
|
+
environment_blocked: "neutral",
|
|
724
|
+
proof_insufficient: "fail",
|
|
725
|
+
product_regression: "fail"
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
// packs/route-inventory-basic/profile.json
|
|
730
|
+
var profile_default8 = {
|
|
731
|
+
version: "riddle-proof.profile.v1",
|
|
732
|
+
name: "route-inventory-basic",
|
|
733
|
+
target: {
|
|
734
|
+
route: "/",
|
|
735
|
+
viewports: [
|
|
736
|
+
{ name: "desktop", width: 1280, height: 900 },
|
|
737
|
+
{ name: "mobile", width: 390, height: 844 }
|
|
738
|
+
],
|
|
739
|
+
wait_for_selector: "[data-testid='route-list']",
|
|
740
|
+
timeout_sec: 180
|
|
741
|
+
},
|
|
742
|
+
checks: [
|
|
743
|
+
{
|
|
744
|
+
type: "route_inventory",
|
|
745
|
+
expected_routes: [
|
|
746
|
+
{ name: "Example Route", path: "/example" }
|
|
747
|
+
],
|
|
748
|
+
link_selector: "a[href='/example']",
|
|
749
|
+
source_selector: "[data-testid='route-list']",
|
|
750
|
+
route_path_prefix: "/example",
|
|
751
|
+
timeout_ms: 3e4
|
|
752
|
+
},
|
|
753
|
+
{ type: "no_mobile_horizontal_overflow", max_overflow_px: 1 },
|
|
754
|
+
{ type: "no_fatal_console_errors" }
|
|
755
|
+
],
|
|
756
|
+
artifacts: ["screenshot", "console", "dom_summary", "proof_json"],
|
|
757
|
+
baseline_policy: "invariant_only"
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
// packs/spa-route-exit-state-hygiene/profile.json
|
|
761
|
+
var profile_default9 = {
|
|
762
|
+
version: "riddle-proof.profile.v1",
|
|
763
|
+
name: "spa-route-exit-state-hygiene",
|
|
764
|
+
target: {
|
|
765
|
+
route: "/games/example?proof=1",
|
|
766
|
+
viewports: [
|
|
767
|
+
{ name: "phone", width: 390, height: 844 },
|
|
768
|
+
{ name: "ipad-mini", width: 768, height: 1024 },
|
|
769
|
+
{ name: "ipad", width: 820, height: 1180 },
|
|
770
|
+
{ name: "desktop", width: 1440, height: 1e3 }
|
|
771
|
+
],
|
|
772
|
+
timeout_sec: 300,
|
|
773
|
+
wait_for_selector: "#game-root",
|
|
774
|
+
screenshot_mode: "viewport",
|
|
775
|
+
setup_actions: [
|
|
776
|
+
{ type: "clear_storage", storage: "both", reload: true },
|
|
777
|
+
{ type: "wait_for_selector", selector: "#game-root", timeout_ms: 2e4 },
|
|
778
|
+
{ type: "wait_for_selector", selector: "#game-root canvas, #game-root [data-proof-ready='true']", timeout_ms: 2e4 },
|
|
779
|
+
{
|
|
780
|
+
type: "window_eval",
|
|
781
|
+
label: "capture-route-active-state",
|
|
782
|
+
timeout_ms: 1e4,
|
|
783
|
+
store_return_to: "__rpRouteExit.active",
|
|
784
|
+
script: "const proof=window.__exampleRouteProof?.read?.()||{};const watched=['__exampleRouteProof','__exampleProofLastReceipt','exampleTouchState'];const activeGlobals=watched.filter((name)=>window[name]!==undefined);const out={ready:proof.ready===true,route:location.pathname,activeGlobals,activeGlobalCount:activeGlobals.length,receiptId:String(proof.receiptId||''),mode:String(proof.mode||'')};out.ok=out.ready===true&&out.activeGlobalCount>0;window.__rpRouteExit={...(window.__rpRouteExit||{}),active:out};return out;",
|
|
785
|
+
return_summary_fields: [
|
|
786
|
+
{ path: "ok" },
|
|
787
|
+
{ path: "ready" },
|
|
788
|
+
{ path: "route" },
|
|
789
|
+
{ path: "activeGlobalCount" },
|
|
790
|
+
{ path: "activeGlobals" }
|
|
791
|
+
]
|
|
792
|
+
},
|
|
793
|
+
{ type: "assert_window_value", path: "__rpRouteExit.active.ok", expected_value: true, timeout_ms: 1e4 },
|
|
794
|
+
{ type: "screenshot", label: "route-active-state", mode: "viewport" },
|
|
795
|
+
{ type: "click", selector: "[data-testid='nav-home'], .nav-logo, a[href='/']", timeout_ms: 1e4 },
|
|
796
|
+
{ type: "wait_for_selector", selector: "[data-testid='home-page'], main, [data-route='home']", timeout_ms: 2e4 },
|
|
797
|
+
{
|
|
798
|
+
type: "window_eval",
|
|
799
|
+
label: "capture-route-exit-cleanup",
|
|
800
|
+
timeout_ms: 1e4,
|
|
801
|
+
store_return_to: "__rpRouteExit.cleanup",
|
|
802
|
+
script: "const watched=['__exampleRouteProof','__exampleProofLastReceipt','exampleTouchState'];const staleNames=watched.filter((name)=>window[name]!==undefined);const out={ok:location.pathname==='/'&&staleNames.length===0,route:location.pathname,staleNames,staleCount:staleNames.length};window.__rpRouteExit={...(window.__rpRouteExit||{}),cleanup:out};return out;",
|
|
803
|
+
return_summary_fields: [
|
|
804
|
+
{ path: "ok" },
|
|
805
|
+
{ path: "route" },
|
|
806
|
+
{ path: "staleCount" },
|
|
807
|
+
{ path: "staleNames" }
|
|
808
|
+
]
|
|
809
|
+
},
|
|
810
|
+
{ type: "assert_window_value", path: "__rpRouteExit.cleanup.ok", expected_value: true, timeout_ms: 1e4 },
|
|
811
|
+
{ type: "assert_window_number", path: "__rpRouteExit.cleanup.staleCount", expected_value: 0, timeout_ms: 1e4 },
|
|
812
|
+
{ type: "screenshot", label: "home-after-route-exit-cleanup", mode: "viewport" }
|
|
813
|
+
]
|
|
814
|
+
},
|
|
815
|
+
checks: [
|
|
816
|
+
{ type: "route_loaded", expected_path: "/" },
|
|
817
|
+
{ type: "selector_visible", selector: "[data-testid='home-page'], main, [data-route='home']" },
|
|
818
|
+
{ type: "text_absent", pattern: "\\bNaN\\b" },
|
|
819
|
+
{ type: "text_absent", pattern: "undefined", flags: "i" },
|
|
820
|
+
{ type: "text_absent", pattern: "\\[object Object\\]" },
|
|
821
|
+
{ type: "no_horizontal_overflow", max_overflow_px: 1 },
|
|
822
|
+
{ type: "no_mobile_horizontal_overflow", max_overflow_px: 1 },
|
|
823
|
+
{ type: "no_fatal_console_errors" },
|
|
824
|
+
{ type: "no_console_warnings" }
|
|
825
|
+
],
|
|
826
|
+
artifacts: ["screenshot", "console", "dom_summary", "proof_json"],
|
|
827
|
+
baseline_policy: "invariant_only",
|
|
828
|
+
failure_policy: {
|
|
829
|
+
environment_blocked: "neutral",
|
|
830
|
+
proof_insufficient: "fail",
|
|
831
|
+
product_regression: "fail"
|
|
832
|
+
},
|
|
833
|
+
metadata: {
|
|
834
|
+
pack_id: "state_hygiene",
|
|
835
|
+
pack_public_name: "State Hygiene Pack",
|
|
836
|
+
required_receipts: [
|
|
837
|
+
"active route-local proof helpers and route state receipt",
|
|
838
|
+
"route-exit affordance inventory before cleanup",
|
|
839
|
+
"route or mode exit action receipt through visible UI",
|
|
840
|
+
"post-cleanup stale-state inventory after route cleanup",
|
|
841
|
+
"screenshots at active and post-cleanup boundaries",
|
|
842
|
+
"console and warning accounting",
|
|
843
|
+
"proof JSON and artifact links"
|
|
844
|
+
],
|
|
845
|
+
purpose: "Template for SPA route-exit hygiene profiles. Replace the example route, selectors, and watched globals with route-local proof helpers, receipts, timers, input state, or touch state that must exist while the feature route is active and must be removed after visible UI navigation returns home."
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
// packs/terminal-result-partial-evidence/profile.json
|
|
850
|
+
var profile_default10 = {
|
|
851
|
+
version: "riddle-proof.profile.v1",
|
|
852
|
+
name: "terminal-result-partial-evidence",
|
|
853
|
+
target: {
|
|
854
|
+
route: "/playground",
|
|
855
|
+
viewports: [
|
|
856
|
+
{ name: "mobile", width: 390, height: 844 },
|
|
857
|
+
{ name: "tablet", width: 820, height: 1180 },
|
|
858
|
+
{ name: "desktop", width: 1440, height: 1e3 }
|
|
859
|
+
],
|
|
860
|
+
timeout_sec: 300,
|
|
861
|
+
wait_ms: 800,
|
|
862
|
+
network_mocks: [
|
|
863
|
+
{
|
|
864
|
+
label: "api-console-sync-terminal-error-with-partial-evidence",
|
|
865
|
+
url: "**/v1/run",
|
|
866
|
+
method: "POST",
|
|
867
|
+
status: 200,
|
|
868
|
+
content_type: "application/json",
|
|
869
|
+
required_hit_count: 3,
|
|
870
|
+
max_hit_count: 3,
|
|
871
|
+
capture_request_body: true,
|
|
872
|
+
request_body_contains: [
|
|
873
|
+
'"sync":true',
|
|
874
|
+
'"include":["screenshots","console","har"]',
|
|
875
|
+
"terminal-result-template-screenshot"
|
|
876
|
+
],
|
|
877
|
+
json: {
|
|
878
|
+
status: "completed_error",
|
|
879
|
+
success: false,
|
|
880
|
+
job_id: "job_terminal_result_template",
|
|
881
|
+
error: {
|
|
882
|
+
message: "Synthetic terminal result template failed after collecting partial evidence"
|
|
883
|
+
},
|
|
884
|
+
screenshots: [
|
|
885
|
+
{
|
|
886
|
+
name: "terminal-result-template-screenshot",
|
|
887
|
+
url: "https://cdn.example.invalid/terminal-result-template-screenshot.png"
|
|
888
|
+
}
|
|
889
|
+
],
|
|
890
|
+
console: [
|
|
891
|
+
{
|
|
892
|
+
type: "log",
|
|
893
|
+
text: "terminal result template collected console evidence"
|
|
894
|
+
}
|
|
895
|
+
],
|
|
896
|
+
har: {
|
|
897
|
+
log: {
|
|
898
|
+
entries: [
|
|
899
|
+
{
|
|
900
|
+
request: {
|
|
901
|
+
method: "GET",
|
|
902
|
+
url: "https://example.com/terminal-result-template-resource"
|
|
903
|
+
},
|
|
904
|
+
response: {
|
|
905
|
+
status: 500
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
]
|
|
909
|
+
}
|
|
910
|
+
},
|
|
911
|
+
billing: {
|
|
912
|
+
actual_seconds: 30,
|
|
913
|
+
cost_usd: 4e-3
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
],
|
|
918
|
+
setup_actions: [
|
|
919
|
+
{ type: "clear_storage", storage: "both", reload: true },
|
|
920
|
+
{ type: "wait_for_selector", selector: "[data-testid='api-console-page']", timeout_ms: 3e4 },
|
|
921
|
+
{ type: "fill", selector: "[data-testid='api-console-json']", value: '{ "steps": [{ "screenshot": "terminal-result-template-screenshot" }], "sync": true, "include": ["screenshots", "console", "har"] }' },
|
|
922
|
+
{ type: "clear_console" },
|
|
923
|
+
{ type: "screenshot", label: "terminal-result-before-submit" },
|
|
924
|
+
{ type: "click", selector: "[data-testid='run-api-console']", text: "Run" },
|
|
925
|
+
{ type: "wait_for_text", selector: "body", text: "Synthetic terminal result template failed after collecting partial evidence", timeout_ms: 3e4 },
|
|
926
|
+
{ type: "wait_for_text", selector: "body", text: "partial results available", timeout_ms: 3e4 },
|
|
927
|
+
{ type: "assert_text_visible", selector: "body", text: "terminal-result-template-screenshot", timeout_ms: 5e3 },
|
|
928
|
+
{ type: "assert_text_visible", selector: "body", text: "terminal result template collected console evidence", timeout_ms: 5e3 },
|
|
929
|
+
{ type: "assert_text_visible", selector: "body", text: "terminal-result-template-resource", timeout_ms: 5e3 },
|
|
930
|
+
{ type: "assert_text_absent", selector: "body", text: "Success", timeout_ms: 1e3 },
|
|
931
|
+
{ type: "assert_text_absent", selector: "body", text: "No screenshots captured", timeout_ms: 1e3 },
|
|
932
|
+
{ type: "assert_text_absent", selector: "body", text: "No console output captured", timeout_ms: 1e3 },
|
|
933
|
+
{ type: "assert_text_absent", selector: "body", text: "No network requests captured", timeout_ms: 1e3 },
|
|
934
|
+
{ type: "screenshot", label: "terminal-result-partial-evidence-expanded" }
|
|
935
|
+
]
|
|
936
|
+
},
|
|
937
|
+
checks: [
|
|
938
|
+
{ type: "route_loaded", expected_path: "/playground" },
|
|
939
|
+
{ type: "selector_visible", selector: "[data-testid='api-console-page']" },
|
|
940
|
+
{ type: "text_visible", text: "Error" },
|
|
941
|
+
{ type: "text_visible", text: "Synthetic terminal result template failed after collecting partial evidence" },
|
|
942
|
+
{ type: "text_visible", text: "partial results available" },
|
|
943
|
+
{ type: "selector_text_visible", selector: "[data-testid='api-console-screenshots']", text: "terminal-result-template-screenshot" },
|
|
944
|
+
{ type: "selector_text_visible", selector: "[data-testid='api-console-output']", text: "terminal result template collected console evidence" },
|
|
945
|
+
{ type: "selector_text_visible", selector: "[data-testid='api-console-har']", text: "terminal-result-template-resource" },
|
|
946
|
+
{ type: "text_absent", text: "Success" },
|
|
947
|
+
{ type: "text_absent", text: "No screenshots captured" },
|
|
948
|
+
{ type: "text_absent", text: "No console output captured" },
|
|
949
|
+
{ type: "text_absent", text: "No network requests captured" },
|
|
950
|
+
{ type: "text_absent", text: "Application error" },
|
|
951
|
+
{ type: "selector_count_equals", selector: "[data-testid='api-console-error-indicator']", expected_count: 1 },
|
|
952
|
+
{ type: "selector_count_equals", selector: "[data-testid='api-console-timeout-indicator']", expected_count: 0 },
|
|
953
|
+
{ type: "selector_count_equals", selector: "[data-testid='api-console-success-indicator']", expected_count: 0 },
|
|
954
|
+
{ type: "selector_count_equals", selector: "[data-testid='api-console-screenshot-item']", expected_count: 1 },
|
|
955
|
+
{ type: "selector_count_at_least", selector: "[data-testid='api-console-output']", min_count: 1 },
|
|
956
|
+
{ type: "selector_count_at_least", selector: "[data-testid='api-console-har']", min_count: 1 },
|
|
957
|
+
{ type: "no_horizontal_overflow", max_overflow_px: 1 },
|
|
958
|
+
{ type: "no_fatal_console_errors" },
|
|
959
|
+
{ type: "no_console_warnings" }
|
|
960
|
+
],
|
|
961
|
+
artifacts: ["screenshot", "console", "dom_summary", "proof_json"],
|
|
962
|
+
baseline_policy: "invariant_only",
|
|
963
|
+
failure_policy: {
|
|
964
|
+
environment_blocked: "neutral",
|
|
965
|
+
proof_insufficient: "fail",
|
|
966
|
+
product_regression: "fail"
|
|
967
|
+
},
|
|
968
|
+
metadata: {
|
|
969
|
+
purpose: "Template for API-console terminal result honesty: return a terminal error or timeout JSON response with partial screenshot, console, and HAR evidence; require visible status honesty, partial-results copy, each artifact class, correct success/error/timeout selector polarity, no contradictory empty-evidence copy, and clean browser evidence. For timeout variants, change the mocked status and visible status checks to the product's timeout indicator while preserving the same partial-evidence contract."
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
|
|
973
|
+
// src/pack-data.ts
|
|
974
|
+
function isRecord(value) {
|
|
975
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
976
|
+
}
|
|
977
|
+
function safeString(value) {
|
|
978
|
+
return typeof value === "string" ? value : void 0;
|
|
979
|
+
}
|
|
980
|
+
function safeStringArray(value) {
|
|
981
|
+
if (!Array.isArray(value)) return [];
|
|
982
|
+
const values = value.filter((item) => typeof item === "string").map((item) => item.trim());
|
|
983
|
+
return values.filter((item) => item.length > 0);
|
|
984
|
+
}
|
|
985
|
+
function toPackMetadata(profile) {
|
|
986
|
+
const metadata = isRecord(profile.metadata) ? profile.metadata : {};
|
|
987
|
+
return {
|
|
988
|
+
packId: safeString(metadata.pack_id),
|
|
989
|
+
packPublicName: safeString(metadata.pack_public_name),
|
|
990
|
+
requiredReceipts: safeStringArray(metadata.required_receipts),
|
|
991
|
+
purpose: safeString(metadata.purpose)
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
var rawProfiles = {
|
|
995
|
+
"page-content-basic": profile_default7,
|
|
996
|
+
"route-inventory-basic": profile_default8,
|
|
997
|
+
"mobile-layout-smoke": profile_default6,
|
|
998
|
+
"spa-route-exit-state-hygiene": profile_default9,
|
|
999
|
+
"handled-recovery-list-load": profile_default5,
|
|
1000
|
+
"handled-recovery-action-malformed-success": profile_default4,
|
|
1001
|
+
"terminal-result-partial-evidence": profile_default10,
|
|
1002
|
+
"gameplay-window-call-until": profile_default3,
|
|
1003
|
+
"canvas-gameplay": profile_default2,
|
|
1004
|
+
"auth-smoke": profile_default
|
|
1005
|
+
};
|
|
1006
|
+
var RIDDLE_PROOF_PACK_PROFILES = Object.freeze(
|
|
1007
|
+
Object.fromEntries(
|
|
1008
|
+
Object.entries(rawProfiles).map(([slug, raw]) => {
|
|
1009
|
+
const profile = normalizeRiddleProofProfile(raw);
|
|
1010
|
+
const normalizedSlug = profile.name || slug;
|
|
1011
|
+
return [normalizedSlug, profile];
|
|
1012
|
+
})
|
|
1013
|
+
)
|
|
1014
|
+
);
|
|
1015
|
+
var RIDDLE_PROOF_PACK_MANIFEST = Object.freeze(
|
|
1016
|
+
Object.entries(rawProfiles).map(([slug, raw]) => {
|
|
1017
|
+
const profile = normalizeRiddleProofProfile(raw);
|
|
1018
|
+
const metadata = toPackMetadata(profile);
|
|
1019
|
+
return Object.freeze({
|
|
1020
|
+
name: profile.name,
|
|
1021
|
+
profile,
|
|
1022
|
+
slug,
|
|
1023
|
+
sourcePath: `packs/${slug}/profile.json`,
|
|
1024
|
+
...metadata
|
|
1025
|
+
});
|
|
1026
|
+
})
|
|
1027
|
+
);
|
|
1028
|
+
|
|
1029
|
+
// src/listPacks.ts
|
|
1030
|
+
function listRiddleProofPackProfiles() {
|
|
1031
|
+
return RIDDLE_PROOF_PACK_MANIFEST;
|
|
1032
|
+
}
|
|
1033
|
+
function listRiddleProofPacks() {
|
|
1034
|
+
return RIDDLE_PROOF_PACK_MANIFEST;
|
|
1035
|
+
}
|
|
1036
|
+
function getRiddleProofPackProfileByPackId(packId) {
|
|
1037
|
+
const normalized = packId.trim().toLowerCase();
|
|
1038
|
+
return RIDDLE_PROOF_PACK_MANIFEST.find(
|
|
1039
|
+
(entry) => normalized.length > 0 && entry.packId?.toLowerCase() === normalized
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
1042
|
+
function getPackEnabledRiddleProofPackProfiles() {
|
|
1043
|
+
return RIDDLE_PROOF_PACK_MANIFEST.filter((entry) => Boolean(entry.packId));
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// src/resolvePack.ts
|
|
1047
|
+
function getRiddleProofPackProfileManifest(name) {
|
|
1048
|
+
const normalized = name.trim().toLowerCase();
|
|
1049
|
+
if (!normalized) return void 0;
|
|
1050
|
+
return RIDDLE_PROOF_PACK_MANIFEST.find(
|
|
1051
|
+
(entry) => entry.name.toLowerCase() === normalized || entry.slug === normalized
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
1054
|
+
function getRiddleProofPackProfile(name) {
|
|
1055
|
+
return RIDDLE_PROOF_PACK_PROFILES[name];
|
|
1056
|
+
}
|
|
1057
|
+
function getRiddleProofProfilesByPackId(packId) {
|
|
1058
|
+
const normalized = packId.trim().toLowerCase();
|
|
1059
|
+
return RIDDLE_PROOF_PACK_MANIFEST.filter(
|
|
1060
|
+
(entry) => normalized.length > 0 && entry.packId?.toLowerCase() === normalized
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
// src/instantiateProfile.ts
|
|
1065
|
+
import { normalizeRiddleProofProfile as normalizeRiddleProofProfile2 } from "@riddledc/riddle-proof";
|
|
1066
|
+
function instantiateRiddleProofProfile(profileName, options = {}) {
|
|
1067
|
+
const manifest = getRiddleProofPackProfileManifest(profileName);
|
|
1068
|
+
if (!manifest) throw new Error(`Unknown proof pack profile: ${profileName}`);
|
|
1069
|
+
const targetOverride = {
|
|
1070
|
+
...manifest.profile.target,
|
|
1071
|
+
...options.target || {},
|
|
1072
|
+
url: options.url ?? manifest.profile.target.url,
|
|
1073
|
+
route: options.route ?? manifest.profile.target.route
|
|
1074
|
+
};
|
|
1075
|
+
return normalizeRiddleProofProfile2(
|
|
1076
|
+
{ ...manifest.profile, target: targetOverride },
|
|
1077
|
+
{
|
|
1078
|
+
url: targetOverride.url,
|
|
1079
|
+
route: targetOverride.route,
|
|
1080
|
+
viewports: targetOverride.viewports
|
|
1081
|
+
}
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
export {
|
|
1085
|
+
RIDDLE_PROOF_PACK_MANIFEST,
|
|
1086
|
+
RIDDLE_PROOF_PACK_PROFILES,
|
|
1087
|
+
getPackEnabledRiddleProofPackProfiles,
|
|
1088
|
+
getRiddleProofPackProfile,
|
|
1089
|
+
getRiddleProofPackProfileByPackId,
|
|
1090
|
+
getRiddleProofPackProfileManifest,
|
|
1091
|
+
getRiddleProofProfilesByPackId,
|
|
1092
|
+
instantiateRiddleProofProfile,
|
|
1093
|
+
listRiddleProofPackProfiles,
|
|
1094
|
+
listRiddleProofPacks
|
|
1095
|
+
};
|