@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.
Files changed (174) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/LICENSE +201 -0
  3. package/README.md +34 -0
  4. package/dist/client/interface.d.ts +8 -0
  5. package/dist/client/interface.js +2 -0
  6. package/dist/client/reporter-api-models.d.ts +96 -0
  7. package/dist/client/reporter-api-models.js +2 -0
  8. package/dist/client/reporter-api.d.ts +14 -0
  9. package/dist/client/reporter-api.js +25 -0
  10. package/dist/client/services/api-error-handler.d.ts +10 -0
  11. package/dist/client/services/api-error-handler.js +44 -0
  12. package/dist/client/services/attachment-service.d.ts +29 -0
  13. package/dist/client/services/attachment-service.js +268 -0
  14. package/dist/client/services/result-transformer.d.ts +21 -0
  15. package/dist/client/services/result-transformer.js +180 -0
  16. package/dist/client/services/run-service.d.ts +20 -0
  17. package/dist/client/services/run-service.js +68 -0
  18. package/dist/client/tiden-client.d.ts +34 -0
  19. package/dist/client/tiden-client.js +99 -0
  20. package/dist/client/tiden-http.d.ts +11 -0
  21. package/dist/client/tiden-http.js +23 -0
  22. package/dist/config/config-loader-interface.d.ts +4 -0
  23. package/dist/config/config-loader-interface.js +2 -0
  24. package/dist/config/config-loader.d.ts +10 -0
  25. package/dist/config/config-loader.js +60 -0
  26. package/dist/config/config-type.d.ts +2 -0
  27. package/dist/config/config-type.js +2 -0
  28. package/dist/config/config-validation-schema.d.ts +212 -0
  29. package/dist/config/config-validation-schema.js +213 -0
  30. package/dist/config/index.d.ts +4 -0
  31. package/dist/config/index.js +7 -0
  32. package/dist/core/options-resolver.d.ts +19 -0
  33. package/dist/core/options-resolver.js +47 -0
  34. package/dist/core/reporter-factory.d.ts +18 -0
  35. package/dist/core/reporter-factory.js +63 -0
  36. package/dist/core/status-processor.d.ts +17 -0
  37. package/dist/core/status-processor.js +48 -0
  38. package/dist/env/env-enum.d.ts +64 -0
  39. package/dist/env/env-enum.js +75 -0
  40. package/dist/env/env-to-config.d.ts +7 -0
  41. package/dist/env/env-to-config.js +60 -0
  42. package/dist/env/env-type.d.ts +29 -0
  43. package/dist/env/env-type.js +3 -0
  44. package/dist/env/env-validation-schema.d.ts +6 -0
  45. package/dist/env/env-validation-schema.js +113 -0
  46. package/dist/env/index.d.ts +4 -0
  47. package/dist/env/index.js +13 -0
  48. package/dist/formatter/formatter-interface.d.ts +3 -0
  49. package/dist/formatter/formatter-interface.js +2 -0
  50. package/dist/formatter/index.d.ts +4 -0
  51. package/dist/formatter/index.js +9 -0
  52. package/dist/formatter/json-formatter.d.ts +13 -0
  53. package/dist/formatter/json-formatter.js +28 -0
  54. package/dist/formatter/jsonp-formatter.d.ts +13 -0
  55. package/dist/formatter/jsonp-formatter.js +29 -0
  56. package/dist/formatter/report-serializer.d.ts +20 -0
  57. package/dist/formatter/report-serializer.js +92 -0
  58. package/dist/index.d.ts +14 -0
  59. package/dist/index.js +30 -0
  60. package/dist/internal/filter-positive-ids.d.ts +17 -0
  61. package/dist/internal/filter-positive-ids.js +38 -0
  62. package/dist/internal/ids-parser.d.ts +9 -0
  63. package/dist/internal/ids-parser.js +21 -0
  64. package/dist/internal/index.d.ts +8 -0
  65. package/dist/internal/index.js +15 -0
  66. package/dist/internal/step-parser.d.ts +11 -0
  67. package/dist/internal/step-parser.js +28 -0
  68. package/dist/internal/suite-file.d.ts +13 -0
  69. package/dist/internal/suite-file.js +16 -0
  70. package/dist/internal/suite-normalizer.d.ts +6 -0
  71. package/dist/internal/suite-normalizer.js +11 -0
  72. package/dist/internal/title.d.ts +5 -0
  73. package/dist/internal/title.js +15 -0
  74. package/dist/models/attachment.d.ts +8 -0
  75. package/dist/models/attachment.js +2 -0
  76. package/dist/models/config/TidenOptionsType.d.ts +33 -0
  77. package/dist/models/config/TidenOptionsType.js +2 -0
  78. package/dist/models/configuration.d.ts +12 -0
  79. package/dist/models/configuration.js +2 -0
  80. package/dist/models/error.d.ts +7 -0
  81. package/dist/models/error.js +24 -0
  82. package/dist/models/execution-sum.d.ts +6 -0
  83. package/dist/models/execution-sum.js +2 -0
  84. package/dist/models/host-data.d.ts +12 -0
  85. package/dist/models/host-data.js +2 -0
  86. package/dist/models/index.d.ts +11 -0
  87. package/dist/models/index.js +15 -0
  88. package/dist/models/report.d.ts +14 -0
  89. package/dist/models/report.js +2 -0
  90. package/dist/models/short-result.d.ts +7 -0
  91. package/dist/models/short-result.js +2 -0
  92. package/dist/models/stats.d.ts +9 -0
  93. package/dist/models/stats.js +2 -0
  94. package/dist/models/step-data.d.ts +19 -0
  95. package/dist/models/step-data.js +2 -0
  96. package/dist/models/step-execution.d.ts +13 -0
  97. package/dist/models/step-execution.js +23 -0
  98. package/dist/models/test-execution.d.ts +20 -0
  99. package/dist/models/test-execution.js +32 -0
  100. package/dist/models/test-result.d.ts +44 -0
  101. package/dist/models/test-result.js +50 -0
  102. package/dist/models/test-step.d.ts +18 -0
  103. package/dist/models/test-step.js +53 -0
  104. package/dist/options/composeOptions.d.ts +8 -0
  105. package/dist/options/composeOptions.js +12 -0
  106. package/dist/options/index.d.ts +3 -0
  107. package/dist/options/index.js +7 -0
  108. package/dist/options/mode-enum.d.ts +8 -0
  109. package/dist/options/mode-enum.js +12 -0
  110. package/dist/options/options-type.d.ts +38 -0
  111. package/dist/options/options-type.js +3 -0
  112. package/dist/profilers/abstract-profiler.d.ts +5 -0
  113. package/dist/profilers/abstract-profiler.js +6 -0
  114. package/dist/profilers/fetch-interceptor.d.ts +60 -0
  115. package/dist/profilers/fetch-interceptor.js +277 -0
  116. package/dist/profilers/http-interceptor.d.ts +76 -0
  117. package/dist/profilers/http-interceptor.js +252 -0
  118. package/dist/profilers/index.d.ts +5 -0
  119. package/dist/profilers/index.js +11 -0
  120. package/dist/profilers/network-profiler.d.ts +61 -0
  121. package/dist/profilers/network-profiler.js +94 -0
  122. package/dist/reporters/abstract-reporter.d.ts +68 -0
  123. package/dist/reporters/abstract-reporter.js +78 -0
  124. package/dist/reporters/index.d.ts +3 -0
  125. package/dist/reporters/index.js +9 -0
  126. package/dist/reporters/report-reporter.d.ts +50 -0
  127. package/dist/reporters/report-reporter.js +167 -0
  128. package/dist/reporters/run-reporter.d.ts +65 -0
  129. package/dist/reporters/run-reporter.js +155 -0
  130. package/dist/reporters/shared/fallback-coordinator.d.ts +47 -0
  131. package/dist/reporters/shared/fallback-coordinator.js +119 -0
  132. package/dist/reporters/shared/run-constants.d.ts +11 -0
  133. package/dist/reporters/shared/run-constants.js +14 -0
  134. package/dist/state/state.d.ts +16 -0
  135. package/dist/state/state.js +70 -0
  136. package/dist/steps/step.d.ts +16 -0
  137. package/dist/steps/step.js +86 -0
  138. package/dist/tiden.d.ts +48 -0
  139. package/dist/tiden.js +223 -0
  140. package/dist/utils/disabled-exception.d.ts +6 -0
  141. package/dist/utils/disabled-exception.js +10 -0
  142. package/dist/utils/get-package-version.d.ts +5 -0
  143. package/dist/utils/get-package-version.js +25 -0
  144. package/dist/utils/hostData.d.ts +8 -0
  145. package/dist/utils/hostData.js +140 -0
  146. package/dist/utils/is-axios-error.d.ts +6 -0
  147. package/dist/utils/is-axios-error.js +11 -0
  148. package/dist/utils/logger.d.ts +33 -0
  149. package/dist/utils/logger.js +141 -0
  150. package/dist/utils/mimeTypes.d.ts +5 -0
  151. package/dist/utils/mimeTypes.js +50 -0
  152. package/dist/utils/project-mapping-utils.d.ts +17 -0
  153. package/dist/utils/project-mapping-utils.js +29 -0
  154. package/dist/utils/signature.d.ts +11 -0
  155. package/dist/utils/signature.js +34 -0
  156. package/dist/utils/status-mapping-utils.d.ts +14 -0
  157. package/dist/utils/status-mapping-utils.js +45 -0
  158. package/dist/utils/test-status-utils.d.ts +8 -0
  159. package/dist/utils/test-status-utils.js +152 -0
  160. package/dist/utils/tiden-error.d.ts +18 -0
  161. package/dist/utils/tiden-error.js +19 -0
  162. package/dist/utils/token-masker.d.ts +11 -0
  163. package/dist/utils/token-masker.js +26 -0
  164. package/dist/utils/validate-json.d.ts +20 -0
  165. package/dist/utils/validate-json.js +41 -0
  166. package/dist/writer/driver-enum.d.ts +13 -0
  167. package/dist/writer/driver-enum.js +18 -0
  168. package/dist/writer/fs-writer.d.ts +40 -0
  169. package/dist/writer/fs-writer.js +139 -0
  170. package/dist/writer/index.d.ts +3 -0
  171. package/dist/writer/index.js +8 -0
  172. package/dist/writer/writer-interface.d.ts +7 -0
  173. package/dist/writer/writer-interface.js +2 -0
  174. 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,13 @@
1
+ /**
2
+ * @enum {string}
3
+ */
4
+ export declare enum DriverEnum {
5
+ local = "local"
6
+ }
7
+ /**
8
+ * @enum {string}
9
+ */
10
+ export declare enum FormatEnum {
11
+ json = "json",
12
+ jsonp = "jsonp"
13
+ }
@@ -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,3 @@
1
+ export { type WriterInterface } from './writer-interface';
2
+ export { FsWriter, type FsWriterOptionsType } from './fs-writer';
3
+ export { DriverEnum, FormatEnum } from './driver-enum';
@@ -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
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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
+ }