@zohodesk/testinglibrary 0.1.8-stb-bdd-v26 → 0.1.9
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 +21 -18
- package/.eslintrc.js +31 -31
- package/.prettierrc +5 -5
- package/README.md +17 -17
- package/bin/cli.js +2 -2
- package/build/bdd-framework/cli/commands/env.js +42 -0
- package/build/bdd-framework/cli/commands/export.js +47 -0
- package/build/bdd-framework/cli/commands/test.js +64 -0
- package/build/bdd-framework/cli/index.js +11 -0
- package/build/bdd-framework/cli/options.js +19 -0
- package/build/bdd-framework/cli/worker.js +13 -0
- package/build/bdd-framework/config/configDir.js +35 -0
- package/build/bdd-framework/config/enrichReporterData.js +23 -0
- package/build/bdd-framework/config/env.js +50 -0
- package/build/bdd-framework/config/index.js +94 -0
- package/build/bdd-framework/config/lang.js +14 -0
- package/build/bdd-framework/cucumber/buildStepDefinition.js +43 -0
- package/build/bdd-framework/cucumber/createTestStep.js +43 -0
- package/build/bdd-framework/cucumber/formatter/EventDataCollector.js +126 -0
- package/build/bdd-framework/cucumber/formatter/GherkinDocumentParser.js +72 -0
- package/build/bdd-framework/cucumber/formatter/PickleParser.js +25 -0
- package/build/bdd-framework/cucumber/formatter/durationHelpers.js +13 -0
- package/build/bdd-framework/cucumber/formatter/getColorFns.js +57 -0
- package/build/bdd-framework/cucumber/formatter/index.js +16 -0
- package/build/bdd-framework/cucumber/formatter/locationHelpers.js +16 -0
- package/build/bdd-framework/cucumber/loadConfig.js +17 -0
- package/build/bdd-framework/cucumber/loadFeatures.js +70 -0
- package/build/bdd-framework/cucumber/loadSnippetBuilder.js +20 -0
- package/build/bdd-framework/cucumber/loadSteps.js +47 -0
- package/build/bdd-framework/cucumber/resolveFeaturePaths.js +62 -0
- package/build/bdd-framework/cucumber/stepArguments.js +21 -0
- package/build/bdd-framework/cucumber/types.js +5 -0
- package/build/bdd-framework/cucumber/valueChecker.js +23 -0
- package/build/bdd-framework/decorators.js +18 -0
- package/build/bdd-framework/gen/fixtures.js +48 -0
- package/build/bdd-framework/gen/formatter.js +123 -0
- package/build/bdd-framework/gen/i18n.js +39 -0
- package/build/bdd-framework/gen/index.js +185 -0
- package/build/bdd-framework/gen/testFile.js +465 -0
- package/build/bdd-framework/gen/testMeta.js +60 -0
- package/build/bdd-framework/gen/testNode.js +60 -0
- package/build/bdd-framework/gen/testPoms.js +133 -0
- package/build/bdd-framework/hooks/scenario.js +130 -0
- package/build/bdd-framework/hooks/worker.js +89 -0
- package/build/bdd-framework/index.js +52 -0
- package/build/bdd-framework/playwright/fixtureParameterNames.js +93 -0
- package/build/bdd-framework/playwright/getLocationInFile.js +79 -0
- package/build/bdd-framework/playwright/loadConfig.js +42 -0
- package/build/bdd-framework/playwright/loadUtils.js +33 -0
- package/build/bdd-framework/playwright/testTypeImpl.js +61 -0
- package/build/bdd-framework/playwright/transform.js +88 -0
- package/build/bdd-framework/playwright/types.js +5 -0
- package/build/bdd-framework/playwright/utils.js +34 -0
- package/build/bdd-framework/reporter/cucumber/base.js +57 -0
- package/build/bdd-framework/reporter/cucumber/custom.js +73 -0
- package/build/bdd-framework/reporter/cucumber/helper.js +12 -0
- package/build/bdd-framework/reporter/cucumber/html.js +35 -0
- package/build/bdd-framework/reporter/cucumber/index.js +74 -0
- package/build/bdd-framework/reporter/cucumber/json.js +312 -0
- package/build/bdd-framework/reporter/cucumber/junit.js +205 -0
- package/build/bdd-framework/reporter/cucumber/message.js +20 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/AttachmentMapper.js +64 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/Builder.js +196 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/GherkinDocument.js +43 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/GherkinDocumentClone.js +52 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/GherkinDocuments.js +105 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/Hook.js +70 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/Meta.js +45 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/Pickles.js +27 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/Projects.js +38 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCase.js +128 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCaseRun.js +126 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCaseRunHooks.js +102 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestStepAttachments.js +50 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestStepRun.js +88 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/index.js +30 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/pwUtils.js +51 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/timing.js +35 -0
- package/build/bdd-framework/reporter/cucumber/messagesBuilder/types.js +5 -0
- package/build/bdd-framework/run/StepInvoker.js +68 -0
- package/build/bdd-framework/run/bddDataAttachment.js +46 -0
- package/build/bdd-framework/run/bddFixtures.js +191 -0
- package/build/bdd-framework/run/bddWorld.js +79 -0
- package/build/bdd-framework/run/bddWorldInternal.js +15 -0
- package/build/bdd-framework/snippets/index.js +132 -0
- package/build/bdd-framework/snippets/snippetSyntax.js +43 -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 +66 -0
- package/build/bdd-framework/stepDefinitions/decorators/class.js +68 -0
- package/build/bdd-framework/stepDefinitions/decorators/steps.js +99 -0
- package/build/bdd-framework/stepDefinitions/defineStep.js +62 -0
- package/build/bdd-framework/stepDefinitions/stepConfig.js +24 -0
- package/build/bdd-framework/utils/AutofillMap.js +20 -0
- package/build/bdd-framework/utils/exit.js +62 -0
- package/build/bdd-framework/utils/index.js +93 -0
- package/build/bdd-framework/utils/jsStringWrap.js +44 -0
- package/build/bdd-framework/utils/logger.js +30 -0
- package/build/bdd-framework/utils/stripAnsiEscapes.js +20 -0
- package/build/core/playwright/builtInFixtures/addTags.js +1 -1
- package/build/core/playwright/builtInFixtures/context.js +18 -1
- package/build/core/playwright/builtInFixtures/i18N.js +33 -0
- package/build/core/playwright/builtInFixtures/index.js +19 -7
- package/build/core/playwright/builtInFixtures/page.js +69 -39
- package/build/core/playwright/builtInFixtures/unauthenticatedPage.js +18 -0
- package/build/core/playwright/clear-caches.js +19 -8
- package/build/core/playwright/codegen.js +4 -4
- package/build/core/playwright/constants/browserTypes.js +12 -0
- package/build/core/playwright/custom-commands.js +1 -1
- package/build/core/playwright/env-initializer.js +10 -6
- package/build/core/playwright/helpers/auth/accountLogin.js +18 -0
- package/build/core/playwright/helpers/auth/checkAuthCookies.js +47 -0
- package/build/core/playwright/helpers/auth/getUrlOrigin.js +13 -0
- package/build/core/playwright/helpers/auth/getUsers.js +72 -0
- package/build/core/playwright/helpers/auth/index.js +58 -0
- package/build/core/playwright/helpers/auth/loginSteps.js +36 -0
- package/build/core/playwright/helpers/configFileNameProvider.js +17 -0
- package/build/core/playwright/helpers/getUserFixtures.js +23 -0
- package/build/core/playwright/helpers/mergeObjects.js +13 -0
- package/build/core/playwright/helpers/parseUserArgs.js +11 -0
- package/build/core/playwright/index.js +69 -15
- package/build/core/playwright/readConfigFile.js +50 -39
- package/build/core/playwright/report-generator.js +7 -7
- package/build/core/playwright/setup/config-creator.js +15 -16
- package/build/core/playwright/setup/config-utils.js +60 -26
- package/build/core/playwright/setup/custom-reporter.js +3 -2
- package/build/core/playwright/tag-processor.js +12 -23
- package/build/core/playwright/test-runner.js +49 -63
- package/build/core/playwright/types.js +43 -0
- package/build/decorators.d.ts +1 -1
- package/build/decorators.js +16 -2
- package/build/index.d.ts +79 -12
- package/build/index.js +51 -9
- package/build/lib/cli.js +12 -3
- package/build/lib/post-install.js +18 -10
- package/build/parser/sample.feature +34 -34
- package/build/parser/sample.spec.js +18 -18
- package/build/setup-folder-structure/helper.js +3 -0
- package/build/setup-folder-structure/reportEnhancement/addonScript.html +24 -24
- package/build/setup-folder-structure/samples/auth-setup-sample.js +72 -72
- package/build/setup-folder-structure/samples/authUsers-sample.json +8 -8
- package/build/setup-folder-structure/samples/env-config-sample.json +20 -20
- package/build/setup-folder-structure/samples/git-ignore.sample.js +36 -36
- package/build/setup-folder-structure/samples/uat-config-sample.js +44 -44
- package/build/utils/cliArgsToObject.js +30 -26
- package/build/utils/fileUtils.js +4 -19
- package/build/utils/getFilePath.js +1 -2
- package/build/utils/rootPath.js +16 -9
- package/changelog.md +144 -131
- package/jest.config.js +63 -63
- package/npm-shrinkwrap.json +6475 -5994
- package/package.json +57 -56
- package/playwright.config.js +112 -112
- package/build/bdd-poc/config/pathConfig.js +0 -22
- package/build/bdd-poc/core-runner/exportMethods.js +0 -22
- package/build/bdd-poc/core-runner/main.js +0 -15
- package/build/bdd-poc/core-runner/stepDefinitions.js +0 -157
- package/build/bdd-poc/core-runner/stepRunner.js +0 -25
- package/build/bdd-poc/errors/throwError.js +0 -23
- package/build/bdd-poc/index.js +0 -26
- package/build/bdd-poc/test/cucumber/featureFileParer.js +0 -84
- package/build/bdd-poc/test/cucumber/parserCucumber.js +0 -15
- package/build/bdd-poc/test/stepGenerate/extractTestInputs.js +0 -65
- package/build/bdd-poc/test/stepGenerate/parserSteps.js +0 -81
- package/build/bdd-poc/test/stepGenerate/stepFileGenerate.js +0 -40
- package/build/bdd-poc/test/stepGenerate/stepsnippets.js +0 -61
- package/build/bdd-poc/test/tagsHandle.js +0 -70
- package/build/bdd-poc/test/testData.js +0 -125
- package/build/bdd-poc/test/testStructure.js +0 -92
- package/build/bdd-poc/utils/stringManipulation.js +0 -26
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.TestCase = void 0;
|
|
7
|
+
var _utils = require("../../../utils");
|
|
8
|
+
class TestCase {
|
|
9
|
+
id;
|
|
10
|
+
gherkinDocuments;
|
|
11
|
+
#pickle;
|
|
12
|
+
#projectInfo;
|
|
13
|
+
beforeHooks = new Map();
|
|
14
|
+
afterHooks = new Map();
|
|
15
|
+
mainSteps = [];
|
|
16
|
+
constructor(id, gherkinDocuments) {
|
|
17
|
+
this.id = id;
|
|
18
|
+
this.gherkinDocuments = gherkinDocuments;
|
|
19
|
+
}
|
|
20
|
+
get projectInfo() {
|
|
21
|
+
if (!this.#projectInfo) {
|
|
22
|
+
throw new Error(`Empty projectInfo for testCase: ${this.id}`);
|
|
23
|
+
}
|
|
24
|
+
return this.#projectInfo;
|
|
25
|
+
}
|
|
26
|
+
get pickle() {
|
|
27
|
+
if (!this.#pickle) {
|
|
28
|
+
throw new Error(`Empty pickle for testCase: ${this.id}`);
|
|
29
|
+
}
|
|
30
|
+
return this.#pickle;
|
|
31
|
+
}
|
|
32
|
+
addRun(testCaseRun) {
|
|
33
|
+
if (!this.#projectInfo) {
|
|
34
|
+
this.#projectInfo = testCaseRun.projectInfo;
|
|
35
|
+
}
|
|
36
|
+
this.addHooks(testCaseRun, 'before');
|
|
37
|
+
this.addHooks(testCaseRun, 'after');
|
|
38
|
+
if (!this.#pickle) {
|
|
39
|
+
this.#pickle = this.findPickle(testCaseRun.bddData);
|
|
40
|
+
this.addStepsFromPickle(this.#pickle);
|
|
41
|
+
}
|
|
42
|
+
this.addStepsArgumentsLists(testCaseRun);
|
|
43
|
+
}
|
|
44
|
+
getHooks(hookType) {
|
|
45
|
+
return hookType == 'before' ? this.beforeHooks : this.afterHooks;
|
|
46
|
+
}
|
|
47
|
+
getMainSteps() {
|
|
48
|
+
return this.mainSteps;
|
|
49
|
+
}
|
|
50
|
+
buildMessage() {
|
|
51
|
+
const testSteps = [...Array.from(this.beforeHooks.values()).map(hook => hook.testStep), ...(this.mainSteps || []), ...Array.from(this.afterHooks.values()).map(hook => hook.testStep)];
|
|
52
|
+
const testCase = {
|
|
53
|
+
id: this.id,
|
|
54
|
+
pickleId: this.pickle.id,
|
|
55
|
+
testSteps
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
testCase
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* We collect hooks from all runs of this test case, avoiding duplicates.
|
|
63
|
+
*/
|
|
64
|
+
addHooks(testCaseRun, hookType) {
|
|
65
|
+
const testCaseHooks = hookType === 'before' ? this.beforeHooks : this.afterHooks;
|
|
66
|
+
const testRunHooks = testCaseRun.getExecutedHooks(hookType);
|
|
67
|
+
testRunHooks.forEach(({
|
|
68
|
+
hook
|
|
69
|
+
}) => {
|
|
70
|
+
if (testCaseHooks.has(hook.internalId)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const testStep = {
|
|
74
|
+
id: `${this.id}-${hookType}-${testCaseHooks.size}`,
|
|
75
|
+
hookId: hook.id
|
|
76
|
+
};
|
|
77
|
+
testCaseHooks.set(hook.internalId, {
|
|
78
|
+
hook,
|
|
79
|
+
testStep
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Initially create steps from pickle steps, with empty stepMatchArgumentsLists.
|
|
85
|
+
*/
|
|
86
|
+
addStepsFromPickle(pickle) {
|
|
87
|
+
this.mainSteps = pickle.steps.map((pickleStep, stepIndex) => {
|
|
88
|
+
return {
|
|
89
|
+
id: `${this.id}-step-${stepIndex}`,
|
|
90
|
+
pickleStepId: pickleStep.id,
|
|
91
|
+
stepDefinitionIds: [],
|
|
92
|
+
stepMatchArgumentsLists: []
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Fill stepMatchArgumentsLists from all test runs.
|
|
98
|
+
* It allows to fill as many steps as possible.
|
|
99
|
+
* Possibly, we write the same stepMatchArgumentsLists several times,
|
|
100
|
+
* looks like it's not a problem as they should be equal for all runs.
|
|
101
|
+
*/
|
|
102
|
+
addStepsArgumentsLists(testCaseRun) {
|
|
103
|
+
testCaseRun.bddData.steps.forEach((bddDataStep, stepIndex) => {
|
|
104
|
+
var _this$mainSteps;
|
|
105
|
+
const testCaseStep = (_this$mainSteps = this.mainSteps) === null || _this$mainSteps === void 0 ? void 0 : _this$mainSteps[stepIndex];
|
|
106
|
+
if (testCaseStep && bddDataStep.stepMatchArgumentsLists) {
|
|
107
|
+
testCaseStep.stepMatchArgumentsLists = bddDataStep.stepMatchArgumentsLists;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
findPickle({
|
|
112
|
+
uri,
|
|
113
|
+
pickleLocation
|
|
114
|
+
}) {
|
|
115
|
+
const doc = this.gherkinDocuments.find(doc => doc.uri === uri);
|
|
116
|
+
if (!doc) {
|
|
117
|
+
throw new Error('GherkinDocument not found');
|
|
118
|
+
}
|
|
119
|
+
const pickle = doc.pickles.find(pickle => {
|
|
120
|
+
return (0, _utils.stringifyLocation)(pickle.location) === pickleLocation;
|
|
121
|
+
});
|
|
122
|
+
if (!pickle) {
|
|
123
|
+
throw new Error('Pickle not found');
|
|
124
|
+
}
|
|
125
|
+
return pickle;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.TestCase = TestCase;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.TestCaseRun = void 0;
|
|
7
|
+
var _utils = require("../../../utils");
|
|
8
|
+
var _TestStepRun = require("./TestStepRun");
|
|
9
|
+
var _timing = require("./timing");
|
|
10
|
+
var _pwUtils = require("./pwUtils");
|
|
11
|
+
var _bddDataAttachment = require("../../../run/bddDataAttachment");
|
|
12
|
+
var _AttachmentMapper = require("./AttachmentMapper");
|
|
13
|
+
var _TestCaseRunHooks = require("./TestCaseRunHooks");
|
|
14
|
+
var _Projects = require("./Projects");
|
|
15
|
+
class TestCaseRun {
|
|
16
|
+
test;
|
|
17
|
+
result;
|
|
18
|
+
hooks;
|
|
19
|
+
id;
|
|
20
|
+
bddData;
|
|
21
|
+
testCase;
|
|
22
|
+
attachmentMapper;
|
|
23
|
+
projectInfo;
|
|
24
|
+
executedBeforeHooks;
|
|
25
|
+
executedAfterHooks;
|
|
26
|
+
executedSteps;
|
|
27
|
+
// eslint-disable-next-line max-params
|
|
28
|
+
constructor(test, result, hooks) {
|
|
29
|
+
this.test = test;
|
|
30
|
+
this.result = result;
|
|
31
|
+
this.hooks = hooks;
|
|
32
|
+
this.id = this.generateTestRunId();
|
|
33
|
+
this.bddData = this.getBddData();
|
|
34
|
+
this.projectInfo = (0, _Projects.getProjectInfo)(this.test);
|
|
35
|
+
this.attachmentMapper = new _AttachmentMapper.AttachmentMapper(this.result);
|
|
36
|
+
this.executedSteps = this.fillExecutedSteps();
|
|
37
|
+
this.executedBeforeHooks = this.fillExecutedHooks('before');
|
|
38
|
+
this.executedAfterHooks = this.fillExecutedHooks('after');
|
|
39
|
+
}
|
|
40
|
+
getTestCase() {
|
|
41
|
+
if (!this.testCase) {
|
|
42
|
+
throw new Error(`TestCase is not set.`);
|
|
43
|
+
}
|
|
44
|
+
return this.testCase;
|
|
45
|
+
}
|
|
46
|
+
generateTestRunId() {
|
|
47
|
+
return `${this.test.id}-run-${this.result.retry}`;
|
|
48
|
+
}
|
|
49
|
+
getBddData() {
|
|
50
|
+
const bddData = (0, _bddDataAttachment.getBddDataFromTestResult)(this.result);
|
|
51
|
+
if (!bddData) {
|
|
52
|
+
throw new Error([`BDD data attachment is not found for test: ${this.test.title}`, `Did you set enrichReporterData: true in the Playwright config?`, ''].join('\n'));
|
|
53
|
+
}
|
|
54
|
+
return bddData;
|
|
55
|
+
}
|
|
56
|
+
fillExecutedSteps() {
|
|
57
|
+
const possiblePwSteps = this.getPossiblePlaywrightSteps();
|
|
58
|
+
return this.bddData.steps.map(bddDataStep => {
|
|
59
|
+
const pwStep = this.findPlaywrightStep(possiblePwSteps, bddDataStep);
|
|
60
|
+
return {
|
|
61
|
+
bddDataStep,
|
|
62
|
+
pwStep
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
fillExecutedHooks(hookType) {
|
|
67
|
+
return new _TestCaseRunHooks.TestCaseRunHooks(this, hookType).fill(this.executedSteps);
|
|
68
|
+
}
|
|
69
|
+
buildMessages() {
|
|
70
|
+
return [this.buildTestCaseStarted(), ...this.executedBeforeHooks.buildMessages(), ...this.buildStepRuns(), ...this.executedAfterHooks.buildMessages(), this.buildTestCaseFinished()];
|
|
71
|
+
}
|
|
72
|
+
getExecutedHooks(hookType) {
|
|
73
|
+
return hookType === 'before' ? this.executedBeforeHooks.executedHooks : this.executedAfterHooks.executedHooks;
|
|
74
|
+
}
|
|
75
|
+
buildTestCaseStarted() {
|
|
76
|
+
const testCaseStarted = {
|
|
77
|
+
id: this.id,
|
|
78
|
+
attempt: this.result.retry,
|
|
79
|
+
testCaseId: this.getTestCase().id,
|
|
80
|
+
// workerId: 'worker-1'
|
|
81
|
+
timestamp: (0, _timing.toCucumberTimestamp)(this.result.startTime.getTime())
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
testCaseStarted
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
buildStepRuns() {
|
|
88
|
+
return this.getTestCase().getMainSteps().reduce((messages, testStep, stepIndex) => {
|
|
89
|
+
const {
|
|
90
|
+
pwStep
|
|
91
|
+
} = this.executedSteps[stepIndex] || {};
|
|
92
|
+
const testStepRun = new _TestStepRun.TestStepRun(this, testStep, pwStep);
|
|
93
|
+
return messages.concat(testStepRun.buildMessages());
|
|
94
|
+
}, []);
|
|
95
|
+
}
|
|
96
|
+
buildTestCaseFinished() {
|
|
97
|
+
const {
|
|
98
|
+
startTime,
|
|
99
|
+
duration
|
|
100
|
+
} = this.result;
|
|
101
|
+
const testCaseFinished = {
|
|
102
|
+
testCaseStartedId: this.id,
|
|
103
|
+
willBeRetried: Boolean(this.result.error && this.result.retry < this.test.retries),
|
|
104
|
+
timestamp: (0, _timing.toCucumberTimestamp)(startTime.getTime() + duration)
|
|
105
|
+
};
|
|
106
|
+
return {
|
|
107
|
+
testCaseFinished
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
findPlaywrightStep(possiblePwSteps, bddDataStep) {
|
|
111
|
+
const pwStep = possiblePwSteps.find(pwStep => {
|
|
112
|
+
return pwStep.location && (0, _utils.stringifyLocation)(pwStep.location) === bddDataStep.pwStepLocation;
|
|
113
|
+
});
|
|
114
|
+
if (!pwStep) {
|
|
115
|
+
throw new Error('Playwright step not found for bdd step');
|
|
116
|
+
}
|
|
117
|
+
return pwStep;
|
|
118
|
+
}
|
|
119
|
+
getPossiblePlaywrightSteps() {
|
|
120
|
+
const beforeHooksRoot = (0, _pwUtils.getHooksRootStep)(this.result, 'before');
|
|
121
|
+
const bgSteps = (0, _pwUtils.collectStepsWithCategory)(beforeHooksRoot, 'test.step');
|
|
122
|
+
const topLevelSteps = this.result.steps.filter(step => step.category === 'test.step');
|
|
123
|
+
return [...bgSteps, ...topLevelSteps];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.TestCaseRun = TestCaseRun;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.TestCaseRunHooks = void 0;
|
|
7
|
+
var _Hook = require("./Hook");
|
|
8
|
+
var _pwUtils = require("./pwUtils");
|
|
9
|
+
var _TestStepRun = require("./TestStepRun");
|
|
10
|
+
class TestCaseRunHooks {
|
|
11
|
+
testCaseRun;
|
|
12
|
+
hookType;
|
|
13
|
+
rootStep;
|
|
14
|
+
candidateSteps = [];
|
|
15
|
+
hookSteps = new Set();
|
|
16
|
+
executedHooks = new Map();
|
|
17
|
+
constructor(testCaseRun, hookType) {
|
|
18
|
+
this.testCaseRun = testCaseRun;
|
|
19
|
+
this.hookType = hookType;
|
|
20
|
+
}
|
|
21
|
+
fill(mainSteps) {
|
|
22
|
+
this.setRootStep();
|
|
23
|
+
this.setCandidateSteps();
|
|
24
|
+
this.addStepsWithName();
|
|
25
|
+
this.addStepsWithAttachment();
|
|
26
|
+
this.addStepWithError();
|
|
27
|
+
this.excludeBackgroundSteps(mainSteps);
|
|
28
|
+
this.setExecutedHooks();
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
buildMessages() {
|
|
32
|
+
const messages = [];
|
|
33
|
+
this.testCaseRun.getTestCase().getHooks(this.hookType).forEach(hookInfo => {
|
|
34
|
+
const executedHook = this.executedHooks.get(hookInfo.hook.internalId);
|
|
35
|
+
// todo: if pwStep is not found in this.executedBeforeHooks,
|
|
36
|
+
// it means that this hook comes from another run of this test case.
|
|
37
|
+
// We can stil try to find it in test result, as otherwise it will be marked as skipped,
|
|
38
|
+
// but actually it was executed.
|
|
39
|
+
const testStepRun = new _TestStepRun.TestStepRun(this.testCaseRun, hookInfo.testStep, executedHook === null || executedHook === void 0 ? void 0 : executedHook.pwStep);
|
|
40
|
+
messages.push(...testStepRun.buildMessages());
|
|
41
|
+
});
|
|
42
|
+
return messages;
|
|
43
|
+
}
|
|
44
|
+
setRootStep() {
|
|
45
|
+
this.rootStep = (0, _pwUtils.getHooksRootStep)(this.testCaseRun.result, this.hookType);
|
|
46
|
+
}
|
|
47
|
+
setCandidateSteps() {
|
|
48
|
+
if (this.rootStep) {
|
|
49
|
+
this.candidateSteps.push(this.rootStep);
|
|
50
|
+
}
|
|
51
|
+
this.candidateSteps.push(...(0, _pwUtils.collectStepsDfs)(this.rootStep));
|
|
52
|
+
}
|
|
53
|
+
addStepsWithName() {
|
|
54
|
+
this.candidateSteps.forEach(pwStep => {
|
|
55
|
+
if (pwStep.category === 'test.step' && pwStep.title) {
|
|
56
|
+
this.hookSteps.add(pwStep);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
addStepsWithAttachment() {
|
|
61
|
+
const {
|
|
62
|
+
attachmentMapper
|
|
63
|
+
} = this.testCaseRun;
|
|
64
|
+
this.candidateSteps.forEach(pwStep => {
|
|
65
|
+
if (attachmentMapper.getStepAttachments(pwStep).length > 0) {
|
|
66
|
+
this.hookSteps.add(pwStep);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
addStepWithError() {
|
|
71
|
+
const stepWithError = (0, _pwUtils.findDeepestErrorStep)(this.rootStep);
|
|
72
|
+
if (stepWithError) {
|
|
73
|
+
this.hookSteps.add(stepWithError);
|
|
74
|
+
// in Playwright error is inherited by all parent steps,
|
|
75
|
+
// but we want to show it once (in the deepest step)
|
|
76
|
+
this.hookSteps.forEach(step => {
|
|
77
|
+
if (step !== stepWithError) {
|
|
78
|
+
delete step.error;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
excludeBackgroundSteps(mainSteps) {
|
|
84
|
+
// exclude background steps, b/c they are in pickle, not in hooks.
|
|
85
|
+
// Important to run this fn after this.fillExecutedSteps()
|
|
86
|
+
// as we assume steps are already populated
|
|
87
|
+
if (this.hookType === 'before') {
|
|
88
|
+
mainSteps.forEach(stepInfo => this.hookSteps.delete(stepInfo.pwStep));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
setExecutedHooks() {
|
|
92
|
+
this.hookSteps.forEach(pwStep => {
|
|
93
|
+
const internalId = _Hook.Hook.getInternalId(pwStep);
|
|
94
|
+
const hook = this.testCaseRun.hooks.getOrCreate(internalId, () => new _Hook.Hook(internalId, pwStep));
|
|
95
|
+
this.executedHooks.set(internalId, {
|
|
96
|
+
hook,
|
|
97
|
+
pwStep
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.TestCaseRunHooks = TestCaseRunHooks;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.TestStepAttachments = void 0;
|
|
8
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
9
|
+
var messages = _interopRequireWildcard(require("@cucumber/messages"));
|
|
10
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
11
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
12
|
+
/**
|
|
13
|
+
* Class for getting attachment messages for a particular step.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
class TestStepAttachments {
|
|
17
|
+
testCaseRun;
|
|
18
|
+
testStep;
|
|
19
|
+
pwStep;
|
|
20
|
+
constructor(testCaseRun, testStep, pwStep) {
|
|
21
|
+
this.testCaseRun = testCaseRun;
|
|
22
|
+
this.testStep = testStep;
|
|
23
|
+
this.pwStep = pwStep;
|
|
24
|
+
}
|
|
25
|
+
buildMessages() {
|
|
26
|
+
if (!this.pwStep) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
return this.testCaseRun.attachmentMapper.getStepAttachments(this.pwStep).map(pwAttachment => this.buildAttachmentMessage(pwAttachment));
|
|
30
|
+
}
|
|
31
|
+
buildAttachmentMessage(pwAttachment) {
|
|
32
|
+
const attachment = {
|
|
33
|
+
testCaseStartedId: this.testCaseRun.id,
|
|
34
|
+
testStepId: this.testStep.id,
|
|
35
|
+
// for now always attach as base64
|
|
36
|
+
// todo: for text/plain and application/json use raw to save some bytes
|
|
37
|
+
body: this.getAttachmentBodyBase64(pwAttachment),
|
|
38
|
+
contentEncoding: messages.AttachmentContentEncoding.BASE64,
|
|
39
|
+
mediaType: pwAttachment.contentType,
|
|
40
|
+
fileName: pwAttachment.name
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
attachment
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
getAttachmentBodyBase64(pwAttachment) {
|
|
47
|
+
return pwAttachment.path ? _fs.default.readFileSync(pwAttachment.path, 'base64') : pwAttachment.body.toString('base64');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.TestStepAttachments = TestStepAttachments;
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.TestStepRun = void 0;
|
|
7
|
+
var messages = _interopRequireWildcard(require("@cucumber/messages"));
|
|
8
|
+
var _stripAnsiEscapes = require("../../../utils/stripAnsiEscapes");
|
|
9
|
+
var _timing = require("./timing");
|
|
10
|
+
var _TestStepAttachments = require("./TestStepAttachments");
|
|
11
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
12
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
13
|
+
class TestStepRun {
|
|
14
|
+
testCaseRun;
|
|
15
|
+
testStep;
|
|
16
|
+
pwStep;
|
|
17
|
+
constructor(testCaseRun, testStep, pwStep) {
|
|
18
|
+
this.testCaseRun = testCaseRun;
|
|
19
|
+
this.testStep = testStep;
|
|
20
|
+
this.pwStep = pwStep;
|
|
21
|
+
}
|
|
22
|
+
buildMessages() {
|
|
23
|
+
const stepAttachments = new _TestStepAttachments.TestStepAttachments(this.testCaseRun, this.testStep, this.pwStep);
|
|
24
|
+
return [this.buildTestStepStarted(),
|
|
25
|
+
// prettier-ignore
|
|
26
|
+
...stepAttachments.buildMessages(), this.buildTestStepFinished()];
|
|
27
|
+
}
|
|
28
|
+
wasExecuted() {
|
|
29
|
+
return Boolean(this.pwStep);
|
|
30
|
+
}
|
|
31
|
+
get startTime() {
|
|
32
|
+
return this.wasExecuted() ? this.pwStep.startTime : this.testCaseRun.result.startTime;
|
|
33
|
+
}
|
|
34
|
+
get duration() {
|
|
35
|
+
return this.wasExecuted() ? this.pwStep.duration : 0;
|
|
36
|
+
}
|
|
37
|
+
buildTestStepStarted() {
|
|
38
|
+
const testStepStarted = {
|
|
39
|
+
testCaseStartedId: this.testCaseRun.id,
|
|
40
|
+
testStepId: this.testStep.id,
|
|
41
|
+
timestamp: (0, _timing.toCucumberTimestamp)(this.startTime.getTime())
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
testStepStarted
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
buildTestStepFinished() {
|
|
48
|
+
var _this$pwStep;
|
|
49
|
+
const error = (_this$pwStep = this.pwStep) === null || _this$pwStep === void 0 ? void 0 : _this$pwStep.error;
|
|
50
|
+
const testStepFinished = {
|
|
51
|
+
testCaseStartedId: this.testCaseRun.id,
|
|
52
|
+
testStepId: this.testStep.id,
|
|
53
|
+
testStepResult: {
|
|
54
|
+
duration: messages.TimeConversion.millisecondsToDuration(this.duration),
|
|
55
|
+
status: this.getStatus(error),
|
|
56
|
+
message: error ? formatError(error) : undefined,
|
|
57
|
+
exception: error ? this.buildException(error) : undefined
|
|
58
|
+
},
|
|
59
|
+
timestamp: (0, _timing.toCucumberTimestamp)(this.startTime.getTime() + this.duration)
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
testStepFinished
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
buildException(error) {
|
|
66
|
+
return {
|
|
67
|
+
type: 'Error',
|
|
68
|
+
message: error.message ? (0, _stripAnsiEscapes.stripAnsiEscapes)(error.message) : undefined,
|
|
69
|
+
stackTrace: error.stack ? (0, _stripAnsiEscapes.stripAnsiEscapes)(error.stack) : undefined
|
|
70
|
+
// Use type casting b/c older versions of @cucumber/messages don't have 'stackTrace' field
|
|
71
|
+
// todo: add direct dependency on @cucumber/messages
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
getStatus(error) {
|
|
75
|
+
switch (true) {
|
|
76
|
+
case !this.wasExecuted():
|
|
77
|
+
return messages.TestStepResultStatus.SKIPPED;
|
|
78
|
+
case Boolean(error):
|
|
79
|
+
return messages.TestStepResultStatus.FAILED;
|
|
80
|
+
default:
|
|
81
|
+
return messages.TestStepResultStatus.PASSED;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.TestStepRun = TestStepRun;
|
|
86
|
+
function formatError(error) {
|
|
87
|
+
return (0, _stripAnsiEscapes.stripAnsiEscapes)([error.message, error.snippet].filter(Boolean).join('\n'));
|
|
88
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getMessagesBuilderRef = getMessagesBuilderRef;
|
|
7
|
+
var _Builder = require("./Builder");
|
|
8
|
+
/**
|
|
9
|
+
* Returns reference to a messagesBuilder singleton.
|
|
10
|
+
* We pass onTestEnd and onEnd calls only for the first reference (reporter),
|
|
11
|
+
* otherwise all events will be duplicated.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
let instance;
|
|
15
|
+
let referenceCount = 0;
|
|
16
|
+
function getMessagesBuilderRef() {
|
|
17
|
+
if (!instance) {
|
|
18
|
+
instance = new _Builder.MessagesBuilder();
|
|
19
|
+
}
|
|
20
|
+
const isFirstRef = ++referenceCount === 1;
|
|
21
|
+
return {
|
|
22
|
+
builder: instance,
|
|
23
|
+
onTestEnd(test, result) {
|
|
24
|
+
isFirstRef && this.builder.onTestEnd(test, result);
|
|
25
|
+
},
|
|
26
|
+
onEnd(fullResult) {
|
|
27
|
+
isFirstRef && this.builder.onEnd(fullResult);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.collectStepsDfs = collectStepsDfs;
|
|
7
|
+
exports.collectStepsWithCategory = collectStepsWithCategory;
|
|
8
|
+
exports.findDeepestErrorStep = findDeepestErrorStep;
|
|
9
|
+
exports.getHooksRootStep = getHooksRootStep;
|
|
10
|
+
/**
|
|
11
|
+
* Utility functions for filtering Playwright steps.
|
|
12
|
+
*/
|
|
13
|
+
// Playwright step categoires, that can be mapped to testStep / hook in Cucumber report
|
|
14
|
+
const MEANINGFUL_STEP_CATEGORIES = ['hook', 'fixture', 'test.step'];
|
|
15
|
+
function collectStepsWithCategory(parent, category) {
|
|
16
|
+
const categories = Array.isArray(category) ? category : [category];
|
|
17
|
+
const steps = collectStepsDfs(parent);
|
|
18
|
+
return steps.filter(step => categories.includes(step.category));
|
|
19
|
+
}
|
|
20
|
+
function getHooksRootStep(result, type) {
|
|
21
|
+
const rootStepTitle = type === 'before' ? 'Before Hooks' : 'After Hooks';
|
|
22
|
+
return result.steps.find(step => step.category === 'hook' && step.title === rootStepTitle);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Drills down to the deepest error step.
|
|
26
|
+
*/
|
|
27
|
+
function findDeepestErrorStep(root) {
|
|
28
|
+
let errorStep = root !== null && root !== void 0 && root.error ? root : null;
|
|
29
|
+
while (errorStep) {
|
|
30
|
+
const nextErrorStep = errorStep.steps.find(step => {
|
|
31
|
+
return step.error && MEANINGFUL_STEP_CATEGORIES.includes(step.category);
|
|
32
|
+
});
|
|
33
|
+
if (!nextErrorStep) {
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
errorStep = nextErrorStep;
|
|
37
|
+
}
|
|
38
|
+
return errorStep;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns all steps in DFS order.
|
|
42
|
+
* See: https://en.wikipedia.org/wiki/Depth-first_search
|
|
43
|
+
*/
|
|
44
|
+
function collectStepsDfs(parent) {
|
|
45
|
+
var _parent$steps;
|
|
46
|
+
return (parent === null || parent === void 0 || (_parent$steps = parent.steps) === null || _parent$steps === void 0 ? void 0 : _parent$steps.reduce((res, step) => {
|
|
47
|
+
res.push(step);
|
|
48
|
+
res.push(...collectStepsDfs(step));
|
|
49
|
+
return res;
|
|
50
|
+
}, [])) || [];
|
|
51
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.calcMinMaxByArray = calcMinMaxByArray;
|
|
7
|
+
exports.toCucumberTimestamp = toCucumberTimestamp;
|
|
8
|
+
var _messages = require("@cucumber/messages");
|
|
9
|
+
/**
|
|
10
|
+
* Timing utils.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
function toCucumberTimestamp(time) {
|
|
14
|
+
return _messages.TimeConversion.millisecondsSinceEpochToTimestamp(time);
|
|
15
|
+
}
|
|
16
|
+
function calcMinMaxByArray(items) {
|
|
17
|
+
let startTime = items.length > 0 ? items[0].startTime : new Date();
|
|
18
|
+
let endTime = items.length > 0 ? getEndTime(items[0]) : new Date();
|
|
19
|
+
items.forEach(item => {
|
|
20
|
+
const resultEndTime = getEndTime(item);
|
|
21
|
+
if (item.startTime < startTime) {
|
|
22
|
+
startTime = item.startTime;
|
|
23
|
+
}
|
|
24
|
+
if (resultEndTime > endTime) {
|
|
25
|
+
endTime = resultEndTime;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
startTime,
|
|
30
|
+
duration: endTime.getTime() - startTime.getTime()
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function getEndTime(entity) {
|
|
34
|
+
return new Date(entity.startTime.getTime() + entity.duration);
|
|
35
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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 step in playwright runner.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
class StepInvoker {
|
|
17
|
+
world;
|
|
18
|
+
keyword;
|
|
19
|
+
constructor(world, keyword) {
|
|
20
|
+
this.world = world;
|
|
21
|
+
this.keyword = keyword;
|
|
22
|
+
this.invoke = this.invoke.bind(this);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Invokes particular step.
|
|
26
|
+
* See: https://github.com/cucumber/cucumber-js/blob/main/src/runtime/test_case_runner.ts#L299
|
|
27
|
+
*/
|
|
28
|
+
async invoke(text, argument, stepFixtures) {
|
|
29
|
+
this.world.$internal.currentStepFixtures = stepFixtures || {};
|
|
30
|
+
const stepDefinition = this.getStepDefinition(text);
|
|
31
|
+
// Get location of step call in generated test file.
|
|
32
|
+
// This call must be exactly here to have correct call stack (before async calls)
|
|
33
|
+
const location = (0, _getLocationInFile.getLocationInFile)(this.world.testInfo.file);
|
|
34
|
+
const stepTitle = this.getStepTitle(text);
|
|
35
|
+
const code = (0, _defineStep.getStepCode)(stepDefinition);
|
|
36
|
+
const parameters = await this.getStepParameters(stepDefinition, text, argument || undefined);
|
|
37
|
+
this.world.$internal.bddData.registerStep(stepDefinition, text, location);
|
|
38
|
+
return (0, _testTypeImpl.runStepWithCustomLocation)(this.world.test, stepTitle, location, () => code.apply(this.world, parameters));
|
|
39
|
+
}
|
|
40
|
+
getStepDefinition(text) {
|
|
41
|
+
const stepDefinition = (0, _loadSteps.findStepDefinition)(this.world.options.supportCodeLibrary, text, this.world.testInfo.file);
|
|
42
|
+
if (!stepDefinition) {
|
|
43
|
+
throw new Error(`Undefined step: "${text}"`);
|
|
44
|
+
}
|
|
45
|
+
return stepDefinition;
|
|
46
|
+
}
|
|
47
|
+
async getStepParameters(stepDefinition, text, argument) {
|
|
48
|
+
// see: https://github.com/cucumber/cucumber-js/blob/main/src/models/step_definition.ts#L25
|
|
49
|
+
const {
|
|
50
|
+
parameters
|
|
51
|
+
} = await stepDefinition.getInvocationParameters({
|
|
52
|
+
hookParameter: {},
|
|
53
|
+
// only text and argument are needed
|
|
54
|
+
step: {
|
|
55
|
+
text,
|
|
56
|
+
argument
|
|
57
|
+
},
|
|
58
|
+
world: this.world
|
|
59
|
+
});
|
|
60
|
+
return parameters;
|
|
61
|
+
}
|
|
62
|
+
getStepTitle(text) {
|
|
63
|
+
// Currently prepend keyword only for English.
|
|
64
|
+
// For other langs it's more complex as we need to pass original keyword from step.
|
|
65
|
+
return (0, _lang.isEnglish)(this.world.options.lang) ? `${this.keyword} ${text}` : text;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.StepInvoker = StepInvoker;
|