@testomatio/reporter 2.3.6 → 2.3.7-beta.-stack-artifacts
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/lib/bin/cli.js +0 -0
- package/lib/bin/reportXml.js +0 -0
- package/lib/bin/startTest.js +0 -0
- package/lib/bin/uploadArtifacts.js +0 -0
- package/lib/client.js +27 -18
- package/lib/reporter.d.ts +19 -9
- package/lib/reporter.js +40 -5
- package/package.json +1 -1
- package/src/client.js +52 -24
- package/src/reporter.js +7 -4
package/lib/bin/cli.js
CHANGED
|
File without changes
|
package/lib/bin/reportXml.js
CHANGED
|
File without changes
|
package/lib/bin/startTest.js
CHANGED
|
File without changes
|
|
File without changes
|
package/lib/client.js
CHANGED
|
@@ -51,7 +51,9 @@ const node_url_1 = require("node:url");
|
|
|
51
51
|
const uploader_js_1 = require("./uploader.js");
|
|
52
52
|
const utils_js_1 = require("./utils/utils.js");
|
|
53
53
|
const filesize_1 = require("filesize");
|
|
54
|
+
const util_1 = require("util");
|
|
54
55
|
const debug = (0, debug_1.default)('@testomatio/reporter:client');
|
|
56
|
+
const stripColors = util_1.stripVTControlCharacters || ((str) => str?.replace(/\x1b\[[0-9;]*m/g, '') || '');
|
|
55
57
|
// removed __dirname usage, because:
|
|
56
58
|
// 1. replaced with ESM syntax (import.meta.url), but it throws an error on tsc compilation;
|
|
57
59
|
// 2. got error "__dirname already defined" in compiles js code (cjs dir)
|
|
@@ -158,17 +160,6 @@ class Client {
|
|
|
158
160
|
* @returns {Promise<PipeResult[]>}
|
|
159
161
|
*/
|
|
160
162
|
async addTestRun(status, testData) {
|
|
161
|
-
if (!this.pipes || !this.pipes.length)
|
|
162
|
-
this.pipes = await (0, index_js_1.pipesFactory)(this.paramsForPipesFactory || {}, this.pipeStore);
|
|
163
|
-
// all pipes disabled, skipping
|
|
164
|
-
if (!this.pipes?.filter(p => p.isEnabled).length)
|
|
165
|
-
return [];
|
|
166
|
-
if (isTestShouldBeExculedFromReport(testData))
|
|
167
|
-
return [];
|
|
168
|
-
if (status === constants_js_1.STATUS.SKIPPED && process.env.TESTOMATIO_EXCLUDE_SKIPPED) {
|
|
169
|
-
debug('Skipping test from report', testData?.title);
|
|
170
|
-
return []; // do not log skipped tests
|
|
171
|
-
}
|
|
172
163
|
if (!testData)
|
|
173
164
|
testData = {
|
|
174
165
|
title: 'Unknown test',
|
|
@@ -181,9 +172,12 @@ class Client {
|
|
|
181
172
|
/**
|
|
182
173
|
* @type {TestData}
|
|
183
174
|
*/
|
|
184
|
-
const { rid, error = null,
|
|
175
|
+
const { rid, error = null, steps: originalSteps, title, suite_title, } = testData;
|
|
176
|
+
const steps = originalSteps;
|
|
177
|
+
const uploadedFiles = [];
|
|
178
|
+
const stackArtifactsEnabled = (0, utils_js_1.transformEnvVarToBoolean)(process.env.TESTOMATIO_STACK_ARTIFACTS);
|
|
179
|
+
const { time = 0, example = null, files = [], filesBuffers = [], code = null, file, suite_id, test_id, timestamp, links, manuallyAttachedArtifacts, overwrite, tags, } = testData;
|
|
185
180
|
let { message = '', meta = {} } = testData;
|
|
186
|
-
// stringify meta values and limit keys and values length to 255
|
|
187
181
|
meta = Object.entries(meta)
|
|
188
182
|
.filter(([, value]) => value !== null && value !== undefined)
|
|
189
183
|
.reduce((acc, [key, value]) => {
|
|
@@ -191,19 +185,34 @@ class Client {
|
|
|
191
185
|
acc[key] = value;
|
|
192
186
|
return acc;
|
|
193
187
|
}, {});
|
|
194
|
-
// Get links from storage using the test context
|
|
195
188
|
const testContext = suite_title ? `${suite_title} ${title}` : title;
|
|
196
189
|
let errorFormatted = '';
|
|
197
190
|
if (error) {
|
|
198
191
|
errorFormatted += this.formatError(error) || '';
|
|
199
192
|
message = error?.message;
|
|
200
193
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
194
|
+
let fullLogs = this.formatLogs({ error: errorFormatted, steps, logs: testData.logs });
|
|
195
|
+
if (stackArtifactsEnabled) {
|
|
196
|
+
const timestamp = +new Date;
|
|
197
|
+
uploadedFiles.push(this.uploader.uploadFileAsBuffer(Buffer.from(stripColors(fullLogs), 'utf8'), [this.runId, rid, `logs_${timestamp}.log`]));
|
|
198
|
+
fullLogs = '';
|
|
199
|
+
}
|
|
200
|
+
if (!this.pipes || !this.pipes.length)
|
|
201
|
+
this.pipes = await (0, index_js_1.pipesFactory)(this.paramsForPipesFactory || {}, this.pipeStore);
|
|
202
|
+
if (!this.pipes?.filter(p => p.isEnabled).length) {
|
|
203
|
+
if (uploadedFiles.length > 0) {
|
|
204
|
+
await Promise.all(uploadedFiles);
|
|
205
|
+
}
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
208
|
+
if (isTestShouldBeExculedFromReport(testData))
|
|
209
|
+
return [];
|
|
210
|
+
if (status === constants_js_1.STATUS.SKIPPED && process.env.TESTOMATIO_EXCLUDE_SKIPPED) {
|
|
211
|
+
debug('Skipping test from report', testData?.title);
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
204
214
|
if (manuallyAttachedArtifacts?.length)
|
|
205
215
|
files.push(...manuallyAttachedArtifacts);
|
|
206
|
-
const uploadedFiles = [];
|
|
207
216
|
for (let f of files) {
|
|
208
217
|
if (!f)
|
|
209
218
|
continue; // f === null
|
package/lib/reporter.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export { Client };
|
|
2
|
+
export const STATUS: {
|
|
3
|
+
PASSED: string;
|
|
4
|
+
FAILED: string;
|
|
5
|
+
SKIPPED: string;
|
|
6
|
+
FINISHED: string;
|
|
7
|
+
};
|
|
1
8
|
export const artifact: (data: string | {
|
|
2
9
|
path: string;
|
|
3
10
|
type: string;
|
|
@@ -80,7 +87,7 @@ export const label: (key: string, value?: string | null) => void;
|
|
|
80
87
|
export const linkTest: (...testIds: string[]) => void;
|
|
81
88
|
export const linkJira: (...jiraIds: string[]) => void;
|
|
82
89
|
declare namespace _default {
|
|
83
|
-
let testomatioLogger: {
|
|
90
|
+
export let testomatioLogger: {
|
|
84
91
|
"__#13@#originalUserLogger": {
|
|
85
92
|
assert(condition?: boolean, ...data: any[]): void;
|
|
86
93
|
assert(value: any, message?: string, ...optionalParams: any[]): void;
|
|
@@ -148,13 +155,13 @@ declare namespace _default {
|
|
|
148
155
|
}): void;
|
|
149
156
|
prettyObjects: boolean;
|
|
150
157
|
};
|
|
151
|
-
let artifact: (data: string | {
|
|
158
|
+
export let artifact: (data: string | {
|
|
152
159
|
path: string;
|
|
153
160
|
type: string;
|
|
154
161
|
name: string;
|
|
155
162
|
}, context?: any) => void;
|
|
156
|
-
let log: (...args: any[]) => void;
|
|
157
|
-
let logger: {
|
|
163
|
+
export let log: (...args: any[]) => void;
|
|
164
|
+
export let logger: {
|
|
158
165
|
"__#13@#originalUserLogger": {
|
|
159
166
|
assert(condition?: boolean, ...data: any[]): void;
|
|
160
167
|
assert(value: any, message?: string, ...optionalParams: any[]): void;
|
|
@@ -222,13 +229,15 @@ declare namespace _default {
|
|
|
222
229
|
}): void;
|
|
223
230
|
prettyObjects: boolean;
|
|
224
231
|
};
|
|
225
|
-
let meta: (keyValue: {
|
|
232
|
+
export let meta: (keyValue: {
|
|
226
233
|
[key: string]: string;
|
|
227
234
|
} | string, value?: string | null) => void;
|
|
228
|
-
let step: (message: string) => void;
|
|
229
|
-
let label: (key: string, value?: string | null) => void;
|
|
230
|
-
let linkTest: (...testIds: string[]) => void;
|
|
231
|
-
let linkJira: (...jiraIds: string[]) => void;
|
|
235
|
+
export let step: (message: string) => void;
|
|
236
|
+
export let label: (key: string, value?: string | null) => void;
|
|
237
|
+
export let linkTest: (...testIds: string[]) => void;
|
|
238
|
+
export let linkJira: (...jiraIds: string[]) => void;
|
|
239
|
+
export { Client as TestomatioClient };
|
|
240
|
+
export { STATUS };
|
|
232
241
|
}
|
|
233
242
|
export default _default;
|
|
234
243
|
export type ArtifactFunction = typeof import("./reporter-functions.js").default.artifact;
|
|
@@ -237,3 +246,4 @@ export type LoggerService = typeof import("./services/index.js").services.logger
|
|
|
237
246
|
export type MetaFunction = typeof import("./reporter-functions.js").default.keyValue;
|
|
238
247
|
export type StepFunction = typeof import("./reporter-functions.js").default.step;
|
|
239
248
|
export type LabelFunction = typeof import("./reporter-functions.js").default.label;
|
|
249
|
+
import Client from './client.js';
|
package/lib/reporter.js
CHANGED
|
@@ -1,13 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
5
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.linkJira = exports.linkTest = exports.label = exports.step = exports.meta = exports.logger = exports.log = exports.artifact = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
39
|
+
exports.linkJira = exports.linkTest = exports.label = exports.step = exports.meta = exports.logger = exports.log = exports.artifact = exports.STATUS = exports.Client = void 0;
|
|
40
|
+
const client_js_1 = __importDefault(require("./client.js"));
|
|
41
|
+
exports.Client = client_js_1.default;
|
|
42
|
+
const TestomatioConstants = __importStar(require("./constants.js"));
|
|
9
43
|
const index_js_1 = require("./services/index.js");
|
|
10
44
|
const reporter_functions_js_1 = __importDefault(require("./reporter-functions.js"));
|
|
45
|
+
exports.STATUS = TestomatioConstants.STATUS;
|
|
11
46
|
exports.artifact = reporter_functions_js_1.default.artifact;
|
|
12
47
|
exports.log = reporter_functions_js_1.default.log;
|
|
13
48
|
exports.logger = index_js_1.services.logger;
|
|
@@ -37,6 +72,6 @@ module.exports = {
|
|
|
37
72
|
label: reporter_functions_js_1.default.label,
|
|
38
73
|
linkTest: reporter_functions_js_1.default.linkTest,
|
|
39
74
|
linkJira: reporter_functions_js_1.default.linkJira,
|
|
40
|
-
|
|
41
|
-
|
|
75
|
+
TestomatioClient: client_js_1.default,
|
|
76
|
+
STATUS: exports.STATUS,
|
|
42
77
|
};
|
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -10,11 +10,21 @@ import { glob } from 'glob';
|
|
|
10
10
|
import path, { sep } from 'path';
|
|
11
11
|
import { fileURLToPath } from 'node:url';
|
|
12
12
|
import { S3Uploader } from './uploader.js';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
formatStep,
|
|
15
|
+
truncate,
|
|
16
|
+
readLatestRunId,
|
|
17
|
+
storeRunId,
|
|
18
|
+
validateSuiteId,
|
|
19
|
+
transformEnvVarToBoolean
|
|
20
|
+
} from './utils/utils.js';
|
|
14
21
|
import { filesize as prettyBytes } from 'filesize';
|
|
22
|
+
import { stripVTControlCharacters } from 'util';
|
|
15
23
|
|
|
16
24
|
const debug = createDebugMessages('@testomatio/reporter:client');
|
|
17
25
|
|
|
26
|
+
const stripColors = stripVTControlCharacters || ((str) => str?.replace(/\x1b\[[0-9;]*m/g, '') || '');
|
|
27
|
+
|
|
18
28
|
// removed __dirname usage, because:
|
|
19
29
|
// 1. replaced with ESM syntax (import.meta.url), but it throws an error on tsc compilation;
|
|
20
30
|
// 2. got error "__dirname already defined" in compiles js code (cjs dir)
|
|
@@ -139,19 +149,6 @@ class Client {
|
|
|
139
149
|
* @returns {Promise<PipeResult[]>}
|
|
140
150
|
*/
|
|
141
151
|
async addTestRun(status, testData) {
|
|
142
|
-
if (!this.pipes || !this.pipes.length)
|
|
143
|
-
this.pipes = await pipesFactory(this.paramsForPipesFactory || {}, this.pipeStore);
|
|
144
|
-
|
|
145
|
-
// all pipes disabled, skipping
|
|
146
|
-
if (!this.pipes?.filter(p => p.isEnabled).length) return [];
|
|
147
|
-
|
|
148
|
-
if (isTestShouldBeExculedFromReport(testData)) return [];
|
|
149
|
-
|
|
150
|
-
if (status === STATUS.SKIPPED && process.env.TESTOMATIO_EXCLUDE_SKIPPED) {
|
|
151
|
-
debug('Skipping test from report', testData?.title);
|
|
152
|
-
return []; // do not log skipped tests
|
|
153
|
-
}
|
|
154
|
-
|
|
155
152
|
if (!testData)
|
|
156
153
|
testData = {
|
|
157
154
|
title: 'Unknown test',
|
|
@@ -169,15 +166,23 @@ class Client {
|
|
|
169
166
|
const {
|
|
170
167
|
rid,
|
|
171
168
|
error = null,
|
|
169
|
+
steps: originalSteps,
|
|
170
|
+
title,
|
|
171
|
+
suite_title,
|
|
172
|
+
} = testData;
|
|
173
|
+
const steps = originalSteps;
|
|
174
|
+
|
|
175
|
+
const uploadedFiles = [];
|
|
176
|
+
const stackArtifactsEnabled = transformEnvVarToBoolean(process.env.TESTOMATIO_STACK_ARTIFACTS);
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
const {
|
|
172
180
|
time = 0,
|
|
173
181
|
example = null,
|
|
174
182
|
files = [],
|
|
175
183
|
filesBuffers = [],
|
|
176
|
-
steps,
|
|
177
184
|
code = null,
|
|
178
|
-
title,
|
|
179
185
|
file,
|
|
180
|
-
suite_title,
|
|
181
186
|
suite_id,
|
|
182
187
|
test_id,
|
|
183
188
|
timestamp,
|
|
@@ -188,7 +193,6 @@ class Client {
|
|
|
188
193
|
} = testData;
|
|
189
194
|
let { message = '', meta = {} } = testData;
|
|
190
195
|
|
|
191
|
-
// stringify meta values and limit keys and values length to 255
|
|
192
196
|
meta = Object.entries(meta)
|
|
193
197
|
.filter(([, value]) => value !== null && value !== undefined)
|
|
194
198
|
.reduce((acc, [key, value]) => {
|
|
@@ -196,7 +200,6 @@ class Client {
|
|
|
196
200
|
return acc;
|
|
197
201
|
}, {});
|
|
198
202
|
|
|
199
|
-
// Get links from storage using the test context
|
|
200
203
|
const testContext = suite_title ? `${suite_title} ${title}` : title;
|
|
201
204
|
|
|
202
205
|
let errorFormatted = '';
|
|
@@ -205,13 +208,38 @@ class Client {
|
|
|
205
208
|
message = error?.message;
|
|
206
209
|
}
|
|
207
210
|
|
|
208
|
-
|
|
209
|
-
const fullLogs = this.formatLogs({ error: errorFormatted, steps, logs: testData.logs });
|
|
211
|
+
let fullLogs = this.formatLogs({ error: errorFormatted, steps, logs: testData.logs });
|
|
210
212
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
+
if (stackArtifactsEnabled) {
|
|
214
|
+
const timestamp = +new Date;
|
|
215
|
+
uploadedFiles.push(
|
|
216
|
+
this.uploader.uploadFileAsBuffer(
|
|
217
|
+
Buffer.from(stripColors(fullLogs), 'utf8'),
|
|
218
|
+
[this.runId, rid, `logs_${timestamp}.log`]
|
|
219
|
+
)
|
|
220
|
+
);
|
|
221
|
+
fullLogs = '';
|
|
222
|
+
}
|
|
213
223
|
|
|
214
|
-
|
|
224
|
+
|
|
225
|
+
if (!this.pipes || !this.pipes.length)
|
|
226
|
+
this.pipes = await pipesFactory(this.paramsForPipesFactory || {}, this.pipeStore);
|
|
227
|
+
|
|
228
|
+
if (!this.pipes?.filter(p => p.isEnabled).length) {
|
|
229
|
+
if (uploadedFiles.length > 0) {
|
|
230
|
+
await Promise.all(uploadedFiles);
|
|
231
|
+
}
|
|
232
|
+
return [];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (isTestShouldBeExculedFromReport(testData)) return [];
|
|
236
|
+
|
|
237
|
+
if (status === STATUS.SKIPPED && process.env.TESTOMATIO_EXCLUDE_SKIPPED) {
|
|
238
|
+
debug('Skipping test from report', testData?.title);
|
|
239
|
+
return [];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (manuallyAttachedArtifacts?.length) files.push(...manuallyAttachedArtifacts);
|
|
215
243
|
|
|
216
244
|
for (let f of files) {
|
|
217
245
|
if (!f) continue; // f === null
|
package/src/reporter.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import Client from './client.js';
|
|
2
|
+
import * as TestomatioConstants from './constants.js';
|
|
3
3
|
import { services } from './services/index.js';
|
|
4
4
|
import reporterFunctions from './reporter-functions.js';
|
|
5
5
|
|
|
6
|
+
export { Client };
|
|
7
|
+
export const STATUS = TestomatioConstants.STATUS;
|
|
6
8
|
export const artifact = reporterFunctions.artifact;
|
|
7
9
|
export const log = reporterFunctions.log;
|
|
8
10
|
export const logger = services.logger;
|
|
@@ -35,6 +37,7 @@ export default {
|
|
|
35
37
|
linkTest: reporterFunctions.linkTest,
|
|
36
38
|
linkJira: reporterFunctions.linkJira,
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
TestomatioClient: Client,
|
|
41
|
+
STATUS,
|
|
42
|
+
|
|
40
43
|
};
|