executable-stories-cypress 8.1.3 → 8.1.5

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/bin/intent.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ await import('@tanstack/intent/intent-library')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "executable-stories-cypress",
3
- "version": "8.1.3",
3
+ "version": "8.1.5",
4
4
  "description": "BDD-style executable stories for Cypress with documentation generation",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -35,17 +35,17 @@
35
35
  "bin"
36
36
  ],
37
37
  "peerDependencies": {
38
- "cypress": ">=15.11.0"
38
+ "cypress": ">=15.13.1"
39
39
  },
40
40
  "dependencies": {
41
- "executable-stories-formatters": "0.7.2"
41
+ "executable-stories-formatters": "0.7.4"
42
42
  },
43
43
  "devDependencies": {
44
44
  "cypress": "^15.12.0",
45
- "@types/node": "^25.5.0",
45
+ "@types/node": "^25.6.0",
46
46
  "tsup": "^8.5.1",
47
- "typescript": "~5.9.3",
48
- "vitest": "^4.1.0"
47
+ "typescript": "~6.0.2",
48
+ "vitest": "^4.1.4"
49
49
  },
50
50
  "repository": {
51
51
  "type": "git",
@@ -1,136 +0,0 @@
1
- ---
2
- name: cypress-converting-tests
3
- description: >
4
- Incrementally adopt executable-stories in Cypress. Add story.init() and
5
- step markers to existing cy.ts spec files. File naming .story.cy.ts.
6
- Requires plugin + support file wiring. Progressive enhancement.
7
- type: lifecycle
8
- library: executable-stories-cypress
9
- library_version: "7.0.1"
10
- requires:
11
- - cypress-story-api
12
- sources:
13
- - "jagreehal/executable-stories:packages/executable-stories-cypress/src/index.ts"
14
- ---
15
-
16
- This skill builds on cypress-story-api. Read cypress-story-api first.
17
-
18
- # Converting Existing Cypress Tests
19
-
20
- ## Setup
21
-
22
- Install and configure the three wiring points:
23
-
24
- ```bash
25
- npm install -D executable-stories-cypress executable-stories-formatters
26
- ```
27
-
28
- ```typescript
29
- // cypress.config.ts
30
- import { defineConfig } from "cypress";
31
- import { registerExecutableStoriesPlugin } from "executable-stories-cypress/plugin";
32
-
33
- export default defineConfig({
34
- e2e: {
35
- setupNodeEvents(on) {
36
- registerExecutableStoriesPlugin(on);
37
- },
38
- },
39
- });
40
- ```
41
-
42
- ```typescript
43
- // cypress/support/e2e.ts
44
- import "executable-stories-cypress/support";
45
- ```
46
-
47
- ## Core Patterns
48
-
49
- ### Step 1: Rename the file
50
-
51
- ```
52
- # Before
53
- cypress/e2e/login.cy.ts
54
-
55
- # After
56
- cypress/e2e/login.story.cy.ts
57
- ```
58
-
59
- ### Step 2: Add story.init() and step markers
60
-
61
- ```typescript
62
- // Before
63
- describe("Login", () => {
64
- it("logs in successfully", () => {
65
- cy.visit("/login");
66
- cy.get("#email").type("user@example.com");
67
- cy.get("#password").type("secret");
68
- cy.get("#submit").click();
69
- cy.get("h1").should("contain", "Dashboard");
70
- });
71
- });
72
- ```
73
-
74
- ```typescript
75
- // After
76
- import { story } from "executable-stories-cypress";
77
-
78
- describe("Login", () => {
79
- it("logs in successfully", () => {
80
- story.init();
81
-
82
- story.given("the login page is loaded");
83
- cy.visit("/login");
84
-
85
- story.when("valid credentials are entered");
86
- cy.get("#email").type("user@example.com");
87
- cy.get("#password").type("secret");
88
- cy.get("#submit").click();
89
-
90
- story.then("the dashboard is shown");
91
- cy.get("h1").should("contain", "Dashboard");
92
- });
93
- });
94
- ```
95
-
96
- ### Step 3: Minimal story
97
-
98
- ```typescript
99
- it("loads homepage", () => {
100
- story.init();
101
- cy.visit("/");
102
- cy.title().should("eq", "My App");
103
- });
104
- ```
105
-
106
- ### Step 4: Add doc entries
107
-
108
- ```typescript
109
- it("shows product details", () => {
110
- story.init({ tags: ["e2e", "products"] });
111
-
112
- story.given("the product page is loaded");
113
- cy.visit("/products/123");
114
-
115
- story.then("the product details are shown");
116
- story.screenshot({ path: "screenshots/product.png", alt: "Product page" });
117
- story.json({ label: "Product", value: { id: 123, name: "Widget" } });
118
- });
119
- ```
120
-
121
- ## Common Mistakes
122
-
123
- ### HIGH Using wrong file extension
124
-
125
- Wrong: `login.story.test.ts` or `login.story.spec.ts`
126
- Correct: `login.story.cy.ts`
127
-
128
- Cypress convention uses `.cy.ts`. The reporter and file matching expect this extension.
129
-
130
- Source: CLAUDE.md — file naming conventions
131
-
132
- ### CRITICAL Forgetting plugin or support file
133
-
134
- Both `registerExecutableStoriesPlugin(on)` in cypress.config.ts AND `import "executable-stories-cypress/support"` in e2e.ts are required. Missing either one causes silent failures — stories record in the browser but never reach the reporter.
135
-
136
- Source: packages/executable-stories-cypress/src/plugin.ts, packages/executable-stories-cypress/src/support.ts
@@ -1,113 +0,0 @@
1
- ---
2
- name: cypress-reporter-setup
3
- description: >
4
- Configure Cypress reporter for executable-stories-cypress. Mocha reporter
5
- via --reporter flag or cypress.config.ts. Module API for programmatic use
6
- with buildRawRunFromCypressResult and generateReportsFromRawRun. Output
7
- formats, directory, naming.
8
- type: core
9
- library: executable-stories-cypress
10
- library_version: "7.0.1"
11
- sources:
12
- - "jagreehal/executable-stories:packages/executable-stories-cypress/src/reporter.ts"
13
- ---
14
-
15
- # executable-stories-cypress — Reporter Setup
16
-
17
- ## Setup
18
-
19
- ### Option A: Mocha reporter (CLI)
20
-
21
- ```bash
22
- cypress run \
23
- --reporter executable-stories-cypress/reporter \
24
- --reporter-options "outputDir=docs,outputName=user-stories,formats=markdown"
25
- ```
26
-
27
- ### Option B: Module API (programmatic)
28
-
29
- ```typescript
30
- // cypress.config.ts
31
- import { defineConfig } from "cypress";
32
- import { registerExecutableStoriesPlugin } from "executable-stories-cypress/plugin";
33
- import {
34
- buildRawRunFromCypressResult,
35
- generateReportsFromRawRun,
36
- } from "executable-stories-cypress/reporter";
37
-
38
- export default defineConfig({
39
- e2e: {
40
- setupNodeEvents(on) {
41
- registerExecutableStoriesPlugin(on);
42
- },
43
- },
44
- });
45
-
46
- // After cypress.run() completes:
47
- const result = await cypress.run();
48
- const rawRun = buildRawRunFromCypressResult(result, { outputDir: "docs" });
49
- await generateReportsFromRawRun(rawRun, {
50
- formats: ["markdown", "html"],
51
- outputDir: "docs",
52
- outputName: "user-stories",
53
- });
54
- ```
55
-
56
- Peer dependency: `executable-stories-formatters` must be installed.
57
-
58
- ## Core Patterns
59
-
60
- ### Mocha reporter with all options
61
-
62
- ```bash
63
- cypress run \
64
- --reporter executable-stories-cypress/reporter \
65
- --reporter-options "outputDir=reports,outputName=test-results,formats=markdown+html+junit"
66
- ```
67
-
68
- ### Module API for CI pipelines
69
-
70
- ```typescript
71
- import cypress from "cypress";
72
- import {
73
- buildRawRunFromCypressResult,
74
- generateReportsFromRawRun,
75
- } from "executable-stories-cypress/reporter";
76
-
77
- const result = await cypress.run({ spec: "cypress/e2e/**/*.story.cy.ts" });
78
-
79
- if (result.status === "finished") {
80
- const rawRun = buildRawRunFromCypressResult(result);
81
- await generateReportsFromRawRun(rawRun, {
82
- formats: ["markdown"],
83
- outputDir: "docs",
84
- outputName: "cypress-stories",
85
- });
86
- }
87
- ```
88
-
89
- ## Common Mistakes
90
-
91
- ### CRITICAL Forgetting plugin + support wiring
92
-
93
- The reporter only works if both the plugin and support file are configured. Without them, the reporter has no story metadata to process. See cypress-story-api/SKILL.md for the required wiring.
94
-
95
- ### HIGH Using reporter without Module API in afterRun
96
-
97
- Wrong:
98
-
99
- ```typescript
100
- // Expecting reporter to auto-generate reports
101
- export default defineConfig({
102
- e2e: {
103
- setupNodeEvents(on) {
104
- registerExecutableStoriesPlugin(on);
105
- },
106
- },
107
- reporter: "executable-stories-cypress/reporter",
108
- });
109
- ```
110
-
111
- The Mocha reporter approach works for CLI usage (`cypress run --reporter`). For programmatic usage with `cypress.run()`, use the Module API (`buildRawRunFromCypressResult` + `generateReportsFromRawRun`).
112
-
113
- Source: packages/executable-stories-cypress/src/reporter.ts
@@ -1,218 +0,0 @@
1
- ---
2
- name: cypress-story-api
3
- description: >
4
- Write BDD stories in Cypress using executable-stories-cypress. story.init()
5
- with optional StoryOptions. Steps: story.given, story.when, story.then,
6
- story.and, story.but. Doc entries: json, kv, code, table, link, section,
7
- mermaid, screenshot, note, tag. Auto-And keyword conversion. Browser-Node
8
- bridge via cy.task. Aliases: arrange, act, assert.
9
- type: core
10
- library: executable-stories-cypress
11
- library_version: "7.0.1"
12
- sources:
13
- - "jagreehal/executable-stories:packages/executable-stories-cypress/src/story-api.ts"
14
- - "jagreehal/executable-stories:packages/executable-stories-cypress/src/index.ts"
15
- ---
16
-
17
- # executable-stories-cypress — Story API
18
-
19
- ## Setup
20
-
21
- Three wiring steps are required:
22
-
23
- ```typescript
24
- // 1. cypress.config.ts — register the plugin
25
- import { defineConfig } from "cypress";
26
- import { registerExecutableStoriesPlugin } from "executable-stories-cypress/plugin";
27
-
28
- export default defineConfig({
29
- e2e: {
30
- setupNodeEvents(on) {
31
- registerExecutableStoriesPlugin(on);
32
- },
33
- },
34
- });
35
- ```
36
-
37
- ```typescript
38
- // 2. cypress/support/e2e.ts — import the support file
39
- import "executable-stories-cypress/support";
40
- ```
41
-
42
- ```typescript
43
- // 3. cypress/e2e/checkout.story.cy.ts — write a story test
44
- import { story } from "executable-stories-cypress";
45
-
46
- describe("Cart checkout", () => {
47
- it("applies discount code", () => {
48
- story.init({ tags: ["checkout"], ticket: "CART-42" });
49
-
50
- story.given("a cart with items totaling $100");
51
- cy.visit("/cart");
52
- cy.get("[data-testid=total]").should("contain", "$100");
53
-
54
- story.when("a 20% discount code is applied");
55
- cy.get("#discount-code").type("SAVE20");
56
- cy.get("#apply-discount").click();
57
-
58
- story.then("the total is $80");
59
- cy.get("[data-testid=total]").should("contain", "$80");
60
- });
61
- });
62
- ```
63
-
64
- File naming: `*.story.cy.ts`.
65
-
66
- ## Core Patterns
67
-
68
- ### Step markers with Auto-And conversion
69
-
70
- ```typescript
71
- it("blocks suspended user login", () => {
72
- story.init();
73
-
74
- story.given("the user account exists"); // renders "Given"
75
- story.given("the account is suspended"); // renders "And" (auto-converted)
76
- story.when("the user submits valid credentials");
77
- cy.get("#email").type("user@test.com");
78
- cy.get("#submit").click();
79
-
80
- story.then("the user sees an error message");
81
- cy.get(".error").should("be.visible");
82
-
83
- story.but("the user is not logged in"); // renders "But" (always)
84
- cy.url().should("include", "/login");
85
- });
86
- ```
87
-
88
- ### Doc entries
89
-
90
- ```typescript
91
- it("processes payment", () => {
92
- story.init();
93
-
94
- story.given("a valid payment request");
95
- story.json({ label: "Payload", value: { amount: 50, currency: "USD" } });
96
-
97
- story.when("the payment is submitted");
98
- cy.get("#pay").click();
99
-
100
- story.then("the order is confirmed");
101
- story.table({
102
- label: "Order summary",
103
- columns: ["Item", "Qty", "Price"],
104
- rows: [["Widget", "2", "$25"]],
105
- });
106
- story.screenshot({ path: "screenshots/confirmation.png", alt: "Confirmation" });
107
- story.note("Payment processed in sandbox mode");
108
- });
109
- ```
110
-
111
- ### Step wrappers
112
-
113
- ```typescript
114
- const result = story.fn("When", "the calculation runs", () => {
115
- return calculate(2, 3);
116
- });
117
-
118
- story.expect("the result is correct", () => {
119
- expect(result).to.equal(5);
120
- });
121
- ```
122
-
123
- ## Common Mistakes
124
-
125
- ### CRITICAL Missing plugin registration
126
-
127
- Wrong:
128
-
129
- ```typescript
130
- // cypress.config.ts
131
- export default defineConfig({
132
- e2e: {
133
- setupNodeEvents(on) {
134
- // No plugin registered
135
- },
136
- },
137
- });
138
- ```
139
-
140
- Correct:
141
-
142
- ```typescript
143
- import { registerExecutableStoriesPlugin } from "executable-stories-cypress/plugin";
144
-
145
- export default defineConfig({
146
- e2e: {
147
- setupNodeEvents(on) {
148
- registerExecutableStoriesPlugin(on);
149
- },
150
- },
151
- });
152
- ```
153
-
154
- The plugin registers `cy.task` handlers for `executableStories:recordMeta`. Without it, the support file's `afterEach` hook fails silently and no story metadata is captured.
155
-
156
- Source: packages/executable-stories-cypress/src/plugin.ts
157
-
158
- ### CRITICAL Missing support file import
159
-
160
- Wrong:
161
-
162
- ```typescript
163
- // cypress/support/e2e.ts
164
- // (no executable-stories import)
165
- ```
166
-
167
- Correct:
168
-
169
- ```typescript
170
- // cypress/support/e2e.ts
171
- import "executable-stories-cypress/support";
172
- ```
173
-
174
- The support file registers an `afterEach` hook that sends story metadata from the browser to Node via `cy.task`. Without it, stories are recorded in the browser but never reach the reporter.
175
-
176
- Source: packages/executable-stories-cypress/src/support.ts
177
-
178
- ### HIGH Using wrong file extension
179
-
180
- Wrong:
181
-
182
- ```
183
- cypress/e2e/checkout.story.test.ts
184
- ```
185
-
186
- Correct:
187
-
188
- ```
189
- cypress/e2e/checkout.story.cy.ts
190
- ```
191
-
192
- Cypress uses `.cy.ts` file extensions. The reporter expects `.story.cy.ts` for story test files.
193
-
194
- Source: CLAUDE.md — "Story test files use .story.cy.ts (cypress)"
195
-
196
- ### MEDIUM Calling steps before story.init()
197
-
198
- Wrong:
199
-
200
- ```typescript
201
- it("my test", () => {
202
- story.given("something");
203
- story.init();
204
- });
205
- ```
206
-
207
- Correct:
208
-
209
- ```typescript
210
- it("my test", () => {
211
- story.init();
212
- story.given("something");
213
- });
214
- ```
215
-
216
- Steps called before `init()` are silently dropped because no story context exists.
217
-
218
- Source: packages/executable-stories-cypress/src/story-api.ts