@zohodesk/testinglibrary 0.1.1-exp.1 → 0.1.1
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/Changelog.md +0 -5
- package/build/bdd-framework/cli/commands/env.js +1 -1
- package/build/bdd-framework/cli/commands/test.js +19 -19
- package/build/bdd-framework/config/env.js +3 -3
- package/build/bdd-framework/cucumber/loadFeatures.js +2 -2
- package/build/bdd-framework/cucumber/loadSteps.js +2 -2
- package/build/bdd-framework/gen/index.js +11 -14
- package/build/bdd-framework/gen/testFile.js +12 -12
- package/build/bdd-framework/gen/testPoms.js +2 -2
- package/build/bdd-framework/playwright/loadConfig.js +2 -2
- package/build/bdd-framework/playwright/testTypeImpl.js +1 -17
- package/build/bdd-framework/run/bddWorld.js +2 -3
- package/build/bdd-framework/snippets/index.js +5 -9
- package/build/bdd-framework/stepDefinitions/createBdd.js +2 -2
- package/build/bdd-framework/stepDefinitions/decorators/poms.js +3 -17
- package/build/bdd-framework/stepDefinitions/defineStep.js +2 -2
- package/build/bdd-framework/utils/index.js +6 -0
- package/npm-shrinkwrap.json +10 -19
- package/package.json +3 -3
- package/build/bdd-framework/utils/exit.js +0 -52
package/Changelog.md
CHANGED
|
@@ -34,7 +34,7 @@ function showPackageVersion(packageName) {
|
|
|
34
34
|
* to aneble using directly from /dist in tests.
|
|
35
35
|
*/
|
|
36
36
|
function getOwnVersion() {
|
|
37
|
-
return '5.
|
|
37
|
+
return '5.3.0';
|
|
38
38
|
}
|
|
39
39
|
function showPlaywrightConfigPath(cliConfigPath) {
|
|
40
40
|
const resolvedConfigFile = (0, _loadConfig.resolveConfigFile)(cliConfigPath);
|
|
@@ -11,40 +11,40 @@ var _events = require("events");
|
|
|
11
11
|
var _path = _interopRequireDefault(require("path"));
|
|
12
12
|
var _commander = require("commander");
|
|
13
13
|
var _gen = require("../../gen");
|
|
14
|
+
var _utils = require("../../utils");
|
|
14
15
|
var _loadConfig = require("../../playwright/loadConfig");
|
|
15
16
|
var _env = require("../../config/env");
|
|
16
17
|
var _config = require("../../config");
|
|
17
18
|
var _options = require("../options");
|
|
18
|
-
var _exit = require("../../utils/exit");
|
|
19
19
|
const GEN_WORKER_PATH = _path.default.resolve(__dirname, '..', 'worker.js');
|
|
20
20
|
const testCommand = new _commander.Command('test').description('Generate Playwright test files from Gherkin documents').addOption(_options.configOption).option('--tags <expression>', `Tags expression to filter scenarios for generation`).option('--verbose', `Verbose mode (default: ${Boolean(_config.defaults.verbose)})`).action(async opts => {
|
|
21
21
|
await (0, _loadConfig.loadConfig)(opts.config);
|
|
22
|
-
const configs = readConfigsFromEnv();
|
|
23
|
-
mergeCliOptions(configs, opts);
|
|
24
|
-
await generateFilesForConfigs(configs);
|
|
25
|
-
});
|
|
26
|
-
exports.testCommand = testCommand;
|
|
27
|
-
function readConfigsFromEnv() {
|
|
28
22
|
const configs = Object.values((0, _env.getEnvConfigs)());
|
|
29
23
|
assertConfigsCount(configs);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
24
|
+
const cliOptions = buildCliOptions(opts);
|
|
25
|
+
await generateFilesForConfigs(configs, cliOptions);
|
|
26
|
+
});
|
|
27
|
+
exports.testCommand = testCommand;
|
|
28
|
+
function buildCliOptions(opts) {
|
|
29
|
+
const config = {};
|
|
30
|
+
if ('tags' in opts) config.tags = opts.tags;
|
|
31
|
+
if ('verbose' in opts) config.verbose = Boolean(opts.verbose);
|
|
32
|
+
return config;
|
|
37
33
|
}
|
|
38
34
|
function assertConfigsCount(configs) {
|
|
39
35
|
if (configs.length === 0) {
|
|
40
|
-
(0,
|
|
36
|
+
(0, _utils.exitWithMessage)(`No BDD configs found. Did you use defineBddConfig() in playwright.config.ts?`);
|
|
41
37
|
}
|
|
42
38
|
}
|
|
43
|
-
async function generateFilesForConfigs(configs) {
|
|
39
|
+
async function generateFilesForConfigs(configs, cliConfig) {
|
|
44
40
|
// run first config in main thread and other in workers (to have fresh require cache)
|
|
45
41
|
// See: https://github.com/vitalets/playwright-bdd/issues/32
|
|
46
42
|
const tasks = configs.map((config, index) => {
|
|
47
|
-
|
|
43
|
+
const finalConfig = {
|
|
44
|
+
...config,
|
|
45
|
+
...cliConfig
|
|
46
|
+
};
|
|
47
|
+
return index === 0 ? new _gen.TestFilesGenerator(finalConfig).generate() : runInWorker(finalConfig);
|
|
48
48
|
});
|
|
49
49
|
return Promise.all(tasks);
|
|
50
50
|
}
|
|
@@ -54,6 +54,6 @@ async function runInWorker(config) {
|
|
|
54
54
|
config
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// todo: check if worker exited with error?
|
|
58
|
+
await (0, _events.once)(worker, 'exit');
|
|
59
59
|
}
|
|
@@ -8,7 +8,7 @@ exports.getConfigFromEnv = getConfigFromEnv;
|
|
|
8
8
|
exports.getEnvConfigs = getEnvConfigs;
|
|
9
9
|
exports.saveConfigToEnv = saveConfigToEnv;
|
|
10
10
|
var _path = _interopRequireDefault(require("path"));
|
|
11
|
-
var
|
|
11
|
+
var _utils = require("../utils");
|
|
12
12
|
/**
|
|
13
13
|
* Storing configs in env var PLAYWRIGHT_BDD_CONFIGS as JSON-stringified values.
|
|
14
14
|
* For passing configs to playwright workers and bddgen.
|
|
@@ -22,7 +22,7 @@ function saveConfigToEnv(config) {
|
|
|
22
22
|
// Throw error only if different calls of defineBddConfig() use the same outputDir.
|
|
23
23
|
// See: https://github.com/vitalets/playwright-bdd/issues/39#issuecomment-1653805368
|
|
24
24
|
if (!isSameConfigs(config, existingConfig)) {
|
|
25
|
-
(0,
|
|
25
|
+
(0, _utils.exitWithMessage)(`When using several calls of defineBddConfig()`, `please manually provide different "outputDir" option.`);
|
|
26
26
|
}
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
@@ -34,7 +34,7 @@ function getConfigFromEnv(outputDir) {
|
|
|
34
34
|
outputDir = _path.default.resolve(outputDir);
|
|
35
35
|
const config = envConfigs[outputDir];
|
|
36
36
|
if (!config) {
|
|
37
|
-
(0,
|
|
37
|
+
(0, _utils.exitWithMessage)(`Config not found for outputDir: "${outputDir}".`, `Available dirs: ${Object.keys(envConfigs).join('\n')}`);
|
|
38
38
|
}
|
|
39
39
|
return config;
|
|
40
40
|
}
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.loadFeatures = loadFeatures;
|
|
7
7
|
var _loadSources = require("./loadSources");
|
|
8
|
-
var
|
|
8
|
+
var _utils = require("../utils");
|
|
9
9
|
async function loadFeatures(runConfiguration, environment) {
|
|
10
10
|
const {
|
|
11
11
|
filteredPickles,
|
|
@@ -34,6 +34,6 @@ function handleParseErrors(parseErrors) {
|
|
|
34
34
|
const message = parseErrors.map(parseError => {
|
|
35
35
|
return `Parse error in "${parseError.source.uri}" ${parseError.message}`;
|
|
36
36
|
}).join('\n');
|
|
37
|
-
(0,
|
|
37
|
+
(0, _utils.exitWithMessage)(message);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -7,8 +7,8 @@ exports.findStepDefinition = findStepDefinition;
|
|
|
7
7
|
exports.hasTsNodeRegister = hasTsNodeRegister;
|
|
8
8
|
exports.loadSteps = loadSteps;
|
|
9
9
|
var _api = require("@cucumber/cucumber/api");
|
|
10
|
+
var _utils = require("../utils");
|
|
10
11
|
var _transform = require("../playwright/transform");
|
|
11
|
-
var _exit = require("../utils/exit");
|
|
12
12
|
const cache = new Map();
|
|
13
13
|
async function loadSteps(runConfiguration, environment = {}) {
|
|
14
14
|
const cacheKey = JSON.stringify(runConfiguration);
|
|
@@ -26,7 +26,7 @@ function findStepDefinition(supportCodeLibrary, stepText, file) {
|
|
|
26
26
|
return step.matchesStepName(stepText);
|
|
27
27
|
});
|
|
28
28
|
if (matchedSteps.length === 0) return;
|
|
29
|
-
if (matchedSteps.length > 1) (0,
|
|
29
|
+
if (matchedSteps.length > 1) (0, _utils.exitWithMessage)([`Several step definitions found for text: ${stepText} (${file})`, ...matchedSteps.map(s => `- ${s.pattern}`)].join('\n'));
|
|
30
30
|
// todo: check stepDefinition.keyword with PickleStepType
|
|
31
31
|
return matchedSteps[0];
|
|
32
32
|
}
|
|
@@ -13,13 +13,13 @@ var _loadConfig = require("../cucumber/loadConfig");
|
|
|
13
13
|
var _loadFeatures = require("../cucumber/loadFeatures");
|
|
14
14
|
var _loadSteps = require("../cucumber/loadSteps");
|
|
15
15
|
var _config = require("../config");
|
|
16
|
+
var _utils = require("../utils");
|
|
16
17
|
var _snippets = require("../snippets");
|
|
17
18
|
var _steps = require("../stepDefinitions/decorators/steps");
|
|
18
19
|
var _transform = require("../playwright/transform");
|
|
19
20
|
var _dir = require("../config/dir");
|
|
20
21
|
var _logger = require("../utils/logger");
|
|
21
22
|
var _tagExpressions = _interopRequireDefault(require("@cucumber/tag-expressions"));
|
|
22
|
-
var _exit = require("../utils/exit");
|
|
23
23
|
/**
|
|
24
24
|
* Generate playwright test files from Gherkin documents.
|
|
25
25
|
*/
|
|
@@ -41,15 +41,13 @@ class TestFilesGenerator {
|
|
|
41
41
|
if (config.tags) this.tagsExpression = (0, _tagExpressions.default)(config.tags);
|
|
42
42
|
}
|
|
43
43
|
async generate() {
|
|
44
|
-
await
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
await this.saveFiles();
|
|
52
|
-
});
|
|
44
|
+
await this.loadCucumberConfig();
|
|
45
|
+
await Promise.all([this.loadFeatures(), this.loadSteps()]);
|
|
46
|
+
this.buildFiles();
|
|
47
|
+
await this.checkUndefinedSteps();
|
|
48
|
+
this.checkImportCustomTest();
|
|
49
|
+
await this.clearOutputDir();
|
|
50
|
+
await this.saveFiles();
|
|
53
51
|
}
|
|
54
52
|
async extractSteps() {
|
|
55
53
|
await this.loadCucumberConfig();
|
|
@@ -120,7 +118,7 @@ class TestFilesGenerator {
|
|
|
120
118
|
const absFeaturePath = _path.default.resolve(configDir, relFeaturePath);
|
|
121
119
|
const relOutputPath = _path.default.relative(this.config.featuresRoot, absFeaturePath);
|
|
122
120
|
if (relOutputPath.startsWith('..')) {
|
|
123
|
-
(0,
|
|
121
|
+
(0, _utils.exitWithMessage)(`All feature files should be located underneath featuresRoot.`, `Please change featuresRoot or paths in configuration.\n`, `featureFile: ${absFeaturePath}\n`, `featuresRoot: ${this.config.featuresRoot}\n`);
|
|
124
122
|
}
|
|
125
123
|
const absOutputPath = _path.default.resolve(this.config.outputDir, relOutputPath);
|
|
126
124
|
return `${absOutputPath}.spec.js`;
|
|
@@ -129,15 +127,14 @@ class TestFilesGenerator {
|
|
|
129
127
|
const undefinedSteps = this.files.reduce((sum, file) => sum + file.undefinedSteps.length, 0);
|
|
130
128
|
if (undefinedSteps > 0) {
|
|
131
129
|
const snippets = new _snippets.Snippets(this.files, this.runConfiguration, this.supportCodeLibrary);
|
|
132
|
-
await snippets.
|
|
133
|
-
(0, _exit.exit)();
|
|
130
|
+
await snippets.printSnippetsAndExit();
|
|
134
131
|
}
|
|
135
132
|
}
|
|
136
133
|
checkImportCustomTest() {
|
|
137
134
|
if (this.config.importTestFrom) return;
|
|
138
135
|
const hasCustomTest = this.files.some(file => file.hasCustomTest);
|
|
139
136
|
if (hasCustomTest) {
|
|
140
|
-
(0,
|
|
137
|
+
(0, _utils.exitWithMessage)(`When using custom "test" function in createBdd() you should`, `set "importTestFrom" config option that points to file exporting custom test.`);
|
|
141
138
|
}
|
|
142
139
|
}
|
|
143
140
|
async saveFiles() {
|
|
@@ -16,7 +16,6 @@ var _utils = require("../utils");
|
|
|
16
16
|
var _testPoms = require("./testPoms");
|
|
17
17
|
var _testNode = require("./testNode");
|
|
18
18
|
var _stepConfig = require("../stepDefinitions/stepConfig");
|
|
19
|
-
var _exit = require("../utils/exit");
|
|
20
19
|
/**
|
|
21
20
|
* Generate test code.
|
|
22
21
|
*/
|
|
@@ -117,7 +116,7 @@ class TestFile {
|
|
|
117
116
|
throw new Error(`Empty child: ${JSON.stringify(child)}`);
|
|
118
117
|
}
|
|
119
118
|
getScenarioLines(scenario, parent) {
|
|
120
|
-
return
|
|
119
|
+
return isOutline(scenario) ? this.getOutlineSuite(scenario, parent) : this.getTest(scenario, parent);
|
|
121
120
|
}
|
|
122
121
|
/**
|
|
123
122
|
* Generate test.beforeEach for Background
|
|
@@ -294,7 +293,12 @@ class TestFile {
|
|
|
294
293
|
}
|
|
295
294
|
getStepKeyword(step) {
|
|
296
295
|
const origKeyword = step.keyword.trim();
|
|
297
|
-
|
|
296
|
+
let enKeyword;
|
|
297
|
+
if (origKeyword === '*') {
|
|
298
|
+
enKeyword = 'And';
|
|
299
|
+
} else {
|
|
300
|
+
enKeyword = this.i18nKeywordsMap ? this.i18nKeywordsMap.get(origKeyword) : origKeyword;
|
|
301
|
+
}
|
|
298
302
|
if (!enKeyword) throw new Error(`Keyword not found: ${origKeyword}`);
|
|
299
303
|
return enKeyword;
|
|
300
304
|
}
|
|
@@ -308,7 +312,7 @@ class TestFile {
|
|
|
308
312
|
if (resolvedFixtures.length !== 1) {
|
|
309
313
|
const suggestedTags = resolvedFixtures.filter(f => !f.byTag).map(f => (0, _testPoms.buildFixtureTag)(f.name)).join(', ');
|
|
310
314
|
const suggestedTagsStr = suggestedTags.length ? ` or set one of the following tags: ${suggestedTags}` : '.';
|
|
311
|
-
(0,
|
|
315
|
+
(0, _utils.exitWithMessage)(`Can't guess fixture for decorator step "${pickleStep.text}" in file: ${this.sourceFile}.`, `Please refactor your Page Object classes${suggestedTagsStr}`);
|
|
312
316
|
}
|
|
313
317
|
const fixtureName = resolvedFixtures[0].name;
|
|
314
318
|
return {
|
|
@@ -345,12 +349,8 @@ class TestFile {
|
|
|
345
349
|
// see: https://github.com/cucumber/tag-expressions/tree/main/javascript
|
|
346
350
|
return ((_this$options$tagsExp = this.options.tagsExpression) === null || _this$options$tagsExp === void 0 ? void 0 : _this$options$tagsExp.evaluate(node.tags)) === false;
|
|
347
351
|
}
|
|
348
|
-
isOutline(scenario) {
|
|
349
|
-
const keyword = this.getEnglishKeyword(scenario.keyword);
|
|
350
|
-
return keyword === 'ScenarioOutline' || keyword === 'Scenario Outline' || keyword === 'Scenario Template';
|
|
351
|
-
}
|
|
352
|
-
getEnglishKeyword(keyword) {
|
|
353
|
-
return this.i18nKeywordsMap ? this.i18nKeywordsMap.get(keyword) : keyword;
|
|
354
|
-
}
|
|
355
352
|
}
|
|
356
|
-
exports.TestFile = TestFile;
|
|
353
|
+
exports.TestFile = TestFile;
|
|
354
|
+
function isOutline(scenario) {
|
|
355
|
+
return scenario.keyword === 'Scenario Outline' || scenario.keyword === 'Scenario Template';
|
|
356
|
+
}
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.TestPoms = void 0;
|
|
7
7
|
exports.buildFixtureTag = buildFixtureTag;
|
|
8
8
|
var _poms = require("../stepDefinitions/decorators/poms");
|
|
9
|
-
var
|
|
9
|
+
var _utils = require("../utils");
|
|
10
10
|
/**
|
|
11
11
|
* Track PomNodes used in the particular test.
|
|
12
12
|
* To select correct fixture for decorator steps.
|
|
@@ -110,7 +110,7 @@ class TestPoms {
|
|
|
110
110
|
if (!usedPom.byTag) return;
|
|
111
111
|
const childFixturesBySteps = childFixtures.filter(f => !f.byTag);
|
|
112
112
|
if (childFixturesBySteps.length) {
|
|
113
|
-
(0,
|
|
113
|
+
(0, _utils.exitWithMessage)(`Scenario "${this.title}" contains ${childFixturesBySteps.length} step(s)`, `not compatible with required fixture "${pomNode.fixtureName}"`);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
}
|
|
@@ -10,7 +10,7 @@ var _path = _interopRequireDefault(require("path"));
|
|
|
10
10
|
var _fs = _interopRequireDefault(require("fs"));
|
|
11
11
|
var _utils = require("./utils");
|
|
12
12
|
var _transform = require("./transform");
|
|
13
|
-
var
|
|
13
|
+
var _utils2 = require("../utils");
|
|
14
14
|
/**
|
|
15
15
|
* Loading Playwright config.
|
|
16
16
|
* See: https://github.com/microsoft/playwright/blob/main/packages/playwright-test/src/common/configLoader.ts
|
|
@@ -37,6 +37,6 @@ function getConfigFilePath(cliConfigPath) {
|
|
|
37
37
|
function assertConfigFileExists(resolvedConfigFile, cliConfigPath) {
|
|
38
38
|
if (!resolvedConfigFile || !_fs.default.existsSync(resolvedConfigFile)) {
|
|
39
39
|
const configFilePath = getConfigFilePath(cliConfigPath);
|
|
40
|
-
(0,
|
|
40
|
+
(0, _utils2.exitWithMessage)(`Can't find Playwright config file in: ${configFilePath}`);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.getTestImpl = getTestImpl;
|
|
6
7
|
exports.isParentChildTest = isParentChildTest;
|
|
7
|
-
exports.runStepWithCustomLocation = runStepWithCustomLocation;
|
|
8
8
|
var _test = require("@playwright/test");
|
|
9
9
|
var _utils = require("../utils");
|
|
10
10
|
/**
|
|
@@ -22,22 +22,6 @@ function getTestFixtures(test) {
|
|
|
22
22
|
function getTestImpl(test) {
|
|
23
23
|
return test[testTypeSymbol];
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Run step with location pointing to Given, When, Then call.
|
|
27
|
-
*/
|
|
28
|
-
// eslint-disable-next-line max-params
|
|
29
|
-
async function runStepWithCustomLocation(test, stepText, location, body) {
|
|
30
|
-
const testInfo = test.info();
|
|
31
|
-
// See: https://github.com/microsoft/playwright/blob/main/packages/playwright/src/common/testType.ts#L221
|
|
32
|
-
// @ts-expect-error _runAsStep is hidden from public
|
|
33
|
-
return testInfo._runAsStep({
|
|
34
|
-
category: 'test.step',
|
|
35
|
-
title: stepText,
|
|
36
|
-
location
|
|
37
|
-
}, async () => {
|
|
38
|
-
return await body();
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
25
|
/**
|
|
42
26
|
* Returns true if all fixtures of parent test found in child test.
|
|
43
27
|
*/
|
|
@@ -27,8 +27,7 @@ class BddWorld extends _cucumber.World {
|
|
|
27
27
|
// attach custom fixtures to world - the only way to pass them to cucumber step fn
|
|
28
28
|
this.customFixtures = customFixtures;
|
|
29
29
|
const code = (0, _defineStep.getStepCode)(stepDefinition);
|
|
30
|
-
//
|
|
31
|
-
// This call must be exactly here to have correct call stack.
|
|
30
|
+
// get location of step call in generated test file
|
|
32
31
|
const location = (0, _getLocationInFile.getLocationInFile)(this.test.info().file);
|
|
33
32
|
const {
|
|
34
33
|
parameters
|
|
@@ -40,7 +39,7 @@ class BddWorld extends _cucumber.World {
|
|
|
40
39
|
},
|
|
41
40
|
world: this
|
|
42
41
|
});
|
|
43
|
-
const res = await (0, _testTypeImpl.
|
|
42
|
+
const res = await (0, _testTypeImpl.getTestImpl)(this.test)._step(location, text, () => code.apply(this, parameters));
|
|
44
43
|
delete this.customFixtures;
|
|
45
44
|
return res;
|
|
46
45
|
}
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.Snippets = void 0;
|
|
7
7
|
var _loadSnippetBuilder = require("../cucumber/loadSnippetBuilder");
|
|
8
|
+
var _utils = require("../utils");
|
|
8
9
|
var _logger = require("../utils/logger");
|
|
9
10
|
var _stepConfig = require("../stepDefinitions/stepConfig");
|
|
10
11
|
/**
|
|
@@ -22,15 +23,13 @@ class Snippets {
|
|
|
22
23
|
this.runConfiguration = runConfiguration;
|
|
23
24
|
this.supportCodeLibrary = supportCodeLibrary;
|
|
24
25
|
}
|
|
25
|
-
async
|
|
26
|
+
async printSnippetsAndExit() {
|
|
26
27
|
this.snippetBuilder = await this.createSnippetBuilder();
|
|
27
28
|
const snippets = this.getSnippets();
|
|
28
29
|
this.printHeader();
|
|
29
30
|
this.printSnippets(snippets);
|
|
30
31
|
this.printFooter(snippets);
|
|
31
|
-
// exit();
|
|
32
32
|
}
|
|
33
|
-
|
|
34
33
|
async createSnippetBuilder() {
|
|
35
34
|
const {
|
|
36
35
|
snippetInterface
|
|
@@ -118,18 +117,15 @@ class Snippets {
|
|
|
118
117
|
_logger.logger.error(snippets.concat(['']).join('\n\n'));
|
|
119
118
|
}
|
|
120
119
|
printFooter(snippets) {
|
|
121
|
-
|
|
122
|
-
this.printWarningOnZeroScannedFiles();
|
|
120
|
+
(0, _utils.exitWithMessage)(`Missing step definitions (${snippets.length}).`, 'Use snippets above to create them.', this.getWarnOnZeroScannedFiles());
|
|
123
121
|
}
|
|
124
|
-
|
|
122
|
+
getWarnOnZeroScannedFiles() {
|
|
125
123
|
const {
|
|
126
124
|
requirePaths,
|
|
127
125
|
importPaths
|
|
128
126
|
} = this.supportCodeLibrary.originalCoordinates;
|
|
129
127
|
const scannedFilesCount = requirePaths.length + importPaths.length;
|
|
130
|
-
|
|
131
|
-
_logger.logger.error(`Note that 0 step definition files found, check the config.`);
|
|
132
|
-
}
|
|
128
|
+
return scannedFilesCount === 0 && !this.isDecorators() ? `\nNote that 0 step definition files found, check the config.` : '';
|
|
133
129
|
}
|
|
134
130
|
}
|
|
135
131
|
exports.Snippets = Snippets;
|
|
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.createBdd = createBdd;
|
|
7
7
|
exports.extractFixtureNames = extractFixtureNames;
|
|
8
8
|
var _fixtureParameterNames = require("../playwright/fixtureParameterNames");
|
|
9
|
+
var _utils = require("../utils");
|
|
9
10
|
var _bddFixtures = require("../run/bddFixtures");
|
|
10
11
|
var _testTypeImpl = require("../playwright/testTypeImpl");
|
|
11
12
|
var _defineStep = require("./defineStep");
|
|
12
|
-
var _exit = require("../utils/exit");
|
|
13
13
|
/**
|
|
14
14
|
* Stuff related to writing steps in Playwright-style.
|
|
15
15
|
*/
|
|
@@ -43,7 +43,7 @@ function extractFixtureNames(fn) {
|
|
|
43
43
|
function isCustomTest(customTest) {
|
|
44
44
|
const isCustomTest = Boolean(customTest && customTest !== _bddFixtures.test);
|
|
45
45
|
if (isCustomTest && customTest && !(0, _testTypeImpl.isParentChildTest)(_bddFixtures.test, customTest)) {
|
|
46
|
-
(0,
|
|
46
|
+
(0, _utils.exitWithMessage)(`createBdd() should use test extended from "playwright-bdd"`);
|
|
47
47
|
}
|
|
48
48
|
return isCustomTest;
|
|
49
49
|
}
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.Fixture = Fixture;
|
|
7
7
|
exports.getPomNodeByFixtureName = getPomNodeByFixtureName;
|
|
8
8
|
var _steps = require("./steps");
|
|
9
|
-
var _exit = require("../../utils/exit");
|
|
10
9
|
/**
|
|
11
10
|
* POM classes marked with @Fixture
|
|
12
11
|
*/
|
|
@@ -21,38 +20,25 @@ const pomGraph = new Map();
|
|
|
21
20
|
*/
|
|
22
21
|
function Fixture(fixtureName) {
|
|
23
22
|
// context parameter is required for decorator by TS even though it's not used
|
|
24
|
-
|
|
23
|
+
// eslint-disable-next-line no-unused-vars
|
|
24
|
+
return (Ctor, _context) => {
|
|
25
25
|
createPomNode(Ctor, fixtureName);
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
function createPomNode(Ctor, fixtureName) {
|
|
29
29
|
const pomNode = {
|
|
30
30
|
fixtureName,
|
|
31
|
-
className: Ctor.name,
|
|
32
31
|
children: new Set()
|
|
33
32
|
};
|
|
34
|
-
ensureUniqueFixtureName(pomNode);
|
|
35
33
|
pomGraph.set(Ctor, pomNode);
|
|
36
34
|
(0, _steps.linkStepsWithPomNode)(Ctor, pomNode);
|
|
37
35
|
linkParentWithPomNode(Ctor, pomNode);
|
|
38
36
|
return pomNode;
|
|
39
37
|
}
|
|
40
|
-
function ensureUniqueFixtureName({
|
|
41
|
-
fixtureName,
|
|
42
|
-
className
|
|
43
|
-
}) {
|
|
44
|
-
if (!fixtureName) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const existingPom = getPomNodeByFixtureName(fixtureName);
|
|
48
|
-
if (existingPom) {
|
|
49
|
-
(0, _exit.exit)(`Duplicate fixture name "${fixtureName}"`, `defined for classes: ${existingPom.className}, ${className}`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
38
|
function linkParentWithPomNode(Ctor, pomNode) {
|
|
53
39
|
const parentCtor = Object.getPrototypeOf(Ctor);
|
|
54
40
|
if (!parentCtor) return;
|
|
55
|
-
// if parentCtor is not in pomGraph, add it
|
|
41
|
+
// if parentCtor is not in pomGraph, add it as well
|
|
56
42
|
// Case: parent class is not marked with @Fixture, but has decorator steps (base class)
|
|
57
43
|
const parentPomNode = pomGraph.get(parentCtor) || createPomNode(parentCtor, '');
|
|
58
44
|
parentPomNode.children.add(pomNode);
|
|
@@ -7,7 +7,7 @@ exports.buildCucumberStepCode = buildCucumberStepCode;
|
|
|
7
7
|
exports.defineStep = defineStep;
|
|
8
8
|
exports.getStepCode = getStepCode;
|
|
9
9
|
var _cucumber = require("@cucumber/cucumber");
|
|
10
|
-
var
|
|
10
|
+
var _utils = require("../utils");
|
|
11
11
|
/**
|
|
12
12
|
* Defines step by config.
|
|
13
13
|
* Calls cucumber's Given(), When(), Then() under the hood.
|
|
@@ -26,7 +26,7 @@ function defineStep(stepConfig) {
|
|
|
26
26
|
// and skip/delay registering cucumber steps until cucumber is loaded
|
|
27
27
|
const isMissingCucumber = /Cucumber that isn't running/i.test(e.message);
|
|
28
28
|
if (isMissingCucumber) {
|
|
29
|
-
(0,
|
|
29
|
+
(0, _utils.exitWithMessage)(`Option "importTestFrom" should point to separate file without step definitions`, `(e.g. without calls of Given, When, Then)`);
|
|
30
30
|
} else {
|
|
31
31
|
throw e;
|
|
32
32
|
}
|
|
@@ -4,6 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
+
exports.exitWithMessage = exitWithMessage;
|
|
7
8
|
exports.getPackageVersion = getPackageVersion;
|
|
8
9
|
exports.getSymbolByName = getSymbolByName;
|
|
9
10
|
exports.removeDuplicates = removeDuplicates;
|
|
@@ -11,6 +12,11 @@ exports.resolvePackageRoot = resolvePackageRoot;
|
|
|
11
12
|
exports.template = template;
|
|
12
13
|
var _fs = _interopRequireDefault(require("fs"));
|
|
13
14
|
var _path = _interopRequireDefault(require("path"));
|
|
15
|
+
var _logger = require("./logger");
|
|
16
|
+
function exitWithMessage(...messages) {
|
|
17
|
+
_logger.logger.error('ERROR:', ...messages.filter(Boolean));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
14
20
|
// See: https://stackoverflow.com/questions/50453640/how-can-i-get-the-value-of-a-symbol-property
|
|
15
21
|
function getSymbolByName(target, name) {
|
|
16
22
|
const ownKeys = Reflect.ownKeys(target);
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zohodesk/testinglibrary",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.0-exp.4",
|
|
4
4
|
"lockfileVersion": 1,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"dependencies": {
|
|
@@ -2577,22 +2577,13 @@
|
|
|
2577
2577
|
"integrity": "sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q=="
|
|
2578
2578
|
},
|
|
2579
2579
|
"@playwright/test": {
|
|
2580
|
-
"version": "1.
|
|
2581
|
-
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.
|
|
2582
|
-
"integrity": "sha512-
|
|
2580
|
+
"version": "1.37.1",
|
|
2581
|
+
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz",
|
|
2582
|
+
"integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==",
|
|
2583
2583
|
"requires": {
|
|
2584
|
-
"
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
"playwright": {
|
|
2588
|
-
"version": "1.39.0",
|
|
2589
|
-
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz",
|
|
2590
|
-
"integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==",
|
|
2591
|
-
"requires": {
|
|
2592
|
-
"fsevents": "2.3.2",
|
|
2593
|
-
"playwright-core": "1.39.0"
|
|
2594
|
-
}
|
|
2595
|
-
}
|
|
2584
|
+
"@types/node": "*",
|
|
2585
|
+
"fsevents": "2.3.2",
|
|
2586
|
+
"playwright-core": "1.37.1"
|
|
2596
2587
|
}
|
|
2597
2588
|
},
|
|
2598
2589
|
"@sinclair/typebox": {
|
|
@@ -6724,9 +6715,9 @@
|
|
|
6724
6715
|
}
|
|
6725
6716
|
},
|
|
6726
6717
|
"playwright-core": {
|
|
6727
|
-
"version": "1.
|
|
6728
|
-
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.
|
|
6729
|
-
"integrity": "sha512
|
|
6718
|
+
"version": "1.37.1",
|
|
6719
|
+
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz",
|
|
6720
|
+
"integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA=="
|
|
6730
6721
|
},
|
|
6731
6722
|
"pretty-format": {
|
|
6732
6723
|
"version": "29.7.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zohodesk/testinglibrary",
|
|
3
|
-
"version": "0.1.1
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@babel/preset-react": "7.22.5",
|
|
24
24
|
"@cucumber/cucumber": "9.2.0",
|
|
25
|
-
"@playwright/test": "1.
|
|
25
|
+
"@playwright/test": "1.37.1",
|
|
26
26
|
"@testing-library/jest-dom": "5.11.9",
|
|
27
27
|
"@testing-library/react": "11.2.7",
|
|
28
28
|
"@testing-library/react-hooks": "7.0.2",
|
|
@@ -51,4 +51,4 @@
|
|
|
51
51
|
"@babel/preset-env": "7.22.15",
|
|
52
52
|
"@babel/runtime": "7.22.15"
|
|
53
53
|
}
|
|
54
|
-
}
|
|
54
|
+
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.exit = exit;
|
|
7
|
-
exports.withExitHandler = withExitHandler;
|
|
8
|
-
var _logger = require("./logger");
|
|
9
|
-
var _worker_threads = require("worker_threads");
|
|
10
|
-
/**
|
|
11
|
-
* Exit utils.
|
|
12
|
-
*
|
|
13
|
-
* When calling process.exit() in worker thread used for file generation,
|
|
14
|
-
* logs are not flushed (https://github.com/vitalets/playwright-bdd/issues/59).
|
|
15
|
-
* That's why instead of process.exit we throw ExitError
|
|
16
|
-
* that just sets process.exitCode = 1 and allow program to exit normally.
|
|
17
|
-
*
|
|
18
|
-
* On the other hand, when running in main thread, especially inside Playwright,
|
|
19
|
-
* thrown error is captured by Playwright and show with additional messages (e.g. no tests found).
|
|
20
|
-
* That's why in main thread we to call process.exit() to show only needed error.
|
|
21
|
-
*
|
|
22
|
-
* Relevant discussions:
|
|
23
|
-
* - https://github.com/nodejs/node/issues/6379
|
|
24
|
-
* - https://github.com/nodejs/node-v0.x-archive/issues/3737
|
|
25
|
-
* - https://github.com/cucumber/cucumber-js/pull/123
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
class ExitError extends Error {
|
|
29
|
-
get stack() {
|
|
30
|
-
return '';
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
async function withExitHandler(fn) {
|
|
34
|
-
try {
|
|
35
|
-
return await fn();
|
|
36
|
-
} catch (e) {
|
|
37
|
-
if (e instanceof ExitError) {
|
|
38
|
-
process.exitCode = 1;
|
|
39
|
-
} else {
|
|
40
|
-
throw e;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function exit(...messages) {
|
|
45
|
-
messages = messages.filter(Boolean);
|
|
46
|
-
if (_worker_threads.isMainThread) {
|
|
47
|
-
if (messages.length) _logger.logger.error('Error:', ...messages);
|
|
48
|
-
process.exit(1);
|
|
49
|
-
} else {
|
|
50
|
-
throw new ExitError(messages.join(' '));
|
|
51
|
-
}
|
|
52
|
-
}
|