@zohodesk/testinglibrary 0.1.8-exp-bdd-v2 → 0.1.8-exp-bdd-v4
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/.eslintrc.js +5 -1
- package/build/bdd-framework/cli/commands/env.js +2 -3
- package/build/bdd-framework/cli/commands/export.js +1 -2
- package/build/bdd-framework/cli/commands/test.js +7 -4
- package/build/bdd-framework/cli/options.js +1 -2
- package/build/bdd-framework/config/env.js +2 -1
- package/build/bdd-framework/config/index.js +1 -2
- package/build/bdd-framework/config/lang.js +14 -0
- package/build/bdd-framework/cucumber/loadSteps.js +8 -3
- package/build/bdd-framework/decorators.js +6 -10
- package/build/bdd-framework/gen/fixtures.js +48 -0
- package/build/bdd-framework/gen/formatter.js +57 -10
- package/build/bdd-framework/gen/i18n.js +6 -2
- package/build/bdd-framework/gen/index.js +7 -6
- package/build/bdd-framework/gen/testFile.js +105 -39
- package/build/bdd-framework/gen/testNode.js +16 -3
- package/build/bdd-framework/gen/testPoms.js +18 -8
- package/build/bdd-framework/hooks/scenario.js +107 -0
- package/build/bdd-framework/hooks/worker.js +83 -0
- package/build/bdd-framework/playwright/fixtureParameterNames.js +24 -8
- package/build/bdd-framework/playwright/getLocationInFile.js +13 -7
- package/build/bdd-framework/playwright/testTypeImpl.js +11 -7
- package/build/bdd-framework/playwright/transform.js +6 -2
- package/build/bdd-framework/playwright/utils.js +1 -4
- package/build/bdd-framework/run/StepInvoker.js +73 -0
- package/build/bdd-framework/run/bddFixtures.js +119 -57
- package/build/bdd-framework/run/bddWorld.js +24 -36
- package/build/bdd-framework/snippets/index.js +3 -2
- package/build/bdd-framework/snippets/snippetSyntax.js +3 -1
- package/build/bdd-framework/stepDefinitions/createBdd.js +28 -11
- package/build/bdd-framework/stepDefinitions/decorators/{poms.js → class.js} +7 -3
- package/build/bdd-framework/stepDefinitions/decorators/steps.js +8 -3
- package/build/bdd-framework/stepDefinitions/defineStep.js +2 -1
- package/build/bdd-framework/utils/exit.js +8 -4
- package/build/bdd-framework/utils/index.js +27 -1
- package/build/bdd-framework/utils/logger.js +4 -3
- package/build/bdd-poc/core-runner/main.js +10 -0
- package/build/bdd-poc/core-runner/stepDefinitions.js +0 -1
- package/build/bdd-poc/index.js +26 -0
- package/build/bdd-poc/test/stepGenerate/stepFileGenerate.js +6 -6
- package/build/bdd-poc/test/stepGenerate/stepsnippets.js +1 -2
- package/build/bdd-poc/test/testDataMap.js +5 -5
- package/build/core/jest/preprocessor/jsPreprocessor.js +2 -3
- package/build/core/playwright/builtInFixtures/addTags.js +19 -0
- package/build/core/playwright/builtInFixtures/cacheLayer.js +13 -0
- package/build/core/playwright/builtInFixtures/context.js +15 -0
- package/build/core/playwright/builtInFixtures/index.js +26 -0
- package/build/core/playwright/builtInFixtures/page.js +51 -0
- package/build/core/playwright/clear-caches.js +29 -0
- package/build/core/playwright/custom-commands.js +1 -2
- package/build/core/playwright/index.js +12 -93
- package/build/core/playwright/readConfigFile.js +12 -6
- package/build/core/playwright/report-generator.js +2 -1
- package/build/core/playwright/setup/config-creator.js +23 -17
- package/build/core/playwright/setup/config-utils.js +43 -11
- package/build/core/playwright/setup/custom-reporter.js +109 -0
- package/build/core/playwright/tag-processor.js +68 -0
- package/build/core/playwright/test-runner.js +40 -36
- package/build/decorators.d.ts +1 -1
- package/build/decorators.js +2 -16
- package/build/index.d.ts +59 -4
- package/build/index.js +10 -9
- package/build/lib/cli.js +10 -1
- package/build/parser/parser.js +0 -1
- package/build/setup-folder-structure/helper.js +34 -0
- package/build/setup-folder-structure/reportEnhancement/addonScript.html +25 -0
- package/build/setup-folder-structure/reportEnhancement/reportAlteration.js +25 -0
- package/build/setup-folder-structure/samples/git-ignore.sample.js +8 -4
- package/build/setup-folder-structure/samples/uat-config-sample.js +3 -2
- package/build/setup-folder-structure/setupProject.js +10 -5
- package/build/utils/fileUtils.js +15 -4
- package/build/utils/logger.js +1 -2
- package/build/utils/stepDefinitionsFormatter.js +1 -2
- package/changelog.md +57 -0
- package/npm-shrinkwrap.json +1426 -2172
- package/package.json +5 -4
- package/build/bdd-framework/cucumber/gherkin.d.ts +0 -45
- package/build/bdd-framework/gen/poms.js +0 -46
- package/build/bdd-framework/stepDefinitions/createDecorators.js +0 -109
- package/build/bdd-poc/main.js +0 -10
- /package/build/bdd-poc/{runner.js → core-runner/runner.js} +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.isTestContainsSubtest = isTestContainsSubtest;
|
|
7
7
|
exports.runStepWithCustomLocation = runStepWithCustomLocation;
|
|
8
8
|
var _test = require("@playwright/test");
|
|
9
9
|
var _utils = require("../utils");
|
|
@@ -39,13 +39,17 @@ async function runStepWithCustomLocation(test, stepText, location, body) {
|
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
-
* Returns true if all fixtures of
|
|
42
|
+
* Returns true if test contains all fixtures of subtest.
|
|
43
|
+
* - test was extended from subtest
|
|
44
|
+
* - test is a result of mergeTests(subtest, ...)
|
|
43
45
|
*/
|
|
44
|
-
function
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
function isTestContainsSubtest(test, subtest) {
|
|
47
|
+
if (test === subtest) {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
const testFixtures = new Set(getTestFixtures(test).map(f => locationToString(f.location)));
|
|
51
|
+
return getTestFixtures(subtest).every(f => {
|
|
52
|
+
return testFixtures.has(locationToString(f.location));
|
|
49
53
|
});
|
|
50
54
|
}
|
|
51
55
|
function locationToString({
|
|
@@ -30,13 +30,17 @@ function installTransform() {
|
|
|
30
30
|
function resolveFilename(specifier, parent, ...rest) {
|
|
31
31
|
if (!reverted && parent) {
|
|
32
32
|
const resolved = resolveHook(parent.filename, specifier);
|
|
33
|
-
if (resolved !== undefined)
|
|
33
|
+
if (resolved !== undefined) {
|
|
34
|
+
specifier = resolved;
|
|
35
|
+
}
|
|
34
36
|
}
|
|
35
37
|
return originalResolveFilename.call(this, specifier, parent, ...rest);
|
|
36
38
|
}
|
|
37
39
|
_module.default._resolveFilename = resolveFilename;
|
|
38
40
|
const revertPirates = pirates.addHook((code, filename) => {
|
|
39
|
-
if (!shouldTransform(filename))
|
|
41
|
+
if (!shouldTransform(filename)) {
|
|
42
|
+
return code;
|
|
43
|
+
}
|
|
40
44
|
return transformHook(code, filename);
|
|
41
45
|
}, {
|
|
42
46
|
exts: ['.ts', '.tsx', '.js', '.jsx', '.mjs']
|
|
@@ -28,10 +28,7 @@ function getPlaywrightRoot() {
|
|
|
28
28
|
// See: https://github.com/microsoft/playwright/pull/26946
|
|
29
29
|
const playwrightTestRoot = (0, _utils.resolvePackageRoot)('@playwright/test');
|
|
30
30
|
const libDir = _path.default.join(playwrightTestRoot, 'lib');
|
|
31
|
-
|
|
32
|
-
// Recently added functionality in playwright
|
|
33
|
-
const playwrightDir = _path.default.join(playwrightTestRoot, 'node_modules', 'playwright');
|
|
34
|
-
playwrightRoot = _fs.default.existsSync(libDir) ? playwrightTestRoot : playwrightDir;
|
|
31
|
+
playwrightRoot = _fs.default.existsSync(libDir) ? playwrightTestRoot : (0, _utils.resolvePackageRoot)('playwright');
|
|
35
32
|
}
|
|
36
33
|
return playwrightRoot;
|
|
37
34
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.StepInvoker = void 0;
|
|
7
|
+
var _loadSteps = require("../cucumber/loadSteps");
|
|
8
|
+
var _getLocationInFile = require("../playwright/getLocationInFile");
|
|
9
|
+
var _testTypeImpl = require("../playwright/testTypeImpl");
|
|
10
|
+
var _defineStep = require("../stepDefinitions/defineStep");
|
|
11
|
+
var _lang = require("../config/lang");
|
|
12
|
+
/**
|
|
13
|
+
* Class to invoke steps in generated files.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
class StepInvoker {
|
|
17
|
+
world;
|
|
18
|
+
keyword;
|
|
19
|
+
text = '';
|
|
20
|
+
argument;
|
|
21
|
+
constructor(world, keyword) {
|
|
22
|
+
this.world = world;
|
|
23
|
+
this.keyword = keyword;
|
|
24
|
+
this.invoke = this.invoke.bind(this);
|
|
25
|
+
}
|
|
26
|
+
async invoke(text, argument, stepFixtures) {
|
|
27
|
+
this.text = text;
|
|
28
|
+
this.argument = argument;
|
|
29
|
+
const {
|
|
30
|
+
world
|
|
31
|
+
} = this;
|
|
32
|
+
world.stepFixtures = stepFixtures || {};
|
|
33
|
+
const stepDefinition = this.getStepDefinition();
|
|
34
|
+
// Get location of step call in generated test file.
|
|
35
|
+
// This call must be exactly here to have correct call stack (before async calls)
|
|
36
|
+
const location = (0, _getLocationInFile.getLocationInFile)(world.test.info().file);
|
|
37
|
+
const stepTitle = this.getStepTitle();
|
|
38
|
+
const code = (0, _defineStep.getStepCode)(stepDefinition);
|
|
39
|
+
const parameters = await this.getStepParameters(stepDefinition);
|
|
40
|
+
return (0, _testTypeImpl.runStepWithCustomLocation)(world.test, stepTitle, location, () => code.apply(world, parameters));
|
|
41
|
+
}
|
|
42
|
+
getStepDefinition() {
|
|
43
|
+
const stepDefinition = (0, _loadSteps.findStepDefinition)(this.world.options.supportCodeLibrary, this.text, this.world.testInfo.file);
|
|
44
|
+
if (!stepDefinition) {
|
|
45
|
+
throw new Error(`Undefined step: "${this.text}"`);
|
|
46
|
+
}
|
|
47
|
+
return stepDefinition;
|
|
48
|
+
}
|
|
49
|
+
async getStepParameters(stepDefinition) {
|
|
50
|
+
const {
|
|
51
|
+
text,
|
|
52
|
+
argument,
|
|
53
|
+
world
|
|
54
|
+
} = this;
|
|
55
|
+
const {
|
|
56
|
+
parameters
|
|
57
|
+
} = await stepDefinition.getInvocationParameters({
|
|
58
|
+
hookParameter: {},
|
|
59
|
+
step: {
|
|
60
|
+
text,
|
|
61
|
+
argument
|
|
62
|
+
},
|
|
63
|
+
world
|
|
64
|
+
});
|
|
65
|
+
return parameters;
|
|
66
|
+
}
|
|
67
|
+
getStepTitle() {
|
|
68
|
+
// Currently prepend keyword only for English.
|
|
69
|
+
// For other langs it's more complex as we need to pass original keyword from step.
|
|
70
|
+
return (0, _lang.isEnglish)(this.world.options.lang) ? `${this.keyword} ${this.text}` : this.text;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.StepInvoker = StepInvoker;
|
|
@@ -13,12 +13,15 @@ var _config = require("../config");
|
|
|
13
13
|
var _env = require("../config/env");
|
|
14
14
|
var _steps = require("../stepDefinitions/decorators/steps");
|
|
15
15
|
var _dir = require("../config/dir");
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
var _scenario = require("../hooks/scenario");
|
|
17
|
+
var _worker = require("../hooks/worker");
|
|
18
|
+
var _StepInvoker = require("./StepInvoker");
|
|
19
|
+
const test = exports.test = _test.test.extend({
|
|
20
|
+
// load cucumber once per worker (auto-fixture)
|
|
21
|
+
// todo: maybe remove caching in cucumber/loadConfig.ts and cucumber/loadSteps.ts
|
|
22
|
+
// as we call it once per worker. Check generation phase.
|
|
23
|
+
$cucumber: [async ({}, use, workerInfo) => {
|
|
24
|
+
const config = (0, _env.getConfigFromEnv)(workerInfo.project.testDir);
|
|
22
25
|
const environment = {
|
|
23
26
|
cwd: (0, _dir.getPlaywrightConfigDir)()
|
|
24
27
|
};
|
|
@@ -30,11 +33,37 @@ const test = _test.test.extend({
|
|
|
30
33
|
const supportCodeLibrary = await (0, _loadSteps.loadSteps)(runConfiguration, environment);
|
|
31
34
|
(0, _steps.appendDecoratorSteps)(supportCodeLibrary);
|
|
32
35
|
const World = (0, _bddWorld.getWorldConstructor)(supportCodeLibrary);
|
|
36
|
+
await use({
|
|
37
|
+
runConfiguration,
|
|
38
|
+
supportCodeLibrary,
|
|
39
|
+
World
|
|
40
|
+
});
|
|
41
|
+
}, {
|
|
42
|
+
auto: true,
|
|
43
|
+
scope: 'worker'
|
|
44
|
+
}],
|
|
45
|
+
$lang: ({}, use) => use(''),
|
|
46
|
+
// init $bddWorldFixtures with empty object, will be owerwritten in test file for cucumber-style
|
|
47
|
+
$bddWorldFixtures: ({}, use) => use({}),
|
|
48
|
+
$bddWorld: async ({
|
|
49
|
+
$tags,
|
|
50
|
+
$test,
|
|
51
|
+
$bddWorldFixtures,
|
|
52
|
+
$cucumber,
|
|
53
|
+
$lang
|
|
54
|
+
}, use, testInfo) => {
|
|
55
|
+
const {
|
|
56
|
+
runConfiguration,
|
|
57
|
+
supportCodeLibrary,
|
|
58
|
+
World
|
|
59
|
+
} = $cucumber;
|
|
33
60
|
const world = new World({
|
|
34
61
|
testInfo,
|
|
35
62
|
supportCodeLibrary,
|
|
36
63
|
$tags,
|
|
37
64
|
$test,
|
|
65
|
+
$bddWorldFixtures,
|
|
66
|
+
lang: $lang,
|
|
38
67
|
parameters: runConfiguration.runtime.worldParameters || {},
|
|
39
68
|
log: () => {},
|
|
40
69
|
attach: async () => {}
|
|
@@ -43,65 +72,98 @@ const test = _test.test.extend({
|
|
|
43
72
|
await use(world);
|
|
44
73
|
await world.destroy();
|
|
45
74
|
},
|
|
46
|
-
$bddWorld: async ({
|
|
47
|
-
$bddWorldBase,
|
|
48
|
-
page,
|
|
49
|
-
context,
|
|
50
|
-
browser,
|
|
51
|
-
browserName,
|
|
52
|
-
request
|
|
53
|
-
}, use) => {
|
|
54
|
-
$bddWorldBase.builtinFixtures = {
|
|
55
|
-
page,
|
|
56
|
-
context,
|
|
57
|
-
browser,
|
|
58
|
-
browserName,
|
|
59
|
-
request
|
|
60
|
-
};
|
|
61
|
-
await use($bddWorldBase);
|
|
62
|
-
},
|
|
63
|
-
// below fixtures are used in playwright-style
|
|
64
|
-
// and does not automatically init Playwright builtin fixtures
|
|
65
75
|
Given: ({
|
|
66
|
-
$bddWorldBase
|
|
67
|
-
}, use) => use($bddWorldBase.invokeStep),
|
|
68
|
-
When: ({
|
|
69
|
-
$bddWorldBase
|
|
70
|
-
}, use) => use($bddWorldBase.invokeStep),
|
|
71
|
-
Then: ({
|
|
72
|
-
$bddWorldBase
|
|
73
|
-
}, use) => use($bddWorldBase.invokeStep),
|
|
74
|
-
And: ({
|
|
75
|
-
$bddWorldBase
|
|
76
|
-
}, use) => use($bddWorldBase.invokeStep),
|
|
77
|
-
But: ({
|
|
78
|
-
$bddWorldBase
|
|
79
|
-
}, use) => use($bddWorldBase.invokeStep),
|
|
80
|
-
// below fixtures are used in cucumber-style
|
|
81
|
-
// and automatically init Playwright builtin fixtures
|
|
82
|
-
Given_: ({
|
|
83
76
|
$bddWorld
|
|
84
|
-
}, use) => use($bddWorld.
|
|
85
|
-
|
|
77
|
+
}, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'Given').invoke),
|
|
78
|
+
When: ({
|
|
86
79
|
$bddWorld
|
|
87
|
-
}, use) => use($bddWorld.
|
|
88
|
-
|
|
80
|
+
}, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'When').invoke),
|
|
81
|
+
Then: ({
|
|
89
82
|
$bddWorld
|
|
90
|
-
}, use) => use($bddWorld.
|
|
91
|
-
|
|
83
|
+
}, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'Then').invoke),
|
|
84
|
+
And: ({
|
|
92
85
|
$bddWorld
|
|
93
|
-
}, use) => use($bddWorld.
|
|
94
|
-
|
|
86
|
+
}, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'And').invoke),
|
|
87
|
+
But: ({
|
|
95
88
|
$bddWorld
|
|
96
|
-
}, use) => use($bddWorld.
|
|
97
|
-
//
|
|
98
|
-
// eslint-disable-next-line
|
|
89
|
+
}, use) => use(new _StepInvoker.StepInvoker($bddWorld, 'But').invoke),
|
|
90
|
+
// init $tags with empty array, can be owerwritten in test file
|
|
99
91
|
$tags: ({}, use) => use([]),
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
92
|
+
// init $test with base test, but it will be always overwritten in test file
|
|
93
|
+
$test: ({}, use) => use(_test.test),
|
|
94
|
+
// can be owerwritten in test file if there are scenario hooks
|
|
95
|
+
$scenarioHookFixtures: ({}, use) => use({}),
|
|
96
|
+
$before: [
|
|
97
|
+
// Unused dependencies are important:
|
|
98
|
+
// 1. $beforeAll / $afterAll: in pw < 1.39 worker-scoped auto-fixtures were called after test-scoped
|
|
99
|
+
// 2. $after: to call after hooks in case of errors in before hooks
|
|
100
|
+
async ({
|
|
101
|
+
$scenarioHookFixtures,
|
|
102
|
+
$bddWorld,
|
|
103
|
+
$tags,
|
|
104
|
+
$beforeAll,
|
|
105
|
+
$afterAll,
|
|
106
|
+
$after
|
|
107
|
+
}, use, $testInfo) => {
|
|
108
|
+
await (0, _scenario.runScenarioHooks)('before', {
|
|
109
|
+
$bddWorld,
|
|
110
|
+
$tags,
|
|
111
|
+
$testInfo,
|
|
112
|
+
...$scenarioHookFixtures
|
|
113
|
+
});
|
|
114
|
+
await use();
|
|
115
|
+
}, {
|
|
116
|
+
auto: true
|
|
117
|
+
}],
|
|
118
|
+
$after: [async ({
|
|
119
|
+
$scenarioHookFixtures,
|
|
120
|
+
$bddWorld,
|
|
121
|
+
$tags
|
|
122
|
+
}, use, $testInfo) => {
|
|
123
|
+
await use();
|
|
124
|
+
await (0, _scenario.runScenarioHooks)('after', {
|
|
125
|
+
$bddWorld,
|
|
126
|
+
$tags,
|
|
127
|
+
$testInfo,
|
|
128
|
+
...$scenarioHookFixtures
|
|
129
|
+
});
|
|
130
|
+
}, {
|
|
131
|
+
auto: true
|
|
132
|
+
}],
|
|
133
|
+
// can be owerwritten in test file if there are worker hooks
|
|
134
|
+
$workerHookFixtures: [({}, use) => use({}), {
|
|
135
|
+
scope: 'worker'
|
|
136
|
+
}],
|
|
137
|
+
$beforeAll: [
|
|
138
|
+
// Important unused dependencies:
|
|
139
|
+
// 1. $afterAll: in pw < 1.39 worker-scoped auto-fixtures are called in incorrect order
|
|
140
|
+
// 2. $cucumber: to load hooks before this fixtures
|
|
141
|
+
async ({
|
|
142
|
+
$workerHookFixtures,
|
|
143
|
+
$cucumber
|
|
144
|
+
}, use, $workerInfo) => {
|
|
145
|
+
await (0, _worker.runWorkerHooks)('beforeAll', {
|
|
146
|
+
$workerInfo,
|
|
147
|
+
...$workerHookFixtures
|
|
148
|
+
});
|
|
149
|
+
await use();
|
|
150
|
+
}, {
|
|
151
|
+
auto: true,
|
|
152
|
+
scope: 'worker'
|
|
153
|
+
}],
|
|
154
|
+
$afterAll: [async ({
|
|
155
|
+
$workerHookFixtures
|
|
156
|
+
}, use, $workerInfo) => {
|
|
157
|
+
await use();
|
|
158
|
+
await (0, _worker.runWorkerHooks)('afterAll', {
|
|
159
|
+
$workerInfo,
|
|
160
|
+
...$workerHookFixtures
|
|
161
|
+
});
|
|
162
|
+
}, {
|
|
163
|
+
auto: true,
|
|
164
|
+
scope: 'worker'
|
|
165
|
+
}]
|
|
103
166
|
});
|
|
104
|
-
exports.test = test;
|
|
105
167
|
const BDD_AUTO_INJECT_FIXTURES = ['$testInfo', '$test', '$tags'];
|
|
106
168
|
function isBddAutoInjectFixture(name) {
|
|
107
169
|
return BDD_AUTO_INJECT_FIXTURES.includes(name);
|
|
@@ -6,58 +6,46 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.BddWorld = void 0;
|
|
7
7
|
exports.getWorldConstructor = getWorldConstructor;
|
|
8
8
|
var _cucumber = require("@cucumber/cucumber");
|
|
9
|
-
var _loadSteps = require("../cucumber/loadSteps");
|
|
10
|
-
var _getLocationInFile = require("../playwright/getLocationInFile");
|
|
11
|
-
var _testTypeImpl = require("../playwright/testTypeImpl");
|
|
12
|
-
var _defineStep = require("../stepDefinitions/defineStep");
|
|
13
9
|
class BddWorld extends _cucumber.World {
|
|
14
10
|
options;
|
|
15
|
-
|
|
16
|
-
customFixtures;
|
|
11
|
+
stepFixtures = {};
|
|
17
12
|
constructor(options) {
|
|
18
13
|
super(options);
|
|
19
14
|
this.options = options;
|
|
20
|
-
this.invokeStep = this.invokeStep.bind(this);
|
|
21
15
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
},
|
|
41
|
-
world: this
|
|
42
|
-
});
|
|
43
|
-
const res = await (0, _testTypeImpl.runStepWithCustomLocation)(this.test, text, location, () => code.apply(this, parameters));
|
|
44
|
-
delete this.customFixtures;
|
|
45
|
-
return res;
|
|
16
|
+
/**
|
|
17
|
+
* Use particular fixture in cucumber-style steps.
|
|
18
|
+
*
|
|
19
|
+
* Note: TS does not support partial generic inference,
|
|
20
|
+
* that's why we can't use this.useFixture<typeof test>('xxx');
|
|
21
|
+
* The solution is to pass TestType as a generic to BddWorld
|
|
22
|
+
* and call useFixture without explicit generic params.
|
|
23
|
+
* Finally, it looks even better as there is no need to pass `typeof test`
|
|
24
|
+
* in every `this.useFixture` call.
|
|
25
|
+
*
|
|
26
|
+
* The downside - it's impossible to pass fixtures type directly to `this.useFixture`
|
|
27
|
+
* like it's done in @Fixture decorator.
|
|
28
|
+
*
|
|
29
|
+
* See: https://stackoverflow.com/questions/45509621/specify-only-first-type-argument
|
|
30
|
+
* See: https://github.com/Microsoft/TypeScript/pull/26349
|
|
31
|
+
*/
|
|
32
|
+
useFixture(fixtureName) {
|
|
33
|
+
return this.stepFixtures[fixtureName];
|
|
46
34
|
}
|
|
47
35
|
get page() {
|
|
48
|
-
return this.
|
|
36
|
+
return this.options.$bddWorldFixtures.page;
|
|
49
37
|
}
|
|
50
38
|
get context() {
|
|
51
|
-
return this.
|
|
39
|
+
return this.options.$bddWorldFixtures.context;
|
|
52
40
|
}
|
|
53
41
|
get browser() {
|
|
54
|
-
return this.
|
|
42
|
+
return this.options.$bddWorldFixtures.browser;
|
|
55
43
|
}
|
|
56
44
|
get browserName() {
|
|
57
|
-
return this.
|
|
45
|
+
return this.options.$bddWorldFixtures.browserName;
|
|
58
46
|
}
|
|
59
47
|
get request() {
|
|
60
|
-
return this.
|
|
48
|
+
return this.options.$bddWorldFixtures.request;
|
|
61
49
|
}
|
|
62
50
|
get testInfo() {
|
|
63
51
|
return this.options.testInfo;
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.Snippets = void 0;
|
|
7
|
+
var _url = require("url");
|
|
7
8
|
var _loadSnippetBuilder = require("../cucumber/loadSnippetBuilder");
|
|
8
9
|
var _logger = require("../utils/logger");
|
|
9
10
|
var _stepConfig = require("../stepDefinitions/stepConfig");
|
|
@@ -30,7 +31,6 @@ class Snippets {
|
|
|
30
31
|
this.printFooter(snippets);
|
|
31
32
|
// exit();
|
|
32
33
|
}
|
|
33
|
-
|
|
34
34
|
async createSnippetBuilder() {
|
|
35
35
|
const {
|
|
36
36
|
snippetInterface
|
|
@@ -44,7 +44,8 @@ class Snippets {
|
|
|
44
44
|
} = this.runConfiguration.formats.options;
|
|
45
45
|
if (!snippetSyntax && this.isPlaywrightStyle()) {
|
|
46
46
|
this.bddBuiltInSyntax = true;
|
|
47
|
-
|
|
47
|
+
const filePath = this.isDecorators() ? require.resolve('./snippetSyntaxDecorators.js') : this.isTypeScript() ? require.resolve('./snippetSyntaxTs.js') : require.resolve('./snippetSyntax.js');
|
|
48
|
+
return (0, _url.pathToFileURL)(filePath).toString();
|
|
48
49
|
} else {
|
|
49
50
|
return snippetSyntax;
|
|
50
51
|
}
|
|
@@ -27,7 +27,9 @@ class _default {
|
|
|
27
27
|
});
|
|
28
28
|
const allParameterNames = ['{}', ...expressionParameters, ...stepParameters];
|
|
29
29
|
const functionSignature = `${functionName}('${this.escapeSpecialCharacters(generatedExpression)}', async (${allParameterNames.join(', ')}) => {`;
|
|
30
|
-
return [functionSignature,
|
|
30
|
+
return [functionSignature,
|
|
31
|
+
// prettier-ignore
|
|
32
|
+
` // ...`, '});'].join('\n');
|
|
31
33
|
}
|
|
32
34
|
escapeSpecialCharacters(generatedExpression) {
|
|
33
35
|
let source = generatedExpression.source;
|
|
@@ -4,27 +4,42 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.createBdd = createBdd;
|
|
7
|
-
exports.
|
|
8
|
-
var _fixtureParameterNames = require("../playwright/fixtureParameterNames");
|
|
7
|
+
exports.hasCustomTest = void 0;
|
|
9
8
|
var _bddFixtures = require("../run/bddFixtures");
|
|
10
9
|
var _testTypeImpl = require("../playwright/testTypeImpl");
|
|
11
10
|
var _defineStep = require("./defineStep");
|
|
12
11
|
var _exit = require("../utils/exit");
|
|
12
|
+
var _scenario = require("../hooks/scenario");
|
|
13
|
+
var _worker = require("../hooks/worker");
|
|
13
14
|
/**
|
|
14
15
|
* Stuff related to writing steps in Playwright-style.
|
|
15
16
|
*/
|
|
16
17
|
|
|
18
|
+
// Global flag showing that custom test was passed.
|
|
19
|
+
// Used when checking 'importTestFrom' config option.
|
|
20
|
+
// todo: https://github.com/vitalets/playwright-bdd/issues/46
|
|
21
|
+
let hasCustomTest = exports.hasCustomTest = false;
|
|
17
22
|
function createBdd(customTest) {
|
|
18
|
-
|
|
23
|
+
if (!hasCustomTest) {
|
|
24
|
+
exports.hasCustomTest = hasCustomTest = isCustomTest(customTest);
|
|
25
|
+
}
|
|
19
26
|
const Given = defineStepCtor('Given', hasCustomTest);
|
|
20
27
|
const When = defineStepCtor('When', hasCustomTest);
|
|
21
28
|
const Then = defineStepCtor('Then', hasCustomTest);
|
|
22
29
|
const Step = defineStepCtor('Unknown', hasCustomTest);
|
|
30
|
+
const Before = (0, _scenario.scenarioHookFactory)('before');
|
|
31
|
+
const After = (0, _scenario.scenarioHookFactory)('after');
|
|
32
|
+
const BeforeAll = (0, _worker.workerHookFactory)('beforeAll');
|
|
33
|
+
const AfterAll = (0, _worker.workerHookFactory)('afterAll');
|
|
23
34
|
return {
|
|
24
35
|
Given,
|
|
25
36
|
When,
|
|
26
37
|
Then,
|
|
27
|
-
Step
|
|
38
|
+
Step,
|
|
39
|
+
Before,
|
|
40
|
+
After,
|
|
41
|
+
BeforeAll,
|
|
42
|
+
AfterAll
|
|
28
43
|
};
|
|
29
44
|
}
|
|
30
45
|
function defineStepCtor(keyword, hasCustomTest) {
|
|
@@ -37,13 +52,15 @@ function defineStepCtor(keyword, hasCustomTest) {
|
|
|
37
52
|
});
|
|
38
53
|
};
|
|
39
54
|
}
|
|
40
|
-
function extractFixtureNames(fn) {
|
|
41
|
-
return (0, _fixtureParameterNames.fixtureParameterNames)(fn).filter(name => !(0, _bddFixtures.isBddAutoInjectFixture)(name));
|
|
42
|
-
}
|
|
43
55
|
function isCustomTest(customTest) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
if (!customTest || customTest === _bddFixtures.test) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
assertTestHasBddFixtures(customTest);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
function assertTestHasBddFixtures(customTest) {
|
|
63
|
+
if (!(0, _testTypeImpl.isTestContainsSubtest)(customTest, _bddFixtures.test)) {
|
|
64
|
+
(0, _exit.exit)(`createBdd() should use 'test' extended from "playwright-bdd"`);
|
|
47
65
|
}
|
|
48
|
-
return isCustomTest;
|
|
49
66
|
}
|
|
@@ -8,7 +8,7 @@ exports.getPomNodeByFixtureName = getPomNodeByFixtureName;
|
|
|
8
8
|
var _steps = require("./steps");
|
|
9
9
|
var _exit = require("../../utils/exit");
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Class level @Fixture decorator.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -51,7 +51,9 @@ function ensureUniqueFixtureName({
|
|
|
51
51
|
}
|
|
52
52
|
function linkParentWithPomNode(Ctor, pomNode) {
|
|
53
53
|
const parentCtor = Object.getPrototypeOf(Ctor);
|
|
54
|
-
if (!parentCtor)
|
|
54
|
+
if (!parentCtor) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
55
57
|
// if parentCtor is not in pomGraph, add it.
|
|
56
58
|
// Case: parent class is not marked with @Fixture, but has decorator steps (base class)
|
|
57
59
|
const parentPomNode = pomGraph.get(parentCtor) || createPomNode(parentCtor, '');
|
|
@@ -59,6 +61,8 @@ function linkParentWithPomNode(Ctor, pomNode) {
|
|
|
59
61
|
}
|
|
60
62
|
function getPomNodeByFixtureName(fixtureName) {
|
|
61
63
|
for (const pomNode of pomGraph.values()) {
|
|
62
|
-
if (pomNode.fixtureName === fixtureName)
|
|
64
|
+
if (pomNode.fixtureName === fixtureName) {
|
|
65
|
+
return pomNode;
|
|
66
|
+
}
|
|
63
67
|
}
|
|
64
68
|
}
|
|
@@ -36,11 +36,15 @@ function createStepDecorator(keyword) {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
function linkStepsWithPomNode(Ctor, pomNode) {
|
|
39
|
-
if (!(Ctor !== null && Ctor !== void 0 && Ctor.prototype))
|
|
39
|
+
if (!(Ctor !== null && Ctor !== void 0 && Ctor.prototype)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
40
42
|
const propertyDescriptors = Object.getOwnPropertyDescriptors(Ctor.prototype);
|
|
41
43
|
return Object.values(propertyDescriptors).forEach(descriptor => {
|
|
42
44
|
const stepConfig = getStepConfigFromMethod(descriptor);
|
|
43
|
-
if (!stepConfig)
|
|
45
|
+
if (!stepConfig) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
44
48
|
stepConfig.pomNode = pomNode;
|
|
45
49
|
decoratedSteps.add(stepConfig);
|
|
46
50
|
});
|
|
@@ -65,7 +69,9 @@ function appendDecoratorSteps(supportCodeLibrary) {
|
|
|
65
69
|
pattern,
|
|
66
70
|
code,
|
|
67
71
|
line: 0,
|
|
72
|
+
// not used in playwright-bdd
|
|
68
73
|
options: {},
|
|
74
|
+
// not used in playwright-bdd
|
|
69
75
|
uri: '' // not used in playwright-bdd
|
|
70
76
|
}, supportCodeLibrary);
|
|
71
77
|
supportCodeLibrary.stepDefinitions.push(stepDefinition);
|
|
@@ -73,7 +79,6 @@ function appendDecoratorSteps(supportCodeLibrary) {
|
|
|
73
79
|
decoratedSteps.clear();
|
|
74
80
|
// todo: fill supportCodeLibrary.originalCoordinates as it is used in snippets?
|
|
75
81
|
}
|
|
76
|
-
|
|
77
82
|
function getFirstNonAutoInjectFixture(fixturesArg, stepConfig) {
|
|
78
83
|
// there should be exatcly one suitable fixture in fixturesArg
|
|
79
84
|
const fixtureNames = Object.keys(fixturesArg).filter(fixtureName => !(0, _bddFixtures.isBddAutoInjectFixture)(fixtureName));
|
|
@@ -34,7 +34,8 @@ function defineStep(stepConfig) {
|
|
|
34
34
|
}
|
|
35
35
|
function buildCucumberStepCode(stepConfig) {
|
|
36
36
|
const code = function (...args) {
|
|
37
|
-
|
|
37
|
+
// build the first argument (fixtures) for step fn
|
|
38
|
+
const fixturesArg = Object.assign({}, this.stepFixtures, {
|
|
38
39
|
$testInfo: this.testInfo,
|
|
39
40
|
$test: this.test,
|
|
40
41
|
$tags: this.tags
|
|
@@ -5,17 +5,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.exit = exit;
|
|
7
7
|
exports.withExitHandler = withExitHandler;
|
|
8
|
-
var _logger = require("./logger");
|
|
9
8
|
var _worker_threads = require("worker_threads");
|
|
10
9
|
/**
|
|
11
10
|
* Exit utils.
|
|
12
11
|
*
|
|
13
|
-
* When calling process.exit() in worker thread used for file generation,
|
|
12
|
+
* When calling process.exit() in worker thread used for test-file generation,
|
|
14
13
|
* logs are not flushed (https://github.com/vitalets/playwright-bdd/issues/59).
|
|
15
14
|
* That's why instead of process.exit we throw ExitError
|
|
16
15
|
* that just sets process.exitCode = 1 and allow program to exit normally.
|
|
16
|
+
* This esnured by wrapping code with withExitHandler().
|
|
17
17
|
*
|
|
18
|
-
* On the other hand, when running in main thread, especially inside Playwright,
|
|
18
|
+
* On the other hand, when running in the main thread, especially inside Playwright,
|
|
19
19
|
* thrown error is captured by Playwright and show with additional messages (e.g. no tests found).
|
|
20
20
|
* That's why in main thread we to call process.exit() to show only needed error.
|
|
21
21
|
*
|
|
@@ -35,6 +35,10 @@ async function withExitHandler(fn) {
|
|
|
35
35
|
return await fn();
|
|
36
36
|
} catch (e) {
|
|
37
37
|
if (e instanceof ExitError) {
|
|
38
|
+
if (e.message) {
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
console.error(e.message);
|
|
41
|
+
}
|
|
38
42
|
process.exitCode = 1;
|
|
39
43
|
} else {
|
|
40
44
|
throw e;
|
|
@@ -45,7 +49,7 @@ function exit(...messages) {
|
|
|
45
49
|
messages = messages.filter(Boolean);
|
|
46
50
|
if (_worker_threads.isMainThread) {
|
|
47
51
|
if (messages.length) {
|
|
48
|
-
|
|
52
|
+
logger.error('Error:', ...messages);
|
|
49
53
|
}
|
|
50
54
|
process.exit(1);
|
|
51
55
|
} else {
|