executable-stories-formatters 1.4.0 → 1.5.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/dist/cli.js +1254 -356
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +292 -144
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +292 -144
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/schemas/raw-run.schema.json +427 -106
- package/templates/astro-thin/astro.config.mjs +6 -22
- package/templates/astro-thin/executable-stories.config.mjs +5 -0
- package/templates/astro-thin/reports/sample-run.json +108 -27
- package/templates/astro-thin/src/content/docs/guides/writing-docs.mdx +51 -0
- package/templates/astro-thin/src/content/docs/index.mdx +7 -0
|
@@ -17,28 +17,12 @@ export default defineConfig({
|
|
|
17
17
|
// Set this to your deployed URL to enable canonical links + the sitemap
|
|
18
18
|
// Starlight ships (otherwise `astro build` prints a harmless sitemap notice).
|
|
19
19
|
// site: 'https://docs.example.com',
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// the island unhydrated and the page rendered as unstyled SSR fallback.
|
|
27
|
-
// If you add your OWN React islands, add their heavy deps to `include` too.
|
|
28
|
-
optimizeDeps: {
|
|
29
|
-
include: [
|
|
30
|
-
'react',
|
|
31
|
-
'react-dom',
|
|
32
|
-
'react-dom/client',
|
|
33
|
-
'react/jsx-runtime',
|
|
34
|
-
'executable-stories-react',
|
|
35
|
-
'executable-stories-react/interactive',
|
|
36
|
-
],
|
|
37
|
-
noDiscovery: true,
|
|
38
|
-
},
|
|
39
|
-
// Keep a single React copy so hooks/context work across the island boundary.
|
|
40
|
-
resolve: { dedupe: ['react', 'react-dom'] },
|
|
41
|
-
},
|
|
20
|
+
|
|
21
|
+
// No vite tuning needed here: the integration pre-bundles React + the report
|
|
22
|
+
// components (optimizeDeps) and dedupes React itself, so fixes ship with
|
|
23
|
+
// `pnpm update executable-stories-astro`. If you add your OWN React islands,
|
|
24
|
+
// list their heavy deps in a `vite.optimizeDeps.include` of your own — it
|
|
25
|
+
// merges with the integration's list.
|
|
42
26
|
integrations: [
|
|
43
27
|
// React renderer for the report islands — must come before executableStories.
|
|
44
28
|
react(),
|
|
@@ -44,4 +44,9 @@ export default defineExecutableStories({
|
|
|
44
44
|
// Starlight, and falls back to standalone pages otherwise. Force it with
|
|
45
45
|
// 'starlight' or 'standalone' if you embed the integration in your own site.
|
|
46
46
|
// shell: 'auto',
|
|
47
|
+
|
|
48
|
+
// Agent-readable endpoints (on by default): /llms.txt indexes every scenario
|
|
49
|
+
// and each story page gets a plain-Markdown twin at /stories/<slug>.md, so
|
|
50
|
+
// the deployed site is consumable by agents/curl, not just browsers.
|
|
51
|
+
// agentEndpoints: true,
|
|
47
52
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"$schema": "https://executable-stories.dev/schemas/raw-run.schema.json",
|
|
3
|
+
"schemaVersion": 1,
|
|
3
4
|
"projectRoot": "/sample",
|
|
4
5
|
"startedAtMs": 0,
|
|
5
6
|
"finishedAtMs": 1234,
|
|
@@ -13,12 +14,26 @@
|
|
|
13
14
|
"durationMs": 41,
|
|
14
15
|
"story": {
|
|
15
16
|
"scenario": "A returning customer checks out with a saved card",
|
|
16
|
-
"tags": [
|
|
17
|
-
|
|
17
|
+
"tags": [
|
|
18
|
+
"checkout",
|
|
19
|
+
"payments"
|
|
20
|
+
],
|
|
21
|
+
"covers": [
|
|
22
|
+
"src/checkout/**"
|
|
23
|
+
],
|
|
18
24
|
"steps": [
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
{
|
|
26
|
+
"keyword": "Given",
|
|
27
|
+
"text": "a signed-in customer with a saved card"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"keyword": "And",
|
|
31
|
+
"text": "a basket worth \u00a342.00"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"keyword": "When",
|
|
35
|
+
"text": "they confirm the order"
|
|
36
|
+
},
|
|
22
37
|
{
|
|
23
38
|
"keyword": "Then",
|
|
24
39
|
"text": "the payment is captured and an order id is returned",
|
|
@@ -27,8 +42,24 @@
|
|
|
27
42
|
"kind": "table",
|
|
28
43
|
"phase": "runtime",
|
|
29
44
|
"label": "Captured payment",
|
|
30
|
-
"columns": [
|
|
31
|
-
|
|
45
|
+
"columns": [
|
|
46
|
+
"Field",
|
|
47
|
+
"Value"
|
|
48
|
+
],
|
|
49
|
+
"rows": [
|
|
50
|
+
[
|
|
51
|
+
"amount",
|
|
52
|
+
"\u00a342.00"
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
"status",
|
|
56
|
+
"captured"
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
"order",
|
|
60
|
+
"ord_1A2B"
|
|
61
|
+
]
|
|
62
|
+
]
|
|
32
63
|
}
|
|
33
64
|
]
|
|
34
65
|
}
|
|
@@ -48,16 +79,35 @@
|
|
|
48
79
|
"sourceLine": 34,
|
|
49
80
|
"status": "fail",
|
|
50
81
|
"durationMs": 28,
|
|
51
|
-
"error": {
|
|
82
|
+
"error": {
|
|
83
|
+
"message": "Expected order to be created, but payment was declined (card_declined)"
|
|
84
|
+
},
|
|
52
85
|
"story": {
|
|
53
86
|
"scenario": "Checkout is blocked when the card is declined",
|
|
54
|
-
"tags": [
|
|
55
|
-
|
|
87
|
+
"tags": [
|
|
88
|
+
"checkout",
|
|
89
|
+
"payments"
|
|
90
|
+
],
|
|
91
|
+
"covers": [
|
|
92
|
+
"src/checkout/**"
|
|
93
|
+
],
|
|
56
94
|
"steps": [
|
|
57
|
-
{
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
95
|
+
{
|
|
96
|
+
"keyword": "Given",
|
|
97
|
+
"text": "a customer whose card will be declined"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"keyword": "When",
|
|
101
|
+
"text": "they confirm the order"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"keyword": "Then",
|
|
105
|
+
"text": "they see a clear decline message"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"keyword": "But",
|
|
109
|
+
"text": "no order is created"
|
|
110
|
+
}
|
|
61
111
|
]
|
|
62
112
|
}
|
|
63
113
|
},
|
|
@@ -69,10 +119,18 @@
|
|
|
69
119
|
"durationMs": 0,
|
|
70
120
|
"story": {
|
|
71
121
|
"scenario": "Gift wrapping is offered above the free-wrap threshold",
|
|
72
|
-
"tags": [
|
|
122
|
+
"tags": [
|
|
123
|
+
"checkout"
|
|
124
|
+
],
|
|
73
125
|
"steps": [
|
|
74
|
-
{
|
|
75
|
-
|
|
126
|
+
{
|
|
127
|
+
"keyword": "Given",
|
|
128
|
+
"text": "a basket above the free-wrap threshold"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"keyword": "Then",
|
|
132
|
+
"text": "free gift wrapping is offered"
|
|
133
|
+
}
|
|
76
134
|
]
|
|
77
135
|
}
|
|
78
136
|
},
|
|
@@ -84,11 +142,21 @@
|
|
|
84
142
|
"durationMs": 17,
|
|
85
143
|
"story": {
|
|
86
144
|
"scenario": "Search ranks exact title matches first",
|
|
87
|
-
"tags": [
|
|
88
|
-
|
|
145
|
+
"tags": [
|
|
146
|
+
"search"
|
|
147
|
+
],
|
|
148
|
+
"covers": [
|
|
149
|
+
"src/search/**"
|
|
150
|
+
],
|
|
89
151
|
"steps": [
|
|
90
|
-
{
|
|
91
|
-
|
|
152
|
+
{
|
|
153
|
+
"keyword": "Given",
|
|
154
|
+
"text": "products titled 'Wireless Mouse' and 'Mouse Pad'"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"keyword": "When",
|
|
158
|
+
"text": "the shopper searches for 'mouse'"
|
|
159
|
+
},
|
|
92
160
|
{
|
|
93
161
|
"keyword": "Then",
|
|
94
162
|
"text": "the exact title match is ranked first",
|
|
@@ -120,12 +188,25 @@
|
|
|
120
188
|
"durationMs": 23,
|
|
121
189
|
"story": {
|
|
122
190
|
"scenario": "Search tolerates a single typo",
|
|
123
|
-
"tags": [
|
|
124
|
-
|
|
191
|
+
"tags": [
|
|
192
|
+
"search"
|
|
193
|
+
],
|
|
194
|
+
"covers": [
|
|
195
|
+
"src/search/**"
|
|
196
|
+
],
|
|
125
197
|
"steps": [
|
|
126
|
-
{
|
|
127
|
-
|
|
128
|
-
|
|
198
|
+
{
|
|
199
|
+
"keyword": "Given",
|
|
200
|
+
"text": "a product titled 'Keyboard'"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"keyword": "When",
|
|
204
|
+
"text": "the shopper searches for 'keybord'"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"keyword": "Then",
|
|
208
|
+
"text": "the product is still found"
|
|
209
|
+
}
|
|
129
210
|
]
|
|
130
211
|
}
|
|
131
212
|
}
|
|
@@ -5,3 +5,54 @@ title: Writing docs
|
|
|
5
5
|
Add your own `.mdx` files under `src/content/docs/` — they appear in the sidebar
|
|
6
6
|
alongside the generated Stories. The generated pages are derived from tests and
|
|
7
7
|
are never written to disk, so you can't accidentally edit them into a lie.
|
|
8
|
+
|
|
9
|
+
## Embed live scenarios in your own pages
|
|
10
|
+
|
|
11
|
+
Your hand-written pages can pull scenarios in as live evidence — rendered from
|
|
12
|
+
the latest test run, so the embedded card can never drift from reality:
|
|
13
|
+
|
|
14
|
+
```mdx
|
|
15
|
+
---
|
|
16
|
+
title: Discount policy
|
|
17
|
+
---
|
|
18
|
+
import StoryScenario from 'executable-stories-astro/components/StoryScenario.astro';
|
|
19
|
+
import StoryStatus from 'executable-stories-astro/components/StoryStatus.astro';
|
|
20
|
+
|
|
21
|
+
We cap discounts at 30% — enforced end-to-end
|
|
22
|
+
(currently <StoryStatus id="checkout--caps-the-discount-at-30-percent" />):
|
|
23
|
+
|
|
24
|
+
<StoryScenario id="checkout--caps-the-discount-at-30-percent" />
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- `<StoryScenario id="…" />` embeds the full scenario card — steps, status,
|
|
28
|
+
failure output, and any docs the test attached.
|
|
29
|
+
- `<StoryStatus id="…" />` is an inline status pill linked to the story page,
|
|
30
|
+
for referencing evidence mid-sentence.
|
|
31
|
+
- `id` accepts the stable scenario id (copy it from the **Explorer** page), the
|
|
32
|
+
URL slug, or the exact title. An id that no longer matches renders a visible
|
|
33
|
+
callout — embedded evidence never silently disappears.
|
|
34
|
+
|
|
35
|
+
## Prove a page is still true
|
|
36
|
+
|
|
37
|
+
Declare which stories verify a page in its frontmatter and render a live badge:
|
|
38
|
+
|
|
39
|
+
```mdx
|
|
40
|
+
---
|
|
41
|
+
title: ADR 0007 — cap discount at 30%
|
|
42
|
+
verifiedBy: [checkout--caps-the-discount-at-30-percent]
|
|
43
|
+
---
|
|
44
|
+
import VerifiedBy from 'executable-stories-astro/components/VerifiedBy.astro';
|
|
45
|
+
|
|
46
|
+
<VerifiedBy refs={frontmatter.verifiedBy} />
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## For agents and tooling
|
|
50
|
+
|
|
51
|
+
The site also publishes machine-readable twins (on by default):
|
|
52
|
+
|
|
53
|
+
- `/llms.txt` — an index of every scenario with links to its Markdown form.
|
|
54
|
+
- `/stories/<slug>.md` — a plain-Markdown twin of each story page.
|
|
55
|
+
|
|
56
|
+
Point an agent at your deployed site's `/llms.txt` and it can read every
|
|
57
|
+
scenario without an HTML parser. Disable with `agentEndpoints: false` in
|
|
58
|
+
`executable-stories.config.mjs`.
|
|
@@ -35,6 +35,13 @@ the matching page change.
|
|
|
35
35
|
- **Trajectory** — pins a baseline when the dev server starts and shows what
|
|
36
36
|
changed *since you started this session* (e.g. "+2 passing, 1 regressed") — the
|
|
37
37
|
signal to watch while iterating in an agent loop.
|
|
38
|
+
- **[/llms.txt](/llms.txt)** — a machine-readable index of every scenario; each
|
|
39
|
+
story page also has a plain-Markdown twin at `/stories/<slug>.md`, so agents
|
|
40
|
+
can read the published site without an HTML parser.
|
|
41
|
+
|
|
42
|
+
Your own pages can embed scenarios as live evidence too — see
|
|
43
|
+
**[Writing docs](/guides/writing-docs/)** for `<StoryScenario/>` and
|
|
44
|
+
`<StoryStatus/>`.
|
|
38
45
|
|
|
39
46
|
## Wiring (one-time)
|
|
40
47
|
|