@testomatio/reporter 2.4.0 → 2.5.0

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.
@@ -28,9 +28,15 @@ declare function logMessage(...args: any[]): void;
28
28
  /**
29
29
  * Similar to "log" function but marks message in report as a step
30
30
  * @param {string} message - step message
31
+ * @param {{[key: string]: any}} [logs] optional key-value object with additional info, e.g. logs
31
32
  * @returns {void}
33
+ *
34
+ * Example:
35
+ * step('Get response', { logs: {status: 'success'} });
32
36
  */
33
- declare function addStep(message: string): void;
37
+ declare function addStep(message: string, logs?: {
38
+ [key: string]: any;
39
+ }): void;
34
40
  /**
35
41
  * Add key-value pair(s) to the test report
36
42
  * @param {{[key: string]: string} | string} keyValue - object { key: value } (multiple props allowed) or key (string)
@@ -25,14 +25,20 @@ function logMessage(...args) {
25
25
  /**
26
26
  * Similar to "log" function but marks message in report as a step
27
27
  * @param {string} message - step message
28
+ * @param {{[key: string]: any}} [logs] optional key-value object with additional info, e.g. logs
28
29
  * @returns {void}
30
+ *
31
+ * Example:
32
+ * step('Get response', { logs: {status: 'success'} });
29
33
  */
30
- function addStep(message) {
31
- index_js_1.services.logger.step(message);
34
+ function addStep(message, logs) {
32
35
  // this is done because Playwright reporter intercepts console logs and then we gather them and show on Testomat
33
36
  // if not console.log, the step message will be lost from reporter
34
37
  if (helpers_js_1.isPlaywright)
35
- console.log(`Step: ${message}`);
38
+ index_js_1.services.logger._templateLiteralLog(message, logs);
39
+ // all other frameworks
40
+ else
41
+ index_js_1.services.logger.step(message, logs);
36
42
  }
37
43
  /**
38
44
  * Add key-value pair(s) to the test report
package/lib/reporter.d.ts CHANGED
@@ -62,6 +62,7 @@ export const logger: {
62
62
  step(strings: any, ...values: any[]): void;
63
63
  getLogs(context: string): string[];
64
64
  "__#14@#stringifyLogs"(...args: any[]): string;
65
+ "__#14@#formatMessage"(strings: any, ...args: any[]): string;
65
66
  _templateLiteralLog(strings: any, ...args: any[]): void;
66
67
  "__#14@#logWrapper"(argsArray: any, level: any): void;
67
68
  assert(...args: any[]): void;
@@ -82,7 +83,9 @@ export const logger: {
82
83
  export const meta: (keyValue: {
83
84
  [key: string]: string;
84
85
  } | string, value?: string | null) => void;
85
- export const step: (message: string) => void;
86
+ export const step: (message: string, logs?: {
87
+ [key: string]: any;
88
+ }) => void;
86
89
  export const label: (key: string, value?: string | null) => void;
87
90
  export const linkTest: (...testIds: string[]) => void;
88
91
  export const linkJira: (...jiraIds: string[]) => void;
@@ -138,6 +141,7 @@ declare namespace _default {
138
141
  step(strings: any, ...values: any[]): void;
139
142
  getLogs(context: string): string[];
140
143
  "__#14@#stringifyLogs"(...args: any[]): string;
144
+ "__#14@#formatMessage"(strings: any, ...args: any[]): string;
141
145
  _templateLiteralLog(strings: any, ...args: any[]): void;
142
146
  "__#14@#logWrapper"(argsArray: any, level: any): void;
143
147
  assert(...args: any[]): void;
@@ -212,6 +216,7 @@ declare namespace _default {
212
216
  step(strings: any, ...values: any[]): void;
213
217
  getLogs(context: string): string[];
214
218
  "__#14@#stringifyLogs"(...args: any[]): string;
219
+ "__#14@#formatMessage"(strings: any, ...args: any[]): string;
215
220
  _templateLiteralLog(strings: any, ...args: any[]): void;
216
221
  "__#14@#logWrapper"(argsArray: any, level: any): void;
217
222
  assert(...args: any[]): void;
@@ -232,7 +237,9 @@ declare namespace _default {
232
237
  export let meta: (keyValue: {
233
238
  [key: string]: string;
234
239
  } | string, value?: string | null) => void;
235
- export let step: (message: string) => void;
240
+ export let step: (message: string, logs?: {
241
+ [key: string]: any;
242
+ }) => void;
236
243
  export let label: (key: string, value?: string | null) => void;
237
244
  export let linkTest: (...testIds: string[]) => void;
238
245
  export let linkJira: (...jiraIds: string[]) => void;
@@ -26,8 +26,8 @@ declare class Logger {
26
26
  */
27
27
  getLogs(context: string): string[];
28
28
  /**
29
- * Tagget template literal. Allows to use different syntaxes:
30
- * 1. Tagget template: log`text ${someVar}`
29
+ * Tagged template literal. Allows to use different syntaxes:
30
+ * 1. Tagged template: log`text ${someVar}`
31
31
  * 2. Standard: log(`text ${someVar}`)
32
32
  * 3. Standard with multiple arguments: log('text', someVar)
33
33
  */
@@ -54,14 +54,10 @@ class Logger {
54
54
  * @param {...any} values
55
55
  */
56
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}`);
57
+ // Filter trailing undefined from optional params (e.g., step('message') called without second arg)
58
+ const filteredValues = values.filter(v => v !== undefined);
59
+ const message = this.#formatMessage(strings, ...filteredValues);
60
+ const logs = picocolors_1.default.blue(`> ${message}`);
65
61
  data_storage_js_1.dataStorage.putData('log', logs);
66
62
  }
67
63
  /**
@@ -82,7 +78,13 @@ class Logger {
82
78
  // ignore empty strings
83
79
  if (arg === '')
84
80
  continue;
85
- if (typeof arg === 'string') {
81
+ if (arg === undefined) {
82
+ logs.push('undefined');
83
+ }
84
+ else if (arg === null) {
85
+ logs.push('null');
86
+ }
87
+ else if (typeof arg === 'string') {
86
88
  logs.push(arg);
87
89
  }
88
90
  else if (Array.isArray(arg)) {
@@ -101,36 +103,37 @@ class Logger {
101
103
  return logs.join(' ');
102
104
  }
103
105
  /**
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)
106
+ * Formats a message from either tagged template literal or standard function call.
107
+ * @param {*} strings - Template strings array or first argument
108
+ * @param {...any} args - Template values or additional arguments
109
+ * @returns {string} Formatted message
108
110
  */
109
- _templateLiteralLog(strings, ...args) {
110
- if (Array.isArray(strings))
111
- strings = strings.filter(item => item !== '').map(item => item.trim());
111
+ #formatMessage(strings, ...args) {
112
112
  if (Array.isArray(args))
113
113
  args = args.filter(item => item !== '');
114
- let logs;
115
- // this block means tagged template is used (syntax like $`text ${someVar}`)
114
+ // Tagged template syntax: func`text ${someVar}`
116
115
  if (Array.isArray(strings) && strings.length === args.length + 1) {
117
- logs = strings.reduce((result, current, index) => result +
116
+ return strings.reduce((result, current, index) => result +
118
117
  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);
118
+ (index < args.length
119
+ ? args[index] === undefined
120
+ ? 'undefined'
121
+ : typeof args[index] === 'string'
122
+ ? args[index]
123
+ : this.#stringifyLogs(args[index])
124
+ : ''), '');
133
125
  }
126
+ // Standard function call: func('text', someVar)
127
+ return this.#stringifyLogs(strings, ...args);
128
+ }
129
+ /**
130
+ * Tagged template literal. Allows to use different syntaxes:
131
+ * 1. Tagged template: log`text ${someVar}`
132
+ * 2. Standard: log(`text ${someVar}`)
133
+ * 3. Standard with multiple arguments: log('text', someVar)
134
+ */
135
+ _templateLiteralLog(strings, ...args) {
136
+ const logs = this.#formatMessage(strings, ...args);
134
137
  this.#originalUserLogger.log(logs);
135
138
  data_storage_js_1.dataStorage.putData('log', logs);
136
139
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testomatio/reporter",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Testomatio Reporter Client",
5
5
  "engines": {
6
6
  "node": ">=18"
@@ -25,13 +25,18 @@ function logMessage(...args) {
25
25
  /**
26
26
  * Similar to "log" function but marks message in report as a step
27
27
  * @param {string} message - step message
28
+ * @param {{[key: string]: any}} [logs] optional key-value object with additional info, e.g. logs
28
29
  * @returns {void}
30
+ *
31
+ * Example:
32
+ * step('Get response', { logs: {status: 'success'} });
29
33
  */
30
- function addStep(message) {
31
- services.logger.step(message);
34
+ function addStep(message, logs) {
32
35
  // this is done because Playwright reporter intercepts console logs and then we gather them and show on Testomat
33
36
  // if not console.log, the step message will be lost from reporter
34
- if (isPlaywright) console.log(`Step: ${message}`);
37
+ if (isPlaywright) services.logger._templateLiteralLog(message, logs);
38
+ // all other frameworks
39
+ else services.logger.step(message, logs);
35
40
  }
36
41
 
37
42
  /**
@@ -59,14 +59,10 @@ class Logger {
59
59
  * @param {...any} values
60
60
  */
61
61
  step(strings, ...values) {
62
- let logs = '';
63
- for (let i = 0; i < strings.length; i++) {
64
- logs += strings[i];
65
- if (i < values.length) {
66
- logs += values[i];
67
- }
68
- }
69
- logs = pc.blue(`> ${logs}`);
62
+ // Filter trailing undefined from optional params (e.g., step('message') called without second arg)
63
+ const filteredValues = values.filter(v => v !== undefined);
64
+ const message = this.#formatMessage(strings, ...filteredValues);
65
+ const logs = pc.blue(`> ${message}`);
70
66
  dataStorage.putData('log', logs);
71
67
  }
72
68
 
@@ -87,7 +83,11 @@ class Logger {
87
83
  for (const arg of args) {
88
84
  // ignore empty strings
89
85
  if (arg === '') continue;
90
- if (typeof arg === 'string') {
86
+ if (arg === undefined) {
87
+ logs.push('undefined');
88
+ } else if (arg === null) {
89
+ logs.push('null');
90
+ } else if (typeof arg === 'string') {
91
91
  logs.push(arg);
92
92
  } else if (Array.isArray(arg)) {
93
93
  logs.push(arg.join(' '));
@@ -104,37 +104,42 @@ class Logger {
104
104
  }
105
105
 
106
106
  /**
107
- * Tagget template literal. Allows to use different syntaxes:
108
- * 1. Tagget template: log`text ${someVar}`
109
- * 2. Standard: log(`text ${someVar}`)
110
- * 3. Standard with multiple arguments: log('text', someVar)
107
+ * Formats a message from either tagged template literal or standard function call.
108
+ * @param {*} strings - Template strings array or first argument
109
+ * @param {...any} args - Template values or additional arguments
110
+ * @returns {string} Formatted message
111
111
  */
112
- _templateLiteralLog(strings, ...args) {
113
- if (Array.isArray(strings)) strings = strings.filter(item => item !== '').map(item => item.trim());
112
+ #formatMessage(strings, ...args) {
114
113
  if (Array.isArray(args)) args = args.filter(item => item !== '');
115
114
 
116
- let logs;
117
- // this block means tagged template is used (syntax like $`text ${someVar}`)
115
+ // Tagged template syntax: func`text ${someVar}`
118
116
  if (Array.isArray(strings) && strings.length === args.length + 1) {
119
- logs = strings.reduce(
117
+ return strings.reduce(
120
118
  (result, current, index) =>
121
119
  result +
122
120
  current +
123
- // strings are splitted by args when use tagged template, thus we add arg after each string
124
- // it looks like: `string1 arg1 string2 arg2 string3`
125
- (args[index] !== undefined
126
- ? typeof args[index] === 'string'
127
- ? args[index] // add arg as it is
128
- : this.#stringifyLogs(args[index]) // stringify arg
121
+ (index < args.length
122
+ ? args[index] === undefined
123
+ ? 'undefined'
124
+ : typeof args[index] === 'string'
125
+ ? args[index]
126
+ : this.#stringifyLogs(args[index])
129
127
  : ''),
130
- // initial accumulator value
131
128
  '',
132
129
  );
133
- } else {
134
- // this block means arguments syntax is used (syntax like $('text', someVar))
135
- // in this case strings represents just a first argument
136
- logs = this.#stringifyLogs(strings, ...args);
137
130
  }
131
+ // Standard function call: func('text', someVar)
132
+ return this.#stringifyLogs(strings, ...args);
133
+ }
134
+
135
+ /**
136
+ * Tagged template literal. Allows to use different syntaxes:
137
+ * 1. Tagged template: log`text ${someVar}`
138
+ * 2. Standard: log(`text ${someVar}`)
139
+ * 3. Standard with multiple arguments: log('text', someVar)
140
+ */
141
+ _templateLiteralLog(strings, ...args) {
142
+ const logs = this.#formatMessage(strings, ...args);
138
143
  this.#originalUserLogger.log(logs);
139
144
  dataStorage.putData('log', logs);
140
145
  }
package/types/types.d.ts CHANGED
@@ -15,8 +15,9 @@ declare module '@testomatio/reporter' {
15
15
  /**
16
16
  * Similar to "log" function but marks message in report as a step
17
17
  * @param message - step message
18
+ * @param logs - optional key-value object with additional info (e.g. logs)
18
19
  */
19
- export function step(message: string): void;
20
+ export function step(message: string, logs?: {[key: string]: any}): void;
20
21
 
21
22
  /**
22
23
  * Add key-value pair(s) to the test report