executable-stories-init 0.1.0 → 0.1.2
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/LICENSE +21 -0
- package/README.md +18 -6
- package/binding.gyp +9 -0
- package/dist/cli/index.js +142 -28
- package/dist/templates/cypress-config.ts.tmpl +19 -0
- package/dist/templates/cypress-sample.story.cy.ts.tmpl +17 -0
- package/dist/templates/cypress-support-e2e.ts.tmpl +2 -0
- package/dist/templates/index.ts +5 -0
- package/dist/templates/jest-config.mjs.tmpl +32 -0
- package/dist/templates/jest-sample.story.test.ts.tmpl +18 -0
- package/index.js +1 -0
- package/package.json +9 -9
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Jag Reehal
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# executable-stories-init
|
|
2
2
|
|
|
3
|
-
Bootstrap [executable-stories](https://github.com/jagreehal/executable-stories) (Vitest and/or
|
|
3
|
+
Bootstrap [executable-stories](https://github.com/jagreehal/executable-stories) (Vitest, Playwright, Jest, and/or Cypress) into a TypeScript repo from zero. Detects your framework, package manager and monorepo layout, installs the right adapter, writes config, drops a sample story, and patches `package.json` scripts.
|
|
4
4
|
|
|
5
5
|
## Install and run
|
|
6
6
|
|
|
@@ -25,10 +25,11 @@ The wizard is interactive by default. Pass `--yes` (or `--json`) to run non-inte
|
|
|
25
25
|
For each selected target (repo root, or one or more workspace packages):
|
|
26
26
|
|
|
27
27
|
1. **Detects** existing Vitest / Playwright installs, an existing config, and TypeScript.
|
|
28
|
-
2. **Installs**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
2. **Installs** framework adapter packages and `executable-stories-formatters` using your repo's package manager (`pnpm`, `yarn`, or `npm`).
|
|
29
|
+
- When multiple frameworks are selected for a target, dependencies are merged into one install pass.
|
|
30
|
+
3. **Writes configs** (`vitest.config.ts`, `playwright.config.ts`, `jest.config.mjs`, `cypress.config.ts`) pre-wired for reporting.
|
|
31
|
+
4. **Writes sample stories** in framework-appropriate locations.
|
|
32
|
+
5. **Patches `package.json` scripts** for selected frameworks.
|
|
32
33
|
6. **Optionally writes `tsconfig.json`** when missing and `--ts` is passed.
|
|
33
34
|
|
|
34
35
|
Anything already present is left alone (or skipped with a reason). Use `--force` to overwrite differing files.
|
|
@@ -39,14 +40,19 @@ Anything already present is left alone (or skipped with a reason). Use `--force`
|
|
|
39
40
|
| ---- | ----------- |
|
|
40
41
|
| `--vitest` | Set up Vitest. |
|
|
41
42
|
| `--playwright` | Set up Playwright. |
|
|
43
|
+
| `--jest` | Set up Jest. |
|
|
44
|
+
| `--cypress` | Set up Cypress. |
|
|
42
45
|
| `--both` | Set up both Vitest and Playwright. |
|
|
46
|
+
| `--all` | Set up Vitest, Playwright, Jest, and Cypress. |
|
|
43
47
|
| `--target <pkg...>` | Workspace package(s) to set up. Use `root` for the repo root. Repeatable. |
|
|
44
48
|
| `--ts` / `--no-ts` | Write a minimal `tsconfig.json` if missing. |
|
|
45
49
|
| `-y`, `--yes` | Non-interactive; accept defaults. |
|
|
46
50
|
| `--interactive` | Force prompts even when piped. |
|
|
47
51
|
| `--dry-run` | Print the plan; do not write or install. |
|
|
48
52
|
| `--force` | Overwrite differing existing files. |
|
|
49
|
-
| `--json` | Machine-readable output. Implies `--yes`. Requires `--vitest
|
|
53
|
+
| `--json` | Machine-readable output. Implies `--yes`. Requires at least one framework flag (`--vitest`, `--playwright`, `--jest`, `--cypress`, `--both`, or `--all`). |
|
|
54
|
+
|
|
55
|
+
`--both` and `--all` are additive with explicit framework flags. Example: `--both --jest` sets up Vitest, Playwright, and Jest.
|
|
50
56
|
|
|
51
57
|
## Examples
|
|
52
58
|
|
|
@@ -84,6 +90,12 @@ cd <target> # repeat per selected target
|
|
|
84
90
|
<pm> run test:e2e # Playwright stories (if installed)
|
|
85
91
|
```
|
|
86
92
|
|
|
93
|
+
If you bootstrap multiple frameworks at once, script names are collision-safe:
|
|
94
|
+
|
|
95
|
+
- Vitest + Jest: `test:stories:vitest`, `test:stories:jest`
|
|
96
|
+
- Playwright + Cypress: `test:e2e:playwright`, `test:e2e:cypress`
|
|
97
|
+
- Vitest + Jest sample files: `src/example.vitest.story.test.ts`, `src/example.jest.story.test.ts`
|
|
98
|
+
|
|
87
99
|
Open the generated report:
|
|
88
100
|
|
|
89
101
|
```bash
|
package/binding.gyp
ADDED
package/dist/cli/index.js
CHANGED
|
@@ -98,6 +98,18 @@ async function statSet(target) {
|
|
|
98
98
|
break;
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
+
for (const f of ["jest.config.ts", "jest.config.js", "jest.config.mjs", "jest.config.cjs", "jest.config.json"]) {
|
|
102
|
+
if (await exists(join(target, f))) {
|
|
103
|
+
flags.add("jest-config");
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (const f of ["cypress.config.ts", "cypress.config.js", "cypress.config.mjs", "cypress.config.cjs"]) {
|
|
108
|
+
if (await exists(join(target, f))) {
|
|
109
|
+
flags.add("cypress-config");
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
101
113
|
return flags;
|
|
102
114
|
}
|
|
103
115
|
async function readWorkspaceGlobs(cwd) {
|
|
@@ -168,8 +180,12 @@ async function detectRepo(args, _deps) {
|
|
|
168
180
|
hasTypeScript: (t) => stats.get(t)?.has("ts") ?? false,
|
|
169
181
|
hasVitest: (t) => depPresent(pkgCache.get(t) ?? rootPkg, "vitest"),
|
|
170
182
|
hasPlaywright: (t) => depPresent(pkgCache.get(t) ?? rootPkg, "@playwright/test"),
|
|
183
|
+
hasJest: (t) => depPresent(pkgCache.get(t) ?? rootPkg, "jest"),
|
|
184
|
+
hasCypress: (t) => depPresent(pkgCache.get(t) ?? rootPkg, "cypress"),
|
|
171
185
|
hasExistingVitestConfig: (t) => stats.get(t)?.has("vitest-config") ?? false,
|
|
172
|
-
hasExistingPlaywrightConfig: (t) => stats.get(t)?.has("playwright-config") ?? false
|
|
186
|
+
hasExistingPlaywrightConfig: (t) => stats.get(t)?.has("playwright-config") ?? false,
|
|
187
|
+
hasExistingJestConfig: (t) => stats.get(t)?.has("jest-config") ?? false,
|
|
188
|
+
hasExistingCypressConfig: (t) => stats.get(t)?.has("cypress-config") ?? false
|
|
173
189
|
};
|
|
174
190
|
}
|
|
175
191
|
|
|
@@ -190,6 +206,13 @@ async function renderTemplate(name) {
|
|
|
190
206
|
async function resolvePlan(args, _deps) {
|
|
191
207
|
const { facts, flags } = args;
|
|
192
208
|
const ops = [];
|
|
209
|
+
const hasVitest = flags.frameworks.includes("vitest");
|
|
210
|
+
const hasPlaywright = flags.frameworks.includes("playwright");
|
|
211
|
+
const hasJest = flags.frameworks.includes("jest");
|
|
212
|
+
const hasCypress = flags.frameworks.includes("cypress");
|
|
213
|
+
const unitScriptConflicts = hasVitest && hasJest;
|
|
214
|
+
const e2eScriptConflicts = hasPlaywright && hasCypress;
|
|
215
|
+
const unitSampleConflicts = hasVitest && hasJest;
|
|
193
216
|
if (flags.writeTsconfig) {
|
|
194
217
|
for (const target of flags.targets) {
|
|
195
218
|
if (!facts.hasTypeScript(target)) {
|
|
@@ -203,18 +226,11 @@ async function resolvePlan(args, _deps) {
|
|
|
203
226
|
}
|
|
204
227
|
}
|
|
205
228
|
for (const target of flags.targets) {
|
|
206
|
-
|
|
229
|
+
const installDeps = /* @__PURE__ */ new Set();
|
|
230
|
+
if (hasVitest) {
|
|
207
231
|
const vitestDeps = ["vitest", "executable-stories-vitest", "executable-stories-formatters"];
|
|
208
232
|
const missing = vitestDeps.filter((dep) => !facts.hasDependency(target, dep));
|
|
209
|
-
|
|
210
|
-
ops.push({
|
|
211
|
-
kind: "install",
|
|
212
|
-
target,
|
|
213
|
-
deps: missing,
|
|
214
|
-
dev: true,
|
|
215
|
-
packageManager: facts.packageManager
|
|
216
|
-
});
|
|
217
|
-
}
|
|
233
|
+
missing.forEach((dep) => installDeps.add(dep));
|
|
218
234
|
if (!facts.hasExistingVitestConfig(target) || flags.force) {
|
|
219
235
|
ops.push({
|
|
220
236
|
kind: "write",
|
|
@@ -226,23 +242,16 @@ async function resolvePlan(args, _deps) {
|
|
|
226
242
|
ops.push({
|
|
227
243
|
kind: "write",
|
|
228
244
|
target,
|
|
229
|
-
path: join3(target, "src/example.story.test.ts"),
|
|
245
|
+
path: join3(target, unitSampleConflicts ? "src/example.vitest.story.test.ts" : "src/example.story.test.ts"),
|
|
230
246
|
contents: await renderTemplate("vitest-sample.story.test.ts")
|
|
231
247
|
});
|
|
232
|
-
|
|
248
|
+
const scriptName = unitScriptConflicts ? "test:stories:vitest" : "test";
|
|
249
|
+
ops.push({ kind: "patch-package-json", target, scripts: { [scriptName]: "vitest run" } });
|
|
233
250
|
}
|
|
234
|
-
if (
|
|
251
|
+
if (hasPlaywright) {
|
|
235
252
|
const pwDeps = ["@playwright/test", "executable-stories-playwright", "executable-stories-formatters"];
|
|
236
253
|
const missing = pwDeps.filter((dep) => !facts.hasDependency(target, dep));
|
|
237
|
-
|
|
238
|
-
ops.push({
|
|
239
|
-
kind: "install",
|
|
240
|
-
target,
|
|
241
|
-
deps: missing,
|
|
242
|
-
dev: true,
|
|
243
|
-
packageManager: facts.packageManager
|
|
244
|
-
});
|
|
245
|
-
}
|
|
254
|
+
missing.forEach((dep) => installDeps.add(dep));
|
|
246
255
|
if (!facts.hasExistingPlaywrightConfig(target) || flags.force) {
|
|
247
256
|
ops.push({
|
|
248
257
|
kind: "write",
|
|
@@ -257,10 +266,85 @@ async function resolvePlan(args, _deps) {
|
|
|
257
266
|
path: join3(target, "tests/example.story.spec.ts"),
|
|
258
267
|
contents: await renderTemplate("playwright-sample.story.spec.ts")
|
|
259
268
|
});
|
|
269
|
+
const scriptName = e2eScriptConflicts ? "test:e2e:playwright" : "test:e2e";
|
|
270
|
+
ops.push({ kind: "patch-package-json", target, scripts: { [scriptName]: "playwright test" } });
|
|
271
|
+
}
|
|
272
|
+
if (hasJest) {
|
|
273
|
+
const jestDeps = ["jest", "@jest/globals", "ts-jest", "executable-stories-jest", "executable-stories-formatters"];
|
|
274
|
+
const missing = jestDeps.filter((dep) => !facts.hasDependency(target, dep));
|
|
275
|
+
missing.forEach((dep) => installDeps.add(dep));
|
|
276
|
+
if (!facts.hasExistingJestConfig(target) || flags.force) {
|
|
277
|
+
ops.push({
|
|
278
|
+
kind: "write",
|
|
279
|
+
target,
|
|
280
|
+
path: join3(target, "jest.config.mjs"),
|
|
281
|
+
contents: await renderTemplate("jest-config.mjs")
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
ops.push({
|
|
285
|
+
kind: "write",
|
|
286
|
+
target,
|
|
287
|
+
path: join3(target, unitSampleConflicts ? "src/example.jest.story.test.ts" : "src/example.story.test.ts"),
|
|
288
|
+
contents: await renderTemplate("jest-sample.story.test.ts")
|
|
289
|
+
});
|
|
290
|
+
const scriptName = unitScriptConflicts ? "test:stories:jest" : "test";
|
|
291
|
+
ops.push({ kind: "patch-package-json", target, scripts: { [scriptName]: "jest --config jest.config.mjs" } });
|
|
292
|
+
}
|
|
293
|
+
if (hasCypress) {
|
|
294
|
+
const cypressDeps = ["cypress", "executable-stories-cypress", "executable-stories-formatters"];
|
|
295
|
+
const missing = cypressDeps.filter((dep) => !facts.hasDependency(target, dep));
|
|
296
|
+
missing.forEach((dep) => installDeps.add(dep));
|
|
297
|
+
if (!facts.hasExistingCypressConfig(target) || flags.force) {
|
|
298
|
+
ops.push({
|
|
299
|
+
kind: "write",
|
|
300
|
+
target,
|
|
301
|
+
path: join3(target, "cypress.config.ts"),
|
|
302
|
+
contents: await renderTemplate("cypress-config.ts")
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
ops.push({
|
|
306
|
+
kind: "write",
|
|
307
|
+
target,
|
|
308
|
+
path: join3(target, "cypress/support/e2e.ts"),
|
|
309
|
+
contents: await renderTemplate("cypress-support-e2e.ts")
|
|
310
|
+
});
|
|
260
311
|
ops.push({
|
|
261
|
-
kind: "
|
|
312
|
+
kind: "write",
|
|
262
313
|
target,
|
|
263
|
-
|
|
314
|
+
path: join3(target, "cypress/e2e/example.story.cy.ts"),
|
|
315
|
+
contents: await renderTemplate("cypress-sample.story.cy.ts")
|
|
316
|
+
});
|
|
317
|
+
const scriptName = e2eScriptConflicts ? "test:e2e:cypress" : "test:e2e";
|
|
318
|
+
ops.push({ kind: "patch-package-json", target, scripts: { [scriptName]: "cypress run" } });
|
|
319
|
+
}
|
|
320
|
+
if (unitScriptConflicts) {
|
|
321
|
+
ops.push({
|
|
322
|
+
kind: "note",
|
|
323
|
+
level: "info",
|
|
324
|
+
message: `Both Vitest and Jest selected in ${target}; writing test:stories:* scripts to avoid test script collisions.`
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
if (e2eScriptConflicts) {
|
|
328
|
+
ops.push({
|
|
329
|
+
kind: "note",
|
|
330
|
+
level: "info",
|
|
331
|
+
message: `Both Playwright and Cypress selected in ${target}; writing test:e2e:* scripts to avoid test:e2e collisions.`
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
if (unitSampleConflicts) {
|
|
335
|
+
ops.push({
|
|
336
|
+
kind: "note",
|
|
337
|
+
level: "info",
|
|
338
|
+
message: `Both Vitest and Jest selected in ${target}; writing framework-specific sample story filenames to avoid file collisions.`
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
if (installDeps.size > 0) {
|
|
342
|
+
ops.push({
|
|
343
|
+
kind: "install",
|
|
344
|
+
target,
|
|
345
|
+
deps: [...installDeps],
|
|
346
|
+
dev: true,
|
|
347
|
+
packageManager: facts.packageManager
|
|
264
348
|
});
|
|
265
349
|
}
|
|
266
350
|
}
|
|
@@ -476,6 +560,16 @@ async function runWizard(args, _deps) {
|
|
|
476
560
|
value: "playwright",
|
|
477
561
|
label: "Playwright",
|
|
478
562
|
hint: facts.hasPlaywright(facts.cwd) ? "already installed" : void 0
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
value: "jest",
|
|
566
|
+
label: "Jest",
|
|
567
|
+
hint: facts.hasJest(facts.cwd) ? "already installed" : void 0
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
value: "cypress",
|
|
571
|
+
label: "Cypress",
|
|
572
|
+
hint: facts.hasCypress(facts.cwd) ? "already installed" : void 0
|
|
479
573
|
}
|
|
480
574
|
],
|
|
481
575
|
required: true
|
|
@@ -548,6 +642,26 @@ function formatCliError(message, json) {
|
|
|
548
642
|
return `Error: ${message}`;
|
|
549
643
|
}
|
|
550
644
|
|
|
645
|
+
// src/flags.ts
|
|
646
|
+
function resolveFrameworks(opts) {
|
|
647
|
+
const frameworks = /* @__PURE__ */ new Set();
|
|
648
|
+
if (opts.all) {
|
|
649
|
+
frameworks.add("vitest");
|
|
650
|
+
frameworks.add("playwright");
|
|
651
|
+
frameworks.add("jest");
|
|
652
|
+
frameworks.add("cypress");
|
|
653
|
+
}
|
|
654
|
+
if (opts.both) {
|
|
655
|
+
frameworks.add("vitest");
|
|
656
|
+
frameworks.add("playwright");
|
|
657
|
+
}
|
|
658
|
+
if (opts.vitest) frameworks.add("vitest");
|
|
659
|
+
if (opts.playwright) frameworks.add("playwright");
|
|
660
|
+
if (opts.jest) frameworks.add("jest");
|
|
661
|
+
if (opts.cypress) frameworks.add("cypress");
|
|
662
|
+
return [...frameworks];
|
|
663
|
+
}
|
|
664
|
+
|
|
551
665
|
// src/index.ts
|
|
552
666
|
async function confirmPlan(plan) {
|
|
553
667
|
const lines = [
|
|
@@ -573,15 +687,15 @@ async function confirmPlan(plan) {
|
|
|
573
687
|
return !p3.isCancel(ok) && ok === true;
|
|
574
688
|
}
|
|
575
689
|
var program = new Command();
|
|
576
|
-
program.name("executable-stories-init").description("Bootstrap executable-stories (Vitest
|
|
690
|
+
program.name("executable-stories-init").description("Bootstrap executable-stories (Vitest, Playwright, Jest, Cypress) into a TypeScript repo").argument("[target]", "target directory (defaults to cwd)").option("--vitest", "set up Vitest").option("--playwright", "set up Playwright").option("--jest", "set up Jest").option("--cypress", "set up Cypress").option("--both", "set up both Vitest and Playwright").option("--all", "set up Vitest, Playwright, Jest, and Cypress").option("--ts", "write tsconfig.json if missing").option("--no-ts", "do not write tsconfig.json").option("-y, --yes", "accept all defaults, non-interactive").option("--dry-run", "print plan but do not write or install").option("--json", "machine-readable JSON output (implies --yes)").option("--interactive", "force interactive prompts").option("--force", "overwrite differing existing files").option("--target <pkg...>", "workspace package(s) to set up (default: prompt or root)").action(async (target, opts) => {
|
|
577
691
|
const cliOpts = buildOpts(opts);
|
|
578
692
|
try {
|
|
579
693
|
const cwd = resolve(target ?? process3.cwd());
|
|
580
694
|
const deps = buildDeps(cliOpts, cwd);
|
|
581
695
|
const facts = await detectRepo({ cwd }, deps);
|
|
582
|
-
const frameworks = opts
|
|
696
|
+
const frameworks = resolveFrameworks(opts);
|
|
583
697
|
if (frameworks.length === 0 && cliOpts.json) {
|
|
584
|
-
console.error(formatCliError("--json requires at least one
|
|
698
|
+
console.error(formatCliError("--json requires at least one framework flag (--vitest, --playwright, --jest, --cypress, --both, --all)", true));
|
|
585
699
|
process3.exit(2);
|
|
586
700
|
}
|
|
587
701
|
if (frameworks.length === 0) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineConfig } from 'cypress';
|
|
2
|
+
import { registerExecutableStoriesPlugin } from 'executable-stories-cypress/plugin';
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
e2e: {
|
|
6
|
+
supportFile: 'cypress/support/e2e.ts',
|
|
7
|
+
specPattern: 'cypress/e2e/**/*.story.cy.ts',
|
|
8
|
+
setupNodeEvents(on) {
|
|
9
|
+
registerExecutableStoriesPlugin(on);
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
reporter: 'executable-stories-cypress/reporter.cjs',
|
|
13
|
+
reporterOptions: {
|
|
14
|
+
formats: ['markdown', 'html'],
|
|
15
|
+
outputDir: 'reports',
|
|
16
|
+
outputName: 'executable-stories',
|
|
17
|
+
output: { mode: 'aggregated' },
|
|
18
|
+
},
|
|
19
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { story } from 'executable-stories-cypress';
|
|
2
|
+
|
|
3
|
+
describe('Calculator', () => {
|
|
4
|
+
it('Adds two numbers', () => {
|
|
5
|
+
story.init();
|
|
6
|
+
|
|
7
|
+
story.given('two numbers 2 and 3');
|
|
8
|
+
const a = 2;
|
|
9
|
+
const b = 3;
|
|
10
|
+
|
|
11
|
+
story.when('the numbers are added');
|
|
12
|
+
const result = a + b;
|
|
13
|
+
|
|
14
|
+
story.then('the result is 5');
|
|
15
|
+
expect(result).toBe(5);
|
|
16
|
+
});
|
|
17
|
+
});
|
package/dist/templates/index.ts
CHANGED
|
@@ -11,8 +11,13 @@ const here = _fileDir.endsWith('/cli') ? join(_fileDir, '..', 'templates') : _fi
|
|
|
11
11
|
const _NAMES = [
|
|
12
12
|
'vitest-config.ts',
|
|
13
13
|
'playwright-config.ts',
|
|
14
|
+
'jest-config.mjs',
|
|
15
|
+
'cypress-config.ts',
|
|
16
|
+
'cypress-support-e2e.ts',
|
|
14
17
|
'vitest-sample.story.test.ts',
|
|
15
18
|
'playwright-sample.story.spec.ts',
|
|
19
|
+
'jest-sample.story.test.ts',
|
|
20
|
+
'cypress-sample.story.cy.ts',
|
|
16
21
|
'tsconfig.json',
|
|
17
22
|
] as const;
|
|
18
23
|
export type TemplateName = (typeof _NAMES)[number];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Jest config with executable-stories-jest. */
|
|
2
|
+
export default {
|
|
3
|
+
rootDir: process.cwd(),
|
|
4
|
+
testEnvironment: 'node',
|
|
5
|
+
testMatch: ['<rootDir>/src/**/*.story.test.ts'],
|
|
6
|
+
setupFilesAfterEnv: ['executable-stories-jest/setup'],
|
|
7
|
+
extensionsToTreatAsEsm: ['.ts'],
|
|
8
|
+
transform: {
|
|
9
|
+
'^.+\\.ts$': [
|
|
10
|
+
'ts-jest',
|
|
11
|
+
{
|
|
12
|
+
useESM: true,
|
|
13
|
+
tsconfig: '<rootDir>/tsconfig.json',
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
},
|
|
17
|
+
moduleNameMapper: {
|
|
18
|
+
'^(\\.{1,2}/.*)\\.js$': '$1',
|
|
19
|
+
},
|
|
20
|
+
reporters: [
|
|
21
|
+
'default',
|
|
22
|
+
[
|
|
23
|
+
'executable-stories-jest/reporter',
|
|
24
|
+
{
|
|
25
|
+
formats: ['markdown', 'html'],
|
|
26
|
+
outputDir: 'reports',
|
|
27
|
+
outputName: 'executable-stories',
|
|
28
|
+
output: { mode: 'aggregated' },
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
],
|
|
32
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { describe, expect, it } from '@jest/globals';
|
|
2
|
+
import { story } from 'executable-stories-jest';
|
|
3
|
+
|
|
4
|
+
describe('Calculator', () => {
|
|
5
|
+
it('Adds two numbers', () => {
|
|
6
|
+
story.init();
|
|
7
|
+
|
|
8
|
+
story.given('two numbers 2 and 3');
|
|
9
|
+
const a = 2;
|
|
10
|
+
const b = 3;
|
|
11
|
+
|
|
12
|
+
story.when('the numbers are added');
|
|
13
|
+
const result = a + b;
|
|
14
|
+
|
|
15
|
+
story.then('the result is 5');
|
|
16
|
+
expect(result).toBe(5);
|
|
17
|
+
});
|
|
18
|
+
});
|