@testomatio/reporter 1.1.0-beta → 1.1.0-beta-2

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,58 +1,40 @@
1
1
  // eslint-disable-next-line global-require, import/no-extraneous-dependencies
2
2
  const Mocha = require('mocha');
3
- const debug = require('debug')('@testomatio/reporter:adapter:mocha');
4
3
  const chalk = require('chalk');
5
4
  const TestomatClient = require('../client');
6
- const { STATUS } = require('../constants');
7
- const { parseTest, specificTestInfo } = require('../util');
8
- const ArtifactStorage = require('../_ArtifactStorageOld');
5
+ const { STATUS, TESTOMAT_TMP_STORAGE_DIR } = require('../constants');
6
+ const { parseTest, fileSystem } = require('../utils/utils');
9
7
 
10
- const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS, EVENT_TEST_PENDING } = Mocha.Runner.constants;
8
+ const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS, EVENT_TEST_PENDING } =
9
+ Mocha.Runner.constants;
11
10
 
12
11
  function MochaReporter(runner, opts) {
13
12
  Mocha.reporters.Base.call(this, runner);
14
- let passes = 0; let failures = 0; let skipped = 0;
15
- let artifactStore;
13
+ let passes = 0;
14
+ let failures = 0;
15
+ let skipped = 0;
16
+ // let artifactStore;
16
17
 
17
18
  const apiKey = opts?.reporterOptions?.apiKey || process.env.TESTOMATIO;
18
19
 
19
- if (!apiKey) {
20
- debug('TESTOMATIO key is empty, ignoring reports');
21
- return;
22
- }
23
20
  const client = new TestomatClient({ apiKey });
24
21
 
25
22
  runner.on(EVENT_RUN_BEGIN, () => {
26
23
  client.createRun();
27
24
 
28
- const params = {
29
- toFile: true
30
- };
31
-
32
- artifactStore = runner._workerReporter !== undefined
33
- ? new ArtifactStorage(params)
34
- : new ArtifactStorage();
25
+ fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
35
26
  });
36
27
 
37
- runner.on(EVENT_TEST_PASS, async(test) => {
28
+ runner.on(EVENT_TEST_PASS, async test => {
38
29
  passes += 1;
39
30
  console.log(chalk.bold.green('✔'), test.fullTitle());
40
31
  const testId = parseTest(test.title);
41
32
 
42
- const specificTest = specificTestInfo(test);
43
- const content = await artifactStore.artifactByTestName(specificTest);
44
-
45
- debug(`test=${specificTest} content = `, content);
46
-
47
- client.addTestRun(
48
- STATUS.PASSED,
49
- {
50
- test_id: testId,
51
- title: test.title,
52
- time: test.duration,
53
- },
54
- content
55
- );
33
+ client.addTestRun(STATUS.PASSED, {
34
+ test_id: testId,
35
+ title: test.title,
36
+ time: test.duration,
37
+ });
56
38
  });
57
39
 
58
40
  runner.on(EVENT_TEST_PENDING, test => {
@@ -66,33 +48,23 @@ function MochaReporter(runner, opts) {
66
48
  });
67
49
  });
68
50
 
69
- runner.on(EVENT_TEST_FAIL, async(test, err) => {
51
+ runner.on(EVENT_TEST_FAIL, async (test, err) => {
70
52
  failures += 1;
71
53
  console.log(chalk.bold.red('✖'), test.fullTitle(), chalk.gray(err.message));
72
54
  const testId = parseTest(test.title);
73
55
 
74
- const specificTest = specificTestInfo(test);
75
- const content = await artifactStore.artifactByTestName(specificTest);
76
-
77
- debug(`fail test=${specificTest} content = `, content);
78
-
79
- client.addTestRun(
80
- STATUS.FAILED, {
81
- error: err,
82
- test_id: testId,
83
- title: test.title,
84
- time: test.duration,
85
- },
86
- content
87
- );
56
+ client.addTestRun(STATUS.FAILED, {
57
+ error: err,
58
+ test_id: testId,
59
+ title: test.title,
60
+ time: test.duration,
61
+ });
88
62
  });
89
63
 
90
64
  runner.on(EVENT_RUN_END, () => {
91
65
  const status = failures === 0 ? STATUS.PASSED : STATUS.FAILED;
92
66
  console.log(chalk.bold(status), `${passes} passed, ${failures} failed, ${skipped} skipped`);
93
67
  client.updateRunStatus(status);
94
-
95
- artifactStore.cleanup();
96
68
  });
97
69
  }
98
70
 
@@ -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_DIR } = require('../constants');
7
7
  const TestomatioClient = require('../client');
8
8
  const { isArtifactsEnabled } = require('../fileUploader');
9
- const { parseTest } = require('../util');
9
+ const { parseTest, fileSystem } = require('../utils/utils');
10
10
 
11
11
  const reportTestPromises = [];
12
12
 
13
- class TestomatioReporter {
13
+ class PlaywrightReporter {
14
14
  constructor(config = {}) {
15
15
  this.client = new TestomatioClient({ apiKey: config?.apiKey });
16
16
 
@@ -18,11 +18,19 @@ class TestomatioReporter {
18
18
  }
19
19
 
20
20
  onBegin(_config, suite) {
21
+ // clean data storage
22
+ fileSystem.clearDir(TESTOMAT_TMP_STORAGE_DIR);
21
23
  if (!this.client) return;
22
24
  this.suite = suite;
23
25
  this.client.createRun();
24
26
  }
25
27
 
28
+ /*
29
+ onTestBegin(test) {
30
+ // does not work; value is not to the storage context
31
+ global.testTitle = test.title;
32
+ } */
33
+
26
34
  onTestEnd(test, result) {
27
35
  if (!this.client) return;
28
36
 
@@ -37,21 +45,34 @@ class TestomatioReporter {
37
45
  for (const step of result.steps) {
38
46
  appendStep(step, steps);
39
47
  }
40
-
41
- const reportTestPromise = this.client.addTestRun(checkStatus(result.status), {
42
- error,
43
- test_id: testId,
44
- suite_title,
45
- title,
46
- steps: steps.join('\n'),
47
- time: duration,
48
- }).then(pipes => {
49
- testId = pipes.filter(p => p.pipe.includes('Testomatio'))[0]?.result?.data?.test_id;
50
-
51
- this.uploads.push({
52
- testId, title, suite_title, files: result.attachments.filter((a) => a.body || a.path)
48
+
49
+ let logs = '';
50
+ if (result.stderr.length || result.stdout.length) {
51
+ logs = `\n\n${chalk.bold('Logs:')}\n${chalk.red(result.stderr.join(''))}\n${result.stdout.join('')}`;
52
+ }
53
+
54
+ const reportTestPromise = this.client
55
+ .addTestRun(checkStatus(result.status), {
56
+ error,
57
+ test_id: testId,
58
+ suite_title,
59
+ title,
60
+ steps: steps.join('\n'),
61
+ time: duration,
62
+ stack: logs,
53
63
  })
54
- });;
64
+ .then(pipes => {
65
+ testId = pipes?.filter(p => p.pipe.includes('Testomatio'))[0]?.result?.data?.test_id;
66
+
67
+ this.uploads.push({
68
+ testId,
69
+ title,
70
+ suite_title,
71
+ files: result.attachments.filter(a => a.body || a.path),
72
+ });
73
+ // remove empty uploads
74
+ this.uploads = this.uploads.filter(upload => upload.files.length);
75
+ });
55
76
 
56
77
  reportTestPromises.push(reportTestPromise);
57
78
  }
@@ -67,10 +88,9 @@ class TestomatioReporter {
67
88
  const promises = [];
68
89
 
69
90
  for (const upload of this.uploads) {
70
-
71
91
  const { title, testId, suite_title } = upload;
72
92
 
73
- const files = upload.files.map((attachment) => {
93
+ const files = upload.files.map(attachment => {
74
94
  if (attachment.body) {
75
95
  const fileName = tmpFile();
76
96
  fs.writeFileSync(fileName, attachment.body);
@@ -78,7 +98,6 @@ class TestomatioReporter {
78
98
  return { path: attachment.path, title, type: attachment.contentType };
79
99
  });
80
100
 
81
-
82
101
  promises.push(
83
102
  this.client.addTestRun(undefined, {
84
103
  test_id: testId,
@@ -124,4 +143,4 @@ function tmpFile(prefix = 'tmp.') {
124
143
  return path.join(tmpdir, prefix + crypto.randomBytes(16).toString('hex'));
125
144
  }
126
145
 
127
- module.exports = TestomatioReporter;
146
+ module.exports = PlaywrightReporter;
@@ -1,7 +1,7 @@
1
1
  // eslint-disable-next-line global-require, import/no-extraneous-dependencies
2
2
  const WDIOReporter = require('@wdio/reporter').default;
3
3
  const TestomatClient = require('../client');
4
- const { parseTest } = require('../util');
4
+ const { parseTest } = require('../utils/utils');
5
5
 
6
6
  class WebdriverReporter extends WDIOReporter {
7
7
  constructor(options) {
@@ -23,6 +23,7 @@ program
23
23
  }
24
24
  let { javaTests, lang } = opts;
25
25
  if (opts.envFile) {
26
+ console.log(APP_PREFIX, 'Loading env file:', opts.envFile);
26
27
  debug('Loading env file: %s', opts.envFile)
27
28
  require('dotenv').config({ path: opts.envFile }); // eslint-disable-line
28
29
  }
@@ -13,9 +13,11 @@ program
13
13
  .option('--launch', 'Start a new run and return its ID')
14
14
  .option('--finish', 'Finish Run by its ID')
15
15
  .option("--env-file <envfile>", "Load environment variables from env file")
16
- .action(opts => {
16
+ .option("--filter <filter>", "Additional execution filter")
17
+ .action(async (opts) => {
18
+ const { launch, finish, filter } = opts;
19
+ let { command } = opts;
17
20
 
18
- const { command, launch, finish } = opts;
19
21
  if (opts.envFile) require('dotenv').config(opts.envFile); // eslint-disable-line
20
22
 
21
23
  const apiKey = process.env['INPUT_TESTOMATIO-KEY'] || process.env.TESTOMATIO;
@@ -51,6 +53,27 @@ program
51
53
 
52
54
  let exitCode = 0;
53
55
 
56
+ const client = new TestomatClient({ apiKey, title, parallel: true });
57
+
58
+ if(filter) {
59
+ const [pipe, ...optsArray] = filter.split(":");
60
+ const pipeOptions = optsArray.join(":");
61
+
62
+ try {
63
+ const tests = await client.prepareRun({pipe, pipeOptions});
64
+
65
+ if(!tests || tests.length === 0) {
66
+ return;
67
+ }
68
+
69
+ const grep = ` --grep (${tests.join('|')})`;
70
+ command += grep;
71
+ }
72
+ catch(err) {
73
+ console.log(APP_PREFIX, err);
74
+ }
75
+ }
76
+
54
77
  if (!command.split) {
55
78
  process.exitCode = 255;
56
79
  console.log(APP_PREFIX, `No command provided. Use -c option to launch a test runner.`);
@@ -73,8 +96,6 @@ program
73
96
  return;
74
97
  }
75
98
 
76
- const client = new TestomatClient({ apiKey, title, parallel: true });
77
-
78
99
  client.createRun().then(() => {
79
100
  const cmd = spawn(testCmds[0], testCmds.slice(1), { stdio: 'inherit' });
80
101
 
package/lib/client.js CHANGED
@@ -1,18 +1,19 @@
1
1
  const debug = require('debug')('@testomatio/reporter:client');
2
2
  const createCallsiteRecord = require('callsite-record');
3
3
  const { sep, join } = require('path');
4
+ const { minimatch } = require('minimatch')
4
5
  const fs = require('fs');
5
6
  const chalk = require('chalk');
6
7
  const { randomUUID } = require('crypto');
7
8
  const upload = require('./fileUploader');
8
9
  const { APP_PREFIX } = require('./constants');
9
10
  const pipesFactory = require('./pipe');
10
- const logger = require('./logger');
11
+ const artifactStorage = require('./storages/artifact-storage');
11
12
 
12
13
  /**
13
14
  * @typedef {import('../types').TestData} TestData
14
15
  * @typedef {import('../types').RunStatus} RunStatus
15
- * @typedef {import('../types').PipeResult} PipeResult
16
+ * @typedef {import('../types').PipeResult} PipeResult
16
17
  */
17
18
 
18
19
  class Client {
@@ -22,39 +23,85 @@ class Client {
22
23
  * @param {*} params
23
24
  */
24
25
  constructor(params = {}) {
25
- this.parallel = params.parallel;
26
26
  const store = {};
27
27
  this.uuid = randomUUID();
28
28
  this.pipes = pipesFactory(params, store);
29
29
  this.queue = Promise.resolve();
30
30
  this.totalUploaded = 0;
31
31
  this.version = JSON.parse(fs.readFileSync(join(__dirname, '..', 'package.json')).toString()).version;
32
+ this.executionList = Promise.resolve();
33
+
32
34
  console.log(APP_PREFIX, `Testomatio Reporter v${this.version}`);
33
35
  }
34
36
 
37
+ /**
38
+ * Asynchronously prepares the execution list for running tests through various pipes.
39
+ * Each pipe in the client is checked for enablement,
40
+ * and if all pipes are disabled, the function returns a resolved Promise.
41
+ * Otherwise, it executes the `prepareRun` method for each enabled pipe and collects the results.
42
+ * The results are then filtered to remove any undefined values.
43
+ * If no valid results are found, the function returns undefined.
44
+ * Otherwise, it returns the first non-empty array from the filtered results.
45
+ *
46
+ * @param {Object} params - The options for preparing the test execution list.
47
+ * @param {string} params.pipe - Name of the executed pipe.
48
+ * @param {string} params.pipeOptions - Filter option.
49
+ * @returns {Promise<any>} - A Promise that resolves to an
50
+ * array containing the prepared execution list,
51
+ * or resolves to undefined if no valid results are found or if all pipes are disabled.
52
+ */
53
+ async prepareRun(params) {
54
+ const { pipe, pipeOptions } = params;
55
+ // all pipes disabled, skipping
56
+ if (!this.pipes.some(p => p.isEnabled)) {
57
+ return Promise.resolve();
58
+ }
59
+
60
+ try {
61
+ const filterPipe = this.pipes.find(p => p.constructor.name.toLowerCase() === `${pipe.toLowerCase()}pipe`);
62
+
63
+ if (!filterPipe.isEnabled) {
64
+ // TODO:for the future for the another pipes
65
+ console.warn(
66
+ APP_PREFIX,
67
+ `At the moment processing is available only for the "testomatio" key. Example: "testomatio:tag-name=xxx"`
68
+ );
69
+ return;
70
+ }
71
+
72
+ const results = await Promise.all(this.pipes.map(async p =>
73
+ ({ pipe: p.toString(), result: await p.prepareRun(pipeOptions) })
74
+ ));
75
+
76
+ const result = results.filter(p => p.pipe.includes('Testomatio'))[0]?.result;
77
+
78
+ if (!result || result.length === 0) {
79
+ return;
80
+ }
81
+
82
+ debug('Execution tests list', result);
83
+
84
+ return result;
85
+ } catch (err) {
86
+ console.error(APP_PREFIX, err);
87
+ }
88
+ }
89
+
35
90
  /**
36
91
  * Used to create a new Test run
37
92
  *
38
93
  * @returns {Promise<any>} - resolves to Run id which should be used to update / add test
39
94
  */
40
95
  createRun() {
96
+ debug('Creating run...');
41
97
  // all pipes disabled, skipping
42
- if (!this.pipes.filter(p => p.isEnabled).length) return Promise.resolve();
43
-
44
- const runParams = {
45
- title: this.title,
46
- parallel: this.parallel,
47
- env: this.env,
48
- };
49
-
50
- global.testomatioArtifacts = [];
51
- // TODO: create global storage
98
+ if (!this.pipes?.filter(p => p.isEnabled).length) return Promise.resolve();
52
99
 
53
100
  this.queue = this.queue
54
- .then(() => Promise.all(this.pipes.map(p => p.createRun(runParams))))
101
+ .then(() => Promise.all(this.pipes.map(p => p.createRun())))
55
102
  .catch(err => console.log(APP_PREFIX, err))
56
103
  .then(() => undefined); // fixes return type
57
- debug('Run', this.queue);
104
+ // debug('Run', this.queue);
58
105
  return this.queue;
59
106
  }
60
107
 
@@ -63,12 +110,11 @@ class Client {
63
110
  *
64
111
  * @param {string|undefined} status
65
112
  * @param {TestData} [testData]
66
- * @param {string[]} [storeArtifacts]
67
113
  * @returns {Promise<PipeResult[]>}
68
114
  */
69
- async addTestRun(status, testData, storeArtifacts = []) {
115
+ async addTestRun(status, testData) {
70
116
  // all pipes disabled, skipping
71
- if (!this.pipes.filter(p => p.isEnabled).length) return;
117
+ if (!this.pipes?.filter(p => p.isEnabled).length) return [];
72
118
 
73
119
  if (!testData)
74
120
  testData = {
@@ -103,20 +149,23 @@ class Client {
103
149
  stack = this.formatSteps(stack, steps);
104
150
  }
105
151
 
152
+ stack += testData.stack || '';
153
+
154
+ // ATTACH LOGS from storage
155
+ // in some cases (e.g. using cucumber) logger instance becomes empty object, if import at the top of the file
156
+ const logger = require('./storages/logger');
106
157
  const testLogs = logger.getLogs(test_id);
107
- debug(`Test logs for ${test_id}:\n`, testLogs);
108
- stack += testLogs;
158
+ // debug(`Test logs for ${test_id}:\n`, testLogs);
159
+ if (stack) stack += '\n\n';
160
+ stack += testLogs ? `${chalk.bold('Logs:')}\n${testLogs}` : '';
109
161
 
110
- if (Array.isArray(storeArtifacts) && storeArtifacts.length) {
111
- debug('CLIENT storeArtifact', storeArtifacts);
112
- files.push(...storeArtifacts);
113
- }
162
+ // GET ARTIFACTS from storage
163
+ const artifactFiles = artifactStorage.get(test_id);
164
+ if (artifactFiles) files.push(...artifactFiles);
114
165
 
115
- if (Array.isArray(global.testomatioArtifacts)) {
116
- debug('CLIENT global[testomatioArtifacts]', global.testomatioArtifacts);
117
- files.push(...global.testomatioArtifacts);
118
- global.testomatioArtifacts = [];
119
- }
166
+ // GET KEY-VALUEs from storage
167
+ const keyValueStorage = require('./storages/key-value-storage');
168
+ const keyValues = keyValueStorage.get(test_id);
120
169
 
121
170
  for (const file of files) {
122
171
  uploadedFiles.push(upload.uploadFileByPath(file, this.uuid));
@@ -129,7 +178,7 @@ class Client {
129
178
 
130
179
  const artifacts = await Promise.all(uploadedFiles);
131
180
 
132
- global.testomatioArtifacts = [];
181
+ // global.testomatioArtifacts = [];
133
182
 
134
183
  this.totalUploaded += uploadedFiles.filter(n => n).length;
135
184
 
@@ -147,19 +196,22 @@ class Client {
147
196
  message,
148
197
  run_time: parseFloat(time),
149
198
  artifacts,
199
+ meta: keyValues,
150
200
  };
151
201
 
152
- this.queue = this.queue
153
- .then(() => Promise.all(this.pipes.map(async p => {
154
- try {
155
- const result = await p.addTest(data);
156
- return { pipe: p.toString(), result };
157
- } catch (err) {
158
- console.log(APP_PREFIX, p.toString(), err);
159
- }
160
- }
161
- )));
162
-
202
+ this.queue = this.queue.then(() =>
203
+ Promise.all(
204
+ this.pipes.map(async p => {
205
+ try {
206
+ const result = await p.addTest(data);
207
+ return { pipe: p.toString(), result };
208
+ } catch (err) {
209
+ console.log(APP_PREFIX, p.toString(), err);
210
+ }
211
+ }),
212
+ ),
213
+ );
214
+
163
215
  return this.queue;
164
216
  }
165
217
 
@@ -171,22 +223,25 @@ class Client {
171
223
  * @returns {Promise<any>} - A Promise that resolves when finishes the run.
172
224
  */
173
225
  updateRunStatus(status, isParallel = false) {
226
+ debug('Updating run status...');
174
227
  // all pipes disabled, skipping
175
- if (!this.pipes.filter(p => p.isEnabled).length) return Promise.resolve();
228
+ if (!this.pipes?.filter(p => p.isEnabled).length) return Promise.resolve();
176
229
 
177
230
  const runParams = { status, parallel: isParallel };
178
231
 
179
232
  this.queue = this.queue
180
233
  .then(() => Promise.all(this.pipes.map(p => p.finishRun(runParams))))
181
234
  .then(() => {
182
- debug('TOTAL uploaded files', this.totalUploaded);
235
+ debug('TOTAL artifacts', this.totalUploaded);
236
+ if (this.totalUploaded && !upload.isArtifactsEnabled())
237
+ debug(`${this.totalUploaded} artifacts are not uploaded, because artifacts uploading is not enabled`);
183
238
 
184
- if (upload.isArtifactsEnabled() && this.totalUploaded > 0) {
239
+ if (this.totalUploaded && upload.isArtifactsEnabled()) {
185
240
  console.log(
186
241
  APP_PREFIX,
187
- `🗄️ Total ${this.totalUploaded} artifacts ${
242
+ `🗄️ ${this.totalUploaded} artifacts ${
188
243
  process.env.TESTOMATIO_PRIVATE_ARTIFACTS ? 'privately' : chalk.bold('publicly')
189
- } uploaded to S3 bucket `,
244
+ } uploaded to S3 bucket`,
190
245
  );
191
246
  }
192
247
  })
@@ -213,17 +268,21 @@ class Client {
213
268
  stack += '\n\n';
214
269
  }
215
270
 
271
+ const customFilter = process.env.TESTOMATIO_STACK_IGNORE;
272
+
216
273
  try {
274
+ let hasFrame = false;
217
275
  const record = createCallsiteRecord({
218
276
  forError: error,
277
+ isCallsiteFrame: frame => {
278
+ if (customFilter && minimatch(frame.getFileName(), customFilter)) return false;
279
+ if (hasFrame) return false;
280
+ if (isNotInternalFrame(frame)) hasFrame = true;
281
+ return hasFrame;
282
+ }
219
283
  });
220
284
  if (record && !record.filename.startsWith('http')) {
221
- stack += record.renderSync({
222
- stackFilter: frame =>
223
- frame.getFileName().indexOf(sep) > -1 &&
224
- frame.getFileName().indexOf('node_modules') < 0 &&
225
- frame.getFileName().indexOf('internal') < 0,
226
- });
285
+ stack += record.renderSync({ stackFilter: isNotInternalFrame });
227
286
  }
228
287
  return stack;
229
288
  } catch (e) {
@@ -232,4 +291,10 @@ class Client {
232
291
  }
233
292
  }
234
293
 
294
+ function isNotInternalFrame(frame) {
295
+ return frame.getFileName().includes(sep) &&
296
+ !frame.getFileName().includes('node_modules') &&
297
+ !frame.getFileName().includes('internal')
298
+ }
299
+
235
300
  module.exports = Client;
package/lib/constants.js CHANGED
@@ -1,11 +1,10 @@
1
1
  const chalk = require('chalk');
2
+ const os = require('os');
3
+ const path = require('path');
2
4
 
3
5
  const APP_PREFIX = chalk.gray('[TESTOMATIO]');
4
- const TESTOMAT_ARTIFACT_SUFFIX = "testomatio_artifact_";
5
6
 
6
- const TESTOMAT_TMP_STORAGE = {
7
- mainDir: "testomatio_tmp",
8
- }
7
+ const TESTOMAT_TMP_STORAGE_DIR = path.join(os.tmpdir(), 'testomatio_tmp');
9
8
 
10
9
  const CSV_HEADERS = [
11
10
  { id: 'suite_title', title: 'Suite_title' },
@@ -24,8 +23,7 @@ const STATUS = {
24
23
 
25
24
  module.exports = {
26
25
  APP_PREFIX,
27
- TESTOMAT_ARTIFACT_SUFFIX,
28
- TESTOMAT_TMP_STORAGE,
26
+ TESTOMAT_TMP_STORAGE_DIR,
29
27
  CSV_HEADERS,
30
28
  STATUS,
31
29
  }
@@ -10,24 +10,42 @@ class JavaAdapter extends Adapter {
10
10
 
11
11
  formatTest(t) {
12
12
  const fileParts = t.suite_title.split('.')
13
- const example = t.title.match(/\[(.*)\]/)?.[1];
14
- if (example) t.example = { "#": example }
15
13
 
16
14
  t.file = namespaceToFileName(t.suite_title);
17
15
  t.title = t.title.split('(')[0];
16
+
17
+ // detect params
18
+ const paramMatches = t.title.match(/\[(.*?)\]/g);
19
+
20
+ if (paramMatches) {
21
+ const params = paramMatches.map((_match, index) => `param${index + 1}`);
22
+ if (params.length === 1) params[0] = 'param';
23
+ let paramIndex = 0;
24
+
25
+ t.title = t.title.replace(/: \[(.*?)\]/g, () => {
26
+ if (params.length < 2) return `\${param}`
27
+ const paramName = params[paramIndex] || `param${paramIndex + 1}`;
28
+ paramIndex++;
29
+ return `\${${paramName}}`;
30
+ });
31
+ const example = {};
32
+ paramMatches.forEach((match, index) => { example[params[index]] = match.replace(/[[\]]/g, '') });
33
+ t.example = example;
34
+ }
35
+
18
36
  t.suite_title = fileParts[fileParts.length - 1].replace(/\$/g, ' | ')
19
37
  return t;
20
38
  }
21
39
 
22
- formatStack(t) {
23
- const stack = super.formatStack(t);
40
+ // formatStack(t) {
41
+ // const stack = super.formatStack(t);
24
42
 
25
- const file = t.suite_title.split('.');
43
+ // const file = t.suite_title.split('.');
26
44
 
27
- const fileLine = `at .*${file[file.length - 1]}\.java:(\\d+)` // eslint-disable-line no-useless-escape
28
- const regexp = new RegExp(fileLine,"g")
29
- return stack.replace(regexp, `${this.opts.javaTests}${path.sep}${namespaceToFileName(t.suite_title)}:$1:`);
30
- }
45
+ // const fileLine = `at .*${file[file.length - 1]}\.java:(\\d+)` // eslint-disable-line no-useless-escape
46
+ // const regexp = new RegExp(fileLine,"g")
47
+ // return stack.replace(regexp, `${this.opts.javaTests}${path.sep}${namespaceToFileName(t.suite_title)}:$1:`);
48
+ // }
31
49
  }
32
50
 
33
51
  function namespaceToFileName(fileName) {
package/lib/pipe/csv.js CHANGED
@@ -4,7 +4,7 @@ const fs = require('fs');
4
4
  const csvWriter = require('csv-writer');
5
5
  const chalk = require('chalk');
6
6
  const merge = require('lodash.merge');
7
- const { isSameTest, getCurrentDateTime } = require('../util');
7
+ const { isSameTest, getCurrentDateTime } = require('../utils/utils');
8
8
  const { CSV_HEADERS } = require('../constants');
9
9
 
10
10
  /**
@@ -40,6 +40,9 @@ class CsvPipe {
40
40
  }
41
41
  }
42
42
 
43
+ // TODO: to using SET opts as argument => prepareRun(opts)
44
+ async prepareRun() {}
45
+
43
46
  async createRun() {
44
47
  // empty
45
48
  }