@crvouga/atlas 1.2.0 → 1.4.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/reports/src/evidence-detail.d.ts +37 -3
  3. package/dist/reports/src/evidence-detail.js +52 -20
  4. package/dist/reports/src/evidence-scope.d.ts +83 -0
  5. package/dist/reports/src/evidence-scope.js +129 -0
  6. package/dist/reports/src/evidence-types.d.ts +3 -1
  7. package/dist/reports/src/explorer-types.d.ts +1 -1
  8. package/dist/reports/src/export-evidence.js +1 -1
  9. package/dist/reports/src/layer-merge.js +3 -2
  10. package/dist/reports/src/layer-types.d.ts +1 -1
  11. package/dist/reports/src/layers-route.d.ts +2 -1
  12. package/dist/reports/src/layers-route.js +8 -4
  13. package/dist/reports/src/publish-checks.js +1 -0
  14. package/dist/reports/src/reporter.d.ts +1 -1
  15. package/dist/reports/src/reports-explorer-route.d.ts +276 -0
  16. package/dist/reports/src/reports-route.d.ts +276 -0
  17. package/dist/reports/src/test-catalog.d.ts +34 -1
  18. package/dist/reports/src/test-catalog.js +23 -5
  19. package/dist/schema/src/api.d.ts +542 -0
  20. package/dist/schema/src/api.js +17 -5
  21. package/dist/schema/src/layer.d.ts +981 -0
  22. package/dist/schema/src/layer.js +43 -4
  23. package/dist/server/src/openapi.js +3 -2
  24. package/docs/extending.md +1 -0
  25. package/docs/reference/http-api.md +6 -4
  26. package/docs/reference/reports.md +243 -14
  27. package/docs/reference/schema.md +23 -0
  28. package/docs/rich-evidence.md +70 -0
  29. package/docs/ui.md +1 -1
  30. package/llms-full.txt +78 -5
  31. package/package.json +1 -1
  32. package/packages/schema/schemas/check-detail.schema.json +697 -1
  33. package/packages/schema/schemas/effective-delta.schema.json +192 -0
  34. package/packages/schema/schemas/effective-evidence.schema.json +192 -0
  35. package/packages/schema/schemas/evidence-page.schema.json +96 -0
  36. package/packages/schema/schemas/layer-rows.schema.json +96 -0
  37. package/packages/schema/schemas/layer.schema.json +1598 -62
  38. package/packages/schema/schemas/publish-checks.schema.json +768 -0
  39. package/packages/schema/schemas/report-run.schema.json +181 -0
  40. package/packages/schema/schemas/report-runs.schema.json +6 -0
  41. package/packages/schema/schemas/test-catalog.schema.json +128 -0
  42. package/packages/schema/schemas/test-history.schema.json +202 -0
  43. package/packages/server/openapi.json +2721 -48
  44. package/packages/visualizer/src/evidence/artifacts.tsx +77 -29
  45. package/packages/visualizer/src/evidence/evidence-scope.tsx +106 -0
  46. package/packages/visualizer/src/evidence/format.ts +11 -0
  47. package/packages/visualizer/src/explorer/Explorer.tsx +28 -5
  48. package/packages/visualizer/src/explorer/RunArtifacts.tsx +246 -0
  49. package/packages/visualizer/src/explorer/RunsView.tsx +40 -9
  50. package/packages/visualizer/src/explorer/search.ts +10 -3
@@ -171,6 +171,12 @@
171
171
  ],
172
172
  "additionalProperties": {}
173
173
  },
174
+ "attachments": {
175
+ "description": "Files attached to the run itself, in its layers, not to a check. Absent when there are none",
176
+ "type": "integer",
177
+ "exclusiveMinimum": 0,
178
+ "maximum": 9007199254740991
179
+ },
174
180
  "artifactTags": {
175
181
  "description": "The normalized tags of the attachments of its results, sorted and distinct. Absent when none is tagged, and in reports of older servers",
176
182
  "type": "array",
@@ -309,6 +315,102 @@
309
315
  "available": {
310
316
  "type": "boolean",
311
317
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
318
+ },
319
+ "scope": {
320
+ "description": "What this recording shows as its producer declared it: its own `scope`, else its attempt's, check's, part's or layer's. Absent: the scope is unknown, never live, physical or audible",
321
+ "type": "object",
322
+ "properties": {
323
+ "surface": {
324
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
325
+ "type": "string",
326
+ "minLength": 1
327
+ },
328
+ "deviceKind": {
329
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
330
+ "type": "string",
331
+ "minLength": 1
332
+ },
333
+ "syntheticData": {
334
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
335
+ "type": "boolean"
336
+ },
337
+ "dependencies": {
338
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
339
+ "type": "string",
340
+ "minLength": 1
341
+ },
342
+ "audioCaptured": {
343
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
344
+ "type": "boolean"
345
+ },
346
+ "pacing": {
347
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
348
+ "type": "string",
349
+ "minLength": 1
350
+ },
351
+ "asserted": {
352
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
353
+ "type": "array",
354
+ "items": {
355
+ "type": "string"
356
+ }
357
+ },
358
+ "limitations": {
359
+ "description": "Known limits of what this evidence shows, in the producer's words",
360
+ "type": "array",
361
+ "items": {
362
+ "type": "string"
363
+ }
364
+ },
365
+ "declaredBy": {
366
+ "description": "Who or what made this declaration: a tool, a team, a person",
367
+ "type": "string"
368
+ },
369
+ "verified": {
370
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
371
+ "type": "array",
372
+ "items": {
373
+ "type": "string"
374
+ }
375
+ },
376
+ "verifiedBy": {
377
+ "description": "What checked the `verified` fields",
378
+ "type": "string"
379
+ },
380
+ "provenance": {
381
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
382
+ "type": "array",
383
+ "items": {
384
+ "type": "object",
385
+ "properties": {
386
+ "url": {
387
+ "type": "string",
388
+ "minLength": 1
389
+ },
390
+ "name": {
391
+ "type": "string"
392
+ },
393
+ "rel": {
394
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
395
+ "type": "string"
396
+ }
397
+ },
398
+ "required": [
399
+ "url"
400
+ ],
401
+ "additionalProperties": {}
402
+ }
403
+ },
404
+ "extensions": {
405
+ "type": "object",
406
+ "propertyNames": {
407
+ "type": "string",
408
+ "minLength": 1
409
+ },
410
+ "additionalProperties": {}
411
+ }
412
+ },
413
+ "additionalProperties": {}
312
414
  }
313
415
  },
314
416
  "required": [
@@ -335,6 +437,85 @@
335
437
  ],
336
438
  "additionalProperties": {}
337
439
  }
440
+ },
441
+ "layers": {
442
+ "description": "Every layer of the run, oldest first. Absent from an older server",
443
+ "type": "array",
444
+ "items": {
445
+ "type": "object",
446
+ "properties": {
447
+ "id": {
448
+ "type": "string",
449
+ "description": "The layer id; read its files with `/api/reports/evidence/detail/{backend}/{id}`"
450
+ },
451
+ "backend": {
452
+ "type": "string"
453
+ },
454
+ "producer": {
455
+ "type": "string"
456
+ },
457
+ "environment": {
458
+ "type": [
459
+ "string",
460
+ "null"
461
+ ]
462
+ },
463
+ "recordedAtMs": {
464
+ "type": "number"
465
+ },
466
+ "checks": {
467
+ "type": "integer",
468
+ "minimum": 0,
469
+ "maximum": 9007199254740991,
470
+ "description": "How many checks the layer recorded. Zero means evidence only, not a pass"
471
+ },
472
+ "attachments": {
473
+ "type": "integer",
474
+ "minimum": 0,
475
+ "maximum": 9007199254740991,
476
+ "description": "Files the layer carries as a whole, not those of its checks"
477
+ },
478
+ "videos": {
479
+ "type": "object",
480
+ "properties": {
481
+ "references": {
482
+ "type": "integer",
483
+ "minimum": 0,
484
+ "maximum": 9007199254740991,
485
+ "description": "Every reference to a video; identical bytes referenced twice count twice"
486
+ },
487
+ "recordings": {
488
+ "type": "integer",
489
+ "minimum": 0,
490
+ "maximum": 9007199254740991,
491
+ "description": "Distinct playable recordings"
492
+ },
493
+ "unavailable": {
494
+ "type": "integer",
495
+ "minimum": 0,
496
+ "maximum": 9007199254740991,
497
+ "description": "References that name no bytes"
498
+ }
499
+ },
500
+ "required": [
501
+ "references",
502
+ "recordings",
503
+ "unavailable"
504
+ ],
505
+ "additionalProperties": {}
506
+ }
507
+ },
508
+ "required": [
509
+ "id",
510
+ "backend",
511
+ "producer",
512
+ "environment",
513
+ "recordedAtMs",
514
+ "checks",
515
+ "attachments"
516
+ ],
517
+ "additionalProperties": {}
518
+ }
338
519
  }
339
520
  },
340
521
  "required": [
@@ -179,6 +179,12 @@
179
179
  ],
180
180
  "additionalProperties": {}
181
181
  },
182
+ "attachments": {
183
+ "description": "Files attached to the run itself, in its layers, not to a check. Absent when there are none",
184
+ "type": "integer",
185
+ "exclusiveMinimum": 0,
186
+ "maximum": 9007199254740991
187
+ },
182
188
  "artifactTags": {
183
189
  "description": "The normalized tags of the attachments of its results, sorted and distinct. Absent when none is tagged, and in reports of older servers",
184
190
  "type": "array",
@@ -611,6 +611,28 @@
611
611
  "additionalProperties": {}
612
612
  }
613
613
  },
614
+ "scopes": {
615
+ "description": "Scope tokens of recordings (`device:simulator`, `unknown`) with the number of tests that have a recording stating each",
616
+ "type": "array",
617
+ "items": {
618
+ "type": "object",
619
+ "properties": {
620
+ "value": {
621
+ "type": "string"
622
+ },
623
+ "count": {
624
+ "type": "integer",
625
+ "minimum": 0,
626
+ "maximum": 9007199254740991
627
+ }
628
+ },
629
+ "required": [
630
+ "value",
631
+ "count"
632
+ ],
633
+ "additionalProperties": {}
634
+ }
635
+ },
614
636
  "branches": {
615
637
  "type": "array",
616
638
  "items": {
@@ -937,6 +959,102 @@
937
959
  "available": {
938
960
  "type": "boolean",
939
961
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
962
+ },
963
+ "scope": {
964
+ "description": "What this recording shows as its producer declared it: its own `scope`, else its attempt's, check's, part's or layer's. Absent: the scope is unknown, never live, physical or audible",
965
+ "type": "object",
966
+ "properties": {
967
+ "surface": {
968
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
969
+ "type": "string",
970
+ "minLength": 1
971
+ },
972
+ "deviceKind": {
973
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
974
+ "type": "string",
975
+ "minLength": 1
976
+ },
977
+ "syntheticData": {
978
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
979
+ "type": "boolean"
980
+ },
981
+ "dependencies": {
982
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
983
+ "type": "string",
984
+ "minLength": 1
985
+ },
986
+ "audioCaptured": {
987
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
988
+ "type": "boolean"
989
+ },
990
+ "pacing": {
991
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
992
+ "type": "string",
993
+ "minLength": 1
994
+ },
995
+ "asserted": {
996
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
997
+ "type": "array",
998
+ "items": {
999
+ "type": "string"
1000
+ }
1001
+ },
1002
+ "limitations": {
1003
+ "description": "Known limits of what this evidence shows, in the producer's words",
1004
+ "type": "array",
1005
+ "items": {
1006
+ "type": "string"
1007
+ }
1008
+ },
1009
+ "declaredBy": {
1010
+ "description": "Who or what made this declaration: a tool, a team, a person",
1011
+ "type": "string"
1012
+ },
1013
+ "verified": {
1014
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
1015
+ "type": "array",
1016
+ "items": {
1017
+ "type": "string"
1018
+ }
1019
+ },
1020
+ "verifiedBy": {
1021
+ "description": "What checked the `verified` fields",
1022
+ "type": "string"
1023
+ },
1024
+ "provenance": {
1025
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
1026
+ "type": "array",
1027
+ "items": {
1028
+ "type": "object",
1029
+ "properties": {
1030
+ "url": {
1031
+ "type": "string",
1032
+ "minLength": 1
1033
+ },
1034
+ "name": {
1035
+ "type": "string"
1036
+ },
1037
+ "rel": {
1038
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
1039
+ "type": "string"
1040
+ }
1041
+ },
1042
+ "required": [
1043
+ "url"
1044
+ ],
1045
+ "additionalProperties": {}
1046
+ }
1047
+ },
1048
+ "extensions": {
1049
+ "type": "object",
1050
+ "propertyNames": {
1051
+ "type": "string",
1052
+ "minLength": 1
1053
+ },
1054
+ "additionalProperties": {}
1055
+ }
1056
+ },
1057
+ "additionalProperties": {}
940
1058
  }
941
1059
  },
942
1060
  "required": [
@@ -1140,6 +1258,16 @@
1140
1258
  "type": "string"
1141
1259
  }
1142
1260
  },
1261
+ "scopeProfiles": {
1262
+ "description": "The scope tokens each distinct playable recording of its current results declares (`device:physical`, `audio:silent`); `[\"unknown\"]` for a recording that declared none. What `?scope=` matches, one recording at a time. Absent when it has no playable recording",
1263
+ "type": "array",
1264
+ "items": {
1265
+ "type": "array",
1266
+ "items": {
1267
+ "type": "string"
1268
+ }
1269
+ }
1270
+ },
1143
1271
  "labels": {
1144
1272
  "type": "object",
1145
1273
  "propertyNames": {
@@ -257,6 +257,102 @@
257
257
  "available": {
258
258
  "type": "boolean",
259
259
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
260
+ },
261
+ "scope": {
262
+ "description": "What this recording shows as its producer declared it: its own `scope`, else its attempt's, check's, part's or layer's. Absent: the scope is unknown, never live, physical or audible",
263
+ "type": "object",
264
+ "properties": {
265
+ "surface": {
266
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
267
+ "type": "string",
268
+ "minLength": 1
269
+ },
270
+ "deviceKind": {
271
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
272
+ "type": "string",
273
+ "minLength": 1
274
+ },
275
+ "syntheticData": {
276
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
277
+ "type": "boolean"
278
+ },
279
+ "dependencies": {
280
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
281
+ "type": "string",
282
+ "minLength": 1
283
+ },
284
+ "audioCaptured": {
285
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
286
+ "type": "boolean"
287
+ },
288
+ "pacing": {
289
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
290
+ "type": "string",
291
+ "minLength": 1
292
+ },
293
+ "asserted": {
294
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
295
+ "type": "array",
296
+ "items": {
297
+ "type": "string"
298
+ }
299
+ },
300
+ "limitations": {
301
+ "description": "Known limits of what this evidence shows, in the producer's words",
302
+ "type": "array",
303
+ "items": {
304
+ "type": "string"
305
+ }
306
+ },
307
+ "declaredBy": {
308
+ "description": "Who or what made this declaration: a tool, a team, a person",
309
+ "type": "string"
310
+ },
311
+ "verified": {
312
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
313
+ "type": "array",
314
+ "items": {
315
+ "type": "string"
316
+ }
317
+ },
318
+ "verifiedBy": {
319
+ "description": "What checked the `verified` fields",
320
+ "type": "string"
321
+ },
322
+ "provenance": {
323
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
324
+ "type": "array",
325
+ "items": {
326
+ "type": "object",
327
+ "properties": {
328
+ "url": {
329
+ "type": "string",
330
+ "minLength": 1
331
+ },
332
+ "name": {
333
+ "type": "string"
334
+ },
335
+ "rel": {
336
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
337
+ "type": "string"
338
+ }
339
+ },
340
+ "required": [
341
+ "url"
342
+ ],
343
+ "additionalProperties": {}
344
+ }
345
+ },
346
+ "extensions": {
347
+ "type": "object",
348
+ "propertyNames": {
349
+ "type": "string",
350
+ "minLength": 1
351
+ },
352
+ "additionalProperties": {}
353
+ }
354
+ },
355
+ "additionalProperties": {}
260
356
  }
261
357
  },
262
358
  "required": [
@@ -460,6 +556,16 @@
460
556
  "type": "string"
461
557
  }
462
558
  },
559
+ "scopeProfiles": {
560
+ "description": "The scope tokens each distinct playable recording of its current results declares (`device:physical`, `audio:silent`); `[\"unknown\"]` for a recording that declared none. What `?scope=` matches, one recording at a time. Absent when it has no playable recording",
561
+ "type": "array",
562
+ "items": {
563
+ "type": "array",
564
+ "items": {
565
+ "type": "string"
566
+ }
567
+ }
568
+ },
463
569
  "labels": {
464
570
  "type": "object",
465
571
  "propertyNames": {
@@ -702,6 +808,102 @@
702
808
  "available": {
703
809
  "type": "boolean",
704
810
  "description": "False when the reference names no bytes (no bundle key, address or inline text)"
811
+ },
812
+ "scope": {
813
+ "description": "What this recording shows as its producer declared it: its own `scope`, else its attempt's, check's, part's or layer's. Absent: the scope is unknown, never live, physical or audible",
814
+ "type": "object",
815
+ "properties": {
816
+ "surface": {
817
+ "description": "Where the product ran, in an open vocabulary: `browser`, `native-app`, `api`, `cli`…",
818
+ "type": "string",
819
+ "minLength": 1
820
+ },
821
+ "deviceKind": {
822
+ "description": "What it ran on, in an open vocabulary: `simulator`, `emulator`, `physical`, `virtual-machine`, `desktop`… A simulator and a physical phone stay distinct values; they are filtered separately",
823
+ "type": "string",
824
+ "minLength": 1
825
+ },
826
+ "syntheticData": {
827
+ "description": "True: the data was made up for the run. False: real data. Absent: unknown",
828
+ "type": "boolean"
829
+ },
830
+ "dependencies": {
831
+ "description": "Whether what the product talks to was `scripted` (replies fixed in advance), `live` or `mixed`. An open vocabulary; absent is unknown",
832
+ "type": "string",
833
+ "minLength": 1
834
+ },
835
+ "audioCaptured": {
836
+ "description": "True: the recording has real audio. False: it is silent. Absent: unknown",
837
+ "type": "boolean"
838
+ },
839
+ "pacing": {
840
+ "description": "How time ran, in an open vocabulary: `paced` (slowed or scripted for a viewer), `real-time`. Absent: unknown",
841
+ "type": "string",
842
+ "minLength": 1
843
+ },
844
+ "asserted": {
845
+ "description": "The boundaries the result actually asserts. Activity visible in a recording beyond them is not verified behavior",
846
+ "type": "array",
847
+ "items": {
848
+ "type": "string"
849
+ }
850
+ },
851
+ "limitations": {
852
+ "description": "Known limits of what this evidence shows, in the producer's words",
853
+ "type": "array",
854
+ "items": {
855
+ "type": "string"
856
+ }
857
+ },
858
+ "declaredBy": {
859
+ "description": "Who or what made this declaration: a tool, a team, a person",
860
+ "type": "string"
861
+ },
862
+ "verified": {
863
+ "description": "The names of the fields above (`surface`, `deviceKind`, `syntheticData`, `dependencies`, `audioCaptured`, `pacing`) that something independent of the producer checked. Every other field is only declared",
864
+ "type": "array",
865
+ "items": {
866
+ "type": "string"
867
+ }
868
+ },
869
+ "verifiedBy": {
870
+ "description": "What checked the `verified` fields",
871
+ "type": "string"
872
+ },
873
+ "provenance": {
874
+ "description": "Where the declaration comes from and how to check it: a document, a CI step, a device log",
875
+ "type": "array",
876
+ "items": {
877
+ "type": "object",
878
+ "properties": {
879
+ "url": {
880
+ "type": "string",
881
+ "minLength": 1
882
+ },
883
+ "name": {
884
+ "type": "string"
885
+ },
886
+ "rel": {
887
+ "description": "Why it is linked, in an open vocabulary: issue, run, trace, docs, source…",
888
+ "type": "string"
889
+ }
890
+ },
891
+ "required": [
892
+ "url"
893
+ ],
894
+ "additionalProperties": {}
895
+ }
896
+ },
897
+ "extensions": {
898
+ "type": "object",
899
+ "propertyNames": {
900
+ "type": "string",
901
+ "minLength": 1
902
+ },
903
+ "additionalProperties": {}
904
+ }
905
+ },
906
+ "additionalProperties": {}
705
907
  }
706
908
  },
707
909
  "required": [