@gherkle/runner 0.1.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/README.md +482 -0
- package/bin/gherkle-runner.js +111 -0
- package/dist/__tests__/agent-executor-selection.test.d.ts +15 -0
- package/dist/__tests__/agent-executor-selection.test.d.ts.map +1 -0
- package/dist/__tests__/agent-executor-selection.test.js +192 -0
- package/dist/__tests__/agent-executor-selection.test.js.map +1 -0
- package/dist/__tests__/envelope-mapper.test.d.ts +17 -0
- package/dist/__tests__/envelope-mapper.test.d.ts.map +1 -0
- package/dist/__tests__/envelope-mapper.test.js +217 -0
- package/dist/__tests__/envelope-mapper.test.js.map +1 -0
- package/dist/__tests__/gherkin-parser.test.d.ts +2 -0
- package/dist/__tests__/gherkin-parser.test.d.ts.map +1 -0
- package/dist/__tests__/gherkin-parser.test.js +375 -0
- package/dist/__tests__/gherkin-parser.test.js.map +1 -0
- package/dist/__tests__/integration-fork.test.d.ts +16 -0
- package/dist/__tests__/integration-fork.test.d.ts.map +1 -0
- package/dist/__tests__/integration-fork.test.js +141 -0
- package/dist/__tests__/integration-fork.test.js.map +1 -0
- package/dist/__tests__/tmpdir-materialization.test.d.ts +18 -0
- package/dist/__tests__/tmpdir-materialization.test.d.ts.map +1 -0
- package/dist/__tests__/tmpdir-materialization.test.js +177 -0
- package/dist/__tests__/tmpdir-materialization.test.js.map +1 -0
- package/dist/agent.d.ts +71 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +312 -0
- package/dist/agent.js.map +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +165 -0
- package/dist/config.js.map +1 -0
- package/dist/frameworks/cucumber-subprocess.d.ts +129 -0
- package/dist/frameworks/cucumber-subprocess.d.ts.map +1 -0
- package/dist/frameworks/cucumber-subprocess.js +469 -0
- package/dist/frameworks/cucumber-subprocess.js.map +1 -0
- package/dist/frameworks/playwright.d.ts +22 -0
- package/dist/frameworks/playwright.d.ts.map +1 -0
- package/dist/frameworks/playwright.js +234 -0
- package/dist/frameworks/playwright.js.map +1 -0
- package/dist/gherkin-parser.d.ts +22 -0
- package/dist/gherkin-parser.d.ts.map +1 -0
- package/dist/gherkin-parser.js +148 -0
- package/dist/gherkin-parser.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/step-registry.d.ts +30 -0
- package/dist/step-registry.d.ts.map +1 -0
- package/dist/step-registry.js +160 -0
- package/dist/step-registry.js.map +1 -0
- package/dist/types.d.ts +117 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/workers/cucumber-worker.d.ts +29 -0
- package/dist/workers/cucumber-worker.d.ts.map +1 -0
- package/dist/workers/cucumber-worker.js +191 -0
- package/dist/workers/cucumber-worker.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const gherkin_parser_1 = require("../gherkin-parser");
|
|
5
|
+
(0, vitest_1.describe)("parseGherkinContent", () => {
|
|
6
|
+
(0, vitest_1.describe)("basic feature parsing", () => {
|
|
7
|
+
(0, vitest_1.it)("parses a minimal feature with one scenario", () => {
|
|
8
|
+
const content = `
|
|
9
|
+
Feature: Login
|
|
10
|
+
Scenario: Successful login
|
|
11
|
+
Given the user is on the login page
|
|
12
|
+
When the user enters valid credentials
|
|
13
|
+
Then the user sees the dashboard
|
|
14
|
+
`;
|
|
15
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
16
|
+
(0, vitest_1.expect)(result.name).toBe("Login");
|
|
17
|
+
(0, vitest_1.expect)(result.scenarios).toHaveLength(1);
|
|
18
|
+
(0, vitest_1.expect)(result.scenarios[0].name).toBe("Successful login");
|
|
19
|
+
(0, vitest_1.expect)(result.scenarios[0].steps).toHaveLength(3);
|
|
20
|
+
});
|
|
21
|
+
(0, vitest_1.it)("extracts feature description", () => {
|
|
22
|
+
const content = `
|
|
23
|
+
Feature: User Management
|
|
24
|
+
As an admin
|
|
25
|
+
I want to manage users
|
|
26
|
+
So that I can control access
|
|
27
|
+
|
|
28
|
+
Scenario: View users
|
|
29
|
+
Given I am an admin
|
|
30
|
+
Then I see the user list
|
|
31
|
+
`;
|
|
32
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
33
|
+
(0, vitest_1.expect)(result.name).toBe("User Management");
|
|
34
|
+
(0, vitest_1.expect)(result.description).toContain("manage users");
|
|
35
|
+
});
|
|
36
|
+
(0, vitest_1.it)("throws when no Feature keyword is found", () => {
|
|
37
|
+
const content = `
|
|
38
|
+
Scenario: Orphan scenario
|
|
39
|
+
Given something
|
|
40
|
+
`;
|
|
41
|
+
(0, vitest_1.expect)(() => (0, gherkin_parser_1.parseGherkinContent)(content)).toThrow();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
(0, vitest_1.describe)("step keyword mapping", () => {
|
|
45
|
+
(0, vitest_1.it)("correctly maps Given, When, Then keywords", () => {
|
|
46
|
+
const content = `
|
|
47
|
+
Feature: Keywords
|
|
48
|
+
Scenario: All keywords
|
|
49
|
+
Given a precondition
|
|
50
|
+
When an action
|
|
51
|
+
Then a result
|
|
52
|
+
`;
|
|
53
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
54
|
+
const steps = result.scenarios[0].steps;
|
|
55
|
+
(0, vitest_1.expect)(steps[0].keyword).toBe("Given");
|
|
56
|
+
(0, vitest_1.expect)(steps[1].keyword).toBe("When");
|
|
57
|
+
(0, vitest_1.expect)(steps[2].keyword).toBe("Then");
|
|
58
|
+
});
|
|
59
|
+
(0, vitest_1.it)("maps And and But keywords", () => {
|
|
60
|
+
const content = `
|
|
61
|
+
Feature: Conjunctions
|
|
62
|
+
Scenario: With And and But
|
|
63
|
+
Given a precondition
|
|
64
|
+
And another precondition
|
|
65
|
+
When an action
|
|
66
|
+
But not this action
|
|
67
|
+
Then a result
|
|
68
|
+
`;
|
|
69
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
70
|
+
const steps = result.scenarios[0].steps;
|
|
71
|
+
(0, vitest_1.expect)(steps[0].keyword).toBe("Given");
|
|
72
|
+
(0, vitest_1.expect)(steps[1].keyword).toBe("And");
|
|
73
|
+
(0, vitest_1.expect)(steps[2].keyword).toBe("When");
|
|
74
|
+
(0, vitest_1.expect)(steps[3].keyword).toBe("But");
|
|
75
|
+
(0, vitest_1.expect)(steps[4].keyword).toBe("Then");
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
(0, vitest_1.describe)("multiple scenarios", () => {
|
|
79
|
+
(0, vitest_1.it)("parses multiple scenarios in one feature", () => {
|
|
80
|
+
const content = `
|
|
81
|
+
Feature: Shopping Cart
|
|
82
|
+
Scenario: Add item
|
|
83
|
+
Given the cart is empty
|
|
84
|
+
When I add an item
|
|
85
|
+
Then the cart has 1 item
|
|
86
|
+
|
|
87
|
+
Scenario: Remove item
|
|
88
|
+
Given the cart has 1 item
|
|
89
|
+
When I remove the item
|
|
90
|
+
Then the cart is empty
|
|
91
|
+
`;
|
|
92
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
93
|
+
(0, vitest_1.expect)(result.scenarios).toHaveLength(2);
|
|
94
|
+
(0, vitest_1.expect)(result.scenarios[0].name).toBe("Add item");
|
|
95
|
+
(0, vitest_1.expect)(result.scenarios[1].name).toBe("Remove item");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
(0, vitest_1.describe)("tags", () => {
|
|
99
|
+
(0, vitest_1.it)("parses feature-level tags", () => {
|
|
100
|
+
const content = `
|
|
101
|
+
@smoke @regression
|
|
102
|
+
Feature: Tagged Feature
|
|
103
|
+
Scenario: Basic
|
|
104
|
+
Given something
|
|
105
|
+
`;
|
|
106
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
107
|
+
(0, vitest_1.expect)(result.tags).toContain("@smoke");
|
|
108
|
+
(0, vitest_1.expect)(result.tags).toContain("@regression");
|
|
109
|
+
});
|
|
110
|
+
(0, vitest_1.it)("parses scenario-level tags", () => {
|
|
111
|
+
const content = `
|
|
112
|
+
Feature: Scenario Tags
|
|
113
|
+
@wip
|
|
114
|
+
Scenario: Work in progress
|
|
115
|
+
Given something
|
|
116
|
+
|
|
117
|
+
@critical
|
|
118
|
+
Scenario: Critical path
|
|
119
|
+
Given something else
|
|
120
|
+
`;
|
|
121
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
122
|
+
(0, vitest_1.expect)(result.scenarios[0].tags).toContain("@wip");
|
|
123
|
+
(0, vitest_1.expect)(result.scenarios[1].tags).toContain("@critical");
|
|
124
|
+
});
|
|
125
|
+
(0, vitest_1.it)("handles both feature and scenario tags", () => {
|
|
126
|
+
const content = `
|
|
127
|
+
@api
|
|
128
|
+
Feature: API Tests
|
|
129
|
+
@auth
|
|
130
|
+
Scenario: Authenticated request
|
|
131
|
+
Given I have a valid token
|
|
132
|
+
`;
|
|
133
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
134
|
+
(0, vitest_1.expect)(result.tags).toContain("@api");
|
|
135
|
+
(0, vitest_1.expect)(result.scenarios[0].tags).toContain("@auth");
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
(0, vitest_1.describe)("Background", () => {
|
|
139
|
+
(0, vitest_1.it)("parses Background steps", () => {
|
|
140
|
+
const content = `
|
|
141
|
+
Feature: With Background
|
|
142
|
+
Background:
|
|
143
|
+
Given the system is running
|
|
144
|
+
And the database is seeded
|
|
145
|
+
|
|
146
|
+
Scenario: First scenario
|
|
147
|
+
When I do something
|
|
148
|
+
Then something happens
|
|
149
|
+
`;
|
|
150
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
151
|
+
(0, vitest_1.expect)(result.background).not.toBeNull();
|
|
152
|
+
(0, vitest_1.expect)(result.background).toHaveLength(2);
|
|
153
|
+
(0, vitest_1.expect)(result.background[0].keyword).toBe("Given");
|
|
154
|
+
(0, vitest_1.expect)(result.background[0].text).toBe("the system is running");
|
|
155
|
+
(0, vitest_1.expect)(result.background[1].keyword).toBe("And");
|
|
156
|
+
(0, vitest_1.expect)(result.background[1].text).toBe("the database is seeded");
|
|
157
|
+
});
|
|
158
|
+
(0, vitest_1.it)("returns null background when none is defined", () => {
|
|
159
|
+
const content = `
|
|
160
|
+
Feature: No Background
|
|
161
|
+
Scenario: Simple
|
|
162
|
+
Given something
|
|
163
|
+
`;
|
|
164
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
165
|
+
(0, vitest_1.expect)(result.background).toBeNull();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
(0, vitest_1.describe)("Data Tables", () => {
|
|
169
|
+
(0, vitest_1.it)("parses a step with a data table", () => {
|
|
170
|
+
const content = `
|
|
171
|
+
Feature: Data Tables
|
|
172
|
+
Scenario: Users table
|
|
173
|
+
Given the following users exist:
|
|
174
|
+
| name | email | role |
|
|
175
|
+
| Alice | alice@test.com | admin |
|
|
176
|
+
| Bob | bob@test.com | user |
|
|
177
|
+
`;
|
|
178
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
179
|
+
const step = result.scenarios[0].steps[0];
|
|
180
|
+
(0, vitest_1.expect)(step.dataTable).toBeDefined();
|
|
181
|
+
(0, vitest_1.expect)(step.dataTable).toHaveLength(3);
|
|
182
|
+
(0, vitest_1.expect)(step.dataTable[0]).toEqual(["name", "email", "role"]);
|
|
183
|
+
(0, vitest_1.expect)(step.dataTable[1]).toEqual(["Alice", "alice@test.com", "admin"]);
|
|
184
|
+
(0, vitest_1.expect)(step.dataTable[2]).toEqual(["Bob", "bob@test.com", "user"]);
|
|
185
|
+
});
|
|
186
|
+
(0, vitest_1.it)("steps without data tables have undefined dataTable", () => {
|
|
187
|
+
const content = `
|
|
188
|
+
Feature: No Tables
|
|
189
|
+
Scenario: Simple
|
|
190
|
+
Given a step without a table
|
|
191
|
+
`;
|
|
192
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
193
|
+
(0, vitest_1.expect)(result.scenarios[0].steps[0].dataTable).toBeUndefined();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
(0, vitest_1.describe)("Doc Strings", () => {
|
|
197
|
+
(0, vitest_1.it)("parses a step with a doc string", () => {
|
|
198
|
+
const content = `
|
|
199
|
+
Feature: Doc Strings
|
|
200
|
+
Scenario: JSON payload
|
|
201
|
+
Given the request body is:
|
|
202
|
+
"""
|
|
203
|
+
{
|
|
204
|
+
"name": "Test",
|
|
205
|
+
"value": 42
|
|
206
|
+
}
|
|
207
|
+
"""
|
|
208
|
+
`;
|
|
209
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
210
|
+
const step = result.scenarios[0].steps[0];
|
|
211
|
+
(0, vitest_1.expect)(step.docString).toBeDefined();
|
|
212
|
+
(0, vitest_1.expect)(step.docString).toContain('"name": "Test"');
|
|
213
|
+
(0, vitest_1.expect)(step.docString).toContain('"value": 42');
|
|
214
|
+
});
|
|
215
|
+
(0, vitest_1.it)("steps without doc strings have undefined docString", () => {
|
|
216
|
+
const content = `
|
|
217
|
+
Feature: No Doc Strings
|
|
218
|
+
Scenario: Simple
|
|
219
|
+
Given a step without a doc string
|
|
220
|
+
`;
|
|
221
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
222
|
+
(0, vitest_1.expect)(result.scenarios[0].steps[0].docString).toBeUndefined();
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
(0, vitest_1.describe)("Scenario Outline", () => {
|
|
226
|
+
(0, vitest_1.it)("expands a Scenario Outline into multiple scenarios", () => {
|
|
227
|
+
const content = `
|
|
228
|
+
Feature: Scenario Outline
|
|
229
|
+
Scenario Outline: Login with <username>
|
|
230
|
+
Given the user "<username>" exists
|
|
231
|
+
When they login with password "<password>"
|
|
232
|
+
Then login is "<result>"
|
|
233
|
+
|
|
234
|
+
Examples:
|
|
235
|
+
| username | password | result |
|
|
236
|
+
| alice | pass123 | success |
|
|
237
|
+
| bob | wrong | failure |
|
|
238
|
+
`;
|
|
239
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
240
|
+
(0, vitest_1.expect)(result.scenarios).toHaveLength(2);
|
|
241
|
+
(0, vitest_1.expect)(result.scenarios[0].name).toContain("alice");
|
|
242
|
+
(0, vitest_1.expect)(result.scenarios[0].steps[0].text).toBe('the user "alice" exists');
|
|
243
|
+
(0, vitest_1.expect)(result.scenarios[0].steps[1].text).toBe('they login with password "pass123"');
|
|
244
|
+
(0, vitest_1.expect)(result.scenarios[0].steps[2].text).toBe('login is "success"');
|
|
245
|
+
(0, vitest_1.expect)(result.scenarios[1].name).toContain("bob");
|
|
246
|
+
(0, vitest_1.expect)(result.scenarios[1].steps[0].text).toBe('the user "bob" exists');
|
|
247
|
+
(0, vitest_1.expect)(result.scenarios[1].steps[1].text).toBe('they login with password "wrong"');
|
|
248
|
+
(0, vitest_1.expect)(result.scenarios[1].steps[2].text).toBe('login is "failure"');
|
|
249
|
+
});
|
|
250
|
+
(0, vitest_1.it)("preserves tags on expanded scenarios", () => {
|
|
251
|
+
const content = `
|
|
252
|
+
Feature: Tagged Outline
|
|
253
|
+
@outline-tag
|
|
254
|
+
Scenario Outline: Test <item>
|
|
255
|
+
Given I have <item>
|
|
256
|
+
|
|
257
|
+
@example-tag
|
|
258
|
+
Examples:
|
|
259
|
+
| item |
|
|
260
|
+
| apples |
|
|
261
|
+
| oranges |
|
|
262
|
+
`;
|
|
263
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
264
|
+
(0, vitest_1.expect)(result.scenarios).toHaveLength(2);
|
|
265
|
+
for (const scenario of result.scenarios) {
|
|
266
|
+
(0, vitest_1.expect)(scenario.tags).toContain("@outline-tag");
|
|
267
|
+
(0, vitest_1.expect)(scenario.tags).toContain("@example-tag");
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
(0, vitest_1.it)("handles multiple Examples blocks", () => {
|
|
271
|
+
const content = `
|
|
272
|
+
Feature: Multiple Examples
|
|
273
|
+
Scenario Outline: Compute <a> + <b>
|
|
274
|
+
Given a is <a>
|
|
275
|
+
And b is <b>
|
|
276
|
+
Then result is <result>
|
|
277
|
+
|
|
278
|
+
Examples: Small numbers
|
|
279
|
+
| a | b | result |
|
|
280
|
+
| 1 | 2 | 3 |
|
|
281
|
+
|
|
282
|
+
Examples: Large numbers
|
|
283
|
+
| a | b | result |
|
|
284
|
+
| 100 | 200 | 300 |
|
|
285
|
+
`;
|
|
286
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
287
|
+
(0, vitest_1.expect)(result.scenarios).toHaveLength(2);
|
|
288
|
+
(0, vitest_1.expect)(result.scenarios[0].steps[0].text).toBe("a is 1");
|
|
289
|
+
(0, vitest_1.expect)(result.scenarios[1].steps[0].text).toBe("a is 100");
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
(0, vitest_1.describe)("line numbers", () => {
|
|
293
|
+
(0, vitest_1.it)("captures line numbers for scenarios", () => {
|
|
294
|
+
const content = `Feature: Lines
|
|
295
|
+
Scenario: First
|
|
296
|
+
Given step one
|
|
297
|
+
|
|
298
|
+
Scenario: Second
|
|
299
|
+
Given step two
|
|
300
|
+
`;
|
|
301
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
302
|
+
(0, vitest_1.expect)(result.scenarios[0].line).toBeGreaterThan(0);
|
|
303
|
+
(0, vitest_1.expect)(result.scenarios[1].line).toBeGreaterThan(result.scenarios[0].line);
|
|
304
|
+
});
|
|
305
|
+
(0, vitest_1.it)("captures line numbers for steps", () => {
|
|
306
|
+
const content = `Feature: Step Lines
|
|
307
|
+
Scenario: Test
|
|
308
|
+
Given first step
|
|
309
|
+
When second step
|
|
310
|
+
Then third step
|
|
311
|
+
`;
|
|
312
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
313
|
+
const steps = result.scenarios[0].steps;
|
|
314
|
+
(0, vitest_1.expect)(steps[0].line).toBeGreaterThan(0);
|
|
315
|
+
(0, vitest_1.expect)(steps[1].line).toBeGreaterThan(steps[0].line);
|
|
316
|
+
(0, vitest_1.expect)(steps[2].line).toBeGreaterThan(steps[1].line);
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
(0, vitest_1.describe)("complex feature file", () => {
|
|
320
|
+
(0, vitest_1.it)("parses a comprehensive feature file", () => {
|
|
321
|
+
const content = `
|
|
322
|
+
@e2e @shopping
|
|
323
|
+
Feature: Shopping Cart Management
|
|
324
|
+
As a customer
|
|
325
|
+
I want to manage my shopping cart
|
|
326
|
+
So that I can purchase items
|
|
327
|
+
|
|
328
|
+
Background:
|
|
329
|
+
Given I am logged in as a customer
|
|
330
|
+
And I have an empty cart
|
|
331
|
+
|
|
332
|
+
@happy-path
|
|
333
|
+
Scenario: Add single item to cart
|
|
334
|
+
When I add "Widget A" to the cart
|
|
335
|
+
Then my cart should contain 1 item
|
|
336
|
+
And the total should be "$9.99"
|
|
337
|
+
|
|
338
|
+
@edge-case
|
|
339
|
+
Scenario: Add item with special characters
|
|
340
|
+
When I add "Widget \"Special\" Edition" to the cart
|
|
341
|
+
Then my cart should contain 1 item
|
|
342
|
+
|
|
343
|
+
Scenario Outline: Add multiple quantities
|
|
344
|
+
When I add <quantity> of "<item>" to the cart
|
|
345
|
+
Then my cart total should be "<total>"
|
|
346
|
+
|
|
347
|
+
Examples:
|
|
348
|
+
| quantity | item | total |
|
|
349
|
+
| 2 | Widget A | $19.98 |
|
|
350
|
+
| 3 | Widget B | $29.97 |
|
|
351
|
+
|
|
352
|
+
Scenario: View cart with data table
|
|
353
|
+
Given the cart contains:
|
|
354
|
+
| item | quantity | price |
|
|
355
|
+
| Widget A | 2 | 9.99 |
|
|
356
|
+
| Widget B | 1 | 9.99 |
|
|
357
|
+
When I view the cart
|
|
358
|
+
Then the total should be "$29.97"
|
|
359
|
+
`;
|
|
360
|
+
const result = (0, gherkin_parser_1.parseGherkinContent)(content);
|
|
361
|
+
(0, vitest_1.expect)(result.name).toBe("Shopping Cart Management");
|
|
362
|
+
(0, vitest_1.expect)(result.tags).toContain("@e2e");
|
|
363
|
+
(0, vitest_1.expect)(result.tags).toContain("@shopping");
|
|
364
|
+
(0, vitest_1.expect)(result.description).toContain("shopping cart");
|
|
365
|
+
(0, vitest_1.expect)(result.background).toHaveLength(2);
|
|
366
|
+
(0, vitest_1.expect)(result.scenarios).toHaveLength(5);
|
|
367
|
+
(0, vitest_1.expect)(result.scenarios[0].tags).toContain("@happy-path");
|
|
368
|
+
(0, vitest_1.expect)(result.scenarios[1].tags).toContain("@edge-case");
|
|
369
|
+
const lastScenario = result.scenarios[4];
|
|
370
|
+
(0, vitest_1.expect)(lastScenario.steps[0].dataTable).toBeDefined();
|
|
371
|
+
(0, vitest_1.expect)(lastScenario.steps[0].dataTable).toHaveLength(3);
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
//# sourceMappingURL=gherkin-parser.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gherkin-parser.test.js","sourceRoot":"","sources":["../../src/__tests__/gherkin-parser.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for the CucumberSubprocessExecutor fork lifecycle.
|
|
3
|
+
*
|
|
4
|
+
* These tests really fork a child process — they use stub worker scripts
|
|
5
|
+
* in ./fixtures/ that mimic the IPC contract without depending on
|
|
6
|
+
* @cucumber/cucumber or chromium. This verifies the real plumbing
|
|
7
|
+
* (fork → IPC messages → exit → cleanup, and SIGTERM-based cancel) without
|
|
8
|
+
* the cost of launching a browser.
|
|
9
|
+
*
|
|
10
|
+
* Coverage:
|
|
11
|
+
* - Happy path: full envelope stream → resolved scenarios + tmpdir cleaned
|
|
12
|
+
* - Fatal: worker reports fatal then exits → executeAll rejects
|
|
13
|
+
* - Cancel: cancel() during hang → SIGTERM → resolved partial scenarios
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=integration-fork.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-fork.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/integration-fork.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Integration tests for the CucumberSubprocessExecutor fork lifecycle.
|
|
4
|
+
*
|
|
5
|
+
* These tests really fork a child process — they use stub worker scripts
|
|
6
|
+
* in ./fixtures/ that mimic the IPC contract without depending on
|
|
7
|
+
* @cucumber/cucumber or chromium. This verifies the real plumbing
|
|
8
|
+
* (fork → IPC messages → exit → cleanup, and SIGTERM-based cancel) without
|
|
9
|
+
* the cost of launching a browser.
|
|
10
|
+
*
|
|
11
|
+
* Coverage:
|
|
12
|
+
* - Happy path: full envelope stream → resolved scenarios + tmpdir cleaned
|
|
13
|
+
* - Fatal: worker reports fatal then exits → executeAll rejects
|
|
14
|
+
* - Cancel: cancel() during hang → SIGTERM → resolved partial scenarios
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
const vitest_1 = require("vitest");
|
|
51
|
+
const fs = __importStar(require("node:fs/promises"));
|
|
52
|
+
const path = __importStar(require("node:path"));
|
|
53
|
+
const cucumber_subprocess_1 = require("../frameworks/cucumber-subprocess");
|
|
54
|
+
const FIXTURES = path.join(__dirname, 'fixtures');
|
|
55
|
+
const noopCallbacks = {
|
|
56
|
+
onScenarioStart: () => { },
|
|
57
|
+
onStepComplete: () => { },
|
|
58
|
+
onScenarioComplete: () => { },
|
|
59
|
+
};
|
|
60
|
+
const dummyFeature = {
|
|
61
|
+
id: 'feat-1',
|
|
62
|
+
name: 'features/x.feature',
|
|
63
|
+
path: 'features/x.feature',
|
|
64
|
+
content: 'Feature: x\n Scenario: y\n Given z\n',
|
|
65
|
+
};
|
|
66
|
+
const dummyStepDef = {
|
|
67
|
+
featureId: 'feat-1',
|
|
68
|
+
filename: 'steps.js',
|
|
69
|
+
content: '// stub',
|
|
70
|
+
language: 'javascript',
|
|
71
|
+
};
|
|
72
|
+
const tmpdirs = [];
|
|
73
|
+
(0, vitest_1.afterEach)(async () => {
|
|
74
|
+
// Best-effort cleanup in case a test fails before the executor cleans up
|
|
75
|
+
while (tmpdirs.length) {
|
|
76
|
+
const p = tmpdirs.pop();
|
|
77
|
+
try {
|
|
78
|
+
await fs.rm(p, { recursive: true, force: true });
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
/* ignore */
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
(0, vitest_1.describe)('CucumberSubprocessExecutor integration: real fork + IPC', () => {
|
|
86
|
+
(0, vitest_1.it)('happy path: emits scenarios from envelope stream and cleans tmpdir', async () => {
|
|
87
|
+
const executor = new cucumber_subprocess_1.CucumberSubprocessExecutor({
|
|
88
|
+
workerPath: path.join(FIXTURES, 'worker-happy.js'),
|
|
89
|
+
});
|
|
90
|
+
const events = [];
|
|
91
|
+
const cbs = {
|
|
92
|
+
onScenarioStart: (id, name) => events.push(`start:${id}:${name}`),
|
|
93
|
+
onStepComplete: (id, step) => events.push(`step:${id}:${step.status}`),
|
|
94
|
+
onScenarioComplete: (id, status) => events.push(`complete:${id}:${status}`),
|
|
95
|
+
};
|
|
96
|
+
const scenarios = await executor.executeAll([dummyFeature], [dummyStepDef], {}, cbs);
|
|
97
|
+
// Envelope ordering must reach callbacks in the order the worker emitted
|
|
98
|
+
(0, vitest_1.expect)(events).toEqual([
|
|
99
|
+
'start:p1:happy scenario',
|
|
100
|
+
'step:p1:passed',
|
|
101
|
+
'complete:p1:passed',
|
|
102
|
+
]);
|
|
103
|
+
(0, vitest_1.expect)(scenarios).toHaveLength(1);
|
|
104
|
+
(0, vitest_1.expect)(scenarios[0].status).toBe('passed');
|
|
105
|
+
}, 10_000);
|
|
106
|
+
(0, vitest_1.it)('fatal: worker sends {kind:"fatal"} then exits → executeAll rejects', async () => {
|
|
107
|
+
const executor = new cucumber_subprocess_1.CucumberSubprocessExecutor({
|
|
108
|
+
workerPath: path.join(FIXTURES, 'worker-fatal.js'),
|
|
109
|
+
});
|
|
110
|
+
await (0, vitest_1.expect)(executor.executeAll([dummyFeature], [dummyStepDef], {}, noopCallbacks)).rejects.toThrow(/simulated boot failure/);
|
|
111
|
+
}, 10_000);
|
|
112
|
+
(0, vitest_1.it)('cancel: SIGTERMs the hanging child and resolves with partial scenarios', async () => {
|
|
113
|
+
const executor = new cucumber_subprocess_1.CucumberSubprocessExecutor({
|
|
114
|
+
workerPath: path.join(FIXTURES, 'worker-hang.js'),
|
|
115
|
+
});
|
|
116
|
+
const runP = executor.executeAll([dummyFeature], [dummyStepDef], {}, noopCallbacks);
|
|
117
|
+
// Give the worker a moment to send pickle/testCase envelopes and
|
|
118
|
+
// for the parent to register child.
|
|
119
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
120
|
+
const start = Date.now();
|
|
121
|
+
executor.cancel();
|
|
122
|
+
const scenarios = await runP;
|
|
123
|
+
const elapsed = Date.now() - start;
|
|
124
|
+
// Should terminate well within the 5s SIGKILL grace.
|
|
125
|
+
(0, vitest_1.expect)(elapsed).toBeLessThan(5_000);
|
|
126
|
+
// The hang stub only emitted pickle + testCase (no testCaseStarted), so
|
|
127
|
+
// no scenario actually entered the in-flight map. Resolving with an
|
|
128
|
+
// empty list is correct — partial means "what we accumulated", not
|
|
129
|
+
// "what was queued".
|
|
130
|
+
(0, vitest_1.expect)(scenarios).toEqual([]);
|
|
131
|
+
}, 10_000);
|
|
132
|
+
(0, vitest_1.it)('cancel after natural exit is a no-op (idempotent)', async () => {
|
|
133
|
+
const executor = new cucumber_subprocess_1.CucumberSubprocessExecutor({
|
|
134
|
+
workerPath: path.join(FIXTURES, 'worker-happy.js'),
|
|
135
|
+
});
|
|
136
|
+
await executor.executeAll([dummyFeature], [dummyStepDef], {}, noopCallbacks);
|
|
137
|
+
// Should not throw, should not hang, should not error
|
|
138
|
+
(0, vitest_1.expect)(() => executor.cancel()).not.toThrow();
|
|
139
|
+
}, 10_000);
|
|
140
|
+
});
|
|
141
|
+
//# sourceMappingURL=integration-fork.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-fork.test.js","sourceRoot":"","sources":["../../src/__tests__/integration-fork.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for CucumberSubprocessExecutor.prepareTmpdir — the on-disk layout
|
|
3
|
+
* the forked Cucumber.js worker reads.
|
|
4
|
+
*
|
|
5
|
+
* Tmpdir layout under verification:
|
|
6
|
+
* <tmpdir>/
|
|
7
|
+
* features/<feature_id>.feature
|
|
8
|
+
* steps/<filename>
|
|
9
|
+
* support/world.{js|ts}
|
|
10
|
+
* cucumber.cjs
|
|
11
|
+
* .use-ts (only when any step-def is TypeScript)
|
|
12
|
+
*
|
|
13
|
+
* The runtime call site is private to executeAll(); this test calls
|
|
14
|
+
* prepareTmpdir directly and asserts the filesystem state. Each test cleans
|
|
15
|
+
* up the directory it created.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=tmpdir-materialization.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmpdir-materialization.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/tmpdir-materialization.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
|