@testomatio/reporter 1.1.0-beta → 1.2.0-beta

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.
@@ -7,9 +7,8 @@ const { TESTOMAT_ARTIFACT_SUFFIX } = require('./constants');
7
7
  const { specificTestInfo } = require('./util');
8
8
 
9
9
  class ArtifactStorage {
10
-
10
+
11
11
  constructor(params) {
12
- this._tmpPrefix = "tsmt_reporter";
13
12
  this.isFile = false;
14
13
  this.isMemory = true;
15
14
  this.storage = params?.toFile;
@@ -21,7 +20,7 @@ class ArtifactStorage {
21
20
  // so the solution is make it opposite to isMemory (which will be retrieved from global)
22
21
  this.isFile = true;
23
22
  this.isMemory = false;
24
- this.tmpDirFullpath = this.createTestomatTmpDir(this._tmpPrefix);
23
+ this.tmpDirFullpath = this.createTestomatTmpDir(ArtifactStorage._tmpPrefix);
25
24
  debug('SAVE to tmp folder mode enabled!');
26
25
  }
27
26
  }
@@ -113,7 +112,7 @@ class ArtifactStorage {
113
112
 
114
113
  // no need to use multiple dirs; we can implement it later if required
115
114
  static tmpTestomatDirNames() {
116
- const subname = this._tmpPrefix || "tsmt_reporter";
115
+ const subname = ArtifactStorage._tmpPrefix || "tsmt_reporter";
117
116
 
118
117
  return fs.readdirSync(os.tmpdir(), { withFileTypes: true })
119
118
  .filter((item) => item.isDirectory())
@@ -138,4 +137,6 @@ class ArtifactStorage {
138
137
  }
139
138
  }
140
139
 
140
+ ArtifactStorage._tmpPrefix = "tsmt_reporter";
141
+
141
142
  module.exports = ArtifactStorage;
package/lib/logger.js CHANGED
@@ -1,7 +1,18 @@
1
+ const chalk = require('chalk');
1
2
  const debug = require('debug')('@testomatio/reporter:logger');
2
3
  const { DataStorage } = require('./dataStorage');
3
4
 
4
5
  const LOG_METHODS = ['assert', 'debug', 'error', 'info', 'log', 'trace', 'warn'];
6
+ const LEVELS = {
7
+ ALL: { severity: 1, color: '' },
8
+ VERBOSE: { severity: 3, color: 'grey' },
9
+ TRACE: { severity: 5, color: 'grey' },
10
+ DEBUG: { severity: 7, color: 'cyan' },
11
+ INFO: { severity: 9, color: 'black' },
12
+ LOG: { severity: 11, color: 'black' },
13
+ WARN: { severity: 13, color: 'yellow' },
14
+ ERROR: { severity: 15, color: 'red' },
15
+ };
5
16
 
6
17
  /**
7
18
  * Logger allows to:
@@ -14,7 +25,11 @@ class Logger {
14
25
  // _loggerToIntercept intercepted and reassigned immediately when added
15
26
 
16
27
  constructor(params = {}) {
28
+ // set default logger to be used in log, warn, error, etc methods
29
+ this._originalUserLogger = { ...console };
30
+
17
31
  this.dataStorage = new DataStorage('log', params);
32
+ this.logLevel = process?.env?.LOG_LEVEL?.toUpperCase() || 'ALL';
18
33
 
19
34
  // commented because prefer to use "intercept" method
20
35
  // if (params?.logger) this._loggerToIntercept = params.logger;
@@ -65,22 +80,38 @@ class Logger {
65
80
  // it looks like: `string1 arg1 string2 arg2 string3`
66
81
  (args[index] !== undefined // eslint-disable-line no-nested-ternary
67
82
  ? typeof args[index] === 'string'
68
- ? // add arg as it is
69
- args[index]
70
- : // stringify arg
71
- this._strinfifyLogs(args[index])
72
- : // add space if no arg after string
73
- ' '),
83
+ ? args[index] // add arg as it is
84
+ : this._strinfifyLogs(args[index]) // stringify arg
85
+ : ' '), // add space if no arg after string
74
86
  // initial accumulator value
75
87
  '',
76
88
  );
77
89
  } else {
78
90
  // this block means arguments syntax is used (syntax like $('text', someVar))
91
+ // in this case strings represents just a first argument
79
92
  logs = this._strinfifyLogs(strings, ...args);
80
93
  }
81
94
  this.dataStorage.putData(logs);
82
95
  }
83
96
 
97
+ /**
98
+ * Allows you to define a step inside a test. Step name is attached to the report and
99
+ * helps to understand the test flow.
100
+ * @param {*} strings
101
+ * @param {...any} values
102
+ */
103
+ step(strings, ...values) {
104
+ let logs = '';
105
+ for (let i = 0; i < strings.length; i++) {
106
+ logs += strings[i];
107
+ if (i < values.length) {
108
+ logs += values[i];
109
+ }
110
+ }
111
+ logs = chalk.blue(`> ${logs}`);
112
+ this.dataStorage.putData(logs);
113
+ }
114
+
84
115
  /**
85
116
  *
86
117
  * @param {*} context testId or test context from test runner
@@ -97,13 +128,23 @@ class Logger {
97
128
  if (typeof arg === 'string') {
98
129
  logs.push(arg);
99
130
  } else {
100
- logs.push(JSON.stringify(arg));
131
+ try {
132
+ // eslint-disable-next-line no-unused-expressions
133
+ this.prettyObjects ? logs.push(JSON.stringify(arg, null, 2)) : logs.push(JSON.stringify(arg));
134
+ } catch (e) {
135
+ debug('Error while stringify object', e);
136
+ logs.push(arg);
137
+ }
101
138
  }
102
139
  }
103
140
  return logs.join(' ');
104
141
  }
105
142
 
106
143
  assert(...args) {
144
+ const level = 'ERROR';
145
+ const severity = LEVELS[level].severity;
146
+ if (severity < LEVELS[this.logLevel]?.severity) return;
147
+
107
148
  const logs = this._strinfifyLogs(...args);
108
149
  this.dataStorage.putData(logs);
109
150
  try {
@@ -114,8 +155,14 @@ class Logger {
114
155
  }
115
156
 
116
157
  debug(...args) {
158
+ const level = 'DEBUG';
159
+ const severity = LEVELS[level].severity;
160
+ if (severity < LEVELS[this.logLevel]?.severity) return;
161
+
162
+ if (this.logLevel === 'error' || this.logLevel === 'warn') return;
117
163
  const logs = this._strinfifyLogs(...args);
118
- this.dataStorage.putData(logs);
164
+ const colorizedLogs = chalk[LEVELS[level].color](logs);
165
+ this.dataStorage.putData(colorizedLogs);
119
166
  try {
120
167
  this._originalUserLogger.debug(...args);
121
168
  } catch (e) {
@@ -124,8 +171,13 @@ class Logger {
124
171
  }
125
172
 
126
173
  error(...args) {
174
+ const level = 'ERROR';
175
+ const severity = LEVELS[level].severity;
176
+ if (severity < LEVELS[this.logLevel]?.severity) return;
177
+
127
178
  const logs = this._strinfifyLogs(...args);
128
- this.dataStorage.putData(logs);
179
+ const colorizedLogs = chalk[LEVELS[level].color](logs);
180
+ this.dataStorage.putData(colorizedLogs);
129
181
  try {
130
182
  this._originalUserLogger.error(...args);
131
183
  } catch (e) {
@@ -134,6 +186,10 @@ class Logger {
134
186
  }
135
187
 
136
188
  info(...args) {
189
+ const level = 'INFO';
190
+ const severity = LEVELS[level].severity;
191
+ if (severity < LEVELS[this.logLevel]?.severity) return;
192
+
137
193
  const logs = this._strinfifyLogs(...args);
138
194
  this.dataStorage.putData(logs);
139
195
  try {
@@ -144,6 +200,10 @@ class Logger {
144
200
  }
145
201
 
146
202
  log(...args) {
203
+ const level = 'INFO';
204
+ const severity = LEVELS[level].severity;
205
+ if (severity < LEVELS[this.logLevel]?.severity) return;
206
+
147
207
  const logs = this._strinfifyLogs(...args);
148
208
  this.dataStorage.putData(logs);
149
209
  try {
@@ -154,8 +214,13 @@ class Logger {
154
214
  }
155
215
 
156
216
  trace(...args) {
217
+ const level = 'TRACE';
218
+ const severity = LEVELS[level].severity;
219
+ if (severity < LEVELS[this.logLevel]?.severity) return;
220
+
157
221
  const logs = this._strinfifyLogs(...args);
158
- this.dataStorage.putData(logs);
222
+ const colorizedLogs = chalk[LEVELS[level].color](logs);
223
+ this.dataStorage.putData(colorizedLogs);
159
224
  try {
160
225
  this._originalUserLogger.trace(...args);
161
226
  } catch (e) {
@@ -164,8 +229,13 @@ class Logger {
164
229
  }
165
230
 
166
231
  warn(...args) {
232
+ const level = 'WARN';
233
+ const severity = LEVELS[level].severity;
234
+ if (severity < LEVELS[this.logLevel]?.severity) return;
235
+
167
236
  const logs = this._strinfifyLogs(...args);
168
- this.dataStorage.putData(logs);
237
+ const colorizedLogs = chalk[LEVELS[level].color](logs);
238
+ this.dataStorage.putData(colorizedLogs);
169
239
  try {
170
240
  this._originalUserLogger.warn(...args);
171
241
  } catch (e) {
@@ -202,6 +272,20 @@ class Logger {
202
272
  this._loggerToIntercept[method] = (...args) => this[method](...args);
203
273
  }
204
274
  }
275
+
276
+ /**
277
+ * Allows to configure logger. Make sure you do it before the logger usage in your code.
278
+ *
279
+ * @param {Object} [config={}] - The configuration object.
280
+ * @param {string} [config.logLevel] - The desired log level. Valid values are 'DEBUG', 'INFO', 'WARN', and 'ERROR'.
281
+ * @param {boolean} [config.prettyObjects] - Specifies whether to enable pretty printing of objects.
282
+ * @returns {void}
283
+ */
284
+ configure(config = {}) {
285
+ if (!config) return;
286
+ if (config.prettyObjects) this.prettyObjects = config.prettyObjects;
287
+ if (config.logLevel) this.logLevel = config.logLevel.toUpperCase();
288
+ }
205
289
  }
206
290
 
207
291
  Logger.instance = null;
@@ -210,12 +294,8 @@ Logger.instance = null;
210
294
  module.exports = new Logger();
211
295
 
212
296
  // TODO: consider using fs promises instead of writeSync/appendFileSync to prevent blocking and improve performance
213
- // TODO: try to use method generator *
214
- // TODO: understand captureStackTrace in output (check on .error) (NOT SUCH IMPORTANT)
215
- // TODO: handle log levels to colorize logs later on UI
216
- // TODO: parse passed arguments as {level: 'str', message: 'str'} because some loggers use such syntax
217
- // TODO: add setLevel method - allows skip messages with the lower level
297
+ // TODO: parse passed arguments as {level: 'str', message: 'str'} because some loggers use such syntax;
298
+ // upd: did not face such loggers, but still could be useful
299
+
218
300
  // TODO: in case of unset _originalUserLogger, logger.{method} will not provide console output,
219
301
  // need to add some logger by default
220
-
221
- // TODO step method (blue color)
package/lib/reporter.js CHANGED
@@ -4,10 +4,12 @@ const TRConstants = require('./constants');
4
4
  const TRArtifacts = require('./_ArtifactStorageOld');
5
5
 
6
6
  const log = logger._log.bind(logger);
7
+ const step = logger.step.bind(logger);
7
8
 
8
9
  module.exports = {
9
10
  logger,
10
11
  log,
12
+ step,
11
13
  TestomatClient,
12
14
  TRConstants,
13
15
  TRArtifacts,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testomatio/reporter",
3
- "version": "1.1.0-beta",
3
+ "version": "1.2.0-beta",
4
4
  "description": "Testomatio Reporter Client",
5
5
  "main": "./lib/reporter.js",
6
6
  "typings": "typings/index.d.ts",