@testomatio/reporter 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +269 -0
- package/lib/adapter/codecept.js +57 -39
- package/lib/adapter/cucumber/current.js +95 -59
- package/lib/adapter/cucumber/legacy.js +25 -11
- package/lib/adapter/jest.js +7 -2
- package/lib/adapter/playwright.js +17 -10
- package/lib/client.js +9 -13
- package/lib/dataStorage.js +113 -49
- package/lib/logger.js +134 -111
- package/lib/pipe/testomatio.js +2 -0
- package/package.json +4 -2
|
@@ -1,35 +1,59 @@
|
|
|
1
|
-
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
|
2
|
-
const { Formatter, formatterHelpers } = require(
|
|
1
|
+
// eslint-disable-next-line global-require, import/no-extraneous-dependencies, import/no-unresolved
|
|
2
|
+
const { Formatter, formatterHelpers } = require('@cucumber/cucumber');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const fs = require('fs');
|
|
5
|
-
const { STATUS } = require('../../constants');
|
|
5
|
+
const { STATUS, TESTOMAT_TMP_STORAGE } = require('../../constants');
|
|
6
6
|
const TestomatClient = require('../../client');
|
|
7
|
+
const logger = require('../../logger');
|
|
8
|
+
const { parseTest, fileSystem } = require('../../util');
|
|
9
|
+
|
|
10
|
+
const { GherkinDocumentParser, PickleParser } = formatterHelpers;
|
|
11
|
+
const { getGherkinScenarioLocationMap, getGherkinStepMap } = GherkinDocumentParser;
|
|
12
|
+
const { getPickleStepMap } = PickleParser;
|
|
13
|
+
|
|
14
|
+
function getTestId(scenario) {
|
|
15
|
+
if (scenario) {
|
|
16
|
+
for (const tag of scenario.tags) {
|
|
17
|
+
const testId = parseTest(tag.name);
|
|
18
|
+
if (testId) return testId;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
7
21
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
getGherkinScenarioLocationMap,
|
|
11
|
-
getGherkinStepMap,
|
|
12
|
-
} = GherkinDocumentParser
|
|
13
|
-
const { getPickleStepMap } = PickleParser
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
14
24
|
|
|
15
25
|
class CucumberReporter extends Formatter {
|
|
16
26
|
constructor(options) {
|
|
17
27
|
super(options);
|
|
18
|
-
options.eventBroadcaster.on('envelope', this.parseEnvelope.bind(this))
|
|
28
|
+
options.eventBroadcaster.on('envelope', this.parseEnvelope.bind(this));
|
|
19
29
|
this.failures = [];
|
|
20
30
|
this.cases = [];
|
|
21
31
|
|
|
22
|
-
this.client = new TestomatClient({ apiKey: process.env.TESTOMATIO
|
|
32
|
+
this.client = new TestomatClient({ apiKey: options.apiKey || process.env.TESTOMATIO });
|
|
23
33
|
this.status = STATUS.PASSED;
|
|
24
34
|
|
|
35
|
+
global.testomatioRunningEnvironment = 'cucumber:current';
|
|
25
36
|
}
|
|
26
37
|
|
|
27
38
|
parseEnvelope(envelope) {
|
|
28
|
-
if (envelope.
|
|
39
|
+
if (envelope.testRunStarted) {
|
|
40
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE.mainDir);
|
|
41
|
+
}
|
|
42
|
+
if (envelope.testCaseStarted && this.client) {
|
|
43
|
+
this.client.createRun();
|
|
44
|
+
this.onTestCaseStarted(envelope.testCaseStarted);
|
|
45
|
+
}
|
|
29
46
|
if (envelope.testCaseFinished) this.onTestCaseFinished(envelope.testCaseFinished);
|
|
30
47
|
if (envelope.testRunFinished) this.onTestRunFinished(envelope);
|
|
31
48
|
}
|
|
32
49
|
|
|
50
|
+
onTestCaseStarted(testCaseStarted) {
|
|
51
|
+
const testCaseAttempt = this.eventDataCollector.getTestCaseAttempt(testCaseStarted.id);
|
|
52
|
+
const testId = getTestId(testCaseAttempt.pickle);
|
|
53
|
+
if (!global.testomatioDataStore) global.testomatioDataStore = {};
|
|
54
|
+
global.testomatioDataStore.currentlyRunningTestId = testId;
|
|
55
|
+
}
|
|
56
|
+
|
|
33
57
|
onTestCaseFinished(testCaseFinished) {
|
|
34
58
|
const testCaseAttempt = this.eventDataCollector.getTestCaseAttempt(testCaseFinished.testCaseStartedId);
|
|
35
59
|
|
|
@@ -45,10 +69,10 @@ class CucumberReporter extends Formatter {
|
|
|
45
69
|
if (testCaseAttempt.worstTestStepResult.status === 'SKIPPED') {
|
|
46
70
|
status = STATUS.SKIPPED;
|
|
47
71
|
}
|
|
48
|
-
if (testCaseAttempt.worstTestStepResult.status === 'UNDEFINED') {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
72
|
+
// if (testCaseAttempt.worstTestStepResult.status === 'UNDEFINED') {
|
|
73
|
+
// status = STATUS.SKIPPED;
|
|
74
|
+
// message = 'Undefined steps. Implement missing steps and rerun this scenario';
|
|
75
|
+
// }
|
|
52
76
|
if (testCaseAttempt.worstTestStepResult.status === 'FAILED') {
|
|
53
77
|
message = testCaseAttempt?.worstTestStepResult?.message;
|
|
54
78
|
status = STATUS.FAILED;
|
|
@@ -64,10 +88,12 @@ class CucumberReporter extends Formatter {
|
|
|
64
88
|
}
|
|
65
89
|
|
|
66
90
|
const scenario = testCaseAttempt.pickle.name;
|
|
67
|
-
|
|
91
|
+
// this may broke something (it is supposed to work, but I am sure it did not)
|
|
92
|
+
// const testId = testCaseAttempt.pickle.id;
|
|
93
|
+
const testId = getTestId(testCaseAttempt.pickle);
|
|
68
94
|
|
|
69
95
|
let exampleString = '';
|
|
70
|
-
if (example) exampleString = ` ${example.join(' | ')}
|
|
96
|
+
if (example) exampleString = ` ${example.join(' | ')}`;
|
|
71
97
|
let cliMessage = `${chalk.bold(scenario)}${exampleString}: ${chalk[color].bold(status.toUpperCase())} `;
|
|
72
98
|
|
|
73
99
|
if (message) cliMessage += chalk.gray(message.split('\n')[0]);
|
|
@@ -79,15 +105,21 @@ class CucumberReporter extends Formatter {
|
|
|
79
105
|
|
|
80
106
|
const time = Object.values(testCaseAttempt.stepResults)
|
|
81
107
|
.map(t => t.duration)
|
|
82
|
-
.reduce((sum, duration) => sum +
|
|
108
|
+
.reduce((sum, duration) => sum + duration.seconds * 1000 + duration.nanos / 1000000, 0);
|
|
83
109
|
|
|
84
110
|
if (!this.client) return;
|
|
85
111
|
|
|
112
|
+
const logs = logger.getLogs(testId);
|
|
113
|
+
|
|
86
114
|
this.client.addTestRun(status, {
|
|
87
115
|
// error: testCaseAttempt.worstTestStepResult.message,
|
|
88
116
|
message,
|
|
89
|
-
steps: getSteps(testCaseAttempt)
|
|
90
|
-
|
|
117
|
+
steps: getSteps(testCaseAttempt)
|
|
118
|
+
.map(s => s.toString())
|
|
119
|
+
.join('\n')
|
|
120
|
+
.trim(),
|
|
121
|
+
example: { ...example },
|
|
122
|
+
stack: logs,
|
|
91
123
|
title: scenario,
|
|
92
124
|
test_id: testId,
|
|
93
125
|
time,
|
|
@@ -99,21 +131,20 @@ class CucumberReporter extends Formatter {
|
|
|
99
131
|
console.log(chalk.bold('\nSUMMARY:\n\n'));
|
|
100
132
|
|
|
101
133
|
this.failures.forEach((tc, i) => {
|
|
102
|
-
let message = ` ${i+1}) ${tc.pickle.name}\n`;
|
|
134
|
+
let message = ` ${i + 1}) ${tc.pickle.name}\n`;
|
|
103
135
|
|
|
104
136
|
const steps = getSteps(tc);
|
|
105
137
|
|
|
106
138
|
steps.forEach(s => {
|
|
107
|
-
message += ` ${s.toString()}\n
|
|
108
|
-
})
|
|
139
|
+
message += ` ${s.toString()}\n`;
|
|
140
|
+
});
|
|
109
141
|
|
|
110
142
|
console.log(message);
|
|
111
143
|
if (tc?.worstTestStepResult?.message) {
|
|
112
144
|
console.log(chalk.red(tc?.worstTestStepResult?.message));
|
|
113
145
|
}
|
|
114
146
|
console.log();
|
|
115
|
-
|
|
116
|
-
})
|
|
147
|
+
});
|
|
117
148
|
}
|
|
118
149
|
|
|
119
150
|
const { testRunFinished } = envelope;
|
|
@@ -125,46 +156,48 @@ class CucumberReporter extends Formatter {
|
|
|
125
156
|
|
|
126
157
|
if (!this.client) return;
|
|
127
158
|
|
|
128
|
-
this.client.updateRunStatus(testRunFinished.success ? STATUS.PASSED : STATUS.FAILED)
|
|
159
|
+
this.client.updateRunStatus(testRunFinished.success ? STATUS.PASSED : STATUS.FAILED);
|
|
129
160
|
}
|
|
130
161
|
}
|
|
131
162
|
|
|
132
163
|
function getSteps(tc) {
|
|
133
164
|
const stepIds = Object.keys(tc.stepResults);
|
|
134
|
-
const pickleSteps = getPickleStepMap(tc.pickle)
|
|
135
|
-
return stepIds
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
165
|
+
const pickleSteps = getPickleStepMap(tc.pickle);
|
|
166
|
+
return stepIds
|
|
167
|
+
.map(stepId => {
|
|
168
|
+
const ts = tc.testCase.testSteps.find(t => t.id === stepId);
|
|
169
|
+
if (!ts) return;
|
|
170
|
+
if (!ts.pickleStepId) return;
|
|
171
|
+
const result = tc.stepResults[stepId];
|
|
172
|
+
const pickleStep = pickleSteps[ts.pickleStepId];
|
|
173
|
+
const sourceStepId = pickleStep.astNodeIds[0];
|
|
174
|
+
const step = {
|
|
175
|
+
text: pickleStep.text,
|
|
176
|
+
duration: result.duration,
|
|
177
|
+
status: result.status,
|
|
178
|
+
};
|
|
179
|
+
const color = getStatusColor(result.status);
|
|
180
|
+
if (sourceStepId && getGherkinStepMap(tc.gherkinDocument)[sourceStepId]) {
|
|
181
|
+
step.keyword = getGherkinStepMap(tc.gherkinDocument)[sourceStepId].keyword;
|
|
182
|
+
}
|
|
183
|
+
step.toString = function toString() {
|
|
184
|
+
const duration = step.duration.seconds * 1000 + step.duration.nanos / 1000000;
|
|
185
|
+
const durationString = ` ${chalk.gray(`(${Number(duration).toFixed(2)}ms)`)}`;
|
|
186
|
+
const stepString = `${chalk.bold(this.keyword)}${this.text}`.trim();
|
|
187
|
+
if (color === 'red') return chalk.red(stepString) + durationString;
|
|
188
|
+
if (color === 'yellow') return chalk.yellow(stepString) + durationString;
|
|
189
|
+
return stepString + durationString;
|
|
190
|
+
};
|
|
191
|
+
return step;
|
|
192
|
+
})
|
|
193
|
+
.filter(s => !!s);
|
|
161
194
|
}
|
|
162
195
|
|
|
163
196
|
function getStatusColor(status) {
|
|
164
197
|
if (status === 'UNDEFINED') return 'yellow';
|
|
165
198
|
if (status === 'SKIPPED') return 'yellow';
|
|
166
199
|
if (status === 'FAILED') return 'red';
|
|
167
|
-
return 'green'
|
|
200
|
+
return 'green';
|
|
168
201
|
}
|
|
169
202
|
|
|
170
203
|
function getExample(testCaseAttempt) {
|
|
@@ -173,11 +206,14 @@ function getExample(testCaseAttempt) {
|
|
|
173
206
|
if (!nodesMap[exampleNodeId]) return;
|
|
174
207
|
const featureDoc = fs.readFileSync(testCaseAttempt.gherkinDocument.uri).toString();
|
|
175
208
|
const { line } = nodesMap[exampleNodeId];
|
|
176
|
-
const example = featureDoc.split('\n')[line-1];
|
|
209
|
+
const example = featureDoc.split('\n')[line - 1];
|
|
177
210
|
if (example) {
|
|
178
|
-
return example
|
|
179
|
-
|
|
180
|
-
|
|
211
|
+
return example
|
|
212
|
+
.trim()
|
|
213
|
+
.split('|')
|
|
214
|
+
.filter(r => !!r)
|
|
215
|
+
.map(r => r.trim());
|
|
216
|
+
}
|
|
181
217
|
}
|
|
182
218
|
|
|
183
219
|
module.exports = CucumberReporter;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// eslint-disable-next-line global-require, import/no-extraneous-dependencies, import/no-unresolved
|
|
2
2
|
const { Formatter } = require('cucumber');
|
|
3
3
|
const chalk = require('chalk');
|
|
4
|
-
const { parseTest } = require('../../util');
|
|
5
|
-
const { STATUS } = require('../../constants');
|
|
4
|
+
const { parseTest, fileSystem } = require('../../util');
|
|
5
|
+
const { STATUS, TESTOMAT_TMP_STORAGE } = require('../../constants');
|
|
6
6
|
const TestomatClient = require('../../client');
|
|
7
7
|
|
|
8
8
|
const createTestomatFormatter = apiKey => {
|
|
@@ -96,9 +96,23 @@ const createTestomatFormatter = apiKey => {
|
|
|
96
96
|
this.status = STATUS.PASSED.toString();
|
|
97
97
|
|
|
98
98
|
options.eventBroadcaster.on('gherkin-document', addDocument);
|
|
99
|
-
options.eventBroadcaster.on('test-run-started', () =>
|
|
99
|
+
options.eventBroadcaster.on('test-run-started', () => {
|
|
100
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE.mainDir);
|
|
101
|
+
this?.client?.createRun();
|
|
102
|
+
});
|
|
100
103
|
options.eventBroadcaster.on('test-case-finished', this.onTestCaseFinished.bind(this));
|
|
104
|
+
options.eventBroadcaster.on('test-case-started', this.onTestCaseStarted.bind(this));
|
|
101
105
|
options.eventBroadcaster.on('test-run-finished', () => this?.client?.updateRunStatus(this.status));
|
|
106
|
+
|
|
107
|
+
global.testomatioRunningEnvironment = 'cucumber:legacy';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
onTestCaseStarted(event) {
|
|
111
|
+
const scenario = getScenario(event.sourceLocation);
|
|
112
|
+
const testId = getTestId(scenario);
|
|
113
|
+
|
|
114
|
+
if (!global.testomatioDataStore) global.testomatioDataStore = {};
|
|
115
|
+
global.testomatioDataStore.currentlyRunningTestId = testId;
|
|
102
116
|
}
|
|
103
117
|
|
|
104
118
|
onTestCaseFinished(event) {
|
|
@@ -111,15 +125,15 @@ const createTestomatFormatter = apiKey => {
|
|
|
111
125
|
|
|
112
126
|
if (!scenario.name) return;
|
|
113
127
|
|
|
114
|
-
|
|
115
|
-
|
|
128
|
+
const message = '';
|
|
129
|
+
const cliMessage = `- ${scenario.name}: ${chalk.bold(status.toUpperCase())}`;
|
|
116
130
|
|
|
117
|
-
if (event.result.status === 'undefined') {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
131
|
+
// if (event.result.status === 'undefined') {
|
|
132
|
+
// cliMessage += chalk.yellow(
|
|
133
|
+
// ' (undefined steps. Run Cucumber without this formatter and implement missing steps)',
|
|
134
|
+
// );
|
|
135
|
+
// message = 'Undefined steps. Implement missing steps and rerun this scenario';
|
|
136
|
+
// }
|
|
123
137
|
console.log(cliMessage);
|
|
124
138
|
if (status !== STATUS.PASSED && status !== STATUS.SKIPPED) {
|
|
125
139
|
this.status = STATUS.FAILED;
|
package/lib/adapter/jest.js
CHANGED
|
@@ -13,8 +13,13 @@ class JestReporter {
|
|
|
13
13
|
|
|
14
14
|
static getIdOfCurrentlyRunningTest() {
|
|
15
15
|
if (!process.env.JEST_WORKER_ID) return null;
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
try {
|
|
17
|
+
// @ts-expect-error "expect" could only be defined inside Jest environement (forbidden to import it outside)
|
|
18
|
+
// eslint-disable-next-line no-undef
|
|
19
|
+
if (expect && expect?.getState()?.currentTestName) return parseTest(expect?.getState()?.currentTestName);
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
onRunStart() {
|
|
@@ -3,14 +3,14 @@ const crypto = require('crypto');
|
|
|
3
3
|
const os = require('os');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const fs = require('fs');
|
|
6
|
-
const { APP_PREFIX, STATUS: Status } = require('../constants');
|
|
6
|
+
const { APP_PREFIX, STATUS: Status, TESTOMAT_TMP_STORAGE } = require('../constants');
|
|
7
7
|
const TestomatioClient = require('../client');
|
|
8
8
|
const { isArtifactsEnabled } = require('../fileUploader');
|
|
9
|
-
const { parseTest } = require('../util');
|
|
9
|
+
const { parseTest, fileSystem } = require('../util');
|
|
10
10
|
|
|
11
11
|
const reportTestPromises = [];
|
|
12
12
|
|
|
13
|
-
class
|
|
13
|
+
class PlaywrightReporter {
|
|
14
14
|
constructor(config = {}) {
|
|
15
15
|
this.client = new TestomatioClient({ apiKey: config?.apiKey });
|
|
16
16
|
|
|
@@ -18,11 +18,17 @@ class TestomatioReporter {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
onBegin(_config, suite) {
|
|
21
|
+
// clean data storage
|
|
22
|
+
fileSystem.clearDir(TESTOMAT_TMP_STORAGE.mainDir);
|
|
21
23
|
if (!this.client) return;
|
|
22
24
|
this.suite = suite;
|
|
23
25
|
this.client.createRun();
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
// onTestBegin(test) {
|
|
29
|
+
// const testId = parseTest(test.title);
|
|
30
|
+
// }
|
|
31
|
+
|
|
26
32
|
onTestEnd(test, result) {
|
|
27
33
|
if (!this.client) return;
|
|
28
34
|
|
|
@@ -37,7 +43,9 @@ class TestomatioReporter {
|
|
|
37
43
|
for (const step of result.steps) {
|
|
38
44
|
appendStep(step, steps);
|
|
39
45
|
}
|
|
40
|
-
|
|
46
|
+
|
|
47
|
+
const logs = `\n\n${chalk.bold('Logs:')}\n${chalk.red(result.stderr.join(''))}\n${result.stdout.join('')}`;
|
|
48
|
+
|
|
41
49
|
const reportTestPromise = this.client.addTestRun(checkStatus(result.status), {
|
|
42
50
|
error,
|
|
43
51
|
test_id: testId,
|
|
@@ -45,13 +53,14 @@ class TestomatioReporter {
|
|
|
45
53
|
title,
|
|
46
54
|
steps: steps.join('\n'),
|
|
47
55
|
time: duration,
|
|
56
|
+
stack: logs,
|
|
48
57
|
}).then(pipes => {
|
|
49
58
|
testId = pipes?.filter(p => p.pipe.includes('Testomatio'))[0]?.result?.data?.test_id;
|
|
50
59
|
|
|
51
60
|
this.uploads.push({
|
|
52
61
|
testId, title, suite_title, files: result.attachments.filter((a) => a.body || a.path)
|
|
53
|
-
})
|
|
54
|
-
})
|
|
62
|
+
});
|
|
63
|
+
});
|
|
55
64
|
|
|
56
65
|
reportTestPromises.push(reportTestPromise);
|
|
57
66
|
}
|
|
@@ -67,10 +76,9 @@ class TestomatioReporter {
|
|
|
67
76
|
const promises = [];
|
|
68
77
|
|
|
69
78
|
for (const upload of this.uploads) {
|
|
70
|
-
|
|
71
79
|
const { title, testId, suite_title } = upload;
|
|
72
80
|
|
|
73
|
-
const files = upload.files.map(
|
|
81
|
+
const files = upload.files.map(attachment => {
|
|
74
82
|
if (attachment.body) {
|
|
75
83
|
const fileName = tmpFile();
|
|
76
84
|
fs.writeFileSync(fileName, attachment.body);
|
|
@@ -78,7 +86,6 @@ class TestomatioReporter {
|
|
|
78
86
|
return { path: attachment.path, title, type: attachment.contentType };
|
|
79
87
|
});
|
|
80
88
|
|
|
81
|
-
|
|
82
89
|
promises.push(
|
|
83
90
|
this.client.addTestRun(undefined, {
|
|
84
91
|
test_id: testId,
|
|
@@ -124,4 +131,4 @@ function tmpFile(prefix = 'tmp.') {
|
|
|
124
131
|
return path.join(tmpdir, prefix + crypto.randomBytes(16).toString('hex'));
|
|
125
132
|
}
|
|
126
133
|
|
|
127
|
-
module.exports =
|
|
134
|
+
module.exports = PlaywrightReporter;
|
package/lib/client.js
CHANGED
|
@@ -21,7 +21,6 @@ class Client {
|
|
|
21
21
|
* @param {*} params
|
|
22
22
|
*/
|
|
23
23
|
constructor(params = {}) {
|
|
24
|
-
this.parallel = params.parallel;
|
|
25
24
|
const store = {};
|
|
26
25
|
this.uuid = randomUUID();
|
|
27
26
|
this.pipes = pipesFactory(params, store);
|
|
@@ -40,20 +39,14 @@ class Client {
|
|
|
40
39
|
// all pipes disabled, skipping
|
|
41
40
|
if (!this.pipes?.filter(p => p.isEnabled).length) return Promise.resolve();
|
|
42
41
|
|
|
43
|
-
const runParams = {
|
|
44
|
-
title: this.title,
|
|
45
|
-
parallel: this.parallel,
|
|
46
|
-
env: this.env,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
42
|
global.testomatioArtifacts = [];
|
|
50
|
-
|
|
43
|
+
if (!global.testomatioDataStore) global.testomatioDataStore = {};
|
|
51
44
|
|
|
52
45
|
this.queue = this.queue
|
|
53
|
-
.then(() => Promise.all(this.pipes.map(p => p.createRun(
|
|
46
|
+
.then(() => Promise.all(this.pipes.map(p => p.createRun())))
|
|
54
47
|
.catch(err => console.log(APP_PREFIX, err))
|
|
55
48
|
.then(() => undefined); // fixes return type
|
|
56
|
-
debug('Run', this.queue);
|
|
49
|
+
// debug('Run', this.queue);
|
|
57
50
|
return this.queue;
|
|
58
51
|
}
|
|
59
52
|
|
|
@@ -99,14 +92,17 @@ class Client {
|
|
|
99
92
|
message = error?.message;
|
|
100
93
|
}
|
|
101
94
|
if (steps) {
|
|
102
|
-
stack
|
|
95
|
+
stack += this.formatSteps(stack, steps);
|
|
103
96
|
}
|
|
104
97
|
|
|
98
|
+
stack += testData.stack || '';
|
|
99
|
+
|
|
100
|
+
// in some cases (e.g. using cucumber) logger instance becomes empty object, if import at the top of the file
|
|
105
101
|
const logger = require('./logger');
|
|
106
102
|
const testLogs = logger.getLogs(test_id);
|
|
107
|
-
debug(`Test logs for ${test_id}:\n`, testLogs);
|
|
103
|
+
// debug(`Test logs for ${test_id}:\n`, testLogs);
|
|
108
104
|
if (stack) stack += '\n\n';
|
|
109
|
-
stack += testLogs;
|
|
105
|
+
stack += testLogs ? `${chalk.bold('Logs:')}\n${testLogs}` : '';
|
|
110
106
|
|
|
111
107
|
if (Array.isArray(storeArtifacts) && storeArtifacts.length) {
|
|
112
108
|
debug('CLIENT storeArtifact', storeArtifacts);
|