@swedevtools/livedoc-vitest 0.2.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/setup.cjs ADDED
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ var livedocVitest = require('@swedevtools/livedoc-vitest');
4
+
5
+ // _src/app/setup.ts
6
+ globalThis.feature = livedocVitest.feature;
7
+ globalThis.scenario = livedocVitest.scenario;
8
+ globalThis.scenarioOutline = livedocVitest.scenarioOutline;
9
+ globalThis.background = livedocVitest.background;
10
+ globalThis.given = livedocVitest.given;
11
+ globalThis.when = livedocVitest.when;
12
+ globalThis.then = livedocVitest.Then;
13
+ globalThis.and = livedocVitest.and;
14
+ globalThis.but = livedocVitest.but;
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/setup.js ADDED
@@ -0,0 +1,12 @@
1
+ import { feature, scenario, scenarioOutline, background, given, when, Then, and, but } from '@swedevtools/livedoc-vitest';
2
+
3
+ // _src/app/setup.ts
4
+ globalThis.feature = feature;
5
+ globalThis.scenario = scenario;
6
+ globalThis.scenarioOutline = scenarioOutline;
7
+ globalThis.background = background;
8
+ globalThis.given = given;
9
+ globalThis.when = when;
10
+ globalThis.then = Then;
11
+ globalThis.and = and;
12
+ globalThis.but = but;
package/package.json ADDED
@@ -0,0 +1,135 @@
1
+ {
2
+ "name": "@swedevtools/livedoc-vitest",
3
+ "version": "0.2.0",
4
+ "author": "Garry McGlennon",
5
+ "license": "MIT",
6
+ "description": "BDD extensions for Vitest that support LiveDoc reporting with Gherkin syntax and MSpec-style specifications.",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/dotnetprofessional/LiveDoc.git",
10
+ "directory": "packages/vitest"
11
+ },
12
+ "homepage": "https://github.com/dotnetprofessional/LiveDoc/tree/master/packages/vitest#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/dotnetprofessional/LiveDoc/issues"
15
+ },
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "type": "module",
20
+ "bin": {
21
+ "livedoc-vitest-setup": "./tools/livedoc-setup.mjs"
22
+ },
23
+ "main": "./dist/index.cjs",
24
+ "module": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js",
30
+ "require": "./dist/index.cjs"
31
+ },
32
+ "./reporter": {
33
+ "types": "./dist/reporter/index.d.ts",
34
+ "import": "./dist/reporter/index.js",
35
+ "require": "./dist/reporter/index.cjs"
36
+ },
37
+ "./setup": {
38
+ "types": "./dist/setup.d.ts",
39
+ "import": "./dist/setup.js",
40
+ "require": "./dist/setup.cjs"
41
+ },
42
+ "./globals": {
43
+ "types": "./dist/globals.d.ts",
44
+ "import": "./dist/globals.js",
45
+ "require": "./dist/globals.cjs"
46
+ },
47
+ "./playwright": {
48
+ "types": "./dist/playwright/index.d.ts",
49
+ "import": "./dist/playwright/index.js",
50
+ "require": "./dist/playwright/index.cjs"
51
+ }
52
+ },
53
+ "files": [
54
+ "dist",
55
+ "tools",
56
+ "README.md",
57
+ "LICENSE"
58
+ ],
59
+ "keywords": [
60
+ "livedoc",
61
+ "vitest",
62
+ "bdd",
63
+ "gherkin",
64
+ "cucumber",
65
+ "mspec",
66
+ "specification",
67
+ "javascript",
68
+ "typescript",
69
+ "testing",
70
+ "tests"
71
+ ],
72
+ "engines": {
73
+ "node": ">=18.0.0"
74
+ },
75
+ "devDependencies": {
76
+ "@types/chai": "^5.2.3",
77
+ "@types/fs-extra": "^11.0.4",
78
+ "@types/node": "^20.19.27",
79
+ "@types/wordwrap": "^1.0.3",
80
+ "@vitest/runner": "^4.0.16",
81
+ "@vitest/ui": "^4.0.16",
82
+ "chai": "^6.2.1",
83
+ "playwright": "^1.59.1",
84
+ "rimraf": "^5.0.10",
85
+ "strip-ansi": "^7.1.2",
86
+ "tsup": "^8.5.1",
87
+ "typescript": "^5.9.3",
88
+ "vitest": "^4.0.16",
89
+ "@swedevtools/livedoc-schema": "1.2.0",
90
+ "@swedevtools/livedoc-server": "^1.2.1"
91
+ },
92
+ "peerDependencies": {
93
+ "@swedevtools/livedoc-server": ">=1.0.0",
94
+ "playwright": ">=1.50.0",
95
+ "vitest": ">=1.0.0"
96
+ },
97
+ "peerDependenciesMeta": {
98
+ "@swedevtools/livedoc-server": {
99
+ "optional": true
100
+ },
101
+ "playwright": {
102
+ "optional": true
103
+ }
104
+ },
105
+ "dependencies": {
106
+ "@types/diff": "^7.0.2",
107
+ "chalk": "^5.6.2",
108
+ "cli-table3": "^0.6.5",
109
+ "diff": "^5.2.0",
110
+ "fs-extra": "^11.3.3",
111
+ "wordwrap": "^1.0.0"
112
+ },
113
+ "scripts": {
114
+ "test": "vitest run --config livedoc.vitest.ts",
115
+ "test:watch": "vitest --config livedoc.vitest.ts",
116
+ "test:ui": "vitest --ui --config livedoc.vitest.ts",
117
+ "test:summary": "vitest run --config vitest.config.summary.ts",
118
+ "test:list": "vitest run --config vitest.config.list.ts",
119
+ "test:spec": "vitest run --config livedoc.vitest.ts",
120
+ "test:silent": "vitest run --config vitest.config.silent.ts",
121
+ "test:file": "vitest run --config vitest.config.file.ts",
122
+ "test:json": "vitest run --config vitest.config.json.ts",
123
+ "test:viewer": "vitest run --config vitest.config.viewer.ts",
124
+ "test:publish": "vitest run --config vitest.config.publish.ts",
125
+ "test:coverage": "vitest run --coverage --config livedoc.vitest.ts",
126
+ "clean": "rimraf dist \"*.tgz\" -g",
127
+ "compile": "tsup",
128
+ "build": "npm run compile",
129
+ "watch": "tsup --watch",
130
+ "pack:local": "pnpm pack",
131
+ "publish:dry": "npm publish --dry-run",
132
+ "publish:beta": "npm publish --tag beta",
133
+ "publish:release": "npm publish"
134
+ }
135
+ }
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env node
2
+ // LiveDoc AI Skill Installer — install AI coding skills for your team.
3
+ // Usage:
4
+ // npx @swedevtools/livedoc-vitest setup # Interactive menu
5
+ // npx @swedevtools/livedoc-vitest setup --tool copilot # Non-interactive
6
+ // npx livedoc-vitest-setup --tool all # Direct bin entry
7
+
8
+ import { existsSync, mkdirSync, cpSync, readdirSync, statSync, copyFileSync } from 'node:fs';
9
+ import { join, dirname, resolve, relative } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { createInterface } from 'node:readline';
12
+ import { execSync } from 'node:child_process';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = dirname(__filename);
16
+
17
+ // ── Paths ──────────────────────────────────────────────────
18
+ const skillsSource = join(__dirname, 'skills');
19
+
20
+ if (!existsSync(join(skillsSource, 'SKILL.md'))) {
21
+ console.error(' Error: Could not find skill files at', skillsSource);
22
+ process.exit(1);
23
+ }
24
+
25
+ // ── Git root discovery ─────────────────────────────────────
26
+ function findGitRoot() {
27
+ try {
28
+ return execSync('git rev-parse --show-toplevel', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
29
+ } catch {
30
+ return process.cwd();
31
+ }
32
+ }
33
+
34
+ const gitRoot = findGitRoot();
35
+
36
+ // ── Tool definitions (same mapping as xUnit SDK) ──────────
37
+ const tools = [
38
+ { key: 'copilot', name: 'GitHub Copilot', dest: '.github/skills/livedoc-vitest' },
39
+ { key: 'claude', name: 'Claude Code', dest: '.claude/skills/livedoc-vitest' },
40
+ { key: 'roo', name: 'Roo Code', dest: '.roo/skills/livedoc-vitest' },
41
+ { key: 'cursor', name: 'Cursor', dest: '.cursor/rules/livedoc-vitest' },
42
+ { key: 'windsurf', name: 'Windsurf', dest: '.windsurf/rules/livedoc-vitest' },
43
+ ];
44
+
45
+ // ── Recursive directory copy ──────────────────────────────
46
+ function copyRecursive(src, dest) {
47
+ const entries = readdirSync(src, { withFileTypes: true });
48
+ mkdirSync(dest, { recursive: true });
49
+ for (const entry of entries) {
50
+ const srcPath = join(src, entry.name);
51
+ const destPath = join(dest, entry.name);
52
+ if (entry.isDirectory()) {
53
+ copyRecursive(srcPath, destPath);
54
+ } else {
55
+ copyFileSync(srcPath, destPath);
56
+ }
57
+ }
58
+ }
59
+
60
+ // ── Install skills for selected tools ─────────────────────
61
+ function installSkills(selected) {
62
+ console.log('');
63
+ for (const tool of selected) {
64
+ const dest = join(gitRoot, tool.dest);
65
+ copyRecursive(skillsSource, dest);
66
+ console.log(` \x1b[32m[ok]\x1b[0m ${tool.name} → ${dest}`);
67
+ }
68
+ console.log('');
69
+ console.log(' \x1b[36mDone! Commit the generated files to share with your team.\x1b[0m');
70
+ console.log('');
71
+ }
72
+
73
+ // ── Parse CLI args ────────────────────────────────────────
74
+ function parseArgs() {
75
+ const args = process.argv.slice(2);
76
+ // Strip leading "setup" command if present (npx @swedevtools/livedoc-vitest setup --tool X)
77
+ if (args[0] === 'setup') args.shift();
78
+
79
+ let toolArg = null;
80
+ for (let i = 0; i < args.length; i++) {
81
+ if (args[i] === '--tool' && args[i + 1]) {
82
+ toolArg = args[i + 1].toLowerCase();
83
+ break;
84
+ }
85
+ // Also support --tool=value
86
+ if (args[i].startsWith('--tool=')) {
87
+ toolArg = args[i].slice('--tool='.length).toLowerCase();
88
+ break;
89
+ }
90
+ }
91
+ return toolArg;
92
+ }
93
+
94
+ // ── Non-interactive mode ──────────────────────────────────
95
+ function resolveNonInteractive(toolArg) {
96
+ if (toolArg === 'all') return tools;
97
+
98
+ const match = tools.find((t) => t.key === toolArg);
99
+ if (!match) {
100
+ console.error(` Unknown tool: ${toolArg}. Use: copilot, claude, roo, cursor, windsurf, all`);
101
+ process.exit(1);
102
+ }
103
+ return [match];
104
+ }
105
+
106
+ // ── Interactive menu ──────────────────────────────────────
107
+ function showInteractiveMenu() {
108
+ return new Promise((resolve) => {
109
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
110
+
111
+ console.log('');
112
+ console.log(' \x1b[36mLiveDoc AI Skill Installer\x1b[0m');
113
+ console.log('');
114
+ console.log(' Select AI tool(s) to install skills for:');
115
+ console.log('');
116
+ tools.forEach((t, i) => {
117
+ console.log(` ${i + 1}. ${t.name}`);
118
+ });
119
+ console.log(' A. All of the above');
120
+ console.log('');
121
+
122
+ rl.question(' Choice [A]: ', (answer) => {
123
+ rl.close();
124
+ const choice = (answer || 'A').trim();
125
+
126
+ if (choice.toLowerCase() === 'a') {
127
+ resolve(tools);
128
+ return;
129
+ }
130
+
131
+ const idx = parseInt(choice, 10);
132
+ if (idx >= 1 && idx <= tools.length) {
133
+ resolve([tools[idx - 1]]);
134
+ return;
135
+ }
136
+
137
+ console.error(` Invalid choice: ${choice}`);
138
+ process.exit(1);
139
+ });
140
+ });
141
+ }
142
+
143
+ // ── Main ──────────────────────────────────────────────────
144
+ async function main() {
145
+ const toolArg = parseArgs();
146
+
147
+ let selected;
148
+ if (toolArg) {
149
+ selected = resolveNonInteractive(toolArg);
150
+ } else if (!process.stdin.isTTY) {
151
+ // Non-interactive context without --tool: default to all
152
+ console.log(' Non-interactive context detected. Installing for all tools.');
153
+ selected = tools;
154
+ } else {
155
+ selected = await showInteractiveMenu();
156
+ }
157
+
158
+ installSkills(selected);
159
+ }
160
+
161
+ main().catch((err) => {
162
+ console.error(err);
163
+ process.exit(1);
164
+ });
@@ -0,0 +1,244 @@
1
+ ---
2
+ name: livedoc-vitest
3
+ description: Expert guidance for writing and modifying BDD/Gherkin and MSpec-style tests using the @swedevtools/livedoc-vitest framework. Generates self-documenting TypeScript specs with correct API usage, value extraction, and living documentation patterns.
4
+ sdk_version: 0.2.0
5
+ ---
6
+
7
+ # LiveDoc Vitest Test Author
8
+
9
+ > **Progressive disclosure**: This file is the routing hub. Read the appropriate sub-resource for full API details.
10
+
11
+ ## Version Check
12
+
13
+ This skill targets **@swedevtools/livedoc-vitest v0.2.0**. Before writing tests, verify the installed version matches:
14
+
15
+ ```bash
16
+ npm ls @swedevtools/livedoc-vitest # or: pnpm ls @swedevtools/livedoc-vitest
17
+ ```
18
+
19
+ If the installed version differs from `0.2.0`, tell the developer: *"Your LiveDoc skill files target v0.2.0 but you have vX.Y.Z installed. Run `npx livedoc-vitest-setup` to update the skill files, or check the changelog for breaking changes."*
20
+
21
+ ## Use this skill when
22
+ - Creating or modifying `.Spec.ts` test files using `@swedevtools/livedoc-vitest`
23
+ - Writing BDD `feature`/`scenario` tests → **read `resources/bdd-features.md`**
24
+ - Writing MSpec `specification`/`rule` tests → **read `resources/specifications.md`**
25
+ - Writing browser-based Playwright tests → **read `resources/playwright.md`**
26
+ - Configuring reporters or static HTML export → **read `resources/reporter-config.md`**
27
+ - Debugging or fixing any LiveDoc Vitest test failures
28
+
29
+ ## Do not use this skill when
30
+ - Writing C#/.NET xUnit tests (use `livedoc-xunit` skill instead)
31
+ - Working on non-test TypeScript code (application logic, UI components, build scripts)
32
+ - Writing plain Vitest tests without LiveDoc BDD/Specification patterns
33
+ - Working on the viewer, VS Code extension, or server packages (unless writing their specs)
34
+
35
+ ---
36
+
37
+ ## Two Test Patterns
38
+
39
+ ### 1. BDD Features (`resources/bdd-features.md`)
40
+
41
+ **Use when**: Testing user journeys, business flows, acceptance criteria. Audience is business + technical. Tests read as Given/When/Then narratives.
42
+
43
+ ```typescript
44
+ import { feature, scenario, given, when, Then as then } from "@swedevtools/livedoc-vitest";
45
+
46
+ feature("Shipping Costs", () => {
47
+ scenario("Free shipping for Australian orders over $100", () => {
48
+ let cart: ShoppingCart;
49
+
50
+ given("the customer is from 'Australia'", (ctx) => {
51
+ cart = new ShoppingCart({ country: ctx.step.values[0] });
52
+ });
53
+
54
+ when("the order totals '100.00' dollars", (ctx) => {
55
+ cart.total = ctx.step.values[0];
56
+ cart.calculate();
57
+ });
58
+
59
+ then("shipping type is 'Free'", (ctx) => {
60
+ expect(cart.shippingType).toBe(ctx.step.values[0]);
61
+ });
62
+ });
63
+ });
64
+ ```
65
+
66
+ **Key concepts**: `feature`, `scenario`, `scenarioOutline`, `background`, `given`/`when`/`then`/`and`/`but`, `ctx.step.values`, `ctx.step.params`, `ctx.example`, data tables, doc strings.
67
+
68
+ → **Read `resources/bdd-features.md`** for complete keyword reference, background patterns, scenarioOutline with Examples, value extraction API, data tables, doc strings, attachment API, and validation checklist.
69
+
70
+ ### 2. Specifications (`resources/specifications.md`)
71
+
72
+ **Use when**: Testing APIs, utilities, algorithms, data-driven edge cases. Developer-only audience. Direct assertions in rules — no Given/When/Then ceremony.
73
+
74
+ ```typescript
75
+ import { specification, rule, ruleOutline } from "@swedevtools/livedoc-vitest";
76
+
77
+ specification("Calculator Operations", () => {
78
+ rule("Adding '5' and '3' returns '8'", (ctx) => {
79
+ const [a, b, expected] = ctx.rule.values;
80
+ expect(a + b).toBe(expected);
81
+ });
82
+
83
+ ruleOutline(`Discount calculations
84
+ Examples:
85
+ | price | discount | expected |
86
+ | 100 | 10 | 90 |
87
+ | 200 | 25 | 150 |
88
+ `, (ctx) => {
89
+ const result = ctx.example.price - (ctx.example.price * ctx.example.discount / 100);
90
+ expect(result).toBe(ctx.example.expected);
91
+ });
92
+ });
93
+ ```
94
+
95
+ **Key concepts**: `specification`, `rule`, `ruleOutline`, `ctx.rule.values`, `ctx.rule.params`, `ctx.example`, data-driven testing.
96
+
97
+ → **Read `resources/specifications.md`** for complete keyword reference, value extraction API, ruleOutline with Examples, async rules, and validation checklist.
98
+
99
+ ### 3. Playwright Integration (`resources/playwright.md`)
100
+
101
+ **Use when**: Browser-based testing — UI validation, screenshot capture, end-to-end web testing.
102
+
103
+ ```typescript
104
+ import { useBrowser, screenshot } from "@swedevtools/livedoc-vitest/playwright";
105
+
106
+ const { page } = useBrowser();
107
+
108
+ // Inside a scenario step:
109
+ when("navigating to the homepage", async (ctx) => {
110
+ await page().goto("http://localhost:3000");
111
+ await screenshot(page(), ctx);
112
+ });
113
+ ```
114
+
115
+ → **Read `resources/playwright.md`** for `useBrowser` options, `screenshot` API, lifecycle management, and troubleshooting.
116
+
117
+ ---
118
+
119
+ ## Shared Concepts
120
+
121
+ ### Folder Structure = Report Hierarchy
122
+
123
+ The **file path** of each `.Spec.ts` file determines the visual tree in the LiveDoc Viewer:
124
+
125
+ ```
126
+ _src/test/
127
+ ├── Checkout/ → "Checkout" node in viewer
128
+ │ └── Cart.Spec.ts
129
+ ├── Shipping/ → "Shipping" node
130
+ │ └── Costs.Spec.ts
131
+ └── Auth/ → "Auth" node
132
+ └── Login.Spec.ts
133
+ ```
134
+
135
+ ### Import Pattern
136
+
137
+ ```typescript
138
+ // BDD pattern
139
+ import { feature, scenario, scenarioOutline, background, given, when, Then as then, and, but } from "@swedevtools/livedoc-vitest";
140
+
141
+ // Specification pattern
142
+ import { specification, rule, ruleOutline } from "@swedevtools/livedoc-vitest";
143
+
144
+ // Playwright (optional)
145
+ import { useBrowser, screenshot } from "@swedevtools/livedoc-vitest/playwright";
146
+
147
+ // Or use globals mode — requires BOTH settings in vitest.config.ts:
148
+ // globals: true
149
+ // setupFiles: ['@swedevtools/livedoc-vitest/setup']
150
+ // Note: globals mode only registers BDD keywords (feature, scenario, given, when, then, etc.)
151
+ // Specification keywords (specification, rule, ruleOutline) must still be imported explicitly.
152
+ ```
153
+
154
+ **CRITICAL**: Import `Then` (uppercase) and alias as `then` (lowercase). ESM thenable detection requires the uppercase export name.
155
+
156
+ ### CRITICAL: Self-Documenting Tests
157
+
158
+ **Embed all inputs and expected outputs in step/rule titles.** Extract them using context APIs. Never hardcode values that appear in titles.
159
+
160
+ ```typescript
161
+ // ✅ Values in title AND extracted from context
162
+ given("a user with balance '500' dollars", (ctx) => {
163
+ account.balance = ctx.step.values[0]; // 500
164
+ });
165
+
166
+ // ✅ Named parameters for clarity
167
+ given("a user with <balance:500> dollars", (ctx) => {
168
+ account.balance = ctx.step.params.balance; // 500
169
+ });
170
+
171
+ // ❌ BAD: Value drift — title says 500, code uses 200
172
+ given("a user with balance '500' dollars", (ctx) => {
173
+ account.balance = 200;
174
+ });
175
+ ```
176
+
177
+ ### Value Extraction Quick Reference
178
+
179
+ | Syntax in Title | Step Access | Rule Access |
180
+ | --- | --- | --- |
181
+ | `'value'` (quoted) | `ctx.step.values[0]` | `ctx.rule.values[0]` |
182
+ | `<name:value>` (named) | `ctx.step.params.name` | `ctx.rule.params.name` |
183
+ | `<Placeholder>` (outline) | `ctx.example.Placeholder` | `ctx.example.Placeholder` |
184
+
185
+ ### Descriptions and Tags
186
+
187
+ Lines after the first line in titles provide descriptions and tags:
188
+
189
+ ```typescript
190
+ feature(`Shopping Cart
191
+ @checkout @critical
192
+ Business rules for the shopping cart checkout flow.
193
+ `, () => { ... });
194
+ ```
195
+
196
+ - **First line** = title
197
+ - **Lines starting with `@`** = tags (used for filtering)
198
+ - **Remaining lines** = description (appears in reports)
199
+
200
+ ### Async Rules
201
+
202
+ - **Only step callbacks, `rule`, and `ruleOutline` support `async`**
203
+ - `feature`, `scenario`, `scenarioOutline`, `specification`, `background` must be **synchronous**
204
+
205
+ ### Modifiers
206
+
207
+ ```typescript
208
+ feature.only("...", fn); feature.skip("...", fn);
209
+ scenario.only("...", fn); scenario.skip("...", fn);
210
+ rule.only("...", fn); rule.skip("...", fn);
211
+ ```
212
+
213
+ ### Build and Test
214
+
215
+ ```bash
216
+ pnpm --filter @swedevtools/livedoc-vitest test # Run all specs
217
+ pnpm --filter @swedevtools/livedoc-vitest test MyFeature.Spec.ts
218
+ ```
219
+
220
+ ---
221
+
222
+ ## Routing Examples
223
+
224
+ ### Positive (USE this skill)
225
+ - "Create a BDD test for shipping costs" → Read `resources/bdd-features.md`, write feature/scenario
226
+ - "Add data-driven tests for tax" → Read `resources/bdd-features.md`, use scenarioOutline
227
+ - "Write spec tests for email validator" → Read `resources/specifications.md`, write specification/rule
228
+ - "Write a Playwright test for the login page" → Read `resources/playwright.md`, use useBrowser
229
+ - "Configure LiveDoc reporter output" → Read `resources/reporter-config.md`
230
+ - "Generate static HTML test report" → Read `resources/reporter-config.md`
231
+
232
+ ### Negative (DO NOT use this skill)
233
+ - "Create a C# test for shipping" → Use `livedoc-xunit` skill
234
+ - "Build a React component" → Use `frontend-design` skill
235
+ - "Write a plain vitest test" → No LiveDoc skill needed
236
+ - "Install AI skills for the team" → Run `npx livedoc-vitest-setup`
237
+
238
+ ## Failure Handling
239
+ - Tests fail to compile → check imports, especially `Then as then` alias
240
+ - Values are `undefined` → verify single quotes `'value'` not backticks or double quotes
241
+ - `ctx.example` undefined → ensure inside `scenarioOutline`/`ruleOutline`, not plain `scenario`/`rule`
242
+ - Async hangs → ensure `async` only on step/rule callbacks, not on `feature`/`scenario`
243
+ - Playwright `page()` throws → `useBrowser()` must be at module scope; `page()` called inside steps
244
+ - Reporter issues → Read `resources/reporter-config.md`
@@ -0,0 +1,29 @@
1
+ # Validation Report — livedoc-vitest
2
+
3
+ ## Result: PASS
4
+
5
+ ## Checks
6
+
7
+ | Check | Status |
8
+ | --- | --- |
9
+ | Frontmatter `name` present | ✅ |
10
+ | Frontmatter `description` present | ✅ |
11
+ | Description ≤ 100 words | ✅ (30 words) |
12
+ | Body ≤ 500 lines | ✅ (321 lines) |
13
+ | `## Use this skill when` | ✅ |
14
+ | `## Do not use this skill when` | ✅ |
15
+ | `## Inputs` | ✅ |
16
+ | `## Outputs` | ✅ |
17
+ | `## Workflow` | ✅ |
18
+ | `## Validation` | ✅ |
19
+ | `## Examples` | ✅ |
20
+ | `### Positive routing examples` | ✅ |
21
+ | `### Negative routing examples` | ✅ |
22
+ | `## Failure handling` | ✅ |
23
+ | Routing examples file (`examples/routing.md`) | ✅ |
24
+
25
+ ## Assumptions
26
+ - Tests are written in TypeScript and use Vitest as the test runner
27
+ - The `@swedevtools/livedoc-vitest` package is available in the monorepo via `workspace:*`
28
+ - Globals mode may or may not be enabled; skill covers both import and globals patterns
29
+ - The existing `.github/instructions/livedoc-vitest.instructions.md` remains the file-pattern instruction; this skill provides broader AI-agent guidance
@@ -0,0 +1,60 @@
1
+ # LiveDoc Vitest Skill — Routing Examples
2
+
3
+ ## Positive routing (USE this skill)
4
+
5
+ ### Example 1: Create a new BDD feature spec
6
+ > "Create a test for the shopping cart checkout flow"
7
+
8
+ → This involves writing a `.Spec.ts` file using `feature`, `scenario`, `given`/`when`/`then` from `@swedevtools/livedoc-vitest`.
9
+
10
+ ### Example 2: Add a scenario outline with examples
11
+ > "Add data-driven tests for email validation"
12
+
13
+ → This involves using `scenarioOutline` or `ruleOutline` with an Examples table and `ctx.example`.
14
+
15
+ ### Example 3: Fix value extraction in a step
16
+ > "The step says '500' but the test uses 200 — fix the value drift"
17
+
18
+ → This involves replacing hardcoded values with `ctx.step.values[0]` or `ctx.step.params`.
19
+
20
+ ### Example 4: Convert a plain vitest test to LiveDoc specification pattern
21
+ > "Rewrite these unit tests as a LiveDoc specification with rules"
22
+
23
+ → This involves using `specification` and `rule`/`ruleOutline` from `@swedevtools/livedoc-vitest`.
24
+
25
+ ### Example 5: Modify an existing spec file
26
+ > "Add a new scenario to UserAuth.Spec.ts for password reset"
27
+
28
+ → This involves editing an existing `.Spec.ts` file using the correct LiveDoc patterns.
29
+
30
+ ### Example 6: Write a browser test with Playwright
31
+ > "Write a Playwright test that checks the viewer homepage loads correctly"
32
+
33
+ → This involves using `useBrowser` and `screenshot` from `@swedevtools/livedoc-vitest/playwright` in a `.Spec.ts` file with BDD patterns.
34
+
35
+ ## Negative routing (DO NOT use this skill)
36
+
37
+ ### Example 1: Writing a C# xUnit test
38
+ > "Create a test for the shipping calculator in C#"
39
+
40
+ → Use the `livedoc-xunit` skill instead. This skill is TypeScript-only.
41
+
42
+ ### Example 2: Building UI components
43
+ > "Create a React component for the test results viewer"
44
+
45
+ → This is UI work, not test authoring. Use the `frontend-design` skill instead.
46
+
47
+ ### Example 3: Plain vitest without LiveDoc
48
+ > "Write a vitest test for this utility function using describe/it"
49
+
50
+ → This skill is for LiveDoc BDD/Specification patterns. Plain vitest tests don't need it.
51
+
52
+ ### Example 4: Fixing build or config issues
53
+ > "The vitest config won't load, fix it"
54
+
55
+ → This is build infrastructure, not test authoring. Handle directly without this skill.
56
+
57
+ ### Example 5: Installing AI skills or generating static reports
58
+ > "Install the LiveDoc AI skill for my team" or "Generate a static HTML report"
59
+
60
+ → These are setup/ops tasks. Run `npx livedoc-vitest-setup` for skills or `npx livedoc-viewer export -i results.json` for reports. Not test authoring.