quickpickle 1.0.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/LICENSE +22 -0
- package/README.md +204 -0
- package/dist/hooks.d.ts +19 -0
- package/dist/index.cjs +424 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.esm.js +377 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/models/DataTable.d.ts +10 -0
- package/dist/models/DocString.d.ts +6 -0
- package/dist/render.d.ts +4 -0
- package/dist/steps.d.ts +13 -0
- package/dist/tags.d.ts +1 -0
- package/dist/world.d.ts +21 -0
- package/package.json +67 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 SamZiegler
|
|
4
|
+
Copyright (c) 2024 David Hunt
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# QuickPickle
|
|
2
|
+
|
|
3
|
+
QuickPickle is a plugin for [Vitest] to run tests written in [Gherkin Syntax].
|
|
4
|
+
It seamlessly integrates Gherkin Feature files into your Vitest testing workflow
|
|
5
|
+
by parsing them with the official [Gherkin Parser] and running them as Vitest tests.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Seamless integration of Gherkin Feature files into Vitest testing workflow
|
|
10
|
+
- Parses Gherkin Feature files using the official [Gherkin Parser]
|
|
11
|
+
- Full typescript and javascript support (because it's really just Vitest)
|
|
12
|
+
- Full support for Gherkin 6 Syntax
|
|
13
|
+
|
|
14
|
+
### Benefits of Gherkin
|
|
15
|
+
|
|
16
|
+
- Write tests in plain English (or your team's language)
|
|
17
|
+
|
|
18
|
+
Because it uses natural language, Gherkin Syntax enables all stakeholders to
|
|
19
|
+
understand and contribute to tests, and having a common vocabulary to describe
|
|
20
|
+
functionality makes it easy to agree on and verify what the program does.
|
|
21
|
+
|
|
22
|
+
- Reuse test step definitions to minimize test code
|
|
23
|
+
|
|
24
|
+
Bugs can happen even in test code, so it's best if the test code changes as seldom
|
|
25
|
+
as possible, but functionality changes all the time. A small library of reusable step
|
|
26
|
+
definitions is much easier to maintain than a large corpus of test code.
|
|
27
|
+
|
|
28
|
+
### When NOT to use Gherkin
|
|
29
|
+
|
|
30
|
+
- For unit tests, it's usually better to use plain Vitest or another testing framework.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
npm install --save-dev quickpickle vitest
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Configuration
|
|
39
|
+
|
|
40
|
+
Add the quickpickle plugin to your Vitest configuration in vite.config.ts (or .js, etc.):
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
// vite.config.ts
|
|
44
|
+
import { quickpickle } from 'quickpickle';
|
|
45
|
+
|
|
46
|
+
const qpConfig:Partial<QuickPickleConfig> = { // <-- Optional configuration (defaults shown)
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The files to be imported for each Feature.
|
|
50
|
+
* All step definitions, hooks, world constructor, etc. must be listed.
|
|
51
|
+
* The value can be a glob pattern or an array of glob patterns.
|
|
52
|
+
*/
|
|
53
|
+
import: [
|
|
54
|
+
'{features,test,tests}/**/*.steps.{ts,js,mjs}',
|
|
55
|
+
'{features,test,tests}/**/*.world.{ts,js,mjs}'
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default {
|
|
61
|
+
plugins: [
|
|
62
|
+
quickpickle(qpConfig) // <-- Add the quickpickle plugin
|
|
63
|
+
],
|
|
64
|
+
test: {
|
|
65
|
+
include : [
|
|
66
|
+
'features/*.feature', // <-- Add Gherkin feature files into "test" configuration
|
|
67
|
+
// (you'll probably want other test files too, for unit tests etc.)
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
### Write Feature files
|
|
76
|
+
|
|
77
|
+
Write your feature files in the directory specified above. Common convention
|
|
78
|
+
is to place feature files in a "features" directory, though some prefer the
|
|
79
|
+
"tests" directory. You can put them anywhere as long as they're listed in the
|
|
80
|
+
"include" configuration in vite.config.ts.
|
|
81
|
+
|
|
82
|
+
```gherkin
|
|
83
|
+
# features/example.feature
|
|
84
|
+
Feature: A simple example
|
|
85
|
+
|
|
86
|
+
Scenario: Adding numbers
|
|
87
|
+
Given a number 1
|
|
88
|
+
And a number 2
|
|
89
|
+
And a number 3
|
|
90
|
+
And another number 3
|
|
91
|
+
Then the sum should be 9
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Run tests
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
npx vitest --run
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Write step definitions
|
|
101
|
+
|
|
102
|
+
Write your step definitions in a typescript or javascript file as configured
|
|
103
|
+
in the "import" declaration of the qpConfig object above.
|
|
104
|
+
|
|
105
|
+
These files will be imported into the Vitest test runner, and the code for
|
|
106
|
+
`Given`, `When`, `Then` will register each of the step definitions with quickpickle.
|
|
107
|
+
These step definitions should run on import, i.e. at the top level of the script,
|
|
108
|
+
not as exported functions like a normal node module would do.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
// features/example.steps.ts
|
|
112
|
+
import { Given, Then } from 'quickpickle'
|
|
113
|
+
|
|
114
|
+
Given('a/another number {int}', (world, int) => {
|
|
115
|
+
if (!world.numbers) world.numbers = [int]
|
|
116
|
+
else world.numbers.push(int)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
Then('the sum should be {int}', (world, int) => {
|
|
120
|
+
expect(world.numbers.reduce((a,b) => a + b, 0)).toBe(int)
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Define a custom "world" variable
|
|
125
|
+
|
|
126
|
+
...instructions coming soon! :)
|
|
127
|
+
|
|
128
|
+
## Differences from CucumberJS
|
|
129
|
+
|
|
130
|
+
The main library for Gherkin in the JS ecosystem is [CucumberJS],
|
|
131
|
+
a test runner written explicitly for Gherkin tests. QuickPickle aims to be
|
|
132
|
+
a complete replacement for that library, using Vite to handle bundling
|
|
133
|
+
and test running while maintaining functional parity with the original.
|
|
134
|
+
Nonetheless, there are differences. Here are the important ones that have
|
|
135
|
+
come to notice:
|
|
136
|
+
|
|
137
|
+
- Each step definition MUST have the "world" variable as its first parameter:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
// QuickPickle step definition
|
|
141
|
+
Given('a number {int}', function(world:QuickPickleWorldInterface, int:number) {
|
|
142
|
+
if (!Array.isArray(world.numbers)) world.numbers = [int]
|
|
143
|
+
else world.numbers.push(int)
|
|
144
|
+
})
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
In CucumberJS, you would write your step definitions using "this":
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
// CucumberJS step definition
|
|
151
|
+
Given('a number {int}', function(int:number) {
|
|
152
|
+
if (!Array.isArray(this.numbers)) this.numbers = [int]
|
|
153
|
+
else this.numbers.push(int)
|
|
154
|
+
})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
"this" led to some sub-optimal usage, including:
|
|
158
|
+
- Arrow functions couldn't be used, because "this" doesn't work with them.
|
|
159
|
+
- When using a custom world, you would have to add `(this:CustomWorldType, ...params)`
|
|
160
|
+
in typescript files or else you wouldn't get the right types.
|
|
161
|
+
|
|
162
|
+
- The default "world" variable contains information about the current step.
|
|
163
|
+
|
|
164
|
+
In CucumberJS, the default "world" variable contains information about the
|
|
165
|
+
test *suite*, but not the *current step*. It's the opposite in QuickPickle;
|
|
166
|
+
the "world" variable passed to each test step contains an "info" property
|
|
167
|
+
with data about the current feature, rule, scenario or example, step, and line:
|
|
168
|
+
|
|
169
|
+
```gherkin
|
|
170
|
+
Feature: Basic Test
|
|
171
|
+
|
|
172
|
+
Rule: Every step must have access to information about itself
|
|
173
|
+
This is so we can know what is happening when writing step definitions
|
|
174
|
+
|
|
175
|
+
@tag-test
|
|
176
|
+
Example: The world has info
|
|
177
|
+
Given I run the tests
|
|
178
|
+
Then the property "info.feature" should include "Basic Test"
|
|
179
|
+
And the property "info.rule" should include "Every step must have access to information about itself"
|
|
180
|
+
And the property "info.scenario" should include "The world has info"
|
|
181
|
+
And the property "info.tags" should include "@tag-test"
|
|
182
|
+
And the property "info.step" should include "FWAH!!! (or really whatever you write here, since it's part of the step)"
|
|
183
|
+
And the property "info.line" should include "23"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Acknowledgements
|
|
187
|
+
|
|
188
|
+
This project started out as a fork of [vitest-cucumber-plugin] by Sam Ziegler.
|
|
189
|
+
It's been almost completely rewritten in the following ways:
|
|
190
|
+
|
|
191
|
+
- it has been converted to typescript
|
|
192
|
+
- a custom Gherkin parser has been replaced with the official [Gherkin Parser]
|
|
193
|
+
- the step definition format has been reverted to more closely match CucumberJS
|
|
194
|
+
|
|
195
|
+
Nonetheless, the brilliant ideas behind the original plugin are still present
|
|
196
|
+
in the architecture of this project. Thanks Sam, your work blew my mind.
|
|
197
|
+
|
|
198
|
+

|
|
199
|
+
|
|
200
|
+
[Vitest]: https://vitest.dev/
|
|
201
|
+
[Gherkin Syntax]: https://cucumber.io/docs/gherkin/reference/
|
|
202
|
+
[Gherkin Parser]: https://www.npmjs.com/package/@cucumber/gherkin
|
|
203
|
+
[CucumberJS]: https://github.com/cucumber/cucumber-js
|
|
204
|
+
[vitest-cucumber-plugin]: https://github.com/samuel-ziegler/vitest-cucumber-plugin
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface Hook {
|
|
2
|
+
name: string;
|
|
3
|
+
f: (state: any) => Promise<any> | any;
|
|
4
|
+
tagsFunction: (tags: string[]) => boolean;
|
|
5
|
+
tags?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const BeforeAll: (opts: string | Hook | ((state: any) => any), f?: (state: any) => any) => void;
|
|
8
|
+
export declare const applyBeforeAllHooks: (state: any) => Promise<any>;
|
|
9
|
+
export declare const Before: (opts: string | Hook | ((state: any) => any), f?: (state: any) => any) => void;
|
|
10
|
+
export declare const applyBeforeHooks: (state: any) => Promise<any>;
|
|
11
|
+
export declare const BeforeStep: (opts: string | Hook | ((state: any) => any), f?: (state: any) => any) => void;
|
|
12
|
+
export declare const applyBeforeStepHooks: (state: any) => Promise<any>;
|
|
13
|
+
export declare const AfterAll: (opts: string | Hook | ((state: any) => any), f?: (state: any) => any) => void;
|
|
14
|
+
export declare const applyAfterAllHooks: (state: any) => Promise<any>;
|
|
15
|
+
export declare const After: (opts: string | Hook | ((state: any) => any), f?: (state: any) => any) => void;
|
|
16
|
+
export declare const applyAfterHooks: (state: any) => Promise<any>;
|
|
17
|
+
export declare const AfterStep: (opts: string | Hook | ((state: any) => any), f?: (state: any) => any) => void;
|
|
18
|
+
export declare const applyAfterStepHooks: (state: any) => Promise<any>;
|
|
19
|
+
export {};
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var cucumberExpressions = require('@cucumber/cucumber-expressions');
|
|
6
|
+
var lodashEs = require('lodash-es');
|
|
7
|
+
var parse = require('@cucumber/tag-expressions');
|
|
8
|
+
var Gherkin = require('@cucumber/gherkin');
|
|
9
|
+
var Messages = require('@cucumber/messages');
|
|
10
|
+
var fg = require('fast-glob');
|
|
11
|
+
var path = require('path');
|
|
12
|
+
var cucumber = require('@cucumber/cucumber');
|
|
13
|
+
|
|
14
|
+
function _interopNamespaceDefault(e) {
|
|
15
|
+
var n = Object.create(null);
|
|
16
|
+
if (e) {
|
|
17
|
+
Object.keys(e).forEach(function (k) {
|
|
18
|
+
if (k !== 'default') {
|
|
19
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
20
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return e[k]; }
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
n.default = e;
|
|
28
|
+
return Object.freeze(n);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
var Gherkin__namespace = /*#__PURE__*/_interopNamespaceDefault(Gherkin);
|
|
32
|
+
var Messages__namespace = /*#__PURE__*/_interopNamespaceDefault(Messages);
|
|
33
|
+
|
|
34
|
+
const steps = [];
|
|
35
|
+
const expressionFactory = new cucumberExpressions.ExpressionFactory(new cucumberExpressions.ParameterTypeRegistry());
|
|
36
|
+
const addStepDefinition = (expression, f) => {
|
|
37
|
+
const cucumberExpression = expressionFactory.createExpression(expression);
|
|
38
|
+
steps.push({ expression, f, cucumberExpression });
|
|
39
|
+
};
|
|
40
|
+
const findStepDefinitionMatches = (step) => {
|
|
41
|
+
return steps.reduce((accumulator, stepDefinition) => {
|
|
42
|
+
const matches = stepDefinition.cucumberExpression.match(step);
|
|
43
|
+
if (matches) {
|
|
44
|
+
return [...accumulator, {
|
|
45
|
+
stepDefinition,
|
|
46
|
+
parameters: matches.map((match) => match.getValue())
|
|
47
|
+
}];
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return accumulator;
|
|
51
|
+
}
|
|
52
|
+
}, []);
|
|
53
|
+
};
|
|
54
|
+
const findStepDefinitionMatch = (step) => {
|
|
55
|
+
const stepDefinitionMatches = findStepDefinitionMatches(step);
|
|
56
|
+
if (!stepDefinitionMatches || stepDefinitionMatches.length === 0) {
|
|
57
|
+
throw new Error(`Undefined. Implement with the following snippet:
|
|
58
|
+
|
|
59
|
+
Given('${step}', (world, ...params) => {
|
|
60
|
+
// Write code here that turns the phrase above into concrete actions
|
|
61
|
+
throw new Error('Not yet implemented!');
|
|
62
|
+
return state;
|
|
63
|
+
});
|
|
64
|
+
`);
|
|
65
|
+
}
|
|
66
|
+
if (stepDefinitionMatches.length > 1) {
|
|
67
|
+
throw new Error(`More than one step which matches: '${step}'`);
|
|
68
|
+
}
|
|
69
|
+
return stepDefinitionMatches[0];
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const parseTagsExpression = (tagsExpression) => {
|
|
73
|
+
try {
|
|
74
|
+
const parsedExpression = parse(tagsExpression);
|
|
75
|
+
return parsedExpression;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
throw new Error(`Failed to parse tag expression: ${error.message}`);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const tagsFunction = (tagsExpression) => {
|
|
82
|
+
if (!tagsExpression) {
|
|
83
|
+
return (tags) => true;
|
|
84
|
+
}
|
|
85
|
+
const parsedTagsExpression = parseTagsExpression(tagsExpression);
|
|
86
|
+
return (tags) => {
|
|
87
|
+
const result = parsedTagsExpression.evaluate(tags);
|
|
88
|
+
return result;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const allHooks = {
|
|
93
|
+
beforeAll: [],
|
|
94
|
+
before: [],
|
|
95
|
+
beforeStep: [],
|
|
96
|
+
afterAll: [],
|
|
97
|
+
after: [],
|
|
98
|
+
afterStep: [],
|
|
99
|
+
};
|
|
100
|
+
const applyHooks = async (hooksName, state) => {
|
|
101
|
+
const hooks = allHooks[hooksName];
|
|
102
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
103
|
+
let hook = hooks[i];
|
|
104
|
+
const result = hook.tagsFunction(state.info.tags);
|
|
105
|
+
if (result) {
|
|
106
|
+
await hook.f(state);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return state;
|
|
110
|
+
};
|
|
111
|
+
const addHook = (hooksName, opts, f) => {
|
|
112
|
+
let hookOpts;
|
|
113
|
+
if (lodashEs.isFunction(opts)) {
|
|
114
|
+
hookOpts = { name: '', f: opts, tagsFunction: () => true };
|
|
115
|
+
}
|
|
116
|
+
else if (lodashEs.isString(opts)) {
|
|
117
|
+
hookOpts = { name: opts, f: f, tagsFunction: () => true };
|
|
118
|
+
}
|
|
119
|
+
else if (lodashEs.isObject(opts)) {
|
|
120
|
+
hookOpts = opts;
|
|
121
|
+
hookOpts.f = f;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
throw new Error('Unknown options argument: ' + JSON.stringify(opts));
|
|
125
|
+
}
|
|
126
|
+
hookOpts.tagsFunction = tagsFunction(hookOpts.tags);
|
|
127
|
+
allHooks[hooksName] = lodashEs.concat(allHooks[hooksName], hookOpts);
|
|
128
|
+
};
|
|
129
|
+
const BeforeAll = (opts, f) => { addHook('beforeAll', opts, f); };
|
|
130
|
+
const applyBeforeAllHooks = (state) => applyHooks('beforeAll', state);
|
|
131
|
+
const Before = (opts, f) => { addHook('before', opts, f); };
|
|
132
|
+
const applyBeforeHooks = (state) => applyHooks('before', state);
|
|
133
|
+
const BeforeStep = (opts, f) => { addHook('beforeStep', opts, f); };
|
|
134
|
+
const applyBeforeStepHooks = (state) => applyHooks('beforeStep', state);
|
|
135
|
+
const AfterAll = (opts, f) => { addHook('afterAll', opts, f); };
|
|
136
|
+
const applyAfterAllHooks = (state) => applyHooks('afterAll', state);
|
|
137
|
+
const After = (opts, f) => { addHook('after', opts, f); };
|
|
138
|
+
const applyAfterHooks = (state) => applyHooks('after', state);
|
|
139
|
+
const AfterStep = (opts, f) => { addHook('afterStep', opts, f); };
|
|
140
|
+
const applyAfterStepHooks = (state) => applyHooks('afterStep', state);
|
|
141
|
+
|
|
142
|
+
const uuidFn = Messages__namespace.IdGenerator.uuid();
|
|
143
|
+
const builder = new Gherkin__namespace.AstBuilder(uuidFn);
|
|
144
|
+
const gherkinMatcher = new Gherkin__namespace.GherkinClassicTokenMatcher();
|
|
145
|
+
const gherkinParser = new Gherkin__namespace.Parser(builder, gherkinMatcher);
|
|
146
|
+
const mdMatcher = new Gherkin__namespace.GherkinInMarkdownTokenMatcher();
|
|
147
|
+
const mdParser = new Gherkin__namespace.Parser(builder, mdMatcher);
|
|
148
|
+
function renderGherkin(src, config, isMarkdown) {
|
|
149
|
+
// Parse the raw file into a GherkinDocument
|
|
150
|
+
const gherkinDocument = isMarkdown ? mdParser.parse(src) : gherkinParser.parse(src);
|
|
151
|
+
// Exit if there's no feature or scenarios
|
|
152
|
+
if (!gherkinDocument?.feature || !gherkinDocument.feature?.children?.length) {
|
|
153
|
+
return '';
|
|
154
|
+
}
|
|
155
|
+
// Get the files to import from config.import
|
|
156
|
+
let imports = '';
|
|
157
|
+
const importFiles = fg.sync(config.import || [], { cwd: process.cwd() });
|
|
158
|
+
imports = importFiles.map(file => `import '${path.resolve(process.cwd(), file)}';`).join('\n');
|
|
159
|
+
return `// Generated by quickpickle
|
|
160
|
+
import { test, describe, beforeAll, afterAll } from 'vitest';
|
|
161
|
+
import {
|
|
162
|
+
qp,
|
|
163
|
+
applyBeforeAllHooks,
|
|
164
|
+
applyBeforeHooks,
|
|
165
|
+
applyAfterAllHooks,
|
|
166
|
+
applyAfterHooks,
|
|
167
|
+
getWorldConstructor,
|
|
168
|
+
} from 'quickpickle';
|
|
169
|
+
${imports}
|
|
170
|
+
let World = getWorldConstructor()
|
|
171
|
+
const worldConfig = {}
|
|
172
|
+
|
|
173
|
+
const common = {};
|
|
174
|
+
|
|
175
|
+
beforeAll(async () => {
|
|
176
|
+
await applyBeforeAllHooks(common);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
afterAll(async () => {
|
|
180
|
+
await applyAfterAllHooks(common);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const afterScenario = async(state) => {
|
|
184
|
+
await applyAfterHooks(state);
|
|
185
|
+
}
|
|
186
|
+
${renderFeature(gherkinDocument.feature, config)}
|
|
187
|
+
`;
|
|
188
|
+
}
|
|
189
|
+
function renderFeature(feature, config) {
|
|
190
|
+
// Get the feature tags
|
|
191
|
+
let tags = feature.tags.map(t => t.name);
|
|
192
|
+
// Get the background stes and all the scenarios
|
|
193
|
+
let { backgroundSteps, children } = renderChildren(feature.children, config, tags);
|
|
194
|
+
// Render the initScenario function, which will be called at the beginning of each scenario
|
|
195
|
+
return `
|
|
196
|
+
const initScenario = async(scenario, tags) => {
|
|
197
|
+
let state = new World(worldConfig);
|
|
198
|
+
await state.init(worldConfig);
|
|
199
|
+
state.common = common;
|
|
200
|
+
state.info.feature = '${q(feature.keyword)}: ${q(feature.name)}';
|
|
201
|
+
state.info.scenario = scenario;
|
|
202
|
+
state.info.tags = [...tags];
|
|
203
|
+
await applyBeforeHooks(state);
|
|
204
|
+
${backgroundSteps}
|
|
205
|
+
return state;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
describe('${q(feature.keyword)}: ${q(feature.name)}', () => {
|
|
209
|
+
${children}
|
|
210
|
+
});`;
|
|
211
|
+
}
|
|
212
|
+
function isRule(child) {
|
|
213
|
+
return child.hasOwnProperty('rule');
|
|
214
|
+
}
|
|
215
|
+
function renderChildren(children, config, tags, sp = ' ') {
|
|
216
|
+
const output = {
|
|
217
|
+
backgroundSteps: '',
|
|
218
|
+
children: '',
|
|
219
|
+
};
|
|
220
|
+
if (!children.length)
|
|
221
|
+
return output;
|
|
222
|
+
if (children[0].hasOwnProperty('background')) {
|
|
223
|
+
output.backgroundSteps = renderSteps(children.shift().background.steps, config, sp);
|
|
224
|
+
}
|
|
225
|
+
for (let child of children) {
|
|
226
|
+
if (isRule(child)) {
|
|
227
|
+
output.children += renderRule(child, config, tags, sp);
|
|
228
|
+
}
|
|
229
|
+
else if (child.hasOwnProperty('scenario')) {
|
|
230
|
+
output.children += renderScenario(child, config, tags, sp);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return output;
|
|
234
|
+
}
|
|
235
|
+
function renderRule(child, config, tags, sp = ' ') {
|
|
236
|
+
tags = [...tags, ...child.rule.tags.map(t => t.name)];
|
|
237
|
+
let { backgroundSteps, children } = renderChildren(child.rule.children, config, tags, sp + ' ');
|
|
238
|
+
return `
|
|
239
|
+
${sp}describe('${q(child.rule.keyword)}: ${q(child.rule.name)}', () => {
|
|
240
|
+
|
|
241
|
+
${sp} const initRuleScenario = async (scenario, tags) => {
|
|
242
|
+
${sp} let state = await initScenario(scenario, tags);
|
|
243
|
+
${sp} state.info.rule = '${q(child.rule.name)}';
|
|
244
|
+
${backgroundSteps}
|
|
245
|
+
${sp} return state;
|
|
246
|
+
${sp} }
|
|
247
|
+
|
|
248
|
+
${children}
|
|
249
|
+
|
|
250
|
+
${sp}});
|
|
251
|
+
`;
|
|
252
|
+
}
|
|
253
|
+
function renderScenario(child, config, tags, sp = ' ') {
|
|
254
|
+
let initFn = sp.length > 2 ? 'initRuleScenario' : 'initScenario';
|
|
255
|
+
tags = [...tags, ...child.scenario.tags.map(t => t.name)];
|
|
256
|
+
// For Scenario Outlines with examples
|
|
257
|
+
if (child.scenario.examples?.[0]?.tableHeader && child.scenario.examples?.[0]?.tableBody) {
|
|
258
|
+
let paramNames = child.scenario?.examples?.[0].tableHeader?.cells?.map(c => c.value) || [];
|
|
259
|
+
let paramValues = child.scenario?.examples?.[0].tableBody.map((r) => {
|
|
260
|
+
return lodashEs.fromPairs(r.cells.map((c, i) => [paramNames[i], c.value]));
|
|
261
|
+
});
|
|
262
|
+
function replaceParamNames(t, withBraces) {
|
|
263
|
+
paramNames.forEach(p => {
|
|
264
|
+
t = t.replace(new RegExp(`<${p}>`, 'g'), (withBraces ? `$\{${p}\}` : `$${p}`));
|
|
265
|
+
});
|
|
266
|
+
return t;
|
|
267
|
+
}
|
|
268
|
+
let describe = q(replaceParamNames(child.scenario?.name ?? ''));
|
|
269
|
+
let name = replaceParamNames(child.scenario?.name ?? '', true).replace(/`/g, '\`');
|
|
270
|
+
return `
|
|
271
|
+
${sp}test.for(${JSON.stringify(paramValues)})(
|
|
272
|
+
${sp} '${q(child.scenario?.keyword || '')}: ${describe}',
|
|
273
|
+
${sp} async ({ ${paramNames?.join(', ')} }) => {
|
|
274
|
+
${sp} let state = await ${initFn}(\`${name}\`, ['${tags.join("', '") || ''}']);
|
|
275
|
+
${child.scenario?.steps.map((step, i) => {
|
|
276
|
+
let text = step.text.replace(/`/g, '\\`');
|
|
277
|
+
text = replaceParamNames(text, true);
|
|
278
|
+
return `${sp} await qp(\`${text}\`, state, ${step.location.line});`;
|
|
279
|
+
}).join('\n')}
|
|
280
|
+
${sp} await afterScenario(state);
|
|
281
|
+
${sp} }
|
|
282
|
+
${sp});
|
|
283
|
+
`;
|
|
284
|
+
}
|
|
285
|
+
return `
|
|
286
|
+
${sp}test('${q(child.scenario.keyword)}: ${q(child.scenario.name)}', async () => {
|
|
287
|
+
${sp} let state = await ${initFn}('${q(child.scenario.name)}', ['${tags.join("', '") || ''}']);
|
|
288
|
+
${renderSteps(child.scenario.steps, config, sp + ' ')}
|
|
289
|
+
${sp} await afterScenario(state);
|
|
290
|
+
${sp}});
|
|
291
|
+
`;
|
|
292
|
+
}
|
|
293
|
+
function renderSteps(steps, config, sp = ' ') {
|
|
294
|
+
return steps.map(step => {
|
|
295
|
+
if (step.dataTable) {
|
|
296
|
+
let data = JSON.stringify(step.dataTable.rows.map(r => {
|
|
297
|
+
return r.cells.map(c => c.value);
|
|
298
|
+
}));
|
|
299
|
+
return `${sp}await qp('${q(step.text)}', state, ${step.location.line}, ${data});`;
|
|
300
|
+
}
|
|
301
|
+
else if (step.docString) {
|
|
302
|
+
let data = JSON.stringify(lodashEs.pick(step.docString, ['content', 'mediaType']));
|
|
303
|
+
return `${sp}await qp('${q(step.text)}', state, ${step.location.line}, ${data});`;
|
|
304
|
+
}
|
|
305
|
+
return `${sp}await qp('${q(step.text)}', state, ${step.location.line});`;
|
|
306
|
+
}).join('\n');
|
|
307
|
+
}
|
|
308
|
+
const q = (t) => (t.replace(/'/g, "\\'"));
|
|
309
|
+
|
|
310
|
+
class DocString extends String {
|
|
311
|
+
constructor(content, mediaType = '') {
|
|
312
|
+
super(content);
|
|
313
|
+
this.mediaType = mediaType;
|
|
314
|
+
}
|
|
315
|
+
toString() {
|
|
316
|
+
return this.valueOf();
|
|
317
|
+
}
|
|
318
|
+
[Symbol.toPrimitive](hint) {
|
|
319
|
+
if (hint === 'number') {
|
|
320
|
+
return Number(this.valueOf());
|
|
321
|
+
}
|
|
322
|
+
return this.valueOf();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
class QuickPickleWorld {
|
|
327
|
+
constructor() {
|
|
328
|
+
this.info = {
|
|
329
|
+
feature: '',
|
|
330
|
+
scenario: '',
|
|
331
|
+
tags: [],
|
|
332
|
+
rule: '',
|
|
333
|
+
step: '',
|
|
334
|
+
};
|
|
335
|
+
this.common = {};
|
|
336
|
+
}
|
|
337
|
+
async init() { }
|
|
338
|
+
}
|
|
339
|
+
let worldConstructor = QuickPickleWorld;
|
|
340
|
+
function getWorldConstructor() {
|
|
341
|
+
return worldConstructor;
|
|
342
|
+
}
|
|
343
|
+
function setWorldConstructor(constructor) {
|
|
344
|
+
worldConstructor = constructor;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const featureRegex = /\.feature(?:\.md)?$/;
|
|
348
|
+
const Given = addStepDefinition;
|
|
349
|
+
const When = addStepDefinition;
|
|
350
|
+
const Then = addStepDefinition;
|
|
351
|
+
const qp = async (step, state, line, data) => {
|
|
352
|
+
const stepDefinitionMatch = findStepDefinitionMatch(step);
|
|
353
|
+
// Set the state info
|
|
354
|
+
state.info.step = step;
|
|
355
|
+
state.info.line = line;
|
|
356
|
+
// Sort out the DataTable or DocString
|
|
357
|
+
if (Array.isArray(data)) {
|
|
358
|
+
data = new cucumber.DataTable(data);
|
|
359
|
+
}
|
|
360
|
+
else if (data?.hasOwnProperty('content')) {
|
|
361
|
+
data = new DocString(data.content, data.mediaType);
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
applyBeforeStepHooks(state);
|
|
365
|
+
await stepDefinitionMatch.stepDefinition.f(state, ...stepDefinitionMatch.parameters, data);
|
|
366
|
+
applyAfterStepHooks(state);
|
|
367
|
+
}
|
|
368
|
+
catch (e) {
|
|
369
|
+
e.message = `${step} (#${line})\n${e.message}`;
|
|
370
|
+
throw e;
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
const defaultConfig = {
|
|
374
|
+
/**
|
|
375
|
+
* The files to be imported for each Feature.
|
|
376
|
+
* All step definitions, hooks, world constructor, etc. must be listed.
|
|
377
|
+
* The value can be a glob pattern or an array of glob patterns.
|
|
378
|
+
*/
|
|
379
|
+
import: [
|
|
380
|
+
'{features,test,tests}/**/*.steps.{ts,js,mjs}',
|
|
381
|
+
'{features,test,tests}/**/*.world.{ts,js,mjs}'
|
|
382
|
+
]
|
|
383
|
+
};
|
|
384
|
+
const quickpickle = function () {
|
|
385
|
+
let config;
|
|
386
|
+
return {
|
|
387
|
+
name: 'quickpickle-transform',
|
|
388
|
+
configResolved: (resolvedConfig) => {
|
|
389
|
+
config = lodashEs.defaults(defaultConfig, lodashEs.get(resolvedConfig, 'test.cucumber'));
|
|
390
|
+
},
|
|
391
|
+
transform: async (src, id) => {
|
|
392
|
+
if (featureRegex.test(id)) {
|
|
393
|
+
return renderGherkin(src, config, id.match(/\.md$/) ? true : false);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
Object.defineProperty(exports, 'DataTable', {
|
|
400
|
+
enumerable: true,
|
|
401
|
+
get: function () { return cucumber.DataTable; }
|
|
402
|
+
});
|
|
403
|
+
exports.After = After;
|
|
404
|
+
exports.AfterAll = AfterAll;
|
|
405
|
+
exports.AfterStep = AfterStep;
|
|
406
|
+
exports.Before = Before;
|
|
407
|
+
exports.BeforeAll = BeforeAll;
|
|
408
|
+
exports.BeforeStep = BeforeStep;
|
|
409
|
+
exports.DocString = DocString;
|
|
410
|
+
exports.Given = Given;
|
|
411
|
+
exports.Then = Then;
|
|
412
|
+
exports.When = When;
|
|
413
|
+
exports.applyAfterAllHooks = applyAfterAllHooks;
|
|
414
|
+
exports.applyAfterHooks = applyAfterHooks;
|
|
415
|
+
exports.applyAfterStepHooks = applyAfterStepHooks;
|
|
416
|
+
exports.applyBeforeAllHooks = applyBeforeAllHooks;
|
|
417
|
+
exports.applyBeforeHooks = applyBeforeHooks;
|
|
418
|
+
exports.applyBeforeStepHooks = applyBeforeStepHooks;
|
|
419
|
+
exports.default = quickpickle;
|
|
420
|
+
exports.getWorldConstructor = getWorldConstructor;
|
|
421
|
+
exports.qp = qp;
|
|
422
|
+
exports.quickpickle = quickpickle;
|
|
423
|
+
exports.setWorldConstructor = setWorldConstructor;
|
|
424
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/steps.ts","../src/tags.ts","../src/hooks.ts","../src/render.ts","../src/models/DocString.ts","../src/world.ts","../src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null],"names":["ExpressionFactory","ParameterTypeRegistry","isFunction","isString","isObject","concat","Messages","Gherkin","fromPairs","pick","DataTable","defaults","get"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BeforeAll, applyBeforeAllHooks, Before, applyBeforeHooks, AfterAll, applyAfterAllHooks, After, applyAfterHooks, BeforeStep, applyBeforeStepHooks, AfterStep, applyAfterStepHooks } from './hooks';
|
|
2
|
+
import { DataTable } from '@cucumber/cucumber';
|
|
3
|
+
import { DocString } from './models/DocString';
|
|
4
|
+
export { setWorldConstructor, getWorldConstructor } from './world';
|
|
5
|
+
export { DocString, DataTable };
|
|
6
|
+
export { BeforeAll, Before, AfterAll, After, BeforeStep, AfterStep };
|
|
7
|
+
export { applyBeforeAllHooks, applyBeforeHooks, applyAfterAllHooks, applyAfterHooks, applyBeforeStepHooks, applyAfterStepHooks, };
|
|
8
|
+
export declare const Given: (expression: string, f: (state: any, ...args: any[]) => any) => void;
|
|
9
|
+
export declare const When: (expression: string, f: (state: any, ...args: any[]) => any) => void;
|
|
10
|
+
export declare const Then: (expression: string, f: (state: any, ...args: any[]) => any) => void;
|
|
11
|
+
export declare const qp: (step: string, state: any, line: number, data?: any) => Promise<any>;
|
|
12
|
+
export type QuickPickleConfig = {
|
|
13
|
+
import: string | string[];
|
|
14
|
+
};
|
|
15
|
+
interface ResolvedConfig {
|
|
16
|
+
test?: {
|
|
17
|
+
cucumber?: Partial<QuickPickleConfig>;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare const quickpickle: () => {
|
|
21
|
+
name: string;
|
|
22
|
+
configResolved: (resolvedConfig: ResolvedConfig) => void;
|
|
23
|
+
transform: (src: string, id: string) => Promise<string | undefined>;
|
|
24
|
+
};
|
|
25
|
+
export default quickpickle;
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { ExpressionFactory, ParameterTypeRegistry } from '@cucumber/cucumber-expressions';
|
|
2
|
+
import { isFunction, isString, isObject, concat, fromPairs, pick, defaults, get } from 'lodash-es';
|
|
3
|
+
import parse from '@cucumber/tag-expressions';
|
|
4
|
+
import * as Gherkin from '@cucumber/gherkin';
|
|
5
|
+
import * as Messages from '@cucumber/messages';
|
|
6
|
+
import fg from 'fast-glob';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { DataTable } from '@cucumber/cucumber';
|
|
9
|
+
export { DataTable } from '@cucumber/cucumber';
|
|
10
|
+
|
|
11
|
+
const steps = [];
|
|
12
|
+
const expressionFactory = new ExpressionFactory(new ParameterTypeRegistry());
|
|
13
|
+
const addStepDefinition = (expression, f) => {
|
|
14
|
+
const cucumberExpression = expressionFactory.createExpression(expression);
|
|
15
|
+
steps.push({ expression, f, cucumberExpression });
|
|
16
|
+
};
|
|
17
|
+
const findStepDefinitionMatches = (step) => {
|
|
18
|
+
return steps.reduce((accumulator, stepDefinition) => {
|
|
19
|
+
const matches = stepDefinition.cucumberExpression.match(step);
|
|
20
|
+
if (matches) {
|
|
21
|
+
return [...accumulator, {
|
|
22
|
+
stepDefinition,
|
|
23
|
+
parameters: matches.map((match) => match.getValue())
|
|
24
|
+
}];
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
return accumulator;
|
|
28
|
+
}
|
|
29
|
+
}, []);
|
|
30
|
+
};
|
|
31
|
+
const findStepDefinitionMatch = (step) => {
|
|
32
|
+
const stepDefinitionMatches = findStepDefinitionMatches(step);
|
|
33
|
+
if (!stepDefinitionMatches || stepDefinitionMatches.length === 0) {
|
|
34
|
+
throw new Error(`Undefined. Implement with the following snippet:
|
|
35
|
+
|
|
36
|
+
Given('${step}', (world, ...params) => {
|
|
37
|
+
// Write code here that turns the phrase above into concrete actions
|
|
38
|
+
throw new Error('Not yet implemented!');
|
|
39
|
+
return state;
|
|
40
|
+
});
|
|
41
|
+
`);
|
|
42
|
+
}
|
|
43
|
+
if (stepDefinitionMatches.length > 1) {
|
|
44
|
+
throw new Error(`More than one step which matches: '${step}'`);
|
|
45
|
+
}
|
|
46
|
+
return stepDefinitionMatches[0];
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const parseTagsExpression = (tagsExpression) => {
|
|
50
|
+
try {
|
|
51
|
+
const parsedExpression = parse(tagsExpression);
|
|
52
|
+
return parsedExpression;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
throw new Error(`Failed to parse tag expression: ${error.message}`);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const tagsFunction = (tagsExpression) => {
|
|
59
|
+
if (!tagsExpression) {
|
|
60
|
+
return (tags) => true;
|
|
61
|
+
}
|
|
62
|
+
const parsedTagsExpression = parseTagsExpression(tagsExpression);
|
|
63
|
+
return (tags) => {
|
|
64
|
+
const result = parsedTagsExpression.evaluate(tags);
|
|
65
|
+
return result;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const allHooks = {
|
|
70
|
+
beforeAll: [],
|
|
71
|
+
before: [],
|
|
72
|
+
beforeStep: [],
|
|
73
|
+
afterAll: [],
|
|
74
|
+
after: [],
|
|
75
|
+
afterStep: [],
|
|
76
|
+
};
|
|
77
|
+
const applyHooks = async (hooksName, state) => {
|
|
78
|
+
const hooks = allHooks[hooksName];
|
|
79
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
80
|
+
let hook = hooks[i];
|
|
81
|
+
const result = hook.tagsFunction(state.info.tags);
|
|
82
|
+
if (result) {
|
|
83
|
+
await hook.f(state);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return state;
|
|
87
|
+
};
|
|
88
|
+
const addHook = (hooksName, opts, f) => {
|
|
89
|
+
let hookOpts;
|
|
90
|
+
if (isFunction(opts)) {
|
|
91
|
+
hookOpts = { name: '', f: opts, tagsFunction: () => true };
|
|
92
|
+
}
|
|
93
|
+
else if (isString(opts)) {
|
|
94
|
+
hookOpts = { name: opts, f: f, tagsFunction: () => true };
|
|
95
|
+
}
|
|
96
|
+
else if (isObject(opts)) {
|
|
97
|
+
hookOpts = opts;
|
|
98
|
+
hookOpts.f = f;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
throw new Error('Unknown options argument: ' + JSON.stringify(opts));
|
|
102
|
+
}
|
|
103
|
+
hookOpts.tagsFunction = tagsFunction(hookOpts.tags);
|
|
104
|
+
allHooks[hooksName] = concat(allHooks[hooksName], hookOpts);
|
|
105
|
+
};
|
|
106
|
+
const BeforeAll = (opts, f) => { addHook('beforeAll', opts, f); };
|
|
107
|
+
const applyBeforeAllHooks = (state) => applyHooks('beforeAll', state);
|
|
108
|
+
const Before = (opts, f) => { addHook('before', opts, f); };
|
|
109
|
+
const applyBeforeHooks = (state) => applyHooks('before', state);
|
|
110
|
+
const BeforeStep = (opts, f) => { addHook('beforeStep', opts, f); };
|
|
111
|
+
const applyBeforeStepHooks = (state) => applyHooks('beforeStep', state);
|
|
112
|
+
const AfterAll = (opts, f) => { addHook('afterAll', opts, f); };
|
|
113
|
+
const applyAfterAllHooks = (state) => applyHooks('afterAll', state);
|
|
114
|
+
const After = (opts, f) => { addHook('after', opts, f); };
|
|
115
|
+
const applyAfterHooks = (state) => applyHooks('after', state);
|
|
116
|
+
const AfterStep = (opts, f) => { addHook('afterStep', opts, f); };
|
|
117
|
+
const applyAfterStepHooks = (state) => applyHooks('afterStep', state);
|
|
118
|
+
|
|
119
|
+
const uuidFn = Messages.IdGenerator.uuid();
|
|
120
|
+
const builder = new Gherkin.AstBuilder(uuidFn);
|
|
121
|
+
const gherkinMatcher = new Gherkin.GherkinClassicTokenMatcher();
|
|
122
|
+
const gherkinParser = new Gherkin.Parser(builder, gherkinMatcher);
|
|
123
|
+
const mdMatcher = new Gherkin.GherkinInMarkdownTokenMatcher();
|
|
124
|
+
const mdParser = new Gherkin.Parser(builder, mdMatcher);
|
|
125
|
+
function renderGherkin(src, config, isMarkdown) {
|
|
126
|
+
// Parse the raw file into a GherkinDocument
|
|
127
|
+
const gherkinDocument = isMarkdown ? mdParser.parse(src) : gherkinParser.parse(src);
|
|
128
|
+
// Exit if there's no feature or scenarios
|
|
129
|
+
if (!gherkinDocument?.feature || !gherkinDocument.feature?.children?.length) {
|
|
130
|
+
return '';
|
|
131
|
+
}
|
|
132
|
+
// Get the files to import from config.import
|
|
133
|
+
let imports = '';
|
|
134
|
+
const importFiles = fg.sync(config.import || [], { cwd: process.cwd() });
|
|
135
|
+
imports = importFiles.map(file => `import '${path.resolve(process.cwd(), file)}';`).join('\n');
|
|
136
|
+
return `// Generated by quickpickle
|
|
137
|
+
import { test, describe, beforeAll, afterAll } from 'vitest';
|
|
138
|
+
import {
|
|
139
|
+
qp,
|
|
140
|
+
applyBeforeAllHooks,
|
|
141
|
+
applyBeforeHooks,
|
|
142
|
+
applyAfterAllHooks,
|
|
143
|
+
applyAfterHooks,
|
|
144
|
+
getWorldConstructor,
|
|
145
|
+
} from 'quickpickle';
|
|
146
|
+
${imports}
|
|
147
|
+
let World = getWorldConstructor()
|
|
148
|
+
const worldConfig = {}
|
|
149
|
+
|
|
150
|
+
const common = {};
|
|
151
|
+
|
|
152
|
+
beforeAll(async () => {
|
|
153
|
+
await applyBeforeAllHooks(common);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
afterAll(async () => {
|
|
157
|
+
await applyAfterAllHooks(common);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const afterScenario = async(state) => {
|
|
161
|
+
await applyAfterHooks(state);
|
|
162
|
+
}
|
|
163
|
+
${renderFeature(gherkinDocument.feature, config)}
|
|
164
|
+
`;
|
|
165
|
+
}
|
|
166
|
+
function renderFeature(feature, config) {
|
|
167
|
+
// Get the feature tags
|
|
168
|
+
let tags = feature.tags.map(t => t.name);
|
|
169
|
+
// Get the background stes and all the scenarios
|
|
170
|
+
let { backgroundSteps, children } = renderChildren(feature.children, config, tags);
|
|
171
|
+
// Render the initScenario function, which will be called at the beginning of each scenario
|
|
172
|
+
return `
|
|
173
|
+
const initScenario = async(scenario, tags) => {
|
|
174
|
+
let state = new World(worldConfig);
|
|
175
|
+
await state.init(worldConfig);
|
|
176
|
+
state.common = common;
|
|
177
|
+
state.info.feature = '${q(feature.keyword)}: ${q(feature.name)}';
|
|
178
|
+
state.info.scenario = scenario;
|
|
179
|
+
state.info.tags = [...tags];
|
|
180
|
+
await applyBeforeHooks(state);
|
|
181
|
+
${backgroundSteps}
|
|
182
|
+
return state;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
describe('${q(feature.keyword)}: ${q(feature.name)}', () => {
|
|
186
|
+
${children}
|
|
187
|
+
});`;
|
|
188
|
+
}
|
|
189
|
+
function isRule(child) {
|
|
190
|
+
return child.hasOwnProperty('rule');
|
|
191
|
+
}
|
|
192
|
+
function renderChildren(children, config, tags, sp = ' ') {
|
|
193
|
+
const output = {
|
|
194
|
+
backgroundSteps: '',
|
|
195
|
+
children: '',
|
|
196
|
+
};
|
|
197
|
+
if (!children.length)
|
|
198
|
+
return output;
|
|
199
|
+
if (children[0].hasOwnProperty('background')) {
|
|
200
|
+
output.backgroundSteps = renderSteps(children.shift().background.steps, config, sp);
|
|
201
|
+
}
|
|
202
|
+
for (let child of children) {
|
|
203
|
+
if (isRule(child)) {
|
|
204
|
+
output.children += renderRule(child, config, tags, sp);
|
|
205
|
+
}
|
|
206
|
+
else if (child.hasOwnProperty('scenario')) {
|
|
207
|
+
output.children += renderScenario(child, config, tags, sp);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return output;
|
|
211
|
+
}
|
|
212
|
+
function renderRule(child, config, tags, sp = ' ') {
|
|
213
|
+
tags = [...tags, ...child.rule.tags.map(t => t.name)];
|
|
214
|
+
let { backgroundSteps, children } = renderChildren(child.rule.children, config, tags, sp + ' ');
|
|
215
|
+
return `
|
|
216
|
+
${sp}describe('${q(child.rule.keyword)}: ${q(child.rule.name)}', () => {
|
|
217
|
+
|
|
218
|
+
${sp} const initRuleScenario = async (scenario, tags) => {
|
|
219
|
+
${sp} let state = await initScenario(scenario, tags);
|
|
220
|
+
${sp} state.info.rule = '${q(child.rule.name)}';
|
|
221
|
+
${backgroundSteps}
|
|
222
|
+
${sp} return state;
|
|
223
|
+
${sp} }
|
|
224
|
+
|
|
225
|
+
${children}
|
|
226
|
+
|
|
227
|
+
${sp}});
|
|
228
|
+
`;
|
|
229
|
+
}
|
|
230
|
+
function renderScenario(child, config, tags, sp = ' ') {
|
|
231
|
+
let initFn = sp.length > 2 ? 'initRuleScenario' : 'initScenario';
|
|
232
|
+
tags = [...tags, ...child.scenario.tags.map(t => t.name)];
|
|
233
|
+
// For Scenario Outlines with examples
|
|
234
|
+
if (child.scenario.examples?.[0]?.tableHeader && child.scenario.examples?.[0]?.tableBody) {
|
|
235
|
+
let paramNames = child.scenario?.examples?.[0].tableHeader?.cells?.map(c => c.value) || [];
|
|
236
|
+
let paramValues = child.scenario?.examples?.[0].tableBody.map((r) => {
|
|
237
|
+
return fromPairs(r.cells.map((c, i) => [paramNames[i], c.value]));
|
|
238
|
+
});
|
|
239
|
+
function replaceParamNames(t, withBraces) {
|
|
240
|
+
paramNames.forEach(p => {
|
|
241
|
+
t = t.replace(new RegExp(`<${p}>`, 'g'), (withBraces ? `$\{${p}\}` : `$${p}`));
|
|
242
|
+
});
|
|
243
|
+
return t;
|
|
244
|
+
}
|
|
245
|
+
let describe = q(replaceParamNames(child.scenario?.name ?? ''));
|
|
246
|
+
let name = replaceParamNames(child.scenario?.name ?? '', true).replace(/`/g, '\`');
|
|
247
|
+
return `
|
|
248
|
+
${sp}test.for(${JSON.stringify(paramValues)})(
|
|
249
|
+
${sp} '${q(child.scenario?.keyword || '')}: ${describe}',
|
|
250
|
+
${sp} async ({ ${paramNames?.join(', ')} }) => {
|
|
251
|
+
${sp} let state = await ${initFn}(\`${name}\`, ['${tags.join("', '") || ''}']);
|
|
252
|
+
${child.scenario?.steps.map((step, i) => {
|
|
253
|
+
let text = step.text.replace(/`/g, '\\`');
|
|
254
|
+
text = replaceParamNames(text, true);
|
|
255
|
+
return `${sp} await qp(\`${text}\`, state, ${step.location.line});`;
|
|
256
|
+
}).join('\n')}
|
|
257
|
+
${sp} await afterScenario(state);
|
|
258
|
+
${sp} }
|
|
259
|
+
${sp});
|
|
260
|
+
`;
|
|
261
|
+
}
|
|
262
|
+
return `
|
|
263
|
+
${sp}test('${q(child.scenario.keyword)}: ${q(child.scenario.name)}', async () => {
|
|
264
|
+
${sp} let state = await ${initFn}('${q(child.scenario.name)}', ['${tags.join("', '") || ''}']);
|
|
265
|
+
${renderSteps(child.scenario.steps, config, sp + ' ')}
|
|
266
|
+
${sp} await afterScenario(state);
|
|
267
|
+
${sp}});
|
|
268
|
+
`;
|
|
269
|
+
}
|
|
270
|
+
function renderSteps(steps, config, sp = ' ') {
|
|
271
|
+
return steps.map(step => {
|
|
272
|
+
if (step.dataTable) {
|
|
273
|
+
let data = JSON.stringify(step.dataTable.rows.map(r => {
|
|
274
|
+
return r.cells.map(c => c.value);
|
|
275
|
+
}));
|
|
276
|
+
return `${sp}await qp('${q(step.text)}', state, ${step.location.line}, ${data});`;
|
|
277
|
+
}
|
|
278
|
+
else if (step.docString) {
|
|
279
|
+
let data = JSON.stringify(pick(step.docString, ['content', 'mediaType']));
|
|
280
|
+
return `${sp}await qp('${q(step.text)}', state, ${step.location.line}, ${data});`;
|
|
281
|
+
}
|
|
282
|
+
return `${sp}await qp('${q(step.text)}', state, ${step.location.line});`;
|
|
283
|
+
}).join('\n');
|
|
284
|
+
}
|
|
285
|
+
const q = (t) => (t.replace(/'/g, "\\'"));
|
|
286
|
+
|
|
287
|
+
class DocString extends String {
|
|
288
|
+
constructor(content, mediaType = '') {
|
|
289
|
+
super(content);
|
|
290
|
+
this.mediaType = mediaType;
|
|
291
|
+
}
|
|
292
|
+
toString() {
|
|
293
|
+
return this.valueOf();
|
|
294
|
+
}
|
|
295
|
+
[Symbol.toPrimitive](hint) {
|
|
296
|
+
if (hint === 'number') {
|
|
297
|
+
return Number(this.valueOf());
|
|
298
|
+
}
|
|
299
|
+
return this.valueOf();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
class QuickPickleWorld {
|
|
304
|
+
constructor() {
|
|
305
|
+
this.info = {
|
|
306
|
+
feature: '',
|
|
307
|
+
scenario: '',
|
|
308
|
+
tags: [],
|
|
309
|
+
rule: '',
|
|
310
|
+
step: '',
|
|
311
|
+
};
|
|
312
|
+
this.common = {};
|
|
313
|
+
}
|
|
314
|
+
async init() { }
|
|
315
|
+
}
|
|
316
|
+
let worldConstructor = QuickPickleWorld;
|
|
317
|
+
function getWorldConstructor() {
|
|
318
|
+
return worldConstructor;
|
|
319
|
+
}
|
|
320
|
+
function setWorldConstructor(constructor) {
|
|
321
|
+
worldConstructor = constructor;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const featureRegex = /\.feature(?:\.md)?$/;
|
|
325
|
+
const Given = addStepDefinition;
|
|
326
|
+
const When = addStepDefinition;
|
|
327
|
+
const Then = addStepDefinition;
|
|
328
|
+
const qp = async (step, state, line, data) => {
|
|
329
|
+
const stepDefinitionMatch = findStepDefinitionMatch(step);
|
|
330
|
+
// Set the state info
|
|
331
|
+
state.info.step = step;
|
|
332
|
+
state.info.line = line;
|
|
333
|
+
// Sort out the DataTable or DocString
|
|
334
|
+
if (Array.isArray(data)) {
|
|
335
|
+
data = new DataTable(data);
|
|
336
|
+
}
|
|
337
|
+
else if (data?.hasOwnProperty('content')) {
|
|
338
|
+
data = new DocString(data.content, data.mediaType);
|
|
339
|
+
}
|
|
340
|
+
try {
|
|
341
|
+
applyBeforeStepHooks(state);
|
|
342
|
+
await stepDefinitionMatch.stepDefinition.f(state, ...stepDefinitionMatch.parameters, data);
|
|
343
|
+
applyAfterStepHooks(state);
|
|
344
|
+
}
|
|
345
|
+
catch (e) {
|
|
346
|
+
e.message = `${step} (#${line})\n${e.message}`;
|
|
347
|
+
throw e;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
const defaultConfig = {
|
|
351
|
+
/**
|
|
352
|
+
* The files to be imported for each Feature.
|
|
353
|
+
* All step definitions, hooks, world constructor, etc. must be listed.
|
|
354
|
+
* The value can be a glob pattern or an array of glob patterns.
|
|
355
|
+
*/
|
|
356
|
+
import: [
|
|
357
|
+
'{features,test,tests}/**/*.steps.{ts,js,mjs}',
|
|
358
|
+
'{features,test,tests}/**/*.world.{ts,js,mjs}'
|
|
359
|
+
]
|
|
360
|
+
};
|
|
361
|
+
const quickpickle = function () {
|
|
362
|
+
let config;
|
|
363
|
+
return {
|
|
364
|
+
name: 'quickpickle-transform',
|
|
365
|
+
configResolved: (resolvedConfig) => {
|
|
366
|
+
config = defaults(defaultConfig, get(resolvedConfig, 'test.cucumber'));
|
|
367
|
+
},
|
|
368
|
+
transform: async (src, id) => {
|
|
369
|
+
if (featureRegex.test(id)) {
|
|
370
|
+
return renderGherkin(src, config, id.match(/\.md$/) ? true : false);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
export { After, AfterAll, AfterStep, Before, BeforeAll, BeforeStep, DocString, Given, Then, When, applyAfterAllHooks, applyAfterHooks, applyAfterStepHooks, applyBeforeAllHooks, applyBeforeHooks, applyBeforeStepHooks, quickpickle as default, getWorldConstructor, qp, quickpickle, setWorldConstructor };
|
|
377
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/steps.ts","../src/tags.ts","../src/hooks.ts","../src/render.ts","../src/models/DocString.ts","../src/world.ts","../src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null],"names":[],"mappings":";;;;;;;;;;AAqBA,MAAM,KAAK,GAAqB,EAAE,CAAC;AAQnC,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC;AAEtE,MAAM,iBAAiB,GAAG,CAAC,UAAkB,EAAE,CAAsC,KAAU;IACpG,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAC1E,KAAK,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,IAAW,KAA2B;IACvE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,WAAkC,EAAE,cAA8B,KAAI;QACzF,MAAM,OAAO,GAAG,cAAc,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,OAAO,EAAE;YACX,OAAO,CAAC,GAAG,WAAW,EAAE;oBACtB,cAAc;AACd,oBAAA,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAAU,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC;AAC1D,iBAAA,CAAC,CAAC;SACJ;aAAM;AACL,YAAA,OAAO,WAAW,CAAC;SACpB;KACF,EAAE,EAAE,CAAC,CAAC;AACT,CAAC,CAAC;AAEK,MAAM,uBAAuB,GAAG,CAAC,IAAW,KAAyB;AAC1E,IAAA,MAAM,qBAAqB,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAE9D,IAAI,CAAC,qBAAqB,IAAI,qBAAqB,CAAC,MAAM,KAAK,CAAC,EAAE;QAChE,MAAM,IAAI,KAAK,CAAC,CAAA;;WAET,IAAI,CAAA;;;;;AAKd,CAAA,CAAC,CAAC;KACA;AAED,IAAA,IAAI,qBAAqB,CAAC,MAAM,GAAG,CAAC,EAAE;AACpC,QAAA,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,CAAA,CAAA,CAAG,CAAC,CAAC;KAChE;AAED,IAAA,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;;AC/DD,MAAM,mBAAmB,GAAG,CAAC,cAAsB,KAAmB;AACpE,IAAA,IAAI;AACF,QAAA,MAAM,gBAAgB,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;AAC/C,QAAA,OAAO,gBAAgB,CAAC;KACzB;IAAC,OAAO,KAAK,EAAE;QACd,MAAM,IAAI,KAAK,CAAC,CAAA,gCAAA,EAAoC,KAAe,CAAC,OAAO,CAAE,CAAA,CAAC,CAAC;KAChF;AACH,CAAC,CAAA;AAEM,MAAM,YAAY,GAAG,CAAC,cAAuB,KAAiC;IACnF,IAAI,CAAC,cAAc,EAAE;AACnB,QAAA,OAAO,CAAC,IAAc,KAAK,IAAI,CAAC;KACjC;AAED,IAAA,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;IAEjE,OAAO,CAAC,IAAc,KAAI;QACxB,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACnD,QAAA,OAAO,MAAM,CAAC;AAChB,KAAC,CAAC;AACJ,CAAC;;ACZD,MAAM,QAAQ,GAAmB;AAC/B,IAAA,SAAS,EAAE,EAAE;AACb,IAAA,MAAM,EAAE,EAAE;AACV,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,QAAQ,EAAE,EAAE;AACZ,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,SAAS,EAAE,EAAE;CACd,CAAC;AAWF,MAAM,UAAU,GAAG,OAAO,SAAiB,EAAE,KAAU,KAAkB;AACvE,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AAClC,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACrC,QAAA,IAAI,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;AACpB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;SACrB;KACF;AACD,IAAA,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,SAAiB,EAAE,IAA2C,EAAE,CAAuB,KAAU;AAChH,IAAA,IAAI,QAAc,CAAC;AAEnB,IAAA,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE;AACpB,QAAA,QAAQ,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;KAC5D;AAAM,SAAA,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE;AACzB,QAAA,QAAQ,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAE,EAAE,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;KAC5D;AAAM,SAAA,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE;QACzB,QAAQ,GAAG,IAAY,CAAC;AACxB,QAAA,QAAQ,CAAC,CAAC,GAAG,CAAE,CAAC;KACjB;SAAM;AACL,QAAA,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;KACtE;IAED,QAAQ,CAAC,YAAY,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAEpD,IAAA,QAAQ,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC9D,CAAC,CAAC;MAEW,SAAS,GAAG,CAAC,IAA2C,EAAE,CAAuB,KAAU,EAAG,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA,GAAG;AACpI,MAAM,mBAAmB,GAAG,CAAC,KAAU,KAAmB,UAAU,CAAC,WAAW,EAAE,KAAK,EAAE;MAEnF,MAAM,GAAG,CAAC,IAA2C,EAAE,CAAuB,KAAU,EAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA,GAAG;AAC9H,MAAM,gBAAgB,GAAG,CAAC,KAAU,KAAmB,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE;MAE7E,UAAU,GAAG,CAAC,IAA2C,EAAE,CAAuB,KAAU,EAAG,OAAO,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA,GAAG;AACtI,MAAM,oBAAoB,GAAG,CAAC,KAAU,KAAmB,UAAU,CAAC,YAAY,EAAE,KAAK,EAAE;MAErF,QAAQ,GAAG,CAAC,IAA2C,EAAE,CAAuB,KAAU,EAAG,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA,GAAG;AAClI,MAAM,kBAAkB,GAAG,CAAC,KAAU,KAAmB,UAAU,CAAC,UAAU,EAAE,KAAK,EAAE;MAEjF,KAAK,GAAG,CAAC,IAA2C,EAAE,CAAuB,KAAU,EAAG,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA,GAAG;AAC5H,MAAM,eAAe,GAAG,CAAC,KAAU,KAAmB,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE;MAE3E,SAAS,GAAG,CAAC,IAA2C,EAAE,CAAuB,KAAU,EAAG,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA,GAAG;AACpI,MAAM,mBAAmB,GAAG,CAAC,KAAU,KAAmB,UAAU,CAAC,WAAW,EAAE,KAAK;;ACtE9F,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;AAC3C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AAC/C,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;AAChE,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;AAClE,MAAM,SAAS,GAAG,IAAI,OAAO,CAAC,6BAA6B,EAAE,CAAC;AAC9D,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;SAExC,aAAa,CAAC,GAAU,EAAE,MAAwB,EAAE,UAAmB,EAAA;;IAGrF,MAAM,eAAe,GAAG,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;;AAGnF,IAAA,IAAI,CAAC,eAAe,EAAE,OAAO,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;AAC3E,QAAA,OAAO,EAAE,CAAA;KACV;;IAGD,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AACxE,IAAA,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,IAAI,CAAA,QAAA,EAAW,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAA,EAAA,CAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE9F,OAAO,CAAA;;;;;;;;;;EAUP,OAAO,CAAA;;;;;;;;;;;;;;;;;AAiBP,EAAA,aAAa,CAAC,eAAe,CAAC,OAAQ,EAAE,MAAM,CAAC,CAAA;CAChD,CAAA;AACD,CAAC;AAEe,SAAA,aAAa,CAAC,OAAe,EAAE,MAAwB,EAAA;;AAGrE,IAAA,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAA;;AAGxC,IAAA,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,QAA0B,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;;IAGpG,OAAM,CAAA;;;;;0BAKkB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAK,EAAA,EAAA,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;;;;EAI9D,eAAe,CAAA;;;;YAIL,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAK,EAAA,EAAA,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;EAChD,QAAQ,CAAA;IACN,CAAA;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,KAA4B,EAAA;AAC1C,IAAA,OAAO,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAA;AACrC,CAAC;AAED,SAAS,cAAc,CAAC,QAAmC,EAAE,MAAwB,EAAE,IAAa,EAAE,EAAE,GAAG,IAAI,EAAA;AAE7G,IAAA,MAAM,MAAM,GAAG;AACb,QAAA,eAAe,EAAE,EAAE;AACnB,QAAA,QAAQ,EAAE,EAAE;KACb,CAAA;IAED,IAAI,CAAC,QAAQ,CAAC,MAAM;AAAE,QAAA,OAAO,MAAM,CAAA;IAEnC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE;AAC5C,QAAA,MAAM,CAAC,eAAe,GAAG,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAG,CAAC,UAAW,CAAC,KAAe,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;KAChG;AAED,IAAA,KAAK,IAAI,KAAK,IAAI,QAAQ,EAAE;AAC1B,QAAA,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE;AACjB,YAAA,MAAM,CAAC,QAAQ,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;SACvD;AACI,aAAA,IAAI,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE;AACzC,YAAA,MAAM,CAAC,QAAQ,IAAI,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;SAC3D;KACF;AAED,IAAA,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,UAAU,CAAC,KAAkB,EAAE,MAAwB,EAAE,IAAa,EAAE,EAAE,GAAG,IAAI,EAAA;IACxF,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC,IAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IACtD,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,IAAK,CAAC,QAAuB,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,CAAA;IAEhH,OAAO,CAAA;AACP,EAAA,EAAE,aAAa,CAAC,CAAC,KAAK,CAAC,IAAK,CAAC,OAAO,CAAC,CAAA,EAAA,EAAK,CAAC,CAAC,KAAK,CAAC,IAAK,CAAC,IAAI,CAAC,CAAA;;EAE7D,EAAE,CAAA;EACF,EAAE,CAAA;EACF,EAAE,CAAA,uBAAA,EAA0B,CAAC,CAAC,KAAK,CAAC,IAAK,CAAC,IAAI,CAAC,CAAA;EAC/C,eAAe,CAAA;EACf,EAAE,CAAA;EACF,EAAE,CAAA;;EAEF,QAAQ,CAAA;;EAER,EAAE,CAAA;CACH,CAAA;AACD,CAAC;AAED,SAAS,cAAc,CAAC,KAAkB,EAAE,MAAwB,EAAE,IAAa,EAAE,EAAE,GAAG,IAAI,EAAA;AAC5F,IAAA,IAAI,MAAM,GAAG,EAAE,CAAC,MAAM,GAAG,CAAC,GAAG,kBAAkB,GAAG,cAAc,CAAA;IAChE,IAAI,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC,QAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;;IAG1D,IAAI,KAAK,CAAC,QAAS,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,WAAW,IAAI,KAAK,CAAC,QAAS,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE;AAE1F,QAAA,IAAI,UAAU,GAAG,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;AAC1F,QAAA,IAAI,WAAW,GAAG,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,KAAI;YAClE,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAC,CAAC,KAAK,CAAE,UAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAE,CAAC,CAAC,CAAA;AACrE,SAAC,CAAC,CAAA;AAEF,QAAA,SAAS,iBAAiB,CAAC,CAAQ,EAAE,UAAmB,EAAA;AACtD,YAAA,UAAU,CAAC,OAAO,CAAC,CAAC,IAAG;AACrB,gBAAA,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,CAAI,CAAA,EAAA,CAAC,CAAG,CAAA,CAAA,EAAE,GAAG,CAAC,GAAG,UAAU,GAAG,CAAA,GAAA,EAAM,CAAC,CAAI,EAAA,CAAA,GAAI,CAAI,CAAA,EAAA,CAAC,CAAE,CAAA,EAAE,CAAA;AACjF,aAAC,CAAC,CAAA;AACF,YAAA,OAAO,CAAC,CAAA;SACT;AAED,QAAA,IAAI,QAAQ,GAAG,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAA;QAC/D,IAAI,IAAI,GAAG,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAElF,OAAO,CAAA;AACT,EAAA,EAAE,YAAY,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;AACzC,EAAA,EAAE,CAAM,GAAA,EAAA,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC,CAAA,EAAA,EAAK,QAAQ,CAAA;AACrD,EAAA,EAAE,cAAc,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;AACtC,EAAA,EAAE,CAAyB,sBAAA,EAAA,MAAM,CAAM,GAAA,EAAA,IAAI,CAAS,MAAA,EAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;AAC3E,EAAA,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAC,CAAC,KAAI;AACrC,YAAA,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACzC,YAAA,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAC,IAAI,CAAC,CAAA;YACnC,OAAO,CAAA,EAAG,EAAE,CAAA,eAAA,EAAkB,IAAI,CAAA,WAAA,EAAc,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAA,EAAA,CAAI,CAAA;AACxE,SAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CACZ,CAAA;EACE,EAAE,CAAA;EACF,EAAE,CAAA;EACF,EAAE,CAAA;CACH,CAAA;KACE;IAED,OAAO,CAAA;AACP,EAAA,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,QAAS,CAAC,OAAO,CAAC,CAAA,EAAA,EAAK,CAAC,CAAC,KAAK,CAAC,QAAS,CAAC,IAAI,CAAC,CAAA;AACjE,EAAA,EAAE,uBAAuB,MAAM,CAAA,EAAA,EAAK,CAAC,CAAC,KAAK,CAAC,QAAS,CAAC,IAAI,CAAC,CAAA,KAAA,EAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;AAC1F,EAAA,WAAW,CAAC,KAAK,CAAC,QAAS,CAAC,KAAe,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,CAAA;EAC/D,EAAE,CAAA;EACF,EAAE,CAAA;CACH,CAAA;AACD,CAAC;AAED,SAAS,WAAW,CAAC,KAAY,EAAE,MAAwB,EAAE,EAAE,GAAG,IAAI,EAAA;AACpE,IAAA,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,IAAG;AAEtB,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AAClB,YAAA,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAG;AACpD,gBAAA,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAA;aACjC,CAAC,CAAC,CAAA;AACH,YAAA,OAAO,GAAG,EAAE,CAAA,UAAA,EAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAa,UAAA,EAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAK,EAAA,EAAA,IAAI,IAAI,CAAA;SAClF;AACI,aAAA,IAAI,IAAI,CAAC,SAAS,EAAE;AACvB,YAAA,IAAI,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,SAAS,EAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AACxE,YAAA,OAAO,GAAG,EAAE,CAAA,UAAA,EAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAa,UAAA,EAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAK,EAAA,EAAA,IAAI,IAAI,CAAA;SAClF;AAED,QAAA,OAAO,GAAG,EAAE,CAAA,UAAA,EAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,UAAA,EAAa,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAA;AAC1E,KAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACf,CAAC;AAED,MAAM,CAAC,GAAG,CAAC,CAAQ,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;;AC5M1C,MAAO,SAAU,SAAQ,MAAM,CAAA;IAGnC,WAAY,CAAA,OAAe,EAAE,SAAA,GAAoB,EAAE,EAAA;QACjD,KAAK,CAAC,OAAO,CAAC,CAAC;AACf,QAAA,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;KAC5B;IAED,QAAQ,GAAA;AACN,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;KACvB;AAED,IAAA,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAY,EAAA;AAC/B,QAAA,IAAI,IAAI,KAAK,QAAQ,EAAE;AACrB,YAAA,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;SAC/B;AACD,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;KACvB;AACF;;MCHY,gBAAgB,CAAA;AAA7B,IAAA,WAAA,GAAA;AACE,QAAA,IAAA,CAAA,IAAI,GAAsC;AACxC,YAAA,OAAO,EAAE,EAAE;AACX,YAAA,QAAQ,EAAE,EAAE;AACZ,YAAA,IAAI,EAAE,EAAE;AACR,YAAA,IAAI,EAAE,EAAE;AACR,YAAA,IAAI,EAAE,EAAE;SACT,CAAA;QACD,IAAM,CAAA,MAAA,GAAwC,EAAE,CAAA;KAEjD;IADC,MAAM,IAAI,GAAA,GAAK;AAChB,CAAA;AAED,IAAI,gBAAgB,GAAG,gBAAgB,CAAA;SAEvB,mBAAmB,GAAA;AACjC,IAAA,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAEK,SAAU,mBAAmB,CAAC,WAAgD,EAAA;IAClF,gBAAgB,GAAG,WAAW,CAAA;AAChC;;ACjBA,MAAM,YAAY,GAAG,qBAAqB,CAAC;AAapC,MAAM,KAAK,GAAG,kBAAkB;AAChC,MAAM,IAAI,GAAG,kBAAkB;AAC/B,MAAM,IAAI,GAAG,kBAAkB;AAqB/B,MAAM,EAAE,GAAG,OAAO,IAAY,EAAE,KAAU,EAAE,IAAY,EAAE,IAAU,KAAkB;AAC3F,IAAA,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;;AAG1D,IAAA,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;AACtB,IAAA,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;;AAGtB,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AACvB,QAAA,IAAI,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,CAAA;KAC3B;AACI,SAAA,IAAI,IAAI,EAAE,cAAc,CAAC,SAAS,CAAC,EAAE;AACxC,QAAA,IAAI,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;KACnD;AAED,IAAA,IAAI;QACF,oBAAoB,CAAC,KAAK,CAAC,CAAC;AAC5B,QAAA,MAAM,mBAAmB,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC3F,mBAAmB,CAAC,KAAK,CAAC,CAAC;KAC5B;IACD,OAAM,CAAK,EAAE;AACX,QAAA,CAAC,CAAC,OAAO,GAAG,CAAA,EAAG,IAAI,CAAA,GAAA,EAAM,IAAI,CAAA,GAAA,EAAM,CAAC,CAAC,OAAO,CAAA,CAAE,CAAA;AAC9C,QAAA,MAAM,CAAC,CAAA;KACR;AACH,EAAE;AAMF,MAAM,aAAa,GAAsB;AAEvC;;;;AAIG;AACH,IAAA,MAAM,EAAE;QACN,8CAA8C;QAC9C,8CAA8C;AAC/C,KAAA;CAEF,CAAA;AAQY,MAAA,WAAW,GAAG,YAAA;AACzB,IAAA,IAAI,MAAyB,CAAC;IAE9B,OAAO;AACL,QAAA,IAAI,EAAE,uBAAuB;AAC7B,QAAA,cAAc,EAAE,CAAC,cAA8B,KAAI;AACjD,YAAA,MAAM,GAAG,QAAQ,CACf,aAAa,EACb,GAAG,CAAC,cAAc,EAAE,eAAe,CAAC,CAChB,CAAC;SACxB;AACD,QAAA,SAAS,EAAE,OAAO,GAAW,EAAE,EAAU,KAAiC;AACxE,YAAA,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;gBACzB,OAAO,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,CAAA;aACpE;SACF;KACF,CAAC;AACJ;;;;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Messages from '@cucumber/messages';
|
|
2
|
+
export declare class DataTable {
|
|
3
|
+
private readonly rawTable;
|
|
4
|
+
constructor(sourceTable: Messages.PickleTable | string[][]);
|
|
5
|
+
hashes(): Record<string, string>[];
|
|
6
|
+
raw(): string[][];
|
|
7
|
+
rows(): string[][];
|
|
8
|
+
rowsHash(): Record<string, string>;
|
|
9
|
+
transpose(): DataTable;
|
|
10
|
+
}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Feature } from "@cucumber/messages";
|
|
2
|
+
import type { QuickPickleConfig } from '.';
|
|
3
|
+
export declare function renderGherkin(src: string, config: QuickPickleConfig, isMarkdown?: boolean): string;
|
|
4
|
+
export declare function renderFeature(feature: Feature, config: QuickPickleConfig): string;
|
package/dist/steps.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Expression } from '@cucumber/cucumber-expressions';
|
|
2
|
+
interface StepDefinition {
|
|
3
|
+
expression: string;
|
|
4
|
+
f: (state: any, ...args: any[]) => any;
|
|
5
|
+
cucumberExpression: Expression;
|
|
6
|
+
}
|
|
7
|
+
interface StepDefinitionMatch {
|
|
8
|
+
stepDefinition: StepDefinition;
|
|
9
|
+
parameters: any[];
|
|
10
|
+
}
|
|
11
|
+
export declare const addStepDefinition: (expression: string, f: (state: any, ...args: any[]) => any) => void;
|
|
12
|
+
export declare const findStepDefinitionMatch: (step: string) => StepDefinitionMatch;
|
|
13
|
+
export {};
|
package/dist/tags.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const tagsFunction: (tagsExpression?: string) => (tags: string[]) => boolean;
|
package/dist/world.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface QuickPickleWorldInterface {
|
|
2
|
+
info: {
|
|
3
|
+
feature: string;
|
|
4
|
+
scenario: string;
|
|
5
|
+
tags: string[];
|
|
6
|
+
rule?: string;
|
|
7
|
+
step?: string;
|
|
8
|
+
line?: number;
|
|
9
|
+
};
|
|
10
|
+
common: {
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
};
|
|
13
|
+
init: () => Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export declare class QuickPickleWorld implements QuickPickleWorldInterface {
|
|
16
|
+
info: QuickPickleWorldInterface['info'];
|
|
17
|
+
common: QuickPickleWorldInterface['common'];
|
|
18
|
+
init(): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export declare function getWorldConstructor(): typeof QuickPickleWorld;
|
|
21
|
+
export declare function setWorldConstructor(constructor: new () => QuickPickleWorldInterface): void;
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "quickpickle",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Plugin for Vitest to run tests written in Gherkin Syntax.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"BDD",
|
|
7
|
+
"testing",
|
|
8
|
+
"behavioral",
|
|
9
|
+
"cucumber",
|
|
10
|
+
"gherkin",
|
|
11
|
+
"vitest",
|
|
12
|
+
"playwright",
|
|
13
|
+
"react",
|
|
14
|
+
"svelte",
|
|
15
|
+
"vue",
|
|
16
|
+
"angular"
|
|
17
|
+
],
|
|
18
|
+
"homepage": "https://github.com/dnotes/quickpickle#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/dnotes/quickpickle/issues"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"main": "./dist/index.cjs",
|
|
24
|
+
"module": "./dist/index.esm.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"require": "./dist/index.cjs",
|
|
30
|
+
"import": "./dist/index.esm.js",
|
|
31
|
+
"types": "./dist/index.d.ts"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "rollup -c",
|
|
39
|
+
"type-check": "tsc --noEmit",
|
|
40
|
+
"test:watch": "vitest",
|
|
41
|
+
"test": "vitest --run"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@cucumber/cucumber": "^11.0.1",
|
|
45
|
+
"@cucumber/cucumber-expressions": "^16.1.2",
|
|
46
|
+
"@cucumber/gherkin": "^29.0.0",
|
|
47
|
+
"@cucumber/messages": "^22.0.0",
|
|
48
|
+
"@cucumber/tag-expressions": "^6.1.0",
|
|
49
|
+
"fast-glob": "^3.3.2",
|
|
50
|
+
"lodash-es": "^4.17.21"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@rollup/plugin-replace": "^6.0.1",
|
|
54
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
55
|
+
"@rollup/plugin-typescript": "^12.1.0",
|
|
56
|
+
"@types/lodash": "^4.14.194",
|
|
57
|
+
"@types/lodash-es": "^4.17.12",
|
|
58
|
+
"@types/node": "^18.16.3",
|
|
59
|
+
"rollup": "^3.20.7",
|
|
60
|
+
"typescript": "^5.6.2",
|
|
61
|
+
"vitest": "^2.1.2"
|
|
62
|
+
},
|
|
63
|
+
"repository": {
|
|
64
|
+
"type": "git",
|
|
65
|
+
"url": "https://github.com/dnotes/quickpickle.git"
|
|
66
|
+
}
|
|
67
|
+
}
|