@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
package/dist/index.d.cts DELETED
@@ -1,291 +0,0 @@
1
- import { R as Rule, S as Specification, T as Table, F as Feature, B as Background, a as Scenario, b as ScenarioOutline, c as StepDefinition } from './index-Blmp569T.cjs';
2
- export { C as ColorTheme, D as DefaultColorTheme, E as Exception, d as ExecutionResults, H as HeaderType, I as IPostReporter, J as JsonReporter, L as LiveDocReporter, e as LiveDocReporterOptions, f as LiveDocRuleViolation, g as LiveDocServerReporter, h as LiveDocSpec, g as LiveDocSpecReporter, i as LiveDocSuite, j as LiveDocTest, k as LiveDocViewerOptions, l as LiveDocViewerReporter, m as LiveDocVitestReporter, n as ReporterOptions, o as RuleViolations, p as ScenarioExample, q as ScenarioOutlineContext, r as SilentReporter, s as SpecStatus, t as Statistics, u as SuiteBase, V as VitestSuite } from './index-Blmp569T.cjs';
3
- import { D as DataTableRow, R as RuleContext } from './RuleContext-BZhuy-zS.cjs';
4
- export { B as BackgroundContext, F as FeatureContext, S as ScenarioContext, b as SpecificationContext, a as StepContext } from './RuleContext-BZhuy-zS.cjs';
5
- import * as vitest from 'vitest';
6
- import 'vitest/reporters';
7
- import '@vitest/runner';
8
- import 'vitest/node';
9
- import '@swedevtools/livedoc-schema';
10
-
11
- declare class TextBlockReader {
12
- private arrayOfLines;
13
- private currentIndex;
14
- constructor(text: string);
15
- get count(): number;
16
- get line(): string | null;
17
- next(): boolean;
18
- reset(): void;
19
- }
20
-
21
- /**
22
- * Thrown when invalid syntax is encountered
23
- */
24
- declare class ParserException extends Error {
25
- description: string;
26
- title: string;
27
- filename: string;
28
- constructor(description: string, title: string, filename: string);
29
- }
30
-
31
- /**
32
- * Extended context for rule outlines including example data
33
- */
34
- interface RuleOutlineContext extends RuleContext {
35
- example: DataTableRow;
36
- exampleRaw: DataTableRow;
37
- }
38
- /**
39
- * RuleExample represents a single data row execution of a RuleOutline.
40
- * Similar to ScenarioExample but for the Specification pattern.
41
- */
42
- declare class RuleExample extends Rule {
43
- example: DataTableRow;
44
- exampleRaw: DataTableRow;
45
- ruleOutline: RuleOutline;
46
- constructor(parent: Specification, ruleOutline: RuleOutline);
47
- getRuleContext(): RuleOutlineContext;
48
- bind(content: string, model: DataTableRow): string;
49
- private sanitizeName;
50
- toJSON(): object;
51
- }
52
-
53
- /**
54
- * RuleOutline is a data-driven rule with Examples table.
55
- * Similar to ScenarioOutline but for the Specification pattern.
56
- */
57
- declare class RuleOutline extends Rule {
58
- tables: Table[];
59
- examples: RuleExample[];
60
- constructor(parent: Specification);
61
- toJSON(): object;
62
- }
63
-
64
- declare class LiveDocGrammarParser {
65
- private formatDisplayTitle;
66
- private formatStepDisplayTitle;
67
- createFeature(description: string, filename: string): Feature;
68
- addBackground(feature: Feature, description: string): Background;
69
- addScenario(feature: Feature, description: string): Scenario;
70
- addScenarioOutline(feature: Feature, description: string): ScenarioOutline;
71
- private addExamplesAsScenarios;
72
- private addExample;
73
- createStep(type: string, description: string, passedParam?: object | (() => object)): StepDefinition;
74
- applyPassedParams(step: StepDefinition): void;
75
- createSpecification(description: string, filename: string): Specification;
76
- addRule(specification: Specification, description: string): Rule;
77
- addRuleOutline(specification: Specification, description: string): RuleOutline;
78
- private addRuleExamples;
79
- private addRuleExample;
80
- }
81
- declare class DescriptionParser {
82
- title: string;
83
- description: string;
84
- text: string;
85
- tags: string[];
86
- tables: Table[];
87
- dataTable: DataTableRow[];
88
- docString: string;
89
- quotedValues: string[];
90
- namedValues: Record<string, string>;
91
- parseDescription(text: string): void;
92
- getTableRowAsEntity(headerRow: DataTableRow, dataRow: DataTableRow, shouldCoerce?: boolean): DataTableRow;
93
- coerceValues(values: string[]): any[];
94
- coerceNamedValues(namedValues: Record<string, string>): Record<string, any>;
95
- coerceValue(valueString: string): any;
96
- private convertToDateIfPossible;
97
- private isCommentedLine;
98
- private parseTable;
99
- parseDataTable(textReader: TextBlockReader): DataTableRow[];
100
- parseDocString(textReader: TextBlockReader): string;
101
- private parseQuotedValues;
102
- private parseNamedValues;
103
- private getFirstNonBlankIndex;
104
- private trimStart;
105
- applyIndenting(text: string, spacing: number): string;
106
- bind(content: string, model: any): string;
107
- secondaryBind(content: string, model: any): string;
108
- private applyBinding;
109
- sanitizeName(name: string): string;
110
- }
111
-
112
- declare enum LiveDocRuleOption {
113
- enabled = "enabled",
114
- disabled = "disabled",
115
- warning = "warning"
116
- }
117
-
118
- declare class LiveDocRules {
119
- /**
120
- * Is triggered when more than 1 given, when or then is used within a single scenario, scenarioOutline or background
121
- */
122
- singleGivenWhenThen: LiveDocRuleOption;
123
- /**
124
- * Is triggered if no given is part of the test
125
- */
126
- mustIncludeGiven: LiveDocRuleOption;
127
- /**
128
- * Is triggered if no when is part of the test
129
- */
130
- mustIncludeWhen: LiveDocRuleOption;
131
- /**
132
- * Is triggered if no then is part of the test
133
- */
134
- mustIncludeThen: LiveDocRuleOption;
135
- /**
136
- * Is triggered if a background uses when or then
137
- */
138
- backgroundMustOnlyIncludeGiven: LiveDocRuleOption;
139
- /**
140
- * Using the before hook has the same affect as the given step definition but with the ability to convey meaning.
141
- * It is therefore encouraged to use a given over the before hook.
142
- */
143
- enforceUsingGivenOverBefore: LiveDocRuleOption;
144
- /**
145
- * Ensures that a title is specified for keywords that require it
146
- */
147
- enforceTitle: LiveDocRuleOption;
148
- }
149
-
150
- declare class FilterOptions {
151
- include?: string[];
152
- exclude?: string[];
153
- showFilterConflicts?: boolean;
154
- }
155
-
156
- declare class PublishOptions {
157
- /** Server URL, e.g., 'http://localhost:3100' */
158
- server: string;
159
- /** Project name (defaults to 'default') */
160
- project: string;
161
- /** Environment name (defaults to 'local') */
162
- environment: string;
163
- /** Whether publishing is enabled */
164
- enabled: boolean;
165
- }
166
-
167
- declare class LiveDocOptions {
168
- rules: LiveDocRules;
169
- filters: FilterOptions;
170
- publish: PublishOptions;
171
- postReporters: any[];
172
- isolatedMode: boolean;
173
- }
174
-
175
- declare const livedoc: {
176
- options: LiveDocOptions;
177
- };
178
- /**
179
- * Feature keyword - creates a new Gherkin feature
180
- */
181
- declare const feature: ((title: string, fn: (ctx: any) => void) => void) & {
182
- skip: (title: string, fn: (ctx: any) => void) => void;
183
- only: (title: string, fn: (ctx: any) => void) => void;
184
- };
185
- /**
186
- * Scenario keyword - creates a new test scenario
187
- */
188
- declare const scenario: ((title: string, fn: (ctx: any) => void | Promise<void>) => void) & {
189
- skip: (title: string, fn: (ctx: any) => void | Promise<void>) => void;
190
- only: (title: string, fn: (ctx: any) => void | Promise<void>) => void;
191
- };
192
- /**
193
- * Background keyword - defines steps to run before each scenario
194
- */
195
- declare const background: ((title: string, fn: (ctx: any) => void) => void) & {
196
- skip: (title: string, fn: (ctx: any) => void) => void;
197
- only: (title: string, fn: (ctx: any) => void) => void;
198
- };
199
- /**
200
- * Register a hook that runs at the START of each scenario/example.
201
- * Used by plugins like the Playwright integration to create fresh browser contexts.
202
- */
203
- declare function onScenarioStart(fn: () => Promise<void>): void;
204
- /**
205
- * Register a hook that runs at the END of each scenario/example.
206
- * Used by plugins like the Playwright integration to clean up browser contexts.
207
- */
208
- declare function onScenarioEnd(fn: () => Promise<void>): void;
209
- /**
210
- * Scenario Outline keyword - creates data-driven scenarios
211
- */
212
- declare const scenarioOutline: ((title: string, fn: (ctx: any) => void) => void) & {
213
- skip: (title: string, fn: (ctx: any) => void) => void;
214
- only: (title: string, fn: (ctx: any) => void) => void;
215
- };
216
- /**
217
- * Specification keyword - creates a new specification container
218
- */
219
- declare const specification: ((title: string, fn: (ctx: any) => void) => void) & {
220
- skip: (title: string, fn: (ctx: any) => void) => void;
221
- only: (title: string, fn: (ctx: any) => void) => void;
222
- };
223
- /**
224
- * Rule keyword - creates a simple specification rule
225
- */
226
- declare const rule: ((title: string, fn: (ctx: any) => void | Promise<void>) => void) & {
227
- skip: (title: string, fn: (ctx: any) => void | Promise<void>) => void;
228
- only: (title: string, fn: (ctx: any) => void | Promise<void>) => void;
229
- };
230
- /**
231
- * Rule Outline keyword - creates data-driven rules
232
- */
233
- declare const ruleOutline: ((title: string, fn: (ctx: any) => void | Promise<void>) => void) & {
234
- skip: (title: string, fn: (ctx: any) => void | Promise<void>) => void;
235
- only: (title: string, fn: (ctx: any) => void | Promise<void>) => void;
236
- };
237
- /**
238
- * given keyword - preconditions
239
- */
240
- declare const given: (title: string, fn?: (ctx: any) => void | Promise<void>, passedParam?: object | Function, internalOptions?: {
241
- docStringRaw?: string;
242
- dataTable?: any[];
243
- }) => void;
244
- /**
245
- * when keyword - actions
246
- */
247
- declare const when: (title: string, fn?: (ctx: any) => void | Promise<void>, passedParam?: object | Function, internalOptions?: {
248
- docStringRaw?: string;
249
- dataTable?: any[];
250
- }) => void;
251
- /**
252
- * Then keyword - assertions
253
- * NOTE: Uppercase 'Then' is required due to ESM thenable detection.
254
- * If a module exports 'then', Node.js treats it as a Promise-like object.
255
- * Users who prefer lowercase can use: import { Then as then } from '@swedevtools/livedoc-vitest'
256
- * Or use globals mode where lowercase 'then' is available.
257
- */
258
- declare const Then: (title: string, fn?: (ctx: any) => void | Promise<void>, passedParam?: object | Function, internalOptions?: {
259
- docStringRaw?: string;
260
- dataTable?: any[];
261
- }) => void;
262
- /**
263
- * and keyword - continuation
264
- */
265
- declare const and: (title: string, fn?: (ctx: any) => void | Promise<void>, passedParam?: object | Function, internalOptions?: {
266
- docStringRaw?: string;
267
- dataTable?: any[];
268
- }) => void;
269
- /**
270
- * but keyword - continuation with contrast
271
- */
272
- declare const but: (title: string, fn?: (ctx: any) => void | Promise<void>, passedParam?: object | Function, internalOptions?: {
273
- docStringRaw?: string;
274
- dataTable?: any[];
275
- }) => void;
276
- /**
277
- * Exported 'it' function with .skip and .only support
278
- */
279
- declare const livedocIt: ((title: string, fn?: Function) => void) & {
280
- skip: (title: string, fn?: Function) => void;
281
- only: (title: string, fn?: Function) => void;
282
- };
283
- /**
284
- * Exported 'describe' function with .skip and .only support
285
- */
286
- declare const livedocDescribe: ((title: string, fn?: Function) => vitest.SuiteCollector<object>) & {
287
- skip: (title: string, fn?: Function) => vitest.SuiteCollector<object>;
288
- only: (title: string, fn?: Function) => vitest.SuiteCollector<object>;
289
- };
290
-
291
- export { Background, DataTableRow, DescriptionParser, Feature, FilterOptions, LiveDocGrammarParser, LiveDocOptions, LiveDocRuleOption, LiveDocRules, ParserException, Rule, RuleContext, RuleExample, RuleOutline, type RuleOutlineContext, Scenario, ScenarioOutline, Specification, StepDefinition, Table, TextBlockReader, Then, and, background, but, livedocDescribe as describe, feature, given, livedocIt as it, livedoc, onScenarioEnd, onScenarioStart, rule, ruleOutline, scenario, scenarioOutline, specification, when };
@@ -1,103 +0,0 @@
1
- 'use strict';
2
-
3
- var vitest = require('vitest');
4
- var livedocVitest = require('@swedevtools/livedoc-vitest');
5
-
6
- // _src/app/playwright/index.ts
7
- var playwrightModule;
8
- var playwrightLoaded = false;
9
- async function ensurePlaywright() {
10
- if (playwrightLoaded) return playwrightModule;
11
- try {
12
- const moduleName = "playwright";
13
- playwrightModule = await import(
14
- /* @vite-ignore */
15
- moduleName
16
- );
17
- playwrightLoaded = true;
18
- return playwrightModule;
19
- } catch {
20
- throw new Error(
21
- "@swedevtools/livedoc-vitest/playwright requires 'playwright' as a peer dependency.\nInstall it with:\n\n pnpm add -D playwright\n npx playwright install chromium\n"
22
- );
23
- }
24
- }
25
- var _screenshotIndex = 0;
26
- function slugify(text) {
27
- return text.toLowerCase().replace(/['"`]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
28
- }
29
- async function screenshot(page, ctx, options) {
30
- const fullPage = options?.fullPage ?? true;
31
- const buffer = await page.screenshot({ fullPage });
32
- const base64 = buffer.toString("base64");
33
- const name = options?.name ?? `${slugify(ctx.step.title)}-${++_screenshotIndex}`;
34
- ctx.step.attachScreenshot(base64, name);
35
- }
36
- function useBrowser(options) {
37
- const baseUrl = options?.baseUrl ?? "http://localhost:3000";
38
- const browserName = options?.browser ?? "chromium";
39
- const freshContext = options?.freshContextPerScenario ?? false;
40
- let _browser;
41
- let _context;
42
- let _page;
43
- vitest.beforeAll(async () => {
44
- const pw = await ensurePlaywright();
45
- const launcher = pw[browserName];
46
- _browser = await launcher.launch(options?.launch ?? { headless: true });
47
- if (!freshContext) {
48
- _context = await _browser.newContext(options?.context ?? {});
49
- _page = await _context.newPage();
50
- }
51
- _screenshotIndex = 0;
52
- });
53
- if (freshContext) {
54
- livedocVitest.onScenarioStart(async () => {
55
- _context = await _browser.newContext(options?.context ?? {});
56
- _page = await _context.newPage();
57
- });
58
- livedocVitest.onScenarioEnd(async () => {
59
- await _context?.close().catch(() => {
60
- });
61
- _page = void 0;
62
- _context = void 0;
63
- });
64
- }
65
- vitest.afterAll(async () => {
66
- try {
67
- await _browser?.close();
68
- } catch {
69
- } finally {
70
- _page = void 0;
71
- _context = void 0;
72
- _browser = void 0;
73
- }
74
- });
75
- return {
76
- page: () => {
77
- if (!_page) {
78
- throw new Error(
79
- "Playwright page is not initialized. Ensure useBrowser() is called at module scope and page() is called inside a step."
80
- );
81
- }
82
- return _page;
83
- },
84
- context: () => {
85
- if (!_context) {
86
- throw new Error("Playwright context is not initialized.");
87
- }
88
- return _context;
89
- },
90
- browser: () => {
91
- if (!_browser) {
92
- throw new Error("Playwright browser is not initialized.");
93
- }
94
- return _browser;
95
- },
96
- baseUrl
97
- };
98
- }
99
- var usePlaywright = useBrowser;
100
-
101
- exports.screenshot = screenshot;
102
- exports.useBrowser = useBrowser;
103
- exports.usePlaywright = usePlaywright;
@@ -1,129 +0,0 @@
1
- import { StepContext } from '@swedevtools/livedoc-vitest';
2
-
3
- /**
4
- * @swedevtools/livedoc-vitest/playwright
5
- *
6
- * Playwright integration for LiveDoc — browser lifecycle management
7
- * and screenshot helpers for BDD feature specs.
8
- *
9
- * @example
10
- * ```typescript
11
- * import { feature, scenario, given, when, then } from '@swedevtools/livedoc-vitest';
12
- * import { useBrowser, screenshot } from '@swedevtools/livedoc-vitest/playwright';
13
- *
14
- * const { page, baseUrl } = useBrowser({ baseUrl: 'http://localhost:5174' });
15
- *
16
- * feature('Checkout Flow', () => {
17
- * scenario('User adds item to cart', () => {
18
- * given("user views the product page", async (ctx) => {
19
- * await page().goto(`${baseUrl}/products/1`);
20
- * await screenshot(page(), ctx);
21
- * });
22
- * });
23
- * });
24
- * ```
25
- */
26
-
27
- /** Minimal Page interface — the real Playwright Page has many more methods */
28
- interface PlaywrightPage {
29
- screenshot(options?: {
30
- fullPage?: boolean;
31
- }): Promise<Buffer>;
32
- goto(url: string, options?: Record<string, unknown>): Promise<unknown>;
33
- close(): Promise<void>;
34
- [key: string]: unknown;
35
- }
36
- /** Minimal BrowserContext interface */
37
- interface PlaywrightBrowserContext {
38
- newPage(): Promise<PlaywrightPage>;
39
- close(): Promise<void>;
40
- [key: string]: unknown;
41
- }
42
- /** Minimal Browser interface */
43
- interface PlaywrightBrowser {
44
- newContext(options?: Record<string, unknown>): Promise<PlaywrightBrowserContext>;
45
- close(): Promise<void>;
46
- [key: string]: unknown;
47
- }
48
- /** Browser engine to use */
49
- type BrowserName = "chromium" | "firefox" | "webkit";
50
- /** Options for useBrowser() / usePlaywright() */
51
- interface PlaywrightOptions {
52
- /** Base URL for navigation (default: 'http://localhost:3000') */
53
- baseUrl?: string;
54
- /** Browser engine (default: 'chromium') */
55
- browser?: BrowserName;
56
- /** Options passed directly to browser.launch() */
57
- launch?: Record<string, unknown>;
58
- /** Options passed directly to browser.newContext() */
59
- context?: Record<string, unknown>;
60
- /** Create a fresh BrowserContext for each scenario (default: false) */
61
- freshContextPerScenario?: boolean;
62
- }
63
- /** Return type of useBrowser() */
64
- interface PlaywrightFixture {
65
- /** Get the current Page instance (call inside steps, not at module scope) */
66
- page: () => PlaywrightPage;
67
- /** Get the current BrowserContext */
68
- context: () => PlaywrightBrowserContext;
69
- /** Get the Browser instance */
70
- browser: () => PlaywrightBrowser;
71
- /** Configured base URL */
72
- baseUrl: string;
73
- }
74
- /** Options for the screenshot() helper */
75
- interface ScreenshotOptions {
76
- /** Override auto-generated screenshot name */
77
- name?: string;
78
- /** Capture full page scroll height (default: true) */
79
- fullPage?: boolean;
80
- }
81
- /**
82
- * Capture a screenshot and attach it to the current LiveDoc step.
83
- *
84
- * Auto-generates a descriptive filename from the step title if no name is provided.
85
- *
86
- * @example
87
- * ```typescript
88
- * // Auto-named from step title
89
- * await screenshot(page(), ctx);
90
- *
91
- * // Custom name
92
- * await screenshot(page(), ctx, { name: 'login-form' });
93
- * ```
94
- */
95
- declare function screenshot(page: PlaywrightPage, ctx: {
96
- step: StepContext;
97
- }, options?: ScreenshotOptions): Promise<void>;
98
- /**
99
- * Initialize Playwright browser lifecycle for a feature file.
100
- *
101
- * Call at **module scope** (outside `feature()` block) to get feature-level
102
- * browser sharing. The browser launches once and is shared across all
103
- * scenarios in the file.
104
- *
105
- * @example
106
- * ```typescript
107
- * import { useBrowser, screenshot } from '@swedevtools/livedoc-vitest/playwright';
108
- *
109
- * const { page, baseUrl } = useBrowser({
110
- * baseUrl: 'http://localhost:5174',
111
- * browser: 'chromium',
112
- * launch: { headless: process.env.CI === 'true' },
113
- * });
114
- *
115
- * feature('My Feature', () => {
116
- * scenario('My Scenario', () => {
117
- * given("I open the app", async (ctx) => {
118
- * await page().goto(baseUrl);
119
- * await screenshot(page(), ctx);
120
- * });
121
- * });
122
- * });
123
- * ```
124
- */
125
- declare function useBrowser(options?: PlaywrightOptions): PlaywrightFixture;
126
- /** Alias for useBrowser() */
127
- declare const usePlaywright: typeof useBrowser;
128
-
129
- export { type BrowserName, type PlaywrightBrowser, type PlaywrightBrowserContext, type PlaywrightFixture, type PlaywrightOptions, type PlaywrightPage, type ScreenshotOptions, screenshot, useBrowser, usePlaywright };