@testomatio/reporter 0.8.0-beta.3 → 0.8.0-beta.30

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.
package/Changelog.md CHANGED
@@ -1,3 +1,15 @@
1
+ # 0.7.6
2
+
3
+ * Updated to use AWS S3 3.0 SDK for uploading
4
+
5
+ # 0.7.5
6
+
7
+ * Fixed reporting skipped tests in mocha
8
+
9
+ # 0.7.4
10
+
11
+ * Fixed parsing source code in JUnit files
12
+
1
13
  # 0.7.3
2
14
 
3
15
  * CodeceptJS: Upload all traces and videos from artifacts
package/README.md CHANGED
@@ -20,6 +20,19 @@ For testcafe use testcafe reporter:
20
20
  npm i testcafe-reporter-testomatio
21
21
  ```
22
22
 
23
+ For newman use:
24
+
25
+ ```bash
26
+ npm i newman-reporter-testomatio --save-dev
27
+ ```
28
+
29
+ >`newman` and `newman-reporter-testomatio` should be installed in the same directory.
30
+ \
31
+ If you run your tests using globally installed newman (`newman run ...`), intall `newman-reporter-testomatio` globally too (`npm i newman-reporter-testomatio -g`).
32
+ \
33
+ If you use locally installed newman (within the project) (`npx newman run ...`), install `newman-reporter-testomatio` locally (`npm i newman-reporter-testomatio`).
34
+ You can verify installed packages via `npm list` or `npm list -g`.
35
+
23
36
  ## Usage
24
37
 
25
38
  ### CodeceptJS
@@ -121,6 +134,15 @@ Run the following command from you project folder:
121
134
  TESTOMATIO={API_KEY} npx testcafe chrome -r testomatio
122
135
  ```
123
136
 
137
+ ### Newman (Postman)
138
+
139
+ Run collection and specify `testomatio` as reporter:
140
+
141
+ `TESTOMATIO={API_KEY} npx newman run {collection_name.json} -r testomatio`
142
+
143
+ > _`check-test` not supported for newman for now, tests will be created on testomatio by default_
144
+
145
+
124
146
  ### Cypress
125
147
 
126
148
  Load the test using using `check-test`.
@@ -208,6 +230,30 @@ Run the following command from you project folder:
208
230
  TESTOMATIO={API_KEY} npx start-test-run -c 'npx wdio wdio.conf.js'
209
231
  ```
210
232
 
233
+ ## Pipes
234
+ Pipes allow you to get report inside different systems (e.g. Pull request comment, database etc)
235
+ For now next pipes available:
236
+
237
+ ### GitHub
238
+ This pipe adds comment with run report to GitHub Pull Request.
239
+
240
+ To use it:
241
+ 1. run your tests using github actions in Pull Request
242
+ 2. pass `GH_PAT` (GitHub Personal Access Token) as environment variable.
243
+
244
+ > Last report (comment) will be replaced with the new one.
245
+ To leave previous report pass `GITHUB_KEEP_OUTDATED_REPORTS=1` env variable.
246
+
247
+ ### GitLab
248
+ This pipe adds comment with run report to GitLab Merge Request.
249
+
250
+ To use it:
251
+ 1. run your tests in Merge Request (pipeline trigger should be `merge_request`)
252
+ 2. pass `GITLAB_PAT` (GitLab Personal Access Token) as environment variable.
253
+
254
+ > Last report (comment) will be replaced with the new one.
255
+ To leave previous report pass `GITLAB_KEEP_OUTDATED_REPORTS=1` env variable.
256
+
211
257
  ## JUnit Reports
212
258
 
213
259
  > **Notice** JUnit reports are supported since 0.6.0
@@ -408,6 +454,23 @@ Add environments to run by providing `TESTOMATIO_ENV` as comma seperated values:
408
454
  TESTOMATIO={API_KEY} TESTOMATIO_ENV="Windows, Chrome" <actual run command>
409
455
  ```
410
456
 
457
+ ### Save test results to .csv file
458
+ Add an env to run by specifying the `TESTOMATIO_CSV_FILENAME` variable.
459
+
460
+ 1) using default report name:
461
+
462
+ ```bash
463
+ TESTOMATIO={API_KEY} TESTOMATIO_CSV_FILENAME="report.csv" <actual run command>
464
+ ```
465
+
466
+ 2) using unique report name:
467
+
468
+ ```bash
469
+ TESTOMATIO={API_KEY} TESTOMATIO_CSV_FILENAME="test.csv" <actual run command>
470
+ ```
471
+ _It's create a new /export folder with csv files_
472
+
473
+
411
474
  ### Attaching Test Artifacts
412
475
 
413
476
  To save a test artifacts (screenshots and videos) of a failed test use S3 storage.
@@ -35,11 +35,6 @@ function CodeceptReporter(config) {
35
35
  const testTimeMap = {};
36
36
  const { apiKey } = config;
37
37
 
38
- if (!apiKey) {
39
- console.log('TESTOMATIO key is empty, ignoring reports');
40
- return;
41
- }
42
-
43
38
  const getDuration = test => {
44
39
  if (testTimeMap[test.id]) {
45
40
  return Date.now() - testTimeMap[test.id];
@@ -72,7 +67,7 @@ function CodeceptReporter(config) {
72
67
  });
73
68
 
74
69
  event.dispatcher.on(event.all.result, async () => {
75
- if (videos.length && upload.isArtifactsEnabled) {
70
+ if (videos.length && upload.isArtifactsEnabled()) {
76
71
  console.log(TRConstants.APP_PREFIX, `🎞️ Uploading ${videos.length} videos...`);
77
72
 
78
73
  const promises = [];
@@ -18,13 +18,7 @@ class CucumberReporter extends Formatter {
18
18
  this.failures = [];
19
19
  this.cases = [];
20
20
 
21
- const apiKey = process.env.TESTOMATIO;
22
- if (!apiKey || apiKey === '') {
23
- console.log(chalk.red('TESTOMATIO key is empty, ignoring reports'));
24
- return;
25
- }
26
-
27
- this.client = new TestomatClient({ apiKey });
21
+ this.client = new TestomatClient();
28
22
  this.status = TRConstants.PASSED;
29
23
 
30
24
  }
@@ -5,14 +5,7 @@ const { PASSED, FAILED } = require('../constants');
5
5
  class JasmineReporter {
6
6
  constructor(options) {
7
7
  this.testTimeMap = {};
8
- const { apiKey } = options;
9
-
10
- if (!apiKey) {
11
- console.log('TESTOMATIO key is empty, ignoring reports');
12
- return;
13
- }
14
-
15
- this.client = new TestomatClient({ apiKey });
8
+ this.client = new TestomatClient({ apiKey: options?.apiKey });
16
9
  this.client.createRun();
17
10
  }
18
11
 
@@ -6,14 +6,8 @@ class JestReporter {
6
6
  constructor(globalConfig, options) {
7
7
  this._globalConfig = globalConfig;
8
8
  this._options = options;
9
- const { apiKey } = options;
10
9
 
11
- if (!apiKey) {
12
- console.log('TESTOMATIO key is empty, ignoring reports');
13
- return;
14
- }
15
-
16
- this.client = new TestomatClient({ apiKey });
10
+ this.client = new TestomatClient({ apiKey: options?.apiKey });
17
11
  this.client.createRun();
18
12
  }
19
13
 
@@ -1,17 +1,23 @@
1
1
  // eslint-disable-next-line global-require, import/no-extraneous-dependencies
2
2
  const Mocha = require('mocha');
3
+ const chalk = require('chalk');
3
4
  const TestomatClient = require('../client');
4
5
  const TRConstants = require('../constants');
5
6
  const { parseTest } = require('../util');
6
7
 
7
- const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS } = Mocha.Runner.constants;
8
+ const { EVENT_RUN_BEGIN, EVENT_RUN_END, EVENT_TEST_FAIL, EVENT_TEST_PASS, EVENT_TEST_PENDING } = Mocha.Runner.constants;
8
9
 
9
10
  function MochaReporter(runner, opts) {
10
11
  Mocha.reporters.Base.call(this, runner);
11
- let passes = 0;
12
- let failures = 0;
12
+ let passes = 0; let failures = 0; let skipped = 0; // eslint-disable-line no-unused-vars
13
13
 
14
- const client = new TestomatClient({ apiKey: opts?.reporterOptions?.apiKey });
14
+ const apiKey = opts?.reporterOptions?.apiKey || process.env.TESTOMATIO;
15
+
16
+ if (!apiKey) {
17
+ console.log('TESTOMATIO key is empty, ignoring reports');
18
+ return;
19
+ }
20
+ const client = new TestomatClient({ apiKey });
15
21
 
16
22
  runner.on(EVENT_RUN_BEGIN, () => {
17
23
  client.createRun();
@@ -19,7 +25,7 @@ function MochaReporter(runner, opts) {
19
25
 
20
26
  runner.on(EVENT_TEST_PASS, test => {
21
27
  passes += 1;
22
- console.log('pass: %s', test.fullTitle());
28
+ console.log(chalk.bold.green(''), test.fullTitle());
23
29
  const testId = parseTest(test.title);
24
30
  client.addTestRun(testId, TRConstants.PASSED, {
25
31
  title: test.title,
@@ -27,9 +33,19 @@ function MochaReporter(runner, opts) {
27
33
  });
28
34
  });
29
35
 
36
+ runner.on(EVENT_TEST_PENDING, test => {
37
+ skipped += 1;
38
+ console.log('skip: %s', test.fullTitle());
39
+ const testId = parseTest(test.title);
40
+ client.addTestRun(testId, TRConstants.SKIPPED, {
41
+ title: test.title,
42
+ time: test.duration,
43
+ });
44
+ });
45
+
30
46
  runner.on(EVENT_TEST_FAIL, (test, err) => {
31
47
  failures += 1;
32
- console.log('fail: %s -- error: %s', test.fullTitle(), err.message);
48
+ console.log(chalk.bold.red(''), test.fullTitle(), chalk.gray(err.message));
33
49
  const testId = parseTest(test.title);
34
50
  client.addTestRun(testId, TRConstants.FAILED, {
35
51
  error: err,
@@ -39,8 +55,8 @@ function MochaReporter(runner, opts) {
39
55
  });
40
56
 
41
57
  runner.on(EVENT_RUN_END, () => {
42
- console.log('end: %d/%d', passes, passes + failures);
43
58
  const status = failures === 0 ? TRConstants.PASSED : TRConstants.FAILED;
59
+ console.log(chalk.bold(status), `${passes} passed, ${failures} failed`);
44
60
  client.updateRunStatus(status);
45
61
  });
46
62
  }
@@ -10,13 +10,7 @@ const { parseTest } = require('../util');
10
10
 
11
11
  class TestomatioReporter {
12
12
  constructor(config = {}) {
13
- const { apiKey } = config;
14
-
15
- if (!apiKey) {
16
- console.log('API Key is not provided. Testomat.io report is disabled');
17
- } else {
18
- this.client = new TestomatioClient({ apiKey });
19
- }
13
+ this.client = new TestomatioClient({ apiKey: config?.apiKey });
20
14
 
21
15
  this.videos = [];
22
16
  }
@@ -75,7 +69,7 @@ class TestomatioReporter {
75
69
  async onEnd(result) {
76
70
  if (!this.client) return;
77
71
 
78
- if (this.videos.length && upload.isArtifactsEnabled) {
72
+ if (this.videos.length && upload.isArtifactsEnabled()) {
79
73
  console.log(Status.APP_PREFIX, `🎞️ Uploading ${this.videos.length} videos...`);
80
74
 
81
75
  const promises = [];
@@ -7,10 +7,7 @@ class WebdriverReporter extends WDIOReporter {
7
7
  constructor(options) {
8
8
  super(options);
9
9
 
10
- const { apiKey } = options;
11
- if (!apiKey) return;
12
-
13
- this.client = new TestomatClient({ apiKey });
10
+ this.client = new TestomatClient({ apiKey: options?.apiKey });
14
11
  options = Object.assign(options, { stdout: true });
15
12
 
16
13
  this._addTestPromises = [];
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
+
2
3
  const program = require("commander");
3
4
  const chalk = require("chalk");
4
5
  const glob = require('glob');
5
-
6
+ const debug = require('debug')('@testomatio/reporter:xml-cli');
6
7
  const { APP_PREFIX } = require('../constants');
7
8
  const XmlReader = require("../xmlReader");
8
9
 
@@ -22,7 +23,10 @@ program
22
23
  pattern += '.xml';
23
24
  }
24
25
  let { javaTests, lang } = opts;
25
- if (opts.envFile) require('dotenv').config(opts.envFile); // eslint-disable-line
26
+ if (opts.envFile) {
27
+ debug('Loading env file: %s', opts.envFile)
28
+ require('dotenv').config({ path: opts.envFile }); // eslint-disable-line
29
+ }
26
30
  if (javaTests === true) javaTests = 'src/test/java';
27
31
  lang = lang?.toLowerCase();
28
32
  const runReader = new XmlReader({ javaTests, lang });
package/lib/client.js CHANGED
@@ -1,4 +1,3 @@
1
- const axios = require('axios');
2
1
  const createCallsiteRecord = require('callsite-record');
3
2
  const { sep, join } = require('path');
4
3
  const fs = require('fs');
@@ -6,8 +5,8 @@ const chalk = require('chalk');
6
5
  const upload = require('./fileUploader');
7
6
  const { PASSED, FAILED, FINISHED, APP_PREFIX } = require('./constants');
8
7
  const pipesFactory = require('./pipe');
9
- const { TESTOMATIO_ENV } = process.env;
10
8
 
9
+ const { TESTOMATIO_ENV } = process.env;
11
10
 
12
11
  class TestomatClient {
13
12
  /**
@@ -15,17 +14,18 @@ class TestomatClient {
15
14
  *
16
15
  * @param {*} params
17
16
  */
18
- constructor(params) {
19
- this.apiKey = params.apiKey || process.env.TESTOMATIO;
17
+ constructor(params = {}) {
20
18
  this.title = params.title || process.env.TESTOMATIO_TITLE;
21
- this.env = TESTOMATIO_ENV;
19
+ this.createNewTests = params.createNewTests ?? !!process.env.TESTOMATIO_CREATE;
20
+ this.proceed = process.env.TESTOMATIO_PROCEED;
21
+ this.env = TESTOMATIO_ENV;
22
22
  this.parallel = params.parallel;
23
- const store = {}
23
+ const store = {};
24
24
  this.pipes = pipesFactory(params, store);
25
25
  this.queue = Promise.resolve();
26
- this.axios = axios.create();
27
26
  this.totalUploaded = 0;
28
27
  this.version = JSON.parse(fs.readFileSync(join(__dirname, '..', 'package.json')).toString()).version;
28
+ console.log(APP_PREFIX, `Testomatio Reporter v${this.version}`);
29
29
  }
30
30
 
31
31
  /**
@@ -34,7 +34,9 @@ class TestomatClient {
34
34
  * @returns {Promise} - resolves to Run id which should be used to update / add test
35
35
  */
36
36
  createRun() {
37
- const { runId } = process.env;
37
+ // all pipes disabled, skipping
38
+ if (!this.pipes.filter(p => p.isEnabled).length) return;
39
+
38
40
  const runParams = {
39
41
  title: this.title,
40
42
  parallel: this.parallel,
@@ -43,7 +45,9 @@ class TestomatClient {
43
45
 
44
46
  global.testomatioArtifacts = [];
45
47
 
46
- this.queue = this.queue.then(() => Promise.all(this.pipes.map(p => p.createRun(runParams))));
48
+ this.queue = this.queue
49
+ .then(() => Promise.all(this.pipes.map(p => p.createRun(runParams))))
50
+ .catch(err => console.log(APP_PREFIX, err));
47
51
 
48
52
  return this.queue;
49
53
  }
@@ -54,6 +58,9 @@ class TestomatClient {
54
58
  * @returns {Promise}
55
59
  */
56
60
  async addTestRun(testId, status, testData = {}) {
61
+ // all pipes disabled, skipping
62
+ if (!this.pipes.filter(p => p.isEnabled).length) return;
63
+
57
64
  const {
58
65
  error = '',
59
66
  time = '',
@@ -96,7 +103,7 @@ class TestomatClient {
96
103
  uploadedFiles.push(upload.uploadFileAsBuffer(buffer, fileName, this.runId));
97
104
  }
98
105
 
99
- const artifacts = await Promise.all(uploadedFiles)
106
+ const artifacts = await Promise.all(uploadedFiles);
100
107
 
101
108
  global.testomatioArtifacts = [];
102
109
 
@@ -108,7 +115,7 @@ class TestomatClient {
108
115
  status,
109
116
  stack,
110
117
  example,
111
- title,
118
+ title,
112
119
  suite_title,
113
120
  suite_id,
114
121
  test_id,
@@ -117,7 +124,9 @@ class TestomatClient {
117
124
  artifacts,
118
125
  };
119
126
 
120
- this.queue = this.queue.then(() => Promise.all(this.pipes.map(p => p.addTest(data))));
127
+ this.queue = this.queue
128
+ .then(() => Promise.all(this.pipes.map(p => p.addTest(data))))
129
+ .catch(err => console.log(APP_PREFIX, err));
121
130
  return this.queue;
122
131
  }
123
132
 
@@ -127,16 +136,21 @@ class TestomatClient {
127
136
  * @returns {Promise}
128
137
  */
129
138
  updateRunStatus(status, isParallel) {
139
+ // all pipes disabled, skipping
140
+ if (!this.pipes.filter(p => p.isEnabled).length) return;
141
+
130
142
  let statusEvent;
131
143
  if (status === FINISHED) statusEvent = 'finish';
132
144
  if (status === PASSED) statusEvent = 'pass';
133
145
  if (status === FAILED) statusEvent = 'fail';
134
146
  if (isParallel) statusEvent += '_parallel';
135
- const runParams = { status, statusEvent }
147
+ const runParams = { status, statusEvent };
136
148
 
137
- this.queue = this.queue.then(() => Promise.all(this.pipes.map(p => p.finishRun(runParams))));
149
+ this.queue = this.queue
150
+ .then(() => Promise.all(this.pipes.map(p => p.finishRun(runParams))))
151
+ .catch(err => console.log(APP_PREFIX, err));
138
152
 
139
- if (upload.isArtifactsEnabled && this.totalUploaded > 0) {
153
+ if (upload.isArtifactsEnabled() && this.totalUploaded > 0) {
140
154
  console.log(
141
155
  APP_PREFIX,
142
156
  `🗄️ Total ${this.totalUploaded} artifacts ${
package/lib/constants.js CHANGED
@@ -2,10 +2,19 @@ const chalk = require('chalk');
2
2
 
3
3
  const APP_PREFIX = chalk.gray('[TESTOMATIO]');
4
4
 
5
+ const CSV_HEADERS = [
6
+ { id: 'suite_title', title: 'Suite_title' },
7
+ { id: 'title', title: 'Title' },
8
+ { id: 'status', title: 'Status' },
9
+ { id: 'message', title: 'Message' },
10
+ { id: 'stack', title: 'Stack' },
11
+ ];
12
+
5
13
  module.exports = Object.freeze({
6
14
  PASSED: 'passed',
7
15
  FAILED: 'failed',
8
16
  SKIPPED: 'skipped',
9
17
  FINISHED: 'finished',
10
18
  APP_PREFIX,
19
+ CSV_HEADERS
11
20
  });
@@ -1,4 +1,6 @@
1
- const AWS = require('aws-sdk');
1
+ const debug = require('debug')('@testomatio/reporter:upload');
2
+ const { S3 } = require('@aws-sdk/client-s3');
3
+ const { Upload } = require("@aws-sdk/lib-storage");
2
4
  const fs = require('fs');
3
5
  const path = require('path');
4
6
  const chalk = require('chalk');
@@ -6,18 +8,38 @@ const { randomUUID } = require('crypto');
6
8
  const memoize = require('lodash.memoize');
7
9
  const { APP_PREFIX } = require('./constants');
8
10
 
9
- const {
10
- S3_ENDPOINT,
11
- S3_REGION,
12
- S3_BUCKET,
13
- S3_ACCESS_KEY_ID,
14
- S3_SECRET_ACCESS_KEY,
15
- TESTOMATIO_DISABLE_ARTIFACTS,
16
- TESTOMATIO_PRIVATE_ARTIFACTS,
17
- S3_FORCE_PATH_STYLE,
18
- } = process.env;
19
-
20
- const isArtifactsEnabled = S3_BUCKET && !TESTOMATIO_DISABLE_ARTIFACTS;
11
+ const keys = [
12
+ 'S3_ENDPOINT',
13
+ 'S3_REGION',
14
+ 'S3_BUCKET',
15
+ 'S3_ACCESS_KEY_ID',
16
+ 'S3_SECRET_ACCESS_KEY',
17
+ 'TESTOMATIO_DISABLE_ARTIFACTS',
18
+ 'TESTOMATIO_PRIVATE_ARTIFACTS',
19
+ 'S3_FORCE_PATH_STYLE',
20
+ ];
21
+
22
+ let config;
23
+
24
+ function getConfig() {
25
+ if (config) return config;
26
+ config = keys.reduce((acc, key) => {
27
+ acc[key] = process.env[key];
28
+ return acc;
29
+ }, {});
30
+ debug('Config', config);
31
+ return config;
32
+ }
33
+
34
+ let isEnabled;
35
+
36
+ const isArtifactsEnabled = () => {
37
+ if (isEnabled !== undefined) return isEnabled;
38
+ const { S3_BUCKET, TESTOMATIO_DISABLE_ARTIFACTS } = getConfig();
39
+ isEnabled = !!(S3_BUCKET && !TESTOMATIO_DISABLE_ARTIFACTS);
40
+ debug(`Upload is ${isEnabled ? 'enabled' : 'disabled'}`);
41
+ return isEnabled;
42
+ };
21
43
 
22
44
  const _getFileExtBase64 = str => {
23
45
  const type = str.charAt(0);
@@ -32,6 +54,25 @@ const _getFileExtBase64 = str => {
32
54
  );
33
55
  };
34
56
 
57
+ const _getS3Config = () => {
58
+ const { S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_FORCE_PATH_STYLE, S3_ENDPOINT } = getConfig();
59
+
60
+ const cfg = {
61
+ region: S3_REGION,
62
+ credentials: {
63
+ accessKeyId: S3_ACCESS_KEY_ID,
64
+ secretAccessKey: S3_SECRET_ACCESS_KEY,
65
+ s3ForcePathStyle: S3_FORCE_PATH_STYLE,
66
+ }
67
+ };
68
+
69
+ if (S3_ENDPOINT) {
70
+ cfg.endpoint = S3_ENDPOINT;
71
+ }
72
+
73
+ return cfg;
74
+ }
75
+
35
76
  const uploadUsingS3 = async (filePath, runId) => {
36
77
  let ContentType;
37
78
  let Key;
@@ -42,40 +83,37 @@ const uploadUsingS3 = async (filePath, runId) => {
42
83
  Key = filePath.name;
43
84
  }
44
85
 
45
- const config = {
46
- region: S3_REGION,
47
- accessKeyId: S3_ACCESS_KEY_ID,
48
- secretAccessKey: S3_SECRET_ACCESS_KEY,
49
- s3ForcePathStyle: S3_FORCE_PATH_STYLE,
50
- };
51
-
52
- if (S3_ENDPOINT) {
53
- config.endpoint = new AWS.Endpoint(S3_ENDPOINT);
54
- }
55
-
56
- const s3 = new AWS.S3(config);
57
86
  if (!fs.existsSync(filePath)) {
58
87
  console.error(chalk.yellow(`Artifacts file ${filePath} does not exist. Skipping...`));
59
88
  return;
60
89
  }
90
+
91
+ const { S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_ENDPOINT, TESTOMATIO_PRIVATE_ARTIFACTS, S3_BUCKET } = getConfig();
61
92
 
62
93
  const file = fs.readFileSync(filePath);
63
94
 
64
95
  Key = `${runId}/${randomUUID()}-${Key || path.basename(filePath)}`;
65
96
  const ACL = TESTOMATIO_PRIVATE_ARTIFACTS ? 'private' : 'public-read';
66
97
 
98
+ const s3 = new S3(_getS3Config());
99
+
67
100
  try {
68
- const out = await s3
69
- .upload({
101
+ const out = new Upload({
102
+ client: s3,
103
+
104
+ params: {
70
105
  Bucket: S3_BUCKET,
71
106
  Key,
72
107
  Body: file,
73
108
  ContentType,
74
109
  ACL,
75
- })
76
- .promise();
110
+ }
111
+ });
77
112
 
78
- return out.Location;
113
+ await out.done();
114
+ debug('Uploaded', out.singleUploadResult.Location)
115
+
116
+ return out.singleUploadResult.Location;
79
117
  } catch (e) {
80
118
  console.log(APP_PREFIX, chalk.bold.red(`Failed uploading '${Key}'. Please check S3 credentials`), {
81
119
  accessKeyId: S3_ACCESS_KEY_ID,
@@ -100,35 +138,30 @@ const uploadUsingS3 = async (filePath, runId) => {
100
138
  };
101
139
 
102
140
  const uploadUsingS3AsBuffer = async (buffer, fileName, runId) => {
103
- const config = {
104
- region: S3_REGION,
105
- accessKeyId: S3_ACCESS_KEY_ID,
106
- secretAccessKey: S3_SECRET_ACCESS_KEY,
107
- s3ForcePathStyle: S3_FORCE_PATH_STYLE,
108
- };
109
-
110
- if (S3_ENDPOINT) {
111
- config.endpoint = new AWS.Endpoint(S3_ENDPOINT);
112
- }
113
141
 
114
- const s3 = new AWS.S3(config);
142
+ const { S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_ENDPOINT, TESTOMATIO_PRIVATE_ARTIFACTS, S3_BUCKET } = getConfig();
115
143
 
116
144
  const ACL = TESTOMATIO_PRIVATE_ARTIFACTS ? 'private' : 'public-read';
117
145
 
118
146
  const fileExtension = _getFileExtBase64(buffer.toString('base64'));
119
147
  const Key = `${runId}/${fileName}${fileExtension}`;
120
148
 
149
+ const s3 = new S3(_getS3Config());
150
+
121
151
  try {
122
- const out = await s3
123
- .upload({
152
+ const out = new Upload({
153
+ client: s3,
154
+
155
+ params: {
124
156
  Bucket: S3_BUCKET,
125
157
  Key,
126
158
  Body: buffer,
127
159
  ACL,
128
- })
129
- .promise();
160
+ }
161
+ });
162
+ await out.done();
130
163
 
131
- return out.Location;
164
+ return out.singleUploadResult.Location;
132
165
  } catch (e) {
133
166
  console.log(APP_PREFIX, chalk.bold.red(`Failed uploading '${Key}'. Please check S3 credentials`), {
134
167
  accessKeyId: S3_ACCESS_KEY_ID,
@@ -154,7 +187,7 @@ const uploadUsingS3AsBuffer = async (buffer, fileName, runId) => {
154
187
 
155
188
  const uploadFileByPath = async (filePath, runId) => {
156
189
  try {
157
- if (isArtifactsEnabled) {
190
+ if (isArtifactsEnabled()) {
158
191
  return uploadUsingS3(filePath, runId);
159
192
  }
160
193
  } catch (e) {
@@ -164,7 +197,7 @@ const uploadFileByPath = async (filePath, runId) => {
164
197
 
165
198
  const uploadFileAsBuffer = async (buffer, fileName, runId) => {
166
199
  try {
167
- if (isArtifactsEnabled) {
200
+ if (isArtifactsEnabled()) {
168
201
  return uploadUsingS3AsBuffer(buffer, fileName, runId);
169
202
  }
170
203
  } catch (e) {
@@ -175,5 +208,5 @@ const uploadFileAsBuffer = async (buffer, fileName, runId) => {
175
208
  module.exports = {
176
209
  uploadFileByPath: memoize(uploadFileByPath),
177
210
  uploadFileAsBuffer: memoize(uploadFileAsBuffer),
178
- isArtifactsEnabled,
211
+ isArtifactsEnabled: memoize(isArtifactsEnabled),
179
212
  };