@kinora/vitest-reporter 0.4.0 → 0.6.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/dist/index.d.mts +14 -1
- package/dist/index.mjs +44 -19
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AttachmentKind, CiMeta, GitMeta } from "@kinora/core";
|
|
1
|
+
import { AttachmentKind, CiMeta, GitMeta, PrCommentOption, PrStatusOption } from "@kinora/core";
|
|
2
2
|
import { Reporter, TestModule, Vitest } from "vitest/node";
|
|
3
3
|
type IncludeTests = 'browser' | 'all';
|
|
4
4
|
export interface KinoraVitestReporterOptions {
|
|
@@ -28,6 +28,18 @@ export interface KinoraVitestReporterOptions {
|
|
|
28
28
|
* tell the legs apart. `false` uploads each shard as its own run.
|
|
29
29
|
*/
|
|
30
30
|
groupKey?: string | false;
|
|
31
|
+
/**
|
|
32
|
+
* Post/update a summary comment on the GitHub PR (uses the job's GITHUB_TOKEN; needs
|
|
33
|
+
* `permissions: pull-requests: write`) or the GitLab MR (needs a GITLAB_TOKEN CI variable with
|
|
34
|
+
* the `api` scope). `label` distinguishes matrix legs sharing one PR.
|
|
35
|
+
*/
|
|
36
|
+
prComment?: PrCommentOption;
|
|
37
|
+
/**
|
|
38
|
+
* Set a `kinora / <project>` commit status on the GitHub PR (needs `permissions: statuses: write`)
|
|
39
|
+
* or the GitLab MR pipeline (GITLAB_TOKEN with the Developer role): red only for tests newly
|
|
40
|
+
* failing vs the base branch. `label` distinguishes matrix legs, defaulting to the `prComment` one.
|
|
41
|
+
*/
|
|
42
|
+
prStatus?: PrStatusOption;
|
|
31
43
|
}
|
|
32
44
|
export default class KinoraVitestReporter implements Reporter {
|
|
33
45
|
private readonly options;
|
|
@@ -37,5 +49,6 @@ export default class KinoraVitestReporter implements Reporter {
|
|
|
37
49
|
onInit(vitest: Vitest): void;
|
|
38
50
|
onTestRunStart(): void;
|
|
39
51
|
onTestRunEnd(modules: ReadonlyArray<TestModule>): Promise<void>;
|
|
52
|
+
private maybePostToPr;
|
|
40
53
|
}
|
|
41
54
|
export {};
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
1
2
|
import { readFile } from "node:fs/promises";
|
|
2
3
|
import process from "node:process";
|
|
3
|
-
import { DEFAULT_KINORA_URL, DEFAULT_UPLOAD_ATTACHMENTS, IngestError, MAX_A11Y_NODES, MAX_A11Y_VIOLATIONS, STORY_ANNOTATION, axeViolations, createIngestClient, describeRetry, detectCiEnv,
|
|
4
|
+
import { DEFAULT_KINORA_URL, DEFAULT_UPLOAD_ATTACHMENTS, IngestError, MAX_A11Y_NODES, MAX_A11Y_VIOLATIONS, STORY_ANNOTATION, artifactsToUpload, axeViolations, createIngestClient, describeRetry, detectCiEnv, flakyTestsOf, makeTestKey, postToPr, prLegLabel, resolvePrContext, resolvePrReportOptions, resolveShardGroup, stripAnsi, uploadArtifacts } from "@kinora/core";
|
|
4
5
|
// src/convert.ts
|
|
5
6
|
function identity(test) {
|
|
6
7
|
const file = test.module.relativeModuleId;
|
|
@@ -203,7 +204,11 @@ var KinoraVitestReporter = class {
|
|
|
203
204
|
return;
|
|
204
205
|
}
|
|
205
206
|
const { tests, skippedNodeTests } = toNormTests(modules, this.options.include);
|
|
206
|
-
const
|
|
207
|
+
const prOptions = resolvePrReportOptions(this.options.prComment, this.options.prStatus);
|
|
208
|
+
const group = this.shard && this.options.groupKey !== false ? resolveShardGroup(process.env, {
|
|
209
|
+
groupKey: this.options.groupKey,
|
|
210
|
+
leg: prLegLabel(prOptions)
|
|
211
|
+
}) : void 0;
|
|
207
212
|
if (!tests.length) {
|
|
208
213
|
if (!group) {
|
|
209
214
|
console.warn(skippedNodeTests ? `[kinora] nothing uploaded: no browser tests in this run (${skippedNodeTests} Node tests left out). Set include: 'all' to upload Node tests too.` : "[kinora] nothing uploaded: no tests ran");
|
|
@@ -234,31 +239,51 @@ var KinoraVitestReporter = class {
|
|
|
234
239
|
const client = createIngestClient({
|
|
235
240
|
baseUrl: url,
|
|
236
241
|
token,
|
|
242
|
+
regression: !!(prOptions.comment || prOptions.status),
|
|
237
243
|
onRetry: (info) => console.warn(`[kinora] ${describeRetry(info)}`)
|
|
238
244
|
});
|
|
239
245
|
const res = await client.uploadRun(payload);
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
try {
|
|
245
|
-
await client.uploadArtifact({
|
|
246
|
-
runId: res.runId,
|
|
247
|
-
testKey: t.testKey,
|
|
248
|
-
name: a.name,
|
|
249
|
-
contentType: a.contentType,
|
|
250
|
-
body: await readFile(a.path)
|
|
251
|
-
});
|
|
252
|
-
artifacts++;
|
|
253
|
-
} catch (err) {
|
|
254
|
-
console.warn(`[kinora] ${a.name} upload failed for ${t.testKey}:`, err instanceof Error ? err.message : err);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
246
|
+
const artifacts = await uploadArtifacts(client, res.runId, artifactsToUpload(tests, this.options.uploadAttachments ?? DEFAULT_UPLOAD_ATTACHMENTS), {
|
|
247
|
+
read: readFile,
|
|
248
|
+
onFailed: (a, err) => console.warn(`[kinora] ${a.name} upload failed for ${a.testKey}:`, err instanceof Error ? err.message : err)
|
|
249
|
+
});
|
|
257
250
|
console.log(`[kinora] uploaded ${res.tests} tests + ${artifacts} artifacts (run ${res.runId}${res.shardProgress ? `, ${res.shardProgress.landed} of ${res.shardProgress.total} shards` : ""})`);
|
|
251
|
+
if (res.incident) console.warn(`[kinora] environment incident, not counted: ${res.incident.reason}`);
|
|
252
|
+
await this.maybePostToPr(prOptions, payload, res);
|
|
258
253
|
} catch (err) {
|
|
259
254
|
if (err instanceof IngestError && err.status === 402) console.warn(`[kinora] ${err.message}`);
|
|
260
255
|
else console.error("[kinora] upload failed:", err instanceof Error ? err.message : err);
|
|
261
256
|
}
|
|
262
257
|
}
|
|
258
|
+
async maybePostToPr(opts, payload, res) {
|
|
259
|
+
if (!opts.comment && !opts.status) return;
|
|
260
|
+
if (this.shard && !res.shardProgress) return;
|
|
261
|
+
const ctx = resolvePrContext(process.env, (p) => {
|
|
262
|
+
try {
|
|
263
|
+
return readFileSync(p, "utf8");
|
|
264
|
+
} catch {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
if (!ctx) return;
|
|
269
|
+
await postToPr(ctx, opts, {
|
|
270
|
+
projectSlug: payload.project.slug,
|
|
271
|
+
projectName: payload.project.name,
|
|
272
|
+
runUrl: res.runUrl,
|
|
273
|
+
ciRunUrl: payload.run.ci?.runUrl,
|
|
274
|
+
counts: res.counts ?? payload.run.counts,
|
|
275
|
+
regression: res.regression,
|
|
276
|
+
flaky: res.flaky ?? flakyTestsOf(payload.tests),
|
|
277
|
+
baseBranch: payload.run.git?.baseBranch,
|
|
278
|
+
...res.shardProgress && { shards: {
|
|
279
|
+
runId: res.runId,
|
|
280
|
+
...res.shardProgress
|
|
281
|
+
} },
|
|
282
|
+
...res.incident && { incident: res.incident }
|
|
283
|
+
}, {
|
|
284
|
+
info: (m) => console.warn(`[kinora] ${m}`),
|
|
285
|
+
warn: (m) => console.warn(`[kinora] ${m}`)
|
|
286
|
+
});
|
|
287
|
+
}
|
|
263
288
|
};
|
|
264
289
|
export { KinoraVitestReporter as default };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kinora/vitest-reporter",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"description": "Vitest reporter that uploads browser-mode and Storybook test results to a kinora server",
|
|
6
6
|
"author": "Joris Gallot",
|
|
7
7
|
"license": "MIT",
|
|
@@ -37,14 +37,14 @@
|
|
|
37
37
|
"vitest": ">=4.1.12"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@kinora/core": "0.
|
|
40
|
+
"@kinora/core": "0.18.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@types/node": "^26.6.
|
|
44
|
-
"@vitest/coverage-v8": "^5.0
|
|
45
|
-
"tsdown": "^0.23.
|
|
43
|
+
"@types/node": "^26.6.6",
|
|
44
|
+
"@vitest/coverage-v8": "^5.1.0",
|
|
45
|
+
"tsdown": "^0.23.7",
|
|
46
46
|
"typescript": "~6.0.3",
|
|
47
|
-
"vitest": "^5.0
|
|
47
|
+
"vitest": "^5.1.0"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsdown",
|