@testomatio/reporter 2.9.3-beta-vitestmeta → 2.9.3-beta.2-allure-improv

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/README.md CHANGED
@@ -76,6 +76,7 @@ npx testomatio-reporter <command> [options]
76
76
  | [TestCafe](./docs/frameworks.md#testcafe) | [Detox](./docs/frameworks.md#detox) | [Codeception](https://github.com/testomatio/php-reporter) |
77
77
  | [Newman (Postman)](./docs/frameworks.md#newman) | [JUnit](./docs/junit.md#junit) | [NUnit](./docs/junit.md#nunit) |
78
78
  | [PyTest](./docs/junit.md#pytest) | [PHPUnit](./docs/junit.md#phpunit) | [Protractor](./docs/frameworks.md#protractor) |
79
+ | [Allure](./docs/allure.md) | | |
79
80
 
80
81
  or **any [other via JUnit](./docs/junit.md)** report....
81
82
 
@@ -137,9 +138,10 @@ Bring this reporter on CI and never lose test results again!
137
138
  - [HTML report](./docs/pipes/html.md)
138
139
  - [Markdown report](./docs/pipes/markdown.md)
139
140
  - [Bitbucket](./docs/pipes/bitbucket.md)
140
- - 🔗 [Linking Tests](./docs/linking-tests.md)
141
- - 📓 [JUnit](./docs/junit.md)
141
+ - 📓 [JUnit Reports](./docs/junit.md)
142
142
  - 🗄️ [Artifacts](./docs/artifacts.md)
143
+ - 🔬 [Allure Reports](./docs/allure.md)
144
+ - 🔗 [Linking Tests](./docs/linking-tests.md)
143
145
  - 🔂 [Workflows](./docs/workflows.md)
144
146
  - 🖊️ [Logger](./docs/logger.md)
145
147
  - 🪲 [Debug File Format](./docs/debug-file-format.md)
@@ -237,7 +237,6 @@ async function uploadAttachments(client, attachments, messagePrefix, attachmentT
237
237
  if (client.uploader.isEnabled) {
238
238
  log_js_1.log.info(`Attachments: ${messagePrefix} ${attachments.length} ${attachmentType} ...`);
239
239
  }
240
- await Promise.all(client.pipes?.map(pipe => pipe.addArtifacts?.(attachments)) || []);
241
240
  const promises = attachments.map(async (attachment) => {
242
241
  const { rid, title, path, type } = attachment;
243
242
  const file = { path, type, title };
@@ -51,8 +51,13 @@ class PlaywrightReporter {
51
51
  const { title } = test;
52
52
  const { error, duration } = result;
53
53
  const pwAttachments = (result.attachments || []).filter(a => a.body || a.path);
54
- const files = buildArtifactFiles(pwAttachments, attachment => this.#getArtifactPath(attachment), title);
55
- const artifactsForUpload = processArtifactsForUpload(pwAttachments);
54
+ const files = pwAttachments
55
+ .map(att => ({
56
+ path: this.#getArtifactPath(att),
57
+ title: att.name || title,
58
+ type: att.contentType,
59
+ }))
60
+ .filter(f => f.path);
56
61
  const suite_title = test.parent ? test.parent?.title : path_1.default.basename(test?.location?.file);
57
62
  const rid = test.id || test.testId || (0, uuid_1.v4)();
58
63
  /**
@@ -139,7 +144,7 @@ class PlaywrightReporter {
139
144
  this.uploads.push({
140
145
  rid: `${rid}-${project.name}`,
141
146
  title: test.title,
142
- files: artifactsForUpload,
147
+ files: pwAttachments,
143
148
  file: test.location?.file,
144
149
  });
145
150
  // remove empty uploads
@@ -205,22 +210,6 @@ function checkStatus(status) {
205
210
  passed: constants_js_1.STATUS.PASSED,
206
211
  }[status] || constants_js_1.STATUS.FAILED);
207
212
  }
208
- function buildArtifactFiles(attachments, getArtifactPath, title) {
209
- return attachments
210
- .filter(isScreenshotArtifact)
211
- .map(attachment => ({
212
- path: getArtifactPath(attachment),
213
- title: attachment.name || title,
214
- type: attachment.contentType,
215
- }))
216
- .filter(file => file.path);
217
- }
218
- function processArtifactsForUpload(attachments) {
219
- return attachments.filter(attachment => !isScreenshotArtifact(attachment));
220
- }
221
- function isScreenshotArtifact(attachment) {
222
- return attachment?.contentType === 'image/png' && attachment?.name === 'screenshot';
223
- }
224
213
  function appendStep(step, shift = 0) {
225
214
  // nesting too deep, ignore those steps
226
215
  if (shift >= 10)
@@ -393,10 +393,7 @@ function normalizeVitestTest(test) {
393
393
  file,
394
394
  suiteTitle,
395
395
  logs: '',
396
- meta: {
397
- ...(test.task?.meta || {}),
398
- ...(typeof test.meta === 'function' ? test.meta() : test.meta || {}),
399
- },
396
+ meta: typeof test.meta === 'function' ? test.meta() : {},
400
397
  };
401
398
  }
402
399
  return {
@@ -0,0 +1,178 @@
1
+ export default AllureReader;
2
+ declare class AllureReader {
3
+ constructor(opts?: {});
4
+ requestParams: {
5
+ apiKey: any;
6
+ url: any;
7
+ title: string;
8
+ env: string;
9
+ group_title: string;
10
+ batchMode: "manual";
11
+ };
12
+ runId: any;
13
+ opts: {};
14
+ withPackage: any;
15
+ store: {};
16
+ pipesPromise: Promise<any[]>;
17
+ _tests: any[];
18
+ stats: {};
19
+ suites: {};
20
+ uploader: S3Uploader;
21
+ version: any;
22
+ set tests(value: any[]);
23
+ get tests(): any[];
24
+ createRun(): Promise<any[]>;
25
+ pipes: any;
26
+ parse(resultsPattern: any): {};
27
+ parseContainerFiles(containerFiles: any): void;
28
+ processAllureResult(result: any, resultsDir: any): {
29
+ rid: any;
30
+ title: any;
31
+ status: any;
32
+ suite_title: any;
33
+ file: string;
34
+ run_time: number;
35
+ steps: any;
36
+ message: any;
37
+ stack: any;
38
+ meta: {};
39
+ links: {
40
+ label: string;
41
+ }[];
42
+ artifacts: any[];
43
+ create: boolean;
44
+ overwrite: boolean;
45
+ };
46
+ mapStatus(status: any): any;
47
+ /**
48
+ * Map an Allure step status to the Testomat.io Step status enum
49
+ * (`passed | failed | none | custom`, see testomat-api-definition.yml).
50
+ *
51
+ * Allure marks a step `broken` when it threw an unexpected error — that is a
52
+ * failure for reporting purposes, matching how `mapStatus` treats tests.
53
+ * `skipped` and anything unknown/absent become `none` (the neutral value),
54
+ * since the step enum has no `skipped`.
55
+ *
56
+ * @param {string} status - Allure step status
57
+ * @returns {'passed'|'failed'|'none'} Testomat.io step status
58
+ */
59
+ mapStepStatus(status: string): "passed" | "failed" | "none";
60
+ extractSuiteTitle(result: any): any;
61
+ stripNamespace(suiteName: any): any;
62
+ extractFile(result: any): string;
63
+ getFileExtension(result: any): any;
64
+ extractMeta(result: any): {};
65
+ extractLinks(result: any): {
66
+ label: string;
67
+ }[];
68
+ /**
69
+ * Extract a Testomat.io test id from Allure links so reported tests match
70
+ * existing cases instead of creating duplicates.
71
+ *
72
+ * Allure's `@TmsLink("T1a2b3c4d")` produces a link with `type: "tms"`. Some exporters
73
+ * omit the type but still point the link URL at a Testomat.io test page; both are
74
+ * accepted. The link `name` is used as the id (falling back to the last URL segment).
75
+ *
76
+ * @param {object} result - Parsed Allure result JSON
77
+ * @returns {string|null} Normalized test id, or null when no usable link exists
78
+ */
79
+ extractTestId(result: object): string | null;
80
+ /**
81
+ * Normalize a value into a Testomat.io test id.
82
+ *
83
+ * Testomat.io test ids are exactly **8 word characters**. The value may arrive bare
84
+ * (`1a2b3c4d`), or carrying the `T` / `@T` markers Testomat uses in code and titles
85
+ * (`T1a2b3c4d`, `@T1a2b3c4d`). The markers are removed only when doing so still leaves
86
+ * a valid 8-char id, so a real id that happens to start with `T` is preserved.
87
+ *
88
+ * Anything that does not resolve to a valid 8-char id — a numeric Allure TestOps id
89
+ * like `12345`, a JIRA key, a 6-digit TMS number — is rejected (returns null) so we
90
+ * never send an unmatchable id that would create duplicates.
91
+ *
92
+ * @param {string|number|null|undefined} value
93
+ * @returns {string|null} The bare 8-char id, or null when the value is not a valid id
94
+ */
95
+ normalizeTestId(value: string | number | null | undefined): string | null;
96
+ /**
97
+ * Recover a Testomat.io test id from the `@TmsLink("…")` annotation in test source.
98
+ *
99
+ * Allure does not emit link annotations for skipped (`@Ignore` / `@Disabled`) tests,
100
+ * so their results carry no `tms` link and `extractTestId` returns null — which makes
101
+ * the server create a duplicate case. The id still lives in the source, on the test
102
+ * method, so we read it from there as a fallback.
103
+ *
104
+ * The lookup is method-scoped: we locate the test method declaration by name, then
105
+ * scan upward across its annotation/comment block (the lines directly above it) for
106
+ * `@TmsLink`. Scanning stops at the first real code line so an unrelated method's
107
+ * annotation can never be picked up.
108
+ *
109
+ * @param {string} contents - full source file
110
+ * @param {object} test - converted test (uses `title`)
111
+ * @returns {string|null} normalized 8-char id, or null
112
+ */
113
+ extractTmsIdFromSource(contents: string, test: object): string | null;
114
+ convertSteps(steps: any, depth?: number): any;
115
+ /**
116
+ * Check whether any step in the given (already converted) subtree already
117
+ * carries an `error`. Used to keep the failure message on the deepest failed
118
+ * step only, instead of repeating it on every ancestor in the failure chain.
119
+ *
120
+ * @param {Array<object>|undefined} steps - converted child steps
121
+ * @returns {boolean}
122
+ */
123
+ subtreeHasError(steps: Array<object> | undefined): boolean;
124
+ /**
125
+ * Build the `error` payload for a failed step from its Allure `statusDetails`.
126
+ *
127
+ * Allure stores the failure message and stack trace (which includes the failing
128
+ * source line) in `statusDetails` on the step itself. We only surface it for
129
+ * failed/broken steps — passing or skipped steps carry no error. Returns null
130
+ * when there is no usable failure information so the field is omitted entirely.
131
+ *
132
+ * @param {object} step - Allure step
133
+ * @returns {{message: string, stack: string}|null}
134
+ */
135
+ extractStepError(step: object): {
136
+ message: string;
137
+ stack: string;
138
+ } | null;
139
+ calculateRunTime(item: any): number;
140
+ convertParameters(parameters: any): {};
141
+ combineRetryAttempts(attempts: any): any;
142
+ calculateStats(): {};
143
+ fetchSourceCode(): void;
144
+ getLanguage(): any;
145
+ /**
146
+ * Fill in `test_id` for tests that have none by reading the `@TmsLink` annotation
147
+ * from their source. This rescues skipped (`@Ignore` / `@Disabled`) tests, whose
148
+ * Allure results drop the `@TmsLink` link and would otherwise create duplicate cases.
149
+ *
150
+ * Opt-in: only runs when `--java-tests` (a source root) is provided. The source
151
+ * files are indexed once by basename; for each id-less test we read the candidate
152
+ * file(s) matching its `testFile` / class name and parse the method's `@TmsLink`.
153
+ */
154
+ recoverTestIdsFromSource(): void;
155
+ /**
156
+ * Build (and cache) a basename -> [absolute paths] index of source files under `root`.
157
+ * Walks synchronously, skipping common build/dependency directories.
158
+ *
159
+ * @param {string} root
160
+ * @returns {Map<string, string[]>}
161
+ */
162
+ indexSourceFiles(root: string): Map<string, string[]>;
163
+ _sourceIndex: Map<any, any>;
164
+ /**
165
+ * Candidate source file paths for a test, looked up in the basename index.
166
+ * Uses the `testFile` meta label (e.g. `Foo.kt`) and the class name from `file`,
167
+ * trying both `.kt` and `.java` extensions. Ambiguity (same basename in several
168
+ * dirs) is harmless: only the file that actually declares the method will match.
169
+ *
170
+ * @param {object} t
171
+ * @param {Map<string, string[]>} index
172
+ * @returns {string[]}
173
+ */
174
+ sourceCandidatesForTest(t: object, index: Map<string, string[]>): string[];
175
+ uploadArtifacts(): Promise<void>;
176
+ uploadData(): Promise<any[]>;
177
+ }
178
+ import { S3Uploader } from './uploader.js';