@tiden/reporter-commons 0.1.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.
- package/CHANGELOG.md +25 -0
- package/LICENSE +201 -0
- package/README.md +34 -0
- package/dist/client/interface.d.ts +8 -0
- package/dist/client/interface.js +2 -0
- package/dist/client/reporter-api-models.d.ts +96 -0
- package/dist/client/reporter-api-models.js +2 -0
- package/dist/client/reporter-api.d.ts +14 -0
- package/dist/client/reporter-api.js +25 -0
- package/dist/client/services/api-error-handler.d.ts +10 -0
- package/dist/client/services/api-error-handler.js +44 -0
- package/dist/client/services/attachment-service.d.ts +29 -0
- package/dist/client/services/attachment-service.js +268 -0
- package/dist/client/services/result-transformer.d.ts +21 -0
- package/dist/client/services/result-transformer.js +180 -0
- package/dist/client/services/run-service.d.ts +20 -0
- package/dist/client/services/run-service.js +68 -0
- package/dist/client/tiden-client.d.ts +34 -0
- package/dist/client/tiden-client.js +99 -0
- package/dist/client/tiden-http.d.ts +11 -0
- package/dist/client/tiden-http.js +23 -0
- package/dist/config/config-loader-interface.d.ts +4 -0
- package/dist/config/config-loader-interface.js +2 -0
- package/dist/config/config-loader.d.ts +10 -0
- package/dist/config/config-loader.js +60 -0
- package/dist/config/config-type.d.ts +2 -0
- package/dist/config/config-type.js +2 -0
- package/dist/config/config-validation-schema.d.ts +212 -0
- package/dist/config/config-validation-schema.js +213 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.js +7 -0
- package/dist/core/options-resolver.d.ts +19 -0
- package/dist/core/options-resolver.js +47 -0
- package/dist/core/reporter-factory.d.ts +18 -0
- package/dist/core/reporter-factory.js +63 -0
- package/dist/core/status-processor.d.ts +17 -0
- package/dist/core/status-processor.js +48 -0
- package/dist/env/env-enum.d.ts +64 -0
- package/dist/env/env-enum.js +75 -0
- package/dist/env/env-to-config.d.ts +7 -0
- package/dist/env/env-to-config.js +60 -0
- package/dist/env/env-type.d.ts +29 -0
- package/dist/env/env-type.js +3 -0
- package/dist/env/env-validation-schema.d.ts +6 -0
- package/dist/env/env-validation-schema.js +113 -0
- package/dist/env/index.d.ts +4 -0
- package/dist/env/index.js +13 -0
- package/dist/formatter/formatter-interface.d.ts +3 -0
- package/dist/formatter/formatter-interface.js +2 -0
- package/dist/formatter/index.d.ts +4 -0
- package/dist/formatter/index.js +9 -0
- package/dist/formatter/json-formatter.d.ts +13 -0
- package/dist/formatter/json-formatter.js +28 -0
- package/dist/formatter/jsonp-formatter.d.ts +13 -0
- package/dist/formatter/jsonp-formatter.js +29 -0
- package/dist/formatter/report-serializer.d.ts +20 -0
- package/dist/formatter/report-serializer.js +92 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +30 -0
- package/dist/internal/filter-positive-ids.d.ts +17 -0
- package/dist/internal/filter-positive-ids.js +38 -0
- package/dist/internal/ids-parser.d.ts +9 -0
- package/dist/internal/ids-parser.js +21 -0
- package/dist/internal/index.d.ts +8 -0
- package/dist/internal/index.js +15 -0
- package/dist/internal/step-parser.d.ts +11 -0
- package/dist/internal/step-parser.js +28 -0
- package/dist/internal/suite-file.d.ts +13 -0
- package/dist/internal/suite-file.js +16 -0
- package/dist/internal/suite-normalizer.d.ts +6 -0
- package/dist/internal/suite-normalizer.js +11 -0
- package/dist/internal/title.d.ts +5 -0
- package/dist/internal/title.js +15 -0
- package/dist/models/attachment.d.ts +8 -0
- package/dist/models/attachment.js +2 -0
- package/dist/models/config/TidenOptionsType.d.ts +33 -0
- package/dist/models/config/TidenOptionsType.js +2 -0
- package/dist/models/configuration.d.ts +12 -0
- package/dist/models/configuration.js +2 -0
- package/dist/models/error.d.ts +7 -0
- package/dist/models/error.js +24 -0
- package/dist/models/execution-sum.d.ts +6 -0
- package/dist/models/execution-sum.js +2 -0
- package/dist/models/host-data.d.ts +12 -0
- package/dist/models/host-data.js +2 -0
- package/dist/models/index.d.ts +11 -0
- package/dist/models/index.js +15 -0
- package/dist/models/report.d.ts +14 -0
- package/dist/models/report.js +2 -0
- package/dist/models/short-result.d.ts +7 -0
- package/dist/models/short-result.js +2 -0
- package/dist/models/stats.d.ts +9 -0
- package/dist/models/stats.js +2 -0
- package/dist/models/step-data.d.ts +19 -0
- package/dist/models/step-data.js +2 -0
- package/dist/models/step-execution.d.ts +13 -0
- package/dist/models/step-execution.js +23 -0
- package/dist/models/test-execution.d.ts +20 -0
- package/dist/models/test-execution.js +32 -0
- package/dist/models/test-result.d.ts +44 -0
- package/dist/models/test-result.js +50 -0
- package/dist/models/test-step.d.ts +18 -0
- package/dist/models/test-step.js +53 -0
- package/dist/options/composeOptions.d.ts +8 -0
- package/dist/options/composeOptions.js +12 -0
- package/dist/options/index.d.ts +3 -0
- package/dist/options/index.js +7 -0
- package/dist/options/mode-enum.d.ts +8 -0
- package/dist/options/mode-enum.js +12 -0
- package/dist/options/options-type.d.ts +38 -0
- package/dist/options/options-type.js +3 -0
- package/dist/profilers/abstract-profiler.d.ts +5 -0
- package/dist/profilers/abstract-profiler.js +6 -0
- package/dist/profilers/fetch-interceptor.d.ts +60 -0
- package/dist/profilers/fetch-interceptor.js +277 -0
- package/dist/profilers/http-interceptor.d.ts +76 -0
- package/dist/profilers/http-interceptor.js +252 -0
- package/dist/profilers/index.d.ts +5 -0
- package/dist/profilers/index.js +11 -0
- package/dist/profilers/network-profiler.d.ts +61 -0
- package/dist/profilers/network-profiler.js +94 -0
- package/dist/reporters/abstract-reporter.d.ts +68 -0
- package/dist/reporters/abstract-reporter.js +78 -0
- package/dist/reporters/index.d.ts +3 -0
- package/dist/reporters/index.js +9 -0
- package/dist/reporters/report-reporter.d.ts +50 -0
- package/dist/reporters/report-reporter.js +167 -0
- package/dist/reporters/run-reporter.d.ts +65 -0
- package/dist/reporters/run-reporter.js +155 -0
- package/dist/reporters/shared/fallback-coordinator.d.ts +47 -0
- package/dist/reporters/shared/fallback-coordinator.js +119 -0
- package/dist/reporters/shared/run-constants.d.ts +11 -0
- package/dist/reporters/shared/run-constants.js +14 -0
- package/dist/state/state.d.ts +16 -0
- package/dist/state/state.js +70 -0
- package/dist/steps/step.d.ts +16 -0
- package/dist/steps/step.js +86 -0
- package/dist/tiden.d.ts +48 -0
- package/dist/tiden.js +223 -0
- package/dist/utils/disabled-exception.d.ts +6 -0
- package/dist/utils/disabled-exception.js +10 -0
- package/dist/utils/get-package-version.d.ts +5 -0
- package/dist/utils/get-package-version.js +25 -0
- package/dist/utils/hostData.d.ts +8 -0
- package/dist/utils/hostData.js +140 -0
- package/dist/utils/is-axios-error.d.ts +6 -0
- package/dist/utils/is-axios-error.js +11 -0
- package/dist/utils/logger.d.ts +33 -0
- package/dist/utils/logger.js +141 -0
- package/dist/utils/mimeTypes.d.ts +5 -0
- package/dist/utils/mimeTypes.js +50 -0
- package/dist/utils/project-mapping-utils.d.ts +17 -0
- package/dist/utils/project-mapping-utils.js +29 -0
- package/dist/utils/signature.d.ts +11 -0
- package/dist/utils/signature.js +34 -0
- package/dist/utils/status-mapping-utils.d.ts +14 -0
- package/dist/utils/status-mapping-utils.js +45 -0
- package/dist/utils/test-status-utils.d.ts +8 -0
- package/dist/utils/test-status-utils.js +152 -0
- package/dist/utils/tiden-error.d.ts +18 -0
- package/dist/utils/tiden-error.js +19 -0
- package/dist/utils/token-masker.d.ts +11 -0
- package/dist/utils/token-masker.js +26 -0
- package/dist/utils/validate-json.d.ts +20 -0
- package/dist/utils/validate-json.js +41 -0
- package/dist/writer/driver-enum.d.ts +13 -0
- package/dist/writer/driver-enum.js +18 -0
- package/dist/writer/fs-writer.d.ts +40 -0
- package/dist/writer/fs-writer.js +139 -0
- package/dist/writer/index.d.ts +3 -0
- package/dist/writer/index.js +8 -0
- package/dist/writer/writer-interface.d.ts +7 -0
- package/dist/writer/writer-interface.js +2 -0
- package/package.json +83 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.determineTestStatus = determineTestStatus;
|
|
4
|
+
const test_execution_1 = require("../models/test-execution");
|
|
5
|
+
/**
|
|
6
|
+
* Determines test status based on error type
|
|
7
|
+
* @param error - Error object or null
|
|
8
|
+
* @param originalStatus - Original test status from test runner
|
|
9
|
+
* @returns TestStatusEnum - failed for assertion errors, invalid for other errors
|
|
10
|
+
*/
|
|
11
|
+
function determineTestStatus(error, originalStatus) {
|
|
12
|
+
// If no error, return the original status
|
|
13
|
+
if (!error) {
|
|
14
|
+
return mapOriginalStatus(originalStatus);
|
|
15
|
+
}
|
|
16
|
+
// When the test runner explicitly reports timeout or interruption,
|
|
17
|
+
// treat as failed regardless of error content.
|
|
18
|
+
// (e.g. Playwright's timedOut/interrupted statuses)
|
|
19
|
+
const normalizedStatus = originalStatus.toLowerCase();
|
|
20
|
+
if (normalizedStatus === 'timedout' || normalizedStatus === 'interrupted') {
|
|
21
|
+
return test_execution_1.TestStatusEnum.failed;
|
|
22
|
+
}
|
|
23
|
+
// Check if it's an assertion error
|
|
24
|
+
if (isAssertionError(error, originalStatus)) {
|
|
25
|
+
return test_execution_1.TestStatusEnum.failed;
|
|
26
|
+
}
|
|
27
|
+
// For all other errors, return invalid
|
|
28
|
+
return test_execution_1.TestStatusEnum.invalid;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Checks if error is an assertion error
|
|
32
|
+
* @param error - Error object
|
|
33
|
+
* @param originalStatus - Original test status from test runner
|
|
34
|
+
* @returns boolean - true if assertion error
|
|
35
|
+
*/
|
|
36
|
+
function isAssertionError(error, originalStatus) {
|
|
37
|
+
const errorMessage = error.message.toLowerCase();
|
|
38
|
+
const errorStack = error.stack?.toLowerCase() || '';
|
|
39
|
+
const normalizedOriginalStatus = originalStatus.toLowerCase();
|
|
40
|
+
// Common assertion error patterns
|
|
41
|
+
const assertionPatterns = [
|
|
42
|
+
'expect',
|
|
43
|
+
'assert',
|
|
44
|
+
'matcher',
|
|
45
|
+
'objectcontaining',
|
|
46
|
+
'assertion',
|
|
47
|
+
'expected',
|
|
48
|
+
'actual',
|
|
49
|
+
'to be',
|
|
50
|
+
'to equal',
|
|
51
|
+
'to contain',
|
|
52
|
+
'to match',
|
|
53
|
+
'to throw',
|
|
54
|
+
'to be called',
|
|
55
|
+
'to have been called',
|
|
56
|
+
'test failed',
|
|
57
|
+
'expectation failed',
|
|
58
|
+
'assertion failed'
|
|
59
|
+
];
|
|
60
|
+
// Non-assertion error patterns that should be invalid
|
|
61
|
+
const nonAssertionPatterns = [
|
|
62
|
+
'syntaxerror',
|
|
63
|
+
'referenceerror',
|
|
64
|
+
'typeerror',
|
|
65
|
+
'network',
|
|
66
|
+
'timeout',
|
|
67
|
+
'connection',
|
|
68
|
+
'http',
|
|
69
|
+
'fetch',
|
|
70
|
+
'axios',
|
|
71
|
+
'cors',
|
|
72
|
+
'permission',
|
|
73
|
+
'access denied',
|
|
74
|
+
'unauthorized',
|
|
75
|
+
'forbidden',
|
|
76
|
+
'not found',
|
|
77
|
+
'server error',
|
|
78
|
+
'internal error'
|
|
79
|
+
];
|
|
80
|
+
// Special case: timeout errors with expect should be treated as assertion errors
|
|
81
|
+
const isTimeoutWithExpect = errorMessage.includes('timeout') &&
|
|
82
|
+
errorMessage.includes('expect');
|
|
83
|
+
if (isTimeoutWithExpect) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
// Check for non-assertion patterns (excluding timeout for special handling above)
|
|
87
|
+
const nonAssertionPatternsWithoutTimeout = nonAssertionPatterns.filter(pattern => pattern !== 'timeout');
|
|
88
|
+
const hasNonAssertionPattern = nonAssertionPatternsWithoutTimeout.some(pattern => errorMessage.includes(pattern) || errorStack.includes(pattern));
|
|
89
|
+
// Cypress retry-ability prefix: "Timed out retrying after Nms:" is added by
|
|
90
|
+
// Cypress' retry mechanism exclusively for DOM-interacting commands (cy.get,
|
|
91
|
+
// cy.click, cy.should, cy.wait with aliases). It never appears in infra
|
|
92
|
+
// failures (cy.request, cy.task). This is the most reliable Cypress signal.
|
|
93
|
+
const isCypressRetryTimeout = /timed out retrying after \d+ms/.test(errorMessage);
|
|
94
|
+
if (hasNonAssertionPattern) {
|
|
95
|
+
const hasAssertionContext = assertionPatterns.some(pattern => errorMessage.includes(pattern) || errorStack.includes(pattern));
|
|
96
|
+
const isRunnerFailed = normalizedOriginalStatus === 'failed' || normalizedOriginalStatus === 'timedout' || normalizedOriginalStatus === 'interrupted';
|
|
97
|
+
const isSyntaxError = errorMessage.includes('syntaxerror') || errorStack.includes('syntaxerror');
|
|
98
|
+
// When runner reported failure and error has assertion context (expect, ObjectContaining, diff),
|
|
99
|
+
// treat as Failed. Exception: SyntaxError (e.g. "Unexpected token") contains "expected" as false positive.
|
|
100
|
+
if (isRunnerFailed && hasAssertionContext && !isSyntaxError) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
// Cypress override: the retry-ability prefix is a strong signal that the
|
|
104
|
+
// test was actively interacting with the application via a retryable command.
|
|
105
|
+
// Cypress errors false-positive on "http" because (a) browser stack traces
|
|
106
|
+
// contain URLs and (b) all error messages include docs links
|
|
107
|
+
// (https://on.cypress.io/...). The retry prefix itself is never
|
|
108
|
+
// infrastructure, so we trust it unconditionally.
|
|
109
|
+
if (isCypressRetryTimeout && isRunnerFailed) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
// Cypress failure without any non-assertion pattern (clean stack trace)
|
|
115
|
+
if (isCypressRetryTimeout) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
// For timeout errors without expect, treat as invalid
|
|
119
|
+
if (errorMessage.includes('timeout')) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
// Check error message and stack for assertion patterns
|
|
123
|
+
const hasAssertionPattern = assertionPatterns.some(pattern => errorMessage.includes(pattern) || errorStack.includes(pattern));
|
|
124
|
+
// Check for specific error types that indicate assertions
|
|
125
|
+
const isJestMatcherError = error.name === 'Error' &&
|
|
126
|
+
(errorMessage.includes('expect') || errorMessage.includes('matcher'));
|
|
127
|
+
const isChaiAssertionError = error.name === 'AssertionError';
|
|
128
|
+
const isPlaywrightAssertionError = error.name === 'Error' &&
|
|
129
|
+
(errorMessage.includes('expect') || errorMessage.includes('assert'));
|
|
130
|
+
return hasAssertionPattern || isJestMatcherError || isChaiAssertionError || isPlaywrightAssertionError;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Maps original test runner status to TestStatusEnum
|
|
134
|
+
* @param originalStatus - Original status from test runner
|
|
135
|
+
* @returns TestStatusEnum
|
|
136
|
+
*/
|
|
137
|
+
function mapOriginalStatus(originalStatus) {
|
|
138
|
+
// Keys must be lowercase to match normalizedStatus (case-insensitive matching)
|
|
139
|
+
const statusMap = {
|
|
140
|
+
'passed': test_execution_1.TestStatusEnum.passed,
|
|
141
|
+
'failed': test_execution_1.TestStatusEnum.failed,
|
|
142
|
+
'skipped': test_execution_1.TestStatusEnum.skipped,
|
|
143
|
+
'disabled': test_execution_1.TestStatusEnum.disabled,
|
|
144
|
+
'pending': test_execution_1.TestStatusEnum.skipped,
|
|
145
|
+
'todo': test_execution_1.TestStatusEnum.disabled,
|
|
146
|
+
'focused': test_execution_1.TestStatusEnum.passed,
|
|
147
|
+
'timedout': test_execution_1.TestStatusEnum.failed,
|
|
148
|
+
'interrupted': test_execution_1.TestStatusEnum.failed,
|
|
149
|
+
};
|
|
150
|
+
const normalizedStatus = originalStatus.toLowerCase();
|
|
151
|
+
return statusMap[normalizedStatus] || test_execution_1.TestStatusEnum.skipped;
|
|
152
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface ErrorOptionsType {
|
|
2
|
+
cause?: unknown;
|
|
3
|
+
}
|
|
4
|
+
export interface TidenErrorInterface extends Error {
|
|
5
|
+
cause?: unknown;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* @class TidenError
|
|
9
|
+
* @extends Error
|
|
10
|
+
* @implements TidenErrorInterface
|
|
11
|
+
*/
|
|
12
|
+
export declare class TidenError extends Error implements TidenErrorInterface {
|
|
13
|
+
/**
|
|
14
|
+
* @type {unknown}
|
|
15
|
+
*/
|
|
16
|
+
cause?: unknown;
|
|
17
|
+
constructor(message?: string, options?: ErrorOptionsType);
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TidenError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @class TidenError
|
|
6
|
+
* @extends Error
|
|
7
|
+
* @implements TidenErrorInterface
|
|
8
|
+
*/
|
|
9
|
+
class TidenError extends Error {
|
|
10
|
+
/**
|
|
11
|
+
* @type {unknown}
|
|
12
|
+
*/
|
|
13
|
+
cause;
|
|
14
|
+
constructor(message, options) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.cause = options?.cause;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.TidenError = TidenError;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mask a token for safe logging.
|
|
3
|
+
* Tokens with 7 chars or fewer are fully masked. Longer tokens expose only
|
|
4
|
+
* the first 3 and last 4 characters.
|
|
5
|
+
*/
|
|
6
|
+
export declare function maskToken(token: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Produce a deep-cloned copy of options with `tiden.api.token` masked.
|
|
9
|
+
* Safe to log — never mutates the input.
|
|
10
|
+
*/
|
|
11
|
+
export declare function sanitizeOptionsForLog<T>(options: T): T;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.maskToken = maskToken;
|
|
4
|
+
exports.sanitizeOptionsForLog = sanitizeOptionsForLog;
|
|
5
|
+
/**
|
|
6
|
+
* Mask a token for safe logging.
|
|
7
|
+
* Tokens with 7 chars or fewer are fully masked. Longer tokens expose only
|
|
8
|
+
* the first 3 and last 4 characters.
|
|
9
|
+
*/
|
|
10
|
+
function maskToken(token) {
|
|
11
|
+
if (token.length <= 7) {
|
|
12
|
+
return '*'.repeat(token.length);
|
|
13
|
+
}
|
|
14
|
+
return `${token.slice(0, 3)}****${token.slice(-4)}`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Produce a deep-cloned copy of options with `tiden.api.token` masked.
|
|
18
|
+
* Safe to log — never mutates the input.
|
|
19
|
+
*/
|
|
20
|
+
function sanitizeOptionsForLog(options) {
|
|
21
|
+
const sanitized = JSON.parse(JSON.stringify(options));
|
|
22
|
+
if (sanitized.tiden?.api?.token) {
|
|
23
|
+
sanitized.tiden.api.token = maskToken(sanitized.tiden.api.token);
|
|
24
|
+
}
|
|
25
|
+
return sanitized;
|
|
26
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ErrorObject, JSONSchemaType } from 'ajv';
|
|
2
|
+
/**
|
|
3
|
+
* @class JsonValidationError
|
|
4
|
+
* @extends Error
|
|
5
|
+
*/
|
|
6
|
+
export declare class JsonValidationError extends Error {
|
|
7
|
+
validationErrors: ErrorObject[];
|
|
8
|
+
/**
|
|
9
|
+
* @param {ErrorObject[]} validationErrors
|
|
10
|
+
* @param {string} message
|
|
11
|
+
*/
|
|
12
|
+
constructor(validationErrors: ErrorObject[], message?: string);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @template T
|
|
16
|
+
* @param {JSONSchemaType<T>} schema
|
|
17
|
+
* @param json
|
|
18
|
+
* @returns {asserts json is T}
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateJson<T>(schema: JSONSchemaType<T>, json: unknown): asserts json is T;
|
|
@@ -0,0 +1,41 @@
|
|
|
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.JsonValidationError = void 0;
|
|
7
|
+
exports.validateJson = validateJson;
|
|
8
|
+
const ajv_1 = __importDefault(require("ajv"));
|
|
9
|
+
/**
|
|
10
|
+
* @type {Ajv}
|
|
11
|
+
*/
|
|
12
|
+
const validator = new ajv_1.default({
|
|
13
|
+
allowUnionTypes: true,
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* @class JsonValidationError
|
|
17
|
+
* @extends Error
|
|
18
|
+
*/
|
|
19
|
+
class JsonValidationError extends Error {
|
|
20
|
+
validationErrors;
|
|
21
|
+
/**
|
|
22
|
+
* @param {ErrorObject[]} validationErrors
|
|
23
|
+
* @param {string} message
|
|
24
|
+
*/
|
|
25
|
+
constructor(validationErrors, message) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.validationErrors = validationErrors;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.JsonValidationError = JsonValidationError;
|
|
31
|
+
/**
|
|
32
|
+
* @template T
|
|
33
|
+
* @param {JSONSchemaType<T>} schema
|
|
34
|
+
* @param json
|
|
35
|
+
* @returns {asserts json is T}
|
|
36
|
+
*/
|
|
37
|
+
function validateJson(schema, json) {
|
|
38
|
+
if (!validator.validate(schema, json)) {
|
|
39
|
+
throw new JsonValidationError(validator.errors ? [...validator.errors] : []);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FormatEnum = exports.DriverEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @enum {string}
|
|
6
|
+
*/
|
|
7
|
+
var DriverEnum;
|
|
8
|
+
(function (DriverEnum) {
|
|
9
|
+
DriverEnum["local"] = "local";
|
|
10
|
+
})(DriverEnum || (exports.DriverEnum = DriverEnum = {}));
|
|
11
|
+
/**
|
|
12
|
+
* @enum {string}
|
|
13
|
+
*/
|
|
14
|
+
var FormatEnum;
|
|
15
|
+
(function (FormatEnum) {
|
|
16
|
+
FormatEnum["json"] = "json";
|
|
17
|
+
FormatEnum["jsonp"] = "jsonp";
|
|
18
|
+
})(FormatEnum || (exports.FormatEnum = FormatEnum = {}));
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { WriterInterface } from './writer-interface';
|
|
2
|
+
import { TestResultType, Attachment, Report } from '../models';
|
|
3
|
+
import { FormatEnum } from './driver-enum';
|
|
4
|
+
export interface FsWriterOptionsType {
|
|
5
|
+
path?: string | undefined;
|
|
6
|
+
format?: FormatEnum | undefined;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* @class FsWriter
|
|
10
|
+
* @implements WriterInterface
|
|
11
|
+
*/
|
|
12
|
+
export declare class FsWriter implements WriterInterface {
|
|
13
|
+
private readonly path;
|
|
14
|
+
private readonly format;
|
|
15
|
+
private formatter;
|
|
16
|
+
/**
|
|
17
|
+
* @param {FsWriterOptionsType | undefined} options
|
|
18
|
+
*/
|
|
19
|
+
constructor(options: FsWriterOptionsType | undefined);
|
|
20
|
+
/**
|
|
21
|
+
* @returns {void}
|
|
22
|
+
*/
|
|
23
|
+
clearPreviousResults(): void;
|
|
24
|
+
/**
|
|
25
|
+
* @param {Attachment[]} attachments
|
|
26
|
+
* @returns {Attachment[]}
|
|
27
|
+
*/
|
|
28
|
+
writeAttachment(attachments: Attachment[]): Attachment[];
|
|
29
|
+
/**
|
|
30
|
+
* @param {TestResultType[]} results
|
|
31
|
+
* @returns {Promise<string>}
|
|
32
|
+
*/
|
|
33
|
+
writeReport(results: Report): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* @returns {Promise<void>}
|
|
36
|
+
* @param {TestResultType} result
|
|
37
|
+
*/
|
|
38
|
+
writeTestResult(result: TestResultType): Promise<void>;
|
|
39
|
+
private deleteFolderRecursive;
|
|
40
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
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
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FsWriter = void 0;
|
|
37
|
+
const fs_1 = require("fs");
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const formatter_1 = require("../formatter");
|
|
40
|
+
const driver_enum_1 = require("./driver-enum");
|
|
41
|
+
/**
|
|
42
|
+
* @class FsWriter
|
|
43
|
+
* @implements WriterInterface
|
|
44
|
+
*/
|
|
45
|
+
class FsWriter {
|
|
46
|
+
path;
|
|
47
|
+
format;
|
|
48
|
+
formatter;
|
|
49
|
+
/**
|
|
50
|
+
* @param {FsWriterOptionsType | undefined} options
|
|
51
|
+
*/
|
|
52
|
+
constructor(options) {
|
|
53
|
+
const { path: pathOptions = path.join('build', 'tiden-report'), format = options?.format ?? driver_enum_1.FormatEnum.json, } = options ?? {};
|
|
54
|
+
this.path = pathOptions;
|
|
55
|
+
this.format = format;
|
|
56
|
+
if (this.format === driver_enum_1.FormatEnum.json) {
|
|
57
|
+
this.formatter = new formatter_1.JsonFormatter();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
this.formatter = new formatter_1.JsonpFormatter();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* @returns {void}
|
|
65
|
+
*/
|
|
66
|
+
clearPreviousResults() {
|
|
67
|
+
this.deleteFolderRecursive(this.path);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @param {Attachment[]} attachments
|
|
71
|
+
* @returns {Attachment[]}
|
|
72
|
+
*/
|
|
73
|
+
writeAttachment(attachments) {
|
|
74
|
+
const attachmentsPath = path.join(this.path, 'attachments');
|
|
75
|
+
try {
|
|
76
|
+
(0, fs_1.mkdirSync)(attachmentsPath, { recursive: true });
|
|
77
|
+
}
|
|
78
|
+
catch (error) { /* ignore */
|
|
79
|
+
}
|
|
80
|
+
for (const attachment of attachments) {
|
|
81
|
+
if (attachment.file_path) {
|
|
82
|
+
attachment.file_name = path.basename(attachment.file_path);
|
|
83
|
+
}
|
|
84
|
+
const filePath = path.join(attachmentsPath, `${attachment.id}-${attachment.file_name}`);
|
|
85
|
+
if (attachment.file_path) {
|
|
86
|
+
(0, fs_1.copyFileSync)(attachment.file_path, filePath);
|
|
87
|
+
attachment.file_path = filePath;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
(0, fs_1.writeFileSync)(filePath, attachment.content);
|
|
91
|
+
attachment.file_path = filePath;
|
|
92
|
+
}
|
|
93
|
+
return attachments;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* @param {TestResultType[]} results
|
|
97
|
+
* @returns {Promise<string>}
|
|
98
|
+
*/
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
100
|
+
async writeReport(results) {
|
|
101
|
+
try {
|
|
102
|
+
(0, fs_1.mkdirSync)(this.path, { recursive: true });
|
|
103
|
+
}
|
|
104
|
+
catch (error) { /* ignore */
|
|
105
|
+
}
|
|
106
|
+
const filePath = path.join(this.path, `run.${this.format}`);
|
|
107
|
+
(0, fs_1.writeFileSync)(filePath, await this.formatter.format(results));
|
|
108
|
+
return filePath;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* @returns {Promise<void>}
|
|
112
|
+
* @param {TestResultType} result
|
|
113
|
+
*/
|
|
114
|
+
async writeTestResult(result) {
|
|
115
|
+
const resultsPath = path.join(this.path, 'results');
|
|
116
|
+
try {
|
|
117
|
+
(0, fs_1.mkdirSync)(resultsPath, { recursive: true });
|
|
118
|
+
}
|
|
119
|
+
catch (error) { /* ignore */
|
|
120
|
+
}
|
|
121
|
+
const filePath = path.join(resultsPath, `${result.id}.${this.format}`);
|
|
122
|
+
(0, fs_1.writeFileSync)(filePath, await this.formatter.format(result));
|
|
123
|
+
}
|
|
124
|
+
deleteFolderRecursive(directoryPath) {
|
|
125
|
+
if ((0, fs_1.existsSync)(directoryPath)) {
|
|
126
|
+
(0, fs_1.readdirSync)(directoryPath).forEach((file) => {
|
|
127
|
+
const curPath = path.join(directoryPath, file);
|
|
128
|
+
if ((0, fs_1.lstatSync)(curPath).isDirectory()) { // recurse
|
|
129
|
+
this.deleteFolderRecursive(curPath);
|
|
130
|
+
}
|
|
131
|
+
else { // delete file
|
|
132
|
+
(0, fs_1.unlinkSync)(curPath);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
(0, fs_1.rmdirSync)(directoryPath);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.FsWriter = FsWriter;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FormatEnum = exports.DriverEnum = exports.FsWriter = void 0;
|
|
4
|
+
var fs_writer_1 = require("./fs-writer");
|
|
5
|
+
Object.defineProperty(exports, "FsWriter", { enumerable: true, get: function () { return fs_writer_1.FsWriter; } });
|
|
6
|
+
var driver_enum_1 = require("./driver-enum");
|
|
7
|
+
Object.defineProperty(exports, "DriverEnum", { enumerable: true, get: function () { return driver_enum_1.DriverEnum; } });
|
|
8
|
+
Object.defineProperty(exports, "FormatEnum", { enumerable: true, get: function () { return driver_enum_1.FormatEnum; } });
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { TestResultType, Attachment, Report } from '../models';
|
|
2
|
+
export interface WriterInterface {
|
|
3
|
+
writeReport(results: Report): Promise<string>;
|
|
4
|
+
writeTestResult(result: TestResultType): Promise<void>;
|
|
5
|
+
writeAttachment(attachments: Attachment[]): Attachment[];
|
|
6
|
+
clearPreviousResults(): void;
|
|
7
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tiden/reporter-commons",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Tiden JS Reporters",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE",
|
|
11
|
+
"CHANGELOG.md"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./profilers": {
|
|
19
|
+
"types": "./dist/profilers/index.d.ts",
|
|
20
|
+
"default": "./dist/profilers/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./internal": {
|
|
23
|
+
"types": "./dist/internal/index.d.ts",
|
|
24
|
+
"default": "./dist/internal/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"typesVersions": {
|
|
29
|
+
"*": {
|
|
30
|
+
"profilers": [
|
|
31
|
+
"./dist/profilers/index.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"internal": [
|
|
34
|
+
"./dist/internal/index.d.ts"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/qase-tms/tiden-javascript",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/qase-tms/tiden-javascript/issues"
|
|
41
|
+
},
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+https://github.com/qase-tms/tiden-javascript.git",
|
|
45
|
+
"directory": "commons"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "npm run clean && tsc --project tsconfig.build.json",
|
|
52
|
+
"lint": "eslint .",
|
|
53
|
+
"test": "jest --passWithNoTests",
|
|
54
|
+
"clean": "rm -rf dist"
|
|
55
|
+
},
|
|
56
|
+
"author": "Tiden Team <support@tiden.ai>",
|
|
57
|
+
"license": "Apache-2.0",
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"ajv": "^8.18.0",
|
|
60
|
+
"async-mutex": "~0.5.0",
|
|
61
|
+
"axios": "^1.16.0",
|
|
62
|
+
"chalk": "^4.1.2",
|
|
63
|
+
"env-schema": "^5.2.1",
|
|
64
|
+
"form-data": "^4.0.6",
|
|
65
|
+
"lodash.get": "^4.4.2",
|
|
66
|
+
"lodash.merge": "^4.6.2",
|
|
67
|
+
"lodash.mergewith": "^4.6.2",
|
|
68
|
+
"mime-types": "^2.1.35",
|
|
69
|
+
"strip-ansi": "^6.0.1",
|
|
70
|
+
"uuid": "11.1.1"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@jest/globals": "^29.7.0",
|
|
74
|
+
"@types/jest": "^29.5.14",
|
|
75
|
+
"@types/lodash.get": "^4.4.9",
|
|
76
|
+
"@types/lodash.merge": "^4.6.9",
|
|
77
|
+
"@types/lodash.mergewith": "^4.6.9",
|
|
78
|
+
"@types/mime-types": "^2.1.4",
|
|
79
|
+
"@types/minimatch": "^6.0.0",
|
|
80
|
+
"jest": "^29.7.0",
|
|
81
|
+
"ts-jest": "^29.4.5"
|
|
82
|
+
}
|
|
83
|
+
}
|