@testomatio/reporter 0.8.0-beta.9 → 0.8.2-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.
@@ -1,100 +1,114 @@
1
+ const debug = require('debug')('@testomatio/reporter:pipe:testomatio');
1
2
  const chalk = require('chalk');
2
3
  const axios = require('axios');
3
4
  const JsonCycle = require('json-cycle');
4
- const { TESTOMATIO_RUNGROUP_TITLE, TESTOMATIO_RUN } = process.env;
5
- const { APP_PREFIX } = require('../constants');
5
+ const { APP_PREFIX, STATUS } = require('../constants');
6
6
  const { isValidUrl } = require('../util');
7
7
 
8
+ const { TESTOMATIO_RUN } = process.env;
8
9
  if (TESTOMATIO_RUN) {
9
10
  process.env.runId = TESTOMATIO_RUN;
10
11
  }
11
12
 
13
+ /**
14
+ * @typedef {import('../../types').Pipe} Pipe
15
+ * @typedef {import('../../types').TestData} TestData
16
+ * @class TestomatioPipe
17
+ * @implements {Pipe}
18
+ */
12
19
  class TestomatioPipe {
13
- isEnabled = false;
14
-
15
- constructor(params, store = {}) {
20
+ constructor(params, store) {
21
+ this.isEnabled = false;
16
22
  this.url = params.testomatioUrl || process.env.TESTOMATIO_URL || 'https://app.testomat.io';
17
23
  this.apiKey = params.apiKey || process.env.TESTOMATIO;
18
- if (process.env.DEBUG) {
19
- console.log(APP_PREFIX, 'Testomatio Pipe: ', this.apiKey ? 'API KEY' : '*no api key*');
20
- }
24
+ debug('Testomatio Pipe: ', this.apiKey ? 'API KEY' : '*no api key*');
21
25
  if (!this.apiKey) {
22
26
  return;
23
27
  }
24
- if (process.env.DEBUG) {
25
- console.log(APP_PREFIX, 'Testomatio Pipe: Enabled');
26
- }
27
- this.store = store;
28
+ debug('Testomatio Pipe: Enabled');
29
+ this.store = store || {};
28
30
  this.title = params.title || process.env.TESTOMATIO_TITLE;
31
+ this.groupTitle = params.groupTitle || process.env.TESTOMATIO_RUNGROUP_TITLE;
32
+ this.env = process.env.TESTOMATIO_ENV;
29
33
  this.axios = axios.create();
30
34
  this.isEnabled = true;
35
+ // do not finish this run (for parallel testing)
31
36
  this.proceed = process.env.TESTOMATIO_PROCEED;
32
37
  this.runId = params.runId || process.env.runId;
33
38
  this.createNewTests = !!process.env.TESTOMATIO_CREATE;
34
39
 
35
40
  if (!isValidUrl(this.url.trim())) {
36
41
  this.isEnabled = false;
37
- console.log(
38
- APP_PREFIX,
39
- chalk.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`),
40
- );
41
- return;
42
+ console.error(APP_PREFIX, chalk.red(`Error creating report on Testomat.io, report url '${this.url}' is invalid`));
42
43
  }
43
44
  }
44
45
 
45
- async createRun(runParams) {
46
+ /**
47
+ * @returns Promise<void>
48
+ */
49
+ async createRun() {
46
50
  if (!this.isEnabled) return;
47
51
 
48
- runParams.api_key = this.apiKey.trim();
49
- runParams.group_title = TESTOMATIO_RUNGROUP_TITLE;
50
-
52
+ const runParams = Object.fromEntries(
53
+ Object.entries({
54
+ api_key: this.apiKey.trim(),
55
+ group_title: this.groupTitle,
56
+ env: this.env,
57
+ title: this.title,
58
+ }).filter(([, value]) => !!value)
59
+ );
60
+
51
61
  if (this.runId) {
52
- return this.axios.put(`${this.url.trim()}/api/reporter/${this.runId}`, runParams)
62
+ return this.axios.put(`${this.url.trim()}/api/reporter/${this.runId}`, runParams);
53
63
  }
54
-
64
+
55
65
  try {
56
66
  const resp = await this.axios.post(`${this.url.trim()}/api/reporter`, runParams, {
57
67
  maxContentLength: Infinity,
58
68
  maxBodyLength: Infinity,
59
- })
69
+ });
60
70
  this.runId = resp.data.uid;
61
71
  this.runUrl = `${this.url}/${resp.data.url.split('/').splice(3).join('/')}`;
62
72
  this.store.runUrl = this.runUrl;
63
- this.store.runId = this.runId;
73
+ this.store.runId = this.runId;
64
74
  console.log(APP_PREFIX, '📊 Report created. Report ID:', this.runId);
65
75
  process.env.runId = this.runId;
66
76
  } catch (err) {
67
- console.log(
77
+ console.error(
68
78
  APP_PREFIX,
69
79
  'Error creating Testomat.io report, please check if your API key is valid. Skipping report',
70
80
  );
71
81
  }
72
82
  }
73
83
 
74
- async addTest(data) {
84
+ /**
85
+ *
86
+ * @param testData data
87
+ * @returns
88
+ */
89
+ addTest(data) {
75
90
  if (!this.isEnabled) return;
76
91
  if (!this.runId) return;
77
92
  data.api_key = this.apiKey;
78
93
  data.create = this.createNewTests;
79
94
  const json = JsonCycle.stringify(data);
80
95
 
81
- try {
82
- return await this.axios.post(`${this.url}/api/reporter/${this.runId}/testrun`, json, {
83
- maxContentLength: Infinity,
84
- maxBodyLength: Infinity,
85
- headers: {
86
- // Overwrite Axios's automatically set Content-Type
87
- 'Content-Type': 'application/json',
88
- },
89
- });
90
- } catch (err) {
96
+ return this.axios.post(`${this.url}/api/reporter/${this.runId}/testrun`, json, {
97
+ maxContentLength: Infinity,
98
+ maxBodyLength: Infinity,
99
+ headers: {
100
+ // Overwrite Axios's automatically set Content-Type
101
+ 'Content-Type': 'application/json',
102
+ },
103
+ })
104
+ .catch((err) => {
91
105
  if (err.response) {
92
106
  if (err.response.status >= 400) {
93
- const data = err.response.data || { message: '' };
107
+ const responseData = err.response.data || { message: '' };
94
108
  console.log(
95
109
  APP_PREFIX,
96
110
  chalk.blue(this.title),
97
- `Report couldn't be processed: (${err.response.status}) ${data.message}`,
111
+ `Report couldn't be processed: (${err.response.status}) ${responseData.message}`,
98
112
  );
99
113
  return;
100
114
  }
@@ -102,18 +116,31 @@ class TestomatioPipe {
102
116
  } else {
103
117
  console.log(APP_PREFIX, chalk.blue(this.title), "Report couldn't be processed", err);
104
118
  }
105
- }
106
-
119
+ });
107
120
  }
108
121
 
122
+ /**
123
+ * @param {import('../../types').RunData} params
124
+ * @returns
125
+ */
109
126
  async finishRun(params) {
110
127
  if (!this.isEnabled) return;
128
+
129
+ const { status, parallel } = params;
130
+
131
+ let status_event;
132
+
133
+ if (status === STATUS.FINISHED) status_event = 'finish';
134
+ if (status === STATUS.PASSED) status_event = 'pass';
135
+ if (status === STATUS.FAILED) status_event = 'fail';
136
+ if (parallel) status_event += '_parallel';
137
+
111
138
  try {
112
139
  if (this.runId && !this.proceed) {
113
140
  await this.axios.put(`${this.url}/api/reporter/${this.runId}`, {
114
141
  api_key: this.apiKey,
115
- status_event: params.statusEvent,
116
- status: params.status,
142
+ status_event,
143
+ tests: params.tests,
117
144
  });
118
145
  if (this.runUrl) {
119
146
  console.log(APP_PREFIX, '📊 Report Saved. Report URL:', chalk.magenta(this.runUrl));
@@ -134,4 +161,4 @@ class TestomatioPipe {
134
161
  }
135
162
  }
136
163
 
137
- module.exports = TestomatioPipe;
164
+ module.exports = TestomatioPipe;
package/lib/reporter.js CHANGED
@@ -1,7 +1,9 @@
1
1
  const TestomatClient = require('./client');
2
2
  const TRConstants = require('./constants');
3
+ const TRArtifacts = require('./ArtifactStorage');
3
4
 
4
5
  module.exports = {
5
6
  TestomatClient,
6
7
  TRConstants,
8
+ TRArtifacts
7
9
  };
package/lib/util.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const { URL } = require('url');
2
- const { sep } = require('path');
2
+ const { sep, basename } = require('path');
3
3
  const chalk = require('chalk');
4
4
  const fs = require('fs');
5
5
  const isValid = require('is-valid-path');
@@ -7,7 +7,7 @@ const isValid = require('is-valid-path');
7
7
  /**
8
8
  * @param {String} testTitle - Test title
9
9
  *
10
- * @returns {String} testId
10
+ * @returns {String|null} testId
11
11
  */
12
12
  const parseTest = testTitle => {
13
13
  const captures = testTitle.match(/@T([\w\d]+)/);
@@ -21,7 +21,7 @@ const parseTest = testTitle => {
21
21
  /**
22
22
  * @param {String} suiteTitle - suite title
23
23
  *
24
- * @returns {String} suiteId
24
+ * @returns {String|null} suiteId
25
25
  */
26
26
  const parseSuite = suiteTitle => {
27
27
  const captures = suiteTitle.match(/@S([\w\d]+)/);
@@ -63,12 +63,12 @@ const fetchSourceCodeFromStackTrace = (stack = '') => {
63
63
  // .map(l => l.match(/\[(.*?)\]/)?.[1] || l) // minitest format
64
64
  // .map(l => l.split(':')[0])
65
65
  .map(l => l.trim())
66
- .map(l => l.split(' ').find(p => p.includes(':')))
67
- .filter(l => isValid(l.split(':')[0]))
66
+ .map(l => l.split(' ').find(p => p.includes(':')) || '')
67
+ .filter(l => isValid(l?.split(':')[0]))
68
68
 
69
69
  // // filter out 3rd party libs
70
- .filter(l => !l.includes(`vendor${ sep}`))
71
- .filter(l => !l.includes(`node_modules${ sep}`))
70
+ .filter(l => !l?.includes(`vendor${ sep}`))
71
+ .filter(l => !l?.includes(`node_modules${ sep}`))
72
72
  .filter(l => fs.existsSync(l.split(':')[0]))
73
73
  .filter(l => fs.lstatSync(l.split(':')[0]).isFile())
74
74
 
@@ -79,6 +79,8 @@ const fetchSourceCodeFromStackTrace = (stack = '') => {
79
79
  const prepend = 3;
80
80
  const source = fetchSourceCode(fs.readFileSync(file).toString(), { line, prepend, limit: 7 })
81
81
 
82
+ if (!source) return '';
83
+
82
84
  return source.split('\n')
83
85
  .map((l, i) => {
84
86
  if (i === prepend) return `${line} > ${chalk.bold(l)}`;
@@ -137,15 +139,46 @@ const fetchSourceCode = (contents, opts = {}) => {
137
139
  }
138
140
  }
139
141
 
140
- const isSameTest = (test, t) => t.title == test.title && t.suite_title == test.suite_title && Object.values(t.example) == Object.values(test.example) && t.test_id == test.test_id
142
+ const isSameTest = (test, t) => (typeof t === 'object')
143
+ && (typeof test === 'object')
144
+ && t.title === test.title
145
+ && t.suite_title === test.suite_title
146
+ && Object.values(t.example || {}) === Object.values(test.example || {})
147
+ && t.test_id === test.test_id;
148
+
149
+ const getCurrentDateTime = () => {
150
+ const today = new Date();
151
+
152
+ return `${today.getFullYear() }_${ today.getMonth() + 1 }_${ today.getDate() }_${
153
+ today.getHours() }_${ today.getMinutes() }_${ today.getSeconds()}`;
154
+ }
155
+
156
+ /**
157
+ * @param {Object} test - Test adapter object
158
+ *
159
+ * @returns {String|null} testInfo as one string
160
+ */
161
+ const specificTestInfo = test => {
162
+ // TODO: afterEach has another context.... need to add specific handler, maybe...
163
+ if (test?.title && test?.file) {
164
+
165
+ return `${basename(test.file).split(".").join("#")
166
+ }#${
167
+ test.title.split(" ").join("#")}`;
168
+ }
169
+
170
+ return null;
171
+ };
141
172
 
142
173
  module.exports = {
143
- parseTest,
144
- parseSuite,
145
- ansiRegExp,
146
174
  isSameTest,
147
- isValidUrl,
148
175
  fetchSourceCode,
149
176
  fetchSourceCodeFromStackTrace,
150
177
  fetchFilesFromStackTrace,
151
- };
178
+ getCurrentDateTime,
179
+ specificTestInfo,
180
+ isValidUrl,
181
+ ansiRegExp,
182
+ parseTest,
183
+ parseSuite
184
+ }
package/lib/xmlReader.js CHANGED
@@ -1,15 +1,15 @@
1
+ const debug = require('debug')('@testomatio/reporter:xml');
1
2
  const path = require("path");
2
3
  const chalk = require('chalk');
3
4
  const fs = require("fs");
4
-
5
- // const util = require("util"); // you can see a result
6
5
  const { XMLParser } = require("fast-xml-parser");
7
- const { APP_PREFIX, PASSED, FAILED, SKIPPED } = require('./constants');
6
+ const { APP_PREFIX, STATUS } = require('./constants');
8
7
  const { fetchFilesFromStackTrace, fetchSourceCode, fetchSourceCodeFromStackTrace } = require('./util');
9
8
  const upload = require('./fileUploader');
10
9
  const pipesFactory = require('./pipe');
11
10
  const adapterFactory = require('./junit-adapter');
12
11
 
12
+
13
13
  const TESTOMATIO_URL = process.env.TESTOMATIO_URL || "https://app.testomat.io";
14
14
  const TESTOMATIO = process.env.TESTOMATIO; // key?
15
15
  const { TESTOMATIO_RUNGROUP_TITLE, TESTOMATIO_TITLE, TESTOMATIO_ENV, TESTOMATIO_RUN } = process.env;
@@ -36,7 +36,9 @@ class XmlReader {
36
36
  };
37
37
  this.runId = opts.runId || TESTOMATIO_RUN;
38
38
  this.adapter = adapterFactory(null, opts)
39
- this.opts = opts;
39
+ if (!this.adapter) throw new Error('XML adapter for this format not found');
40
+
41
+ this.opts = opts || {};
40
42
  const store = {}
41
43
  this.pipes = pipesFactory(opts, store);
42
44
 
@@ -92,7 +94,7 @@ class XmlReader {
92
94
  create_tests: true,
93
95
  name,
94
96
  tests_count: parseInt(tests, 10),
95
- passed_count: parseInt(tests - failures, 10),
97
+ passed_count: parseInt(tests, 10) - parseInt(failures, 10),
96
98
  failed_count: parseInt(failures, 10),
97
99
  skipped_count: 0,
98
100
  tests: resultTests,
@@ -119,49 +121,62 @@ class XmlReader {
119
121
  }
120
122
 
121
123
  processTRX(jsonSuite) {
122
- const tests = jsonSuite?.TestRun?.TestDefinitions?.UnitTest?.map(td => {
124
+ let defs = jsonSuite?.TestRun?.TestDefinitions?.UnitTest;
125
+ if (!Array.isArray(defs)) defs = [defs].filter(d => !!d);
126
+
127
+ const tests = defs.map(td => {
123
128
  const title = td.name.replace(/\(.*?\)/, '').trim();
124
129
  let example = td.name.match(/\((.*?)\)/);
125
130
  if (example) example = { ...example[1].split(',')};
126
- const suite = td.TestMethod.className.split('.');
131
+ const suite = td.TestMethod.className.split(', ')[0].split('.');
127
132
  const suite_title = suite.pop();
128
133
  return {
129
134
  title,
130
135
  example,
131
136
  file: suite.join('/'),
137
+ description: td.Description,
132
138
  suite_title,
133
139
  id: td.Execution.id,
134
140
  }
135
141
  }) || [];
136
142
 
137
- const results = jsonSuite?.TestRun?.Results?.UnitTestResult?.map(td => ({
143
+ let result = jsonSuite?.TestRun?.Results?.UnitTestResult;
144
+ if (!Array.isArray(result)) result = [result].filter(d => !!d);
145
+
146
+ const results = result.map(td => ({
138
147
  id: td.executionId,
139
148
  run_time: parseFloat(td.duration),
140
149
  status: td.outcome,
141
- stack: td.Output.StdOut
150
+ stack: td.Output.StdOut,
151
+ files: td?.ResultFiles?.ResultFile?.map(rf => rf.path)
142
152
  }));
143
153
 
154
+
144
155
  results.forEach(r => {
145
- const test = tests.find(t => t.id === r.id) || {};
156
+ const test = tests.find(t => t.id === r.id) || { };
146
157
  r.suite_title = test.suite_title;
147
158
  r.title = test.title?.trim();
159
+ if (test.code) r.code = test.code;
160
+ if (test.description) r.description = test.description;
148
161
  if (test.example) r.example = test.example;
149
162
  if (test.file) r.file = test.file;
150
163
  r.create = true;
151
- if (r.status === 'Passed') r.status = PASSED;
152
- if (r.status === 'Failed') r.status = FAILED;
153
- if (r.status === 'Skipped') r.status = SKIPPED;
164
+ if (r.status === 'Passed') r.status = STATUS.PASSED;
165
+ if (r.status === 'Failed') r.status = STATUS.FAILED;
166
+ if (r.status === 'Skipped') r.status = STATUS.SKIPPED;
154
167
  delete r.id;
155
168
  });
169
+
170
+ debug(results);
156
171
 
157
172
  const counters = jsonSuite?.TestRun?.ResultSummary?.Counters || {};
158
173
 
159
174
  const failed_count = parseInt(counters.failed, 10) + parseInt(counters.error, 10);
160
175
 
161
- let status = PASSED;
162
- if (failed_count > 0) status = FAILED;
176
+ let status = STATUS.PASSED.toString();
177
+ if (failed_count > 0) status = STATUS.FAILED;
163
178
 
164
- this.tests = results;
179
+ this.tests = results.filter(t => !!t.title);
165
180
 
166
181
  return {
167
182
  status,
@@ -212,9 +227,7 @@ class XmlReader {
212
227
  const contents = fs.readFileSync(file).toString();
213
228
  t.code = fetchSourceCode(contents, { ...t, lang: this.stats.language })
214
229
  } catch (err) {
215
- if (process.env.DEBUG) {
216
- console.log(err)
217
- }
230
+ debug(err)
218
231
  }
219
232
  });
220
233
  }
@@ -264,7 +277,10 @@ class XmlReader {
264
277
 
265
278
  async uploadArtifacts() {
266
279
  for (const test of this.tests.filter(t => !!t.stack)) {
267
- const files = fetchFilesFromStackTrace(test.stack);
280
+ let files = [];
281
+ if (test.files.length) files = test.files.map(f => path.join(process.cwd(), f))
282
+ files = [...files, ...fetchFilesFromStackTrace(test.stack)];
283
+ debug('Uploading files', files)
268
284
  test.artifacts = await Promise.all(files.map(f => upload.uploadFileByPath(f, this.runId)));
269
285
  }
270
286
  }
@@ -277,7 +293,7 @@ class XmlReader {
277
293
  group_title: this.requestParams.group_title,
278
294
  };
279
295
 
280
- if (process.env.DEBUG) console.log("Run", runParams);
296
+ debug("Run", runParams);
281
297
 
282
298
  return Promise.all(this.pipes.map(p => p.createRun(runParams)));
283
299
  }
@@ -290,17 +306,17 @@ class XmlReader {
290
306
  this.formatErrors();
291
307
  this.formatTests();
292
308
 
293
- if (process.env.DEBUG) {
294
- console.log({
295
- ...this.stats,
296
- tests: this.tests,
297
- })
298
- }
309
+ debug(
310
+ 'Uploading data',
311
+ {
312
+ ...this.stats,
313
+ tests: this.tests,
314
+ })
299
315
 
300
316
  const dataString = {
301
317
  ...this.stats,
302
318
  api_key: this.requestParams.apiKey,
303
- status_event: 'finish',
319
+ status: 'finished',
304
320
  tests: this.tests,
305
321
  };
306
322
 
@@ -335,9 +351,9 @@ function reduceTestCases(prev, item) {
335
351
  // prepend system output
336
352
  stack = `${testCaseItem['system-out'] || testCaseItem.output || testCaseItem.log || ''}\n\n${stack}`.trim()
337
353
 
338
- let status = PASSED;
339
- if ('failure' in testCaseItem || 'error' in testCaseItem) status = FAILED;
340
- if ('skipped' in testCaseItem) status = SKIPPED;
354
+ let status = STATUS.PASSED.toString();
355
+ if ('failure' in testCaseItem || 'error' in testCaseItem) status = STATUS.FAILED;
356
+ if ('skipped' in testCaseItem) status = STATUS.SKIPPED;
341
357
 
342
358
  prev.push({
343
359
  create: true,
package/package.json CHANGED
@@ -1,26 +1,33 @@
1
1
  {
2
2
  "name": "@testomatio/reporter",
3
- "version": "0.8.0-beta.9",
3
+ "version": "0.8.2-beta.1",
4
4
  "description": "Testomatio Reporter Client",
5
5
  "main": "./lib/reporter.js",
6
+ "typings": "typings/index.d.ts",
6
7
  "repository": "git@github.com:testomatio/reporter.git",
7
8
  "author": "Michael Bodnarchuk <davert@testomat.io>,Koushik Mohan <koushikmohan1996@gmail.com>",
8
9
  "license": "MIT",
9
10
  "dependencies": {
11
+ "@aws-sdk/client-s3": "^3.279.0",
12
+ "@aws-sdk/lib-storage": "^3.279.0",
10
13
  "@octokit/rest": "^19.0.5",
11
14
  "aws-sdk": "^2.1072.0",
12
15
  "axios": "^0.25.0",
13
16
  "callsite-record": "^4.1.4",
14
17
  "chalk": "^4.1.0",
15
18
  "commander": "^4.1.1",
19
+ "csv-writer": "^1.6.0",
20
+ "debug": "^4.3.4",
16
21
  "dotenv": "^16.0.1",
17
22
  "fast-xml-parser": "^4.0.8",
18
23
  "glob": "^8.0.3",
19
24
  "has-flag": "^5.0.1",
25
+ "humanize-duration": "^3.27.3",
20
26
  "is-valid-path": "^0.1.1",
21
27
  "json-cycle": "^1.3.0",
22
28
  "lodash.memoize": "^4.1.2",
23
- "lodash.merge": "^4.6.2"
29
+ "lodash.merge": "^4.6.2",
30
+ "uuid": "^9.0.0"
24
31
  },
25
32
  "files": [
26
33
  "bin",
@@ -28,6 +35,7 @@
28
35
  "testcafe"
29
36
  ],
30
37
  "scripts": {
38
+ "clear-exportdir": "rm -rf export/",
31
39
  "pretty": "prettier --write .",
32
40
  "lint": "eslint lib",
33
41
  "lint:fix": "eslint lib --fix",
@@ -35,15 +43,16 @@
35
43
  "init": "cd ./tests/adapter/examples/cucumber && npm i",
36
44
  "test:unit": "mocha tests",
37
45
  "test:adapter": "mocha './tests/adapter/index.test.js'",
46
+ "test:pipes": "mocha './tests/pipes/*_test.js'",
38
47
  "test:adapter:jest:example": "jest './tests/adapter/examples/jest/index.test.js' --config='./tests/adapter/examples/jest/jest.config.js'",
39
48
  "test:adapter:mocha:example": "mocha './tests/adapter/examples/mocha/index.test.js' --config='./tests/adapter/examples/mocha/mocha.config.js'",
40
49
  "test:adapter:jasmine:example": "./tests/adapter/examples/jasmine/passReporterOpts.sh && jasmine './tests/adapter/examples/jasmine/index.test.js' --reporter=./../../../lib/adapter/jasmine.js",
41
50
  "test:adapter:codecept:example": "codeceptjs run --config='./tests/adapter/examples/codecept/codecept.conf.js'",
42
51
  "test:adapter:cucumber:example": "cd ./tests/adapter/examples/cucumber && npx cucumber-js"
43
52
  },
44
- "peerDependencies": {},
45
53
  "devDependencies": {
46
54
  "@cucumber/cucumber": "^8.6.0",
55
+ "@redocly/cli": "^1.0.0-beta.125",
47
56
  "@wdio/reporter": "^7.16.13",
48
57
  "chai": "^4.3.6",
49
58
  "codeceptjs": "^3.2.3",
package/testcafe/index.js DELETED
@@ -1,61 +0,0 @@
1
- const TestomatClient = require('@testomatio/reporter/lib/client');
2
- const TRConstants = require('@testomatio/reporter/lib/constants');
3
- const util = require('@testomatio/reporter/lib/util');
4
-
5
- module.exports = () => {
6
- const apiKey = process.env.TESTOMATIO;
7
- let failed = false;
8
-
9
- if (apiKey === '' || apiKey === undefined) {
10
- throw new Error('Testomat.io API key cannot be empty');
11
- }
12
- const client = new TestomatClient({ apiKey });
13
-
14
- return {
15
- reportTaskStart(startTime, userAgents) {
16
- console.log('TestCafe started with: ', userAgents);
17
- client.createRun();
18
- },
19
-
20
- reportFixtureStart(name) {
21
- console.log(`Suite : ${name}`);
22
- },
23
-
24
- reportTestDone(name, testRunInfo) {
25
- let status = TRConstants.PASSED;
26
- let message = '';
27
-
28
- if (testRunInfo.skipped) {
29
- status = TRConstants.SKIPPED;
30
- }
31
- if (testRunInfo.errs.length) {
32
- status = TRConstants.FAILED;
33
- message = this.renderErrors(testRunInfo.errs);
34
- failed = true;
35
- }
36
- console.log(` - ${name} : ${status}`);
37
- client.addTestRun(util.parseTest(name), status, {
38
- error: testRunInfo.errs.length ? testRunInfo.errs[0] : null,
39
- message,
40
- title: name,
41
- time: testRunInfo.durationMs,
42
- });
43
- },
44
-
45
- renderErrors(errors) {
46
- let errorMessage = '';
47
- errors.forEach((error, id) => {
48
- errorMessage = `${errorMessage}${this.formatError(error, `${id + 1} `)}\n`;
49
- });
50
-
51
- console.log(errorMessage);
52
- return errorMessage.replace(util.ansiRegExp(), '');
53
- },
54
-
55
- reportTaskDone() {
56
- const status = failed ? TRConstants.FAILED : TRConstants.PASSED;
57
- console.log(`Status : ${status}`);
58
- client.updateRunStatus(status);
59
- },
60
- };
61
- };
@@ -1,14 +0,0 @@
1
- {
2
- "name": "testcafe-reporter-testomatio",
3
- "version": "0.1.1",
4
- "description": "",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "author": "koushikmohan1996@gmail.com",
10
- "license": "ISC",
11
- "dependencies": {
12
- "@testomatio/reporter": "^0.6.10"
13
- }
14
- }