@lynxwall/cucumber-tsflow 6.1.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -21
- package/lib/behave.d.ts +1 -1
- package/lib/behave.js +27 -27
- package/lib/cli/argv-parser.d.ts +24 -24
- package/lib/cli/argv-parser.js +103 -103
- package/lib/cli/index.d.ts +21 -22
- package/lib/cli/index.js +95 -101
- package/lib/cli/load-configuration.d.ts +20 -20
- package/lib/cli/load-configuration.js +101 -93
- package/lib/cli/run.d.ts +1 -1
- package/lib/cli/run.js +49 -47
- package/lib/cucumber/binding-decorator.d.ts +10 -10
- package/lib/cucumber/binding-decorator.js +180 -180
- package/lib/cucumber/binding-registry.d.ts +82 -82
- package/lib/cucumber/binding-registry.js +215 -215
- package/lib/cucumber/hook-decorators.d.ts +46 -46
- package/lib/cucumber/hook-decorators.js +102 -102
- package/lib/cucumber/managed-scenario-context.d.ts +21 -21
- package/lib/cucumber/managed-scenario-context.js +95 -95
- package/lib/cucumber/message-collector.d.ts +81 -81
- package/lib/cucumber/message-collector.js +250 -250
- package/lib/cucumber/parallel/coordinator.d.ts +79 -79
- package/lib/cucumber/parallel/coordinator.js +246 -246
- package/lib/cucumber/parallel/run-worker.d.ts +1 -1
- package/lib/cucumber/parallel/run-worker.js +31 -31
- package/lib/cucumber/parallel/worker.d.ts +30 -30
- package/lib/cucumber/parallel/worker.js +103 -103
- package/lib/cucumber/run-cucumber.d.ts +14 -14
- package/lib/cucumber/run-cucumber.js +118 -118
- package/lib/cucumber/runtime.d.ts +25 -25
- package/lib/cucumber/runtime.js +39 -39
- package/lib/cucumber/step-definition-decorators.d.ts +24 -24
- package/lib/cucumber/step-definition-decorators.js +91 -91
- package/lib/cucumber/utils.d.ts +16 -16
- package/lib/cucumber/utils.js +77 -77
- package/lib/esnode.js +18 -18
- package/lib/esvue.d.ts +1 -1
- package/lib/esvue.js +40 -40
- package/lib/formatters/behave-json-formatter.d.ts +49 -49
- package/lib/formatters/behave-json-formatter.js +74 -74
- package/lib/formatters/tsflow-snippet-syntax.d.ts +9 -9
- package/lib/formatters/tsflow-snippet-syntax.js +89 -89
- package/lib/gherkin/configuration.d.ts +30 -30
- package/lib/gherkin/configuration.js +26 -26
- package/lib/gherkin/gherkin-feature.d.ts +28 -28
- package/lib/gherkin/gherkin-feature.js +353 -333
- package/lib/gherkin/gherkin-manager.d.ts +29 -29
- package/lib/gherkin/gherkin-manager.js +143 -139
- package/lib/gherkin/models.d.ts +46 -45
- package/lib/gherkin/models.js +2 -2
- package/lib/index.d.ts +4 -4
- package/lib/index.js +22 -22
- package/lib/snippet.d.ts +1 -1
- package/lib/snippet.js +27 -27
- package/lib/transpilers/esbuild-transpiler.d.ts +4 -4
- package/lib/transpilers/esbuild-transpiler.js +18 -18
- package/lib/transpilers/esbuild.d.ts +12 -12
- package/lib/transpilers/esbuild.js +54 -54
- package/lib/transpilers/vue-sfc/compiler.d.ts +7 -7
- package/lib/transpilers/vue-sfc/compiler.js +21 -21
- package/lib/transpilers/vue-sfc/index.d.ts +23 -23
- package/lib/transpilers/vue-sfc/index.js +46 -46
- package/lib/transpilers/vue-sfc/main.d.ts +8 -8
- package/lib/transpilers/vue-sfc/main.js +247 -247
- package/lib/transpilers/vue-sfc/script.d.ts +5 -5
- package/lib/transpilers/vue-sfc/script.js +41 -41
- package/lib/transpilers/vue-sfc/template.d.ts +8 -8
- package/lib/transpilers/vue-sfc/template.js +101 -101
- package/lib/transpilers/vue-sfc/types.d.ts +55 -55
- package/lib/transpilers/vue-sfc/types.js +2 -2
- package/lib/transpilers/vue-sfc/utils/descriptorCache.d.ts +13 -13
- package/lib/transpilers/vue-sfc/utils/descriptorCache.js +67 -67
- package/lib/transpilers/vue-sfc/utils/error.d.ts +3 -3
- package/lib/transpilers/vue-sfc/utils/error.js +22 -22
- package/lib/transpilers/vue-sfc/utils/query.d.ts +13 -13
- package/lib/transpilers/vue-sfc/utils/query.js +35 -35
- package/lib/tsnode.js +17 -17
- package/lib/tsvue.d.ts +1 -1
- package/lib/tsvue.js +39 -39
- package/lib/types/scenario-context.d.ts +16 -16
- package/lib/types/scenario-context.js +17 -17
- package/lib/types/scenario-info.d.ts +16 -16
- package/lib/types/scenario-info.js +22 -22
- package/lib/types/step-binding-flags.d.ts +53 -53
- package/lib/types/step-binding-flags.js +59 -59
- package/lib/types/step-binding.d.ts +50 -50
- package/lib/types/step-binding.js +17 -17
- package/lib/types/types.d.ts +21 -21
- package/lib/types/types.js +2 -2
- package/lib/utils/helpers.d.ts +6 -6
- package/lib/utils/helpers.js +17 -17
- package/lib/utils/logger.d.ts +3 -3
- package/lib/utils/logger.js +29 -29
- package/lib/utils/our-callsite.d.ts +27 -27
- package/lib/utils/our-callsite.js +72 -72
- package/lib/version.d.ts +1 -1
- package/lib/version.js +5 -5
- package/package.json +16 -16
|
@@ -1,251 +1,251 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
const messages = __importStar(require("@cucumber/messages"));
|
|
27
|
-
const value_checker_1 = require("@cucumber/cucumber/lib/value_checker");
|
|
28
|
-
const managed_scenario_context_1 = require("./managed-scenario-context");
|
|
29
|
-
const utils_1 = require("./utils");
|
|
30
|
-
const helpers_1 = require("../utils/helpers");
|
|
31
|
-
const messages_1 = require("@cucumber/messages");
|
|
32
|
-
/**
|
|
33
|
-
* Custom implementation of the EventDataCollector from cucumber.js
|
|
34
|
-
*
|
|
35
|
-
* This implements all of the functions from the original EventDataCollector along
|
|
36
|
-
* with new functions to support binding to tsFlow tests.
|
|
37
|
-
*
|
|
38
|
-
* By extending the original version we're also reducing the amount of data stored
|
|
39
|
-
* during test runs because the original MessageCollector was capturing the same
|
|
40
|
-
* pickle and testCase data that the EventDataCollector does.
|
|
41
|
-
*/
|
|
42
|
-
class MessageCollector {
|
|
43
|
-
gherkinDocumentMap = {};
|
|
44
|
-
pickleMap = {};
|
|
45
|
-
testCaseMap = {};
|
|
46
|
-
testCaseAttemptDataMap = {};
|
|
47
|
-
undefinedParameterTypes = [];
|
|
48
|
-
testCaseRunningMap = {};
|
|
49
|
-
// Used during parallel execution to add the current pickle and testCase
|
|
50
|
-
// to a new Worker instance of the MessageCollector
|
|
51
|
-
addPickleAndTestCase(pickle, testCase) {
|
|
52
|
-
this.pickleMap[pickle.id] = pickle;
|
|
53
|
-
this.testCaseMap[testCase.id] = testCase;
|
|
54
|
-
}
|
|
55
|
-
hasFailures() {
|
|
56
|
-
for (const caseKey in this.testCaseAttemptDataMap) {
|
|
57
|
-
const stepResults = this.testCaseAttemptDataMap[caseKey].stepResults;
|
|
58
|
-
for (const key in stepResults) {
|
|
59
|
-
if (stepResults[key].status === messages_1.TestStepResultStatus.FAILED) {
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
getGherkinDocument(uri) {
|
|
67
|
-
return this.gherkinDocumentMap[uri];
|
|
68
|
-
}
|
|
69
|
-
getPickle(pickleId) {
|
|
70
|
-
return this.pickleMap[pickleId];
|
|
71
|
-
}
|
|
72
|
-
getTestCaseAttempts() {
|
|
73
|
-
return Object.keys(this.testCaseAttemptDataMap).map(testCaseStartedId => {
|
|
74
|
-
return this.getTestCaseAttempt(testCaseStartedId);
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
getTestCaseAttempt(testCaseStartedId) {
|
|
78
|
-
const testCaseAttemptData = this.testCaseAttemptDataMap[testCaseStartedId];
|
|
79
|
-
const testCase = this.testCaseMap[testCaseAttemptData.testCaseId];
|
|
80
|
-
const pickle = this.pickleMap[testCase.pickleId];
|
|
81
|
-
return {
|
|
82
|
-
gherkinDocument: this.gherkinDocumentMap[pickle.uri],
|
|
83
|
-
pickle,
|
|
84
|
-
testCase,
|
|
85
|
-
attempt: testCaseAttemptData.attempt,
|
|
86
|
-
willBeRetried: testCaseAttemptData.willBeRetried,
|
|
87
|
-
stepAttachments: testCaseAttemptData.stepAttachments,
|
|
88
|
-
stepResults: testCaseAttemptData.stepResults,
|
|
89
|
-
worstTestStepResult: testCaseAttemptData.worstTestStepResult
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
parseEnvelope(envelope) {
|
|
93
|
-
if (envelope.gherkinDocument && envelope.gherkinDocument.uri) {
|
|
94
|
-
this.gherkinDocumentMap[envelope.gherkinDocument.uri] = envelope.gherkinDocument;
|
|
95
|
-
}
|
|
96
|
-
else if (envelope.pickle && envelope.pickle.id) {
|
|
97
|
-
this.pickleMap[envelope.pickle.id] = envelope.pickle;
|
|
98
|
-
}
|
|
99
|
-
else if (envelope.undefinedParameterType) {
|
|
100
|
-
this.undefinedParameterTypes.push(envelope.undefinedParameterType);
|
|
101
|
-
}
|
|
102
|
-
else if (envelope.testCase && envelope.testCase.id) {
|
|
103
|
-
this.testCaseMap[envelope.testCase.id] = envelope.testCase;
|
|
104
|
-
}
|
|
105
|
-
else if (envelope.testCaseStarted) {
|
|
106
|
-
this.initTestCaseAttempt(envelope.testCaseStarted);
|
|
107
|
-
this.startTestCase(envelope.testCaseStarted);
|
|
108
|
-
}
|
|
109
|
-
else if (envelope.attachment) {
|
|
110
|
-
this.storeAttachment(envelope.attachment);
|
|
111
|
-
}
|
|
112
|
-
else if (envelope.testStepFinished) {
|
|
113
|
-
this.storeTestStepResult(envelope.testStepFinished);
|
|
114
|
-
}
|
|
115
|
-
else if (envelope.testCaseFinished) {
|
|
116
|
-
this.storeTestCaseResult(envelope.testCaseFinished);
|
|
117
|
-
this.endTestCase(envelope.testCaseFinished);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
initTestCaseAttempt(testCaseStarted) {
|
|
121
|
-
this.testCaseAttemptDataMap[testCaseStarted.id] = {
|
|
122
|
-
attempt: testCaseStarted.attempt,
|
|
123
|
-
willBeRetried: false,
|
|
124
|
-
testCaseId: testCaseStarted.testCaseId,
|
|
125
|
-
stepAttachments: {},
|
|
126
|
-
stepResults: {},
|
|
127
|
-
worstTestStepResult: {
|
|
128
|
-
duration: { seconds: 0, nanos: 0 },
|
|
129
|
-
status: messages.TestStepResultStatus.UNKNOWN
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
storeAttachment(attachment) {
|
|
134
|
-
const { testCaseStartedId, testStepId } = attachment;
|
|
135
|
-
if (testCaseStartedId && testStepId) {
|
|
136
|
-
const { stepAttachments } = this.testCaseAttemptDataMap[testCaseStartedId];
|
|
137
|
-
if ((0, value_checker_1.doesNotHaveValue)(stepAttachments[testStepId])) {
|
|
138
|
-
stepAttachments[testStepId] = [];
|
|
139
|
-
}
|
|
140
|
-
stepAttachments[testStepId].push(attachment);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
storeTestStepResult({ testCaseStartedId, testStepId, testStepResult }) {
|
|
144
|
-
this.testCaseAttemptDataMap[testCaseStartedId].stepResults[testStepId] = testStepResult;
|
|
145
|
-
}
|
|
146
|
-
storeTestCaseResult({ testCaseStartedId, willBeRetried }) {
|
|
147
|
-
const stepResults = Object.values(this.testCaseAttemptDataMap[testCaseStartedId].stepResults);
|
|
148
|
-
this.testCaseAttemptDataMap[testCaseStartedId].worstTestStepResult = messages.getWorstTestStepResult(stepResults);
|
|
149
|
-
this.testCaseAttemptDataMap[testCaseStartedId].willBeRetried = willBeRetried;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Gets the Pickle from hook parameters passed in from Cucumber
|
|
153
|
-
* to find a matching Pickle (scenario) and return the scenario Context
|
|
154
|
-
* @param hookParam
|
|
155
|
-
* @returns
|
|
156
|
-
*/
|
|
157
|
-
getHookScenarioContext(hookParam) {
|
|
158
|
-
let scenarioContext;
|
|
159
|
-
if (hookParam) {
|
|
160
|
-
const pickle = hookParam.pickle;
|
|
161
|
-
const scenario = this.pickleMap[pickle.id];
|
|
162
|
-
if (scenario && scenario.scenarioContext) {
|
|
163
|
-
scenarioContext = scenario.scenarioContext;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
return scenarioContext;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Uses StepPattern information to find a matching scenario
|
|
170
|
-
* and return the ScenarioContext
|
|
171
|
-
* @param stepBinding
|
|
172
|
-
* @returns
|
|
173
|
-
*/
|
|
174
|
-
getStepScenarioContext(stepBinding) {
|
|
175
|
-
let scenarioContext;
|
|
176
|
-
for (const [, pickle] of Object.entries(this.pickleMap)) {
|
|
177
|
-
const scenario = pickle;
|
|
178
|
-
for (const step of scenario.steps) {
|
|
179
|
-
if ((0, utils_1.hasMatchingStep)(stepBinding.stepPattern.toString(), step.text)) {
|
|
180
|
-
// if we have tags on the step binding check to see if it matches one in the
|
|
181
|
-
// current scenario, which also includes tags associated with the feature
|
|
182
|
-
if (stepBinding.tags && this.stepHasTags(stepBinding.tags)) {
|
|
183
|
-
if (scenario.tags.length > 0 &&
|
|
184
|
-
(0, utils_1.hasMatchingTags)(stepBinding.tags, scenario.tags.map(x => x.name))) {
|
|
185
|
-
scenarioContext = scenario.scenarioContext;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
scenarioContext = scenario.scenarioContext;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
if (scenarioContext)
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
if (scenarioContext)
|
|
196
|
-
break;
|
|
197
|
-
}
|
|
198
|
-
return scenarioContext;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Called when a test case (scenario) starts. Intercepting
|
|
202
|
-
* this message to initialize a new ScenarioContext
|
|
203
|
-
* @param testCaseStarted
|
|
204
|
-
*/
|
|
205
|
-
startTestCase(testCaseStarted) {
|
|
206
|
-
this.testCaseRunningMap[testCaseStarted.id] = testCaseStarted;
|
|
207
|
-
const scenario = this.getScenarioForTest(testCaseStarted.testCaseId);
|
|
208
|
-
if (scenario) {
|
|
209
|
-
const tags = scenario.tags.map(t => t.name);
|
|
210
|
-
scenario.scenarioContext = new managed_scenario_context_1.ManagedScenarioContext(scenario.name, tags);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Called when a test case (scenario) ends. Intercepting
|
|
215
|
-
* this message to dispose and clear the ScenarioContext
|
|
216
|
-
* @param testCaseFinished
|
|
217
|
-
*/
|
|
218
|
-
endTestCase(testCaseFinished) {
|
|
219
|
-
const testCase = this.testCaseRunningMap[testCaseFinished.testCaseStartedId];
|
|
220
|
-
if (testCase) {
|
|
221
|
-
const scenario = this.getScenarioForTest(testCase.testCaseId);
|
|
222
|
-
if (scenario && scenario.scenarioContext) {
|
|
223
|
-
scenario.scenarioContext.dispose();
|
|
224
|
-
scenario.scenarioContext = undefined;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Uses the testCaleId passed in to find the associated Pickle (scenario)
|
|
230
|
-
* @param testCaseId
|
|
231
|
-
* @returns
|
|
232
|
-
*/
|
|
233
|
-
getScenarioForTest(testCaseId) {
|
|
234
|
-
const testCase = this.testCaseMap[testCaseId];
|
|
235
|
-
if (testCase) {
|
|
236
|
-
return this.pickleMap[testCase.pickleId];
|
|
237
|
-
}
|
|
238
|
-
return undefined;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* StepBinding tags are initialized with an astrick when empty.
|
|
242
|
-
* Need to make sure tags has a value and not an astrick
|
|
243
|
-
* @param tags
|
|
244
|
-
* @returns
|
|
245
|
-
*/
|
|
246
|
-
stepHasTags(tags) {
|
|
247
|
-
return (0, helpers_1.hasStringValue)(tags) && !tags?.includes('*');
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
exports.default = MessageCollector;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const messages = __importStar(require("@cucumber/messages"));
|
|
27
|
+
const value_checker_1 = require("@cucumber/cucumber/lib/value_checker");
|
|
28
|
+
const managed_scenario_context_1 = require("./managed-scenario-context");
|
|
29
|
+
const utils_1 = require("./utils");
|
|
30
|
+
const helpers_1 = require("../utils/helpers");
|
|
31
|
+
const messages_1 = require("@cucumber/messages");
|
|
32
|
+
/**
|
|
33
|
+
* Custom implementation of the EventDataCollector from cucumber.js
|
|
34
|
+
*
|
|
35
|
+
* This implements all of the functions from the original EventDataCollector along
|
|
36
|
+
* with new functions to support binding to tsFlow tests.
|
|
37
|
+
*
|
|
38
|
+
* By extending the original version we're also reducing the amount of data stored
|
|
39
|
+
* during test runs because the original MessageCollector was capturing the same
|
|
40
|
+
* pickle and testCase data that the EventDataCollector does.
|
|
41
|
+
*/
|
|
42
|
+
class MessageCollector {
|
|
43
|
+
gherkinDocumentMap = {};
|
|
44
|
+
pickleMap = {};
|
|
45
|
+
testCaseMap = {};
|
|
46
|
+
testCaseAttemptDataMap = {};
|
|
47
|
+
undefinedParameterTypes = [];
|
|
48
|
+
testCaseRunningMap = {};
|
|
49
|
+
// Used during parallel execution to add the current pickle and testCase
|
|
50
|
+
// to a new Worker instance of the MessageCollector
|
|
51
|
+
addPickleAndTestCase(pickle, testCase) {
|
|
52
|
+
this.pickleMap[pickle.id] = pickle;
|
|
53
|
+
this.testCaseMap[testCase.id] = testCase;
|
|
54
|
+
}
|
|
55
|
+
hasFailures() {
|
|
56
|
+
for (const caseKey in this.testCaseAttemptDataMap) {
|
|
57
|
+
const stepResults = this.testCaseAttemptDataMap[caseKey].stepResults;
|
|
58
|
+
for (const key in stepResults) {
|
|
59
|
+
if (stepResults[key].status === messages_1.TestStepResultStatus.FAILED) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
getGherkinDocument(uri) {
|
|
67
|
+
return this.gherkinDocumentMap[uri];
|
|
68
|
+
}
|
|
69
|
+
getPickle(pickleId) {
|
|
70
|
+
return this.pickleMap[pickleId];
|
|
71
|
+
}
|
|
72
|
+
getTestCaseAttempts() {
|
|
73
|
+
return Object.keys(this.testCaseAttemptDataMap).map(testCaseStartedId => {
|
|
74
|
+
return this.getTestCaseAttempt(testCaseStartedId);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
getTestCaseAttempt(testCaseStartedId) {
|
|
78
|
+
const testCaseAttemptData = this.testCaseAttemptDataMap[testCaseStartedId];
|
|
79
|
+
const testCase = this.testCaseMap[testCaseAttemptData.testCaseId];
|
|
80
|
+
const pickle = this.pickleMap[testCase.pickleId];
|
|
81
|
+
return {
|
|
82
|
+
gherkinDocument: this.gherkinDocumentMap[pickle.uri],
|
|
83
|
+
pickle,
|
|
84
|
+
testCase,
|
|
85
|
+
attempt: testCaseAttemptData.attempt,
|
|
86
|
+
willBeRetried: testCaseAttemptData.willBeRetried,
|
|
87
|
+
stepAttachments: testCaseAttemptData.stepAttachments,
|
|
88
|
+
stepResults: testCaseAttemptData.stepResults,
|
|
89
|
+
worstTestStepResult: testCaseAttemptData.worstTestStepResult
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
parseEnvelope(envelope) {
|
|
93
|
+
if (envelope.gherkinDocument && envelope.gherkinDocument.uri) {
|
|
94
|
+
this.gherkinDocumentMap[envelope.gherkinDocument.uri] = envelope.gherkinDocument;
|
|
95
|
+
}
|
|
96
|
+
else if (envelope.pickle && envelope.pickle.id) {
|
|
97
|
+
this.pickleMap[envelope.pickle.id] = envelope.pickle;
|
|
98
|
+
}
|
|
99
|
+
else if (envelope.undefinedParameterType) {
|
|
100
|
+
this.undefinedParameterTypes.push(envelope.undefinedParameterType);
|
|
101
|
+
}
|
|
102
|
+
else if (envelope.testCase && envelope.testCase.id) {
|
|
103
|
+
this.testCaseMap[envelope.testCase.id] = envelope.testCase;
|
|
104
|
+
}
|
|
105
|
+
else if (envelope.testCaseStarted) {
|
|
106
|
+
this.initTestCaseAttempt(envelope.testCaseStarted);
|
|
107
|
+
this.startTestCase(envelope.testCaseStarted);
|
|
108
|
+
}
|
|
109
|
+
else if (envelope.attachment) {
|
|
110
|
+
this.storeAttachment(envelope.attachment);
|
|
111
|
+
}
|
|
112
|
+
else if (envelope.testStepFinished) {
|
|
113
|
+
this.storeTestStepResult(envelope.testStepFinished);
|
|
114
|
+
}
|
|
115
|
+
else if (envelope.testCaseFinished) {
|
|
116
|
+
this.storeTestCaseResult(envelope.testCaseFinished);
|
|
117
|
+
this.endTestCase(envelope.testCaseFinished);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
initTestCaseAttempt(testCaseStarted) {
|
|
121
|
+
this.testCaseAttemptDataMap[testCaseStarted.id] = {
|
|
122
|
+
attempt: testCaseStarted.attempt,
|
|
123
|
+
willBeRetried: false,
|
|
124
|
+
testCaseId: testCaseStarted.testCaseId,
|
|
125
|
+
stepAttachments: {},
|
|
126
|
+
stepResults: {},
|
|
127
|
+
worstTestStepResult: {
|
|
128
|
+
duration: { seconds: 0, nanos: 0 },
|
|
129
|
+
status: messages.TestStepResultStatus.UNKNOWN
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
storeAttachment(attachment) {
|
|
134
|
+
const { testCaseStartedId, testStepId } = attachment;
|
|
135
|
+
if (testCaseStartedId && testStepId) {
|
|
136
|
+
const { stepAttachments } = this.testCaseAttemptDataMap[testCaseStartedId];
|
|
137
|
+
if ((0, value_checker_1.doesNotHaveValue)(stepAttachments[testStepId])) {
|
|
138
|
+
stepAttachments[testStepId] = [];
|
|
139
|
+
}
|
|
140
|
+
stepAttachments[testStepId].push(attachment);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
storeTestStepResult({ testCaseStartedId, testStepId, testStepResult }) {
|
|
144
|
+
this.testCaseAttemptDataMap[testCaseStartedId].stepResults[testStepId] = testStepResult;
|
|
145
|
+
}
|
|
146
|
+
storeTestCaseResult({ testCaseStartedId, willBeRetried }) {
|
|
147
|
+
const stepResults = Object.values(this.testCaseAttemptDataMap[testCaseStartedId].stepResults);
|
|
148
|
+
this.testCaseAttemptDataMap[testCaseStartedId].worstTestStepResult = messages.getWorstTestStepResult(stepResults);
|
|
149
|
+
this.testCaseAttemptDataMap[testCaseStartedId].willBeRetried = willBeRetried;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Gets the Pickle from hook parameters passed in from Cucumber
|
|
153
|
+
* to find a matching Pickle (scenario) and return the scenario Context
|
|
154
|
+
* @param hookParam
|
|
155
|
+
* @returns
|
|
156
|
+
*/
|
|
157
|
+
getHookScenarioContext(hookParam) {
|
|
158
|
+
let scenarioContext;
|
|
159
|
+
if (hookParam) {
|
|
160
|
+
const pickle = hookParam.pickle;
|
|
161
|
+
const scenario = this.pickleMap[pickle.id];
|
|
162
|
+
if (scenario && scenario.scenarioContext) {
|
|
163
|
+
scenarioContext = scenario.scenarioContext;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return scenarioContext;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Uses StepPattern information to find a matching scenario
|
|
170
|
+
* and return the ScenarioContext
|
|
171
|
+
* @param stepBinding
|
|
172
|
+
* @returns
|
|
173
|
+
*/
|
|
174
|
+
getStepScenarioContext(stepBinding) {
|
|
175
|
+
let scenarioContext;
|
|
176
|
+
for (const [, pickle] of Object.entries(this.pickleMap)) {
|
|
177
|
+
const scenario = pickle;
|
|
178
|
+
for (const step of scenario.steps) {
|
|
179
|
+
if ((0, utils_1.hasMatchingStep)(stepBinding.stepPattern.toString(), step.text)) {
|
|
180
|
+
// if we have tags on the step binding check to see if it matches one in the
|
|
181
|
+
// current scenario, which also includes tags associated with the feature
|
|
182
|
+
if (stepBinding.tags && this.stepHasTags(stepBinding.tags)) {
|
|
183
|
+
if (scenario.tags.length > 0 &&
|
|
184
|
+
(0, utils_1.hasMatchingTags)(stepBinding.tags, scenario.tags.map(x => x.name))) {
|
|
185
|
+
scenarioContext = scenario.scenarioContext;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
scenarioContext = scenario.scenarioContext;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (scenarioContext)
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
if (scenarioContext)
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
return scenarioContext;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Called when a test case (scenario) starts. Intercepting
|
|
202
|
+
* this message to initialize a new ScenarioContext
|
|
203
|
+
* @param testCaseStarted
|
|
204
|
+
*/
|
|
205
|
+
startTestCase(testCaseStarted) {
|
|
206
|
+
this.testCaseRunningMap[testCaseStarted.id] = testCaseStarted;
|
|
207
|
+
const scenario = this.getScenarioForTest(testCaseStarted.testCaseId);
|
|
208
|
+
if (scenario) {
|
|
209
|
+
const tags = scenario.tags.map(t => t.name);
|
|
210
|
+
scenario.scenarioContext = new managed_scenario_context_1.ManagedScenarioContext(scenario.name, tags);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Called when a test case (scenario) ends. Intercepting
|
|
215
|
+
* this message to dispose and clear the ScenarioContext
|
|
216
|
+
* @param testCaseFinished
|
|
217
|
+
*/
|
|
218
|
+
endTestCase(testCaseFinished) {
|
|
219
|
+
const testCase = this.testCaseRunningMap[testCaseFinished.testCaseStartedId];
|
|
220
|
+
if (testCase) {
|
|
221
|
+
const scenario = this.getScenarioForTest(testCase.testCaseId);
|
|
222
|
+
if (scenario && scenario.scenarioContext) {
|
|
223
|
+
scenario.scenarioContext.dispose();
|
|
224
|
+
scenario.scenarioContext = undefined;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Uses the testCaleId passed in to find the associated Pickle (scenario)
|
|
230
|
+
* @param testCaseId
|
|
231
|
+
* @returns
|
|
232
|
+
*/
|
|
233
|
+
getScenarioForTest(testCaseId) {
|
|
234
|
+
const testCase = this.testCaseMap[testCaseId];
|
|
235
|
+
if (testCase) {
|
|
236
|
+
return this.pickleMap[testCase.pickleId];
|
|
237
|
+
}
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* StepBinding tags are initialized with an astrick when empty.
|
|
242
|
+
* Need to make sure tags has a value and not an astrick
|
|
243
|
+
* @param tags
|
|
244
|
+
* @returns
|
|
245
|
+
*/
|
|
246
|
+
stepHasTags(tags) {
|
|
247
|
+
return (0, helpers_1.hasStringValue)(tags) && !tags?.includes('*');
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
exports.default = MessageCollector;
|
|
251
251
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnZS1jb2xsZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY3VjdW1iZXIvbWVzc2FnZS1jb2xsZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDZEQUErQztBQUMvQyx3RUFBd0U7QUFFeEUseUVBQW9FO0FBQ3BFLG1DQUEyRDtBQUMzRCw4Q0FBa0Q7QUFDbEQsaURBQTBEO0FBMEIxRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFxQixnQkFBZ0I7SUFDNUIsa0JBQWtCLEdBQTZDLEVBQUUsQ0FBQztJQUNsRSxTQUFTLEdBQW9DLEVBQUUsQ0FBQztJQUNoRCxXQUFXLEdBQXNDLEVBQUUsQ0FBQztJQUNwRCxzQkFBc0IsR0FBeUMsRUFBRSxDQUFDO0lBQ2pFLHVCQUF1QixHQUFzQyxFQUFFLENBQUM7SUFDakUsa0JBQWtCLEdBQTZDLEVBQUUsQ0FBQztJQUUxRSx3RUFBd0U7SUFDeEUsbURBQW1EO0lBQ25ELG9CQUFvQixDQUFDLE1BQXVCLEVBQUUsUUFBMkI7UUFDeEUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQ25DLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQztJQUMxQyxDQUFDO0lBRUQsV0FBVztRQUNWLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLHNCQUFzQixFQUFFO1lBQ2xELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLENBQUM7WUFDckUsS0FBSyxNQUFNLEdBQUcsSUFBSSxXQUFXLEVBQUU7Z0JBQzlCLElBQUksV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sS0FBSywrQkFBb0IsQ0FBQyxNQUFNLEVBQUU7b0JBQzVELE9BQU8sSUFBSSxDQUFDO2lCQUNaO2FB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
|