@zohodesk/testinglibrary 0.0.5 → 0.0.7
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 +19 -0
- package/.eslintrc.js +27 -0
- package/.prettierrc +6 -0
- package/{changelog.md → Changelog.md} +42 -25
- package/README.md +17 -17
- package/bin/cli.js +2 -2
- package/bin/postinstall.js +1 -16
- package/build/bdd-framework/cli/commands/env.js +43 -0
- package/build/bdd-framework/cli/commands/export.js +48 -0
- package/build/bdd-framework/cli/commands/test.js +59 -0
- package/build/bdd-framework/cli/index.js +11 -0
- package/build/bdd-framework/cli/options.js +20 -0
- package/build/bdd-framework/cli/worker.js +13 -0
- package/build/bdd-framework/config/dir.js +27 -0
- package/build/bdd-framework/config/env.js +49 -0
- package/build/bdd-framework/config/index.js +91 -0
- package/build/bdd-framework/cucumber/buildStepDefinition.js +43 -0
- package/build/bdd-framework/cucumber/gherkin.d.js +5 -0
- package/build/bdd-framework/cucumber/gherkin.d.ts +45 -0
- package/build/bdd-framework/cucumber/loadConfig.js +17 -0
- package/build/bdd-framework/cucumber/loadFeatures.js +39 -0
- package/build/bdd-framework/cucumber/loadSnippetBuilder.js +20 -0
- package/build/bdd-framework/cucumber/loadSources.js +57 -0
- package/build/bdd-framework/cucumber/loadSteps.js +35 -0
- package/build/bdd-framework/decorators.js +22 -0
- package/build/bdd-framework/gen/formatter.js +88 -0
- package/build/bdd-framework/gen/i18n.js +35 -0
- package/build/bdd-framework/gen/index.js +160 -0
- package/build/bdd-framework/gen/poms.js +46 -0
- package/build/bdd-framework/gen/testFile.js +356 -0
- package/build/bdd-framework/gen/testNode.js +48 -0
- package/build/bdd-framework/gen/testPoms.js +123 -0
- package/build/bdd-framework/index.js +45 -0
- package/build/bdd-framework/playwright/fixtureParameterNames.js +77 -0
- package/build/bdd-framework/playwright/getLocationInFile.js +46 -0
- package/build/bdd-framework/playwright/loadConfig.js +42 -0
- package/build/bdd-framework/playwright/testTypeImpl.js +41 -0
- package/build/bdd-framework/playwright/transform.js +80 -0
- package/build/bdd-framework/playwright/types.js +5 -0
- package/build/bdd-framework/playwright/utils.js +34 -0
- package/build/bdd-framework/run/bddFixtures.js +108 -0
- package/build/bdd-framework/run/bddWorld.js +87 -0
- package/build/bdd-framework/snippets/index.js +131 -0
- package/build/bdd-framework/snippets/snippetSyntax.js +41 -0
- package/build/bdd-framework/snippets/snippetSyntaxDecorators.js +26 -0
- package/build/bdd-framework/snippets/snippetSyntaxTs.js +18 -0
- package/build/bdd-framework/stepDefinitions/createBdd.js +49 -0
- package/build/bdd-framework/stepDefinitions/createDecorators.js +109 -0
- package/build/bdd-framework/stepDefinitions/decorators/poms.js +50 -0
- package/build/bdd-framework/stepDefinitions/decorators/steps.js +94 -0
- package/build/bdd-framework/stepDefinitions/defineStep.js +61 -0
- package/build/bdd-framework/stepDefinitions/stepConfig.js +24 -0
- package/build/bdd-framework/utils/index.js +50 -0
- package/build/bdd-framework/utils/jsStringWrap.js +44 -0
- package/build/bdd-framework/utils/logger.js +29 -0
- package/build/core/jest/preprocessor/jsPreprocessor.js +13 -0
- package/{src → build}/core/jest/runner/jest-runner.js +46 -44
- package/build/core/jest/setup/index.js +9 -0
- package/build/core/playwright/codegen.js +55 -0
- package/build/core/playwright/custom-commands.js +8 -0
- package/build/core/playwright/env-initializer.js +21 -0
- package/{src → build}/core/playwright/index.js +112 -82
- package/build/core/playwright/readConfigFile.js +69 -0
- package/build/core/playwright/report-generator.js +41 -0
- package/build/core/playwright/setup/config-creator.js +117 -0
- package/build/core/playwright/test-runner.js +132 -0
- package/build/decorators.d.ts +1 -0
- package/build/decorators.js +16 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +59 -0
- package/build/lib/cli.js +54 -0
- package/build/lib/post-install.js +17 -0
- package/build/lint/index.js +4 -0
- package/build/parser/parser.js +206 -0
- package/build/parser/sample.feature +34 -0
- package/build/parser/sample.spec.js +37 -0
- package/build/parser/verifier.js +130 -0
- package/build/setup-folder-structure/samples/auth-setup-sample.js +72 -0
- package/build/setup-folder-structure/samples/authUsers-sample.json +9 -0
- package/build/setup-folder-structure/samples/env-config-sample.json +21 -0
- package/build/setup-folder-structure/samples/git-ignore.sample.js +33 -0
- package/build/setup-folder-structure/samples/uat-config-sample.js +35 -0
- package/build/setup-folder-structure/setupProject.js +100 -0
- package/{src → build}/utils/cliArgsToObject.js +65 -63
- package/build/utils/fileUtils.js +53 -0
- package/build/utils/getFilePath.js +11 -0
- package/build/utils/logger.js +58 -0
- package/build/utils/rootPath.js +46 -0
- package/build/utils/stepDefinitionsFormatter.js +12 -0
- package/jest.config.js +63 -63
- package/npm-shrinkwrap.json +8790 -5772
- package/package.json +53 -30
- package/playwright.config.js +112 -112
- package/src/core/jest/preprocessor/jsPreprocessor.js +0 -9
- package/src/core/jest/setup/index.js +0 -165
- package/src/core/playwright/codegen.js +0 -60
- package/src/core/playwright/custom-commands.js +0 -3
- package/src/core/playwright/env-initializer.js +0 -24
- package/src/core/playwright/readConfigFile.js +0 -63
- package/src/core/playwright/report-generator.js +0 -45
- package/src/core/playwright/setup/config-creator.js +0 -77
- package/src/core/playwright/test-runner.js +0 -67
- package/src/index.js +0 -9
- package/src/lib/cli.js +0 -42
- package/src/setup-folder-structure/env-config-sample.json +0 -17
- package/src/setup-folder-structure/setupProject.js +0 -99
- package/src/setup-folder-structure/uat-config-sample.js +0 -22
- package/src/setup-folder-structure/user-example.json +0 -3
- package/src/utils/getFilePath.js +0 -9
- package/src/utils/logger.js +0 -28
- package/src/utils/rootPath.js +0 -51
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.loadFeatures = loadFeatures;
|
|
7
|
+
var _loadSources = require("./loadSources");
|
|
8
|
+
var _utils = require("../utils");
|
|
9
|
+
async function loadFeatures(runConfiguration, environment) {
|
|
10
|
+
const {
|
|
11
|
+
filteredPickles,
|
|
12
|
+
parseErrors
|
|
13
|
+
} = await (0, _loadSources.loadSources)(runConfiguration.sources, environment);
|
|
14
|
+
handleParseErrors(parseErrors);
|
|
15
|
+
return groupByDocument(filteredPickles);
|
|
16
|
+
}
|
|
17
|
+
function groupByDocument(filteredPickles) {
|
|
18
|
+
const features = new Map();
|
|
19
|
+
filteredPickles.forEach(({
|
|
20
|
+
pickle,
|
|
21
|
+
gherkinDocument
|
|
22
|
+
}) => {
|
|
23
|
+
let pickles = features.get(gherkinDocument);
|
|
24
|
+
if (!pickles) {
|
|
25
|
+
pickles = [];
|
|
26
|
+
features.set(gherkinDocument, pickles);
|
|
27
|
+
}
|
|
28
|
+
pickles.push(pickle);
|
|
29
|
+
});
|
|
30
|
+
return features;
|
|
31
|
+
}
|
|
32
|
+
function handleParseErrors(parseErrors) {
|
|
33
|
+
if (parseErrors.length) {
|
|
34
|
+
const message = parseErrors.map(parseError => {
|
|
35
|
+
return `Parse error in "${parseError.source.uri}" ${parseError.message}`;
|
|
36
|
+
}).join('\n');
|
|
37
|
+
(0, _utils.exitWithMessage)(message);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.loadSnippetBuilder = loadSnippetBuilder;
|
|
7
|
+
var _cucumber = require("@cucumber/cucumber");
|
|
8
|
+
/**
|
|
9
|
+
* Loads snippet builder
|
|
10
|
+
* See: https://github.com/cucumber/cucumber-js/blob/main/src/formatter/builder.ts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
async function loadSnippetBuilder(supportCodeLibrary, snippetInterface, snippetSyntax) {
|
|
14
|
+
return _cucumber.FormatterBuilder.getStepDefinitionSnippetBuilder({
|
|
15
|
+
cwd: process.cwd(),
|
|
16
|
+
snippetInterface,
|
|
17
|
+
snippetSyntax,
|
|
18
|
+
supportCodeLibrary
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.loadSources = loadSources;
|
|
7
|
+
var _paths = require("@cucumber/cucumber/lib/api/paths");
|
|
8
|
+
var _messages = require("@cucumber/messages");
|
|
9
|
+
var _environment = require("@cucumber/cucumber/lib/api/environment");
|
|
10
|
+
var _gherkin = require("@cucumber/cucumber/lib/api/gherkin");
|
|
11
|
+
var _console_logger = require("@cucumber/cucumber/lib/api/console_logger");
|
|
12
|
+
/**
|
|
13
|
+
* Copied from original load_sources, but returns full Pickles.
|
|
14
|
+
* See: https://github.com/cucumber/cucumber-js/blob/main/src/api/load_sources.ts
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Load and parse features, produce a filtered and ordered test plan and/or parse errors.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
* @param coordinates - Coordinates required to find features
|
|
22
|
+
* @param environment - Project environment.
|
|
23
|
+
*/
|
|
24
|
+
async function loadSources(coordinates, environment = {}) {
|
|
25
|
+
const {
|
|
26
|
+
cwd,
|
|
27
|
+
stderr,
|
|
28
|
+
debug
|
|
29
|
+
} = (0, _environment.mergeEnvironment)(environment);
|
|
30
|
+
const logger = new _console_logger.ConsoleLogger(stderr, debug);
|
|
31
|
+
const newId = _messages.IdGenerator.uuid();
|
|
32
|
+
const {
|
|
33
|
+
unexpandedFeaturePaths,
|
|
34
|
+
featurePaths
|
|
35
|
+
} = await (0, _paths.resolvePaths)(logger, cwd, coordinates);
|
|
36
|
+
if (featurePaths.length === 0) {
|
|
37
|
+
return {
|
|
38
|
+
filteredPickles: [],
|
|
39
|
+
parseErrors: []
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const {
|
|
43
|
+
filteredPickles,
|
|
44
|
+
parseErrors
|
|
45
|
+
} = await (0, _gherkin.getFilteredPicklesAndErrors)({
|
|
46
|
+
newId,
|
|
47
|
+
cwd,
|
|
48
|
+
logger,
|
|
49
|
+
unexpandedFeaturePaths,
|
|
50
|
+
featurePaths,
|
|
51
|
+
coordinates
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
filteredPickles,
|
|
55
|
+
parseErrors
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.findStepDefinition = findStepDefinition;
|
|
7
|
+
exports.hasTsNodeRegister = hasTsNodeRegister;
|
|
8
|
+
exports.loadSteps = loadSteps;
|
|
9
|
+
var _api = require("@cucumber/cucumber/api");
|
|
10
|
+
var _utils = require("../utils");
|
|
11
|
+
var _transform = require("../playwright/transform");
|
|
12
|
+
const cache = new Map();
|
|
13
|
+
async function loadSteps(runConfiguration, environment = {}) {
|
|
14
|
+
const cacheKey = JSON.stringify(runConfiguration);
|
|
15
|
+
let lib = cache.get(cacheKey);
|
|
16
|
+
if (!lib) {
|
|
17
|
+
// use Playwright's built-in hook to compile TypeScript steps
|
|
18
|
+
const uninstall = !hasTsNodeRegister(runConfiguration) ? (0, _transform.installTransform)() : () => {};
|
|
19
|
+
lib = (0, _api.loadSupport)(runConfiguration, environment).finally(() => uninstall());
|
|
20
|
+
cache.set(cacheKey, lib);
|
|
21
|
+
}
|
|
22
|
+
return lib;
|
|
23
|
+
}
|
|
24
|
+
function findStepDefinition(supportCodeLibrary, stepText, file) {
|
|
25
|
+
const matchedSteps = supportCodeLibrary.stepDefinitions.filter(step => {
|
|
26
|
+
return step.matchesStepName(stepText);
|
|
27
|
+
});
|
|
28
|
+
if (matchedSteps.length === 0) return;
|
|
29
|
+
if (matchedSteps.length > 1) (0, _utils.exitWithMessage)([`Several step definitions found for text: ${stepText} (${file})`, ...matchedSteps.map(s => `- ${s.pattern}`)].join('\n'));
|
|
30
|
+
// todo: check stepDefinition.keyword with PickleStepType
|
|
31
|
+
return matchedSteps[0];
|
|
32
|
+
}
|
|
33
|
+
function hasTsNodeRegister(runConfiguration) {
|
|
34
|
+
return runConfiguration.support.requireModules.includes('ts-node/register');
|
|
35
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "Fixture", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _poms.Fixture;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
exports.When = exports.Then = exports.Step = exports.Given = void 0;
|
|
13
|
+
var _poms = require("./stepDefinitions/decorators/poms");
|
|
14
|
+
var _steps = require("./stepDefinitions/decorators/steps");
|
|
15
|
+
const Given = (0, _steps.createStepDecorator)('Given');
|
|
16
|
+
exports.Given = Given;
|
|
17
|
+
const When = (0, _steps.createStepDecorator)('When');
|
|
18
|
+
exports.When = When;
|
|
19
|
+
const Then = (0, _steps.createStepDecorator)('Then');
|
|
20
|
+
exports.Then = Then;
|
|
21
|
+
const Step = (0, _steps.createStepDecorator)('Unknown');
|
|
22
|
+
exports.Step = Step;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Formatter = void 0;
|
|
7
|
+
var _jsStringWrap = require("../utils/jsStringWrap");
|
|
8
|
+
/**
|
|
9
|
+
* Helper to format Playwright test file.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const TAGS_FIXTURE_TEST_KEY_SEPARATOR = '|';
|
|
13
|
+
class Formatter {
|
|
14
|
+
config;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
}
|
|
18
|
+
fileHeader(uri, importTestFrom) {
|
|
19
|
+
const file = (importTestFrom === null || importTestFrom === void 0 ? void 0 : importTestFrom.file) || '@zohodesk/testinglibrary';
|
|
20
|
+
let varName = (importTestFrom === null || importTestFrom === void 0 ? void 0 : importTestFrom.varName) || 'test';
|
|
21
|
+
if (varName !== 'test') varName = `${varName} as test`;
|
|
22
|
+
return [`/** Generated from: ${uri} */`,
|
|
23
|
+
// this.quoted() is not possible for 'import from' as backticks not parsed
|
|
24
|
+
`import { ${varName} } from ${JSON.stringify(file)};`, ''];
|
|
25
|
+
}
|
|
26
|
+
suite(node, children) {
|
|
27
|
+
// prettier-ignore
|
|
28
|
+
return [`test.describe${this.getSubFn(node)}(${this.quoted(node.title)}, () => {`, '', ...children.map(indent), `});`, ''];
|
|
29
|
+
}
|
|
30
|
+
beforeEach(fixtures, children) {
|
|
31
|
+
const fixturesStr = [...fixtures].join(', ');
|
|
32
|
+
// prettier-ignore
|
|
33
|
+
return [`test.beforeEach(async ({ ${fixturesStr} }) => {`, ...children.map(indent), `});`, ''];
|
|
34
|
+
}
|
|
35
|
+
test(node, fixtures, children) {
|
|
36
|
+
const fixturesStr = [...fixtures].join(', ');
|
|
37
|
+
// prettier-ignore
|
|
38
|
+
return [`test${this.getSubFn(node)}(${this.quoted(node.title)}, async ({ ${fixturesStr} }) => {`, ...children.map(indent), `});`, ''];
|
|
39
|
+
}
|
|
40
|
+
// eslint-disable-next-line max-params
|
|
41
|
+
step(keyword, text, argument, fixtureNames = []) {
|
|
42
|
+
const fixtures = fixtureNames.length ? `{ ${fixtureNames.join(', ')} }` : '';
|
|
43
|
+
const argumentArg = argument ? JSON.stringify(argument) : fixtures ? 'null' : '';
|
|
44
|
+
const textArg = this.quoted(text);
|
|
45
|
+
const args = [textArg, argumentArg, fixtures].filter(arg => arg !== '').join(', ');
|
|
46
|
+
return `await ${keyword}(${args});`;
|
|
47
|
+
}
|
|
48
|
+
missingStep(keyword, text) {
|
|
49
|
+
return `// missing step: ${keyword}(${this.quoted(text)});`;
|
|
50
|
+
}
|
|
51
|
+
useFixtures(fixtures) {
|
|
52
|
+
return fixtures.length > 0 ? ['// == technical section ==', '', 'test.use({', ...fixtures.map(indent), '});'] : [];
|
|
53
|
+
}
|
|
54
|
+
testFixture() {
|
|
55
|
+
return ['$test: ({}, use) => use(test),'];
|
|
56
|
+
}
|
|
57
|
+
tagsFixture(testNodes) {
|
|
58
|
+
const lines = testNodes.filter(node => node.tags.length).map(node => {
|
|
59
|
+
// remove first parent as it is the same for all tests: root suite
|
|
60
|
+
const key = node.titlePath.slice(1).join(TAGS_FIXTURE_TEST_KEY_SEPARATOR);
|
|
61
|
+
return `${JSON.stringify(key)}: ${JSON.stringify(node.tags)},`;
|
|
62
|
+
});
|
|
63
|
+
return lines.length > 0 ? ['$tags: ({}, use, testInfo) => use({', ...lines.map(indent),
|
|
64
|
+
// .slice(2) -> b/c we remove filename and root suite title
|
|
65
|
+
`}[testInfo.titlePath.slice(2).join(${JSON.stringify(TAGS_FIXTURE_TEST_KEY_SEPARATOR)})] || []),`] : [];
|
|
66
|
+
}
|
|
67
|
+
getSubFn(node) {
|
|
68
|
+
if (node.flags.only) return '.only';
|
|
69
|
+
if (node.flags.skip) return '.skip';
|
|
70
|
+
if (node.flags.fixme) return '.fixme';
|
|
71
|
+
return '';
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Apply this function only to string literals (mostly titles here).
|
|
75
|
+
* Objects and arrays are handled with JSON.strinigfy,
|
|
76
|
+
* b/c object keys can't be in backtiks.
|
|
77
|
+
* See: https://stackoverflow.com/questions/33194138/template-string-as-object-property-name
|
|
78
|
+
*/
|
|
79
|
+
quoted(str) {
|
|
80
|
+
return (0, _jsStringWrap.jsStringWrap)(str, {
|
|
81
|
+
quotes: this.config.quotes
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.Formatter = Formatter;
|
|
86
|
+
function indent(value) {
|
|
87
|
+
return value ? `${' '}${value}` : value;
|
|
88
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getKeywordsMap = getKeywordsMap;
|
|
7
|
+
var _gherkin = require("@cucumber/gherkin");
|
|
8
|
+
/**
|
|
9
|
+
* Get i18n keywords.
|
|
10
|
+
* See: https://github.com/cucumber/cucumber-js/blob/main/src/cli/i18n.ts
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
function getKeywordsMap(language) {
|
|
14
|
+
const origMap = _gherkin.dialects[language];
|
|
15
|
+
if (!origMap) {
|
|
16
|
+
throw new Error(`Language not found: ${language}`);
|
|
17
|
+
}
|
|
18
|
+
const targetMap = new Map();
|
|
19
|
+
const enKeywords = Object.keys(origMap);
|
|
20
|
+
enKeywords.forEach(enKeyword => handleKeyword(enKeyword, origMap, targetMap));
|
|
21
|
+
return targetMap;
|
|
22
|
+
}
|
|
23
|
+
function handleKeyword(enKeyword, origMap, targetMap) {
|
|
24
|
+
const nativeKeywords = origMap[enKeyword];
|
|
25
|
+
// Array.isArray converts to any[]
|
|
26
|
+
if (typeof nativeKeywords === 'string') return;
|
|
27
|
+
nativeKeywords.forEach(nativeKeyword => {
|
|
28
|
+
nativeKeyword = nativeKeyword.trim();
|
|
29
|
+
if (!nativeKeyword || nativeKeyword === '*') return;
|
|
30
|
+
targetMap.set(nativeKeyword, capitalizeFirstLetter(enKeyword));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function capitalizeFirstLetter(s) {
|
|
34
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
35
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.TestFilesGenerator = void 0;
|
|
8
|
+
var _promises = _interopRequireDefault(require("fs/promises"));
|
|
9
|
+
var _path = _interopRequireDefault(require("path"));
|
|
10
|
+
var _fastGlob = _interopRequireDefault(require("fast-glob"));
|
|
11
|
+
var _testFile = require("./testFile");
|
|
12
|
+
var _loadConfig = require("../cucumber/loadConfig");
|
|
13
|
+
var _loadFeatures = require("../cucumber/loadFeatures");
|
|
14
|
+
var _loadSteps = require("../cucumber/loadSteps");
|
|
15
|
+
var _config = require("../config");
|
|
16
|
+
var _utils = require("../utils");
|
|
17
|
+
var _snippets = require("../snippets");
|
|
18
|
+
var _steps = require("../stepDefinitions/decorators/steps");
|
|
19
|
+
var _transform = require("../playwright/transform");
|
|
20
|
+
var _dir = require("../config/dir");
|
|
21
|
+
var _logger = require("../utils/logger");
|
|
22
|
+
var _tagExpressions = _interopRequireDefault(require("@cucumber/tag-expressions"));
|
|
23
|
+
/**
|
|
24
|
+
* Generate playwright test files from Gherkin documents.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
class TestFilesGenerator {
|
|
28
|
+
config;
|
|
29
|
+
// all these props are exist
|
|
30
|
+
runConfiguration;
|
|
31
|
+
features;
|
|
32
|
+
supportCodeLibrary;
|
|
33
|
+
files = [];
|
|
34
|
+
tagsExpression;
|
|
35
|
+
logger;
|
|
36
|
+
constructor(config) {
|
|
37
|
+
this.config = config;
|
|
38
|
+
this.logger = new _logger.Logger({
|
|
39
|
+
verbose: config.verbose
|
|
40
|
+
});
|
|
41
|
+
if (config.tags) this.tagsExpression = (0, _tagExpressions.default)(config.tags);
|
|
42
|
+
}
|
|
43
|
+
async generate() {
|
|
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();
|
|
51
|
+
}
|
|
52
|
+
async extractSteps() {
|
|
53
|
+
await this.loadCucumberConfig();
|
|
54
|
+
await this.loadSteps();
|
|
55
|
+
return this.supportCodeLibrary.stepDefinitions;
|
|
56
|
+
}
|
|
57
|
+
async loadCucumberConfig() {
|
|
58
|
+
const environment = {
|
|
59
|
+
cwd: (0, _dir.getPlaywrightConfigDir)()
|
|
60
|
+
};
|
|
61
|
+
const {
|
|
62
|
+
runConfiguration
|
|
63
|
+
} = await (0, _loadConfig.loadConfig)({
|
|
64
|
+
provided: (0, _config.extractCucumberConfig)(this.config)
|
|
65
|
+
}, environment);
|
|
66
|
+
this.runConfiguration = runConfiguration;
|
|
67
|
+
this.warnForTsNodeRegister();
|
|
68
|
+
}
|
|
69
|
+
async loadFeatures() {
|
|
70
|
+
const environment = {
|
|
71
|
+
cwd: (0, _dir.getPlaywrightConfigDir)()
|
|
72
|
+
};
|
|
73
|
+
this.logger.log(`Loading features from: ${this.runConfiguration.sources.paths.join(', ')}`);
|
|
74
|
+
this.features = await (0, _loadFeatures.loadFeatures)(this.runConfiguration, environment);
|
|
75
|
+
this.logger.log(`Loaded features: ${this.features.size}`);
|
|
76
|
+
}
|
|
77
|
+
async loadSteps() {
|
|
78
|
+
const {
|
|
79
|
+
requirePaths,
|
|
80
|
+
importPaths
|
|
81
|
+
} = this.runConfiguration.support;
|
|
82
|
+
this.logger.log(`Loading steps from: ${requirePaths.concat(importPaths).join(', ')}`);
|
|
83
|
+
const environment = {
|
|
84
|
+
cwd: (0, _dir.getPlaywrightConfigDir)()
|
|
85
|
+
};
|
|
86
|
+
this.supportCodeLibrary = await (0, _loadSteps.loadSteps)(this.runConfiguration, environment);
|
|
87
|
+
await this.loadDecoratorSteps();
|
|
88
|
+
this.logger.log(`Loaded steps: ${this.supportCodeLibrary.stepDefinitions.length}`);
|
|
89
|
+
}
|
|
90
|
+
async loadDecoratorSteps() {
|
|
91
|
+
const {
|
|
92
|
+
importTestFrom
|
|
93
|
+
} = this.config;
|
|
94
|
+
if (importTestFrom) {
|
|
95
|
+
// require importTestFrom for case when it is not required by step definitions
|
|
96
|
+
// possible re-require but it's not a problem as it is cached by Node.js
|
|
97
|
+
await (0, _transform.requireTransform)().requireOrImport(importTestFrom.file);
|
|
98
|
+
(0, _steps.appendDecoratorSteps)(this.supportCodeLibrary);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
buildFiles() {
|
|
102
|
+
this.files = [...this.features.entries()].map(([doc, pickles]) => {
|
|
103
|
+
return new _testFile.TestFile({
|
|
104
|
+
doc,
|
|
105
|
+
pickles,
|
|
106
|
+
supportCodeLibrary: this.supportCodeLibrary,
|
|
107
|
+
outputPath: this.getOutputPath(doc),
|
|
108
|
+
config: this.config,
|
|
109
|
+
tagsExpression: this.tagsExpression
|
|
110
|
+
}).build();
|
|
111
|
+
}).filter(file => file.testNodes.length > 0);
|
|
112
|
+
}
|
|
113
|
+
getOutputPath(doc) {
|
|
114
|
+
const configDir = (0, _dir.getPlaywrightConfigDir)();
|
|
115
|
+
// doc.uri is always relative to cwd (coming after cucumber handling)
|
|
116
|
+
// see: https://github.com/cucumber/cucumber-js/blob/main/src/api/gherkin.ts#L51
|
|
117
|
+
const relFeaturePath = doc.uri;
|
|
118
|
+
const absFeaturePath = _path.default.resolve(configDir, relFeaturePath);
|
|
119
|
+
const relOutputPath = _path.default.relative(this.config.featuresRoot, absFeaturePath);
|
|
120
|
+
if (relOutputPath.startsWith('..')) {
|
|
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`);
|
|
122
|
+
}
|
|
123
|
+
const absOutputPath = _path.default.resolve(this.config.outputDir, relOutputPath);
|
|
124
|
+
return `${absOutputPath}.spec.js`;
|
|
125
|
+
}
|
|
126
|
+
async checkUndefinedSteps() {
|
|
127
|
+
const undefinedSteps = this.files.reduce((sum, file) => sum + file.undefinedSteps.length, 0);
|
|
128
|
+
if (undefinedSteps > 0) {
|
|
129
|
+
const snippets = new _snippets.Snippets(this.files, this.runConfiguration, this.supportCodeLibrary);
|
|
130
|
+
await snippets.printSnippetsAndExit();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
checkImportCustomTest() {
|
|
134
|
+
if (this.config.importTestFrom) return;
|
|
135
|
+
const hasCustomTest = this.files.some(file => file.hasCustomTest);
|
|
136
|
+
if (hasCustomTest) {
|
|
137
|
+
(0, _utils.exitWithMessage)(`When using custom "test" function in createBdd() you should`, `set "importTestFrom" config option that points to file exporting custom test.`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async saveFiles() {
|
|
141
|
+
this.files.forEach(file => {
|
|
142
|
+
file.save();
|
|
143
|
+
this.logger.log(`Generated: ${_path.default.relative(process.cwd(), file.outputPath)}`);
|
|
144
|
+
});
|
|
145
|
+
this.logger.log(`Generated files: ${this.files.length}`);
|
|
146
|
+
}
|
|
147
|
+
async clearOutputDir() {
|
|
148
|
+
const pattern = `${_fastGlob.default.convertPathToPattern(this.config.outputDir)}/**/*.spec.js`;
|
|
149
|
+
const testFiles = await (0, _fastGlob.default)(pattern);
|
|
150
|
+
this.logger.log(`Clearing output dir: ${testFiles.length} file(s)`);
|
|
151
|
+
const tasks = testFiles.map(testFile => _promises.default.rm(testFile));
|
|
152
|
+
await Promise.all(tasks);
|
|
153
|
+
}
|
|
154
|
+
warnForTsNodeRegister() {
|
|
155
|
+
if ((0, _loadSteps.hasTsNodeRegister)(this.runConfiguration)) {
|
|
156
|
+
this.logger.warn(`WARNING: usage of requireModule: ['ts-node/register'] is not recommended for playwright-bdd.`, `Remove this option from defineBddConfig() and`, `Playwright's built-in loader will be used to compile TypeScript step definitions.`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
exports.TestFilesGenerator = TestFilesGenerator;
|
|
@@ -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
|
+
}
|