@autometa/app 0.4.2 → 1.0.0-rc.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/index.d.ts CHANGED
@@ -1,110 +1,2 @@
1
- import { Container } from '@autometa/injection';
2
- import { Class } from '@autometa/types';
3
-
4
- /**
5
- * Basic Key Value store for managing state across Step Definitions. A unique copy of this object
6
- * is shared between all steps and hooks in a given running Scenario, however it is not possible
7
- * to interact with state outside of that Scenarios life cycle. That is to say, while the World
8
- * is shared between steps, it is unique across tests.
9
- *
10
- * To extend the worlds vocabulary, you can declare properties on the World. These do not need
11
- * to be defined at run time. Instead they will be filled in as they are produced by steps.
12
- *
13
- * To declare World properties, you can simply declare an uninitialized property. Depending
14
- * on your `tsconfig.json` settings you can do so with one of the three following syntaxes:
15
- *
16
- * ```typescript
17
- * @Fixture
18
- * export class World {
19
- * [key: string]: unknown;
20
- *
21
- * declare foo: number
22
- *
23
- * foo: number
24
- *
25
- * foo!: number
26
- * }
27
- *
28
- * The World is automatically injected into the {@link App} object, and can be accessed via
29
- * the last (or only) argument of a step definition callback.
30
- *
31
- * ```ts
32
- * Given('I have {int} cats', (cats: number, app: App) => {
33
- * app.world.cats = cats
34
- * })
35
- *
36
- * // using destructuring
37
- * Given('I have {int} cats', ({world}: App) => {
38
- * world.cats = cats
39
- * })
40
- * ```
41
- */
42
- interface World {
43
- [key: string]: unknown;
44
- }
45
- /**
46
- * The App object is the primary interface for interacting with the running application. It is
47
- * composed of `Fixtures` which are classes decorated with the `@Fixture` decorator. Fixtures
48
- * are automatically instantiated and injected into the App object. The App object is then
49
- * injected into the last (or only) argument of a step definition callback.
50
- *
51
- * i.e.
52
- *
53
- * ```ts
54
- * // single argument
55
- * Given('I have 5 cats', (app: App) => {})
56
- * // Cucumber Expression
57
- * Given('I have {int} cats', (cats: number, app: App) => {})
58
- * // Data table
59
- * Given('I have {int} cats', (cats: number, table: HTable app: App) => {}, HTable)
60
- * ```
61
- *
62
- * **Note**: The type annotations here are optional. Non-custom Cucumber Expression types
63
- * will be automatically inferred by their expression template. Custom types will need to
64
- * be added via declaration file (see docs)
65
- *
66
- * The App is unique across all tests, and is shared between all steps and hooks within a test.
67
- * If you have any Fixture classes defined, you can add them as constructor parameters of the App
68
- * to make them available to step Definitions (Fixtures can also be accessed as properties from other Fixtures if not defined here);
69
- *
70
- * ```ts
71
- * \@\Fixture
72
- * export class World {}
73
- *
74
- *
75
- * \@\Fixture
76
- * export class Fixture1 {}
77
- *
78
- * \@\Fixture
79
- * export class Fixture2 {
80
- * constructor(readonly fixture1: Fixture1, readonly world: World) {}
81
- * }
82
- *
83
- * \@\AppType(World)
84
- * export class App {
85
- * constructor(readonly fixture1: Fixture1, readonly fixture2: Fixture2) {}
86
- * }
87
- * ```
88
- */
89
- interface App {
90
- world: World;
91
- di: Container;
92
- }
93
-
94
- declare abstract class AutometaApp {
95
- id: string;
96
- [key: string]: unknown;
97
- world: World;
98
- }
99
-
100
- declare class AutometaWorld {
101
- }
102
-
103
- declare function getApp<T extends AutometaApp>(appType: Class<T>, containerName?: string): App;
104
-
105
- declare function AppType(container: Record<string, {
106
- app: Class<App>;
107
- world: Class<World>;
108
- }>, world: Class<AutometaWorld>, environment?: string): (target: Class<unknown>) => void;
109
-
110
- export { App, AppType, AutometaApp, AutometaWorld, World, getApp };
1
+ export { createStepDefinitions } from "./create-step-definitions";
2
+ export type { StepSuite, StepFactoryOptions, StepDsl, StepExpression, StepCallback, HookSuite, StepFlowBuilder, StepFlowRunner, WorldHierarchy, WorldScope, StepRuntimeContext, ScopeKeyResolver, } from "./types";
package/dist/index.js CHANGED
@@ -1,71 +1,497 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ import { AutomationError } from '@autometa/errors';
2
+ import { Container, Scope } from '@autometa/injection';
19
3
 
20
- // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
23
- AppType: () => AppType,
24
- AutometaApp: () => AutometaApp,
25
- AutometaWorld: () => AutometaWorld,
26
- getApp: () => getApp
27
- });
28
- module.exports = __toCommonJS(src_exports);
29
-
30
- // src/autometa-app.ts
31
- var AutometaApp = class {
32
- };
33
-
34
- // src/autometa-world.ts
35
- var AutometaWorld = class {
4
+ // src/create-step-definitions.ts
5
+ var ScopeManager = class {
6
+ constructor(options) {
7
+ this.options = options;
8
+ this.root = new Container();
9
+ this.enterHandlers = {
10
+ feature: /* @__PURE__ */ new Set(),
11
+ rule: /* @__PURE__ */ new Set(),
12
+ outline: /* @__PURE__ */ new Set(),
13
+ scenario: /* @__PURE__ */ new Set()
14
+ };
15
+ this.exitHandlers = {
16
+ feature: /* @__PURE__ */ new Set(),
17
+ rule: /* @__PURE__ */ new Set(),
18
+ outline: /* @__PURE__ */ new Set(),
19
+ scenario: /* @__PURE__ */ new Set()
20
+ };
21
+ }
22
+ getHierarchy() {
23
+ if (!this.scenario) {
24
+ throw new AutomationError("Scenario world has not been initialised yet.");
25
+ }
26
+ return {
27
+ scenario: this.scenario.instance,
28
+ feature: this.feature?.instance ?? void 0,
29
+ rule: this.rule?.instance ?? void 0,
30
+ outline: this.outline?.instance ?? void 0
31
+ };
32
+ }
33
+ async startScenario(rawContext, explicitKeys) {
34
+ const context = rawContext ?? {};
35
+ const keys = explicitKeys ?? this.resolveKeys(context);
36
+ await this.ensureFeature(keys, context);
37
+ await this.ensureRule(keys, context);
38
+ await this.ensureOutline(keys, context);
39
+ if (this.scenario) {
40
+ await this.disposeScenario(false);
41
+ }
42
+ this.scenario = this.createScopeState(
43
+ this.options.scenario,
44
+ keys.scenario,
45
+ this.parentContainerFor("scenario"),
46
+ context
47
+ );
48
+ this.syncHierarchyReferences();
49
+ await this.triggerEnter("scenario", context);
50
+ }
51
+ async finishScenario(context) {
52
+ await this.disposeScenario(true, context);
53
+ }
54
+ async resetAll(context) {
55
+ await this.disposeScenario(true, context);
56
+ await this.disposeOutline(context);
57
+ await this.disposeRule(context);
58
+ await this.disposeFeature(context);
59
+ }
60
+ onEnter(scope, handler) {
61
+ this.enterHandlers[scope].add(handler);
62
+ }
63
+ onExit(scope, handler) {
64
+ this.exitHandlers[scope].add(handler);
65
+ }
66
+ resolveKeys(context) {
67
+ const { keyResolver } = this.options;
68
+ const result = {
69
+ scenario: keyResolver.scenario(context)
70
+ };
71
+ const feature = keyResolver.feature?.(context);
72
+ if (feature) {
73
+ result.feature = feature;
74
+ }
75
+ const rule = keyResolver.rule?.(context);
76
+ if (rule) {
77
+ result.rule = rule;
78
+ }
79
+ const outline = keyResolver.outline?.(context);
80
+ if (outline) {
81
+ result.outline = outline;
82
+ }
83
+ if (!result.feature) {
84
+ result.feature = "feature";
85
+ }
86
+ return result;
87
+ }
88
+ hasScenario() {
89
+ return Boolean(this.scenario);
90
+ }
91
+ parentContainerFor(scope) {
92
+ switch (scope) {
93
+ case "feature":
94
+ return this.root;
95
+ case "rule":
96
+ return this.feature?.container ?? this.root;
97
+ case "outline":
98
+ return this.rule?.container ?? this.feature?.container ?? this.root;
99
+ case "scenario":
100
+ default:
101
+ return this.outline?.container ?? this.rule?.container ?? this.feature?.container ?? this.root;
102
+ }
103
+ }
104
+ ensureFeature(keys, context) {
105
+ const featureCtor = this.options.feature;
106
+ if (!featureCtor) {
107
+ return;
108
+ }
109
+ if (this.feature && this.feature.key === keys.feature) {
110
+ return;
111
+ }
112
+ return this.replaceFeature(featureCtor, keys.feature ?? "feature", context);
113
+ }
114
+ async ensureRule(keys, context) {
115
+ const ruleCtor = this.options.rule;
116
+ if (!ruleCtor) {
117
+ return;
118
+ }
119
+ if (this.rule && this.rule.key === keys.rule) {
120
+ return;
121
+ }
122
+ await this.disposeRule(context);
123
+ if (!keys.rule) {
124
+ return;
125
+ }
126
+ this.rule = this.createScopeState(
127
+ ruleCtor,
128
+ keys.rule,
129
+ this.parentContainerFor("rule"),
130
+ context
131
+ );
132
+ this.syncHierarchyReferences();
133
+ await this.triggerEnter("rule", context);
134
+ }
135
+ async ensureOutline(keys, context) {
136
+ const outlineCtor = this.options.outline;
137
+ if (!outlineCtor) {
138
+ return;
139
+ }
140
+ if (this.outline && this.outline.key === keys.outline) {
141
+ return;
142
+ }
143
+ await this.disposeOutline(context);
144
+ if (!keys.outline) {
145
+ return;
146
+ }
147
+ this.outline = this.createScopeState(
148
+ outlineCtor,
149
+ keys.outline,
150
+ this.parentContainerFor("outline"),
151
+ context
152
+ );
153
+ this.syncHierarchyReferences();
154
+ await this.triggerEnter("outline", context);
155
+ }
156
+ async replaceFeature(ctor, key, context) {
157
+ await this.disposeFeature(context);
158
+ this.feature = this.createScopeState(ctor, key, this.parentContainerFor("feature"), context);
159
+ this.syncHierarchyReferences();
160
+ await this.triggerEnter("feature", context);
161
+ }
162
+ createScopeState(ctor, key, parent, context) {
163
+ const container = parent.createChild();
164
+ container.registerClass(ctor, { scope: Scope.SINGLETON });
165
+ const instance = container.resolve(ctor);
166
+ return { ctor, key, container, instance, context };
167
+ }
168
+ async disposeScenario(runHandlers, context) {
169
+ if (!this.scenario) {
170
+ return;
171
+ }
172
+ if (runHandlers) {
173
+ await this.triggerExit("scenario", context ?? this.scenario.context);
174
+ }
175
+ await this.scenario.container.dispose();
176
+ this.scenario = void 0;
177
+ }
178
+ async disposeOutline(context) {
179
+ if (!this.outline) {
180
+ return;
181
+ }
182
+ await this.triggerExit("outline", context ?? this.outline.context);
183
+ await this.outline.container.dispose();
184
+ this.outline = void 0;
185
+ }
186
+ async disposeRule(context) {
187
+ if (!this.rule) {
188
+ return;
189
+ }
190
+ await this.triggerExit("rule", context ?? this.rule.context);
191
+ await this.rule.container.dispose();
192
+ this.rule = void 0;
193
+ }
194
+ async disposeFeature(context) {
195
+ if (!this.feature) {
196
+ return;
197
+ }
198
+ await this.triggerExit("feature", context ?? this.feature.context);
199
+ await this.feature.container.dispose();
200
+ this.feature = void 0;
201
+ }
202
+ async triggerEnter(scope, context) {
203
+ const handlers = this.enterHandlers[scope];
204
+ if (!handlers.size) {
205
+ return;
206
+ }
207
+ const payload = this.createPayload(scope);
208
+ for (const handler of handlers) {
209
+ await handler(payload, context);
210
+ }
211
+ }
212
+ async triggerExit(scope, context) {
213
+ const handlers = this.exitHandlers[scope];
214
+ if (!handlers.size) {
215
+ return;
216
+ }
217
+ const payload = this.createPayload(scope);
218
+ for (const handler of handlers) {
219
+ await handler(payload, context);
220
+ }
221
+ }
222
+ createPayload(scope) {
223
+ switch (scope) {
224
+ case "feature":
225
+ if (!this.feature) {
226
+ throw new AutomationError("Feature world has not been initialised.");
227
+ }
228
+ return { feature: this.feature.instance };
229
+ case "rule":
230
+ if (!this.rule) {
231
+ throw new AutomationError("Rule world has not been initialised.");
232
+ }
233
+ return {
234
+ feature: this.feature?.instance ?? void 0,
235
+ rule: this.rule.instance
236
+ };
237
+ case "outline":
238
+ if (!this.outline) {
239
+ throw new AutomationError("Outline world has not been initialised.");
240
+ }
241
+ return {
242
+ feature: this.feature?.instance ?? void 0,
243
+ rule: this.rule?.instance ?? void 0,
244
+ outline: this.outline.instance
245
+ };
246
+ case "scenario":
247
+ default:
248
+ if (!this.scenario) {
249
+ throw new AutomationError("Scenario world has not been initialised.");
250
+ }
251
+ return {
252
+ feature: this.feature?.instance ?? void 0,
253
+ rule: this.rule?.instance ?? void 0,
254
+ outline: this.outline?.instance ?? void 0,
255
+ scenario: this.scenario.instance
256
+ };
257
+ }
258
+ }
259
+ syncHierarchyReferences() {
260
+ if (this.rule?.instance && this.feature?.instance) {
261
+ this.attachParent(this.rule.instance, "feature", this.feature.instance);
262
+ }
263
+ if (this.outline?.instance) {
264
+ if (this.feature?.instance) {
265
+ this.attachParent(this.outline.instance, "feature", this.feature.instance);
266
+ }
267
+ if (this.rule?.instance) {
268
+ this.attachParent(this.outline.instance, "rule", this.rule.instance);
269
+ }
270
+ }
271
+ if (this.scenario?.instance) {
272
+ if (this.feature?.instance) {
273
+ this.attachParent(this.scenario.instance, "feature", this.feature.instance);
274
+ }
275
+ if (this.rule?.instance) {
276
+ this.attachParent(this.scenario.instance, "rule", this.rule.instance);
277
+ }
278
+ if (this.outline?.instance) {
279
+ this.attachParent(this.scenario.instance, "outline", this.outline.instance);
280
+ }
281
+ }
282
+ }
283
+ attachParent(target, property, value) {
284
+ if (property in target && Reflect.get(target, property) === value) {
285
+ return;
286
+ }
287
+ Object.defineProperty(target, property, {
288
+ value,
289
+ enumerable: false,
290
+ configurable: true,
291
+ writable: false
292
+ });
293
+ }
36
294
  };
37
295
 
38
- // src/get-app.ts
39
- var import_uuid = require("uuid");
40
- var import_injection = require("@autometa/injection");
41
- function getApp(appType, containerName = (0, import_uuid.v4)()) {
42
- const context = (0, import_injection.defineContainerContext)(containerName);
43
- const container = new import_injection.Container(context);
44
- const app = container.get(appType);
45
- app.di = container;
46
- return app;
296
+ // src/create-step-definitions.ts
297
+ function baseCreateStepDefinitions(scenarioCtor, options = {}) {
298
+ const dsl = resolveDsl(options.dsl);
299
+ const keyResolver = options.keyResolver ?? defaultKeyResolver;
300
+ const manager = new ScopeManager({
301
+ scenario: scenarioCtor,
302
+ keyResolver,
303
+ ...options.feature ? { feature: options.feature } : {},
304
+ ...options.rule ? { rule: options.rule } : {},
305
+ ...options.outline ? { outline: options.outline } : {}
306
+ });
307
+ if (Array.isArray(options.expressions) && dsl.defineParameterType) {
308
+ for (const definition of options.expressions) {
309
+ dsl.defineParameterType(definition);
310
+ }
311
+ }
312
+ setupLifecycleHooks(dsl, manager);
313
+ const given = wrapStepRegistrar("Given", dsl, dsl.Given, manager);
314
+ const when = wrapStepRegistrar("When", dsl, dsl.When, manager);
315
+ const then = wrapStepRegistrar("Then", dsl, dsl.Then, manager);
316
+ const and = wrapStepRegistrar("And", dsl, dsl.And ?? dsl.Given, manager);
317
+ const but = wrapStepRegistrar("But", dsl, dsl.But ?? dsl.Given, manager);
318
+ const hooks = {
319
+ BeforeFeature(handler) {
320
+ manager.onEnter("feature", handler);
321
+ },
322
+ AfterFeature(handler) {
323
+ manager.onExit("feature", handler);
324
+ },
325
+ BeforeRule(handler) {
326
+ manager.onEnter("rule", handler);
327
+ },
328
+ AfterRule(handler) {
329
+ manager.onExit("rule", handler);
330
+ },
331
+ BeforeOutline(handler) {
332
+ manager.onEnter("outline", handler);
333
+ },
334
+ AfterOutline(handler) {
335
+ manager.onExit("outline", handler);
336
+ },
337
+ BeforeScenario(handler) {
338
+ manager.onEnter("scenario", handler);
339
+ },
340
+ AfterScenario(handler) {
341
+ manager.onExit("scenario", handler);
342
+ }
343
+ };
344
+ const flow = createFlowBuilder({
345
+ given,
346
+ when,
347
+ then,
348
+ and,
349
+ but
350
+ });
351
+ return {
352
+ Given: given,
353
+ When: when,
354
+ Then: then,
355
+ And: and,
356
+ But: but,
357
+ hooks,
358
+ flow
359
+ };
47
360
  }
48
-
49
- // src/decorators/app-type.ts
50
- var import_injection2 = require("@autometa/injection");
51
- function AppType(container, world, environment = "default") {
52
- const env = environment ?? "default";
53
- return (target) => {
54
- (0, import_injection2.metadata)(target).set({
55
- key: "world",
56
- class: world
57
- });
58
- container[env] = {
59
- app: target,
60
- world
361
+ var createStepDefinitions = Object.assign(
362
+ baseCreateStepDefinitions,
363
+ {
364
+ flow: (scenarioCtor, options) => baseCreateStepDefinitions(scenarioCtor, options).flow
365
+ }
366
+ );
367
+ function resolveDsl(dsl) {
368
+ if (!dsl) {
369
+ throw new AutomationError(
370
+ "Step-definition DSL is required. Pass an explicit dsl option when creating step definitions."
371
+ );
372
+ }
373
+ return ensureRegistrars(dsl);
374
+ }
375
+ function ensureRegistrars(dsl) {
376
+ if (!dsl.Given || !dsl.When || !dsl.Then) {
377
+ throw new AutomationError("Step DSL must provide Given, When, and Then registrars.");
378
+ }
379
+ return dsl;
380
+ }
381
+ function wrapStepRegistrar(keyword, dsl, registrar, manager) {
382
+ if (!registrar) {
383
+ return () => {
384
+ throw new AutomationError(`Step DSL does not expose a registrar for ${keyword}.`);
61
385
  };
386
+ }
387
+ return (expression, handler) => {
388
+ const wrapped = createStepWrapper(keyword, expression, handler, manager);
389
+ registrar.call(dsl, expression, wrapped);
390
+ };
391
+ }
392
+ function createStepWrapper(keyword, expression, handler, manager) {
393
+ return async function stepExecution(...args) {
394
+ if (!manager.hasScenario()) {
395
+ const context = resolveRuntimeContext(void 0, this);
396
+ const keys = manager.resolveKeys(context);
397
+ await manager.startScenario(context, keys);
398
+ }
399
+ const { scenario } = manager.getHierarchy();
400
+ try {
401
+ if (expectsThis(handler)) {
402
+ return await handler.apply(scenario, args);
403
+ }
404
+ return await handler(scenario, ...args);
405
+ } catch (error) {
406
+ throw wrapStepError(error, keyword, expression);
407
+ }
408
+ };
409
+ }
410
+ function expectsThis(handler) {
411
+ return Boolean(handler.prototype);
412
+ }
413
+ function wrapStepError(error, keyword, expression) {
414
+ if (error instanceof AutomationError) {
415
+ return error;
416
+ }
417
+ const baseMessage = error instanceof Error ? error.message : typeof error === "string" ? error : "Unknown error";
418
+ const message = `Step failed for ${keyword} ${String(expression)}: ${baseMessage}`;
419
+ return new AutomationError(message, {
420
+ cause: error instanceof Error ? error : void 0
421
+ });
422
+ }
423
+ function resolveRuntimeContext(hookArg, worldValue) {
424
+ if (hookArg && typeof hookArg === "object") {
425
+ return hookArg;
426
+ }
427
+ if (worldValue && typeof worldValue === "object") {
428
+ return worldValue;
429
+ }
430
+ return {};
431
+ }
432
+ function setupLifecycleHooks(dsl, manager) {
433
+ if (dsl.Before) {
434
+ dsl.Before.call(dsl, async function beforeScenario(context) {
435
+ const runtime = resolveRuntimeContext(context, this);
436
+ await manager.startScenario(runtime);
437
+ });
438
+ }
439
+ if (dsl.After) {
440
+ dsl.After.call(dsl, async function afterScenario(context) {
441
+ const runtime = resolveRuntimeContext(context, this);
442
+ await manager.finishScenario(runtime);
443
+ });
444
+ }
445
+ if (dsl.AfterAll) {
446
+ dsl.AfterAll.call(dsl, async function afterAll() {
447
+ const runtime = resolveRuntimeContext(void 0, this);
448
+ await manager.resetAll(runtime);
449
+ });
450
+ }
451
+ }
452
+ function createFlowBuilder(registrars) {
453
+ const builder = {
454
+ given: (expression) => createFlowRunner(registrars.given, expression, () => builder),
455
+ when: (expression) => createFlowRunner(registrars.when, expression, () => builder),
456
+ then: (expression) => createFlowRunner(registrars.then, expression, () => builder),
457
+ and: (expression) => createFlowRunner(registrars.and, expression, () => builder),
458
+ but: (expression) => createFlowRunner(registrars.but, expression, () => builder)
459
+ };
460
+ return builder;
461
+ }
462
+ function createFlowRunner(registrar, expression, next) {
463
+ return {
464
+ run(handler) {
465
+ registrar(expression, handler);
466
+ return next();
467
+ }
62
468
  };
63
469
  }
64
- // Annotate the CommonJS export names for ESM import in node:
65
- 0 && (module.exports = {
66
- AppType,
67
- AutometaApp,
68
- AutometaWorld,
69
- getApp
70
- });
470
+ var nextScenarioId = createKeyFactory("scenario");
471
+ var defaultKeyResolver = {
472
+ feature(context) {
473
+ return context.gherkinDocument?.feature?.name ?? context.pickle?.uri ?? void 0;
474
+ },
475
+ rule(context) {
476
+ const nodes = context.pickle?.astNodeIds;
477
+ return Array.isArray(nodes) && nodes.length > 1 ? nodes[0] : void 0;
478
+ },
479
+ outline(context) {
480
+ const nodes = context.pickle?.astNodeIds;
481
+ if (Array.isArray(nodes) && nodes.length > 1) {
482
+ return nodes.slice(1).join(":");
483
+ }
484
+ return void 0;
485
+ },
486
+ scenario(context) {
487
+ return context.pickle?.id ?? context.pickle?.name ?? nextScenarioId();
488
+ }
489
+ };
490
+ function createKeyFactory(prefix) {
491
+ let counter = 0;
492
+ return () => `${prefix}-${++counter}`;
493
+ }
494
+
495
+ export { createStepDefinitions };
496
+ //# sourceMappingURL=out.js.map
71
497
  //# sourceMappingURL=index.js.map