@zohodesk/testinglibrary 0.1.7 → 0.1.8-exp-bdd
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/.babelrc +18 -18
- package/.eslintrc.js +27 -31
- package/.prettierrc +5 -5
- package/README.md +17 -17
- package/bin/cli.js +2 -2
- package/build/bdd-framework/cli/commands/env.js +4 -4
- package/build/bdd-framework/cli/commands/test.js +2 -6
- package/build/bdd-framework/cli/options.js +4 -4
- package/build/bdd-framework/cli/worker.js +3 -3
- package/build/bdd-framework/config/dir.js +6 -6
- package/build/bdd-framework/config/env.js +4 -5
- package/build/bdd-framework/config/index.js +2 -2
- package/build/bdd-framework/cucumber/buildStepDefinition.js +3 -3
- package/build/bdd-framework/cucumber/gherkin.d.ts +45 -0
- package/build/bdd-framework/cucumber/loadSnippetBuilder.js +3 -3
- package/build/bdd-framework/cucumber/loadSources.js +9 -9
- package/build/bdd-framework/cucumber/loadSteps.js +3 -8
- package/build/bdd-framework/decorators.js +2 -2
- package/build/bdd-framework/gen/formatter.js +17 -64
- package/build/bdd-framework/gen/i18n.js +5 -9
- package/build/bdd-framework/gen/index.js +8 -9
- package/build/bdd-framework/gen/poms.js +46 -0
- package/build/bdd-framework/gen/testFile.js +55 -121
- package/build/bdd-framework/gen/testNode.js +6 -19
- package/build/bdd-framework/gen/testPoms.js +39 -49
- package/build/bdd-framework/playwright/fixtureParameterNames.js +11 -27
- package/build/bdd-framework/playwright/getLocationInFile.js +11 -17
- package/build/bdd-framework/playwright/loadConfig.js +3 -3
- package/build/bdd-framework/playwright/testTypeImpl.js +15 -19
- package/build/bdd-framework/playwright/transform.js +6 -10
- package/build/bdd-framework/playwright/utils.js +6 -3
- package/build/bdd-framework/run/bddFixtures.js +55 -118
- package/build/bdd-framework/run/bddWorld.js +36 -24
- package/build/bdd-framework/snippets/index.js +3 -5
- package/build/bdd-framework/snippets/snippetSyntax.js +1 -3
- package/build/bdd-framework/snippets/snippetSyntaxTs.js +4 -4
- package/build/bdd-framework/stepDefinitions/createBdd.js +13 -30
- package/build/bdd-framework/stepDefinitions/createDecorators.js +108 -0
- package/build/bdd-framework/stepDefinitions/decorators/{class.js → poms.js} +9 -13
- package/build/bdd-framework/stepDefinitions/decorators/steps.js +8 -14
- package/build/bdd-framework/stepDefinitions/defineStep.js +4 -5
- package/build/bdd-framework/stepDefinitions/stepConfig.js +5 -5
- package/build/bdd-framework/utils/exit.js +18 -26
- package/build/bdd-framework/utils/index.js +4 -30
- package/build/bdd-framework/utils/jsStringWrap.js +9 -9
- package/build/bdd-framework/utils/logger.js +3 -5
- package/build/bdd-poc/core-runner/exportMethods.js +14 -0
- package/build/bdd-poc/core-runner/stepDefinitions.js +55 -0
- package/build/bdd-poc/main.js +10 -0
- package/build/bdd-poc/test/cucumber/featureFileParer.js +81 -0
- package/build/bdd-poc/test/stepGenerate/stepFileGenerate.js +36 -0
- package/build/bdd-poc/test/stepGenerate/stepsnippets.js +43 -0
- package/build/bdd-poc/test/testDataMap.js +98 -0
- package/build/bdd-poc/test/testStructure.js +83 -0
- package/build/bdd-poc/utils/stringManipulation.js +19 -0
- package/build/core/playwright/custom-commands.js +1 -1
- package/build/core/playwright/index.js +0 -15
- package/build/core/playwright/readConfigFile.js +30 -37
- package/build/core/playwright/report-generator.js +1 -2
- package/build/core/playwright/setup/config-creator.js +15 -21
- package/build/core/playwright/setup/config-utils.js +0 -30
- package/build/core/playwright/test-runner.js +5 -7
- package/build/index.d.ts +5 -60
- package/build/index.js +3 -5
- package/build/lib/cli.js +1 -10
- package/build/parser/sample.feature +34 -34
- package/build/parser/sample.spec.js +18 -18
- package/build/setup-folder-structure/samples/auth-setup-sample.js +72 -72
- package/build/setup-folder-structure/samples/authUsers-sample.json +8 -8
- package/build/setup-folder-structure/samples/env-config-sample.json +20 -20
- package/build/setup-folder-structure/samples/git-ignore.sample.js +32 -36
- package/build/setup-folder-structure/samples/uat-config-sample.js +43 -44
- package/build/setup-folder-structure/setupProject.js +5 -10
- package/build/utils/cliArgsToObject.js +25 -25
- package/build/utils/fileUtils.js +0 -12
- package/changelog.md +74 -124
- package/jest.config.js +63 -63
- package/npm-shrinkwrap.json +7781 -6469
- package/package.json +54 -55
- package/playwright.config.js +112 -112
- package/build/bdd-framework/config/lang.js +0 -14
- package/build/bdd-framework/gen/fixtures.js +0 -48
- package/build/bdd-framework/hooks/scenario.js +0 -107
- package/build/bdd-framework/hooks/worker.js +0 -83
- package/build/bdd-framework/run/StepInvoker.js +0 -73
- package/build/core/playwright/clear-caches.js +0 -29
- package/build/core/playwright/setup/custom-reporter.js +0 -100
- package/build/core/playwright/tag-processor.js +0 -68
- package/build/setup-folder-structure/helper.js +0 -34
- package/build/setup-folder-structure/reportEnhancement/addonScript.html +0 -25
- package/build/setup-folder-structure/reportEnhancement/reportAlteration.js +0 -25
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.POMS = void 0;
|
|
7
|
+
exports.buildFixtureTag = buildFixtureTag;
|
|
8
|
+
var _createDecorators = require("../stepDefinitions/createDecorators");
|
|
9
|
+
/**
|
|
10
|
+
* Handle POMs graph for decorator steps.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const FIXTURE_TAG_PREFIX = '@fixture:';
|
|
14
|
+
class POMS {
|
|
15
|
+
usedPoms = new Map();
|
|
16
|
+
add(pomNode) {
|
|
17
|
+
if (pomNode) this.usedPoms.set(pomNode, null);
|
|
18
|
+
}
|
|
19
|
+
addByFixtureName(fixtureName) {
|
|
20
|
+
const pomNode = (0, _createDecorators.getPomNodeByFixtureName)(fixtureName);
|
|
21
|
+
if (pomNode) this.add(pomNode);
|
|
22
|
+
}
|
|
23
|
+
addByTag(tag) {
|
|
24
|
+
const fixtureName = extractFixtureName(tag);
|
|
25
|
+
if (fixtureName) this.addByFixtureName(fixtureName);
|
|
26
|
+
}
|
|
27
|
+
resolveFixtureNames(pomNode) {
|
|
28
|
+
const resolvedFixtureNames = this.usedPoms.get(pomNode);
|
|
29
|
+
if (resolvedFixtureNames) return resolvedFixtureNames;
|
|
30
|
+
const fixtureNames = [...pomNode.children].map(child => this.resolveFixtureNames(child)).flat();
|
|
31
|
+
if (this.usedPoms.has(pomNode)) {
|
|
32
|
+
// if nothing returned from children, use own fixtureName,
|
|
33
|
+
// otherwise use what returned from child
|
|
34
|
+
if (!fixtureNames.length) fixtureNames.push(pomNode.fixtureName);
|
|
35
|
+
this.usedPoms.set(pomNode, fixtureNames);
|
|
36
|
+
}
|
|
37
|
+
return fixtureNames;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.POMS = POMS;
|
|
41
|
+
function extractFixtureName(tag) {
|
|
42
|
+
return tag.startsWith(FIXTURE_TAG_PREFIX) ? tag.replace(FIXTURE_TAG_PREFIX, '') : '';
|
|
43
|
+
}
|
|
44
|
+
function buildFixtureTag(fixtureName) {
|
|
45
|
+
return `${FIXTURE_TAG_PREFIX}${fixtureName}`;
|
|
46
|
+
}
|
|
@@ -10,18 +10,15 @@ var _path = _interopRequireDefault(require("path"));
|
|
|
10
10
|
var _formatter = require("./formatter");
|
|
11
11
|
var _i18n = require("./i18n");
|
|
12
12
|
var _loadSteps = require("../cucumber/loadSteps");
|
|
13
|
+
var _createBdd = require("../stepDefinitions/createBdd");
|
|
13
14
|
var _index = require("@cucumber/cucumber/lib/formatter/helpers/index");
|
|
14
15
|
var _utils = require("../utils");
|
|
15
16
|
var _testPoms = require("./testPoms");
|
|
16
17
|
var _testNode = require("./testNode");
|
|
17
18
|
var _stepConfig = require("../stepDefinitions/stepConfig");
|
|
18
19
|
var _exit = require("../utils/exit");
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
var _worker = require("../hooks/worker");
|
|
22
|
-
var _lang = require("../config/lang");
|
|
23
|
-
/**
|
|
24
|
-
* Generate test code.
|
|
20
|
+
/**
|
|
21
|
+
* Generate test code.
|
|
25
22
|
*/
|
|
26
23
|
|
|
27
24
|
class TestFile {
|
|
@@ -29,7 +26,6 @@ class TestFile {
|
|
|
29
26
|
lines = [];
|
|
30
27
|
i18nKeywordsMap;
|
|
31
28
|
formatter;
|
|
32
|
-
hasCucumberStyle = false;
|
|
33
29
|
testNodes = [];
|
|
34
30
|
hasCustomTest = false;
|
|
35
31
|
undefinedSteps = [];
|
|
@@ -41,9 +37,7 @@ class TestFile {
|
|
|
41
37
|
const {
|
|
42
38
|
uri
|
|
43
39
|
} = this.options.doc;
|
|
44
|
-
if (!uri)
|
|
45
|
-
throw new Error(`Document without uri`);
|
|
46
|
-
}
|
|
40
|
+
if (!uri) throw new Error(`Document without uri`);
|
|
47
41
|
return uri;
|
|
48
42
|
}
|
|
49
43
|
get content() {
|
|
@@ -51,10 +45,7 @@ class TestFile {
|
|
|
51
45
|
}
|
|
52
46
|
get language() {
|
|
53
47
|
var _this$options$doc$fea;
|
|
54
|
-
return ((_this$options$doc$fea = this.options.doc.feature) === null || _this$options$doc$fea === void 0 ? void 0 : _this$options$doc$fea.language) ||
|
|
55
|
-
}
|
|
56
|
-
get isEnglish() {
|
|
57
|
-
return (0, _lang.isEnglish)(this.language);
|
|
48
|
+
return ((_this$options$doc$fea = this.options.doc.feature) === null || _this$options$doc$fea === void 0 ? void 0 : _this$options$doc$fea.language) || 'en';
|
|
58
49
|
}
|
|
59
50
|
get config() {
|
|
60
51
|
return this.options.config;
|
|
@@ -64,18 +55,14 @@ class TestFile {
|
|
|
64
55
|
}
|
|
65
56
|
build() {
|
|
66
57
|
this.loadI18nKeywords();
|
|
67
|
-
this.lines = [...this.getFileHeader(),
|
|
68
|
-
// prettier-ignore
|
|
69
|
-
...this.getRootSuite(), ...this.getFileFixtures()];
|
|
58
|
+
this.lines = [...this.getFileHeader(), ...this.getRootSuite(), ...this.getFileFixtures()];
|
|
70
59
|
return this;
|
|
71
60
|
}
|
|
72
61
|
save() {
|
|
73
62
|
const dir = _path.default.dirname(this.outputPath);
|
|
74
|
-
if (!_fs.default.existsSync(dir)) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
});
|
|
78
|
-
}
|
|
63
|
+
if (!_fs.default.existsSync(dir)) _fs.default.mkdirSync(dir, {
|
|
64
|
+
recursive: true
|
|
65
|
+
});
|
|
79
66
|
_fs.default.writeFileSync(this.outputPath, this.content);
|
|
80
67
|
}
|
|
81
68
|
getFileHeader() {
|
|
@@ -83,7 +70,7 @@ class TestFile {
|
|
|
83
70
|
return this.formatter.fileHeader(this.sourceFile, importTestFrom);
|
|
84
71
|
}
|
|
85
72
|
loadI18nKeywords() {
|
|
86
|
-
if (
|
|
73
|
+
if (this.language !== 'en') {
|
|
87
74
|
this.i18nKeywordsMap = (0, _i18n.getKeywordsMap)(this.language);
|
|
88
75
|
}
|
|
89
76
|
}
|
|
@@ -91,9 +78,7 @@ class TestFile {
|
|
|
91
78
|
const {
|
|
92
79
|
importTestFrom
|
|
93
80
|
} = this.config;
|
|
94
|
-
if (!importTestFrom)
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
81
|
+
if (!importTestFrom) return;
|
|
97
82
|
const {
|
|
98
83
|
file,
|
|
99
84
|
varName
|
|
@@ -105,46 +90,37 @@ class TestFile {
|
|
|
105
90
|
};
|
|
106
91
|
}
|
|
107
92
|
getFileFixtures() {
|
|
108
|
-
return this.formatter.useFixtures([...this.formatter.testFixture(), ...
|
|
93
|
+
return this.formatter.useFixtures([...this.formatter.testFixture(), ...this.formatter.tagsFixture(this.testNodes)]);
|
|
109
94
|
}
|
|
110
95
|
getRootSuite() {
|
|
111
96
|
const {
|
|
112
97
|
feature
|
|
113
98
|
} = this.options.doc;
|
|
114
|
-
if (!feature)
|
|
115
|
-
throw new Error(`Document without feature.`);
|
|
116
|
-
}
|
|
99
|
+
if (!feature) throw new Error(`Document without feature.`);
|
|
117
100
|
return this.getSuite(feature);
|
|
118
101
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Generate test.describe suite for root Feature or Rule
|
|
102
|
+
/**
|
|
103
|
+
* Generate test.describe suite for root Feature or Rule
|
|
121
104
|
*/
|
|
122
105
|
getSuite(feature, parent) {
|
|
123
106
|
const node = new _testNode.TestNode(feature, parent);
|
|
124
|
-
if (node.isSkipped()) {
|
|
125
|
-
return this.formatter.suite(node, []);
|
|
126
|
-
}
|
|
127
107
|
const lines = [];
|
|
108
|
+
// const { backgrounds, rules, scenarios } =
|
|
109
|
+
// bgFixtures, bgTags - used as fixture hints for decorator steps
|
|
128
110
|
feature.children.forEach(child => lines.push(...this.getSuiteChild(child, node)));
|
|
129
111
|
return this.formatter.suite(node, lines);
|
|
130
112
|
}
|
|
131
113
|
getSuiteChild(child, parent) {
|
|
132
|
-
if ('rule' in child && child.rule)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (child.background) {
|
|
136
|
-
return this.getBeforeEach(child.background, parent);
|
|
137
|
-
}
|
|
138
|
-
if (child.scenario) {
|
|
139
|
-
return this.getScenarioLines(child.scenario, parent);
|
|
140
|
-
}
|
|
114
|
+
if ('rule' in child && child.rule) return this.getSuite(child.rule, parent);
|
|
115
|
+
if (child.background) return this.getBeforeEach(child.background, parent);
|
|
116
|
+
if (child.scenario) return this.getScenarioLines(child.scenario, parent);
|
|
141
117
|
throw new Error(`Empty child: ${JSON.stringify(child)}`);
|
|
142
118
|
}
|
|
143
119
|
getScenarioLines(scenario, parent) {
|
|
144
120
|
return this.isOutline(scenario) ? this.getOutlineSuite(scenario, parent) : this.getTest(scenario, parent);
|
|
145
121
|
}
|
|
146
|
-
/**
|
|
147
|
-
* Generate test.beforeEach for Background
|
|
122
|
+
/**
|
|
123
|
+
* Generate test.beforeEach for Background
|
|
148
124
|
*/
|
|
149
125
|
getBeforeEach(bg, parent) {
|
|
150
126
|
const node = new _testNode.TestNode({
|
|
@@ -157,18 +133,15 @@ class TestFile {
|
|
|
157
133
|
} = this.getSteps(bg, node.tags);
|
|
158
134
|
return this.formatter.beforeEach(fixtures, lines);
|
|
159
135
|
}
|
|
160
|
-
/**
|
|
161
|
-
* Generate test.describe suite for Scenario Outline
|
|
136
|
+
/**
|
|
137
|
+
* Generate test.describe suite for Scenario Outline
|
|
162
138
|
*/
|
|
163
139
|
getOutlineSuite(scenario, parent) {
|
|
164
140
|
const node = new _testNode.TestNode(scenario, parent);
|
|
165
|
-
if (node.isSkipped()) {
|
|
166
|
-
return this.formatter.suite(node, []);
|
|
167
|
-
}
|
|
168
141
|
const lines = [];
|
|
169
142
|
let exampleIndex = 0;
|
|
170
143
|
scenario.examples.forEach(examples => {
|
|
171
|
-
const titleFormat = this.getExamplesTitleFormat(
|
|
144
|
+
const titleFormat = this.getExamplesTitleFormat(examples);
|
|
172
145
|
examples.tableBody.forEach(exampleRow => {
|
|
173
146
|
const testTitle = this.getOutlineTestTitle(titleFormat, examples, exampleRow, ++exampleIndex);
|
|
174
147
|
const testLines = this.getOutlineTest(scenario, examples, exampleRow, testTitle, node);
|
|
@@ -177,8 +150,8 @@ class TestFile {
|
|
|
177
150
|
});
|
|
178
151
|
return this.formatter.suite(node, lines);
|
|
179
152
|
}
|
|
180
|
-
/**
|
|
181
|
-
* Generate test from Examples row of Scenario Outline
|
|
153
|
+
/**
|
|
154
|
+
* Generate test from Examples row of Scenario Outline
|
|
182
155
|
*/
|
|
183
156
|
// eslint-disable-next-line max-params
|
|
184
157
|
getOutlineTest(scenario, examples, exampleRow, title, parent) {
|
|
@@ -186,12 +159,7 @@ class TestFile {
|
|
|
186
159
|
name: title,
|
|
187
160
|
tags: examples.tags
|
|
188
161
|
}, parent);
|
|
189
|
-
if (this.skipByTagsExpression(node))
|
|
190
|
-
return [];
|
|
191
|
-
}
|
|
192
|
-
if (node.isSkipped()) {
|
|
193
|
-
return this.formatter.test(node, new Set(), []);
|
|
194
|
-
}
|
|
162
|
+
if (this.skipByTagsExpression(node)) return [];
|
|
195
163
|
this.testNodes.push(node);
|
|
196
164
|
const {
|
|
197
165
|
fixtures,
|
|
@@ -199,17 +167,12 @@ class TestFile {
|
|
|
199
167
|
} = this.getSteps(scenario, node.tags, exampleRow.id);
|
|
200
168
|
return this.formatter.test(node, fixtures, lines);
|
|
201
169
|
}
|
|
202
|
-
/**
|
|
203
|
-
* Generate test from Scenario
|
|
170
|
+
/**
|
|
171
|
+
* Generate test from Scenario
|
|
204
172
|
*/
|
|
205
173
|
getTest(scenario, parent) {
|
|
206
174
|
const node = new _testNode.TestNode(scenario, parent);
|
|
207
|
-
if (this.skipByTagsExpression(node))
|
|
208
|
-
return [];
|
|
209
|
-
}
|
|
210
|
-
if (node.isSkipped()) {
|
|
211
|
-
return this.formatter.test(node, new Set(), []);
|
|
212
|
-
}
|
|
175
|
+
if (this.skipByTagsExpression(node)) return [];
|
|
213
176
|
this.testNodes.push(node);
|
|
214
177
|
const {
|
|
215
178
|
fixtures,
|
|
@@ -217,8 +180,8 @@ class TestFile {
|
|
|
217
180
|
} = this.getSteps(scenario, node.tags);
|
|
218
181
|
return this.formatter.test(node, fixtures, lines);
|
|
219
182
|
}
|
|
220
|
-
/**
|
|
221
|
-
* Generate test steps
|
|
183
|
+
/**
|
|
184
|
+
* Generate test steps
|
|
222
185
|
*/
|
|
223
186
|
getSteps(scenario, tags, outlineExampleRowId) {
|
|
224
187
|
const testFixtureNames = new Set();
|
|
@@ -267,8 +230,8 @@ class TestFile {
|
|
|
267
230
|
lines
|
|
268
231
|
};
|
|
269
232
|
}
|
|
270
|
-
/**
|
|
271
|
-
* Generate step for Given, When, Then
|
|
233
|
+
/**
|
|
234
|
+
* Generate step for Given, When, Then
|
|
272
235
|
*/
|
|
273
236
|
// eslint-disable-next-line max-statements, complexity
|
|
274
237
|
getStep(step, previousKeywordType, outlineExampleRowId) {
|
|
@@ -279,27 +242,26 @@ class TestFile {
|
|
|
279
242
|
language: this.language,
|
|
280
243
|
previousKeywordType
|
|
281
244
|
});
|
|
282
|
-
|
|
245
|
+
let keyword = this.getStepKeyword(step);
|
|
283
246
|
if (!stepDefinition) {
|
|
284
247
|
this.undefinedSteps.push({
|
|
285
248
|
keywordType,
|
|
286
249
|
step,
|
|
287
250
|
pickleStep
|
|
288
251
|
});
|
|
289
|
-
return this.getMissingStep(
|
|
252
|
+
return this.getMissingStep(keyword, keywordType, pickleStep);
|
|
290
253
|
}
|
|
291
254
|
// for cucumber-style stepConfig is undefined
|
|
292
255
|
const stepConfig = (0, _stepConfig.getStepConfig)(stepDefinition);
|
|
293
|
-
if (stepConfig !== null && stepConfig !== void 0 && stepConfig.hasCustomTest)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (!(0, _stepConfig.isPlaywrightStyle)(stepConfig)) {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
const line = (0, _stepConfig.isDecorator)(stepConfig) ? '' : this.formatter.step(enKeyword, pickleStep.text, pickleStep.argument, fixtureNames);
|
|
256
|
+
if (stepConfig !== null && stepConfig !== void 0 && stepConfig.hasCustomTest) this.hasCustomTest = true;
|
|
257
|
+
// for cucumber-style transform Given/When/Then -> Given_/When_/Then_
|
|
258
|
+
// to use own bddWorld (containing PW built-in fixtures)
|
|
259
|
+
if (!(0, _stepConfig.isPlaywrightStyle)(stepConfig)) keyword = `${keyword}_`;
|
|
260
|
+
// for decorator steps fixtureNames are defined later in second pass
|
|
261
|
+
const fixtureNames = (0, _stepConfig.isDecorator)(stepConfig) ? [] : (0, _createBdd.extractFixtureNames)(stepConfig === null || stepConfig === void 0 ? void 0 : stepConfig.fn);
|
|
262
|
+
const line = (0, _stepConfig.isDecorator)(stepConfig) ? '' : this.formatter.step(keyword, pickleStep.text, pickleStep.argument, fixtureNames);
|
|
301
263
|
return {
|
|
302
|
-
keyword
|
|
264
|
+
keyword,
|
|
303
265
|
keywordType,
|
|
304
266
|
fixtureNames,
|
|
305
267
|
line,
|
|
@@ -326,29 +288,16 @@ class TestFile {
|
|
|
326
288
|
const hasRowId = !outlineExampleRowId || astNodeIds.includes(outlineExampleRowId);
|
|
327
289
|
return hasStepId && hasRowId;
|
|
328
290
|
});
|
|
329
|
-
if (pickleStep)
|
|
330
|
-
return pickleStep;
|
|
331
|
-
}
|
|
291
|
+
if (pickleStep) return pickleStep;
|
|
332
292
|
}
|
|
333
293
|
throw new Error(`Pickle step not found for step: ${step.text}`);
|
|
334
294
|
}
|
|
335
|
-
|
|
336
|
-
const
|
|
337
|
-
const enKeyword =
|
|
338
|
-
if (!enKeyword) {
|
|
339
|
-
throw new Error(`Keyword not found: ${nativeKeyword}`);
|
|
340
|
-
}
|
|
295
|
+
getStepKeyword(step) {
|
|
296
|
+
const origKeyword = step.keyword.trim();
|
|
297
|
+
const enKeyword = origKeyword === '*' ? 'And' : this.getEnglishKeyword(origKeyword);
|
|
298
|
+
if (!enKeyword) throw new Error(`Keyword not found: ${origKeyword}`);
|
|
341
299
|
return enKeyword;
|
|
342
300
|
}
|
|
343
|
-
getStepFixtureNames(stepDefinition) {
|
|
344
|
-
const stepConfig = (0, _stepConfig.getStepConfig)(stepDefinition);
|
|
345
|
-
if ((0, _stepConfig.isPlaywrightStyle)(stepConfig)) {
|
|
346
|
-
// for decorator steps fixtureNames are defined later in second pass
|
|
347
|
-
return (0, _stepConfig.isDecorator)(stepConfig) ? [] : (0, _fixtures.extractFixtureNames)(stepConfig.fn);
|
|
348
|
-
} else {
|
|
349
|
-
return (0, _fixtures.extractFixtureNamesFromFnBodyMemo)(stepDefinition.code);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
301
|
getDecoratorStep(step, testPoms) {
|
|
353
302
|
const {
|
|
354
303
|
keyword,
|
|
@@ -374,16 +323,11 @@ class TestFile {
|
|
|
374
323
|
exampleRow.cells.forEach((cell, index) => {
|
|
375
324
|
var _examples$tableHeader;
|
|
376
325
|
const colName = (_examples$tableHeader = examples.tableHeader) === null || _examples$tableHeader === void 0 || (_examples$tableHeader = _examples$tableHeader.cells[index]) === null || _examples$tableHeader === void 0 ? void 0 : _examples$tableHeader.value;
|
|
377
|
-
if (colName)
|
|
378
|
-
params[colName] = cell.value;
|
|
379
|
-
}
|
|
326
|
+
if (colName) params[colName] = cell.value;
|
|
380
327
|
});
|
|
381
328
|
return (0, _utils.template)(titleFormat, params);
|
|
382
329
|
}
|
|
383
|
-
getExamplesTitleFormat(
|
|
384
|
-
return this.getExamplesTitleFormatFromComment(examples) || this.getExamplesTitleFormatFromScenarioName(scenario, examples) || this.config.examplesTitleFormat;
|
|
385
|
-
}
|
|
386
|
-
getExamplesTitleFormatFromComment(examples) {
|
|
330
|
+
getExamplesTitleFormat(examples) {
|
|
387
331
|
var _comment$text;
|
|
388
332
|
const {
|
|
389
333
|
line
|
|
@@ -394,22 +338,12 @@ class TestFile {
|
|
|
394
338
|
});
|
|
395
339
|
const commentText = comment === null || comment === void 0 || (_comment$text = comment.text) === null || _comment$text === void 0 ? void 0 : _comment$text.trim();
|
|
396
340
|
const prefix = '# title-format:';
|
|
397
|
-
return commentText !== null && commentText !== void 0 && commentText.startsWith(prefix) ? commentText.replace(prefix, '').trim() :
|
|
398
|
-
}
|
|
399
|
-
getExamplesTitleFormatFromScenarioName(scenario, examples) {
|
|
400
|
-
var _examples$tableHeader2;
|
|
401
|
-
const columnsInScenarioName = (0, _utils.extractTemplateParams)(scenario.name);
|
|
402
|
-
const hasColumnsFromExamples = columnsInScenarioName.length && ((_examples$tableHeader2 = examples.tableHeader) === null || _examples$tableHeader2 === void 0 || (_examples$tableHeader2 = _examples$tableHeader2.cells) === null || _examples$tableHeader2 === void 0 ? void 0 : _examples$tableHeader2.some(cell => {
|
|
403
|
-
return cell.value && columnsInScenarioName.includes(cell.value);
|
|
404
|
-
}));
|
|
405
|
-
return hasColumnsFromExamples ? scenario.name : '';
|
|
341
|
+
return commentText !== null && commentText !== void 0 && commentText.startsWith(prefix) ? commentText.replace(prefix, '').trim() : this.config.examplesTitleFormat;
|
|
406
342
|
}
|
|
407
343
|
skipByTagsExpression(node) {
|
|
344
|
+
var _this$options$tagsExp;
|
|
408
345
|
// see: https://github.com/cucumber/tag-expressions/tree/main/javascript
|
|
409
|
-
|
|
410
|
-
tagsExpression
|
|
411
|
-
} = this.options;
|
|
412
|
-
return tagsExpression && !tagsExpression.evaluate(node.tags);
|
|
346
|
+
return ((_this$options$tagsExp = this.options.tagsExpression) === null || _this$options$tagsExp === void 0 ? void 0 : _this$options$tagsExp.evaluate(node.tags)) === false;
|
|
413
347
|
}
|
|
414
348
|
isOutline(scenario) {
|
|
415
349
|
const keyword = this.getEnglishKeyword(scenario.keyword);
|
|
@@ -5,9 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.TestNode = void 0;
|
|
7
7
|
var _utils = require("../utils");
|
|
8
|
-
/**
|
|
9
|
-
* Universal TestNode class of parent-child relations in test file structure.
|
|
10
|
-
* Holds tags and titles path.
|
|
8
|
+
/**
|
|
9
|
+
* Universal TestNode class of parent-child relations in test file structure.
|
|
10
|
+
* Holds tags and titles path.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
const SPECIAL_TAGS = ['@only', '@skip', '@fixme'];
|
|
@@ -23,9 +23,6 @@ class TestNode {
|
|
|
23
23
|
this.title = gherkinNode.name;
|
|
24
24
|
this.titlePath = ((parent === null || parent === void 0 ? void 0 : parent.titlePath) || []).concat([this.title]);
|
|
25
25
|
}
|
|
26
|
-
isSkipped() {
|
|
27
|
-
return this.flags.skip || this.flags.fixme;
|
|
28
|
-
}
|
|
29
26
|
initOwnTags(gherkinNode) {
|
|
30
27
|
const tagNames = (0, _utils.removeDuplicates)(getTagNames(gherkinNode.tags));
|
|
31
28
|
tagNames.forEach(tag => {
|
|
@@ -36,20 +33,10 @@ class TestNode {
|
|
|
36
33
|
}
|
|
37
34
|
});
|
|
38
35
|
}
|
|
39
|
-
// eslint-disable-next-line complexity
|
|
40
36
|
setFlag(tag) {
|
|
41
|
-
|
|
42
|
-
if (tag === '@
|
|
43
|
-
|
|
44
|
-
only: true
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
if (tag === '@skip' && !this.flags.only) {
|
|
48
|
-
this.flags.skip = true;
|
|
49
|
-
}
|
|
50
|
-
if (tag === '@fixme' && !this.flags.only) {
|
|
51
|
-
this.flags.fixme = true;
|
|
52
|
-
}
|
|
37
|
+
if (tag === '@only') this.flags.only = true;
|
|
38
|
+
if (tag === '@skip') this.flags.skip = true;
|
|
39
|
+
if (tag === '@fixme') this.flags.fixme = true;
|
|
53
40
|
}
|
|
54
41
|
}
|
|
55
42
|
exports.TestNode = TestNode;
|
|
@@ -5,29 +5,29 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.TestPoms = void 0;
|
|
7
7
|
exports.buildFixtureTag = buildFixtureTag;
|
|
8
|
-
var
|
|
8
|
+
var _poms = require("../stepDefinitions/decorators/poms");
|
|
9
9
|
var _exit = require("../utils/exit");
|
|
10
|
-
/**
|
|
11
|
-
* Track PomNodes used in the particular test.
|
|
12
|
-
* To select correct fixture for decorator steps.
|
|
13
|
-
*
|
|
14
|
-
* Idea: try to use the deepest child fixture for parent steps.
|
|
15
|
-
*
|
|
16
|
-
* Example inheritance tree:
|
|
17
|
-
* A
|
|
18
|
-
* / \
|
|
19
|
-
* B C
|
|
20
|
-
* / \ \
|
|
21
|
-
* D E F
|
|
22
|
-
*
|
|
23
|
-
* If test uses steps from classes A and D:
|
|
24
|
-
* -> resolved fixture will be D, even for steps from A.
|
|
25
|
-
*
|
|
26
|
-
* If test uses steps from classes A, D and C:
|
|
27
|
-
* -> error, b/c A has 2 possible fixtures.
|
|
28
|
-
*
|
|
29
|
-
* If test uses steps from classes A and C, but @fixture tag is D:
|
|
30
|
-
* -> error, b/c A has 2 possible fixtures.
|
|
10
|
+
/**
|
|
11
|
+
* Track PomNodes used in the particular test.
|
|
12
|
+
* To select correct fixture for decorator steps.
|
|
13
|
+
*
|
|
14
|
+
* Idea: try to use the deepest child fixture for parent steps.
|
|
15
|
+
*
|
|
16
|
+
* Example inheritance tree:
|
|
17
|
+
* A
|
|
18
|
+
* / \
|
|
19
|
+
* B C
|
|
20
|
+
* / \ \
|
|
21
|
+
* D E F
|
|
22
|
+
*
|
|
23
|
+
* If test uses steps from classes A and D:
|
|
24
|
+
* -> resolved fixture will be D, even for steps from A.
|
|
25
|
+
*
|
|
26
|
+
* If test uses steps from classes A, D and C:
|
|
27
|
+
* -> error, b/c A has 2 possible fixtures.
|
|
28
|
+
*
|
|
29
|
+
* If test uses steps from classes A and C, but @fixture tag is D:
|
|
30
|
+
* -> error, b/c A has 2 possible fixtures.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
const FIXTURE_TAG_PREFIX = '@fixture:';
|
|
@@ -44,7 +44,7 @@ class TestPoms {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
addByFixtureName(fixtureName) {
|
|
47
|
-
const pomNode = (0,
|
|
47
|
+
const pomNode = (0, _poms.getPomNodeByFixtureName)(fixtureName);
|
|
48
48
|
this.addUsedPom(pomNode, {
|
|
49
49
|
byTag: false
|
|
50
50
|
});
|
|
@@ -52,35 +52,31 @@ class TestPoms {
|
|
|
52
52
|
addByTag(tag) {
|
|
53
53
|
const fixtureName = extractFixtureName(tag);
|
|
54
54
|
if (fixtureName) {
|
|
55
|
-
const pomNode = (0,
|
|
55
|
+
const pomNode = (0, _poms.getPomNodeByFixtureName)(fixtureName);
|
|
56
56
|
this.addUsedPom(pomNode, {
|
|
57
57
|
byTag: true
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Resolve all used pomNodes to fixtures.
|
|
63
|
-
* This is needed to handle @fixture: tagged pomNodes
|
|
64
|
-
* that does not have steps in the test, but should be considered.
|
|
61
|
+
/**
|
|
62
|
+
* Resolve all used pomNodes to fixtures.
|
|
63
|
+
* This is needed to handle @fixture: tagged pomNodes
|
|
64
|
+
* that does not have steps in the test, but should be considered.
|
|
65
65
|
*/
|
|
66
66
|
resolveFixtures() {
|
|
67
67
|
this.usedPoms.forEach((_, pomNode) => {
|
|
68
68
|
this.getResolvedFixtures(pomNode);
|
|
69
69
|
});
|
|
70
70
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Returns fixtures suitable for particular pomNode (actually for step)
|
|
71
|
+
/**
|
|
72
|
+
* Returns fixtures suitable for particular pomNode (actually for step)
|
|
73
73
|
*/
|
|
74
74
|
getResolvedFixtures(pomNode) {
|
|
75
75
|
const usedPom = this.usedPoms.get(pomNode);
|
|
76
|
-
if (usedPom !== null && usedPom !== void 0 && usedPom.fixtures)
|
|
77
|
-
return usedPom.fixtures;
|
|
78
|
-
}
|
|
76
|
+
if (usedPom !== null && usedPom !== void 0 && usedPom.fixtures) return usedPom.fixtures;
|
|
79
77
|
// Recursively resolve children fixtures, used in test.
|
|
80
78
|
let childFixtures = [...pomNode.children].map(child => this.getResolvedFixtures(child)).flat();
|
|
81
|
-
if (!usedPom)
|
|
82
|
-
return childFixtures;
|
|
83
|
-
}
|
|
79
|
+
if (!usedPom) return childFixtures;
|
|
84
80
|
if (childFixtures.length) {
|
|
85
81
|
this.verifyChildFixtures(pomNode, usedPom, childFixtures);
|
|
86
82
|
usedPom.fixtures = childFixtures;
|
|
@@ -95,29 +91,23 @@ class TestPoms {
|
|
|
95
91
|
addUsedPom(pomNode, {
|
|
96
92
|
byTag
|
|
97
93
|
}) {
|
|
98
|
-
if (!pomNode)
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
94
|
+
if (!pomNode) return;
|
|
101
95
|
const usedPom = this.usedPoms.get(pomNode);
|
|
102
96
|
if (usedPom) {
|
|
103
|
-
if (byTag && !usedPom.byTag)
|
|
104
|
-
usedPom.byTag = true;
|
|
105
|
-
}
|
|
97
|
+
if (byTag && !usedPom.byTag) usedPom.byTag = true;
|
|
106
98
|
} else {
|
|
107
99
|
this.usedPoms.set(pomNode, {
|
|
108
100
|
byTag
|
|
109
101
|
});
|
|
110
102
|
}
|
|
111
103
|
}
|
|
112
|
-
/**
|
|
113
|
-
* For scenarios with @fixture:xxx tags verify that there are no steps from fixtures,
|
|
114
|
-
* deeper than xxx.
|
|
115
|
-
* @fixture:xxx tag provides maximum fixture that can be used in the scenario.
|
|
104
|
+
/**
|
|
105
|
+
* For scenarios with @fixture:xxx tags verify that there are no steps from fixtures,
|
|
106
|
+
* deeper than xxx.
|
|
107
|
+
* @fixture:xxx tag provides maximum fixture that can be used in the scenario.
|
|
116
108
|
*/
|
|
117
109
|
verifyChildFixtures(pomNode, usedPom, childFixtures) {
|
|
118
|
-
if (!usedPom.byTag)
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
110
|
+
if (!usedPom.byTag) return;
|
|
121
111
|
const childFixturesBySteps = childFixtures.filter(f => !f.byTag);
|
|
122
112
|
if (childFixturesBySteps.length) {
|
|
123
113
|
(0, _exit.exit)(`Scenario "${this.title}" contains ${childFixturesBySteps.length} step(s)`, `not compatible with required fixture "${pomNode.fixtureName}"`);
|
|
@@ -4,31 +4,23 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.fixtureParameterNames = fixtureParameterNames;
|
|
7
|
-
/**
|
|
8
|
-
* Extracted from playwright.
|
|
9
|
-
* https://github.com/microsoft/playwright/blob/main/packages/playwright-test/src/common/fixtures.ts#L226
|
|
7
|
+
/**
|
|
8
|
+
* Extracted from playwright.
|
|
9
|
+
* https://github.com/microsoft/playwright/blob/main/packages/playwright-test/src/common/fixtures.ts#L226
|
|
10
10
|
*/
|
|
11
11
|
/* eslint-disable max-statements, complexity, max-len, max-depth */
|
|
12
12
|
const signatureSymbol = Symbol('signature');
|
|
13
13
|
function fixtureParameterNames(fn) {
|
|
14
|
-
if (typeof fn !== 'function')
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
if (!fn[signatureSymbol]) {
|
|
18
|
-
fn[signatureSymbol] = innerFixtureParameterNames(fn);
|
|
19
|
-
}
|
|
14
|
+
if (typeof fn !== 'function') return [];
|
|
15
|
+
if (!fn[signatureSymbol]) fn[signatureSymbol] = innerFixtureParameterNames(fn);
|
|
20
16
|
return fn[signatureSymbol];
|
|
21
17
|
}
|
|
22
18
|
function innerFixtureParameterNames(fn) {
|
|
23
19
|
const text = filterOutComments(fn.toString());
|
|
24
20
|
const match = text.match(/(?:async)?(?:\s+function)?[^(]*\(([^)]*)/);
|
|
25
|
-
if (!match)
|
|
26
|
-
return [];
|
|
27
|
-
}
|
|
21
|
+
if (!match) return [];
|
|
28
22
|
const trimmedParams = match[1].trim();
|
|
29
|
-
if (!trimmedParams)
|
|
30
|
-
return [];
|
|
31
|
-
}
|
|
23
|
+
if (!trimmedParams) return [];
|
|
32
24
|
const [firstParam] = splitByComma(trimmedParams);
|
|
33
25
|
if (firstParam[0] !== '{' || firstParam[firstParam.length - 1] !== '}') {
|
|
34
26
|
throw new Error('First argument must use the object destructuring pattern: ' + firstParam + ' ' + fn.toString());
|
|
@@ -48,13 +40,9 @@ function filterOutComments(s) {
|
|
|
48
40
|
let commentState = 'none';
|
|
49
41
|
for (let i = 0; i < s.length; ++i) {
|
|
50
42
|
if (commentState === 'singleline') {
|
|
51
|
-
if (s[i] === '\n')
|
|
52
|
-
commentState = 'none';
|
|
53
|
-
}
|
|
43
|
+
if (s[i] === '\n') commentState = 'none';
|
|
54
44
|
} else if (commentState === 'multiline') {
|
|
55
|
-
if (s[i - 1] === '*' && s[i] === '/')
|
|
56
|
-
commentState = 'none';
|
|
57
|
-
}
|
|
45
|
+
if (s[i - 1] === '*' && s[i] === '/') commentState = 'none';
|
|
58
46
|
} else if (commentState === 'none') {
|
|
59
47
|
if (s[i] === '/' && s[i + 1] === '/') {
|
|
60
48
|
commentState = 'singleline';
|
|
@@ -79,15 +67,11 @@ function splitByComma(s) {
|
|
|
79
67
|
stack.pop();
|
|
80
68
|
} else if (!stack.length && s[i] === ',') {
|
|
81
69
|
const token = s.substring(start, i).trim();
|
|
82
|
-
if (token)
|
|
83
|
-
result.push(token);
|
|
84
|
-
}
|
|
70
|
+
if (token) result.push(token);
|
|
85
71
|
start = i + 1;
|
|
86
72
|
}
|
|
87
73
|
}
|
|
88
74
|
const lastToken = s.substring(start).trim();
|
|
89
|
-
if (lastToken)
|
|
90
|
-
result.push(lastToken);
|
|
91
|
-
}
|
|
75
|
+
if (lastToken) result.push(lastToken);
|
|
92
76
|
return result;
|
|
93
77
|
}
|