@zohodesk/testinglibrary 0.1.9-exp-actors → 0.2.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/build/bdd-framework/cli/commands/env.js +1 -1
- package/build/bdd-framework/cli/commands/export.js +18 -3
- package/build/bdd-framework/decorators.js +2 -2
- package/build/bdd-framework/gen/formatter.js +57 -13
- package/build/bdd-framework/gen/index.js +21 -9
- package/build/bdd-framework/gen/specialTags.js +70 -0
- package/build/bdd-framework/gen/testFile.js +10 -5
- package/build/bdd-framework/gen/testNode.js +4 -29
- package/build/bdd-framework/gen/testPoms.js +1 -1
- package/build/bdd-framework/index.js +1 -1
- package/build/bdd-framework/playwright/testTypeImpl.js +28 -10
- package/build/bdd-framework/playwright/types.js +8 -1
- package/build/bdd-framework/playwright/utils.js +22 -0
- package/build/bdd-framework/reporter/cucumber/base.js +2 -7
- package/build/bdd-framework/reporter/cucumber/html.js +9 -4
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/AttachmentMapper.js +28 -10
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/Builder.js +21 -20
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/Hook.js +3 -3
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCaseRun.js +46 -18
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCaseRunHooks.js +41 -20
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestStepAttachments.js +19 -2
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestStepRun.js +42 -16
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/{pwUtils.js → pwStepUtils.js} +33 -14
- package/build/bdd-framework/run/StepInvoker.js +8 -7
- package/build/bdd-framework/run/bddData/index.js +59 -0
- package/build/bdd-framework/run/bddData/types.js +5 -0
- package/build/bdd-framework/run/bddFixtures.js +5 -4
- package/build/bdd-framework/run/bddWorld.js +3 -3
- package/build/bdd-framework/run/bddWorldInternal.js +1 -5
- package/build/bdd-framework/snippets/index.js +1 -1
- package/build/bdd-framework/steps/createBdd.js +78 -0
- package/build/bdd-framework/steps/decorators/class.js +68 -0
- package/build/bdd-framework/steps/decorators/steps.js +98 -0
- package/build/bdd-framework/steps/defineStep.js +62 -0
- package/build/bdd-framework/steps/stepConfig.js +24 -0
- package/build/core/playwright/env-initializer.js +17 -2
- package/build/core/playwright/helpers/configFileNameProvider.js +1 -0
- package/build/core/playwright/index.js +14 -71
- package/build/core/playwright/readConfigFile.js +13 -2
- package/build/index.d.ts +2 -21
- package/changelog.md +14 -0
- package/npm-shrinkwrap.json +1 -1
- package/package.json +3 -2
- package/build/bdd-framework/run/bddDataAttachment.js +0 -46
|
@@ -33,7 +33,7 @@ function showPackageVersion(packageName) {
|
|
|
33
33
|
* to aneble using directly from /dist in tests.
|
|
34
34
|
*/
|
|
35
35
|
function getOwnVersion() {
|
|
36
|
-
return '6.
|
|
36
|
+
return '6.1.1';
|
|
37
37
|
}
|
|
38
38
|
function showPlaywrightConfigPath(cliConfigPath) {
|
|
39
39
|
const resolvedConfigFile = (0, _loadConfig.resolveConfigFile)(cliConfigPath);
|
|
@@ -16,14 +16,18 @@ var _gen = require("../../gen");
|
|
|
16
16
|
const logger = new _logger.Logger({
|
|
17
17
|
verbose: true
|
|
18
18
|
});
|
|
19
|
-
const exportCommand = exports.exportCommand = new _commander.Command('export').description('Prints
|
|
19
|
+
const exportCommand = exports.exportCommand = new _commander.Command('export').description('Prints step definitions').addOption(_options.configOption).option('--unused-steps', 'Output only unused steps').action(async opts => {
|
|
20
20
|
const {
|
|
21
21
|
resolvedConfigFile
|
|
22
22
|
} = await (0, _loadConfig.loadConfig)(opts.config);
|
|
23
|
-
logger.log(`
|
|
23
|
+
logger.log(`Using config: ${_path.default.relative(process.cwd(), resolvedConfigFile)}`);
|
|
24
24
|
const configs = Object.values((0, _env.getEnvConfigs)());
|
|
25
25
|
(0, _test.assertConfigsCount)(configs);
|
|
26
|
-
|
|
26
|
+
if (opts.unusedSteps) {
|
|
27
|
+
await showUnusedStepsForConfigs(configs);
|
|
28
|
+
} else {
|
|
29
|
+
await showStepsForConfigs(configs);
|
|
30
|
+
}
|
|
27
31
|
});
|
|
28
32
|
async function showStepsForConfigs(configs) {
|
|
29
33
|
// here we don't need workers (as in test command) because if some step files
|
|
@@ -34,6 +38,17 @@ async function showStepsForConfigs(configs) {
|
|
|
34
38
|
stepDefinitions.forEach(s => steps.add(`* ${getStepText(s)}`));
|
|
35
39
|
});
|
|
36
40
|
await Promise.all(tasks);
|
|
41
|
+
logger.log(`List of all steps (${steps.size}):`);
|
|
42
|
+
steps.forEach(stepText => logger.log(stepText));
|
|
43
|
+
}
|
|
44
|
+
async function showUnusedStepsForConfigs(configs) {
|
|
45
|
+
const steps = new Set();
|
|
46
|
+
const tasks = configs.map(async config => {
|
|
47
|
+
const stepDefinitions = await new _gen.TestFilesGenerator(config).extractUnusedSteps();
|
|
48
|
+
stepDefinitions.forEach(s => steps.add(`* ${getStepText(s)}`));
|
|
49
|
+
});
|
|
50
|
+
await Promise.all(tasks);
|
|
51
|
+
logger.log(`List of unused steps (${steps.size}):`);
|
|
37
52
|
steps.forEach(stepText => logger.log(stepText));
|
|
38
53
|
}
|
|
39
54
|
function getStepText({
|
|
@@ -10,8 +10,8 @@ Object.defineProperty(exports, "Fixture", {
|
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
exports.When = exports.Then = exports.Step = exports.Given = void 0;
|
|
13
|
-
var _class = require("./
|
|
14
|
-
var _steps = require("./
|
|
13
|
+
var _class = require("./steps/decorators/class");
|
|
14
|
+
var _steps = require("./steps/decorators/steps");
|
|
15
15
|
const Given = exports.Given = (0, _steps.createStepDecorator)('Given');
|
|
16
16
|
const When = exports.When = (0, _steps.createStepDecorator)('When');
|
|
17
17
|
const Then = exports.Then = (0, _steps.createStepDecorator)('Then');
|
|
@@ -6,10 +6,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.Formatter = void 0;
|
|
7
7
|
var _jsStringWrap = require("../utils/jsStringWrap");
|
|
8
8
|
var _utils = require("../utils");
|
|
9
|
+
var _utils2 = require("../playwright/utils");
|
|
9
10
|
/**
|
|
10
11
|
* Helper to format Playwright test file.
|
|
11
12
|
*/
|
|
12
13
|
|
|
14
|
+
const supportsTags = _utils2.playwrightVersion >= '1.42.0';
|
|
13
15
|
class Formatter {
|
|
14
16
|
config;
|
|
15
17
|
constructor(config) {
|
|
@@ -27,12 +29,14 @@ class Formatter {
|
|
|
27
29
|
// this.quoted() is not possible for 'import from' as backticks not parsed
|
|
28
30
|
`import { ${varName} } from ${JSON.stringify(importTestFromFile)};`, ''];
|
|
29
31
|
}
|
|
30
|
-
|
|
31
|
-
const firstLine = `test
|
|
32
|
+
describe(node, children) {
|
|
33
|
+
const firstLine = `test.${this.getFunction('describe', node)}(${this.quoted(node.title)}, () => {`;
|
|
32
34
|
if (!children.length) {
|
|
33
35
|
return [`${firstLine}});`, ''];
|
|
34
36
|
}
|
|
35
|
-
return [firstLine,
|
|
37
|
+
return [firstLine,
|
|
38
|
+
// prettier-ignore
|
|
39
|
+
...this.describeConfigure(node).map(indent), '', ...children.map(indent), `});`, ''];
|
|
36
40
|
}
|
|
37
41
|
beforeEach(fixtures, children) {
|
|
38
42
|
const fixturesStr = [...fixtures].join(', ');
|
|
@@ -42,11 +46,19 @@ class Formatter {
|
|
|
42
46
|
test(node, fixtures, children) {
|
|
43
47
|
const fixturesStr = [...fixtures].join(', ');
|
|
44
48
|
const title = this.quoted(node.title);
|
|
45
|
-
const
|
|
49
|
+
const tags = this.testTags(node);
|
|
50
|
+
const firstLine = `${this.getFunction('test', node)}(${title}, ${tags}async ({ ${fixturesStr} }) => {`;
|
|
46
51
|
if (!children.length) {
|
|
47
52
|
return [`${firstLine}});`, ''];
|
|
48
53
|
}
|
|
49
|
-
|
|
54
|
+
const lines = [firstLine,
|
|
55
|
+
// prettier-ignore
|
|
56
|
+
...children.map(indent), `});`, ''];
|
|
57
|
+
// wrap test into anonymous describe in case of retries / timeout tags
|
|
58
|
+
const specialTagsConfigure = this.describeConfigure(node);
|
|
59
|
+
return specialTagsConfigure.length ? ['test.describe(() => {',
|
|
60
|
+
// prettier-ignore
|
|
61
|
+
...specialTagsConfigure.map(indent), '', ...lines.map(indent), `});`, ''] : lines;
|
|
50
62
|
}
|
|
51
63
|
// eslint-disable-next-line max-params
|
|
52
64
|
step(keyword, text, argument, fixtureNames = []) {
|
|
@@ -93,17 +105,49 @@ class Formatter {
|
|
|
93
105
|
langFixture(lang) {
|
|
94
106
|
return [`$lang: ({}, use) => use(${this.quoted(lang)}),`];
|
|
95
107
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
108
|
+
// eslint-disable-next-line complexity
|
|
109
|
+
getFunction(baseFn, node) {
|
|
110
|
+
if (node.specialTags.only) {
|
|
111
|
+
return `${baseFn}.only`;
|
|
112
|
+
}
|
|
113
|
+
// describe.fail is not supported
|
|
114
|
+
if (baseFn === 'test' && node.specialTags.fail) {
|
|
115
|
+
return `${baseFn}.fail`;
|
|
116
|
+
}
|
|
117
|
+
if (node.specialTags.skip) {
|
|
118
|
+
return `${baseFn}.skip`;
|
|
119
|
+
}
|
|
120
|
+
if (node.specialTags.fixme) {
|
|
121
|
+
return `${baseFn}.fixme`;
|
|
122
|
+
}
|
|
123
|
+
return baseFn;
|
|
124
|
+
}
|
|
125
|
+
describeConfigure(node) {
|
|
126
|
+
const options = {};
|
|
127
|
+
const {
|
|
128
|
+
retries,
|
|
129
|
+
timeout,
|
|
130
|
+
mode
|
|
131
|
+
} = node.specialTags;
|
|
132
|
+
if (retries !== undefined) {
|
|
133
|
+
options.retries = retries;
|
|
99
134
|
}
|
|
100
|
-
if (
|
|
101
|
-
|
|
135
|
+
if (timeout !== undefined) {
|
|
136
|
+
options.timeout = timeout;
|
|
102
137
|
}
|
|
103
|
-
if (
|
|
104
|
-
|
|
138
|
+
if (mode !== undefined) {
|
|
139
|
+
options.mode = mode;
|
|
105
140
|
}
|
|
106
|
-
return
|
|
141
|
+
return Object.keys(options).length ? [`test.describe.configure(${JSON.stringify(options)});`] : [];
|
|
142
|
+
}
|
|
143
|
+
testTags(node) {
|
|
144
|
+
return supportsTags && node.tags.length ? `{ tag: [${node.tags.map(tag => this.quoted(tag)).join(', ')}] }, ` : '';
|
|
145
|
+
}
|
|
146
|
+
testTimeout(node) {
|
|
147
|
+
const {
|
|
148
|
+
timeout
|
|
149
|
+
} = node.specialTags;
|
|
150
|
+
return timeout !== undefined ? [`test.setTimeout(${timeout});`] : [];
|
|
107
151
|
}
|
|
108
152
|
/**
|
|
109
153
|
* Apply this function only to string literals (mostly titles here).
|
|
@@ -14,13 +14,13 @@ var _loadFeatures = require("../cucumber/loadFeatures");
|
|
|
14
14
|
var _loadSteps = require("../cucumber/loadSteps");
|
|
15
15
|
var _config = require("../config");
|
|
16
16
|
var _snippets = require("../snippets");
|
|
17
|
-
var _steps = require("../
|
|
17
|
+
var _steps = require("../steps/decorators/steps");
|
|
18
18
|
var _transform = require("../playwright/transform");
|
|
19
19
|
var _configDir = require("../config/configDir");
|
|
20
20
|
var _logger = require("../utils/logger");
|
|
21
21
|
var _tagExpressions = _interopRequireDefault(require("@cucumber/tag-expressions"));
|
|
22
22
|
var _exit = require("../utils/exit");
|
|
23
|
-
var _createBdd = require("../
|
|
23
|
+
var _createBdd = require("../steps/createBdd");
|
|
24
24
|
var _resolveFeaturePaths = require("../cucumber/resolveFeaturePaths");
|
|
25
25
|
/**
|
|
26
26
|
* Generate playwright test files from Gherkin documents.
|
|
@@ -60,6 +60,16 @@ class TestFilesGenerator {
|
|
|
60
60
|
await this.loadSteps();
|
|
61
61
|
return this.supportCodeLibrary.stepDefinitions;
|
|
62
62
|
}
|
|
63
|
+
// todo: combine with extractSteps
|
|
64
|
+
async extractUnusedSteps() {
|
|
65
|
+
await this.loadCucumberConfig();
|
|
66
|
+
await Promise.all([this.loadFeatures(), this.loadSteps()]);
|
|
67
|
+
this.buildFiles();
|
|
68
|
+
return this.supportCodeLibrary.stepDefinitions.filter(stepDefinition => {
|
|
69
|
+
const isUsed = this.files.some(file => file.usedStepDefinitions.has(stepDefinition));
|
|
70
|
+
return !isUsed;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
63
73
|
async loadCucumberConfig() {
|
|
64
74
|
const environment = {
|
|
65
75
|
cwd: (0, _configDir.getPlaywrightConfigDir)()
|
|
@@ -75,20 +85,22 @@ class TestFilesGenerator {
|
|
|
75
85
|
async loadFeatures() {
|
|
76
86
|
const cwd = (0, _configDir.getPlaywrightConfigDir)();
|
|
77
87
|
const {
|
|
78
|
-
paths,
|
|
79
88
|
defaultDialect
|
|
80
89
|
} = this.runConfiguration.sources;
|
|
81
|
-
this.logger.log(`Loading features from: ${paths.join(', ')}`);
|
|
82
90
|
const {
|
|
83
91
|
featurePaths
|
|
84
92
|
} = await (0, _resolveFeaturePaths.resovleFeaturePaths)(this.runConfiguration, {
|
|
85
93
|
cwd
|
|
86
94
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
95
|
+
this.logger.log(`Loading features from paths (${featurePaths.length}):`);
|
|
96
|
+
featurePaths.forEach(featurePath => this.logger.log(featurePath));
|
|
97
|
+
if (featurePaths.length) {
|
|
98
|
+
await this.featuresLoader.load(featurePaths, {
|
|
99
|
+
relativeTo: cwd,
|
|
100
|
+
defaultDialect
|
|
101
|
+
});
|
|
102
|
+
this.handleParseErrors();
|
|
103
|
+
}
|
|
92
104
|
this.logger.log(`Loaded features: ${this.featuresLoader.getDocumentsCount()}`);
|
|
93
105
|
}
|
|
94
106
|
async loadSteps() {
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SpecialTags = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Special tags.
|
|
9
|
+
*/
|
|
10
|
+
class SpecialTags {
|
|
11
|
+
ownTags;
|
|
12
|
+
allTags;
|
|
13
|
+
only;
|
|
14
|
+
skip;
|
|
15
|
+
fixme;
|
|
16
|
+
fail;
|
|
17
|
+
retries;
|
|
18
|
+
timeout;
|
|
19
|
+
mode;
|
|
20
|
+
constructor(ownTags, allTags) {
|
|
21
|
+
this.ownTags = ownTags;
|
|
22
|
+
this.allTags = allTags;
|
|
23
|
+
this.extractFlags();
|
|
24
|
+
this.extractRetries();
|
|
25
|
+
this.extractTimeout();
|
|
26
|
+
this.extractMode();
|
|
27
|
+
}
|
|
28
|
+
extractFlags() {
|
|
29
|
+
// order is important
|
|
30
|
+
const flags = ['only', 'fail', 'skip', 'fixme'];
|
|
31
|
+
for (const flag of flags) {
|
|
32
|
+
if (this.ownTags.includes(`@${flag}`)) {
|
|
33
|
+
this[flag] = true;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// describe.fail is not supported, so mark all nested tests as failed instead
|
|
38
|
+
if (this.allTags.includes(`@fail`)) {
|
|
39
|
+
this.fail = true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
extractRetries() {
|
|
43
|
+
for (const tag of this.ownTags.reverse()) {
|
|
44
|
+
const match = tag.match(/@retries:(\d+)/i);
|
|
45
|
+
if (match) {
|
|
46
|
+
this.retries = Number(match[1]);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
extractTimeout() {
|
|
52
|
+
for (const tag of this.ownTags.reverse()) {
|
|
53
|
+
const match = tag.match(/@timeout:(\d+)/i);
|
|
54
|
+
if (match) {
|
|
55
|
+
this.timeout = Number(match[1]);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
extractMode() {
|
|
61
|
+
for (const tag of this.ownTags.reverse()) {
|
|
62
|
+
const match = tag.match(/@mode:(default|parallel|serial)/i);
|
|
63
|
+
if (match) {
|
|
64
|
+
this.mode = match[1];
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.SpecialTags = SpecialTags;
|
|
@@ -14,7 +14,7 @@ var _index = require("@cucumber/cucumber/lib/formatter/helpers/index");
|
|
|
14
14
|
var _utils = require("../utils");
|
|
15
15
|
var _testPoms = require("./testPoms");
|
|
16
16
|
var _testNode = require("./testNode");
|
|
17
|
-
var _stepConfig = require("../
|
|
17
|
+
var _stepConfig = require("../steps/stepConfig");
|
|
18
18
|
var _exit = require("../utils/exit");
|
|
19
19
|
var _fixtures = require("./fixtures");
|
|
20
20
|
var _scenario = require("../hooks/scenario");
|
|
@@ -35,6 +35,7 @@ class TestFile {
|
|
|
35
35
|
hasCustomTest = false;
|
|
36
36
|
undefinedSteps = [];
|
|
37
37
|
featureUri;
|
|
38
|
+
usedStepDefinitions = new Set();
|
|
38
39
|
constructor(options) {
|
|
39
40
|
this.options = options;
|
|
40
41
|
this.formatter = new _formatter.Formatter(options.config);
|
|
@@ -67,6 +68,9 @@ class TestFile {
|
|
|
67
68
|
return this.testMetaBuilder.testCount;
|
|
68
69
|
}
|
|
69
70
|
build() {
|
|
71
|
+
if (!this.pickles.length) {
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
70
74
|
this.loadI18nKeywords();
|
|
71
75
|
this.lines = [...this.getFileHeader(),
|
|
72
76
|
// prettier-ignore
|
|
@@ -136,11 +140,11 @@ class TestFile {
|
|
|
136
140
|
getSuite(feature, parent) {
|
|
137
141
|
const node = new _testNode.TestNode(feature, parent);
|
|
138
142
|
if (node.isSkipped()) {
|
|
139
|
-
return this.formatter.
|
|
143
|
+
return this.formatter.describe(node, []);
|
|
140
144
|
}
|
|
141
145
|
const lines = [];
|
|
142
146
|
feature.children.forEach(child => lines.push(...this.getSuiteChild(child, node)));
|
|
143
|
-
return this.formatter.
|
|
147
|
+
return this.formatter.describe(node, lines);
|
|
144
148
|
}
|
|
145
149
|
getSuiteChild(child, parent) {
|
|
146
150
|
if ('rule' in child && child.rule) {
|
|
@@ -177,7 +181,7 @@ class TestFile {
|
|
|
177
181
|
getOutlineSuite(scenario, parent) {
|
|
178
182
|
const node = new _testNode.TestNode(scenario, parent);
|
|
179
183
|
if (node.isSkipped()) {
|
|
180
|
-
return this.formatter.
|
|
184
|
+
return this.formatter.describe(node, []);
|
|
181
185
|
}
|
|
182
186
|
const lines = [];
|
|
183
187
|
let exampleIndex = 0;
|
|
@@ -189,7 +193,7 @@ class TestFile {
|
|
|
189
193
|
lines.push(...testLines);
|
|
190
194
|
});
|
|
191
195
|
});
|
|
192
|
-
return this.formatter.
|
|
196
|
+
return this.formatter.describe(node, lines);
|
|
193
197
|
}
|
|
194
198
|
/**
|
|
195
199
|
* Generate test from Examples row of Scenario Outline
|
|
@@ -304,6 +308,7 @@ class TestFile {
|
|
|
304
308
|
});
|
|
305
309
|
return this.getMissingStep(enKeyword, keywordType, pickleStep);
|
|
306
310
|
}
|
|
311
|
+
this.usedStepDefinitions.add(stepDefinition);
|
|
307
312
|
// for cucumber-style stepConfig is undefined
|
|
308
313
|
const stepConfig = (0, _stepConfig.getStepConfig)(stepDefinition);
|
|
309
314
|
if (stepConfig !== null && stepConfig !== void 0 && stepConfig.hasCustomTest) {
|
|
@@ -5,56 +5,31 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.TestNode = void 0;
|
|
7
7
|
var _utils = require("../utils");
|
|
8
|
+
var _specialTags = require("./specialTags");
|
|
8
9
|
/**
|
|
9
10
|
* Universal TestNode class representing test or suite in a test file.
|
|
10
11
|
* Holds parent-child links.
|
|
11
12
|
* Allows to inherit tags and titles path.
|
|
12
13
|
*/
|
|
13
14
|
|
|
14
|
-
const SPECIAL_TAGS = ['@only', '@skip', '@fixme'];
|
|
15
15
|
class TestNode {
|
|
16
16
|
title;
|
|
17
17
|
titlePath;
|
|
18
18
|
ownTags;
|
|
19
19
|
tags;
|
|
20
|
-
|
|
20
|
+
specialTags;
|
|
21
21
|
constructor(gherkinNode, parent) {
|
|
22
22
|
this.title = gherkinNode.name;
|
|
23
23
|
this.titlePath = ((parent === null || parent === void 0 ? void 0 : parent.titlePath) || []).concat([this.title]);
|
|
24
24
|
this.ownTags = (0, _utils.removeDuplicates)(getTagNames(gherkinNode.tags));
|
|
25
25
|
this.tags = (0, _utils.removeDuplicates)(((parent === null || parent === void 0 ? void 0 : parent.tags) || []).concat(this.ownTags));
|
|
26
|
-
this.
|
|
26
|
+
this.specialTags = new _specialTags.SpecialTags(this.ownTags, this.tags);
|
|
27
27
|
}
|
|
28
28
|
isSkipped() {
|
|
29
|
-
return this.
|
|
30
|
-
}
|
|
31
|
-
initFlags() {
|
|
32
|
-
this.ownTags.forEach(tag => {
|
|
33
|
-
if (isSpecialTag(tag)) {
|
|
34
|
-
this.setFlag(tag);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
// eslint-disable-next-line complexity
|
|
39
|
-
setFlag(tag) {
|
|
40
|
-
// in case of several special tags, @only takes precendence
|
|
41
|
-
if (tag === '@only') {
|
|
42
|
-
this.flags = {
|
|
43
|
-
only: true
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
if (tag === '@skip' && !this.flags.only) {
|
|
47
|
-
this.flags.skip = true;
|
|
48
|
-
}
|
|
49
|
-
if (tag === '@fixme' && !this.flags.only) {
|
|
50
|
-
this.flags.fixme = true;
|
|
51
|
-
}
|
|
29
|
+
return this.specialTags.skip || this.specialTags.fixme;
|
|
52
30
|
}
|
|
53
31
|
}
|
|
54
32
|
exports.TestNode = TestNode;
|
|
55
33
|
function getTagNames(tags) {
|
|
56
34
|
return tags.map(tag => tag.name);
|
|
57
|
-
}
|
|
58
|
-
function isSpecialTag(tag) {
|
|
59
|
-
return SPECIAL_TAGS.includes(tag);
|
|
60
35
|
}
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.TestPoms = void 0;
|
|
7
7
|
exports.buildFixtureTag = buildFixtureTag;
|
|
8
|
-
var _class = require("../
|
|
8
|
+
var _class = require("../steps/decorators/class");
|
|
9
9
|
var _exit = require("../utils/exit");
|
|
10
10
|
/**
|
|
11
11
|
* Track PomNodes used in the particular test.
|
|
@@ -46,7 +46,7 @@ Object.defineProperty(exports, "test", {
|
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
48
|
var _config = require("./config");
|
|
49
|
-
var _createBdd = require("./
|
|
49
|
+
var _createBdd = require("./steps/createBdd");
|
|
50
50
|
var _bddFixtures = require("./run/bddFixtures");
|
|
51
51
|
var _bddWorld = require("./run/bddWorld");
|
|
52
52
|
var _helper = require("./reporter/cucumber/helper");
|
|
@@ -7,6 +7,7 @@ exports.isTestContainsSubtest = isTestContainsSubtest;
|
|
|
7
7
|
exports.runStepWithCustomLocation = runStepWithCustomLocation;
|
|
8
8
|
var _test = require("@playwright/test");
|
|
9
9
|
var _utils = require("../utils");
|
|
10
|
+
var _utils2 = require("./utils");
|
|
10
11
|
/**
|
|
11
12
|
* Helpers to deal with Playwright test internal stuff.
|
|
12
13
|
* See: https://github.com/microsoft/playwright/blob/main/packages/playwright-test/src/common/testType.ts
|
|
@@ -27,16 +28,33 @@ function getTestImpl(test) {
|
|
|
27
28
|
*/
|
|
28
29
|
// eslint-disable-next-line max-params
|
|
29
30
|
async function runStepWithCustomLocation(test, stepText, location, body) {
|
|
30
|
-
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
// Since PW 1.43 testInfo._runAsStep was replaced with a more complex logic.
|
|
32
|
+
// To run step with a custom location, we hijack testInfo._addStep()
|
|
33
|
+
// so that it appends location for the bdd step calls.
|
|
34
|
+
// Finally we call test.step(), that internally invokes testInfo._addStep().
|
|
35
|
+
// See: https://github.com/microsoft/playwright/issues/30160
|
|
36
|
+
// See: https://github.com/microsoft/playwright/blob/release-1.43/packages/playwright/src/common/testType.ts#L262
|
|
37
|
+
// See: https://github.com/microsoft/playwright/blob/release-1.43/packages/playwright/src/worker/testInfo.ts#L247
|
|
38
|
+
if (_utils2.playwrightVersion >= '1.39.0') {
|
|
39
|
+
const testInfo = test.info();
|
|
40
|
+
// here we rely on that testInfo._addStep is called synchronously in test.step()
|
|
41
|
+
const origAddStep = testInfo._addStep;
|
|
42
|
+
testInfo._addStep = function (data) {
|
|
43
|
+
data.location = location;
|
|
44
|
+
testInfo._addStep = origAddStep;
|
|
45
|
+
return origAddStep.call(this, data);
|
|
46
|
+
};
|
|
47
|
+
return test.step(stepText, body);
|
|
48
|
+
} else {
|
|
49
|
+
const testInfo = test.info();
|
|
50
|
+
return testInfo._runAsStep({
|
|
51
|
+
category: 'test.step',
|
|
52
|
+
title: stepText,
|
|
53
|
+
location
|
|
54
|
+
}, async () => {
|
|
55
|
+
return await body();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
40
58
|
}
|
|
41
59
|
/**
|
|
42
60
|
* Returns true if test contains all fixtures of subtest.
|
|
@@ -2,4 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
|
-
});
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "PlaywrightLocation", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _reporter.Location;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _reporter = require("@playwright/test/reporter");
|
|
@@ -5,12 +5,15 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.getPlaywrightModulePath = getPlaywrightModulePath;
|
|
8
|
+
exports.playwrightVersion = void 0;
|
|
8
9
|
exports.requirePlaywrightModule = requirePlaywrightModule;
|
|
10
|
+
exports.updateAnnotation = updateAnnotation;
|
|
9
11
|
var _fs = _interopRequireDefault(require("fs"));
|
|
10
12
|
var _path = _interopRequireDefault(require("path"));
|
|
11
13
|
var _utils = require("../utils");
|
|
12
14
|
// cache playwright root
|
|
13
15
|
let playwrightRoot = '';
|
|
16
|
+
const playwrightVersion = exports.playwrightVersion = (0, _utils.getPackageVersion)('@playwright/test');
|
|
14
17
|
/**
|
|
15
18
|
* Requires Playwright's internal module that is not exported via package.exports.
|
|
16
19
|
*/
|
|
@@ -31,4 +34,23 @@ function getPlaywrightRoot() {
|
|
|
31
34
|
playwrightRoot = _fs.default.existsSync(libDir) ? playwrightTestRoot : (0, _utils.resolvePackageRoot)('playwright');
|
|
32
35
|
}
|
|
33
36
|
return playwrightRoot;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create or update annotation with provided type.
|
|
40
|
+
*/
|
|
41
|
+
function updateAnnotation(testInfo, annotation, {
|
|
42
|
+
create = false
|
|
43
|
+
} = {}) {
|
|
44
|
+
const {
|
|
45
|
+
annotations
|
|
46
|
+
} = testInfo;
|
|
47
|
+
const index = annotations.findIndex(a => a.type === annotation.type);
|
|
48
|
+
if (index === -1 && !create) {
|
|
49
|
+
throw new Error(`Annotation "${annotation.type}" is not found.`);
|
|
50
|
+
}
|
|
51
|
+
if (index === -1) {
|
|
52
|
+
annotations.push(annotation);
|
|
53
|
+
} else {
|
|
54
|
+
annotations[index] = annotation;
|
|
55
|
+
}
|
|
34
56
|
}
|
|
@@ -7,14 +7,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.default = void 0;
|
|
8
8
|
var _path = _interopRequireDefault(require("path"));
|
|
9
9
|
var _fs = _interopRequireDefault(require("fs"));
|
|
10
|
-
var
|
|
10
|
+
var _promises = require("node:stream/promises");
|
|
11
11
|
/**
|
|
12
12
|
* Base reporter for Cucumber reporters.
|
|
13
13
|
* Reference: https://github.com/cucumber/cucumber-js/blob/main/src/formatter/index.ts
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
// Import pipeline from the 'stream' module
|
|
17
|
-
|
|
18
16
|
class BaseReporter {
|
|
19
17
|
internalOptions;
|
|
20
18
|
outputStream = process.stdout;
|
|
@@ -34,10 +32,7 @@ class BaseReporter {
|
|
|
34
32
|
async finished() {
|
|
35
33
|
if (!isStdout(this.outputStream)) {
|
|
36
34
|
this.outputStream.end();
|
|
37
|
-
await
|
|
38
|
-
this.outputStream.on('finish', resolve);
|
|
39
|
-
this.outputStream.on('error', reject);
|
|
40
|
-
});
|
|
35
|
+
await (0, _promises.finished)(this.outputStream);
|
|
41
36
|
}
|
|
42
37
|
}
|
|
43
38
|
setOutputStream(outputFile) {
|
|
@@ -5,10 +5,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.default = void 0;
|
|
8
|
+
var _promises = require("node:stream/promises");
|
|
8
9
|
var _htmlFormatter = _interopRequireDefault(require("@cucumber/html-formatter"));
|
|
9
10
|
var _utils = require("../../utils");
|
|
10
11
|
var _path = _interopRequireDefault(require("path"));
|
|
11
12
|
var _base = _interopRequireDefault(require("./base"));
|
|
13
|
+
/**
|
|
14
|
+
* Cucumber html reporter.
|
|
15
|
+
* Based on: https://github.com/cucumber/cucumber-js/blob/main/src/formatter/html_formatter.ts
|
|
16
|
+
* See: https://github.com/cucumber/html-formatter
|
|
17
|
+
* See: https://github.com/cucumber/react-components
|
|
18
|
+
*/
|
|
19
|
+
|
|
12
20
|
class HtmlReporter extends _base.default {
|
|
13
21
|
userOptions;
|
|
14
22
|
htmlStream;
|
|
@@ -25,10 +33,7 @@ class HtmlReporter extends _base.default {
|
|
|
25
33
|
}
|
|
26
34
|
async finished() {
|
|
27
35
|
this.htmlStream.end();
|
|
28
|
-
await
|
|
29
|
-
this.htmlStream.on('finish', resolve);
|
|
30
|
-
this.htmlStream.on('error', reject);
|
|
31
|
-
});
|
|
36
|
+
await (0, _promises.finished)(this.htmlStream);
|
|
32
37
|
await super.finished();
|
|
33
38
|
}
|
|
34
39
|
}
|