executable-stories-formatters 1.11.0 → 1.13.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/README.md +10 -0
- package/dist/adapters.cjs +17 -0
- package/dist/adapters.cjs.map +1 -1
- package/dist/adapters.d.cts +3 -1
- package/dist/adapters.d.ts +3 -1
- package/dist/adapters.js +17 -0
- package/dist/adapters.js.map +1 -1
- package/dist/cli.js +12227 -11022
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +9553 -9066
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +310 -168
- package/dist/index.d.ts +310 -168
- package/dist/index.js +9392 -8898
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/schemas/README.md +4 -0
- package/schemas/raw-run.schema.json +100 -0
- package/templates/astro-thin/executable-stories.config.mjs +11 -6
- package/templates/astro-thin/src/content/docs/index.mdx +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "executable-stories-formatters",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Cucumber-compatible report formats (HTML, Markdown, JUnit XML, Cucumber JSON) for executable-stories test results.",
|
|
5
5
|
"author": "Jag Reehal <jag@jagreehal.com>",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"yaml": "^2.9.0",
|
|
63
63
|
"react": "^19.2.7",
|
|
64
64
|
"react-dom": "^19.2.7",
|
|
65
|
-
"executable-stories-core": "0.
|
|
66
|
-
"executable-stories-react": "0.
|
|
65
|
+
"executable-stories-core": "0.21.0",
|
|
66
|
+
"executable-stories-react": "0.12.0"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@faker-js/faker": "^10.4.0",
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"scripts": {
|
|
81
81
|
"embed-assets": "node scripts/embed-react-assets.mjs",
|
|
82
82
|
"build": "node scripts/embed-react-assets.mjs && tsup",
|
|
83
|
+
"lint": "eslint .",
|
|
83
84
|
"test": "node scripts/embed-react-assets.mjs && vitest run",
|
|
84
85
|
"test:watch": "node scripts/embed-react-assets.mjs && vitest",
|
|
85
86
|
"type-check": "node scripts/embed-react-assets.mjs && tsc --noEmit",
|
package/schemas/README.md
CHANGED
|
@@ -81,6 +81,9 @@ The full schema is in [`raw-run.schema.json`](raw-run.schema.json). Here are the
|
|
|
81
81
|
| `gitSha` | `string` | No | Git commit SHA |
|
|
82
82
|
| `ci` | `RawCIInfo` | No | CI environment info (`name`, `url`, `buildNumber`) |
|
|
83
83
|
| `meta` | `object` | No | Arbitrary metadata (escape hatch) |
|
|
84
|
+
| `runScope` | `full \| filtered` | No | Whether the adapter knows the run covered whole source files or used a name filter |
|
|
85
|
+
| `coveredSourceFiles` | `string[]` | No | Every test source executed, including files that produced no scenarios |
|
|
86
|
+
| `incompleteSourceFiles` | `string[]` | No | Source files whose collection failed and must not retire earlier scenarios |
|
|
84
87
|
|
|
85
88
|
### RawTestCase
|
|
86
89
|
|
|
@@ -142,6 +145,7 @@ Emitters/converters should output these RawStatus values. Canonicalization norma
|
|
|
142
145
|
| `text` | `string` | Yes | Step description |
|
|
143
146
|
| `mode` | `normal \| skip \| only \| todo \| fails \| concurrent` | No | Execution mode |
|
|
144
147
|
| `docs` | `DocEntry[]` | No | Step-level documentation |
|
|
148
|
+
| `assertions` | `integer >= 0` | No | Assertions observed or declared for the step; absent means unknown, zero means observed none |
|
|
145
149
|
|
|
146
150
|
### DocEntry kinds
|
|
147
151
|
|
|
@@ -26,6 +26,13 @@
|
|
|
26
26
|
},
|
|
27
27
|
"description": "All test cases from the run."
|
|
28
28
|
},
|
|
29
|
+
"features": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"items": {
|
|
32
|
+
"$ref": "#/$defs/RawFeature"
|
|
33
|
+
},
|
|
34
|
+
"description": "Feature declarations from story.feature(...), keyed to their source files."
|
|
35
|
+
},
|
|
29
36
|
"startedAtMs": {
|
|
30
37
|
"type": "number",
|
|
31
38
|
"minimum": 0,
|
|
@@ -55,6 +62,28 @@
|
|
|
55
62
|
"meta": {
|
|
56
63
|
"type": "object",
|
|
57
64
|
"description": "Arbitrary runner-specific metadata. Escape hatch for data not covered by the schema."
|
|
65
|
+
},
|
|
66
|
+
"runScope": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"enum": [
|
|
69
|
+
"full",
|
|
70
|
+
"filtered"
|
|
71
|
+
],
|
|
72
|
+
"description": "How much of each source file this run covered. \"full\" means the adapter determined no name filter was applied, so the reported test cases are each file's complete set and a scenario missing from them may be retired. \"filtered\" means a name filter was applied (vitest -t, jest -t, playwright --grep), so the run saw only part of its own files. Omit when the adapter cannot tell: consumers then keep what the run did not report rather than deleting on a guess."
|
|
73
|
+
},
|
|
74
|
+
"coveredSourceFiles": {
|
|
75
|
+
"type": "array",
|
|
76
|
+
"items": {
|
|
77
|
+
"type": "string"
|
|
78
|
+
},
|
|
79
|
+
"description": "Source files this run executed, whether or not they produced test cases. A run's test cases only name files that produced something, so without this a file whose last scenario was deleted is indistinguishable from one that did not run. Optional."
|
|
80
|
+
},
|
|
81
|
+
"incompleteSourceFiles": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"items": {
|
|
84
|
+
"type": "string"
|
|
85
|
+
},
|
|
86
|
+
"description": "Source files whose scenarios could not be collected in full (a hook threw before the story was declared, a collection error, a crash). Such a file looks exactly like one whose scenarios were deleted, so it is never treated as authoritative however complete the rest of the run is."
|
|
58
87
|
}
|
|
59
88
|
},
|
|
60
89
|
"required": [
|
|
@@ -295,6 +324,11 @@
|
|
|
295
324
|
"type": "number",
|
|
296
325
|
"minimum": 0,
|
|
297
326
|
"description": "Step-level duration in milliseconds (from startTimer/endTimer)."
|
|
327
|
+
},
|
|
328
|
+
"assertions": {
|
|
329
|
+
"type": "integer",
|
|
330
|
+
"minimum": 0,
|
|
331
|
+
"description": "Assertions observed while this step ran. Omit when the adapter cannot observe assertions at all: absent means unknown, 0 means observed none."
|
|
298
332
|
}
|
|
299
333
|
},
|
|
300
334
|
"required": [
|
|
@@ -917,6 +951,72 @@
|
|
|
917
951
|
"name"
|
|
918
952
|
],
|
|
919
953
|
"additionalProperties": false
|
|
954
|
+
},
|
|
955
|
+
"RawFeature": {
|
|
956
|
+
"type": "object",
|
|
957
|
+
"description": "A feature declared in a test file: what it is for, in the words the business uses.",
|
|
958
|
+
"properties": {
|
|
959
|
+
"sourceFile": {
|
|
960
|
+
"type": "string",
|
|
961
|
+
"minLength": 1,
|
|
962
|
+
"description": "Source file the declaration was made in. Declarations without one are dropped."
|
|
963
|
+
},
|
|
964
|
+
"title": {
|
|
965
|
+
"type": "string",
|
|
966
|
+
"minLength": 1,
|
|
967
|
+
"description": "Heading for the feature."
|
|
968
|
+
},
|
|
969
|
+
"kind": {
|
|
970
|
+
"type": "string",
|
|
971
|
+
"enum": [
|
|
972
|
+
"feature",
|
|
973
|
+
"ability",
|
|
974
|
+
"business-need"
|
|
975
|
+
],
|
|
976
|
+
"description": "How to introduce the feature. Defaults to feature."
|
|
977
|
+
},
|
|
978
|
+
"narrative": {
|
|
979
|
+
"type": "string",
|
|
980
|
+
"description": "Markdown explaining why the feature exists and who it serves."
|
|
981
|
+
},
|
|
982
|
+
"tags": {
|
|
983
|
+
"type": "array",
|
|
984
|
+
"items": {
|
|
985
|
+
"type": "string"
|
|
986
|
+
},
|
|
987
|
+
"description": "Tags applied to every scenario in the file."
|
|
988
|
+
},
|
|
989
|
+
"glossary": {
|
|
990
|
+
"type": "array",
|
|
991
|
+
"items": {
|
|
992
|
+
"$ref": "#/$defs/RawGlossaryTerm"
|
|
993
|
+
},
|
|
994
|
+
"description": "Terms this feature defines."
|
|
995
|
+
}
|
|
996
|
+
},
|
|
997
|
+
"required": [
|
|
998
|
+
"title"
|
|
999
|
+
],
|
|
1000
|
+
"additionalProperties": false
|
|
1001
|
+
},
|
|
1002
|
+
"RawGlossaryTerm": {
|
|
1003
|
+
"type": "object",
|
|
1004
|
+
"description": "One glossary entry: a term the scenarios use and what it means.",
|
|
1005
|
+
"properties": {
|
|
1006
|
+
"term": {
|
|
1007
|
+
"type": "string",
|
|
1008
|
+
"minLength": 1
|
|
1009
|
+
},
|
|
1010
|
+
"definition": {
|
|
1011
|
+
"type": "string",
|
|
1012
|
+
"minLength": 1
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
1015
|
+
"required": [
|
|
1016
|
+
"term",
|
|
1017
|
+
"definition"
|
|
1018
|
+
],
|
|
1019
|
+
"additionalProperties": false
|
|
920
1020
|
}
|
|
921
1021
|
}
|
|
922
1022
|
}
|
|
@@ -5,12 +5,17 @@ import { defineExecutableStories } from 'executable-stories-astro';
|
|
|
5
5
|
* astro.config.mjs (route injection, nav, theme) and src/content.config.ts
|
|
6
6
|
* (the loaders) — so everything lives in one place.
|
|
7
7
|
*
|
|
8
|
-
* `source` points at the
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* `source` points at the directory of per-file reports your test run writes,
|
|
9
|
+
* one per test source file. Pointing at the directory rather than a single run
|
|
10
|
+
* JSON is what keeps the site showing your whole suite when you have only run
|
|
11
|
+
* part of it. Run your tests in watch mode + `astro dev` to hot-reload these
|
|
12
|
+
* pages; new test files appear without a restart.
|
|
13
|
+
*
|
|
14
|
+
* A single run JSON still works if you want only the last run:
|
|
15
|
+
* `source: '../reports/raw-run.json'`.
|
|
11
16
|
*/
|
|
12
17
|
export default defineExecutableStories({
|
|
13
|
-
source: process.env.ES_RUN_JSON ?? '../reports/
|
|
18
|
+
source: process.env.ES_RUN_JSON ?? '../reports/by-file',
|
|
14
19
|
|
|
15
20
|
// Shown only until your tests emit the run JSON above, so `astro dev` is
|
|
16
21
|
// populated on first run instead of empty. Replaced automatically the moment
|
|
@@ -28,8 +33,8 @@ export default defineExecutableStories({
|
|
|
28
33
|
|
|
29
34
|
// Combine several test suites in one site (optional):
|
|
30
35
|
// sources: [
|
|
31
|
-
// { name: 'web', label: 'Web app', source: '../apps/web/reports/
|
|
32
|
-
// { name: 'api', label: 'API', source: '../apps/api/reports/
|
|
36
|
+
// { name: 'web', label: 'Web app', source: '../apps/web/reports/by-file' },
|
|
37
|
+
// { name: 'api', label: 'API', source: '../apps/api/reports/by-file' },
|
|
33
38
|
// ],
|
|
34
39
|
|
|
35
40
|
// Audience lenses (optional): each view mounts a filtered, re-grouped index
|
|
@@ -13,7 +13,7 @@ pages are never written to disk, so they can't drift into a lie. Everything unde
|
|
|
13
13
|
Run two things side by side and leave them running:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
# Terminal 1 — your tests in watch mode (rewrites reports/
|
|
16
|
+
# Terminal 1 — your tests in watch mode (rewrites reports/by-file/ on every run)
|
|
17
17
|
pnpm test --watch # or: vitest, jest --watch, playwright --ui, …
|
|
18
18
|
|
|
19
19
|
# Terminal 2 — this docs site
|
|
@@ -46,6 +46,6 @@ Your own pages can embed scenarios as live evidence too — see
|
|
|
46
46
|
## Wiring (one-time)
|
|
47
47
|
|
|
48
48
|
The site reads the run JSON your test adapter writes. Point `source` in
|
|
49
|
-
`executable-stories.config.mjs` at it (default `../reports/
|
|
49
|
+
`executable-stories.config.mjs` at it (default `../reports/by-file`), and set
|
|
50
50
|
the matching `rawRunPath` in your StoryReporter config. That's the only wiring —
|
|
51
51
|
no per-test setup.
|