@testomatio/reporter 2.0.1-beta.5-timestamp → 2.0.1-beta.6

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.
Files changed (149) hide show
  1. package/README.md +1 -0
  2. package/lib/adapter/codecept.d.ts +2 -0
  3. package/lib/adapter/codecept.js +293 -335
  4. package/lib/adapter/cucumber/current.d.ts +14 -0
  5. package/lib/adapter/cucumber/current.js +195 -203
  6. package/lib/adapter/cucumber/legacy.d.ts +0 -0
  7. package/lib/adapter/cucumber/legacy.js +130 -155
  8. package/lib/adapter/cucumber.d.ts +2 -0
  9. package/lib/adapter/cucumber.js +5 -16
  10. package/lib/adapter/cypress-plugin/index.d.ts +2 -0
  11. package/lib/adapter/cypress-plugin/index.js +91 -105
  12. package/lib/adapter/jasmine.d.ts +11 -0
  13. package/lib/adapter/jasmine.js +54 -53
  14. package/lib/adapter/jest.d.ts +13 -0
  15. package/lib/adapter/jest.js +97 -99
  16. package/lib/adapter/mocha.d.ts +2 -0
  17. package/lib/adapter/mocha.js +112 -141
  18. package/lib/adapter/nightwatch.d.ts +4 -0
  19. package/lib/adapter/nightwatch.js +80 -0
  20. package/lib/adapter/playwright.d.ts +14 -0
  21. package/lib/adapter/playwright.js +199 -231
  22. package/lib/adapter/vitest.d.ts +35 -0
  23. package/lib/adapter/vitest.js +150 -149
  24. package/lib/adapter/webdriver.d.ts +24 -0
  25. package/lib/adapter/webdriver.js +144 -121
  26. package/lib/bin/cli.d.ts +2 -0
  27. package/lib/bin/cli.js +229 -211
  28. package/lib/bin/reportXml.d.ts +2 -0
  29. package/lib/bin/reportXml.js +51 -52
  30. package/lib/bin/startTest.d.ts +2 -0
  31. package/lib/bin/startTest.js +83 -95
  32. package/lib/bin/uploadArtifacts.d.ts +2 -0
  33. package/lib/bin/uploadArtifacts.js +56 -61
  34. package/lib/client.d.ts +76 -0
  35. package/lib/client.js +429 -465
  36. package/lib/config.d.ts +1 -0
  37. package/lib/config.js +18 -23
  38. package/lib/constants.d.ts +25 -0
  39. package/lib/constants.js +50 -44
  40. package/lib/data-storage.d.ts +34 -0
  41. package/lib/data-storage.js +216 -188
  42. package/lib/junit-adapter/adapter.d.ts +9 -0
  43. package/lib/junit-adapter/adapter.js +17 -20
  44. package/lib/junit-adapter/csharp.d.ts +5 -0
  45. package/lib/junit-adapter/csharp.js +28 -14
  46. package/lib/junit-adapter/index.d.ts +3 -0
  47. package/lib/junit-adapter/index.js +27 -25
  48. package/lib/junit-adapter/java.d.ts +5 -0
  49. package/lib/junit-adapter/java.js +41 -53
  50. package/lib/junit-adapter/javascript.d.ts +4 -0
  51. package/lib/junit-adapter/javascript.js +30 -27
  52. package/lib/junit-adapter/python.d.ts +5 -0
  53. package/lib/junit-adapter/python.js +38 -37
  54. package/lib/junit-adapter/ruby.d.ts +4 -0
  55. package/lib/junit-adapter/ruby.js +11 -8
  56. package/lib/output.d.ts +11 -0
  57. package/lib/output.js +44 -52
  58. package/lib/package.json +3 -0
  59. package/lib/pipe/bitbucket.d.ts +25 -0
  60. package/lib/pipe/bitbucket.js +223 -230
  61. package/lib/pipe/csv.d.ts +47 -0
  62. package/lib/pipe/csv.js +113 -126
  63. package/lib/pipe/debug.d.ts +29 -0
  64. package/lib/pipe/debug.js +125 -99
  65. package/lib/pipe/github.d.ts +30 -0
  66. package/lib/pipe/github.js +218 -213
  67. package/lib/pipe/gitlab.d.ts +25 -0
  68. package/lib/pipe/gitlab.js +183 -206
  69. package/lib/pipe/html.d.ts +35 -0
  70. package/lib/pipe/html.js +258 -321
  71. package/lib/pipe/index.d.ts +1 -0
  72. package/lib/pipe/index.js +94 -66
  73. package/lib/pipe/testomatio.d.ts +71 -0
  74. package/lib/pipe/testomatio.js +429 -474
  75. package/lib/replay.d.ts +31 -0
  76. package/lib/replay.js +255 -0
  77. package/lib/reporter-functions.d.ts +34 -0
  78. package/lib/reporter-functions.js +28 -26
  79. package/lib/reporter.d.ts +232 -0
  80. package/lib/reporter.js +34 -29
  81. package/lib/services/artifacts.d.ts +33 -0
  82. package/lib/services/artifacts.js +55 -51
  83. package/lib/services/index.d.ts +9 -0
  84. package/lib/services/index.js +14 -12
  85. package/lib/services/key-values.d.ts +27 -0
  86. package/lib/services/key-values.js +56 -53
  87. package/lib/services/logger.d.ts +64 -0
  88. package/lib/services/logger.js +226 -245
  89. package/lib/template/testomatio.hbs +1026 -1366
  90. package/lib/uploader.d.ts +60 -0
  91. package/lib/uploader.js +295 -364
  92. package/lib/utils/pipe_utils.d.ts +41 -0
  93. package/lib/utils/pipe_utils.js +89 -85
  94. package/lib/utils/utils.d.ts +54 -0
  95. package/lib/utils/utils.js +398 -307
  96. package/lib/xmlReader.d.ts +92 -0
  97. package/lib/xmlReader.js +525 -532
  98. package/package.json +64 -21
  99. package/src/adapter/codecept.js +373 -0
  100. package/src/adapter/cucumber/current.js +228 -0
  101. package/src/adapter/cucumber/legacy.js +158 -0
  102. package/src/adapter/cucumber.js +4 -0
  103. package/src/adapter/cypress-plugin/index.js +110 -0
  104. package/src/adapter/jasmine.js +60 -0
  105. package/src/adapter/jest.js +107 -0
  106. package/src/adapter/mocha.cjs +2 -0
  107. package/src/adapter/mocha.js +156 -0
  108. package/src/adapter/nightwatch.js +88 -0
  109. package/src/adapter/playwright.js +254 -0
  110. package/src/adapter/vitest.js +183 -0
  111. package/src/adapter/webdriver.js +142 -0
  112. package/src/bin/cli.js +348 -0
  113. package/src/bin/reportXml.js +77 -0
  114. package/src/bin/startTest.js +124 -0
  115. package/src/bin/uploadArtifacts.js +91 -0
  116. package/src/client.js +515 -0
  117. package/src/config.js +30 -0
  118. package/src/constants.js +53 -0
  119. package/src/data-storage.js +204 -0
  120. package/src/junit-adapter/adapter.js +23 -0
  121. package/src/junit-adapter/csharp.js +28 -0
  122. package/src/junit-adapter/index.js +28 -0
  123. package/src/junit-adapter/java.js +58 -0
  124. package/src/junit-adapter/javascript.js +31 -0
  125. package/src/junit-adapter/python.js +42 -0
  126. package/src/junit-adapter/ruby.js +10 -0
  127. package/src/output.js +57 -0
  128. package/src/pipe/bitbucket.js +252 -0
  129. package/src/pipe/csv.js +140 -0
  130. package/src/pipe/debug.js +125 -0
  131. package/src/pipe/github.js +232 -0
  132. package/src/pipe/gitlab.js +247 -0
  133. package/src/pipe/html.js +373 -0
  134. package/src/pipe/index.js +71 -0
  135. package/src/pipe/testomatio.js +504 -0
  136. package/src/replay.js +262 -0
  137. package/src/reporter-functions.js +55 -0
  138. package/src/reporter.cjs_decprecated +21 -0
  139. package/src/reporter.js +33 -0
  140. package/src/services/artifacts.js +59 -0
  141. package/src/services/index.js +13 -0
  142. package/src/services/key-values.js +59 -0
  143. package/src/services/logger.js +315 -0
  144. package/src/template/emptyData.svg +23 -0
  145. package/src/template/testomatio.hbs +1081 -0
  146. package/src/uploader.js +376 -0
  147. package/src/utils/pipe_utils.js +119 -0
  148. package/src/utils/utils.js +416 -0
  149. package/src/xmlReader.js +614 -0
@@ -1,272 +1,254 @@
1
- const chalk = require('chalk');
2
- const debug = require('debug')('@testomatio/reporter:services-logger');
3
- const { dataStorage } = require('../data-storage');
4
-
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.logger = void 0;
7
+ const picocolors_1 = __importDefault(require("picocolors"));
8
+ const debug_1 = __importDefault(require("debug"));
9
+ const data_storage_js_1 = require("../data-storage.js");
10
+ const debug = (0, debug_1.default)('@testomatio/reporter:services-logger');
5
11
  const LOG_METHODS = ['assert', 'debug', 'error', 'info', 'log', 'trace', 'warn'];
6
12
  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' },
13
+ ALL: { severity: 1, color: '' },
14
+ VERBOSE: { severity: 3, color: 'grey' },
15
+ TRACE: { severity: 5, color: 'grey' },
16
+ DEBUG: { severity: 7, color: 'cyan' },
17
+ INFO: { severity: 9, color: 'black' },
18
+ LOG: { severity: 11, color: 'black' },
19
+ WARN: { severity: 13, color: 'yellow' },
20
+ ERROR: { severity: 15, color: 'red' },
15
21
  };
16
-
17
22
  // ! DON'T use console.log, console.warn, etc in this file, because it will lead to infinite loop
18
23
  // use debug() instead
19
-
20
24
  /**
21
25
  * Logger allows to intercept logs from any logger (console.log, tracer, pino, etc)
22
26
  * and save in the testomatio reporter.
23
27
  * Supports different syntaxes to satisfy any user preferences.
24
28
  */
25
29
  class Logger {
26
- // set default logger to be used in log, warn, error, etc methods
27
- #originalUserLogger = { ...console };
28
-
29
- #userLoggerWithOverridenMethods;
30
-
31
- static #instance;
32
-
33
- /**
34
- *
35
- * @returns {Logger}
36
- */
37
- static getInstance() {
38
- if (!this.#instance) {
39
- this.#instance = new Logger();
30
+ // set default logger to be used in log, warn, error, etc methods
31
+ #originalUserLogger = { ...console };
32
+ #userLoggerWithOverridenMethods;
33
+ static #instance;
34
+ /**
35
+ *
36
+ * @returns {Logger}
37
+ */
38
+ static getInstance() {
39
+ if (!this.#instance) {
40
+ this.#instance = new Logger();
41
+ }
42
+ return this.#instance;
40
43
  }
41
- return this.#instance;
42
- }
43
-
44
- logLevel = process?.env?.LOG_LEVEL?.toUpperCase() || 'ALL';
45
-
46
- constructor() {
47
- if (!dataStorage.isFileStorage || process.env.TESTOMATIO_INTERCEPT_CONSOLE_LOGS) this.intercept(console);
48
- }
49
-
50
- /**
51
- * Allows you to define a step inside a test. Step name is attached to the report and
52
- * helps to understand the test flow.
53
- * @param {*} strings
54
- * @param {...any} values
55
- */
56
- step(strings, ...values) {
57
- let logs = '';
58
- for (let i = 0; i < strings.length; i++) {
59
- logs += strings[i];
60
- if (i < values.length) {
61
- logs += values[i];
62
- }
44
+ logLevel = process?.env?.LOG_LEVEL?.toUpperCase() || 'ALL';
45
+ constructor() {
46
+ if (!data_storage_js_1.dataStorage.isFileStorage ||
47
+ (process.env.TESTOMATIO_INTERCEPT_CONSOLE_LOGS && process.env.TESTOMATIO_INTERCEPT_CONSOLE_LOGS !== 'false'))
48
+ this.intercept(console);
63
49
  }
64
- logs = chalk.blue(`> ${logs}`);
65
- dataStorage.putData('log', logs);
66
- }
67
-
68
- /**
69
- *
70
- * @param {string} context testId or test context from test runner
71
- * @returns {string[]}
72
- */
73
- getLogs(context) {
74
- const logs = dataStorage.getData('log', context);
75
- if (!logs) return [];
76
- return logs;
77
- }
78
-
79
- #stringifyLogs(...args) {
80
- const logs = [];
81
- // stringify everything except strings
82
- for (const arg of args) {
83
- // ignore empty strings
84
- if (arg === '') continue;
85
- if (typeof arg === 'string') {
86
- logs.push(arg);
87
- } else if (Array.isArray(arg)) {
88
- logs.push(arg.join(' '));
89
- } else {
50
+ /**
51
+ * Allows you to define a step inside a test. Step name is attached to the report and
52
+ * helps to understand the test flow.
53
+ * @param {*} strings
54
+ * @param {...any} values
55
+ */
56
+ step(strings, ...values) {
57
+ let logs = '';
58
+ for (let i = 0; i < strings.length; i++) {
59
+ logs += strings[i];
60
+ if (i < values.length) {
61
+ logs += values[i];
62
+ }
63
+ }
64
+ logs = picocolors_1.default.blue(`> ${logs}`);
65
+ data_storage_js_1.dataStorage.putData('log', logs);
66
+ }
67
+ /**
68
+ *
69
+ * @param {string} context testId or test context from test runner
70
+ * @returns {string[]}
71
+ */
72
+ getLogs(context) {
73
+ const logs = data_storage_js_1.dataStorage.getData('log', context);
74
+ if (!logs)
75
+ return [];
76
+ return logs;
77
+ }
78
+ #stringifyLogs(...args) {
79
+ const logs = [];
80
+ // stringify everything except strings
81
+ for (const arg of args) {
82
+ // ignore empty strings
83
+ if (arg === '')
84
+ continue;
85
+ if (typeof arg === 'string') {
86
+ logs.push(arg);
87
+ }
88
+ else if (Array.isArray(arg)) {
89
+ logs.push(arg.join(' '));
90
+ }
91
+ else {
92
+ try {
93
+ this.prettyObjects ? logs.push(JSON.stringify(arg, null, 2)) : logs.push(JSON.stringify(arg));
94
+ }
95
+ catch (e) {
96
+ debug('Error while stringify object', e);
97
+ logs.push(arg);
98
+ }
99
+ }
100
+ }
101
+ return logs.join(' ');
102
+ }
103
+ /**
104
+ * Tagget template literal. Allows to use different syntaxes:
105
+ * 1. Tagget template: log`text ${someVar}`
106
+ * 2. Standard: log(`text ${someVar}`)
107
+ * 3. Standard with multiple arguments: log('text', someVar)
108
+ */
109
+ _templateLiteralLog(strings, ...args) {
110
+ if (Array.isArray(strings))
111
+ strings = strings.filter(item => item !== '').map(item => item.trim());
112
+ if (Array.isArray(args))
113
+ args = args.filter(item => item !== '');
114
+ let logs;
115
+ // this block means tagged template is used (syntax like $`text ${someVar}`)
116
+ if (Array.isArray(strings) && strings.length === args.length + 1) {
117
+ logs = strings.reduce((result, current, index) => result +
118
+ current +
119
+ // strings are splitted by args when use tagged template, thus we add arg after each string
120
+ // it looks like: `string1 arg1 string2 arg2 string3`
121
+ (args[index] !== undefined
122
+ ? typeof args[index] === 'string'
123
+ ? args[index] // add arg as it is
124
+ : this.#stringifyLogs(args[index]) // stringify arg
125
+ : ''),
126
+ // initial accumulator value
127
+ '');
128
+ }
129
+ else {
130
+ // this block means arguments syntax is used (syntax like $('text', someVar))
131
+ // in this case strings represents just a first argument
132
+ logs = this.#stringifyLogs(strings, ...args);
133
+ }
134
+ this.#originalUserLogger.log(logs);
135
+ data_storage_js_1.dataStorage.putData('log', logs);
136
+ }
137
+ /**
138
+ * This function is a wrapper for each logging methods (log, warn, error etc) (not to repeat the same code)
139
+ * @param {*} argsArray
140
+ * @param {*} level
141
+ * @returns
142
+ */
143
+ #logWrapper(argsArray, level) {
144
+ if (!argsArray.length)
145
+ return;
146
+ const severity = LEVELS[level].severity;
147
+ if (severity < LEVELS[this.logLevel]?.severity)
148
+ return;
149
+ const logs = this.#stringifyLogs(...argsArray);
150
+ const colorizedLogs = picocolors_1.default[LEVELS[level].color](logs);
151
+ // do not attach logs from testomatio reporter itself
152
+ if (!logs.includes('[TESTOMATIO]')) {
153
+ data_storage_js_1.dataStorage.putData('log', colorizedLogs);
154
+ }
90
155
  try {
91
- // eslint-disable-next-line no-unused-expressions
92
- this.prettyObjects ? logs.push(JSON.stringify(arg, null, 2)) : logs.push(JSON.stringify(arg));
93
- } catch (e) {
94
- debug('Error while stringify object', e);
95
- logs.push(arg);
156
+ // level.toLowerCase() represents method name (log, warn, error, etc)
157
+ this.#originalUserLogger[level.toLowerCase()](colorizedLogs);
158
+ }
159
+ catch (e) {
160
+ // method could be unexisting, ignore error
96
161
  }
97
- }
98
162
  }
99
- return logs.join(' ');
100
- }
101
-
102
- /**
103
- * Tagget template literal. Allows to use different syntaxes:
104
- * 1. Tagget template: log`text ${someVar}`
105
- * 2. Standard: log(`text ${someVar}`)
106
- * 3. Standard with multiple arguments: log('text', someVar)
107
- */
108
- _templateLiteralLog(strings, ...args) {
109
- if (Array.isArray(strings)) strings = strings.filter(item => item !== '').map(item => item.trim());
110
- if (Array.isArray(args)) args = args.filter(item => item !== '');
111
-
112
- let logs;
113
- // this block means tagged template is used (syntax like $`text ${someVar}`)
114
- if (Array.isArray(strings) && strings.length === args.length + 1) {
115
- logs = strings.reduce(
116
- (result, current, index) =>
117
- result +
118
- current +
119
- // strings are splitted by args when use tagged template, thus we add arg after each string
120
- // it looks like: `string1 arg1 string2 arg2 string3`
121
- (args[index] !== undefined // eslint-disable-line no-nested-ternary
122
- ? typeof args[index] === 'string'
123
- ? args[index] // add arg as it is
124
- : this.#stringifyLogs(args[index]) // stringify arg
125
- : ''),
126
- // initial accumulator value
127
- '',
128
- );
129
- } else {
130
- // this block means arguments syntax is used (syntax like $('text', someVar))
131
- // in this case strings represents just a first argument
132
- logs = this.#stringifyLogs(strings, ...args);
163
+ assert(...args) {
164
+ this.#logWrapper(args, 'ERROR');
133
165
  }
134
- this.#originalUserLogger.log(logs);
135
- dataStorage.putData('log', logs);
136
- }
137
-
138
- /**
139
- * This function is a wrapper for each logging methods (log, warn, error etc) (not to repeat the same code)
140
- * @param {*} argsArray
141
- * @param {*} level
142
- * @returns
143
- */
144
- #logWrapper(argsArray, level) {
145
- if (!argsArray.length) return;
146
-
147
- const severity = LEVELS[level].severity;
148
- if (severity < LEVELS[this.logLevel]?.severity) return;
149
-
150
- const logs = this.#stringifyLogs(...argsArray);
151
-
152
- const colorizedLogs = chalk[LEVELS[level].color](logs);
153
- // do not attach logs from testomatio reporter itself
154
- if (!logs.includes('[TESTOMATIO]')) {
155
- dataStorage.putData('log', colorizedLogs);
166
+ debug(...args) {
167
+ this.#logWrapper(args, 'DEBUG');
156
168
  }
157
-
158
- try {
159
- // level.toLowerCase() represents method name (log, warn, error, etc)
160
- this.#originalUserLogger[level.toLowerCase()](colorizedLogs);
161
- } catch (e) {
162
- // method could be unexisting, ignore error
169
+ error(...args) {
170
+ this.#logWrapper(args, 'ERROR');
163
171
  }
164
- }
165
-
166
- assert(...args) {
167
- this.#logWrapper(args, 'ERROR');
168
- }
169
-
170
- debug(...args) {
171
- this.#logWrapper(args, 'DEBUG');
172
- }
173
-
174
- error(...args) {
175
- this.#logWrapper(args, 'ERROR');
176
- }
177
-
178
- info(...args) {
179
- this.#logWrapper(args, 'INFO');
180
- }
181
-
182
- log(...args) {
183
- this.#logWrapper(args, 'LOG');
184
- }
185
-
186
- trace(...args) {
187
- this.#logWrapper(args, 'TRACE');
188
- }
189
-
190
- warn(...args) {
191
- this.#logWrapper(args, 'WARN');
192
- }
193
-
194
- /**
195
- * Intercepts user logger messages.
196
- * When call this method, Logger start to control the user logger
197
- * @param {*} userLogger
198
- */
199
- intercept(userLogger) {
200
- // STEP 1: reset previously intercepted logger methods to original
201
- if (this.#userLoggerWithOverridenMethods) {
202
- for (const method of LOG_METHODS) {
203
- this.#userLoggerWithOverridenMethods[method] = this.#originalUserLogger[method];
204
- }
172
+ info(...args) {
173
+ this.#logWrapper(args, 'INFO');
205
174
  }
206
-
207
- // STEP 2: intercept new logger
208
- this.#originalUserLogger = { ...userLogger };
209
-
210
- const isUserLoggerConsole = userLogger.toString?.().toLowerCase() === '[object console]';
211
- debug(`Intercepting ${isUserLoggerConsole ? 'console' : 'some user'} logger}`);
212
-
213
- // override user logger (any, e.g. console) methods to intercept log messages
214
- for (const method of LOG_METHODS) {
215
- /*
216
- its better to create method even if it does not exist in user logger;
217
- on method invocation, we will store the data anyway and catch block will prevent potential errors
218
- while trying to output the message to terminal
219
- */
220
- // if (!this._loggerToIntercept[method]) continue;
221
- userLogger[method] = (...args) => this[method](...args);
175
+ log(...args) {
176
+ this.#logWrapper(args, 'LOG');
222
177
  }
223
-
224
- this.#userLoggerWithOverridenMethods = userLogger;
225
-
226
- /*
227
- Initial idea was to intercept any logger (tracer, pino, etc),
228
- intercept message and provide output by the same logger.
229
- But reality brings some problems: the same messages are intercepted multiple times
230
- (because of multiple loggers are created at the same terminal process).
231
- Also its difficult to understand (actually did not find the way to do it) if logger was already intercepted or not.
232
- Thus, decided to intercept only console by default and provide output by default console.
233
- It means, if user uses his own logger, its messages will be intercepted,
234
- but the output will be always provided by console.
235
- TODO: try to implement the providing output to terminal by user logger
236
- */
237
- }
238
-
239
- stopInterception() {
240
- debug('Stop ntercepting logs');
241
-
242
- // restore original user logger
243
- if (this.#userLoggerWithOverridenMethods) {
244
- for (const method of LOG_METHODS) {
245
- this.#userLoggerWithOverridenMethods[method] = this.#originalUserLogger[method];
246
- }
178
+ trace(...args) {
179
+ this.#logWrapper(args, 'TRACE');
180
+ }
181
+ warn(...args) {
182
+ this.#logWrapper(args, 'WARN');
183
+ }
184
+ /**
185
+ * Intercepts user logger messages.
186
+ * When call this method, Logger start to control the user logger
187
+ * @param {*} userLogger
188
+ */
189
+ intercept(userLogger) {
190
+ // STEP 1: reset previously intercepted logger methods to original
191
+ if (this.#userLoggerWithOverridenMethods) {
192
+ for (const method of LOG_METHODS) {
193
+ this.#userLoggerWithOverridenMethods[method] = this.#originalUserLogger[method];
194
+ }
195
+ }
196
+ // STEP 2: intercept new logger
197
+ this.#originalUserLogger = { ...userLogger };
198
+ const isUserLoggerConsole = userLogger.toString?.().toLowerCase() === '[object console]';
199
+ debug(`Intercepting ${isUserLoggerConsole ? 'console' : 'some user'} logger}`);
200
+ // override user logger (any, e.g. console) methods to intercept log messages
201
+ for (const method of LOG_METHODS) {
202
+ /*
203
+ its better to create method even if it does not exist in user logger;
204
+ on method invocation, we will store the data anyway and catch block will prevent potential errors
205
+ while trying to output the message to terminal
206
+ */
207
+ // if (!this._loggerToIntercept[method]) continue;
208
+ userLogger[method] = (...args) => this[method](...args);
209
+ }
210
+ this.#userLoggerWithOverridenMethods = userLogger;
211
+ /*
212
+ Initial idea was to intercept any logger (tracer, pino, etc),
213
+ intercept message and provide output by the same logger.
214
+ But reality brings some problems: the same messages are intercepted multiple times
215
+ (because of multiple loggers are created at the same terminal process).
216
+ Also its difficult to understand (actually did not find the way to do it) if logger was already intercepted or not.
217
+ Thus, decided to intercept only console by default and provide output by default console.
218
+ It means, if user uses his own logger, its messages will be intercepted,
219
+ but the output will be always provided by console.
220
+ TODO: try to implement the providing output to terminal by user logger
221
+ */
222
+ }
223
+ stopInterception() {
224
+ debug('Stop ntercepting logs');
225
+ // restore original user logger
226
+ if (this.#userLoggerWithOverridenMethods) {
227
+ for (const method of LOG_METHODS) {
228
+ this.#userLoggerWithOverridenMethods[method] = this.#originalUserLogger[method];
229
+ }
230
+ }
231
+ }
232
+ /**
233
+ * Allows to configure logger. Make sure you do it before the logger usage in your code.
234
+ *
235
+ * @param {Object} [config={}] - The configuration object.
236
+ * @param {string} [config.logLevel] - The desired log level. Valid values are 'DEBUG', 'INFO', 'WARN', and 'ERROR'.
237
+ * @param {boolean} [config.prettyObjects] - Specifies whether to enable pretty printing of objects.
238
+ * @returns {void}
239
+ */
240
+ configure(config = {}) {
241
+ if (!config)
242
+ return;
243
+ if (config.prettyObjects === false || config.prettyObjects === true)
244
+ this.prettyObjects = config.prettyObjects;
245
+ if (config.logLevel)
246
+ this.logLevel = config.logLevel.toUpperCase();
247
247
  }
248
- }
249
-
250
- /**
251
- * Allows to configure logger. Make sure you do it before the logger usage in your code.
252
- *
253
- * @param {Object} [config={}] - The configuration object.
254
- * @param {string} [config.logLevel] - The desired log level. Valid values are 'DEBUG', 'INFO', 'WARN', and 'ERROR'.
255
- * @param {boolean} [config.prettyObjects] - Specifies whether to enable pretty printing of objects.
256
- * @returns {void}
257
- */
258
- configure(config = {}) {
259
- if (!config) return;
260
- if (config.prettyObjects === false || config.prettyObjects === true) this.prettyObjects = config.prettyObjects;
261
- if (config.logLevel) this.logLevel = config.logLevel.toUpperCase();
262
- }
263
248
  }
264
-
265
- module.exports.logger = Logger.getInstance();
266
-
249
+ exports.logger = Logger.getInstance();
267
250
  // TODO: parse passed arguments as {level: 'str', message: 'str'} because some loggers use such syntax;
268
251
  // upd: did not face such loggers, but still could be useful
269
-
270
252
  /* Cypress
271
253
  There is no listener like "after:test" in cypress, only "after:spec" is available.
272
254
  Thus, cannot separate logs even when I gather them (because I don't know when the test is done, just know about suite).
@@ -306,6 +288,5 @@ Finally, in the test it will look like:
306
288
 
307
289
  Parallelization in Cypress is only available if using Cypress Dashboard??
308
290
  */
309
-
310
291
  // TODO: add time to logs
311
292
  // TODO: add logger name to logs?