@crvouga/atlas 1.7.0 → 1.9.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/CHANGELOG.md +13 -1
- package/dist/reports/src/evidence-detail.js +6 -1
- package/dist/reports/src/evidence-types.d.ts +2 -0
- package/dist/reports/src/explorer-types.d.ts +19 -0
- package/dist/reports/src/latency.d.ts +204 -0
- package/dist/reports/src/latency.js +219 -0
- package/dist/reports/src/reliability.d.ts +181 -0
- package/dist/reports/src/reliability.js +294 -0
- package/dist/reports/src/report-index.js +1 -1
- package/dist/reports/src/reports-explorer-route.d.ts +19 -6
- package/dist/reports/src/reports-route.d.ts +19 -6
- package/dist/reports/src/test-catalog.d.ts +11 -3
- package/dist/reports/src/test-catalog.js +12 -5
- package/dist/schema/src/api.d.ts +377 -0
- package/dist/schema/src/api.js +55 -3
- package/dist/schema/src/layer.d.ts +90 -0
- package/dist/schema/src/layer.js +20 -1
- package/dist/server/src/app.js +15 -0
- package/dist/server/src/llms.js +1 -0
- package/dist/server/src/openapi.js +25 -2
- package/docs/extending.md +1 -1
- package/docs/reference/http-api.md +48 -0
- package/docs/reference/reports.md +619 -1
- package/docs/reference/schema.md +39 -0
- package/docs/rich-evidence.md +43 -0
- package/docs/server.md +18 -0
- package/docs/ui.md +20 -1
- package/llms-full.txt +130 -2
- package/package.json +1 -1
- package/packages/schema/schemas/check-detail.schema.json +56 -1
- package/packages/schema/schemas/effective-delta.schema.json +86 -2
- package/packages/schema/schemas/effective-evidence.schema.json +86 -2
- package/packages/schema/schemas/evidence-page.schema.json +13 -0
- package/packages/schema/schemas/layer-rows.schema.json +73 -2
- package/packages/schema/schemas/layer.schema.json +112 -2
- package/packages/schema/schemas/publish-checks.schema.json +56 -1
- package/packages/schema/schemas/test-catalog.schema.json +102 -0
- package/packages/schema/schemas/test-history.schema.json +204 -0
- package/packages/schema/schemas/test-reliability.schema.json +629 -0
- package/packages/server/openapi.json +2354 -661
- package/packages/visualizer/src/evidence/check-detail.tsx +9 -0
- package/packages/visualizer/src/explorer/ProductLatency.tsx +214 -0
- package/packages/visualizer/src/explorer/Reliability.tsx +337 -0
- package/packages/visualizer/src/explorer/TestDetail.tsx +12 -2
- package/packages/visualizer/src/explorer/catalog.tsx +1 -1
- package/packages/visualizer/src/explorer/search.ts +36 -0
package/docs/reference/schema.md
CHANGED
|
@@ -300,6 +300,17 @@ export const TestHistorySchema = …
|
|
|
300
300
|
|
|
301
301
|
`GET /api/reports/tests/history`: one test and every result recorded for it (at most 100), newest first.
|
|
302
302
|
|
|
303
|
+
#### `TestReliabilitySchema`
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
export const TestReliabilitySchema = …
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
`GET /api/reports/tests/reliability`: how reliable one test is inside a scope, and exactly how that figure was counted.
|
|
310
|
+
The snapshots one run recorded for one producer, environment and parameter set are one independent execution; only
|
|
311
|
+
`passed` and `failed` executions are trials; `notes` say when the sample is too small, pooled, selectively rerun or
|
|
312
|
+
bounded. It reads results and never changes a status. It is not a production failure probability.
|
|
313
|
+
|
|
303
314
|
#### `ReportRunSchema`
|
|
304
315
|
|
|
305
316
|
```ts
|
|
@@ -742,6 +753,22 @@ export type LayerRun = z.output<typeof LayerRunSchema>;
|
|
|
742
753
|
|
|
743
754
|
The execution of a layer, parsed from `LayerRunSchema`.
|
|
744
755
|
|
|
756
|
+
#### `PRODUCT_LATENCY_KIND`
|
|
757
|
+
|
|
758
|
+
```ts
|
|
759
|
+
export const PRODUCT_LATENCY_KIND = …
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
The `kind` of a measurement that is a named, user-visible product latency (see docs/rich-evidence.md#product-latency).
|
|
763
|
+
|
|
764
|
+
#### `MeasurementBoundarySchema`
|
|
765
|
+
|
|
766
|
+
```ts
|
|
767
|
+
export const MeasurementBoundarySchema = …
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
The two ends of a measured interval, named in the producer's words: `{ from: 'submit pressed', to: 'confirmation visible' }`.
|
|
771
|
+
|
|
745
772
|
#### `MeasurementSchema`
|
|
746
773
|
|
|
747
774
|
```ts
|
|
@@ -751,6 +778,18 @@ export const MeasurementSchema = …
|
|
|
751
778
|
A number a check measured, such as a latency or a size, with its unit and an optional allowance. A measurement over
|
|
752
779
|
its `limit` is reported and never changes the check's status.
|
|
753
780
|
|
|
781
|
+
A measurement of `kind` `product-latency` is how quickly the product responded to a user, between two named events.
|
|
782
|
+
It is not the check's duration (which includes setup, waits and pacing) and a number with no `kind` is never read as
|
|
783
|
+
product latency. All the fields after `limit` are optional and describe the measurement; none decides a status.
|
|
784
|
+
|
|
785
|
+
#### `Measurement`
|
|
786
|
+
|
|
787
|
+
```ts
|
|
788
|
+
export type Measurement = z.output<typeof MeasurementSchema>;
|
|
789
|
+
```
|
|
790
|
+
|
|
791
|
+
A measurement as stored in a layer, parsed from `MeasurementSchema`.
|
|
792
|
+
|
|
754
793
|
#### `ExtensionsSchema`
|
|
755
794
|
|
|
756
795
|
```ts
|
package/docs/rich-evidence.md
CHANGED
|
@@ -109,6 +109,49 @@ Every field is optional, and every value except the booleans is an open string.
|
|
|
109
109
|
- **It decides nothing.** A scope never changes a status, a slot or a winner. A scope an older Atlas cannot read is
|
|
110
110
|
dropped, and the attachment, check and layer stay.
|
|
111
111
|
|
|
112
|
+
## Product latency
|
|
113
|
+
|
|
114
|
+
A test's `durationMs` includes fixture setup, deliberate waits, demo pacing, retries and cleanup, so it says how long the
|
|
115
|
+
test ran and nothing about how quickly the product responded. Name the numbers that do, as measurements of `kind`
|
|
116
|
+
`product-latency` between two events:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
measurements: [
|
|
120
|
+
{ name: 'Fixture setup', value: 20_000, unit: 'ms' }, // just a number: never read as latency
|
|
121
|
+
{
|
|
122
|
+
name: 'Confirmation', value: 500, unit: 'ms', kind: 'product-latency',
|
|
123
|
+
from: 'submit pressed', to: 'confirmation visible', // the boundaries are part of the claim
|
|
124
|
+
limit: 800, // the budget
|
|
125
|
+
source: 'app-instrumentation', instrumentation: 'spans-v2',
|
|
126
|
+
labels: { device: 'pixel-8', build: '4821' } // what it is comparable with
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The test page shows **Product latency** apart from the test statistics, whose durations are labelled as test execution
|
|
132
|
+
time. Every field after `unit` is optional and none of them decides a status, a slot or a winner.
|
|
133
|
+
|
|
134
|
+
- **Only named measurements are latency.** A check's duration, a video's length, a step and a number with no `kind` are
|
|
135
|
+
never product latency. A test that recorded none shows that its latency is unknown, not fast.
|
|
136
|
+
- **Boundaries are part of the claim.** Without both `from` and `to` the numbers are shown but no percentile or product
|
|
137
|
+
claim is made, and the page says so. When the interval you measured is only part of what the name claims, say what it
|
|
138
|
+
claims in `intended` (`{ "to": "audible response" }` on a measurement that ends at `tts dispatch`) and the viewer labels
|
|
139
|
+
it a partial interval, never the complete one.
|
|
140
|
+
- **Percentiles need samples.** p50 needs 5 observations and p95 needs 20; fewer shows `Withheld` with the count it has.
|
|
141
|
+
One observation shows no spread or confidence.
|
|
142
|
+
- **A timeout is a sample.** `outcome: "timeout"` or `"failed"` (anything but `observed`) means `value` is how long the
|
|
143
|
+
observation waited. It stays in the sample count and the percentiles, counts as over budget whenever a `limit` is set,
|
|
144
|
+
and marks the figures as lower bounds, so a stuck product never looks healthy.
|
|
145
|
+
- **Groups.** The viewer groups observations by `device`, `build` or the UTC day they were recorded, taking `device` and
|
|
146
|
+
`build` from the measurement's `labels`, else the result's labels, parameters, environment and commit. Each group has
|
|
147
|
+
its own sample count, p50/p95, budget and breaches. A group that names nothing is `unknown device` or `unknown build`.
|
|
148
|
+
- **Baselines.** A group is compared with a chosen baseline by absolute and relative change of p50 (and p95), or of the
|
|
149
|
+
newest observation when percentiles are not supported on both sides. Measurements with different names, units or
|
|
150
|
+
boundaries are not compared. A change of `instrumentation`, environment, other labels or parameters, or budget between
|
|
151
|
+
the two sides is listed beside the change.
|
|
152
|
+
- **Reading it from the API.** `GET /api/reports/tests/history` entries carry `latency` (their product-latency
|
|
153
|
+
measurements) next to `durationMs`. The pure functions are in `@crvouga/atlas/reports/latency`.
|
|
154
|
+
|
|
112
155
|
## Finding runs and artifacts
|
|
113
156
|
|
|
114
157
|
The viewer's **Runs** and **Artifacts** tabs and the API answer one query, so a link means the same thing everywhere.
|
package/docs/server.md
CHANGED
|
@@ -374,6 +374,7 @@ with `format=markdown` (or `Accept: text/markdown`), and takes the project prefi
|
|
|
374
374
|
| Every test, a summary (by status, environment, producer, domain), insights (failing, flaky, slowest) and facets | `GET /api/reports/tests` |
|
|
375
375
|
| Only some: `q` (all words), `status` (or `flaky`), `environment`, `producer`, `domain`, `spec`, `tag`, `run`; `sort`, `offset`, `limit` | `GET /api/reports/tests?status=failed&environment=ios` |
|
|
376
376
|
| One test: every recorded result (status, duration, environment, branch, commit, CI run), newest first | `GET /api/reports/tests/history?key=<key>` |
|
|
377
|
+
| How reliable one test is in a scope (environment, producer, parameters, branch, commit, spec revision, time window): independent executions, first-try and eventual success, what was left out and why | `GET /api/reports/tests/reliability?key=<key>&environment=phone` |
|
|
377
378
|
| Why Specs, domains and counts disagree: ambiguous spec paths, shared domains, gaps, a reconciliation of the totals | `GET /api/reports/tests/health` |
|
|
378
379
|
| The runs that recorded the report (by CI run URL, else branch and commit); `?video=true` keeps those with a playable video; `artifactTag`, `type`, `label`, `environment`, `branch`, `outcome`, `since`, `until` narrow it ([filtering](rich-evidence.md#finding-runs-and-artifacts)) | `GET /api/reports/runs` |
|
|
379
380
|
| Recorded results that carry evidence, across the whole history, found by tag, media type, label, feature, environment, branch, revision, outcome and time | `GET /api/reports/artifacts?artifactTag=demo&type=video` |
|
|
@@ -388,6 +389,21 @@ curl "$ATLAS_SERVER_URL/api/projects/$ATLAS_PROJECT/reports/tests?format=markdow
|
|
|
388
389
|
`stats` describes its recorded history: pass rate, flips, whether it is flaky and why (it passed and failed on the
|
|
389
390
|
same commit, passed only after a retry, or its producer said so), durations (avg, p50, p95, min, max, last), runs
|
|
390
391
|
and branches.
|
|
392
|
+
- The **reliability** document qualifies `stats.passRate` instead of repeating it. The snapshots one run recorded for one
|
|
393
|
+
producer, environment and parameter set (running, finished, enriched) are **one independent execution**, counted by its last
|
|
394
|
+
word with the tries it recorded; `firstAttempt` counts executions whose first try passed, `eventual` those that passed in the
|
|
395
|
+
end, and an execution that recorded no tries (`attemptStatuses` on its evidence) is never assumed to have passed first time.
|
|
396
|
+
Choose the scope with `environment`, `producer`, `parameter=key=value`, `branch`, `sha`, `specRevision`, `since` and `until`:
|
|
397
|
+
other environments never add to a phone's sample. By default only the newest recorded spec revision (the `fingerprint` of its
|
|
398
|
+
spec text, `specRevision` on each result) counts and earlier ones appear as `historical` context; `revision=any` pools them
|
|
399
|
+
and says so. Only `passed` and `failed` executions are trials; `not-run`, unfinished and unknown ones are named under
|
|
400
|
+
`excluded` and never become a pass. `sample` is `none`, `insufficient` (under `minimumExecutions`) or `sufficient`, a count
|
|
401
|
+
only: `notes` say when the figure pools environments, producers or branches, when failed cases were published again
|
|
402
|
+
(`selected-reruns`), and when history is bounded to the newest 100 results. `executions` is the denominator, one row per
|
|
403
|
+
independent execution with its tries and snapshots, so the same query can be inspected and shared. The Wilson interval states
|
|
404
|
+
its assumptions. It describes the checks Atlas holds; it is not a production failure probability. The viewer shows the same
|
|
405
|
+
figures under a test (scope in the address as `relEnv`, `relProducer`, `relBranch`, `relParam`, `relSince`, `relUntil`,
|
|
406
|
+
`relRevision=any`, `relOpen=true`).
|
|
391
407
|
- The **health** document explains the numbers instead of adding one. It keeps spec files, defined specs, specs with an
|
|
392
408
|
executed test, tests, outlines, examples and per-environment observations apart, and walks from the Specs total to
|
|
393
409
|
the Tests total. Two spec paths are one logical spec only when a mapping says so
|
|
@@ -453,6 +469,8 @@ curl "$ATLAS_SERVER_URL/api/projects/$ATLAS_PROJECT/reports/tests?format=markdow
|
|
|
453
469
|
| `GET /api/projects/{project}/reports/tests/health` | read | Why specs, domains and counts disagree. |
|
|
454
470
|
| `GET /api/reports/tests/history` | read | One test and every result recorded for it. |
|
|
455
471
|
| `GET /api/projects/{project}/reports/tests/history` | read | One test and every result recorded for it. |
|
|
472
|
+
| `GET /api/reports/tests/reliability` | read | How reliable one test is in a scope, and how that was counted. |
|
|
473
|
+
| `GET /api/projects/{project}/reports/tests/reliability` | read | How reliable one test is in a scope, and how that was counted. |
|
|
456
474
|
| `GET /api/reports/artifact-tags` | read | Reviewer tags of attachments: every recorded edit. |
|
|
457
475
|
| `GET /api/projects/{project}/reports/artifact-tags` | read | Reviewer tags of attachments: every recorded edit. |
|
|
458
476
|
| `POST /api/reports/artifact-tags` | publish | Tag or untag one attachment after upload. |
|
package/docs/ui.md
CHANGED
|
@@ -87,6 +87,25 @@ when Watch is on screen.
|
|
|
87
87
|
- The spec index searches titles, paths and declared domains, and can group by the domain from spec metadata (specs with
|
|
88
88
|
none are listed under "No domain declared"; the Tests view reports domain problems).
|
|
89
89
|
|
|
90
|
+
## Reliability
|
|
91
|
+
|
|
92
|
+
An open test shows its reliability (`explorer/Reliability.tsx`, worked out by `reports/reliability` from the history the page
|
|
93
|
+
already holds). Never show a bare percentage: it always comes with the number of independent executions it rests on, the
|
|
94
|
+
"Insufficient evidence" badge below the minimum (one pass is not established reliability), the scope (environment,
|
|
95
|
+
producer, branch, parameters, time window, spec revision) and the warning notes (pooled environments, failed cases
|
|
96
|
+
published again, bounded history). First-try success is over executions that recorded their tries only; a result that
|
|
97
|
+
did not run or did not finish is excluded by name and never counted as a pass. The scope and the open executions table
|
|
98
|
+
are in the address (`rel*`), so a link reproduces the figure and the executions behind it.
|
|
99
|
+
|
|
100
|
+
## Product latency
|
|
101
|
+
|
|
102
|
+
A test's duration and its product latency are different things and the viewer never mixes them (`explorer/ProductLatency.tsx`,
|
|
103
|
+
`@crvouga/atlas/reports/latency`). Statistics and the trend are labelled test execution time. Product latency is read only from
|
|
104
|
+
measurements named `product-latency`; it shows boundaries, group (device, build, day), samples, budget and breaches, and a
|
|
105
|
+
baseline comparison that lists changes of instrumentation or conditions. Percentiles and product claims that the evidence
|
|
106
|
+
cannot support are shown as `Withheld` with the reason, a partial interval is badged, timeouts count as samples and breaches,
|
|
107
|
+
and a test with no latency says it is unknown, not fast.
|
|
108
|
+
|
|
90
109
|
## Outcome summary
|
|
91
110
|
|
|
92
111
|
A test or behavior detail states what the **selected** result says apart from what the other current sources say
|
|
@@ -170,7 +189,7 @@ The narrowly scoped exceptions are:
|
|
|
170
189
|
| --- | --- | --- |
|
|
171
190
|
| Shared shell | Project switching, spec navigation, run selection, connection status, diagnostics, mobile index | AppShell, Burger, NavLink, Menu, Popover, NativeSelect, Drawer |
|
|
172
191
|
| Project home | Tests/runs/artifacts tabs, a run's Artifacts (files of its layers, shared recordings, direct links), metrics, search, status/environment/domain/artifact-tag filters, run and artifact facets with saved views, grouping, sorting, show more | Container, Tabs, SimpleGrid, Paper, TextInput, MultiSelect, Popover, Button, Accordion |
|
|
173
|
-
| Test detail | Current outcomes, statistics, duration graph, history, artifacts, recording; the `layer` address parameter pins it to one run's result, labelled "This run" against "Latest combined evidence" | Drawer, Table, Badge, Alert, Stage |
|
|
192
|
+
| Test detail | Current outcomes, statistics, duration graph, product latency with budgets and baselines, history, artifacts, recording; the `layer` address parameter pins it to one run's result, labelled "This run" against "Latest combined evidence" | Drawer, Table, Badge, Alert, Stage |
|
|
174
193
|
| Specs | All six existing kinds, overview/index with title search and folder or declared-domain grouping, Gherkin rules/scenarios/examples with a coverage summary and Read / Watch / Inspect per behavior, Quint declarations/traces, DMN tables, source text | SpecHeader, Accordion, Tabs, Table, CodeHighlightTabs, ResultRow |
|
|
175
194
|
| Statecharts | Graph, screen/event/journey details, developer metadata, chart test results | Mantine cards/navigation and product compositions; graph exception above |
|
|
176
195
|
| Evidence | Steps, retries, annotations, facts, unknown extensions, safe downloads and previews | List, Badge, Accordion, Code, Image, native media |
|
package/llms-full.txt
CHANGED
|
@@ -1096,6 +1096,49 @@ Every field is optional, and every value except the booleans is an open string.
|
|
|
1096
1096
|
- **It decides nothing.** A scope never changes a status, a slot or a winner. A scope an older Atlas cannot read is
|
|
1097
1097
|
dropped, and the attachment, check and layer stay.
|
|
1098
1098
|
|
|
1099
|
+
## Product latency
|
|
1100
|
+
|
|
1101
|
+
A test's `durationMs` includes fixture setup, deliberate waits, demo pacing, retries and cleanup, so it says how long the
|
|
1102
|
+
test ran and nothing about how quickly the product responded. Name the numbers that do, as measurements of `kind`
|
|
1103
|
+
`product-latency` between two events:
|
|
1104
|
+
|
|
1105
|
+
```ts
|
|
1106
|
+
measurements: [
|
|
1107
|
+
{ name: 'Fixture setup', value: 20_000, unit: 'ms' }, // just a number: never read as latency
|
|
1108
|
+
{
|
|
1109
|
+
name: 'Confirmation', value: 500, unit: 'ms', kind: 'product-latency',
|
|
1110
|
+
from: 'submit pressed', to: 'confirmation visible', // the boundaries are part of the claim
|
|
1111
|
+
limit: 800, // the budget
|
|
1112
|
+
source: 'app-instrumentation', instrumentation: 'spans-v2',
|
|
1113
|
+
labels: { device: 'pixel-8', build: '4821' } // what it is comparable with
|
|
1114
|
+
}
|
|
1115
|
+
]
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
The test page shows **Product latency** apart from the test statistics, whose durations are labelled as test execution
|
|
1119
|
+
time. Every field after `unit` is optional and none of them decides a status, a slot or a winner.
|
|
1120
|
+
|
|
1121
|
+
- **Only named measurements are latency.** A check's duration, a video's length, a step and a number with no `kind` are
|
|
1122
|
+
never product latency. A test that recorded none shows that its latency is unknown, not fast.
|
|
1123
|
+
- **Boundaries are part of the claim.** Without both `from` and `to` the numbers are shown but no percentile or product
|
|
1124
|
+
claim is made, and the page says so. When the interval you measured is only part of what the name claims, say what it
|
|
1125
|
+
claims in `intended` (`{ "to": "audible response" }` on a measurement that ends at `tts dispatch`) and the viewer labels
|
|
1126
|
+
it a partial interval, never the complete one.
|
|
1127
|
+
- **Percentiles need samples.** p50 needs 5 observations and p95 needs 20; fewer shows `Withheld` with the count it has.
|
|
1128
|
+
One observation shows no spread or confidence.
|
|
1129
|
+
- **A timeout is a sample.** `outcome: "timeout"` or `"failed"` (anything but `observed`) means `value` is how long the
|
|
1130
|
+
observation waited. It stays in the sample count and the percentiles, counts as over budget whenever a `limit` is set,
|
|
1131
|
+
and marks the figures as lower bounds, so a stuck product never looks healthy.
|
|
1132
|
+
- **Groups.** The viewer groups observations by `device`, `build` or the UTC day they were recorded, taking `device` and
|
|
1133
|
+
`build` from the measurement's `labels`, else the result's labels, parameters, environment and commit. Each group has
|
|
1134
|
+
its own sample count, p50/p95, budget and breaches. A group that names nothing is `unknown device` or `unknown build`.
|
|
1135
|
+
- **Baselines.** A group is compared with a chosen baseline by absolute and relative change of p50 (and p95), or of the
|
|
1136
|
+
newest observation when percentiles are not supported on both sides. Measurements with different names, units or
|
|
1137
|
+
boundaries are not compared. A change of `instrumentation`, environment, other labels or parameters, or budget between
|
|
1138
|
+
the two sides is listed beside the change.
|
|
1139
|
+
- **Reading it from the API.** `GET /api/reports/tests/history` entries carry `latency` (their product-latency
|
|
1140
|
+
measurements) next to `durationMs`. The pure functions are in `@crvouga/atlas/reports/latency`.
|
|
1141
|
+
|
|
1099
1142
|
## Finding runs and artifacts
|
|
1100
1143
|
|
|
1101
1144
|
The viewer's **Runs** and **Artifacts** tabs and the API answer one query, so a link means the same thing everywhere.
|
|
@@ -1720,6 +1763,7 @@ with `format=markdown` (or `Accept: text/markdown`), and takes the project prefi
|
|
|
1720
1763
|
| Every test, a summary (by status, environment, producer, domain), insights (failing, flaky, slowest) and facets | `GET /api/reports/tests` |
|
|
1721
1764
|
| Only some: `q` (all words), `status` (or `flaky`), `environment`, `producer`, `domain`, `spec`, `tag`, `run`; `sort`, `offset`, `limit` | `GET /api/reports/tests?status=failed&environment=ios` |
|
|
1722
1765
|
| One test: every recorded result (status, duration, environment, branch, commit, CI run), newest first | `GET /api/reports/tests/history?key=<key>` |
|
|
1766
|
+
| How reliable one test is in a scope (environment, producer, parameters, branch, commit, spec revision, time window): independent executions, first-try and eventual success, what was left out and why | `GET /api/reports/tests/reliability?key=<key>&environment=phone` |
|
|
1723
1767
|
| Why Specs, domains and counts disagree: ambiguous spec paths, shared domains, gaps, a reconciliation of the totals | `GET /api/reports/tests/health` |
|
|
1724
1768
|
| The runs that recorded the report (by CI run URL, else branch and commit); `?video=true` keeps those with a playable video; `artifactTag`, `type`, `label`, `environment`, `branch`, `outcome`, `since`, `until` narrow it ([filtering](rich-evidence.md#finding-runs-and-artifacts)) | `GET /api/reports/runs` |
|
|
1725
1769
|
| Recorded results that carry evidence, across the whole history, found by tag, media type, label, feature, environment, branch, revision, outcome and time | `GET /api/reports/artifacts?artifactTag=demo&type=video` |
|
|
@@ -1734,6 +1778,21 @@ curl "$ATLAS_SERVER_URL/api/projects/$ATLAS_PROJECT/reports/tests?format=markdow
|
|
|
1734
1778
|
`stats` describes its recorded history: pass rate, flips, whether it is flaky and why (it passed and failed on the
|
|
1735
1779
|
same commit, passed only after a retry, or its producer said so), durations (avg, p50, p95, min, max, last), runs
|
|
1736
1780
|
and branches.
|
|
1781
|
+
- The **reliability** document qualifies `stats.passRate` instead of repeating it. The snapshots one run recorded for one
|
|
1782
|
+
producer, environment and parameter set (running, finished, enriched) are **one independent execution**, counted by its last
|
|
1783
|
+
word with the tries it recorded; `firstAttempt` counts executions whose first try passed, `eventual` those that passed in the
|
|
1784
|
+
end, and an execution that recorded no tries (`attemptStatuses` on its evidence) is never assumed to have passed first time.
|
|
1785
|
+
Choose the scope with `environment`, `producer`, `parameter=key=value`, `branch`, `sha`, `specRevision`, `since` and `until`:
|
|
1786
|
+
other environments never add to a phone's sample. By default only the newest recorded spec revision (the `fingerprint` of its
|
|
1787
|
+
spec text, `specRevision` on each result) counts and earlier ones appear as `historical` context; `revision=any` pools them
|
|
1788
|
+
and says so. Only `passed` and `failed` executions are trials; `not-run`, unfinished and unknown ones are named under
|
|
1789
|
+
`excluded` and never become a pass. `sample` is `none`, `insufficient` (under `minimumExecutions`) or `sufficient`, a count
|
|
1790
|
+
only: `notes` say when the figure pools environments, producers or branches, when failed cases were published again
|
|
1791
|
+
(`selected-reruns`), and when history is bounded to the newest 100 results. `executions` is the denominator, one row per
|
|
1792
|
+
independent execution with its tries and snapshots, so the same query can be inspected and shared. The Wilson interval states
|
|
1793
|
+
its assumptions. It describes the checks Atlas holds; it is not a production failure probability. The viewer shows the same
|
|
1794
|
+
figures under a test (scope in the address as `relEnv`, `relProducer`, `relBranch`, `relParam`, `relSince`, `relUntil`,
|
|
1795
|
+
`relRevision=any`, `relOpen=true`).
|
|
1737
1796
|
- The **health** document explains the numbers instead of adding one. It keeps spec files, defined specs, specs with an
|
|
1738
1797
|
executed test, tests, outlines, examples and per-environment observations apart, and walks from the Specs total to
|
|
1739
1798
|
the Tests total. Two spec paths are one logical spec only when a mapping says so
|
|
@@ -1799,6 +1858,8 @@ curl "$ATLAS_SERVER_URL/api/projects/$ATLAS_PROJECT/reports/tests?format=markdow
|
|
|
1799
1858
|
| `GET /api/projects/{project}/reports/tests/health` | read | Why specs, domains and counts disagree. |
|
|
1800
1859
|
| `GET /api/reports/tests/history` | read | One test and every result recorded for it. |
|
|
1801
1860
|
| `GET /api/projects/{project}/reports/tests/history` | read | One test and every result recorded for it. |
|
|
1861
|
+
| `GET /api/reports/tests/reliability` | read | How reliable one test is in a scope, and how that was counted. |
|
|
1862
|
+
| `GET /api/projects/{project}/reports/tests/reliability` | read | How reliable one test is in a scope, and how that was counted. |
|
|
1802
1863
|
| `GET /api/reports/artifact-tags` | read | Reviewer tags of attachments: every recorded edit. |
|
|
1803
1864
|
| `GET /api/projects/{project}/reports/artifact-tags` | read | Reviewer tags of attachments: every recorded edit. |
|
|
1804
1865
|
| `POST /api/reports/artifact-tags` | publish | Tag or untag one attachment after upload. |
|
|
@@ -2830,7 +2891,7 @@ carry any of these. Every one is optional.
|
|
|
2830
2891
|
| `scope{}` | What the evidence does and does not show: surface, device kind, synthetic data, scripted dependencies, audio, pacing, what was asserted and its limits. Unknown when absent. See [Evidence scope](rich-evidence.md#evidence-scope). |
|
|
2831
2892
|
| `links[]` | Where to read more: the CI run, the issue, the trace client. |
|
|
2832
2893
|
| `extensions{}` | Structured data of your own or a tool's, under a name you own. |
|
|
2833
|
-
| `measurements[]` | Numbers, with units and an allowance (already part of the contract). |
|
|
2894
|
+
| `measurements[]` | Numbers, with units and an allowance (already part of the contract). A measurement of `kind` `product-latency` names a user-visible response time between two events; see [Product latency](rich-evidence.md#product-latency). |
|
|
2834
2895
|
|
|
2835
2896
|
An attachment may carry its own `tags[]` (`demo`): shown as `#demo` and searchable; see
|
|
2836
2897
|
[Tagging artifacts and demos](rich-evidence.md#tagging-artifacts-and-demos).
|
|
@@ -3936,6 +3997,25 @@ when Watch is on screen.
|
|
|
3936
3997
|
- The spec index searches titles, paths and declared domains, and can group by the domain from spec metadata (specs with
|
|
3937
3998
|
none are listed under "No domain declared"; the Tests view reports domain problems).
|
|
3938
3999
|
|
|
4000
|
+
## Reliability
|
|
4001
|
+
|
|
4002
|
+
An open test shows its reliability (`explorer/Reliability.tsx`, worked out by `reports/reliability` from the history the page
|
|
4003
|
+
already holds). Never show a bare percentage: it always comes with the number of independent executions it rests on, the
|
|
4004
|
+
"Insufficient evidence" badge below the minimum (one pass is not established reliability), the scope (environment,
|
|
4005
|
+
producer, branch, parameters, time window, spec revision) and the warning notes (pooled environments, failed cases
|
|
4006
|
+
published again, bounded history). First-try success is over executions that recorded their tries only; a result that
|
|
4007
|
+
did not run or did not finish is excluded by name and never counted as a pass. The scope and the open executions table
|
|
4008
|
+
are in the address (`rel*`), so a link reproduces the figure and the executions behind it.
|
|
4009
|
+
|
|
4010
|
+
## Product latency
|
|
4011
|
+
|
|
4012
|
+
A test's duration and its product latency are different things and the viewer never mixes them (`explorer/ProductLatency.tsx`,
|
|
4013
|
+
`@crvouga/atlas/reports/latency`). Statistics and the trend are labelled test execution time. Product latency is read only from
|
|
4014
|
+
measurements named `product-latency`; it shows boundaries, group (device, build, day), samples, budget and breaches, and a
|
|
4015
|
+
baseline comparison that lists changes of instrumentation or conditions. Percentiles and product claims that the evidence
|
|
4016
|
+
cannot support are shown as `Withheld` with the reason, a partial interval is badged, timeouts count as samples and breaches,
|
|
4017
|
+
and a test with no latency says it is unknown, not fast.
|
|
4018
|
+
|
|
3939
4019
|
## Outcome summary
|
|
3940
4020
|
|
|
3941
4021
|
A test or behavior detail states what the **selected** result says apart from what the other current sources say
|
|
@@ -4019,7 +4099,7 @@ The narrowly scoped exceptions are:
|
|
|
4019
4099
|
| --- | --- | --- |
|
|
4020
4100
|
| Shared shell | Project switching, spec navigation, run selection, connection status, diagnostics, mobile index | AppShell, Burger, NavLink, Menu, Popover, NativeSelect, Drawer |
|
|
4021
4101
|
| Project home | Tests/runs/artifacts tabs, a run's Artifacts (files of its layers, shared recordings, direct links), metrics, search, status/environment/domain/artifact-tag filters, run and artifact facets with saved views, grouping, sorting, show more | Container, Tabs, SimpleGrid, Paper, TextInput, MultiSelect, Popover, Button, Accordion |
|
|
4022
|
-
| Test detail | Current outcomes, statistics, duration graph, history, artifacts, recording; the `layer` address parameter pins it to one run's result, labelled "This run" against "Latest combined evidence" | Drawer, Table, Badge, Alert, Stage |
|
|
4102
|
+
| Test detail | Current outcomes, statistics, duration graph, product latency with budgets and baselines, history, artifacts, recording; the `layer` address parameter pins it to one run's result, labelled "This run" against "Latest combined evidence" | Drawer, Table, Badge, Alert, Stage |
|
|
4023
4103
|
| Specs | All six existing kinds, overview/index with title search and folder or declared-domain grouping, Gherkin rules/scenarios/examples with a coverage summary and Read / Watch / Inspect per behavior, Quint declarations/traces, DMN tables, source text | SpecHeader, Accordion, Tabs, Table, CodeHighlightTabs, ResultRow |
|
|
4024
4104
|
| Statecharts | Graph, screen/event/journey details, developer metadata, chart test results | Mantine cards/navigation and product compositions; graph exception above |
|
|
4025
4105
|
| Evidence | Steps, retries, annotations, facts, unknown extensions, safe downloads and previews | List, Badge, Accordion, Code, Image, native media |
|
|
@@ -5156,6 +5236,54 @@ Scoped to one project. The same project may be selected on the unprefixed API us
|
|
|
5156
5236
|
|
|
5157
5237
|
Responses: `200` The test and its history.; `304` Unchanged since the `If-None-Match` ETag.; `400` No `key`.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `404` No test in the report has that key.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
|
|
5158
5238
|
|
|
5239
|
+
### How reliable one test is in a scope, and how that was counted
|
|
5240
|
+
|
|
5241
|
+
`GET /api/reports/tests/reliability` · role: read
|
|
5242
|
+
|
|
5243
|
+
A success rate for one test that says what it counted. The snapshots one run recorded for one producer, environment and parameter set (running, finished, enriched) are one independent execution; its last word counts once with the tries it recorded. `eventual` is the share of executions that passed in the end, `firstAttempt` the share whose first try passed (over executions that recorded their tries; the rest are `unrecordedAttempts`, never assumed to have passed first time).
|
|
5244
|
+
|
|
5245
|
+
Choose the scope with `environment`, `producer`, `parameter` (`key=value`), `branch`, `sha`, `specRevision`, `since` and `until`; executions elsewhere never count. By default only the newest recorded spec revision counts and earlier ones appear under `historical`; send `revision=any` to pool them. Only `passed` and `failed` executions are trials: `not-run` and unfinished ones are listed under `excluded` and never counted as a pass. `sample` is `none`, `insufficient` (fewer than `minimumExecutions`) or `sufficient`, a count only: `notes` say when environments, producers or branches are pooled, failed cases were published again, or history is bounded to the newest 100 results. `executions` is the denominator, open to inspection. The interval states its assumptions. This is not a production failure probability. Send `format=markdown` for Markdown.
|
|
5246
|
+
|
|
5247
|
+
- `key` (query, required): The test's `key` from `/api/reports/tests`.
|
|
5248
|
+
- `environment` (query): Environments or devices to count. Comma-separated.
|
|
5249
|
+
- `producer` (query): Producers to count. Comma-separated.
|
|
5250
|
+
- `parameter` (query): Parameter choices `key=value`; all must match. Comma-separated.
|
|
5251
|
+
- `branch` (query): Branches to count. Comma-separated.
|
|
5252
|
+
- `sha` (query): Commits: a full id or a prefix of at least seven characters. Comma-separated.
|
|
5253
|
+
- `specRevision` (query): Only executions recorded against these spec fingerprints (overrides `revision`). Comma-separated.
|
|
5254
|
+
- `revision` (query): `any` pools every spec revision; otherwise only the newest recorded one counts.
|
|
5255
|
+
- `since` (query): Only executions at or after this time: epoch milliseconds or a date.
|
|
5256
|
+
- `until` (query): Only executions at or before this time: epoch milliseconds or a date.
|
|
5257
|
+
- `format` (query): `markdown` for Markdown instead of JSON.
|
|
5258
|
+
- `project` (query): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
|
|
5259
|
+
|
|
5260
|
+
Responses: `200` The reliability of the test in the scope.; `304` Unchanged since the `If-None-Match` ETag.; `400` No `key`.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `404` No test in the report has that key.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
|
|
5261
|
+
|
|
5262
|
+
### How reliable one test is in a scope, and how that was counted
|
|
5263
|
+
|
|
5264
|
+
`GET /api/projects/{project}/reports/tests/reliability` · role: read
|
|
5265
|
+
|
|
5266
|
+
A success rate for one test that says what it counted. The snapshots one run recorded for one producer, environment and parameter set (running, finished, enriched) are one independent execution; its last word counts once with the tries it recorded. `eventual` is the share of executions that passed in the end, `firstAttempt` the share whose first try passed (over executions that recorded their tries; the rest are `unrecordedAttempts`, never assumed to have passed first time).
|
|
5267
|
+
|
|
5268
|
+
Choose the scope with `environment`, `producer`, `parameter` (`key=value`), `branch`, `sha`, `specRevision`, `since` and `until`; executions elsewhere never count. By default only the newest recorded spec revision counts and earlier ones appear under `historical`; send `revision=any` to pool them. Only `passed` and `failed` executions are trials: `not-run` and unfinished ones are listed under `excluded` and never counted as a pass. `sample` is `none`, `insufficient` (fewer than `minimumExecutions`) or `sufficient`, a count only: `notes` say when environments, producers or branches are pooled, failed cases were published again, or history is bounded to the newest 100 results. `executions` is the denominator, open to inspection. The interval states its assumptions. This is not a production failure probability. Send `format=markdown` for Markdown.
|
|
5269
|
+
|
|
5270
|
+
Scoped to one project. The same project may be selected on the unprefixed API using ?project= or X-Atlas-Project. Unknown projects return 404 on reads and are created by an authenticated upload.
|
|
5271
|
+
|
|
5272
|
+
- `project` (path, required): Project slug. Alternatively send X-Atlas-Project or use the project-prefixed route. Omit for the default project. Conflicting selectors are refused.
|
|
5273
|
+
- `key` (query, required): The test's `key` from `/api/reports/tests`.
|
|
5274
|
+
- `environment` (query): Environments or devices to count. Comma-separated.
|
|
5275
|
+
- `producer` (query): Producers to count. Comma-separated.
|
|
5276
|
+
- `parameter` (query): Parameter choices `key=value`; all must match. Comma-separated.
|
|
5277
|
+
- `branch` (query): Branches to count. Comma-separated.
|
|
5278
|
+
- `sha` (query): Commits: a full id or a prefix of at least seven characters. Comma-separated.
|
|
5279
|
+
- `specRevision` (query): Only executions recorded against these spec fingerprints (overrides `revision`). Comma-separated.
|
|
5280
|
+
- `revision` (query): `any` pools every spec revision; otherwise only the newest recorded one counts.
|
|
5281
|
+
- `since` (query): Only executions at or after this time: epoch milliseconds or a date.
|
|
5282
|
+
- `until` (query): Only executions at or before this time: epoch milliseconds or a date.
|
|
5283
|
+
- `format` (query): `markdown` for Markdown instead of JSON.
|
|
5284
|
+
|
|
5285
|
+
Responses: `200` The reliability of the test in the scope.; `304` Unchanged since the `If-None-Match` ETag.; `400` No `key`.; `401` No token, or an unknown one. Send `Authorization: Bearer <token>`.; `404` No test in the report has that key.; `503` The server is still reading its backends. Retry after the number of seconds in `Retry-After`.
|
|
5286
|
+
|
|
5159
5287
|
### Reviewer tags of attachments: every recorded edit
|
|
5160
5288
|
|
|
5161
5289
|
`GET /api/reports/artifact-tags` · role: read
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crvouga/atlas",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Atlas: specs of any kind, reported as layered evidence. Publish checks from any runner (JUnit, CTRF, a script), combine them across nodes, branches, environments and backends, gate CI on the result, and run statecharts against the real app.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -56,8 +56,63 @@
|
|
|
56
56
|
"type": "string"
|
|
57
57
|
},
|
|
58
58
|
"limit": {
|
|
59
|
-
"description": "The allowance. A measurement over it is reported, and never fails the check by itself",
|
|
59
|
+
"description": "The allowance, or budget. A measurement over it is reported, and never fails the check by itself",
|
|
60
60
|
"type": "number"
|
|
61
|
+
},
|
|
62
|
+
"kind": {
|
|
63
|
+
"description": "What the number is, in an open vocabulary. `product-latency`: a user-visible response time between `from` and `to`. Absent: just a number, never read as product latency",
|
|
64
|
+
"type": "string",
|
|
65
|
+
"minLength": 1
|
|
66
|
+
},
|
|
67
|
+
"from": {
|
|
68
|
+
"description": "The event the interval starts at. Without both `from` and `to` a latency is shown but no product claim is made from it",
|
|
69
|
+
"type": "string",
|
|
70
|
+
"minLength": 1
|
|
71
|
+
},
|
|
72
|
+
"to": {
|
|
73
|
+
"description": "The event the interval ends at",
|
|
74
|
+
"type": "string",
|
|
75
|
+
"minLength": 1
|
|
76
|
+
},
|
|
77
|
+
"intended": {
|
|
78
|
+
"description": "The interval the name of the measurement claims, when what was measured is only part of it. If `intended.to` differs from `to` (or `intended.from` from `from`) the measurement is shown as partial, never as the complete interval",
|
|
79
|
+
"type": "object",
|
|
80
|
+
"properties": {
|
|
81
|
+
"from": {
|
|
82
|
+
"description": "The event the interval starts at: `end of speech`, `submit pressed`",
|
|
83
|
+
"type": "string",
|
|
84
|
+
"minLength": 1
|
|
85
|
+
},
|
|
86
|
+
"to": {
|
|
87
|
+
"description": "The event the interval ends at: `audible response`, `confirmation visible`",
|
|
88
|
+
"type": "string",
|
|
89
|
+
"minLength": 1
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"additionalProperties": {}
|
|
93
|
+
},
|
|
94
|
+
"source": {
|
|
95
|
+
"description": "How it was measured: `app-instrumentation`, `trace`, `recording-analysis`",
|
|
96
|
+
"type": "string"
|
|
97
|
+
},
|
|
98
|
+
"outcome": {
|
|
99
|
+
"description": "`observed` (the default), `timeout` or `failed`. For anything but `observed` the value is how long the observation waited: at least that much, so it counts against a budget and is never dropped",
|
|
100
|
+
"type": "string",
|
|
101
|
+
"minLength": 1
|
|
102
|
+
},
|
|
103
|
+
"instrumentation": {
|
|
104
|
+
"description": "The version or method of the measurement. A change of it between two sets of observations is disclosed when they are compared",
|
|
105
|
+
"type": "string"
|
|
106
|
+
},
|
|
107
|
+
"labels": {
|
|
108
|
+
"description": "What the observation is comparable with: `device`, `build`, `network`. `device` and `build` group the observations and, when two groups differ in the others, the comparison says so",
|
|
109
|
+
"type": "object",
|
|
110
|
+
"propertyNames": {
|
|
111
|
+
"type": "string"
|
|
112
|
+
},
|
|
113
|
+
"additionalProperties": {
|
|
114
|
+
"type": "string"
|
|
115
|
+
}
|
|
61
116
|
}
|
|
62
117
|
},
|
|
63
118
|
"required": [
|
|
@@ -57,16 +57,74 @@
|
|
|
57
57
|
"type": "object",
|
|
58
58
|
"properties": {
|
|
59
59
|
"name": {
|
|
60
|
-
"type": "string"
|
|
60
|
+
"type": "string",
|
|
61
|
+
"minLength": 1
|
|
61
62
|
},
|
|
62
63
|
"value": {
|
|
63
|
-
"type": "number"
|
|
64
|
+
"type": "number",
|
|
65
|
+
"description": "A finite number"
|
|
64
66
|
},
|
|
65
67
|
"unit": {
|
|
66
68
|
"type": "string"
|
|
67
69
|
},
|
|
68
70
|
"limit": {
|
|
71
|
+
"description": "The allowance, or budget. A measurement over it is reported, and never fails the check by itself",
|
|
69
72
|
"type": "number"
|
|
73
|
+
},
|
|
74
|
+
"kind": {
|
|
75
|
+
"description": "What the number is, in an open vocabulary. `product-latency`: a user-visible response time between `from` and `to`. Absent: just a number, never read as product latency",
|
|
76
|
+
"type": "string",
|
|
77
|
+
"minLength": 1
|
|
78
|
+
},
|
|
79
|
+
"from": {
|
|
80
|
+
"description": "The event the interval starts at. Without both `from` and `to` a latency is shown but no product claim is made from it",
|
|
81
|
+
"type": "string",
|
|
82
|
+
"minLength": 1
|
|
83
|
+
},
|
|
84
|
+
"to": {
|
|
85
|
+
"description": "The event the interval ends at",
|
|
86
|
+
"type": "string",
|
|
87
|
+
"minLength": 1
|
|
88
|
+
},
|
|
89
|
+
"intended": {
|
|
90
|
+
"description": "The interval the name of the measurement claims, when what was measured is only part of it. If `intended.to` differs from `to` (or `intended.from` from `from`) the measurement is shown as partial, never as the complete interval",
|
|
91
|
+
"type": "object",
|
|
92
|
+
"properties": {
|
|
93
|
+
"from": {
|
|
94
|
+
"description": "The event the interval starts at: `end of speech`, `submit pressed`",
|
|
95
|
+
"type": "string",
|
|
96
|
+
"minLength": 1
|
|
97
|
+
},
|
|
98
|
+
"to": {
|
|
99
|
+
"description": "The event the interval ends at: `audible response`, `confirmation visible`",
|
|
100
|
+
"type": "string",
|
|
101
|
+
"minLength": 1
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"additionalProperties": {}
|
|
105
|
+
},
|
|
106
|
+
"source": {
|
|
107
|
+
"description": "How it was measured: `app-instrumentation`, `trace`, `recording-analysis`",
|
|
108
|
+
"type": "string"
|
|
109
|
+
},
|
|
110
|
+
"outcome": {
|
|
111
|
+
"description": "`observed` (the default), `timeout` or `failed`. For anything but `observed` the value is how long the observation waited: at least that much, so it counts against a budget and is never dropped",
|
|
112
|
+
"type": "string",
|
|
113
|
+
"minLength": 1
|
|
114
|
+
},
|
|
115
|
+
"instrumentation": {
|
|
116
|
+
"description": "The version or method of the measurement. A change of it between two sets of observations is disclosed when they are compared",
|
|
117
|
+
"type": "string"
|
|
118
|
+
},
|
|
119
|
+
"labels": {
|
|
120
|
+
"description": "What the observation is comparable with: `device`, `build`, `network`. `device` and `build` group the observations and, when two groups differ in the others, the comparison says so",
|
|
121
|
+
"type": "object",
|
|
122
|
+
"propertyNames": {
|
|
123
|
+
"type": "string"
|
|
124
|
+
},
|
|
125
|
+
"additionalProperties": {
|
|
126
|
+
"type": "string"
|
|
127
|
+
}
|
|
70
128
|
}
|
|
71
129
|
},
|
|
72
130
|
"required": [
|
|
@@ -121,6 +179,19 @@
|
|
|
121
179
|
"minimum": 0,
|
|
122
180
|
"maximum": 9007199254740991
|
|
123
181
|
},
|
|
182
|
+
"attemptStatuses": {
|
|
183
|
+
"description": "The status of each recorded try, in the order they were made. Absent when no try was recorded, and in reports written before this was recorded: a first try is then unknown, never assumed to have passed",
|
|
184
|
+
"type": "array",
|
|
185
|
+
"items": {
|
|
186
|
+
"type": "string",
|
|
187
|
+
"enum": [
|
|
188
|
+
"passed",
|
|
189
|
+
"failed",
|
|
190
|
+
"running",
|
|
191
|
+
"not-run"
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
},
|
|
124
195
|
"links": {
|
|
125
196
|
"type": "integer",
|
|
126
197
|
"minimum": 0,
|
|
@@ -514,6 +585,19 @@
|
|
|
514
585
|
"minimum": 0,
|
|
515
586
|
"maximum": 9007199254740991
|
|
516
587
|
},
|
|
588
|
+
"attemptStatuses": {
|
|
589
|
+
"description": "The status of each recorded try, in the order they were made. Absent when no try was recorded, and in reports written before this was recorded: a first try is then unknown, never assumed to have passed",
|
|
590
|
+
"type": "array",
|
|
591
|
+
"items": {
|
|
592
|
+
"type": "string",
|
|
593
|
+
"enum": [
|
|
594
|
+
"passed",
|
|
595
|
+
"failed",
|
|
596
|
+
"running",
|
|
597
|
+
"not-run"
|
|
598
|
+
]
|
|
599
|
+
}
|
|
600
|
+
},
|
|
517
601
|
"links": {
|
|
518
602
|
"type": "integer",
|
|
519
603
|
"minimum": 0,
|