@testomatio/reporter 0.4.6 → 0.5.0-beta.1

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 (49) hide show
  1. package/.eslintrc.js +18 -22
  2. package/.github/workflows/node.js.yml +2 -1
  3. package/.prettierrc.js +12 -0
  4. package/Changelog.md +18 -18
  5. package/README.md +122 -93
  6. package/example/codecept/codecept.conf.js +7 -7
  7. package/example/codecept/index_test.js +8 -8
  8. package/example/codecept/sample_test.js +4 -4
  9. package/example/codecept/steps.d.ts +1 -1
  10. package/example/codecept/steps_file.js +4 -2
  11. package/example/core/index.js +6 -6
  12. package/example/jest/index.test.js +3 -3
  13. package/example/jest/jest.config.js +1 -1
  14. package/example/jest/sample.test.js +4 -4
  15. package/example/mocha/test/index.test.js +5 -5
  16. package/lib/adapter/codecept.js +62 -67
  17. package/lib/adapter/cucumber.js +35 -52
  18. package/lib/adapter/cypress-plugin/index.js +42 -0
  19. package/lib/adapter/jasmine.js +15 -6
  20. package/lib/adapter/jest.js +9 -10
  21. package/lib/adapter/mocha.js +17 -14
  22. package/lib/adapter/playwright.js +25 -25
  23. package/lib/adapter/webdriver.js +3 -3
  24. package/lib/bin/startTest.js +56 -60
  25. package/lib/client.js +58 -110
  26. package/lib/constants.js +6 -6
  27. package/lib/fileUploader.js +17 -16
  28. package/lib/output.js +6 -8
  29. package/lib/reporter.js +2 -2
  30. package/lib/util.js +18 -5
  31. package/package.json +27 -15
  32. package/testcafe/index.js +11 -14
  33. package/tests/adapter/config/index.js +10 -0
  34. package/tests/adapter/examples/codecept/codecept.conf.js +33 -0
  35. package/tests/adapter/examples/codecept/index_test.js +11 -0
  36. package/tests/adapter/examples/codecept/jsconfig.json +5 -0
  37. package/tests/adapter/examples/codecept/output/Test_for_suite_2_@Tc2171bd2.failed.png +0 -0
  38. package/tests/adapter/examples/codecept/output/Test_issue_for_suite_1_@Tca70c8c4.failed.png +0 -0
  39. package/tests/adapter/examples/codecept/sample_test.js +7 -0
  40. package/tests/adapter/examples/codecept/steps_file.js +10 -0
  41. package/tests/adapter/examples/jasmine/index.test.js +11 -0
  42. package/tests/adapter/examples/jasmine/passReporterOpts.sh +8 -0
  43. package/tests/adapter/examples/jest/index.test.js +11 -0
  44. package/tests/adapter/examples/jest/jest.config.js +4 -0
  45. package/tests/adapter/examples/mocha/index.test.js +13 -0
  46. package/tests/adapter/examples/mocha/mocha.config.js +4 -0
  47. package/tests/adapter/index.test.js +136 -0
  48. package/tests/adapter/utils/index.js +40 -0
  49. package/.prettierrc.json +0 -1
@@ -1,9 +1,9 @@
1
- describe("Suite 1", () => {
2
- test("Test addition", () => {
1
+ describe('Suite 1', () => {
2
+ test('Test addition', () => {
3
3
  expect(1 + 2).toBe(4);
4
4
  });
5
5
 
6
- test("Test some more addition", () => {
6
+ test('Test some more addition', () => {
7
7
  expect(1 + 2).toBe(3);
8
8
  });
9
9
  });
@@ -132,7 +132,7 @@ module.exports = {
132
132
  // snapshotSerializers: [],
133
133
 
134
134
  // The test environment that will be used for testing
135
- testEnvironment: "node",
135
+ testEnvironment: 'node',
136
136
 
137
137
  // Options that will be passed to the testEnvironment
138
138
  // testEnvironmentOptions: {},
@@ -1,13 +1,13 @@
1
- describe("Suite 2", () => {
2
- test("This is a sample test 3", () => {
1
+ describe('Suite 2', () => {
2
+ test('This is a sample test 3', () => {
3
3
  expect(1 + 2).toBe(3);
4
4
  });
5
5
 
6
- test("This is a sample test 4", () => {
6
+ test('This is a sample test 4', () => {
7
7
  expect(1 + 2).toBe(3);
8
8
  });
9
9
 
10
- test("Test for suite 2", () => {
10
+ test('Test for suite 2', () => {
11
11
  expect(1 + 2).toBe(3);
12
12
  });
13
13
  });
@@ -1,13 +1,13 @@
1
- const assert = require("assert");
1
+ const assert = require('assert');
2
2
 
3
- describe("Sample mocha suite", () => {
4
- it("Sample mocha test", () => {
3
+ describe('Sample mocha suite', () => {
4
+ it('Sample mocha test', () => {
5
5
  assert.equal([1, 2, 3].indexOf(4), 0);
6
6
  });
7
7
  });
8
8
 
9
- describe("Sample mocha suite 2", () => {
10
- it("Sample mocha test 2", () => {
9
+ describe('Sample mocha suite 2', () => {
10
+ it('Sample mocha test 2', () => {
11
11
  assert.equal(1, 1);
12
12
  });
13
13
  });
@@ -1,63 +1,46 @@
1
- /* eslint-disable no-param-reassign */
2
1
  if (!global.codeceptjs) {
3
- global.codeceptjs = require("codeceptjs");
2
+ // eslint-disable-next-line global-require
3
+ global.codeceptjs = require('codeceptjs');
4
4
  }
5
+
5
6
  const { event, recorder, codecept } = global.codeceptjs;
6
- const chalk = require("chalk");
7
- const TestomatClient = require("../client");
8
- const { FAILED } = require("../constants");
9
- const TRConstants = require("../constants");
10
- const upload = require("../fileUploader");
11
- const Output = require("../output");
7
+ const chalk = require('chalk');
8
+ const TestomatClient = require('../client');
9
+ const { FAILED } = require('../constants');
10
+ const TRConstants = require('../constants');
11
+ const upload = require('../fileUploader');
12
+ const Output = require('../output');
12
13
 
13
14
  let currentMetaStep = [];
14
15
  let error;
15
16
  let stepShift = 0;
17
+
16
18
  const output = new Output({
17
- filterFn: (stack) => !stack.includes("codeceptjs/lib/output"), // output from codeceptjs
19
+ filterFn: stack => !stack.includes('codeceptjs/lib/output'), // output from codeceptjs
18
20
  });
21
+
19
22
  let stepStart = new Date();
20
23
 
21
24
  const MAJOR_VERSION = parseInt(codecept.version().match(/\d/)[0], 10);
22
25
 
26
+ const DATA_REGEXP = /[|\s]+?(\{".*\}|\[.*\])/;
27
+
23
28
  if (MAJOR_VERSION < 3) {
24
- console.log(
25
- "🔴 This reporter works with CodeceptJS 3+, please update your tests"
26
- );
29
+ console.log('🔴 This reporter works with CodeceptJS 3+, please update your tests');
27
30
  }
28
31
 
29
- const parseTest = (tags) => {
30
- if (tags) {
31
- for (const tag of tags) {
32
- if (tag.startsWith("@T")) {
33
- return tag.substring(2, tag.length);
34
- }
35
- }
36
- }
37
-
38
- return null;
39
- };
40
-
41
- const getTestAndMessage = (title) => {
42
- const testObj = { message: "" };
43
- const testArr = title.split(/\s(\|\s\{.*?\})/);
44
- testObj.title = testArr[0];
45
-
46
- return testObj;
47
- };
48
-
49
- module.exports = (config) => {
32
+ function CodeceptReporter(config) {
50
33
  let failedTests = [];
51
34
  let videos = [];
52
35
  const testTimeMap = {};
53
36
  const { apiKey } = config;
54
37
 
55
38
  if (!apiKey) {
56
- console.log("TESTOMATIO key is empty, ignoring reports");
39
+ console.log('TESTOMATIO key is empty, ignoring reports');
57
40
  return;
58
41
  }
59
42
 
60
- const getDuration = (test) => {
43
+ const getDuration = test => {
61
44
  if (testTimeMap[test.id]) {
62
45
  return Date.now() - testTimeMap[test.id];
63
46
  }
@@ -71,7 +54,7 @@ module.exports = (config) => {
71
54
 
72
55
  // Listening to events
73
56
  event.dispatcher.on(event.all.before, () => {
74
- recorder.add("Creating new run", () => client.createRun());
57
+ recorder.add('Creating new run', () => client.createRun());
75
58
  videos = [];
76
59
  });
77
60
 
@@ -84,23 +67,24 @@ module.exports = (config) => {
84
67
  });
85
68
  });
86
69
 
87
- event.dispatcher.on(event.test.started, (test) => {
70
+ event.dispatcher.on(event.test.started, test => {
88
71
  testTimeMap[test.id] = Date.now();
89
- err = null;
90
72
  });
91
73
 
92
74
  event.dispatcher.on(event.all.result, async () => {
93
75
  if (videos.length && upload.isEnabled()) {
94
76
  console.log(TRConstants.APP_PREFIX, `🎞️ Uploading ${videos.length} videos...`);
95
77
 
96
- let promises = [];
78
+ const promises = [];
97
79
  for (const video of videos) {
98
80
  const { testId, title, path, type } = video;
99
81
  const file = { path, type, title };
100
- promises.push(client.addTestRun(testId, undefined, {
101
- ...stripExampleFromTitle(title),
102
- files: [file],
103
- }));
82
+ promises.push(
83
+ client.addTestRun(testId, undefined, {
84
+ ...stripExampleFromTitle(title),
85
+ files: [file],
86
+ }),
87
+ );
104
88
  }
105
89
  await Promise.all(promises);
106
90
  }
@@ -109,10 +93,10 @@ module.exports = (config) => {
109
93
  client.updateRunStatus(status);
110
94
  });
111
95
 
112
- event.dispatcher.on(event.test.passed, (test) => {
96
+ event.dispatcher.on(event.test.passed, test => {
113
97
  const { id, tags, title } = test;
114
98
  if (id && failedTests.includes(id)) {
115
- failedTests = failedTests.filter((failed) => id !== failed);
99
+ failedTests = failedTests.filter(failed => id !== failed);
116
100
  }
117
101
  const testId = parseTest(tags);
118
102
  const testObj = getTestAndMessage(title);
@@ -129,7 +113,7 @@ module.exports = (config) => {
129
113
  error = err;
130
114
  });
131
115
 
132
- event.dispatcher.on(event.test.after, (test) => {
116
+ event.dispatcher.on(event.test.after, test => {
133
117
  if (test.state && test.state !== FAILED) return;
134
118
  if (test.err) error = test.err;
135
119
  const { id, tags, title, artifacts } = test;
@@ -156,7 +140,7 @@ module.exports = (config) => {
156
140
  output.stop();
157
141
  });
158
142
 
159
- event.dispatcher.on(event.test.skipped, (test) => {
143
+ event.dispatcher.on(event.test.skipped, test => {
160
144
  const { tags, title } = test;
161
145
  const testId = parseTest(tags);
162
146
  const testObj = getTestAndMessage(title);
@@ -168,13 +152,13 @@ module.exports = (config) => {
168
152
  output.stop();
169
153
  });
170
154
 
171
- event.dispatcher.on(event.step.started, (step) => {
155
+ event.dispatcher.on(event.step.started, step => {
172
156
  stepShift = 0;
173
157
  step.started = true;
174
158
  stepStart = new Date();
175
159
  });
176
160
 
177
- event.dispatcher.on(event.step.finished, (step) => {
161
+ event.dispatcher.on(event.step.finished, step => {
178
162
  if (!step.started) return;
179
163
  let processingStep = step;
180
164
  const metaSteps = [];
@@ -184,24 +168,15 @@ module.exports = (config) => {
184
168
  }
185
169
  const shift = metaSteps.length;
186
170
 
187
- for (
188
- let i = 0;
189
- i < Math.max(currentMetaStep.length, metaSteps.length);
190
- i++
191
- ) {
171
+ for (let i = 0; i < Math.max(currentMetaStep.length, metaSteps.length); i++) {
192
172
  if (currentMetaStep[i] !== metaSteps[i]) {
193
173
  stepShift = 2 * i;
174
+ // eslint-disable-next-line no-continue
194
175
  if (!metaSteps[i]) continue;
195
176
  if (metaSteps[i].isBDD()) {
196
- output.push(
197
- repeat(stepShift) +
198
- chalk.bold(metaSteps[i].toString()) +
199
- metaSteps[i].comment
200
- );
177
+ output.push(repeat(stepShift) + chalk.bold(metaSteps[i].toString()) + metaSteps[i].comment);
201
178
  } else {
202
- output.push(
203
- repeat(stepShift) + chalk.green.bold(metaSteps[i].toString())
204
- );
179
+ output.push(repeat(stepShift) + chalk.green.bold(metaSteps[i].toString()));
205
180
  }
206
181
  }
207
182
  }
@@ -220,23 +195,43 @@ module.exports = (config) => {
220
195
  }
221
196
  });
222
197
 
223
- event.dispatcher.on(event.step.comment, (step) => {
198
+ event.dispatcher.on(event.step.comment, step => {
224
199
  output.push(chalk.cyan.bold(step.toString()));
225
200
  });
226
- };
201
+ }
227
202
 
228
- const DATA_REGEXP = /[|\s]+?(\{".*\}|\[.*\])/;
203
+ function parseTest(tags) {
204
+ if (tags) {
205
+ for (const tag of tags) {
206
+ if (tag.startsWith('@T')) {
207
+ return tag.substring(2, tag.length);
208
+ }
209
+ }
210
+ }
211
+
212
+ return null;
213
+ }
214
+
215
+ function getTestAndMessage(title) {
216
+ const testObj = { message: '' };
217
+ const testArr = title.split(/\s(\|\s\{.*?\})/);
218
+ testObj.title = testArr[0];
219
+
220
+ return testObj;
221
+ }
229
222
 
230
223
  function stripExampleFromTitle(title) {
231
224
  const res = title.match(DATA_REGEXP);
232
225
  if (!res) return { title, example: null };
233
226
 
234
227
  const example = JSON.parse(res[1]);
235
- title = title.replace(DATA_REGEXP, "").trim();
228
+ title = title.replace(DATA_REGEXP, '').trim();
236
229
 
237
230
  return { title, example };
238
231
  }
239
232
 
240
233
  function repeat(num) {
241
- return "".padStart(num, " ");
234
+ return ''.padStart(num, ' ');
242
235
  }
236
+
237
+ module.exports = CodeceptReporter;
@@ -1,24 +1,25 @@
1
- const { Formatter } = require("cucumber");
2
- const chalk = require("chalk");
3
- const { TestomatClient, TRConstants } = require("../reporter");
4
- const { parseTest } = require("../util");
5
-
6
- const createTestomatFormatter = (apiKey) => {
7
- if (!apiKey || apiKey === "") {
8
- console.log(chalk.red("TESTOMATIO key is empty, ignoring reports"));
1
+ // eslint-disable-next-line import/no-unresolved
2
+ const { Formatter } = require('cucumber');
3
+ const chalk = require('chalk');
4
+ const { TestomatClient, TRConstants } = require('../reporter');
5
+ const { parseTest } = require('../util');
6
+
7
+ const createTestomatFormatter = apiKey => {
8
+ if (!apiKey || apiKey === '') {
9
+ console.log(chalk.red('TESTOMATIO key is empty, ignoring reports'));
9
10
  }
10
11
 
11
12
  const documents = {};
12
13
  const dataTableMap = {};
13
14
 
14
- const addDocument = (gherkinDocument) => {
15
+ const addDocument = gherkinDocument => {
15
16
  documents[gherkinDocument.uri] = gherkinDocument.document;
16
17
  };
17
18
 
18
- const getTitle = (scenario) => {
19
+ const getTitle = scenario => {
19
20
  let { name } = scenario;
20
21
  if (scenario.tags.length) {
21
- let tags = "";
22
+ let tags = '';
22
23
  for (const tag of scenario.tags) {
23
24
  tags = `${tags} ${tag.name}`;
24
25
  }
@@ -27,18 +28,15 @@ const createTestomatFormatter = (apiKey) => {
27
28
  return name;
28
29
  };
29
30
 
30
- const getFeature = (uri) => documents[uri].feature;
31
+ const getFeature = uri => documents[uri].feature;
31
32
 
32
- const getScenario = (location) => {
33
+ const getScenario = location => {
33
34
  const { children } = getFeature(location.uri);
34
35
  for (const scenario of children) {
35
- if (
36
- scenario.type === "Scenario" &&
37
- scenario.location.line === location.line
38
- ) {
36
+ if (scenario.type === 'Scenario' && scenario.location.line === location.line) {
39
37
  return scenario;
40
38
  }
41
- if (scenario.type === "ScenarioOutline") {
39
+ if (scenario.type === 'ScenarioOutline') {
42
40
  for (const example of scenario.examples) {
43
41
  for (const tableBody of example.tableBody) {
44
42
  if (tableBody.location.line === location.line) {
@@ -53,19 +51,15 @@ const createTestomatFormatter = (apiKey) => {
53
51
  };
54
52
 
55
53
  const loadDataTable = (scenario, uri) => {
56
- if (scenario.type === "ScenarioOutline") {
54
+ if (scenario.type === 'ScenarioOutline') {
57
55
  for (const example of scenario.examples) {
58
56
  for (const tableBody of example.tableBody) {
59
- const dataMap = example.tableHeader.cells.reduce(
60
- (acc, cell, index) => {
61
- acc[cell.value] = tableBody.cells[index].value;
62
- return acc;
63
- },
64
- {}
65
- );
66
-
67
- dataTableMap[`${uri}:${tableBody.location.line}`] =
68
- JSON.stringify(dataMap);
57
+ const dataMap = example.tableHeader.cells.reduce((acc, cell, index) => {
58
+ acc[cell.value] = tableBody.cells[index].value;
59
+ return acc;
60
+ }, {});
61
+
62
+ dataTableMap[`${uri}:${tableBody.location.line}`] = JSON.stringify(dataMap);
69
63
  }
70
64
  }
71
65
  }
@@ -77,10 +71,10 @@ const createTestomatFormatter = (apiKey) => {
77
71
  loadDataTable(scenario, sourceLocation.uri);
78
72
  }
79
73
 
80
- return dataTableMap[key] || "";
74
+ return dataTableMap[key] || '';
81
75
  };
82
76
 
83
- const getTestId = (scenario) => {
77
+ const getTestId = scenario => {
84
78
  if (scenario) {
85
79
  for (const tag of scenario.tags) {
86
80
  const testId = parseTest(tag.name);
@@ -100,41 +94,30 @@ const createTestomatFormatter = (apiKey) => {
100
94
  this.client = new TestomatClient({ apiKey });
101
95
  this.status = TRConstants.PASSED;
102
96
 
103
- options.eventBroadcaster.on("gherkin-document", addDocument);
104
- options.eventBroadcaster.on("test-run-started", () =>
105
- this.client.createRun());
106
- options.eventBroadcaster.on(
107
- "test-case-finished",
108
- this.onTestCaseFinished.bind(this)
109
- );
110
- options.eventBroadcaster.on("test-run-finished", () =>
111
- this.client.updateRunStatus(this.status));
97
+ options.eventBroadcaster.on('gherkin-document', addDocument);
98
+ options.eventBroadcaster.on('test-run-started', () => this.client.createRun());
99
+ options.eventBroadcaster.on('test-case-finished', this.onTestCaseFinished.bind(this));
100
+ options.eventBroadcaster.on('test-run-finished', () => this.client.updateRunStatus(this.status));
112
101
  }
113
102
 
114
103
  onTestCaseFinished(event) {
115
104
  const scenario = getScenario(event.sourceLocation);
116
105
  const testId = getTestId(scenario);
117
- const status =
118
- event.result.status === "undefined"
119
- ? TRConstants.SKIPPED
120
- : event.result.status;
106
+ const status = event.result.status === 'undefined' ? TRConstants.SKIPPED : event.result.status;
121
107
 
122
108
  let example = getDataTableMap(scenario, event.sourceLocation);
123
109
  if (example) example = JSON.parse(example);
124
110
 
125
111
  if (!scenario.name) return;
126
112
 
127
- let message = "";
128
- let cliMessage = `- ${scenario.name}: ${chalk.bold(
129
- status.toUpperCase()
130
- )}`;
113
+ let message = '';
114
+ let cliMessage = `- ${scenario.name}: ${chalk.bold(status.toUpperCase())}`;
131
115
 
132
- if (event.result.status === "undefined") {
116
+ if (event.result.status === 'undefined') {
133
117
  cliMessage += chalk.yellow(
134
- " (undefined steps. Run Cucumber without this formatter and implement missing steps)"
118
+ ' (undefined steps. Run Cucumber without this formatter and implement missing steps)',
135
119
  );
136
- message =
137
- "Undefined steps. Implement missing steps and rerun this scenario";
120
+ message = 'Undefined steps. Implement missing steps and rerun this scenario';
138
121
  }
139
122
  console.log(cliMessage);
140
123
  if (status !== TRConstants.PASSED && status !== TRConstants.SKIPPED) {
@@ -0,0 +1,42 @@
1
+ const TRConstants = require('../../constants');
2
+ const { parseTest } = require('../../util');
3
+ const TestomatClient = require('../../client');
4
+
5
+ const testomatioReporter = on => {
6
+ const client = new TestomatClient({ apiKey: process.env.TESTOMATIO });
7
+
8
+ on('before:run', async () => {
9
+ await client.createRun();
10
+ });
11
+
12
+ on('after:spec', async (_spec, results) => {
13
+ const addSpecTestsPromises = [];
14
+
15
+ for (const test of results.tests) {
16
+ const latestAttempt = test.attempts[test.attempts.length - 1];
17
+ console.log({ latestAttempt })
18
+ const time = latestAttempt.duration;
19
+ const error = latestAttempt.error;
20
+
21
+ const title = test.title[1]; // [0] - spec title, [1] - test title
22
+ const testId = parseTest(title);
23
+
24
+ const videos = [results.video];
25
+ const screenshots = results.screenshots.map(screenshot => screenshot.path);
26
+ const files = [...videos, ...screenshots];
27
+
28
+ const state = test.state === 'passed' ? TRConstants.PASSED : TRConstants.FAILED;
29
+
30
+ addSpecTestsPromises.push(client.addTestRun(testId, state, { title, time, error, files }));
31
+ }
32
+
33
+ await Promise.all(addSpecTestsPromises);
34
+ });
35
+
36
+ on('after:run', async results => {
37
+ const status = results.totalFailed ? TRConstants.FAILED : TRConstants.PASSED;
38
+ await client.updateRunStatus(status);
39
+ });
40
+ };
41
+
42
+ module.exports = testomatioReporter;
@@ -1,6 +1,6 @@
1
- const TestomatClient = require("../client");
2
- const { parseTest, ansiRegExp } = require("../util");
3
- const { PASSED } = require("../constants");
1
+ const TestomatClient = require('../client');
2
+ const { parseTest, ansiRegExp } = require('../util');
3
+ const { PASSED, FAILED } = require('../constants');
4
4
 
5
5
  class JasmineReporter {
6
6
  constructor(options) {
@@ -8,7 +8,7 @@ class JasmineReporter {
8
8
  const { apiKey } = options;
9
9
 
10
10
  if (!apiKey) {
11
- console.log("TESTOMATIO key is empty, ignoring reports");
11
+ console.log('TESTOMATIO key is empty, ignoring reports');
12
12
  return;
13
13
  }
14
14
 
@@ -33,7 +33,7 @@ class JasmineReporter {
33
33
 
34
34
  const title = result.description;
35
35
  const { status } = result;
36
- let errorMessage = "";
36
+ let errorMessage = '';
37
37
 
38
38
  for (let i = 0; i < result.failedExpectations.length; i += 1) {
39
39
  errorMessage = `${errorMessage}Failure: ${result.failedExpectations[i].message}\n`;
@@ -42,7 +42,7 @@ class JasmineReporter {
42
42
  console.log(`${title} : ${PASSED}`);
43
43
  console.log(errorMessage);
44
44
  const testId = parseTest(title);
45
- errorMessage = errorMessage.replace(ansiRegExp(), "");
45
+ errorMessage = errorMessage.replace(ansiRegExp(), '');
46
46
  this.client.addTestRun(testId, status, {
47
47
  error: result.failedExpectations[0],
48
48
  message: errorMessage,
@@ -50,6 +50,15 @@ class JasmineReporter {
50
50
  time: this.getDuration(result),
51
51
  });
52
52
  }
53
+
54
+ jasmineDone(suiteInfo, done) {
55
+ if (!this.client) return;
56
+
57
+ const { overallStatus } = suiteInfo;
58
+ const status = overallStatus === 'failed' ? FAILED : PASSED;
59
+
60
+ this.client.updateRunStatus(status).then(() => done);
61
+ }
53
62
  }
54
63
 
55
64
  module.exports = JasmineReporter;
@@ -1,6 +1,6 @@
1
- const TestomatClient = require("../client");
2
- const TRConstants = require("../constants");
3
- const { parseTest, ansiRegExp } = require("../util");
1
+ const TestomatClient = require('../client');
2
+ const TRConstants = require('../constants');
3
+ const { parseTest, ansiRegExp } = require('../util');
4
4
 
5
5
  class JestReporter {
6
6
  constructor(globalConfig, options) {
@@ -9,7 +9,7 @@ class JestReporter {
9
9
  const { apiKey } = options;
10
10
 
11
11
  if (!apiKey) {
12
- console.log("TESTOMATIO key is empty, ignoring reports");
12
+ console.log('TESTOMATIO key is empty, ignoring reports');
13
13
  return;
14
14
  }
15
15
 
@@ -26,19 +26,19 @@ class JestReporter {
26
26
  let steps = null;
27
27
  const { status, title, duration, failureMessages } = result;
28
28
  if (failureMessages[0]) {
29
- let errorMessage = failureMessages[0].replace(ansiRegExp(), "");
30
- errorMessage = errorMessage.split("\n")[0];
29
+ let errorMessage = failureMessages[0].replace(ansiRegExp(), '');
30
+ errorMessage = errorMessage.split('\n')[0];
31
31
  error = {
32
32
  message: errorMessage,
33
33
  };
34
34
  steps = failureMessages[0];
35
35
  }
36
36
  const testId = parseTest(title);
37
- const deducedStatus = status === "pending" ? "skipped" : status;
37
+ const deducedStatus = status === 'pending' ? 'skipped' : status;
38
38
 
39
39
  // In jest if test is not matched with test name pattern it is considered as skipped.
40
40
  // So adding a check if it is skipped for real or because of test pattern
41
- if (!this._globalConfig.testNamePattern || deducedStatus !== "skipped") {
41
+ if (!this._globalConfig.testNamePattern || deducedStatus !== 'skipped') {
42
42
  this.client.addTestRun(testId, deducedStatus, {
43
43
  error,
44
44
  steps,
@@ -53,8 +53,7 @@ class JestReporter {
53
53
  if (!this.client) return;
54
54
 
55
55
  const { numFailedTests } = results;
56
- const status =
57
- numFailedTests === 0 ? TRConstants.PASSED : TRConstants.FAILED;
56
+ const status = numFailedTests === 0 ? TRConstants.PASSED : TRConstants.FAILED;
58
57
  this.client.updateRunStatus(status);
59
58
  }
60
59
  }
@@ -1,27 +1,30 @@
1
- const mocha = require("mocha");
2
- const TestomatClient = require("../client");
3
- const TRConstants = require("../constants");
4
- const { parseTest } = require("../util");
1
+ const Mocha = require('mocha');
2
+ const TestomatClient = require('../client');
3
+ const TRConstants = require('../constants');
4
+ const { parseTest } = require('../util');
5
+
6
+ const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS } = Mocha.Runner.constants;
5
7
 
6
8
  function MochaReporter(runner, opts) {
7
- mocha.reporters.Base.call(this, runner);
9
+ Mocha.reporters.Base.call(this, runner);
8
10
  let passes = 0;
9
11
  let failures = 0;
10
12
 
11
13
  const { apiKey } = opts.reporterOptions;
14
+
12
15
  if (!apiKey) {
13
- console.log("TESTOMATIO key is empty, ignoring reports");
16
+ console.log('TESTOMATIO key is empty, ignoring reports');
14
17
  return;
15
18
  }
16
19
  const client = new TestomatClient({ apiKey });
17
20
 
18
- runner.on("start", () => {
21
+ runner.on(EVENT_RUN_BEGIN, () => {
19
22
  client.createRun();
20
23
  });
21
24
 
22
- runner.on("pass", (test) => {
25
+ runner.on(EVENT_TEST_PASS, test => {
23
26
  passes += 1;
24
- console.log("pass: %s", test.fullTitle());
27
+ console.log('pass: %s', test.fullTitle());
25
28
  const testId = parseTest(test.title);
26
29
  client.addTestRun(testId, TRConstants.PASSED, {
27
30
  title: test.title,
@@ -29,9 +32,9 @@ function MochaReporter(runner, opts) {
29
32
  });
30
33
  });
31
34
 
32
- runner.on("fail", (test, err) => {
35
+ runner.on(EVENT_TEST_FAIL, (test, err) => {
33
36
  failures += 1;
34
- console.log("fail: %s -- error: %s", test.fullTitle(), err.message);
37
+ console.log('fail: %s -- error: %s', test.fullTitle(), err.message);
35
38
  const testId = parseTest(test.title);
36
39
  client.addTestRun(testId, TRConstants.FAILED, {
37
40
  error: err,
@@ -40,14 +43,14 @@ function MochaReporter(runner, opts) {
40
43
  });
41
44
  });
42
45
 
43
- runner.on("end", () => {
44
- console.log("end: %d/%d", passes, passes + failures);
46
+ runner.on(EVENT_RUN_END, () => {
47
+ console.log('end: %d/%d', passes, passes + failures);
45
48
  const status = failures === 0 ? TRConstants.PASSED : TRConstants.FAILED;
46
49
  client.updateRunStatus(status);
47
50
  });
48
51
  }
49
52
 
50
53
  // To have this reporter "extend" a built-in reporter uncomment the following line:
51
- mocha.utils.inherits(MochaReporter, mocha.reporters.Spec);
54
+ Mocha.utils.inherits(MochaReporter, Mocha.reporters.Spec);
52
55
 
53
56
  module.exports = MochaReporter;