@lynxwall/cucumber-tsflow 6.5.7 → 7.0.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 +20 -10
- package/api/index.d.ts +6 -0
- package/bin/cucumber-tsflow +3 -3
- package/bin/cucumber-tsflow.js +3 -0
- package/lib/api/index.d.ts +17 -0
- package/lib/api/index.js +30 -0
- package/lib/api/index.js.map +1 -0
- package/lib/api/load-configuration.d.ts +21 -0
- package/lib/api/load-configuration.js +127 -0
- package/lib/api/load-configuration.js.map +1 -0
- package/lib/api/load-support.d.ts +10 -0
- package/lib/api/load-support.js +48 -0
- package/lib/api/load-support.js.map +1 -0
- package/lib/api/run-cucumber.d.ts +16 -0
- package/lib/api/run-cucumber.js +151 -0
- package/lib/api/run-cucumber.js.map +1 -0
- package/lib/api/wrapper.mjs +6 -0
- package/lib/behave.js +18 -8
- package/lib/behave.js.map +1 -0
- package/lib/bindings/binding-context.d.ts +17 -0
- package/lib/bindings/binding-context.js +36 -0
- package/lib/bindings/binding-context.js.map +1 -0
- package/lib/{cucumber → bindings}/binding-decorator.d.ts +2 -2
- package/lib/bindings/binding-decorator.js +201 -0
- package/lib/bindings/binding-decorator.js.map +1 -0
- package/lib/{cucumber → bindings}/binding-registry.d.ts +8 -8
- package/lib/bindings/binding-registry.js +232 -0
- package/lib/bindings/binding-registry.js.map +1 -0
- package/lib/{cucumber → bindings}/hook-decorators.d.ts +6 -6
- package/lib/{cucumber → bindings}/hook-decorators.js +17 -15
- package/lib/bindings/hook-decorators.js.map +1 -0
- package/lib/{cucumber/step-definition-decorators.d.ts → bindings/step-decorators.d.ts} +3 -3
- package/lib/bindings/step-decorators.js +97 -0
- package/lib/bindings/step-decorators.js.map +1 -0
- package/lib/cli/argv-parser.js +3 -3
- package/lib/cli/argv-parser.js.map +1 -0
- package/lib/cli/index.d.ts +1 -2
- package/lib/cli/index.js +12 -40
- package/lib/cli/index.js.map +1 -0
- package/lib/cli/load-configuration.d.ts +2 -1
- package/lib/cli/load-configuration.js +12 -10
- package/lib/cli/load-configuration.js.map +1 -0
- package/lib/cli/run.js +5 -7
- package/lib/cli/run.js.map +1 -0
- package/lib/cucumber/coordinator.d.ts +15 -0
- package/lib/cucumber/coordinator.js +40 -0
- package/lib/cucumber/coordinator.js.map +1 -0
- package/lib/cucumber/make-runtime.d.ts +12 -16
- package/lib/cucumber/make-runtime.js +10 -33
- package/lib/cucumber/make-runtime.js.map +1 -0
- package/lib/cucumber/managed-scenario-context.d.ts +3 -3
- package/lib/cucumber/managed-scenario-context.js +24 -24
- package/lib/cucumber/managed-scenario-context.js.map +1 -0
- package/lib/cucumber/message-collector.d.ts +3 -0
- package/lib/cucumber/message-collector.js +38 -16
- package/lib/cucumber/message-collector.js.map +1 -0
- package/lib/cucumber/parallel/adapter.d.ts +46 -0
- package/lib/cucumber/parallel/adapter.js +156 -0
- package/lib/cucumber/parallel/adapter.js.map +1 -0
- package/lib/cucumber/parallel/run-worker.d.ts +1 -1
- package/lib/cucumber/parallel/run-worker.js +8 -16
- package/lib/cucumber/parallel/run-worker.js.map +1 -0
- package/lib/cucumber/parallel/worker.d.ts +10 -14
- package/lib/cucumber/parallel/worker.js +59 -68
- package/lib/cucumber/parallel/worker.js.map +1 -0
- package/lib/cucumber/run-cucumber.d.ts +5 -3
- package/lib/cucumber/run-cucumber.js +59 -38
- package/lib/cucumber/run-cucumber.js.map +1 -0
- package/lib/cucumber/serial/adapter.d.ts +12 -0
- package/lib/cucumber/serial/adapter.js +24 -0
- package/lib/cucumber/serial/adapter.js.map +1 -0
- package/lib/cucumber/test-case-info.js +1 -1
- package/lib/cucumber/test-case-info.js.map +1 -0
- package/lib/cucumber/test-case-runner.d.ts +2 -2
- package/lib/cucumber/test-case-runner.js +47 -19
- package/lib/cucumber/test-case-runner.js.map +1 -0
- package/lib/cucumber/utils.js +1 -1
- package/lib/cucumber/utils.js.map +1 -0
- package/lib/cucumber/worker.d.ts +17 -0
- package/lib/cucumber/worker.js +57 -0
- package/lib/cucumber/worker.js.map +1 -0
- package/lib/esnode.d.ts +1 -0
- package/lib/esnode.js +5 -7
- package/lib/esnode.js.map +1 -0
- package/lib/esvue.js +3 -6
- package/lib/esvue.js.map +1 -0
- package/lib/formatters/behave-json-formatter.js +18 -8
- package/lib/formatters/behave-json-formatter.js.map +1 -0
- package/lib/formatters/junit-bamboo-formatter.js +2 -2
- package/lib/formatters/junit-bamboo-formatter.js.map +1 -0
- package/lib/formatters/tsflow-snippet-syntax.js +2 -3
- package/lib/formatters/tsflow-snippet-syntax.js.map +1 -0
- package/lib/gherkin/configuration.d.ts +4 -4
- package/lib/gherkin/configuration.js +1 -1
- package/lib/gherkin/configuration.js.map +1 -0
- package/lib/gherkin/gherkin-feature.js +18 -8
- package/lib/gherkin/gherkin-feature.js.map +1 -0
- package/lib/gherkin/gherkin-manager.js +2 -2
- package/lib/gherkin/gherkin-manager.js.map +1 -0
- package/lib/gherkin/models.d.ts +1 -1
- package/lib/gherkin/models.js +1 -1
- package/lib/gherkin/models.js.map +1 -0
- package/lib/index.d.ts +6 -4
- package/lib/index.js +30 -18
- package/lib/index.js.map +1 -0
- package/lib/junitbamboo.js +18 -8
- package/lib/junitbamboo.js.map +1 -0
- package/lib/runtime/coordinator.d.ts +15 -0
- package/lib/runtime/coordinator.js +40 -0
- package/lib/runtime/coordinator.js.map +1 -0
- package/lib/runtime/make-runtime.d.ts +22 -0
- package/lib/runtime/make-runtime.js +17 -0
- package/lib/runtime/make-runtime.js.map +1 -0
- package/lib/runtime/managed-scenario-context.d.ts +52 -0
- package/lib/runtime/managed-scenario-context.js +149 -0
- package/lib/runtime/managed-scenario-context.js.map +1 -0
- package/lib/runtime/message-collector.d.ts +98 -0
- package/lib/runtime/message-collector.js +284 -0
- package/lib/runtime/message-collector.js.map +1 -0
- package/lib/runtime/parallel/adapter.d.ts +47 -0
- package/lib/runtime/parallel/adapter.js +159 -0
- package/lib/runtime/parallel/adapter.js.map +1 -0
- package/lib/runtime/parallel/run-worker.d.ts +1 -0
- package/lib/runtime/parallel/run-worker.js +24 -0
- package/lib/runtime/parallel/run-worker.js.map +1 -0
- package/lib/runtime/parallel/types.d.ts +13 -0
- package/lib/runtime/parallel/types.js +3 -0
- package/lib/runtime/parallel/types.js.map +1 -0
- package/lib/runtime/parallel/worker.d.ts +44 -0
- package/lib/runtime/parallel/worker.js +118 -0
- package/lib/runtime/parallel/worker.js.map +1 -0
- package/lib/runtime/serial/adapter.d.ts +12 -0
- package/lib/runtime/serial/adapter.js +24 -0
- package/lib/runtime/serial/adapter.js.map +1 -0
- package/lib/runtime/test-case-info.d.ts +23 -0
- package/lib/runtime/test-case-info.js +3 -0
- package/lib/runtime/test-case-info.js.map +1 -0
- package/lib/runtime/test-case-runner.d.ts +48 -0
- package/lib/runtime/test-case-runner.js +359 -0
- package/lib/runtime/test-case-runner.js.map +1 -0
- package/lib/runtime/utils.d.ts +16 -0
- package/lib/runtime/utils.js +78 -0
- package/lib/runtime/utils.js.map +1 -0
- package/lib/runtime/worker.d.ts +17 -0
- package/lib/runtime/worker.js +57 -0
- package/lib/runtime/worker.js.map +1 -0
- package/lib/snippet.js +20 -10
- package/lib/snippet.js.map +1 -0
- package/lib/transpilers/esbuild-transpiler.d.ts +1 -1
- package/lib/transpilers/esbuild-transpiler.js +1 -1
- package/lib/transpilers/esbuild-transpiler.js.map +1 -0
- package/lib/transpilers/esbuild.js +4 -4
- package/lib/transpilers/esbuild.js.map +1 -0
- package/lib/transpilers/vue-sfc/compiler.js +1 -1
- package/lib/transpilers/vue-sfc/compiler.js.map +1 -0
- package/lib/transpilers/vue-sfc/index.d.ts +4 -4
- package/lib/transpilers/vue-sfc/index.js +1 -2
- package/lib/transpilers/vue-sfc/index.js.map +1 -0
- package/lib/transpilers/vue-sfc/main.d.ts +1 -1
- package/lib/transpilers/vue-sfc/main.js +1 -1
- package/lib/transpilers/vue-sfc/main.js.map +1 -0
- package/lib/transpilers/vue-sfc/script.js +1 -2
- package/lib/transpilers/vue-sfc/script.js.map +1 -0
- package/lib/transpilers/vue-sfc/template.d.ts +1 -1
- package/lib/transpilers/vue-sfc/template.js +2 -3
- package/lib/transpilers/vue-sfc/template.js.map +1 -0
- package/lib/transpilers/vue-sfc/types.d.ts +2 -2
- package/lib/transpilers/vue-sfc/types.js +1 -1
- package/lib/transpilers/vue-sfc/types.js.map +1 -0
- package/lib/transpilers/vue-sfc/utils/descriptorCache.js +1 -1
- package/lib/transpilers/vue-sfc/utils/descriptorCache.js.map +1 -0
- package/lib/transpilers/vue-sfc/utils/error.js +1 -1
- package/lib/transpilers/vue-sfc/utils/error.js.map +1 -0
- package/lib/transpilers/vue-sfc/utils/query.js +1 -1
- package/lib/transpilers/vue-sfc/utils/query.js.map +1 -0
- package/lib/tsconfig.node.tsbuildinfo +1 -0
- package/lib/tsnode.d.ts +1 -0
- package/lib/tsnode.js +4 -6
- package/lib/tsnode.js.map +1 -0
- package/lib/tsvue.js +3 -6
- package/lib/tsvue.js.map +1 -0
- package/lib/types/parallel.d.ts +11 -0
- package/lib/types/parallel.js +3 -0
- package/lib/types/parallel.js.map +1 -0
- package/lib/types/scenario-context.js +1 -1
- package/lib/types/scenario-context.js.map +1 -0
- package/lib/types/scenario-info.js +1 -1
- package/lib/types/scenario-info.js.map +1 -0
- package/lib/types/step-binding-flags.js +1 -1
- package/lib/types/step-binding-flags.js.map +1 -0
- package/lib/types/step-binding.d.ts +30 -20
- package/lib/types/step-binding.js +1 -1
- package/lib/types/step-binding.js.map +1 -0
- package/lib/types/types.js +1 -1
- package/lib/types/types.js.map +1 -0
- package/lib/utils/helpers.js +1 -1
- package/lib/utils/helpers.js.map +1 -0
- package/lib/utils/logger.d.ts +2 -2
- package/lib/utils/logger.js +7 -26
- package/lib/utils/logger.js.map +1 -0
- package/lib/utils/our-callsite.js +18 -8
- package/lib/utils/our-callsite.js.map +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +2 -2
- package/lib/version.js.map +1 -0
- package/lib/wrapper.mjs +21 -0
- package/package.json +68 -27
- package/lib/cucumber/binding-decorator.js +0 -181
- package/lib/cucumber/binding-registry.js +0 -231
- package/lib/cucumber/parallel/coordinator.d.ts +0 -79
- package/lib/cucumber/parallel/coordinator.js +0 -247
- package/lib/cucumber/runtime.d.ts +0 -40
- package/lib/cucumber/runtime.js +0 -85
- package/lib/cucumber/step-definition-decorators.js +0 -92
|
@@ -0,0 +1,284 @@
|
|
|
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 () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const messages = __importStar(require("@cucumber/messages"));
|
|
37
|
+
const value_checker_1 = require("@cucumber/cucumber/lib/value_checker");
|
|
38
|
+
const managed_scenario_context_1 = require("./managed-scenario-context");
|
|
39
|
+
const utils_1 = require("./utils");
|
|
40
|
+
const helpers_1 = require("../utils/helpers");
|
|
41
|
+
const messages_1 = require("@cucumber/messages");
|
|
42
|
+
/**
|
|
43
|
+
* Custom implementation of the EventDataCollector from cucumber.js
|
|
44
|
+
*
|
|
45
|
+
* This implements all of the functions from the original EventDataCollector along
|
|
46
|
+
* with new functions to support binding to tsFlow tests.
|
|
47
|
+
*
|
|
48
|
+
* By extending the original version we're also reducing the amount of data stored
|
|
49
|
+
* during test runs because the original MessageCollector was capturing the same
|
|
50
|
+
* pickle and testCase data that the EventDataCollector does.
|
|
51
|
+
*/
|
|
52
|
+
class MessageCollector {
|
|
53
|
+
gherkinDocumentMap = {};
|
|
54
|
+
pickleMap = {};
|
|
55
|
+
testCaseMap = {};
|
|
56
|
+
testCaseAttemptDataMap = {};
|
|
57
|
+
undefinedParameterTypes = [];
|
|
58
|
+
testCaseRunningMap = {};
|
|
59
|
+
constructor(eventBroadcaster) {
|
|
60
|
+
eventBroadcaster.on('envelope', this.parseEnvelope.bind(this));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Reset this message collector for a new parallel test run.
|
|
64
|
+
* @param messageData Gerkin information from initial load
|
|
65
|
+
*/
|
|
66
|
+
reset(messageData) {
|
|
67
|
+
this.gherkinDocumentMap = messageData.gherkinDocumentMap;
|
|
68
|
+
this.pickleMap = messageData.pickleMap;
|
|
69
|
+
this.testCaseMap = messageData.testCaseMap;
|
|
70
|
+
this.testCaseAttemptDataMap = {};
|
|
71
|
+
this.undefinedParameterTypes = [];
|
|
72
|
+
this.testCaseRunningMap = {};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get Gerkin message data for parallel runs
|
|
76
|
+
* @returns Gerkin informaion loaded during startup
|
|
77
|
+
*/
|
|
78
|
+
getMessageData() {
|
|
79
|
+
const data = {};
|
|
80
|
+
data.gherkinDocumentMap = this.gherkinDocumentMap;
|
|
81
|
+
data.pickleMap = this.pickleMap;
|
|
82
|
+
data.testCaseMap = this.testCaseMap;
|
|
83
|
+
return data;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Check for failures in a test run
|
|
87
|
+
* @returns true if there are failures in the last test case attempt
|
|
88
|
+
*/
|
|
89
|
+
hasFailures() {
|
|
90
|
+
for (const caseKey in this.testCaseAttemptDataMap) {
|
|
91
|
+
const stepResults = this.testCaseAttemptDataMap[caseKey].stepResults;
|
|
92
|
+
for (const key in stepResults) {
|
|
93
|
+
if (stepResults[key].status === messages_1.TestStepResultStatus.FAILED) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
getGherkinDocument(uri) {
|
|
101
|
+
return this.gherkinDocumentMap[uri];
|
|
102
|
+
}
|
|
103
|
+
getPickle(pickleId) {
|
|
104
|
+
return this.pickleMap[pickleId];
|
|
105
|
+
}
|
|
106
|
+
getTestCaseAttempts() {
|
|
107
|
+
return Object.keys(this.testCaseAttemptDataMap).map(testCaseStartedId => {
|
|
108
|
+
return this.getTestCaseAttempt(testCaseStartedId);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
getTestCaseAttempt(testCaseStartedId) {
|
|
112
|
+
const testCaseAttemptData = this.testCaseAttemptDataMap[testCaseStartedId];
|
|
113
|
+
const testCase = this.testCaseMap[testCaseAttemptData.testCaseId];
|
|
114
|
+
const pickle = this.pickleMap[testCase.pickleId];
|
|
115
|
+
return {
|
|
116
|
+
gherkinDocument: this.gherkinDocumentMap[pickle.uri],
|
|
117
|
+
pickle,
|
|
118
|
+
testCase,
|
|
119
|
+
attempt: testCaseAttemptData.attempt,
|
|
120
|
+
willBeRetried: testCaseAttemptData.willBeRetried,
|
|
121
|
+
stepAttachments: testCaseAttemptData.stepAttachments,
|
|
122
|
+
stepResults: testCaseAttemptData.stepResults,
|
|
123
|
+
worstTestStepResult: testCaseAttemptData.worstTestStepResult
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
parseEnvelope(envelope) {
|
|
127
|
+
if ((0, value_checker_1.doesHaveValue)(envelope.gherkinDocument)) {
|
|
128
|
+
this.gherkinDocumentMap[envelope.gherkinDocument.uri] = envelope.gherkinDocument;
|
|
129
|
+
}
|
|
130
|
+
else if ((0, value_checker_1.doesHaveValue)(envelope.pickle)) {
|
|
131
|
+
this.pickleMap[envelope.pickle.id] = envelope.pickle;
|
|
132
|
+
}
|
|
133
|
+
else if ((0, value_checker_1.doesHaveValue)(envelope.undefinedParameterType)) {
|
|
134
|
+
this.undefinedParameterTypes.push(envelope.undefinedParameterType);
|
|
135
|
+
}
|
|
136
|
+
else if ((0, value_checker_1.doesHaveValue)(envelope.testCase)) {
|
|
137
|
+
this.testCaseMap[envelope.testCase.id] = envelope.testCase;
|
|
138
|
+
}
|
|
139
|
+
else if ((0, value_checker_1.doesHaveValue)(envelope.testCaseStarted)) {
|
|
140
|
+
this.initTestCaseAttempt(envelope.testCaseStarted);
|
|
141
|
+
this.startTestCase(envelope.testCaseStarted);
|
|
142
|
+
}
|
|
143
|
+
else if ((0, value_checker_1.doesHaveValue)(envelope.attachment)) {
|
|
144
|
+
this.storeAttachment(envelope.attachment);
|
|
145
|
+
}
|
|
146
|
+
else if ((0, value_checker_1.doesHaveValue)(envelope.testStepFinished)) {
|
|
147
|
+
this.storeTestStepResult(envelope.testStepFinished);
|
|
148
|
+
}
|
|
149
|
+
else if ((0, value_checker_1.doesHaveValue)(envelope.testCaseFinished)) {
|
|
150
|
+
this.storeTestCaseResult(envelope.testCaseFinished);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
initTestCaseAttempt(testCaseStarted) {
|
|
154
|
+
this.testCaseAttemptDataMap[testCaseStarted.id] = {
|
|
155
|
+
attempt: testCaseStarted.attempt,
|
|
156
|
+
willBeRetried: false,
|
|
157
|
+
testCaseId: testCaseStarted.testCaseId,
|
|
158
|
+
stepAttachments: {},
|
|
159
|
+
stepResults: {},
|
|
160
|
+
worstTestStepResult: {
|
|
161
|
+
duration: { seconds: 0, nanos: 0 },
|
|
162
|
+
status: messages.TestStepResultStatus.UNKNOWN
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
storeAttachment(attachment) {
|
|
167
|
+
const { testCaseStartedId, testStepId } = attachment;
|
|
168
|
+
if (testCaseStartedId && testStepId) {
|
|
169
|
+
const { stepAttachments } = this.testCaseAttemptDataMap[testCaseStartedId];
|
|
170
|
+
if ((0, value_checker_1.doesNotHaveValue)(stepAttachments[testStepId])) {
|
|
171
|
+
stepAttachments[testStepId] = [];
|
|
172
|
+
}
|
|
173
|
+
stepAttachments[testStepId].push(attachment);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
storeTestStepResult({ testCaseStartedId, testStepId, testStepResult }) {
|
|
177
|
+
this.testCaseAttemptDataMap[testCaseStartedId].stepResults[testStepId] = testStepResult;
|
|
178
|
+
}
|
|
179
|
+
storeTestCaseResult({ testCaseStartedId, willBeRetried }) {
|
|
180
|
+
const stepResults = Object.values(this.testCaseAttemptDataMap[testCaseStartedId].stepResults);
|
|
181
|
+
this.testCaseAttemptDataMap[testCaseStartedId].worstTestStepResult = messages.getWorstTestStepResult(stepResults);
|
|
182
|
+
this.testCaseAttemptDataMap[testCaseStartedId].willBeRetried = willBeRetried;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Gets the Pickle from hook parameters passed in from Cucumber
|
|
186
|
+
* to find a matching Pickle (scenario) and return the scenario Context
|
|
187
|
+
* @param hookParam
|
|
188
|
+
* @returns
|
|
189
|
+
*/
|
|
190
|
+
getHookScenarioContext(hookParam) {
|
|
191
|
+
let scenarioContext;
|
|
192
|
+
if (hookParam) {
|
|
193
|
+
const pickle = hookParam.pickle;
|
|
194
|
+
const scenario = this.pickleMap[pickle.id];
|
|
195
|
+
if (scenario && scenario.scenarioContext) {
|
|
196
|
+
scenarioContext = scenario.scenarioContext;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return scenarioContext;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Uses StepPattern information to find a matching scenario
|
|
203
|
+
* and return the ScenarioContext
|
|
204
|
+
* @param stepBinding
|
|
205
|
+
* @returns
|
|
206
|
+
*/
|
|
207
|
+
getStepScenarioContext(stepBinding) {
|
|
208
|
+
let scenarioContext;
|
|
209
|
+
for (const [, pickle] of Object.entries(this.pickleMap)) {
|
|
210
|
+
const scenario = pickle;
|
|
211
|
+
for (const step of scenario.steps) {
|
|
212
|
+
if ((0, utils_1.hasMatchingStep)(stepBinding.stepPattern.toString(), step.text)) {
|
|
213
|
+
// if we have tags on the step binding check to see if it matches one in the
|
|
214
|
+
// current scenario, which also includes tags associated with the feature
|
|
215
|
+
if (stepBinding.tags && this.stepHasTags(stepBinding.tags)) {
|
|
216
|
+
if (scenario.tags.length > 0 &&
|
|
217
|
+
(0, utils_1.hasMatchingTags)(stepBinding.tags, scenario.tags.map(x => x.name))) {
|
|
218
|
+
scenarioContext = scenario.scenarioContext;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
scenarioContext = scenario.scenarioContext;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (scenarioContext)
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
if (scenarioContext)
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
return scenarioContext;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Called when a test case (scenario) starts. Intercepting
|
|
235
|
+
* this message to initialize a new ScenarioContext
|
|
236
|
+
* @param testCaseStarted
|
|
237
|
+
*/
|
|
238
|
+
startTestCase(testCaseStarted) {
|
|
239
|
+
this.testCaseRunningMap[testCaseStarted.id] = testCaseStarted;
|
|
240
|
+
const scenario = this.getScenarioForTest(testCaseStarted.testCaseId);
|
|
241
|
+
if (scenario) {
|
|
242
|
+
const tags = scenario.tags.map(t => t.name);
|
|
243
|
+
scenario.scenarioContext = new managed_scenario_context_1.ManagedScenarioContext(scenario.name, tags);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Called when a test case (scenario) ends. Intercepting
|
|
248
|
+
* this message to dispose and clear the ScenarioContext
|
|
249
|
+
* @param testCaseFinished
|
|
250
|
+
*/
|
|
251
|
+
async endTestCase(endTestCase) {
|
|
252
|
+
const testCase = this.testCaseRunningMap[endTestCase.testCaseStartedId];
|
|
253
|
+
if (testCase) {
|
|
254
|
+
const scenario = this.getScenarioForTest(testCase.testCaseId);
|
|
255
|
+
if (scenario && scenario.scenarioContext) {
|
|
256
|
+
await scenario.scenarioContext.dispose(endTestCase);
|
|
257
|
+
scenario.scenarioContext = undefined;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Uses the testCaleId passed in to find the associated Pickle (scenario)
|
|
263
|
+
* @param testCaseId
|
|
264
|
+
* @returns
|
|
265
|
+
*/
|
|
266
|
+
getScenarioForTest(testCaseId) {
|
|
267
|
+
const testCase = this.testCaseMap[testCaseId];
|
|
268
|
+
if (testCase) {
|
|
269
|
+
return this.pickleMap[testCase.pickleId];
|
|
270
|
+
}
|
|
271
|
+
return undefined;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* StepBinding tags are initialized with an astrick when empty.
|
|
275
|
+
* Need to make sure tags has a value and not an astrick
|
|
276
|
+
* @param tags
|
|
277
|
+
* @returns
|
|
278
|
+
*/
|
|
279
|
+
stepHasTags(tags) {
|
|
280
|
+
return (0, helpers_1.hasStringValue)(tags) && !tags?.includes('*');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
exports.default = MessageCollector;
|
|
284
|
+
//# sourceMappingURL=message-collector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-collector.js","sourceRoot":"","sources":["../../src/runtime/message-collector.ts"],"names":[],"mappings":"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","sourcesContent":["import * as messages from '@cucumber/messages';\r\nimport { doesHaveValue, doesNotHaveValue } from '@cucumber/cucumber/lib/value_checker';\r\nimport { StepBinding } from '../types/step-binding';\r\nimport { ManagedScenarioContext } from './managed-scenario-context';\r\nimport { hasMatchingStep, hasMatchingTags } from './utils';\r\nimport { hasStringValue } from '../utils/helpers';\r\nimport { TestStepResultStatus } from '@cucumber/messages';\r\nimport EventEmitter from 'events';\r\nimport { EndTestCaseInfo } from './test-case-info';\r\nimport { IMessageData } from './parallel/types';\r\n\r\ninterface ITestCaseAttemptData {\r\n\tattempt: number;\r\n\twillBeRetried: boolean;\r\n\ttestCaseId: string;\r\n\tstepAttachments: Record<string, messages.Attachment[]>;\r\n\tstepResults: Record<string, messages.TestStepResult>;\r\n\tworstTestStepResult: messages.TestStepResult;\r\n}\r\n\r\nexport interface ITestCaseAttempt {\r\n\tattempt: number;\r\n\twillBeRetried: boolean;\r\n\tgherkinDocument: messages.GherkinDocument;\r\n\tpickle: messages.Pickle;\r\n\tstepAttachments: Record<string, messages.Attachment[]>;\r\n\tstepResults: Record<string, messages.TestStepResult>;\r\n\ttestCase: messages.TestCase;\r\n\tworstTestStepResult: messages.TestStepResult;\r\n}\r\n\r\ninterface IScenario extends messages.Pickle {\r\n\tscenarioContext: ManagedScenarioContext | undefined;\r\n}\r\n\r\n/**\r\n * Custom implementation of the EventDataCollector from cucumber.js\r\n *\r\n * This implements all of the functions from the original EventDataCollector along\r\n * with new functions to support binding to tsFlow tests.\r\n *\r\n * By extending the original version we're also reducing the amount of data stored\r\n * during test runs because the original MessageCollector was capturing the same\r\n * pickle and testCase data that the EventDataCollector does.\r\n */\r\nexport default class MessageCollector {\r\n\tprivate gherkinDocumentMap: Record<string, messages.GherkinDocument> = {};\r\n\tprivate pickleMap: Record<string, messages.Pickle> = {};\r\n\tprivate testCaseMap: Record<string, messages.TestCase> = {};\r\n\tprivate testCaseAttemptDataMap: Record<string, ITestCaseAttemptData> = {};\r\n\tprivate undefinedParameterTypes: messages.UndefinedParameterType[] = [];\r\n\tprivate testCaseRunningMap: Record<string, messages.TestCaseStarted> = {};\r\n\r\n\tconstructor(eventBroadcaster: EventEmitter) {\r\n\t\teventBroadcaster.on('envelope', this.parseEnvelope.bind(this));\r\n\t}\r\n\r\n\t/**\r\n\t * Reset this message collector for a new parallel test run.\r\n\t * @param messageData Gerkin information from initial load\r\n\t */\r\n\treset(messageData: IMessageData): void {\r\n\t\tthis.gherkinDocumentMap = messageData.gherkinDocumentMap;\r\n\t\tthis.pickleMap = messageData.pickleMap;\r\n\t\tthis.testCaseMap = messageData.testCaseMap;\r\n\t\tthis.testCaseAttemptDataMap = {};\r\n\t\tthis.undefinedParameterTypes = [];\r\n\t\tthis.testCaseRunningMap = {};\r\n\t}\r\n\r\n\t/**\r\n\t * Get Gerkin message data for parallel runs\r\n\t * @returns Gerkin informaion loaded during startup\r\n\t */\r\n\tgetMessageData(): IMessageData {\r\n\t\tconst data = {} as IMessageData;\r\n\t\tdata.gherkinDocumentMap = this.gherkinDocumentMap;\r\n\t\tdata.pickleMap = this.pickleMap;\r\n\t\tdata.testCaseMap = this.testCaseMap;\r\n\r\n\t\treturn data;\r\n\t}\r\n\r\n\t/**\r\n\t * Check for failures in a test run\r\n\t * @returns true if there are failures in the last test case attempt\r\n\t */\r\n\thasFailures(): boolean {\r\n\t\tfor (const caseKey in this.testCaseAttemptDataMap) {\r\n\t\t\tconst stepResults = this.testCaseAttemptDataMap[caseKey].stepResults;\r\n\t\t\tfor (const key in stepResults) {\r\n\t\t\t\tif (stepResults[key].status === TestStepResultStatus.FAILED) {\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\tgetGherkinDocument(uri: string): messages.GherkinDocument {\r\n\t\treturn this.gherkinDocumentMap[uri];\r\n\t}\r\n\r\n\tgetPickle(pickleId: string): messages.Pickle {\r\n\t\treturn this.pickleMap[pickleId];\r\n\t}\r\n\r\n\tgetTestCaseAttempts(): ITestCaseAttempt[] {\r\n\t\treturn Object.keys(this.testCaseAttemptDataMap).map(testCaseStartedId => {\r\n\t\t\treturn this.getTestCaseAttempt(testCaseStartedId);\r\n\t\t});\r\n\t}\r\n\r\n\tgetTestCaseAttempt(testCaseStartedId: string): ITestCaseAttempt {\r\n\t\tconst testCaseAttemptData = this.testCaseAttemptDataMap[testCaseStartedId];\r\n\t\tconst testCase = this.testCaseMap[testCaseAttemptData.testCaseId];\r\n\t\tconst pickle = this.pickleMap[testCase.pickleId];\r\n\t\treturn {\r\n\t\t\tgherkinDocument: this.gherkinDocumentMap[pickle.uri],\r\n\t\t\tpickle,\r\n\t\t\ttestCase,\r\n\t\t\tattempt: testCaseAttemptData.attempt,\r\n\t\t\twillBeRetried: testCaseAttemptData.willBeRetried,\r\n\t\t\tstepAttachments: testCaseAttemptData.stepAttachments,\r\n\t\t\tstepResults: testCaseAttemptData.stepResults,\r\n\t\t\tworstTestStepResult: testCaseAttemptData.worstTestStepResult\r\n\t\t};\r\n\t}\r\n\r\n\tparseEnvelope(envelope: messages.Envelope): void {\r\n\t\tif (doesHaveValue(envelope.gherkinDocument)) {\r\n\t\t\tthis.gherkinDocumentMap[envelope.gherkinDocument.uri] = envelope.gherkinDocument;\r\n\t\t} else if (doesHaveValue(envelope.pickle)) {\r\n\t\t\tthis.pickleMap[envelope.pickle.id] = envelope.pickle;\r\n\t\t} else if (doesHaveValue(envelope.undefinedParameterType)) {\r\n\t\t\tthis.undefinedParameterTypes.push(envelope.undefinedParameterType);\r\n\t\t} else if (doesHaveValue(envelope.testCase)) {\r\n\t\t\tthis.testCaseMap[envelope.testCase.id] = envelope.testCase;\r\n\t\t} else if (doesHaveValue(envelope.testCaseStarted)) {\r\n\t\t\tthis.initTestCaseAttempt(envelope.testCaseStarted);\r\n\t\t\tthis.startTestCase(envelope.testCaseStarted);\r\n\t\t} else if (doesHaveValue(envelope.attachment)) {\r\n\t\t\tthis.storeAttachment(envelope.attachment);\r\n\t\t} else if (doesHaveValue(envelope.testStepFinished)) {\r\n\t\t\tthis.storeTestStepResult(envelope.testStepFinished);\r\n\t\t} else if (doesHaveValue(envelope.testCaseFinished)) {\r\n\t\t\tthis.storeTestCaseResult(envelope.testCaseFinished);\r\n\t\t}\r\n\t}\r\n\r\n\tprivate initTestCaseAttempt(testCaseStarted: messages.TestCaseStarted): void {\r\n\t\tthis.testCaseAttemptDataMap[testCaseStarted.id] = {\r\n\t\t\tattempt: testCaseStarted.attempt,\r\n\t\t\twillBeRetried: false,\r\n\t\t\ttestCaseId: testCaseStarted.testCaseId,\r\n\t\t\tstepAttachments: {},\r\n\t\t\tstepResults: {},\r\n\t\t\tworstTestStepResult: {\r\n\t\t\t\tduration: { seconds: 0, nanos: 0 },\r\n\t\t\t\tstatus: messages.TestStepResultStatus.UNKNOWN\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n\r\n\tstoreAttachment(attachment: messages.Attachment): void {\r\n\t\tconst { testCaseStartedId, testStepId } = attachment;\r\n\t\tif (testCaseStartedId && testStepId) {\r\n\t\t\tconst { stepAttachments } = this.testCaseAttemptDataMap[testCaseStartedId];\r\n\t\t\tif (doesNotHaveValue(stepAttachments[testStepId])) {\r\n\t\t\t\tstepAttachments[testStepId] = [];\r\n\t\t\t}\r\n\t\t\tstepAttachments[testStepId].push(attachment);\r\n\t\t}\r\n\t}\r\n\r\n\tstoreTestStepResult({ testCaseStartedId, testStepId, testStepResult }: messages.TestStepFinished): void {\r\n\t\tthis.testCaseAttemptDataMap[testCaseStartedId].stepResults[testStepId] = testStepResult;\r\n\t}\r\n\r\n\tstoreTestCaseResult({ testCaseStartedId, willBeRetried }: messages.TestCaseFinished): void {\r\n\t\tconst stepResults = Object.values(this.testCaseAttemptDataMap[testCaseStartedId].stepResults);\r\n\t\tthis.testCaseAttemptDataMap[testCaseStartedId].worstTestStepResult = messages.getWorstTestStepResult(stepResults);\r\n\t\tthis.testCaseAttemptDataMap[testCaseStartedId].willBeRetried = willBeRetried;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the Pickle from hook parameters passed in from Cucumber\r\n\t * to find a matching Pickle (scenario) and return the scenario Context\r\n\t * @param hookParam\r\n\t * @returns\r\n\t */\r\n\tgetHookScenarioContext(hookParam: any): ManagedScenarioContext | undefined {\r\n\t\tlet scenarioContext: ManagedScenarioContext | undefined;\r\n\r\n\t\tif (hookParam) {\r\n\t\t\tconst pickle = hookParam.pickle;\r\n\t\t\tconst scenario = this.pickleMap[pickle.id] as IScenario;\r\n\t\t\tif (scenario && scenario.scenarioContext) {\r\n\t\t\t\tscenarioContext = scenario.scenarioContext;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn scenarioContext;\r\n\t}\r\n\r\n\t/**\r\n\t * Uses StepPattern information to find a matching scenario\r\n\t * and return the ScenarioContext\r\n\t * @param stepBinding\r\n\t * @returns\r\n\t */\r\n\tgetStepScenarioContext(stepBinding: StepBinding): ManagedScenarioContext | undefined {\r\n\t\tlet scenarioContext: ManagedScenarioContext | undefined;\r\n\t\tfor (const [, pickle] of Object.entries(this.pickleMap)) {\r\n\t\t\tconst scenario = pickle as IScenario;\r\n\t\t\tfor (const step of scenario.steps) {\r\n\t\t\t\tif (hasMatchingStep(stepBinding.stepPattern.toString(), step.text)) {\r\n\t\t\t\t\t// if we have tags on the step binding check to see if it matches one in the\r\n\t\t\t\t\t// current scenario, which also includes tags associated with the feature\r\n\t\t\t\t\tif (stepBinding.tags && this.stepHasTags(stepBinding.tags)) {\r\n\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\tscenario.tags.length > 0 &&\r\n\t\t\t\t\t\t\thasMatchingTags(\r\n\t\t\t\t\t\t\t\tstepBinding.tags,\r\n\t\t\t\t\t\t\t\tscenario.tags.map(x => x.name)\r\n\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\tscenarioContext = scenario.scenarioContext;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tscenarioContext = scenario.scenarioContext;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (scenarioContext) break;\r\n\t\t\t}\r\n\t\t\tif (scenarioContext) break;\r\n\t\t}\r\n\t\treturn scenarioContext;\r\n\t}\r\n\t/**\r\n\t * Called when a test case (scenario) starts. Intercepting\r\n\t * this message to initialize a new ScenarioContext\r\n\t * @param testCaseStarted\r\n\t */\r\n\tprivate startTestCase(testCaseStarted: messages.TestCaseStarted): void {\r\n\t\tthis.testCaseRunningMap[testCaseStarted.id] = testCaseStarted;\r\n\t\tconst scenario = this.getScenarioForTest(testCaseStarted.testCaseId);\r\n\t\tif (scenario) {\r\n\t\t\tconst tags = scenario.tags.map(t => t.name);\r\n\t\t\tscenario.scenarioContext = new ManagedScenarioContext(scenario.name, tags);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Called when a test case (scenario) ends. Intercepting\r\n\t * this message to dispose and clear the ScenarioContext\r\n\t * @param testCaseFinished\r\n\t */\r\n\tpublic async endTestCase(endTestCase: EndTestCaseInfo): Promise<void> {\r\n\t\tconst testCase = this.testCaseRunningMap[endTestCase.testCaseStartedId];\r\n\t\tif (testCase) {\r\n\t\t\tconst scenario = this.getScenarioForTest(testCase.testCaseId);\r\n\t\t\tif (scenario && scenario.scenarioContext) {\r\n\t\t\t\tawait scenario.scenarioContext.dispose(endTestCase);\r\n\t\t\t\tscenario.scenarioContext = undefined;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Uses the testCaleId passed in to find the associated Pickle (scenario)\r\n\t * @param testCaseId\r\n\t * @returns\r\n\t */\r\n\tprivate getScenarioForTest(testCaseId: string): IScenario | undefined {\r\n\t\tconst testCase = this.testCaseMap[testCaseId];\r\n\t\tif (testCase) {\r\n\t\t\treturn this.pickleMap[testCase.pickleId] as IScenario;\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\t/**\r\n\t * StepBinding tags are initialized with an astrick when empty.\r\n\t * Need to make sure tags has a value and not an astrick\r\n\t * @param tags\r\n\t * @returns\r\n\t */\r\n\tprivate stepHasTags(tags: string): boolean {\r\n\t\treturn hasStringValue(tags) && !tags?.includes('*');\r\n\t}\r\n}\r\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ChildProcess } from 'node:child_process';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
import { SupportCodeLibrary } from '@cucumber/cucumber/lib/support_code_library_builder/types';
|
|
4
|
+
import { AssembledTestCase } from '@cucumber/cucumber/lib/assemble/index';
|
|
5
|
+
import { ILogger, IRunEnvironment } from '@cucumber/cucumber/lib/environment/index';
|
|
6
|
+
import { RuntimeAdapter } from '@cucumber/cucumber/lib/runtime/types';
|
|
7
|
+
import { IRunOptionsRuntime, ISourcesCoordinates } from '@cucumber/cucumber/lib/api/index';
|
|
8
|
+
import { WorkerToCoordinatorEvent } from '@cucumber/cucumber/lib/runtime/parallel/types';
|
|
9
|
+
declare const enum WorkerState {
|
|
10
|
+
'idle' = 0,
|
|
11
|
+
'closed' = 1,
|
|
12
|
+
'running' = 2,
|
|
13
|
+
'new' = 3
|
|
14
|
+
}
|
|
15
|
+
interface ManagedWorker {
|
|
16
|
+
state: WorkerState;
|
|
17
|
+
process: ChildProcess;
|
|
18
|
+
id: string;
|
|
19
|
+
}
|
|
20
|
+
interface WorkPlacement {
|
|
21
|
+
index: number;
|
|
22
|
+
item: AssembledTestCase;
|
|
23
|
+
}
|
|
24
|
+
export declare class ChildProcessAdapter implements RuntimeAdapter {
|
|
25
|
+
private readonly environment;
|
|
26
|
+
private readonly logger;
|
|
27
|
+
private readonly eventBroadcaster;
|
|
28
|
+
private readonly options;
|
|
29
|
+
private readonly supportCodeLibrary;
|
|
30
|
+
private readonly coordinates;
|
|
31
|
+
private idleInterventions;
|
|
32
|
+
private failing;
|
|
33
|
+
private onFinish;
|
|
34
|
+
private todo;
|
|
35
|
+
private readonly inProgress;
|
|
36
|
+
private readonly workers;
|
|
37
|
+
constructor(environment: IRunEnvironment, logger: ILogger, eventBroadcaster: EventEmitter, options: IRunOptionsRuntime, supportCodeLibrary: SupportCodeLibrary, coordinates: ISourcesCoordinates);
|
|
38
|
+
parseWorkerMessage(worker: ManagedWorker, message: WorkerToCoordinatorEvent): void;
|
|
39
|
+
awakenWorkers(triggeringWorker: ManagedWorker): void;
|
|
40
|
+
startWorker(id: string, total: number): void;
|
|
41
|
+
onWorkerProcessClose(exitCode: number): void;
|
|
42
|
+
run(assembledTestCases: ReadonlyArray<AssembledTestCase>): Promise<boolean>;
|
|
43
|
+
nextWorkPlacement(): WorkPlacement | null;
|
|
44
|
+
placementAt(index: number): WorkPlacement;
|
|
45
|
+
giveWork(worker: ManagedWorker, force?: boolean): void;
|
|
46
|
+
}
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ChildProcessAdapter = void 0;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const runWorkerPath = node_path_1.default.resolve(__dirname, 'run-worker');
|
|
10
|
+
class ChildProcessAdapter {
|
|
11
|
+
environment;
|
|
12
|
+
logger;
|
|
13
|
+
eventBroadcaster;
|
|
14
|
+
options;
|
|
15
|
+
supportCodeLibrary;
|
|
16
|
+
coordinates;
|
|
17
|
+
idleInterventions = 0;
|
|
18
|
+
failing = false;
|
|
19
|
+
onFinish = success => {
|
|
20
|
+
return success;
|
|
21
|
+
};
|
|
22
|
+
todo = [];
|
|
23
|
+
inProgress = {};
|
|
24
|
+
workers = {};
|
|
25
|
+
constructor(environment, logger, eventBroadcaster, options, supportCodeLibrary, coordinates) {
|
|
26
|
+
this.environment = environment;
|
|
27
|
+
this.logger = logger;
|
|
28
|
+
this.eventBroadcaster = eventBroadcaster;
|
|
29
|
+
this.options = options;
|
|
30
|
+
this.supportCodeLibrary = supportCodeLibrary;
|
|
31
|
+
this.coordinates = coordinates;
|
|
32
|
+
}
|
|
33
|
+
parseWorkerMessage(worker, message) {
|
|
34
|
+
switch (message.type) {
|
|
35
|
+
case 'READY':
|
|
36
|
+
worker.state = 0 /* WorkerState.idle */;
|
|
37
|
+
this.awakenWorkers(worker);
|
|
38
|
+
break;
|
|
39
|
+
case 'ENVELOPE':
|
|
40
|
+
this.eventBroadcaster.emit('envelope', message.envelope);
|
|
41
|
+
break;
|
|
42
|
+
case 'FINISHED':
|
|
43
|
+
if (!message.success) {
|
|
44
|
+
this.failing = true;
|
|
45
|
+
}
|
|
46
|
+
delete this.inProgress[worker.id];
|
|
47
|
+
worker.state = 0 /* WorkerState.idle */;
|
|
48
|
+
this.awakenWorkers(worker);
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
throw new Error(`Unexpected message from worker: ${JSON.stringify(message)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
awakenWorkers(triggeringWorker) {
|
|
55
|
+
Object.values(this.workers).forEach(worker => {
|
|
56
|
+
if (worker.state === 0 /* WorkerState.idle */) {
|
|
57
|
+
this.giveWork(worker);
|
|
58
|
+
}
|
|
59
|
+
return worker.state !== 0 /* WorkerState.idle */;
|
|
60
|
+
});
|
|
61
|
+
if (Object.keys(this.inProgress).length == 0 && this.todo.length > 0) {
|
|
62
|
+
this.giveWork(triggeringWorker, true);
|
|
63
|
+
this.idleInterventions++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
startWorker(id, total) {
|
|
67
|
+
const workerProcess = (0, node_child_process_1.fork)(runWorkerPath, [], {
|
|
68
|
+
cwd: this.environment.cwd,
|
|
69
|
+
env: {
|
|
70
|
+
...this.environment.env,
|
|
71
|
+
CUCUMBER_PARALLEL: 'true',
|
|
72
|
+
CUCUMBER_TOTAL_WORKERS: total.toString(),
|
|
73
|
+
CUCUMBER_WORKER_ID: id
|
|
74
|
+
},
|
|
75
|
+
stdio: ['inherit', 'inherit', 'inherit', 'ipc']
|
|
76
|
+
});
|
|
77
|
+
const worker = { state: 3 /* WorkerState.new */, process: workerProcess, id };
|
|
78
|
+
this.workers[id] = worker;
|
|
79
|
+
worker.process.on('message', (message) => {
|
|
80
|
+
this.parseWorkerMessage(worker, message);
|
|
81
|
+
});
|
|
82
|
+
worker.process.on('close', exitCode => {
|
|
83
|
+
worker.state = 1 /* WorkerState.closed */;
|
|
84
|
+
this.onWorkerProcessClose(exitCode);
|
|
85
|
+
});
|
|
86
|
+
const messageData = global.messageCollector.getMessageData();
|
|
87
|
+
messageData.coordinates = this.coordinates;
|
|
88
|
+
worker.process.send({
|
|
89
|
+
type: 'INITIALIZE',
|
|
90
|
+
supportCodeCoordinates: this.supportCodeLibrary.originalCoordinates,
|
|
91
|
+
supportCodeIds: {
|
|
92
|
+
stepDefinitionIds: this.supportCodeLibrary.stepDefinitions.map(s => s.id),
|
|
93
|
+
beforeTestCaseHookDefinitionIds: this.supportCodeLibrary.beforeTestCaseHookDefinitions.map(h => h.id),
|
|
94
|
+
afterTestCaseHookDefinitionIds: this.supportCodeLibrary.afterTestCaseHookDefinitions.map(h => h.id)
|
|
95
|
+
},
|
|
96
|
+
options: this.options,
|
|
97
|
+
messageData: messageData
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
onWorkerProcessClose(exitCode) {
|
|
101
|
+
if (exitCode !== 0) {
|
|
102
|
+
this.failing = true;
|
|
103
|
+
}
|
|
104
|
+
if (Object.values(this.workers).every(x => x.state === 1 /* WorkerState.closed */)) {
|
|
105
|
+
this.onFinish(!this.failing);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async run(assembledTestCases) {
|
|
109
|
+
this.todo = Array.from(assembledTestCases);
|
|
110
|
+
return await new Promise(resolve => {
|
|
111
|
+
for (let i = 0; i < this.options.parallel; i++) {
|
|
112
|
+
this.startWorker(i.toString(), this.options.parallel);
|
|
113
|
+
}
|
|
114
|
+
this.onFinish = status => {
|
|
115
|
+
if (this.idleInterventions > 0) {
|
|
116
|
+
this.logger.warn(`WARNING: All workers went idle ${this.idleInterventions} time(s). Consider revising handler passed to setParallelCanAssign.`);
|
|
117
|
+
}
|
|
118
|
+
resolve(status);
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
nextWorkPlacement() {
|
|
123
|
+
for (let index = 0; index < this.todo.length; index++) {
|
|
124
|
+
const placement = this.placementAt(index);
|
|
125
|
+
if (this.supportCodeLibrary.parallelCanAssign(placement.item.pickle, Object.values(this.inProgress).map(({ pickle }) => pickle))) {
|
|
126
|
+
return placement;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
placementAt(index) {
|
|
132
|
+
return {
|
|
133
|
+
index,
|
|
134
|
+
item: this.todo[index]
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
giveWork(worker, force = false) {
|
|
138
|
+
if (this.todo.length < 1) {
|
|
139
|
+
worker.state = 2 /* WorkerState.running */;
|
|
140
|
+
worker.process.send({ type: 'FINALIZE' });
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const workPlacement = force ? this.placementAt(0) : this.nextWorkPlacement();
|
|
144
|
+
if (workPlacement === null) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const { index: nextIndex, item } = workPlacement;
|
|
148
|
+
this.todo.splice(nextIndex, 1);
|
|
149
|
+
this.inProgress[worker.id] = item;
|
|
150
|
+
worker.state = 2 /* WorkerState.running */;
|
|
151
|
+
worker.process.send({
|
|
152
|
+
type: 'RUN',
|
|
153
|
+
assembledTestCase: item,
|
|
154
|
+
failing: this.failing
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.ChildProcessAdapter = ChildProcessAdapter;
|
|
159
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/runtime/parallel/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChildProcess, fork } from 'node:child_process';\r\nimport path from 'node:path';\r\nimport { EventEmitter } from 'node:events';\r\nimport { SupportCodeLibrary } from '@cucumber/cucumber/lib/support_code_library_builder/types';\r\nimport { AssembledTestCase } from '@cucumber/cucumber/lib/assemble/index';\r\nimport { ILogger, IRunEnvironment } from '@cucumber/cucumber/lib/environment/index';\r\nimport { RuntimeAdapter } from '@cucumber/cucumber/lib/runtime/types';\r\nimport { IRunOptionsRuntime, ISourcesCoordinates } from '@cucumber/cucumber/lib/api/index';\r\nimport { FinalizeCommand, RunCommand, WorkerToCoordinatorEvent } from '@cucumber/cucumber/lib/runtime/parallel/types';\r\nimport { InitializeTsflowCommand } from './types';\r\n\r\nconst runWorkerPath = path.resolve(__dirname, 'run-worker');\r\n\r\nconst enum WorkerState {\r\n\t'idle',\r\n\t'closed',\r\n\t'running',\r\n\t'new'\r\n}\r\n\r\ninterface ManagedWorker {\r\n\tstate: WorkerState;\r\n\tprocess: ChildProcess;\r\n\tid: string;\r\n}\r\n\r\ninterface WorkPlacement {\r\n\tindex: number;\r\n\titem: AssembledTestCase;\r\n}\r\n\r\nexport class ChildProcessAdapter implements RuntimeAdapter {\r\n\tprivate idleInterventions: number = 0;\r\n\tprivate failing: boolean = false;\r\n\tprivate onFinish: (success: boolean) => void = success => {\r\n\t\treturn success;\r\n\t};\r\n\tprivate todo: Array<AssembledTestCase> = [];\r\n\tprivate readonly inProgress: Record<string, AssembledTestCase> = {};\r\n\tprivate readonly workers: Record<string, ManagedWorker> = {};\r\n\r\n\tconstructor(\r\n\t\tprivate readonly environment: IRunEnvironment,\r\n\t\tprivate readonly logger: ILogger,\r\n\t\tprivate readonly eventBroadcaster: EventEmitter,\r\n\t\tprivate readonly options: IRunOptionsRuntime,\r\n\t\tprivate readonly supportCodeLibrary: SupportCodeLibrary,\r\n\t\tprivate readonly coordinates: ISourcesCoordinates\r\n\t) {}\r\n\r\n\tparseWorkerMessage(worker: ManagedWorker, message: WorkerToCoordinatorEvent): void {\r\n\t\tswitch (message.type) {\r\n\t\t\tcase 'READY':\r\n\t\t\t\tworker.state = WorkerState.idle;\r\n\t\t\t\tthis.awakenWorkers(worker);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'ENVELOPE':\r\n\t\t\t\tthis.eventBroadcaster.emit('envelope', message.envelope);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'FINISHED':\r\n\t\t\t\tif (!message.success) {\r\n\t\t\t\t\tthis.failing = true;\r\n\t\t\t\t}\r\n\t\t\t\tdelete this.inProgress[worker.id];\r\n\t\t\t\tworker.state = WorkerState.idle;\r\n\t\t\t\tthis.awakenWorkers(worker);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tthrow new Error(`Unexpected message from worker: ${JSON.stringify(message)}`);\r\n\t\t}\r\n\t}\r\n\r\n\tawakenWorkers(triggeringWorker: ManagedWorker): void {\r\n\t\tObject.values(this.workers).forEach(worker => {\r\n\t\t\tif (worker.state === WorkerState.idle) {\r\n\t\t\t\tthis.giveWork(worker);\r\n\t\t\t}\r\n\t\t\treturn worker.state !== WorkerState.idle;\r\n\t\t});\r\n\r\n\t\tif (Object.keys(this.inProgress).length == 0 && this.todo.length > 0) {\r\n\t\t\tthis.giveWork(triggeringWorker, true);\r\n\t\t\tthis.idleInterventions++;\r\n\t\t}\r\n\t}\r\n\r\n\tstartWorker(id: string, total: number): void {\r\n\t\tconst workerProcess = fork(runWorkerPath, [], {\r\n\t\t\tcwd: this.environment.cwd,\r\n\t\t\tenv: {\r\n\t\t\t\t...this.environment.env,\r\n\t\t\t\tCUCUMBER_PARALLEL: 'true',\r\n\t\t\t\tCUCUMBER_TOTAL_WORKERS: total.toString(),\r\n\t\t\t\tCUCUMBER_WORKER_ID: id\r\n\t\t\t},\r\n\t\t\tstdio: ['inherit', 'inherit', 'inherit', 'ipc']\r\n\t\t});\r\n\t\tconst worker = { state: WorkerState.new, process: workerProcess, id };\r\n\t\tthis.workers[id] = worker;\r\n\t\tworker.process.on('message', (message: WorkerToCoordinatorEvent) => {\r\n\t\t\tthis.parseWorkerMessage(worker, message);\r\n\t\t});\r\n\t\tworker.process.on('close', exitCode => {\r\n\t\t\tworker.state = WorkerState.closed;\r\n\t\t\tthis.onWorkerProcessClose(exitCode!);\r\n\t\t});\r\n\r\n\t\tconst messageData = global.messageCollector.getMessageData();\r\n\t\tmessageData.coordinates = this.coordinates;\r\n\r\n\t\tworker.process.send({\r\n\t\t\ttype: 'INITIALIZE',\r\n\t\t\tsupportCodeCoordinates: this.supportCodeLibrary.originalCoordinates,\r\n\t\t\tsupportCodeIds: {\r\n\t\t\t\tstepDefinitionIds: this.supportCodeLibrary.stepDefinitions.map(s => s.id),\r\n\t\t\t\tbeforeTestCaseHookDefinitionIds: this.supportCodeLibrary.beforeTestCaseHookDefinitions.map(h => h.id),\r\n\t\t\t\tafterTestCaseHookDefinitionIds: this.supportCodeLibrary.afterTestCaseHookDefinitions.map(h => h.id)\r\n\t\t\t},\r\n\t\t\toptions: this.options,\r\n\t\t\tmessageData: messageData\r\n\t\t} satisfies InitializeTsflowCommand);\r\n\t}\r\n\r\n\tonWorkerProcessClose(exitCode: number): void {\r\n\t\tif (exitCode !== 0) {\r\n\t\t\tthis.failing = true;\r\n\t\t}\r\n\r\n\t\tif (Object.values(this.workers).every(x => x.state === WorkerState.closed)) {\r\n\t\t\tthis.onFinish(!this.failing);\r\n\t\t}\r\n\t}\r\n\r\n\tasync run(assembledTestCases: ReadonlyArray<AssembledTestCase>): Promise<boolean> {\r\n\t\tthis.todo = Array.from(assembledTestCases);\r\n\t\treturn await new Promise<boolean>(resolve => {\r\n\t\t\tfor (let i = 0; i < this.options.parallel; i++) {\r\n\t\t\t\tthis.startWorker(i.toString(), this.options.parallel);\r\n\t\t\t}\r\n\t\t\tthis.onFinish = status => {\r\n\t\t\t\tif (this.idleInterventions > 0) {\r\n\t\t\t\t\tthis.logger.warn(\r\n\t\t\t\t\t\t`WARNING: All workers went idle ${this.idleInterventions} time(s). Consider revising handler passed to setParallelCanAssign.`\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tresolve(status);\r\n\t\t\t};\r\n\t\t});\r\n\t}\r\n\r\n\tnextWorkPlacement(): WorkPlacement | null {\r\n\t\tfor (let index = 0; index < this.todo.length; index++) {\r\n\t\t\tconst placement = this.placementAt(index);\r\n\t\t\tif (\r\n\t\t\t\tthis.supportCodeLibrary.parallelCanAssign(\r\n\t\t\t\t\tplacement.item.pickle,\r\n\t\t\t\t\tObject.values(this.inProgress).map(({ pickle }) => pickle)\r\n\t\t\t\t)\r\n\t\t\t) {\r\n\t\t\t\treturn placement;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn null;\r\n\t}\r\n\r\n\tplacementAt(index: number): WorkPlacement {\r\n\t\treturn {\r\n\t\t\tindex,\r\n\t\t\titem: this.todo[index]\r\n\t\t};\r\n\t}\r\n\r\n\tgiveWork(worker: ManagedWorker, force: boolean = false): void {\r\n\t\tif (this.todo.length < 1) {\r\n\t\t\tworker.state = WorkerState.running;\r\n\t\t\tworker.process.send({ type: 'FINALIZE' } satisfies FinalizeCommand);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst workPlacement = force ? this.placementAt(0) : this.nextWorkPlacement();\r\n\r\n\t\tif (workPlacement === null) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst { index: nextIndex, item } = workPlacement;\r\n\r\n\t\tthis.todo.splice(nextIndex, 1);\r\n\t\tthis.inProgress[worker.id] = item;\r\n\t\tworker.state = WorkerState.running;\r\n\t\tworker.process.send({\r\n\t\t\ttype: 'RUN',\r\n\t\t\tassembledTestCase: item,\r\n\t\t\tfailing: this.failing\r\n\t\t} satisfies RunCommand);\r\n\t}\r\n}\r\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import 'polyfill-symbol-metadata';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const value_checker_1 = require("@cucumber/cucumber/lib/value_checker");
|
|
4
|
+
const worker_1 = require("./worker");
|
|
5
|
+
require("polyfill-symbol-metadata");
|
|
6
|
+
function run() {
|
|
7
|
+
const exit = (exitCode, error, message) => {
|
|
8
|
+
if ((0, value_checker_1.doesHaveValue)(error)) {
|
|
9
|
+
console.error(new Error(message, { cause: error }));
|
|
10
|
+
}
|
|
11
|
+
process.exit(exitCode);
|
|
12
|
+
};
|
|
13
|
+
const worker = new worker_1.ChildProcessWorker({
|
|
14
|
+
id: process.env.CUCUMBER_WORKER_ID,
|
|
15
|
+
sendMessage: (message) => process.send(message),
|
|
16
|
+
cwd: process.cwd(),
|
|
17
|
+
exit
|
|
18
|
+
});
|
|
19
|
+
process.on('message', (m) => {
|
|
20
|
+
worker.receiveMessage(m).catch((error) => exit(1, error, 'Unexpected error on worker.receiveMessage'));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
run();
|
|
24
|
+
//# sourceMappingURL=run-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-worker.js","sourceRoot":"","sources":["../../../src/runtime/parallel/run-worker.ts"],"names":[],"mappings":";;AAAA,wEAAqE;AACrE,qCAA8C;AAC9C,oCAAkC;AAElC,SAAS,GAAG;IACX,MAAM,IAAI,GAAG,CAAC,QAAgB,EAAE,KAAa,EAAE,OAAgB,EAAQ,EAAE;QACxE,IAAI,IAAA,6BAAa,EAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,2BAAkB,CAAC;QACrC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAmB;QACnC,WAAW,EAAE,CAAC,OAAY,EAAE,EAAE,CAAC,OAAO,CAAC,IAAK,CAAC,OAAO,CAAC;QACrD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI;KACJ,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAM,EAAQ,EAAE;QACtC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,2CAA2C,CAAC,CAAC,CAAC;IAC/G,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,GAAG,EAAE,CAAC","sourcesContent":["import { doesHaveValue } from '@cucumber/cucumber/lib/value_checker';\r\nimport { ChildProcessWorker } from './worker';\r\nimport 'polyfill-symbol-metadata';\r\n\r\nfunction run(): void {\r\n\tconst exit = (exitCode: number, error?: Error, message?: string): void => {\r\n\t\tif (doesHaveValue(error)) {\r\n\t\t\tconsole.error(new Error(message, { cause: error }));\r\n\t\t}\r\n\t\tprocess.exit(exitCode);\r\n\t};\r\n\tconst worker = new ChildProcessWorker({\r\n\t\tid: process.env.CUCUMBER_WORKER_ID!,\r\n\t\tsendMessage: (message: any) => process.send!(message),\r\n\t\tcwd: process.cwd(),\r\n\t\texit\r\n\t});\r\n\tprocess.on('message', (m: any): void => {\r\n\t\tworker.receiveMessage(m).catch((error: Error) => exit(1, error, 'Unexpected error on worker.receiveMessage'));\r\n\t});\r\n}\r\n\r\nrun();\r\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as messages from '@cucumber/messages';
|
|
2
|
+
import { FinalizeCommand, InitializeCommand, RunCommand } from '@cucumber/cucumber/lib/runtime/parallel/types';
|
|
3
|
+
import { ISourcesCoordinates } from '@cucumber/cucumber/api';
|
|
4
|
+
export interface IMessageData {
|
|
5
|
+
gherkinDocumentMap: Record<string, messages.GherkinDocument>;
|
|
6
|
+
pickleMap: Record<string, messages.Pickle>;
|
|
7
|
+
testCaseMap: Record<string, messages.TestCase>;
|
|
8
|
+
coordinates: ISourcesCoordinates;
|
|
9
|
+
}
|
|
10
|
+
export interface InitializeTsflowCommand extends InitializeCommand {
|
|
11
|
+
messageData: IMessageData;
|
|
12
|
+
}
|
|
13
|
+
export type CoordinatorToWorkerCommand = InitializeTsflowCommand | RunCommand | FinalizeCommand;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/runtime/parallel/types.ts"],"names":[],"mappings":"","sourcesContent":["import * as messages from '@cucumber/messages';\r\nimport { FinalizeCommand, InitializeCommand, RunCommand } from '@cucumber/cucumber/lib/runtime/parallel/types';\r\nimport { ISourcesCoordinates } from '@cucumber/cucumber/api';\r\n\r\nexport interface IMessageData {\r\n\tgherkinDocumentMap: Record<string, messages.GherkinDocument>;\r\n\tpickleMap: Record<string, messages.Pickle>;\r\n\ttestCaseMap: Record<string, messages.TestCase>;\r\n\tcoordinates: ISourcesCoordinates;\r\n}\r\n\r\nexport interface InitializeTsflowCommand extends InitializeCommand {\r\n\tmessageData: IMessageData;\r\n}\r\n\r\nexport type CoordinatorToWorkerCommand = InitializeTsflowCommand | RunCommand | FinalizeCommand;\r\n"]}
|