@testomatio/reporter 1.0.0-beta.4 → 1.0.1-6.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,6 +1,6 @@
1
1
  const TestomatClient = require('../client');
2
- const { STATUS } = require('../constants');
3
- const { parseTest, ansiRegExp } = require('../util');
2
+ const { STATUS, TESTOMAT_TMP_STORAGE } = require('../constants');
3
+ const { parseTest, ansiRegExp, fileSystem } = require('../utils/utils');
4
4
 
5
5
  class JestReporter {
6
6
  constructor(globalConfig, options) {
@@ -11,6 +11,22 @@ class JestReporter {
11
11
  this.client.createRun();
12
12
  }
13
13
 
14
+ static getIdOfCurrentlyRunningTest() {
15
+ if (!process.env.JEST_WORKER_ID) return null;
16
+ try {
17
+ // @ts-expect-error "expect" could only be defined inside Jest environement (forbidden to import it outside)
18
+ // eslint-disable-next-line no-undef
19
+ if (expect && expect?.getState()?.currentTestName) return parseTest(expect?.getState()?.currentTestName);
20
+ } catch (e) {
21
+ return null;
22
+ }
23
+ }
24
+
25
+ onRunStart() {
26
+ // clear tmp dir
27
+ fileSystem.clearDir(TESTOMAT_TMP_STORAGE.mainDir);
28
+ }
29
+
14
30
  onTestResult(test, testResult) {
15
31
  if (!this.client) return;
16
32
 
@@ -26,12 +42,21 @@ class JestReporter {
26
42
  steps = failureMessages[0];
27
43
  }
28
44
  const testId = parseTest(title);
45
+ let suite_title;
46
+ // this is test without a suite
47
+ if (result.fullName === result.title) {
48
+ suite_title = testResult.testFilePath.split('/').pop();
49
+ } else {
50
+ suite_title = result.fullName.replace(result.title, '');
51
+ }
52
+
29
53
  const deducedStatus = status === 'pending' ? 'skipped' : status;
30
54
  // In jest if test is not matched with test name pattern it is considered as skipped.
31
55
  // So adding a check if it is skipped for real or because of test pattern
32
56
  if (!this._globalConfig.testNamePattern || deducedStatus !== 'skipped') {
33
57
  this.client.addTestRun(deducedStatus, {
34
58
  test_id: testId,
59
+ suite_title,
35
60
  error,
36
61
  steps,
37
62
  title,
@@ -47,6 +72,9 @@ class JestReporter {
47
72
  const { numFailedTests } = results;
48
73
  const status = numFailedTests === 0 ? STATUS.PASSED : STATUS.FAILED;
49
74
  this.client.updateRunStatus(status);
75
+
76
+ // clear tmp dir
77
+ fileSystem.clearDir(TESTOMAT_TMP_STORAGE.mainDir);
50
78
  }
51
79
  }
52
80
 
@@ -3,55 +3,54 @@ const Mocha = require('mocha');
3
3
  const debug = require('debug')('@testomatio/reporter:adapter:mocha');
4
4
  const chalk = require('chalk');
5
5
  const TestomatClient = require('../client');
6
- const { STATUS } = require('../constants');
7
- const { parseTest, specificTestInfo } = require('../util');
8
- const ArtifactStorage = require('../ArtifactStorage');
6
+ const { STATUS, TESTOMAT_TMP_STORAGE } = require('../constants');
7
+ const { parseTest, specificTestInfo, fileSystem } = require('../utils/utils');
8
+ const ArtifactStorage = require('../_ArtifactStorageOld');
9
9
 
10
- const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS, EVENT_TEST_PENDING } = Mocha.Runner.constants;
10
+ const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS, EVENT_TEST_PENDING } =
11
+ Mocha.Runner.constants;
11
12
 
12
13
  function MochaReporter(runner, opts) {
13
14
  Mocha.reporters.Base.call(this, runner);
14
- let passes = 0; let failures = 0; let skipped = 0;
15
+ let passes = 0;
16
+ let failures = 0;
17
+ let skipped = 0;
15
18
  let artifactStore;
16
19
 
17
20
  const apiKey = opts?.reporterOptions?.apiKey || process.env.TESTOMATIO;
18
21
 
19
- if (!apiKey) {
20
- debug('TESTOMATIO key is empty, ignoring reports');
21
- return;
22
- }
23
22
  const client = new TestomatClient({ apiKey });
24
23
 
25
24
  runner.on(EVENT_RUN_BEGIN, () => {
26
25
  client.createRun();
27
26
 
28
- const params = {
29
- toFile: true
27
+ const params = {
28
+ toFile: true,
30
29
  };
31
-
32
- artifactStore = runner._workerReporter !== undefined
33
- ? new ArtifactStorage(params)
34
- : new ArtifactStorage();
30
+
31
+ artifactStore = runner._workerReporter !== undefined ? new ArtifactStorage(params) : new ArtifactStorage();
32
+
33
+ fileSystem.clearDir(TESTOMAT_TMP_STORAGE.mainDir);
35
34
  });
36
35
 
37
- runner.on(EVENT_TEST_PASS, async(test) => {
36
+ runner.on(EVENT_TEST_PASS, async test => {
38
37
  passes += 1;
39
38
  console.log(chalk.bold.green('✔'), test.fullTitle());
40
39
  const testId = parseTest(test.title);
41
40
 
42
- const specificTest = specificTestInfo(test);
41
+ const specificTest = specificTestInfo(test);
43
42
  const content = await artifactStore.artifactByTestName(specificTest);
44
43
 
45
44
  debug(`test=${specificTest} content = `, content);
46
45
 
47
46
  client.addTestRun(
48
- STATUS.PASSED,
47
+ STATUS.PASSED,
49
48
  {
50
49
  test_id: testId,
51
50
  title: test.title,
52
51
  time: test.duration,
53
52
  },
54
- content
53
+ content,
55
54
  );
56
55
  });
57
56
 
@@ -66,24 +65,25 @@ function MochaReporter(runner, opts) {
66
65
  });
67
66
  });
68
67
 
69
- runner.on(EVENT_TEST_FAIL, async(test, err) => {
68
+ runner.on(EVENT_TEST_FAIL, async (test, err) => {
70
69
  failures += 1;
71
70
  console.log(chalk.bold.red('✖'), test.fullTitle(), chalk.gray(err.message));
72
71
  const testId = parseTest(test.title);
73
72
 
74
- const specificTest = specificTestInfo(test);
73
+ const specificTest = specificTestInfo(test);
75
74
  const content = await artifactStore.artifactByTestName(specificTest);
76
75
 
77
76
  debug(`fail test=${specificTest} content = `, content);
78
77
 
79
78
  client.addTestRun(
80
- STATUS.FAILED, {
79
+ STATUS.FAILED,
80
+ {
81
81
  error: err,
82
82
  test_id: testId,
83
83
  title: test.title,
84
84
  time: test.duration,
85
- },
86
- content
85
+ },
86
+ content,
87
87
  );
88
88
  });
89
89
 
@@ -3,14 +3,14 @@ const crypto = require('crypto');
3
3
  const os = require('os');
4
4
  const path = require('path');
5
5
  const fs = require('fs');
6
- const { APP_PREFIX, STATUS: Status } = require('../constants');
6
+ const { APP_PREFIX, STATUS: Status, TESTOMAT_TMP_STORAGE } = require('../constants');
7
7
  const TestomatioClient = require('../client');
8
8
  const { isArtifactsEnabled } = require('../fileUploader');
9
- const { parseTest } = require('../util');
9
+ const { parseTest, fileSystem } = require('../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,17 @@ class TestomatioReporter {
18
18
  }
19
19
 
20
20
  onBegin(_config, suite) {
21
+ // clean data storage
22
+ fileSystem.clearDir(TESTOMAT_TMP_STORAGE.mainDir);
21
23
  if (!this.client) return;
22
24
  this.suite = suite;
23
25
  this.client.createRun();
24
26
  }
25
27
 
28
+ // onTestBegin(test) {
29
+ // const testId = parseTest(test.title);
30
+ // }
31
+
26
32
  onTestEnd(test, result) {
27
33
  if (!this.client) return;
28
34
 
@@ -37,7 +43,9 @@ class TestomatioReporter {
37
43
  for (const step of result.steps) {
38
44
  appendStep(step, steps);
39
45
  }
40
-
46
+
47
+ const logs = `\n\n${chalk.bold('Logs:')}\n${chalk.red(result.stderr.join(''))}\n${result.stdout.join('')}`;
48
+
41
49
  const reportTestPromise = this.client.addTestRun(checkStatus(result.status), {
42
50
  error,
43
51
  test_id: testId,
@@ -45,13 +53,14 @@ class TestomatioReporter {
45
53
  title,
46
54
  steps: steps.join('\n'),
47
55
  time: duration,
56
+ stack: logs,
48
57
  }).then(pipes => {
49
- testId = pipes.filter(p => p.pipe.includes('Testomatio'))[0]?.result?.data?.test_id;
58
+ testId = pipes?.filter(p => p.pipe.includes('Testomatio'))[0]?.result?.data?.test_id;
50
59
 
51
60
  this.uploads.push({
52
61
  testId, title, suite_title, files: result.attachments.filter((a) => a.body || a.path)
53
- })
54
- });;
62
+ });
63
+ });
55
64
 
56
65
  reportTestPromises.push(reportTestPromise);
57
66
  }
@@ -67,10 +76,9 @@ class TestomatioReporter {
67
76
  const promises = [];
68
77
 
69
78
  for (const upload of this.uploads) {
70
-
71
79
  const { title, testId, suite_title } = upload;
72
80
 
73
- const files = upload.files.map((attachment) => {
81
+ const files = upload.files.map(attachment => {
74
82
  if (attachment.body) {
75
83
  const fileName = tmpFile();
76
84
  fs.writeFileSync(fileName, attachment.body);
@@ -78,7 +86,6 @@ class TestomatioReporter {
78
86
  return { path: attachment.path, title, type: attachment.contentType };
79
87
  });
80
88
 
81
-
82
89
  promises.push(
83
90
  this.client.addTestRun(undefined, {
84
91
  test_id: testId,
@@ -124,4 +131,4 @@ function tmpFile(prefix = 'tmp.') {
124
131
  return path.join(tmpdir, prefix + crypto.randomBytes(16).toString('hex'));
125
132
  }
126
133
 
127
- module.exports = TestomatioReporter;
134
+ 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) {
@@ -0,0 +1,25 @@
1
+ // const debug = require('debug')('@testomatio/reporter:logger');
2
+ const { DataStorage } = require('./dataStorage');
3
+
4
+ class ArtifactStorage {
5
+ constructor() {
6
+ this.dataStorage = new DataStorage('artifact');
7
+
8
+ // singleton
9
+ if (!ArtifactStorage.instance) {
10
+ ArtifactStorage.instance = this;
11
+ }
12
+ }
13
+
14
+ save(data, context = null) {
15
+ this.dataStorage.putData(data, context);
16
+ }
17
+
18
+ get(context) {
19
+ this.dataStorage.getData(context);
20
+ }
21
+ }
22
+
23
+ ArtifactStorage.instance = null;
24
+
25
+ module.exports = new ArtifactStorage();
@@ -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,6 +1,7 @@
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');
@@ -11,6 +12,7 @@ const pipesFactory = require('./pipe');
11
12
  /**
12
13
  * @typedef {import('../types').TestData} TestData
13
14
  * @typedef {import('../types').RunStatus} RunStatus
15
+ * @typedef {import('../types').PipeResult} PipeResult
14
16
  */
15
17
 
16
18
  class Client {
@@ -20,57 +22,109 @@ class Client {
20
22
  * @param {*} params
21
23
  */
22
24
  constructor(params = {}) {
23
- this.parallel = params.parallel;
24
25
  const store = {};
25
26
  this.uuid = randomUUID();
26
27
  this.pipes = pipesFactory(params, store);
27
28
  this.queue = Promise.resolve();
28
29
  this.totalUploaded = 0;
29
30
  this.version = JSON.parse(fs.readFileSync(join(__dirname, '..', 'package.json')).toString()).version;
31
+ this.executionList = Promise.resolve();
32
+
30
33
  console.log(APP_PREFIX, `Testomatio Reporter v${this.version}`);
31
34
  }
32
35
 
36
+ /**
37
+ * Asynchronously prepares the execution list for running tests through various pipes.
38
+ * Each pipe in the client is checked for enablement,
39
+ * and if all pipes are disabled, the function returns a resolved Promise.
40
+ * Otherwise, it executes the `prepareRun` method for each enabled pipe and collects the results.
41
+ * The results are then filtered to remove any undefined values.
42
+ * If no valid results are found, the function returns undefined.
43
+ * Otherwise, it returns the first non-empty array from the filtered results.
44
+ *
45
+ * @param {Object} params - The options for preparing the test execution list.
46
+ * @param {string} params.pipe - Name of the executed pipe.
47
+ * @param {string} params.pipeOptions - Filter option.
48
+ * @returns {Promise<any>} - A Promise that resolves to an
49
+ * array containing the prepared execution list,
50
+ * or resolves to undefined if no valid results are found or if all pipes are disabled.
51
+ */
52
+ async prepareRun(params) {
53
+ const { pipe, pipeOptions } = params;
54
+ // all pipes disabled, skipping
55
+ if (!this.pipes.some(p => p.isEnabled)) {
56
+ return Promise.resolve();
57
+ }
58
+
59
+ try {
60
+ const filterPipe = this.pipes.find(p => p.constructor.name.toLowerCase() === `${pipe.toLowerCase()}pipe`);
61
+
62
+ if (!filterPipe.isEnabled) {
63
+ // TODO:for the future for the another pipes
64
+ console.warn(
65
+ APP_PREFIX,
66
+ `At the moment processing is available only for the "testomatio" key. Example: "testomatio:tag-name=xxx"`
67
+ );
68
+ return;
69
+ }
70
+
71
+ const results = await Promise.all(this.pipes.map(async p =>
72
+ ({ pipe: p.toString(), result: await p.prepareRun(pipeOptions) })
73
+ ));
74
+
75
+ const result = results.filter(p => p.pipe.includes('Testomatio'))[0]?.result;
76
+
77
+ if (!result || result.length === 0) {
78
+ return;
79
+ }
80
+
81
+ debug('Execution tests list', result);
82
+
83
+ return result;
84
+ } catch (err) {
85
+ console.error(APP_PREFIX, err);
86
+ }
87
+ }
88
+
33
89
  /**
34
90
  * Used to create a new Test run
35
91
  *
36
- * @returns {Promise<void>} - resolves to Run id which should be used to update / add test
92
+ * @returns {Promise<any>} - resolves to Run id which should be used to update / add test
37
93
  */
38
94
  createRun() {
95
+ debug('Creating run...');
39
96
  // all pipes disabled, skipping
40
- if (!this.pipes.filter(p => p.isEnabled).length) return Promise.resolve();
41
-
42
- const runParams = {
43
- title: this.title,
44
- parallel: this.parallel,
45
- env: this.env,
46
- };
97
+ if (!this.pipes?.filter(p => p.isEnabled).length) return Promise.resolve();
47
98
 
48
99
  global.testomatioArtifacts = [];
100
+ if (!global.testomatioDataStore) global.testomatioDataStore = {};
49
101
 
50
102
  this.queue = this.queue
51
- .then(() => Promise.all(this.pipes.map(p => p.createRun(runParams))))
103
+ .then(() => Promise.all(this.pipes.map(p => p.createRun())))
52
104
  .catch(err => console.log(APP_PREFIX, err))
53
105
  .then(() => undefined); // fixes return type
54
- debug('Run', this.queue);
106
+ // debug('Run', this.queue);
55
107
  return this.queue;
56
108
  }
57
109
 
58
110
  /**
59
111
  * Updates test status and its data
60
- *
112
+ *
61
113
  * @param {string|undefined} status
62
114
  * @param {TestData} [testData]
63
115
  * @param {string[]} [storeArtifacts]
64
- * @returns {Promise<void>}
116
+ * @returns {Promise<PipeResult[]>}
65
117
  */
66
118
  async addTestRun(status, testData, storeArtifacts = []) {
119
+ debug('Adding test run for test', testData?.test_id || 'unknown test');
67
120
  // all pipes disabled, skipping
68
- if (!this.pipes.filter(p => p.isEnabled).length) return;
121
+ if (!this.pipes?.filter(p => p.isEnabled).length) return [];
69
122
 
70
- if (!testData) testData = {
71
- title: 'Unknown test',
72
- suite_title: 'Unknown suite',
73
- }
123
+ if (!testData)
124
+ testData = {
125
+ title: 'Unknown test',
126
+ suite_title: 'Unknown suite',
127
+ };
74
128
 
75
129
  const {
76
130
  error = null,
@@ -99,13 +153,22 @@ class Client {
99
153
  stack = this.formatSteps(stack, steps);
100
154
  }
101
155
 
156
+ stack += testData.stack || '';
157
+
158
+ // in some cases (e.g. using cucumber) logger instance becomes empty object, if import at the top of the file
159
+ const logger = require('./logger');
160
+ const testLogs = logger.getLogs(test_id);
161
+ // debug(`Test logs for ${test_id}:\n`, testLogs);
162
+ if (stack) stack += '\n\n';
163
+ stack += testLogs ? `${chalk.bold('Logs:')}\n${testLogs}` : '';
164
+
102
165
  if (Array.isArray(storeArtifacts) && storeArtifacts.length) {
103
- debug("CLIENT storeArtifact", storeArtifacts);
166
+ debug('CLIENT storeArtifact', storeArtifacts);
104
167
  files.push(...storeArtifacts);
105
168
  }
106
169
 
107
170
  if (Array.isArray(global.testomatioArtifacts)) {
108
- debug("CLIENT global[testomatioArtifacts]", global.testomatioArtifacts);
171
+ debug('CLIENT global[testomatioArtifacts]', global.testomatioArtifacts);
109
172
  files.push(...global.testomatioArtifacts);
110
173
  global.testomatioArtifacts = [];
111
174
  }
@@ -141,17 +204,19 @@ class Client {
141
204
  artifacts,
142
205
  };
143
206
 
144
- this.queue = this.queue
145
- .then(() => Promise.all(this.pipes.map(async p => {
146
- try {
147
- const result = await p.addTest(data);
148
- return { pipe: p.toString(), result };
149
- } catch (err) {
150
- console.log(APP_PREFIX, pipe.toString(), err);
151
- }
152
- }
153
- )));
154
-
207
+ this.queue = this.queue.then(() =>
208
+ Promise.all(
209
+ this.pipes.map(async p => {
210
+ try {
211
+ const result = await p.addTest(data);
212
+ return { pipe: p.toString(), result };
213
+ } catch (err) {
214
+ console.log(APP_PREFIX, p.toString(), err);
215
+ }
216
+ }),
217
+ ),
218
+ );
219
+
155
220
  return this.queue;
156
221
  }
157
222
 
@@ -160,19 +225,20 @@ class Client {
160
225
  * Updates the status of the current test run and finishes the run.
161
226
  * @param {RunStatus} status - The status of the current test run. Must be one of "passed", "failed", or "finished"
162
227
  * @param {boolean} [isParallel] - Whether the current test run was executed in parallel with other tests.
163
- * @returns {Promise<void>} - A Promise that resolves when finishes the run.
228
+ * @returns {Promise<any>} - A Promise that resolves when finishes the run.
164
229
  */
165
230
  updateRunStatus(status, isParallel = false) {
231
+ debug('Updating run status...');
166
232
  // all pipes disabled, skipping
167
- if (!this.pipes.filter(p => p.isEnabled).length) return Promise.resolve();
233
+ if (!this.pipes?.filter(p => p.isEnabled).length) return Promise.resolve();
168
234
 
169
235
  const runParams = { status, parallel: isParallel };
170
236
 
171
237
  this.queue = this.queue
172
238
  .then(() => Promise.all(this.pipes.map(p => p.finishRun(runParams))))
173
239
  .then(() => {
174
- debug("TOTAL uploaded files", this.totalUploaded);
175
-
240
+ debug('TOTAL uploaded files', this.totalUploaded);
241
+
176
242
  if (upload.isArtifactsEnabled() && this.totalUploaded > 0) {
177
243
  console.log(
178
244
  APP_PREFIX,
@@ -205,17 +271,21 @@ class Client {
205
271
  stack += '\n\n';
206
272
  }
207
273
 
274
+ const customFilter = process.env.TESTOMATIO_STACK_IGNORE;
275
+
208
276
  try {
277
+ let hasFrame = false;
209
278
  const record = createCallsiteRecord({
210
279
  forError: error,
280
+ isCallsiteFrame: frame => {
281
+ if (customFilter && minimatch(frame.getFileName(), customFilter)) return false;
282
+ if (hasFrame) return false;
283
+ if (isNotInternalFrame(frame)) hasFrame = true;
284
+ return hasFrame;
285
+ }
211
286
  });
212
287
  if (record && !record.filename.startsWith('http')) {
213
- stack += record.renderSync({
214
- stackFilter: frame =>
215
- frame.getFileName().indexOf(sep) > -1 &&
216
- frame.getFileName().indexOf('node_modules') < 0 &&
217
- frame.getFileName().indexOf('internal') < 0,
218
- });
288
+ stack += record.renderSync({ stackFilter: isNotInternalFrame });
219
289
  }
220
290
  return stack;
221
291
  } catch (e) {
@@ -224,4 +294,10 @@ class Client {
224
294
  }
225
295
  }
226
296
 
297
+ function isNotInternalFrame(frame) {
298
+ return frame.getFileName().includes(sep) &&
299
+ !frame.getFileName().includes('node_modules') &&
300
+ !frame.getFileName().includes('internal')
301
+ }
302
+
227
303
  module.exports = Client;
package/lib/constants.js CHANGED
@@ -3,6 +3,10 @@ const chalk = require('chalk');
3
3
  const APP_PREFIX = chalk.gray('[TESTOMATIO]');
4
4
  const TESTOMAT_ARTIFACT_SUFFIX = "testomatio_artifact_";
5
5
 
6
+ const TESTOMAT_TMP_STORAGE = {
7
+ mainDir: "testomatio_tmp",
8
+ }
9
+
6
10
  const CSV_HEADERS = [
7
11
  { id: 'suite_title', title: 'Suite_title' },
8
12
  { id: 'title', title: 'Title' },
@@ -21,6 +25,7 @@ const STATUS = {
21
25
  module.exports = {
22
26
  APP_PREFIX,
23
27
  TESTOMAT_ARTIFACT_SUFFIX,
28
+ TESTOMAT_TMP_STORAGE,
24
29
  CSV_HEADERS,
25
30
  STATUS,
26
31
  }