@testomatio/reporter 2.0.1-beta.3 → 2.0.1-beta.5-timestamp

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.
Files changed (148) hide show
  1. package/lib/adapter/codecept.js +335 -293
  2. package/lib/adapter/cucumber/current.js +203 -195
  3. package/lib/adapter/cucumber/legacy.js +155 -130
  4. package/lib/adapter/cucumber.js +16 -5
  5. package/lib/adapter/cypress-plugin/index.js +105 -91
  6. package/lib/adapter/jasmine.js +53 -54
  7. package/lib/adapter/jest.js +99 -97
  8. package/lib/adapter/mocha.js +141 -112
  9. package/lib/adapter/playwright.js +231 -199
  10. package/lib/adapter/vitest.js +149 -150
  11. package/lib/adapter/webdriver.js +121 -144
  12. package/lib/bin/cli.js +211 -229
  13. package/lib/bin/reportXml.js +52 -51
  14. package/lib/bin/startTest.js +95 -83
  15. package/lib/bin/uploadArtifacts.js +61 -56
  16. package/lib/client.js +465 -424
  17. package/lib/config.js +23 -18
  18. package/lib/constants.js +44 -50
  19. package/lib/data-storage.js +188 -216
  20. package/lib/junit-adapter/adapter.js +20 -17
  21. package/lib/junit-adapter/csharp.js +14 -28
  22. package/lib/junit-adapter/index.js +25 -27
  23. package/lib/junit-adapter/java.js +53 -41
  24. package/lib/junit-adapter/javascript.js +27 -30
  25. package/lib/junit-adapter/python.js +37 -38
  26. package/lib/junit-adapter/ruby.js +8 -11
  27. package/lib/output.js +52 -44
  28. package/lib/pipe/bitbucket.js +230 -223
  29. package/lib/pipe/csv.js +126 -113
  30. package/lib/pipe/debug.js +99 -118
  31. package/lib/pipe/github.js +213 -218
  32. package/lib/pipe/gitlab.js +206 -183
  33. package/lib/pipe/html.js +321 -258
  34. package/lib/pipe/index.js +66 -94
  35. package/lib/pipe/testomatio.js +474 -429
  36. package/lib/reporter-functions.js +26 -28
  37. package/lib/reporter.js +29 -34
  38. package/lib/services/artifacts.js +51 -55
  39. package/lib/services/index.js +12 -14
  40. package/lib/services/key-values.js +53 -56
  41. package/lib/services/logger.js +245 -226
  42. package/lib/template/testomatio.hbs +1366 -1026
  43. package/lib/uploader.js +364 -295
  44. package/lib/utils/pipe_utils.js +85 -89
  45. package/lib/utils/utils.js +307 -398
  46. package/lib/xmlReader.js +532 -525
  47. package/package.json +21 -64
  48. package/lib/adapter/codecept.d.ts +0 -2
  49. package/lib/adapter/cucumber/current.d.ts +0 -14
  50. package/lib/adapter/cucumber/legacy.d.ts +0 -0
  51. package/lib/adapter/cucumber.d.ts +0 -2
  52. package/lib/adapter/cypress-plugin/index.d.ts +0 -2
  53. package/lib/adapter/jasmine.d.ts +0 -11
  54. package/lib/adapter/jest.d.ts +0 -13
  55. package/lib/adapter/mocha.d.ts +0 -2
  56. package/lib/adapter/nightwatch.d.ts +0 -4
  57. package/lib/adapter/nightwatch.js +0 -80
  58. package/lib/adapter/playwright.d.ts +0 -14
  59. package/lib/adapter/vitest.d.ts +0 -35
  60. package/lib/adapter/webdriver.d.ts +0 -24
  61. package/lib/bin/cli.d.ts +0 -2
  62. package/lib/bin/reportXml.d.ts +0 -2
  63. package/lib/bin/startTest.d.ts +0 -2
  64. package/lib/bin/uploadArtifacts.d.ts +0 -2
  65. package/lib/client.d.ts +0 -76
  66. package/lib/config.d.ts +0 -1
  67. package/lib/constants.d.ts +0 -25
  68. package/lib/data-storage.d.ts +0 -34
  69. package/lib/junit-adapter/adapter.d.ts +0 -9
  70. package/lib/junit-adapter/csharp.d.ts +0 -5
  71. package/lib/junit-adapter/index.d.ts +0 -3
  72. package/lib/junit-adapter/java.d.ts +0 -5
  73. package/lib/junit-adapter/javascript.d.ts +0 -4
  74. package/lib/junit-adapter/python.d.ts +0 -5
  75. package/lib/junit-adapter/ruby.d.ts +0 -4
  76. package/lib/output.d.ts +0 -11
  77. package/lib/package.json +0 -3
  78. package/lib/pipe/bitbucket.d.ts +0 -25
  79. package/lib/pipe/csv.d.ts +0 -47
  80. package/lib/pipe/debug.d.ts +0 -29
  81. package/lib/pipe/github.d.ts +0 -30
  82. package/lib/pipe/gitlab.d.ts +0 -25
  83. package/lib/pipe/html.d.ts +0 -35
  84. package/lib/pipe/index.d.ts +0 -1
  85. package/lib/pipe/testomatio.d.ts +0 -71
  86. package/lib/replay.d.ts +0 -31
  87. package/lib/replay.js +0 -237
  88. package/lib/reporter-functions.d.ts +0 -34
  89. package/lib/reporter.d.ts +0 -232
  90. package/lib/services/artifacts.d.ts +0 -33
  91. package/lib/services/index.d.ts +0 -9
  92. package/lib/services/key-values.d.ts +0 -27
  93. package/lib/services/logger.d.ts +0 -64
  94. package/lib/uploader.d.ts +0 -60
  95. package/lib/utils/pipe_utils.d.ts +0 -41
  96. package/lib/utils/utils.d.ts +0 -54
  97. package/lib/xmlReader.d.ts +0 -92
  98. package/src/adapter/codecept.js +0 -373
  99. package/src/adapter/cucumber/current.js +0 -228
  100. package/src/adapter/cucumber/legacy.js +0 -158
  101. package/src/adapter/cucumber.js +0 -4
  102. package/src/adapter/cypress-plugin/index.js +0 -110
  103. package/src/adapter/jasmine.js +0 -60
  104. package/src/adapter/jest.js +0 -107
  105. package/src/adapter/mocha.cjs +0 -2
  106. package/src/adapter/mocha.js +0 -156
  107. package/src/adapter/nightwatch.js +0 -88
  108. package/src/adapter/playwright.js +0 -254
  109. package/src/adapter/vitest.js +0 -183
  110. package/src/adapter/webdriver.js +0 -142
  111. package/src/bin/cli.js +0 -348
  112. package/src/bin/reportXml.js +0 -77
  113. package/src/bin/startTest.js +0 -124
  114. package/src/bin/uploadArtifacts.js +0 -91
  115. package/src/client.js +0 -508
  116. package/src/config.js +0 -30
  117. package/src/constants.js +0 -53
  118. package/src/data-storage.js +0 -204
  119. package/src/junit-adapter/adapter.js +0 -23
  120. package/src/junit-adapter/csharp.js +0 -28
  121. package/src/junit-adapter/index.js +0 -28
  122. package/src/junit-adapter/java.js +0 -58
  123. package/src/junit-adapter/javascript.js +0 -31
  124. package/src/junit-adapter/python.js +0 -42
  125. package/src/junit-adapter/ruby.js +0 -10
  126. package/src/output.js +0 -57
  127. package/src/pipe/bitbucket.js +0 -252
  128. package/src/pipe/csv.js +0 -140
  129. package/src/pipe/debug.js +0 -119
  130. package/src/pipe/github.js +0 -232
  131. package/src/pipe/gitlab.js +0 -247
  132. package/src/pipe/html.js +0 -373
  133. package/src/pipe/index.js +0 -71
  134. package/src/pipe/testomatio.js +0 -504
  135. package/src/replay.js +0 -245
  136. package/src/reporter-functions.js +0 -55
  137. package/src/reporter.cjs_decprecated +0 -21
  138. package/src/reporter.js +0 -33
  139. package/src/services/artifacts.js +0 -59
  140. package/src/services/index.js +0 -13
  141. package/src/services/key-values.js +0 -59
  142. package/src/services/logger.js +0 -315
  143. package/src/template/emptyData.svg +0 -23
  144. package/src/template/testomatio.hbs +0 -1081
  145. package/src/uploader.js +0 -376
  146. package/src/utils/pipe_utils.js +0 -119
  147. package/src/utils/utils.js +0 -416
  148. package/src/xmlReader.js +0 -614
@@ -1,216 +1,224 @@
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.CucumberReporter = void 0;
7
- const cucumber_1 = require("@cucumber/cucumber");
8
- const picocolors_1 = __importDefault(require("picocolors"));
9
- const fs_1 = __importDefault(require("fs"));
10
- const constants_js_1 = require("../../constants.js");
11
- const client_js_1 = __importDefault(require("../../client.js"));
12
- const utils_js_1 = require("../../utils/utils.js");
13
- const config_js_1 = require("../../config.js");
14
- const index_js_1 = require("../../services/index.js");
15
- const { GherkinDocumentParser, PickleParser } = cucumber_1.formatterHelpers;
1
+ // eslint-disable-next-line global-require, import/no-extraneous-dependencies, import/no-unresolved
2
+ const { Formatter, formatterHelpers } = require('@cucumber/cucumber');
3
+ const chalk = require('chalk');
4
+ const fs = require('fs');
5
+ const { STATUS, TESTOMAT_TMP_STORAGE_DIR } = require('../../constants');
6
+ const TestomatClient = require('../../client');
7
+ const { getTestomatIdFromTestTitle, fileSystem } = require('../../utils/utils');
8
+ const config = require('../../config');
9
+ const { services } = require('../../services');
10
+
11
+ const { GherkinDocumentParser, PickleParser } = formatterHelpers;
16
12
  const { getGherkinScenarioLocationMap, getGherkinStepMap } = GherkinDocumentParser;
17
13
  const { getPickleStepMap } = PickleParser;
14
+
18
15
  function getTestId(scenario) {
19
- if (scenario) {
20
- for (const tag of scenario.tags) {
21
- const testId = (0, utils_js_1.getTestomatIdFromTestTitle)(tag.name);
22
- if (testId)
23
- return testId;
24
- }
16
+ if (scenario) {
17
+ for (const tag of scenario.tags) {
18
+ const testId = getTestomatIdFromTestTitle(tag.name);
19
+ if (testId) return testId;
25
20
  }
26
- return null;
21
+ }
22
+
23
+ return null;
27
24
  }
28
- class CucumberReporter extends cucumber_1.Formatter {
29
- constructor(options) {
30
- super(options);
31
- options.eventBroadcaster.on('envelope', this.parseEnvelope.bind(this));
32
- this.failures = [];
33
- this.cases = [];
34
- this.client = new client_js_1.default({ apiKey: options.apiKey || config_js_1.config.TESTOMATIO });
35
- this.client.createRun();
36
- this.status = constants_js_1.STATUS.PASSED;
25
+
26
+ class CucumberReporter extends Formatter {
27
+ constructor(options) {
28
+ super(options);
29
+ options.eventBroadcaster.on('envelope', this.parseEnvelope.bind(this));
30
+ this.failures = [];
31
+ this.cases = [];
32
+
33
+ this.client = new TestomatClient({ apiKey: options.apiKey || config.TESTOMATIO });
34
+ this.status = STATUS.PASSED;
35
+ this.client.createRun();
36
+ }
37
+
38
+ parseEnvelope(envelope) {
39
+ if (envelope.testRunStarted) {
40
+ fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
37
41
  }
38
- parseEnvelope(envelope) {
39
- if (envelope.testRunStarted) {
40
- utils_js_1.fileSystem.clearDir(constants_js_1.TESTOMAT_TMP_STORAGE_DIR);
41
- }
42
- if (envelope.testCaseStarted && this.client) {
43
- this.onTestCaseStarted(envelope.testCaseStarted);
44
- }
45
- if (envelope.testCaseFinished)
46
- this.onTestCaseFinished(envelope.testCaseFinished);
47
- if (envelope.testRunFinished)
48
- this.onTestRunFinished(envelope);
42
+ if (envelope.testCaseStarted && this.client) this.onTestCaseStarted(envelope.testCaseStarted);
43
+ if (envelope.testCaseFinished) this.onTestCaseFinished(envelope.testCaseFinished);
44
+ if (envelope.testRunFinished) this.onTestRunFinished(envelope);
45
+ }
46
+
47
+ onTestCaseStarted(testCaseStarted) {
48
+ const testCaseAttempt = this.eventDataCollector.getTestCaseAttempt(testCaseStarted.id);
49
+ if (!global.testomatioDataStore) global.testomatioDataStore = {};
50
+
51
+ const testTitle = testCaseAttempt.pickle.name + testCaseAttempt.pickle.uri;
52
+ services.setContext(testTitle);
53
+ }
54
+
55
+ onTestCaseFinished(testCaseFinished) {
56
+ const testCaseAttempt = this.eventDataCollector.getTestCaseAttempt(testCaseFinished.testCaseStartedId);
57
+
58
+ let example;
59
+
60
+ let status = STATUS.PASSED;
61
+ let color = 'green';
62
+ let message;
63
+
64
+ this.cases.push(testCaseAttempt);
65
+
66
+ if (testCaseAttempt.worstTestStepResult) {
67
+ if (testCaseAttempt.worstTestStepResult.status === 'SKIPPED') {
68
+ status = STATUS.SKIPPED;
69
+ }
70
+ // if (testCaseAttempt.worstTestStepResult.status === 'UNDEFINED') {
71
+ // status = STATUS.SKIPPED;
72
+ // message = 'Undefined steps. Implement missing steps and rerun this scenario';
73
+ // }
74
+ if (testCaseAttempt.worstTestStepResult.status === 'FAILED') {
75
+ message = testCaseAttempt?.worstTestStepResult?.message;
76
+ status = STATUS.FAILED;
77
+ }
78
+ color = getStatusColor(testCaseAttempt.worstTestStepResult.status);
79
+ if (status !== STATUS.PASSED) this.failures.push(testCaseAttempt);
49
80
  }
50
- onTestCaseStarted(testCaseStarted) {
51
- const testCaseAttempt = this.eventDataCollector.getTestCaseAttempt(testCaseStarted.id);
52
- if (!global.testomatioDataStore)
53
- global.testomatioDataStore = {};
54
- const testTitle = testCaseAttempt.pickle.name + testCaseAttempt.pickle.uri;
55
- index_js_1.services.setContext(testTitle);
81
+
82
+ if (testCaseAttempt.pickle.astNodeIds.length > 1) {
83
+ example = getExample(testCaseAttempt);
84
+ // @ts-ignore
85
+ testCaseAttempt.example = example;
56
86
  }
57
- onTestCaseFinished(testCaseFinished) {
58
- const testCaseAttempt = this.eventDataCollector.getTestCaseAttempt(testCaseFinished.testCaseStartedId);
59
- let example;
60
- let status = constants_js_1.STATUS.PASSED;
61
- let color = 'green';
62
- let message;
63
- this.cases.push(testCaseAttempt);
64
- if (testCaseAttempt.worstTestStepResult) {
65
- if (testCaseAttempt.worstTestStepResult.status === 'SKIPPED') {
66
- status = constants_js_1.STATUS.SKIPPED;
67
- }
68
- // if (testCaseAttempt.worstTestStepResult.status === 'UNDEFINED') {
69
- // status = STATUS.SKIPPED;
70
- // message = 'Undefined steps. Implement missing steps and rerun this scenario';
71
- // }
72
- if (testCaseAttempt.worstTestStepResult.status === 'FAILED') {
73
- message = testCaseAttempt?.worstTestStepResult?.message;
74
- status = constants_js_1.STATUS.FAILED;
75
- }
76
- color = getStatusColor(testCaseAttempt.worstTestStepResult.status);
77
- if (status !== constants_js_1.STATUS.PASSED)
78
- this.failures.push(testCaseAttempt);
79
- }
80
- if (testCaseAttempt.pickle.astNodeIds.length > 1) {
81
- example = getExample(testCaseAttempt);
82
- // @ts-ignore
83
- testCaseAttempt.example = example;
84
- }
85
- const scenario = testCaseAttempt.pickle.name;
86
- // this may broke something (it is supposed to work, but I am sure it did not)
87
- // const testId = testCaseAttempt.pickle.id;
88
- const testId = getTestId(testCaseAttempt.pickle);
89
- let exampleString = '';
90
- if (example)
91
- exampleString = ` ${example.join(' | ')}`;
92
- let cliMessage = `${picocolors_1.default.bold(scenario)}${exampleString}: ${picocolors_1.default[color](picocolors_1.default.bold(status.toUpperCase()))} `;
93
- if (message)
94
- cliMessage += picocolors_1.default.gray(message.split('\n')[0]);
95
- console.log(cliMessage);
96
- if (status !== constants_js_1.STATUS.PASSED && status !== constants_js_1.STATUS.SKIPPED) {
97
- this.status = constants_js_1.STATUS.FAILED;
98
- }
99
- const time = Object.values(testCaseAttempt.stepResults)
100
- .map(t => t.duration)
101
- .reduce((sum, duration) => sum + duration.seconds * 1000 + duration.nanos / 1000000, 0);
102
- if (!this.client)
103
- return;
104
- const testTitle = testCaseAttempt.pickle.name + testCaseAttempt.pickle.uri;
105
- const logs = index_js_1.services.logger.getLogs(testTitle).join('\n');
106
- const artifacts = index_js_1.services.artifacts.get(testTitle);
107
- const keyValues = index_js_1.services.keyValues.get(testTitle);
108
- this.client.addTestRun(status, {
109
- // error: testCaseAttempt.worstTestStepResult.message,
110
- message,
111
- steps: getSteps(testCaseAttempt)
112
- .map(s => s.toString())
113
- .join('\n')
114
- .trim(),
115
- example: { ...example },
116
- logs,
117
- manuallyAttachedArtifacts: artifacts,
118
- meta: keyValues,
119
- title: scenario,
120
- test_id: testId,
121
- time,
122
- });
123
- index_js_1.services.setContext(null);
87
+
88
+ const scenario = testCaseAttempt.pickle.name;
89
+ // this may broke something (it is supposed to work, but I am sure it did not)
90
+ // const testId = testCaseAttempt.pickle.id;
91
+ const testId = getTestId(testCaseAttempt.pickle);
92
+
93
+ let exampleString = '';
94
+ if (example) exampleString = ` ${example.join(' | ')}`;
95
+ let cliMessage = `${chalk.bold(scenario)}${exampleString}: ${chalk[color].bold(status.toUpperCase())} `;
96
+
97
+ if (message) cliMessage += chalk.gray(message.split('\n')[0]);
98
+ console.log(cliMessage);
99
+
100
+ if (status !== STATUS.PASSED && status !== STATUS.SKIPPED) {
101
+ this.status = STATUS.FAILED;
124
102
  }
125
- onTestRunFinished(envelope) {
126
- if (this.failures.length > 0) {
127
- console.log(picocolors_1.default.bold('\nSUMMARY:\n\n'));
128
- this.failures.forEach((tc, i) => {
129
- let message = ` ${i + 1}) ${tc.pickle.name}\n`;
130
- const steps = getSteps(tc);
131
- steps.forEach(s => {
132
- message += ` ${s.toString()}\n`;
133
- });
134
- console.log(message);
135
- if (tc?.worstTestStepResult?.message) {
136
- console.log(picocolors_1.default.red(tc?.worstTestStepResult?.message));
137
- }
138
- console.log();
139
- });
103
+
104
+ const time = Object.values(testCaseAttempt.stepResults)
105
+ .map(t => t.duration)
106
+ .reduce((sum, duration) => sum + duration.seconds * 1000 + duration.nanos / 1000000, 0);
107
+
108
+ if (!this.client) return;
109
+
110
+ const testTitle = testCaseAttempt.pickle.name + testCaseAttempt.pickle.uri;
111
+ const logs = services.logger.getLogs(testTitle).join('\n');
112
+ const artifacts = services.artifacts.get(testTitle);
113
+ const keyValues = services.keyValues.get(testTitle);
114
+
115
+ this.client.addTestRun(status, {
116
+ // error: testCaseAttempt.worstTestStepResult.message,
117
+ message,
118
+ steps: getSteps(testCaseAttempt)
119
+ .map(s => s.toString())
120
+ .join('\n')
121
+ .trim(),
122
+ example: { ...example },
123
+ logs,
124
+ manuallyAttachedArtifacts: artifacts,
125
+ meta: keyValues,
126
+ title: scenario,
127
+ test_id: testId,
128
+ time,
129
+ });
130
+
131
+ services.setContext(null);
132
+ }
133
+
134
+ onTestRunFinished(envelope) {
135
+ if (this.failures.length > 0) {
136
+ console.log(chalk.bold('\nSUMMARY:\n\n'));
137
+
138
+ this.failures.forEach((tc, i) => {
139
+ let message = ` ${i + 1}) ${tc.pickle.name}\n`;
140
+
141
+ const steps = getSteps(tc);
142
+
143
+ steps.forEach(s => {
144
+ message += ` ${s.toString()}\n`;
145
+ });
146
+
147
+ console.log(message);
148
+ if (tc?.worstTestStepResult?.message) {
149
+ console.log(chalk.red(tc?.worstTestStepResult?.message));
140
150
  }
141
- const { testRunFinished } = envelope;
142
- const bgColor = testRunFinished.success ? 'bgGreen' : 'bgRed';
143
- const prefixSummary = `${picocolors_1.default.bold(testRunFinished.success ? ' SUCCESS ' : ' FALIURE ')}`;
144
151
  console.log();
145
- console.log(picocolors_1.default[bgColor](` ${prefixSummary} | Total Scenarios: ${picocolors_1.default.bold(this.cases.length)} `));
146
- if (!this.client)
147
- return;
148
- // @ts-ignore
149
- this.client.updateRunStatus(testRunFinished.success ? constants_js_1.STATUS.PASSED : constants_js_1.STATUS.FAILED);
152
+ });
150
153
  }
154
+
155
+ const { testRunFinished } = envelope;
156
+
157
+ const bgColor = testRunFinished.success ? 'bgGreen' : 'bgRed';
158
+ const prefixSummary = `${chalk.bold(testRunFinished.success ? ' SUCCESS ' : ' FALIURE ')}`;
159
+ console.log();
160
+ console.log(chalk[bgColor](` ${prefixSummary} | Total Scenarios: ${chalk.bold(this.cases.length)} `));
161
+
162
+ if (!this.client) return;
163
+
164
+ this.client.updateRunStatus(testRunFinished.success ? STATUS.PASSED : STATUS.FAILED);
165
+ }
151
166
  }
152
- exports.CucumberReporter = CucumberReporter;
167
+
153
168
  function getSteps(tc) {
154
- const stepIds = Object.keys(tc.stepResults);
155
- const pickleSteps = getPickleStepMap(tc.pickle);
156
- return stepIds
157
- .map(stepId => {
158
- const ts = tc.testCase.testSteps.find(t => t.id === stepId);
159
- if (!ts)
160
- return;
161
- if (!ts.pickleStepId)
162
- return;
163
- const result = tc.stepResults[stepId];
164
- const pickleStep = pickleSteps[ts.pickleStepId];
165
- const sourceStepId = pickleStep.astNodeIds[0];
166
- const step = {
167
- text: pickleStep.text,
168
- duration: result.duration,
169
- status: result.status,
170
- };
171
- const color = getStatusColor(result.status);
172
- if (sourceStepId && getGherkinStepMap(tc.gherkinDocument)[sourceStepId]) {
173
- step.keyword = getGherkinStepMap(tc.gherkinDocument)[sourceStepId].keyword;
174
- }
175
- step.toString = function toString() {
176
- const duration = step.duration.seconds * 1000 + step.duration.nanos / 1000000;
177
- const durationString = ` ${picocolors_1.default.gray(`(${Number(duration).toFixed(2)}ms)`)}`;
178
- const stepString = `${picocolors_1.default.bold(this.keyword)}${this.text}`.trim();
179
- if (color === 'red')
180
- return picocolors_1.default.red(stepString) + durationString;
181
- if (color === 'yellow')
182
- return picocolors_1.default.yellow(stepString) + durationString;
183
- return stepString + durationString;
184
- };
185
- return step;
169
+ const stepIds = Object.keys(tc.stepResults);
170
+ const pickleSteps = getPickleStepMap(tc.pickle);
171
+ return stepIds
172
+ .map(stepId => {
173
+ const ts = tc.testCase.testSteps.find(t => t.id === stepId);
174
+ if (!ts) return;
175
+ if (!ts.pickleStepId) return;
176
+ const result = tc.stepResults[stepId];
177
+ const pickleStep = pickleSteps[ts.pickleStepId];
178
+ const sourceStepId = pickleStep.astNodeIds[0];
179
+ const step = {
180
+ text: pickleStep.text,
181
+ duration: result.duration,
182
+ status: result.status,
183
+ };
184
+ const color = getStatusColor(result.status);
185
+ if (sourceStepId && getGherkinStepMap(tc.gherkinDocument)[sourceStepId]) {
186
+ step.keyword = getGherkinStepMap(tc.gherkinDocument)[sourceStepId].keyword;
187
+ }
188
+ step.toString = function toString() {
189
+ const duration = step.duration.seconds * 1000 + step.duration.nanos / 1000000;
190
+ const durationString = ` ${chalk.gray(`(${Number(duration).toFixed(2)}ms)`)}`;
191
+ const stepString = `${chalk.bold(this.keyword)}${this.text}`.trim();
192
+ if (color === 'red') return chalk.red(stepString) + durationString;
193
+ if (color === 'yellow') return chalk.yellow(stepString) + durationString;
194
+ return stepString + durationString;
195
+ };
196
+ return step;
186
197
  })
187
- .filter(s => !!s);
198
+ .filter(s => !!s);
188
199
  }
200
+
189
201
  function getStatusColor(status) {
190
- if (status === 'UNDEFINED')
191
- return 'yellow';
192
- if (status === 'SKIPPED')
193
- return 'yellow';
194
- if (status === 'FAILED')
195
- return 'red';
196
- return 'green';
202
+ if (status === 'UNDEFINED') return 'yellow';
203
+ if (status === 'SKIPPED') return 'yellow';
204
+ if (status === 'FAILED') return 'red';
205
+ return 'green';
197
206
  }
207
+
198
208
  function getExample(testCaseAttempt) {
199
- const nodesMap = getGherkinScenarioLocationMap(testCaseAttempt.gherkinDocument);
200
- const exampleNodeId = testCaseAttempt.pickle.astNodeIds[1];
201
- if (!nodesMap[exampleNodeId])
202
- return;
203
- const featureDoc = fs_1.default.readFileSync(testCaseAttempt.gherkinDocument.uri).toString();
204
- const { line } = nodesMap[exampleNodeId];
205
- const example = featureDoc.split('\n')[line - 1];
206
- if (example) {
207
- return example
208
- .trim()
209
- .split('|')
210
- .filter(r => !!r)
211
- .map(r => r.trim());
212
- }
209
+ const nodesMap = getGherkinScenarioLocationMap(testCaseAttempt.gherkinDocument);
210
+ const exampleNodeId = testCaseAttempt.pickle.astNodeIds[1];
211
+ if (!nodesMap[exampleNodeId]) return;
212
+ const featureDoc = fs.readFileSync(testCaseAttempt.gherkinDocument.uri).toString();
213
+ const { line } = nodesMap[exampleNodeId];
214
+ const example = featureDoc.split('\n')[line - 1];
215
+ if (example) {
216
+ return example
217
+ .trim()
218
+ .split('|')
219
+ .filter(r => !!r)
220
+ .map(r => r.trim());
221
+ }
213
222
  }
214
- module.exports = CucumberReporter;
215
223
 
216
- module.exports.CucumberReporter = CucumberReporter;
224
+ module.exports = CucumberReporter;