@swedevtools/livedoc-vitest 0.2.0 → 0.3.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 (35) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/LICENSE +20 -20
  3. package/README.md +160 -95
  4. package/dist/{RuleContext-BZhuy-zS.d.cts → RuleContext-DQ8o_n1D.d.ts} +62 -62
  5. package/dist/globals.d.ts +99 -99
  6. package/dist/{index-Blmp569T.d.cts → index-sbV15ohX.d.ts} +21 -2
  7. package/dist/index.d.ts +7 -5
  8. package/dist/index.js +1062 -159
  9. package/dist/reporter/index.d.ts +2 -2
  10. package/dist/reporter/index.js +629 -84
  11. package/package.json +14 -12
  12. package/tools/livedoc-setup.mjs +172 -164
  13. package/tools/skills/SKILL.md +339 -244
  14. package/tools/skills/VALIDATION.md +37 -29
  15. package/tools/skills/examples/routing.md +75 -60
  16. package/tools/skills/resources/anti-patterns.md +19 -0
  17. package/tools/skills/resources/bdd-features.md +231 -231
  18. package/tools/skills/resources/partial-testing.md +77 -0
  19. package/tools/skills/resources/playwright.md +148 -148
  20. package/tools/skills/resources/reporter-config.md +213 -163
  21. package/tools/skills/resources/specifications.md +159 -159
  22. package/tools/skills/resources/test-strategy.md +103 -0
  23. package/tools/skills/resources/web-testing.md +62 -0
  24. package/dist/RuleContext-BZhuy-zS.d.ts +0 -206
  25. package/dist/globals.cjs +0 -2
  26. package/dist/globals.d.cts +0 -104
  27. package/dist/index-CysiWbtk.d.ts +0 -687
  28. package/dist/index.cjs +0 -10024
  29. package/dist/index.d.cts +0 -291
  30. package/dist/playwright/index.cjs +0 -103
  31. package/dist/playwright/index.d.cts +0 -129
  32. package/dist/reporter/index.cjs +0 -8676
  33. package/dist/reporter/index.d.cts +0 -7
  34. package/dist/setup.cjs +0 -14
  35. package/dist/setup.d.cts +0 -2
@@ -1,231 +1,231 @@
1
- # BDD Features — Full Reference
2
-
3
- Complete reference for writing BDD/Gherkin-style tests with `@swedevtools/livedoc-vitest`.
4
-
5
- ## Keywords
6
-
7
- ```
8
- feature → scenario | scenarioOutline | background → given | when | then | and | but
9
- ```
10
-
11
- All blocks receive a `ctx` parameter with framework metadata.
12
-
13
- ## Import Block
14
-
15
- ```typescript
16
- import { feature, scenario, scenarioOutline, background, given, when, Then as then, and, but } from "@swedevtools/livedoc-vitest";
17
- ```
18
-
19
- **CRITICAL**: Import `Then` (uppercase) and alias as `then` (lowercase). ESM thenable detection requires the uppercase export name.
20
-
21
- ## Feature
22
-
23
- ```typescript
24
- feature("Shopping Cart", (ctx) => {
25
- // ctx.feature → { filename, title, description, tags }
26
- });
27
- ```
28
-
29
- ## Scenario
30
-
31
- ```typescript
32
- scenario("Adding items to cart", (ctx) => {
33
- // ctx.scenario → { title, description, tags, given?, steps }
34
- given("...", (ctx) => { /* ctx.step available */ });
35
- when("...", (ctx) => { /* ctx.step available */ });
36
- then("...", (ctx) => { /* ctx.step available */ });
37
- });
38
- ```
39
-
40
- ## Background
41
-
42
- Shared setup that runs before every scenario in a feature:
43
-
44
- ```typescript
45
- feature("User Dashboard", () => {
46
- background("Authenticated user", (ctx) => {
47
- given("the user is logged in", () => {
48
- user = await login();
49
- });
50
-
51
- // Optional cleanup — runs after each scenario
52
- ctx.afterBackground(() => {
53
- user = null;
54
- });
55
- });
56
-
57
- scenario("Viewing the dashboard", () => {
58
- // 'given' from background runs first
59
- when("...", () => { });
60
- then("...", () => { });
61
- });
62
- });
63
- ```
64
-
65
- **Note**: `background()` requires a title as the first argument.
66
-
67
- ## Descriptions and Tags
68
-
69
- Lines after the first line in titles provide descriptions and tags:
70
-
71
- ```typescript
72
- feature(`Shopping Cart Checkout
73
- @checkout @critical
74
- Business rules for the shopping cart checkout flow.
75
- Covers GST calculation, shipping tiers, and discount codes.
76
- `, (ctx) => {
77
-
78
- scenario(`Free shipping for large orders
79
- Orders over $100 qualify for free shipping in Australia.
80
- `, (ctx) => {
81
- // steps...
82
- });
83
- });
84
- ```
85
-
86
- - **First line** = title
87
- - **Lines starting with `@`** = tags (used for filtering)
88
- - **Remaining lines** = description (appears in output and reports)
89
-
90
- **Always add descriptions** to `feature` blocks for context. Optionally to `scenario` blocks.
91
-
92
- ## Value Extraction
93
-
94
- ### Quoted Values — auto-extracted, type-coerced
95
-
96
- ```typescript
97
- given("user has '100' items and active is 'true'", (ctx) => {
98
- const [count, isActive] = ctx.step.values;
99
- // count = 100 (number), isActive = true (boolean)
100
- });
101
- ```
102
-
103
- ### Named Parameters — `<name:value>` syntax
104
-
105
- ```typescript
106
- given("a user with <email:john@test.com> and <age:25>", (ctx) => {
107
- const email = ctx.step.params.email; // "john@test.com"
108
- const age = ctx.step.params.age; // 25
109
- });
110
- ```
111
-
112
- ### Data Tables
113
-
114
- ```typescript
115
- given(`users:
116
- | name | age |
117
- | Alice | 30 |
118
- | Bob | 25 |
119
- `, (ctx) => {
120
- // ctx.step.table => [{name: "Alice", age: 30}, {name: "Bob", age: 25}]
121
- // ctx.step.tableAsEntity => (2-col table as single object)
122
- // ctx.step.tableAsSingleList => (first column as flat array)
123
- // ctx.step.dataTable => (raw 2D array)
124
- });
125
- ```
126
-
127
- ### Doc Strings
128
-
129
- ```typescript
130
- given(`config:
131
- """
132
- {"debug": true, "level": 5}
133
- """
134
- `, (ctx) => {
135
- const raw = ctx.step.docString; // '{"debug": true, "level": 5}'
136
- const parsed = ctx.step.docStringAsEntity; // {debug: true, level: 5}
137
- });
138
- ```
139
-
140
- ## ScenarioOutline with Examples
141
-
142
- Data-driven scenarios. Each row in the Examples table creates a separate test:
143
-
144
- ```typescript
145
- scenarioOutline(`Validate inputs
146
- Examples:
147
- | input | expected |
148
- | foo | true |
149
- | bar | false |
150
- `, (ctx) => {
151
- when("checking <input>", (ctx) => {
152
- result = validate(ctx.example.input);
153
- });
154
- then("result is <expected>", (ctx) => {
155
- expect(result).toBe(ctx.example.expected);
156
- });
157
- });
158
- ```
159
-
160
- Access example data via `ctx.example.<columnName>`. Values are type-coerced.
161
-
162
- ## Step Attachment API
163
-
164
- Attach files, screenshots, and data to steps. Attachments appear in the LiveDoc Viewer.
165
-
166
- ```typescript
167
- // Attach JSON data
168
- ctx.step.attachJSON(data, "API Response");
169
-
170
- // Attach a screenshot (base64 PNG)
171
- ctx.step.attachScreenshot(base64Data, "Login Page");
172
-
173
- // Attach arbitrary data
174
- ctx.step.attach(base64Data, { mimeType: "image/png", kind: "image", title: "Chart" });
175
- ```
176
-
177
- **Methods:**
178
- - `attach(base64Data, options?)` — options: `{mimeType, kind: 'image'|'screenshot'|'file', title}`
179
- - `attachScreenshot(base64Data, title?)` — convenience for PNG screenshots
180
- - `attachJSON(data, title?)` — convenience for JSON data
181
-
182
- Read attachments: `ctx.step.attachments` (read-only array)
183
-
184
- ## Async Rules
185
-
186
- - **Only step callbacks support `async`** (`given`, `when`, `then`, `and`, `but`)
187
- - `feature`, `scenario`, `scenarioOutline`, `background` must be **synchronous**
188
-
189
- ```typescript
190
- when("data is fetched", async (ctx) => {
191
- result = await fetchData(); // ✅ OK
192
- });
193
-
194
- scenario("Test", async (ctx) => { /* ❌ NOT ALLOWED */ });
195
- ```
196
-
197
- ## Context Reference
198
-
199
- | Property | Type | Description |
200
- | --- | --- | --- |
201
- | `ctx.feature` | `FeatureContext` | `{filename, title, description, tags}` |
202
- | `ctx.scenario` | `ScenarioContext` | `{title, description, tags, given?, steps}` |
203
- | `ctx.step` | `StepContext` | `{title, type, values, docString, table, ...}` |
204
- | `ctx.example` | `object` | Current example row (scenarioOutline only) |
205
- | `ctx.background` | `BackgroundContext` | Background metadata |
206
- | `ctx.afterBackground(fn)` | function | Register cleanup (background only) |
207
-
208
- ### StepContext Properties
209
-
210
- | Property | Returns |
211
- | --- | --- |
212
- | `values` | Coerced quoted values array |
213
- | `valuesRaw` | Raw string values |
214
- | `params` | Coerced named values object `<n:v>` |
215
- | `paramsRaw` | Raw named values string object |
216
- | `docString` | Raw doc string content |
217
- | `docStringAsEntity` | Parsed JSON or undefined |
218
- | `table` | Headers as keys, array of row objects |
219
- | `tableAsEntity` | 2-col table as single object |
220
- | `tableAsSingleList` | First column as flat array |
221
- | `dataTable` | Raw 2D array |
222
- | `attachments` | Read-only `Attachment[]` |
223
-
224
- ## Validation Checklist
225
-
226
- - [ ] All test data appears in step title strings (self-documenting)
227
- - [ ] Descriptions provided on `feature` blocks for context
228
- - [ ] Values extracted via `ctx.step.values`, `ctx.step.params`, or `ctx.example`
229
- - [ ] `Then` imported as uppercase, aliased to lowercase `then`
230
- - [ ] Async only on step callbacks
231
- - [ ] File name ends in `.Spec.ts`
1
+ # BDD Features — Full Reference
2
+
3
+ Complete reference for writing BDD/Gherkin-style tests with `@swedevtools/livedoc-vitest`.
4
+
5
+ ## Keywords
6
+
7
+ ```
8
+ feature → scenario | scenarioOutline | background → given | when | then | and | but
9
+ ```
10
+
11
+ All blocks receive a `ctx` parameter with framework metadata.
12
+
13
+ ## Import Block
14
+
15
+ ```typescript
16
+ import { feature, scenario, scenarioOutline, background, given, when, Then as then, and, but } from "@swedevtools/livedoc-vitest";
17
+ ```
18
+
19
+ **CRITICAL**: Import `Then` (uppercase) and alias as `then` (lowercase). ESM thenable detection requires the uppercase export name.
20
+
21
+ ## Feature
22
+
23
+ ```typescript
24
+ feature("Shopping Cart", (ctx) => {
25
+ // ctx.feature → { filename, title, description, tags }
26
+ });
27
+ ```
28
+
29
+ ## Scenario
30
+
31
+ ```typescript
32
+ scenario("Adding items to cart", (ctx) => {
33
+ // ctx.scenario → { title, description, tags, given?, steps }
34
+ given("...", (ctx) => { /* ctx.step available */ });
35
+ when("...", (ctx) => { /* ctx.step available */ });
36
+ then("...", (ctx) => { /* ctx.step available */ });
37
+ });
38
+ ```
39
+
40
+ ## Background
41
+
42
+ Shared setup that runs before every scenario in a feature:
43
+
44
+ ```typescript
45
+ feature("User Dashboard", () => {
46
+ background("Authenticated user", (ctx) => {
47
+ given("the user is logged in", () => {
48
+ user = await login();
49
+ });
50
+
51
+ // Optional cleanup — runs after each scenario
52
+ ctx.afterBackground(() => {
53
+ user = null;
54
+ });
55
+ });
56
+
57
+ scenario("Viewing the dashboard", () => {
58
+ // 'given' from background runs first
59
+ when("...", () => { });
60
+ then("...", () => { });
61
+ });
62
+ });
63
+ ```
64
+
65
+ **Note**: `background()` requires a title as the first argument.
66
+
67
+ ## Descriptions and Tags
68
+
69
+ Lines after the first line in titles provide descriptions and tags:
70
+
71
+ ```typescript
72
+ feature(`Shopping Cart Checkout
73
+ @checkout @critical
74
+ Business rules for the shopping cart checkout flow.
75
+ Covers GST calculation, shipping tiers, and discount codes.
76
+ `, (ctx) => {
77
+
78
+ scenario(`Free shipping for large orders
79
+ Orders over $100 qualify for free shipping in Australia.
80
+ `, (ctx) => {
81
+ // steps...
82
+ });
83
+ });
84
+ ```
85
+
86
+ - **First line** = title
87
+ - **Lines starting with `@`** = tags (used for filtering)
88
+ - **Remaining lines** = description (appears in output and reports)
89
+
90
+ **Always add descriptions** to `feature` blocks for context. Optionally to `scenario` blocks.
91
+
92
+ ## Value Extraction
93
+
94
+ ### Quoted Values — auto-extracted, type-coerced
95
+
96
+ ```typescript
97
+ given("user has '100' items and active is 'true'", (ctx) => {
98
+ const [count, isActive] = ctx.step.values;
99
+ // count = 100 (number), isActive = true (boolean)
100
+ });
101
+ ```
102
+
103
+ ### Named Parameters — `<name:value>` syntax
104
+
105
+ ```typescript
106
+ given("a user with <email:john@test.com> and <age:25>", (ctx) => {
107
+ const email = ctx.step.params.email; // "john@test.com"
108
+ const age = ctx.step.params.age; // 25
109
+ });
110
+ ```
111
+
112
+ ### Data Tables
113
+
114
+ ```typescript
115
+ given(`users:
116
+ | name | age |
117
+ | Alice | 30 |
118
+ | Bob | 25 |
119
+ `, (ctx) => {
120
+ // ctx.step.table => [{name: "Alice", age: 30}, {name: "Bob", age: 25}]
121
+ // ctx.step.tableAsEntity => (2-col table as single object)
122
+ // ctx.step.tableAsSingleList => (first column as flat array)
123
+ // ctx.step.dataTable => (raw 2D array)
124
+ });
125
+ ```
126
+
127
+ ### Doc Strings
128
+
129
+ ```typescript
130
+ given(`config:
131
+ """
132
+ {"debug": true, "level": 5}
133
+ """
134
+ `, (ctx) => {
135
+ const raw = ctx.step.docString; // '{"debug": true, "level": 5}'
136
+ const parsed = ctx.step.docStringAsEntity; // {debug: true, level: 5}
137
+ });
138
+ ```
139
+
140
+ ## ScenarioOutline with Examples
141
+
142
+ Data-driven scenarios. Each row in the Examples table creates a separate test:
143
+
144
+ ```typescript
145
+ scenarioOutline(`Validate inputs
146
+ Examples:
147
+ | input | expected |
148
+ | foo | true |
149
+ | bar | false |
150
+ `, (ctx) => {
151
+ when("checking <input>", (ctx) => {
152
+ result = validate(ctx.example.input);
153
+ });
154
+ then("result is <expected>", (ctx) => {
155
+ expect(result).toBe(ctx.example.expected);
156
+ });
157
+ });
158
+ ```
159
+
160
+ Access example data via `ctx.example.<columnName>`. Values are type-coerced.
161
+
162
+ ## Step Attachment API
163
+
164
+ Attach files, screenshots, and data to steps. Attachments appear in the LiveDoc Viewer.
165
+
166
+ ```typescript
167
+ // Attach JSON data
168
+ ctx.step.attachJSON(data, "API Response");
169
+
170
+ // Attach a screenshot (base64 PNG)
171
+ ctx.step.attachScreenshot(base64Data, "Login Page");
172
+
173
+ // Attach arbitrary data
174
+ ctx.step.attach(base64Data, { mimeType: "image/png", kind: "image", title: "Chart" });
175
+ ```
176
+
177
+ **Methods:**
178
+ - `attach(base64Data, options?)` — options: `{mimeType, kind: 'image'|'screenshot'|'file', title}`
179
+ - `attachScreenshot(base64Data, title?)` — convenience for PNG screenshots
180
+ - `attachJSON(data, title?)` — convenience for JSON data
181
+
182
+ Read attachments: `ctx.step.attachments` (read-only array)
183
+
184
+ ## Async Rules
185
+
186
+ - **Only step callbacks support `async`** (`given`, `when`, `then`, `and`, `but`)
187
+ - `feature`, `scenario`, `scenarioOutline`, `background` must be **synchronous**
188
+
189
+ ```typescript
190
+ when("data is fetched", async (ctx) => {
191
+ result = await fetchData(); // ✅ OK
192
+ });
193
+
194
+ scenario("Test", async (ctx) => { /* ❌ NOT ALLOWED */ });
195
+ ```
196
+
197
+ ## Context Reference
198
+
199
+ | Property | Type | Description |
200
+ | --- | --- | --- |
201
+ | `ctx.feature` | `FeatureContext` | `{filename, title, description, tags}` |
202
+ | `ctx.scenario` | `ScenarioContext` | `{title, description, tags, given?, steps}` |
203
+ | `ctx.step` | `StepContext` | `{title, type, values, docString, table, ...}` |
204
+ | `ctx.example` | `object` | Current example row (scenarioOutline only) |
205
+ | `ctx.background` | `BackgroundContext` | Background metadata |
206
+ | `ctx.afterBackground(fn)` | function | Register cleanup (background only) |
207
+
208
+ ### StepContext Properties
209
+
210
+ | Property | Returns |
211
+ | --- | --- |
212
+ | `values` | Coerced quoted values array |
213
+ | `valuesRaw` | Raw string values |
214
+ | `params` | Coerced named values object `<n:v>` |
215
+ | `paramsRaw` | Raw named values string object |
216
+ | `docString` | Raw doc string content |
217
+ | `docStringAsEntity` | Parsed JSON or undefined |
218
+ | `table` | Headers as keys, array of row objects |
219
+ | `tableAsEntity` | 2-col table as single object |
220
+ | `tableAsSingleList` | First column as flat array |
221
+ | `dataTable` | Raw 2D array |
222
+ | `attachments` | Read-only `Attachment[]` |
223
+
224
+ ## Validation Checklist
225
+
226
+ - [ ] All test data appears in step title strings (self-documenting)
227
+ - [ ] Descriptions provided on `feature` blocks for context
228
+ - [ ] Values extracted via `ctx.step.values`, `ctx.step.params`, or `ctx.example`
229
+ - [ ] `Then` imported as uppercase, aliased to lowercase `then`
230
+ - [ ] Async only on step callbacks
231
+ - [ ] File name ends in `.Spec.ts`
@@ -0,0 +1,77 @@
1
+ # Tag-Scoped Partial Testing
2
+
3
+ Use tags as the primary selector for incremental validation. File paths and test
4
+ titles are fallback selectors when no stable capability tag exists.
5
+
6
+ ## Viewer Contract
7
+
8
+ 1. Publish at least one successful full run for the project and environment.
9
+ 2. Run the affected tags with `LIVEDOC_RUN_TYPE=partial`.
10
+ 3. The server stores the focused invocation and composes it over the latest full
11
+ baseline.
12
+ 4. The Viewer can show the Combined result or only that partial invocation.
13
+
14
+ Tests omitted from a partial invocation keep their baseline result. Partial runs
15
+ require server history and cannot be written directly as static JSON.
16
+
17
+ ## Configure a Tag Selector
18
+
19
+ LiveDoc Vitest exposes tag filters through `livedoc.options.filters`. Use this
20
+ setup convention so agents and scripts can select tags without editing source:
21
+
22
+ ```typescript
23
+ // test/livedoc.setup.ts
24
+ import { livedoc } from "@swedevtools/livedoc-vitest";
25
+
26
+ const requestedTags = process.env.LIVEDOC_TAGS
27
+ ?.split(",")
28
+ .map((tag) => tag.trim())
29
+ .filter(Boolean)
30
+ .map((tag) => tag.startsWith("@") ? tag : `@${tag}`);
31
+
32
+ if (requestedTags?.length) {
33
+ livedoc.options.filters.include = requestedTags;
34
+ }
35
+ ```
36
+
37
+ Register the file through Vitest `setupFiles`. `LIVEDOC_TAGS` is a project setup
38
+ convention implemented by this file; the framework reads the resulting
39
+ `filters.include` values.
40
+
41
+ ## Agent Workflow
42
+
43
+ 1. Identify the smallest stable capability tags affected by the code change.
44
+ 2. Prefer domain tags such as `@checkout`, `@pricing`, or `@authentication`.
45
+ 3. Do not add temporary `@changed` tags or rewrite tests solely for selection.
46
+ 4. Run the affected tags as a partial:
47
+
48
+ ```powershell
49
+ $env:LIVEDOC_TAGS = "checkout,pricing"
50
+ $env:LIVEDOC_RUN_TYPE = "partial"
51
+ try {
52
+ pnpm exec vitest run
53
+ }
54
+ finally {
55
+ Remove-Item Env:\LIVEDOC_TAGS -ErrorAction SilentlyContinue
56
+ Remove-Item Env:\LIVEDOC_RUN_TYPE -ErrorAction SilentlyContinue
57
+ }
58
+ ```
59
+
60
+ ```bash
61
+ LIVEDOC_TAGS=checkout,pricing LIVEDOC_RUN_TYPE=partial pnpm exec vitest run
62
+ ```
63
+
64
+ 5. Use file or `-t` filtering only when the affected behavior has no suitable
65
+ tag.
66
+ 6. Run and publish a full suite before release, merge, or whenever the baseline
67
+ may be stale.
68
+
69
+ ## Failure Handling
70
+
71
+ - No tests execute: verify the setup file is registered and tags include the
72
+ `@` prefix after normalization.
73
+ - The Viewer loses unaffected results: the run was published as `full`; repeat
74
+ with `LIVEDOC_RUN_TYPE=partial`.
75
+ - Combined view is unavailable: publish a full baseline with the same project
76
+ and environment first.
77
+ - Static export fails: partial runs are server-only; use a full run for exports.