@elench/testkit 0.1.32 → 0.1.34
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/runner/artifacts.mjs +43 -0
- package/lib/runner/default-runtime-errors.mjs +53 -0
- package/lib/runner/default-runtime-errors.test.mjs +49 -0
- package/lib/runner/default-runtime-runner.mjs +119 -0
- package/lib/runner/formatting.mjs +129 -0
- package/lib/runner/formatting.test.mjs +100 -0
- package/lib/runner/index.mjs +2 -1575
- package/lib/runner/maintenance.mjs +72 -0
- package/lib/runner/orchestrator.mjs +254 -0
- package/lib/runner/playwright-config.mjs +61 -0
- package/lib/runner/playwright-config.test.mjs +58 -0
- package/lib/runner/playwright-runner.mjs +85 -0
- package/lib/runner/processes.mjs +106 -0
- package/lib/runner/readiness.mjs +117 -0
- package/lib/runner/reporting.mjs +180 -0
- package/lib/runner/reporting.test.mjs +193 -0
- package/lib/runner/results.mjs +36 -266
- package/lib/runner/results.test.mjs +4 -204
- package/lib/runner/runtime-contexts.mjs +133 -0
- package/lib/runner/selection.mjs +33 -0
- package/lib/runner/selection.test.mjs +25 -0
- package/lib/runner/services.mjs +73 -0
- package/lib/runner/state-io.mjs +25 -0
- package/lib/runner/worker-loop.mjs +95 -0
- package/package.json +1 -1
package/lib/runner/results.mjs
CHANGED
|
@@ -32,13 +32,6 @@ export function buildServiceTrackers(servicePlans, startedAt) {
|
|
|
32
32
|
completedFileCount: 0,
|
|
33
33
|
failedFiles: [],
|
|
34
34
|
failedFileSet: new Set(),
|
|
35
|
-
fileResults: suite.files.map((file) => ({
|
|
36
|
-
path: normalizePathSeparators(file),
|
|
37
|
-
failed: false,
|
|
38
|
-
durationMs: 0,
|
|
39
|
-
error: null,
|
|
40
|
-
status: "not_run",
|
|
41
|
-
})),
|
|
42
35
|
fileResultsByPath: new Map(
|
|
43
36
|
suite.files.map((file) => {
|
|
44
37
|
const normalizedPath = normalizePathSeparators(file);
|
|
@@ -57,9 +50,6 @@ export function buildServiceTrackers(servicePlans, startedAt) {
|
|
|
57
50
|
durationMs: 0,
|
|
58
51
|
error: null,
|
|
59
52
|
}));
|
|
60
|
-
for (const suite of suites) {
|
|
61
|
-
suite.fileResults = [...suite.fileResultsByPath.values()];
|
|
62
|
-
}
|
|
63
53
|
|
|
64
54
|
trackers.set(plan.config.name, {
|
|
65
55
|
name: plan.config.name,
|
|
@@ -112,15 +102,13 @@ export function recordTaskOutcome(trackers, task, outcome, finishedAt = Date.now
|
|
|
112
102
|
existingFileResult.error = outcome.error;
|
|
113
103
|
existingFileResult.status = outcome.failed ? "failed" : "passed";
|
|
114
104
|
} else {
|
|
115
|
-
|
|
105
|
+
suite.fileResultsByPath.set(normalizedPath, {
|
|
116
106
|
path: normalizedPath,
|
|
117
107
|
failed: outcome.failed,
|
|
118
108
|
durationMs: outcomeDurationMs,
|
|
119
109
|
error: outcome.error,
|
|
120
110
|
status: outcome.failed ? "failed" : "passed",
|
|
121
|
-
};
|
|
122
|
-
suite.fileResultsByPath.set(normalizedPath, fileResult);
|
|
123
|
-
suite.fileResults.push(fileResult);
|
|
111
|
+
});
|
|
124
112
|
}
|
|
125
113
|
if (outcome.failed && !suite.failedFileSet.has(task.file)) {
|
|
126
114
|
suite.failedFileSet.add(task.file);
|
|
@@ -164,25 +152,18 @@ export function finalizeServiceResult(tracker, startedAt, finishedAt) {
|
|
|
164
152
|
};
|
|
165
153
|
}
|
|
166
154
|
|
|
167
|
-
const suites = [...tracker.suites]
|
|
168
|
-
(a, b) => a.orderIndex - b.orderIndex || a.name.localeCompare(b.name)
|
|
169
|
-
|
|
155
|
+
const suites = [...tracker.suites]
|
|
156
|
+
.sort((a, b) => a.orderIndex - b.orderIndex || a.name.localeCompare(b.name))
|
|
157
|
+
.map((suite) => finalizeSuite(suite));
|
|
158
|
+
|
|
170
159
|
const completedSuiteCount = suites.filter(
|
|
171
160
|
(suite) => suite.completedFileCount === suite.fileCount
|
|
172
161
|
).length;
|
|
173
|
-
const failedSuiteCount = suites.filter((suite) => suite.
|
|
162
|
+
const failedSuiteCount = suites.filter((suite) => suite.failedFileCount > 0).length;
|
|
174
163
|
const totalFileCount = suites.reduce((sum, suite) => sum + suite.fileCount, 0);
|
|
175
|
-
const completedFileCount = suites.reduce(
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
);
|
|
179
|
-
const failedFileCount = suites.reduce((sum, suite) => sum + suite.failedFiles.length, 0);
|
|
180
|
-
const passedFileCount = suites.reduce(
|
|
181
|
-
(sum, suite) =>
|
|
182
|
-
sum +
|
|
183
|
-
suite.fileResults.filter((file) => file.status === "passed").length,
|
|
184
|
-
0
|
|
185
|
-
);
|
|
164
|
+
const completedFileCount = suites.reduce((sum, suite) => sum + suite.completedFileCount, 0);
|
|
165
|
+
const failedFileCount = suites.reduce((sum, suite) => sum + suite.failedFileCount, 0);
|
|
166
|
+
const passedFileCount = suites.reduce((sum, suite) => sum + suite.passedFileCount, 0);
|
|
186
167
|
const notRunFileCount = totalFileCount - completedFileCount;
|
|
187
168
|
const totalTaskDurationMs =
|
|
188
169
|
tracker.totalTaskDurationMs || suites.reduce((sum, suite) => sum + suite.durationMs, 0);
|
|
@@ -209,207 +190,11 @@ export function finalizeServiceResult(tracker, startedAt, finishedAt) {
|
|
|
209
190
|
notRunFileCount,
|
|
210
191
|
durationMs,
|
|
211
192
|
totalTaskDurationMs,
|
|
212
|
-
suites
|
|
213
|
-
name: suite.name,
|
|
214
|
-
type: suite.type,
|
|
215
|
-
framework: formatFrameworkForArtifact(suite.framework),
|
|
216
|
-
failed: suite.failedFiles.length > 0,
|
|
217
|
-
fileCount: suite.fileCount,
|
|
218
|
-
completedFileCount: suite.completedFileCount,
|
|
219
|
-
passedFileCount: suite.fileResults.filter((file) => file.status === "passed").length,
|
|
220
|
-
failedFileCount: suite.failedFiles.length,
|
|
221
|
-
notRunFileCount: suite.fileCount - suite.completedFileCount,
|
|
222
|
-
failedFiles: suite.failedFiles,
|
|
223
|
-
durationMs: suite.durationMs,
|
|
224
|
-
error: suite.error,
|
|
225
|
-
files: suite.fileResults
|
|
226
|
-
.slice()
|
|
227
|
-
.sort((a, b) => a.path.localeCompare(b.path))
|
|
228
|
-
.map((file) => ({
|
|
229
|
-
path: file.path,
|
|
230
|
-
failed: file.failed,
|
|
231
|
-
status: file.status,
|
|
232
|
-
durationMs: file.durationMs,
|
|
233
|
-
error: file.error,
|
|
234
|
-
})),
|
|
235
|
-
})),
|
|
193
|
+
suites,
|
|
236
194
|
errors: tracker.errors,
|
|
237
195
|
};
|
|
238
196
|
}
|
|
239
197
|
|
|
240
|
-
export function buildStatusArtifact({
|
|
241
|
-
productDir,
|
|
242
|
-
results,
|
|
243
|
-
suiteType,
|
|
244
|
-
suiteNames,
|
|
245
|
-
fileNames,
|
|
246
|
-
framework,
|
|
247
|
-
shard,
|
|
248
|
-
serviceFilter,
|
|
249
|
-
metadata,
|
|
250
|
-
}) {
|
|
251
|
-
const executedResults = results.filter((result) => !result.skipped);
|
|
252
|
-
const tests = [];
|
|
253
|
-
|
|
254
|
-
for (const result of executedResults) {
|
|
255
|
-
for (const suite of result.suites) {
|
|
256
|
-
for (const file of suite.files) {
|
|
257
|
-
tests.push({
|
|
258
|
-
service: result.name,
|
|
259
|
-
type: suite.type,
|
|
260
|
-
path: file.path,
|
|
261
|
-
status: file.status,
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
tests.sort(
|
|
268
|
-
(left, right) =>
|
|
269
|
-
left.service.localeCompare(right.service) ||
|
|
270
|
-
left.type.localeCompare(right.type) ||
|
|
271
|
-
left.path.localeCompare(right.path)
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
const summary = {
|
|
275
|
-
services: {
|
|
276
|
-
total: executedResults.length,
|
|
277
|
-
passed: executedResults.filter((result) => !result.failed).length,
|
|
278
|
-
failed: executedResults.filter((result) => result.failed).length,
|
|
279
|
-
},
|
|
280
|
-
tests: {
|
|
281
|
-
total: tests.length,
|
|
282
|
-
passed: tests.filter((test) => test.status === "passed").length,
|
|
283
|
-
failed: tests.filter((test) => test.status === "failed").length,
|
|
284
|
-
notRun: tests.filter((test) => test.status === "not_run").length,
|
|
285
|
-
},
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const scope = {
|
|
289
|
-
suiteType,
|
|
290
|
-
suiteNames: [...(suiteNames || [])].sort(),
|
|
291
|
-
fileNames: [...(fileNames || [])].sort(),
|
|
292
|
-
framework: formatFrameworkForArtifact(framework || "all"),
|
|
293
|
-
shard: shard || null,
|
|
294
|
-
serviceFilter: serviceFilter || null,
|
|
295
|
-
};
|
|
296
|
-
scope.isFullRun =
|
|
297
|
-
scope.suiteNames.length === 0 &&
|
|
298
|
-
scope.fileNames.length === 0 &&
|
|
299
|
-
scope.framework === "all" &&
|
|
300
|
-
scope.shard === null &&
|
|
301
|
-
scope.serviceFilter === null;
|
|
302
|
-
|
|
303
|
-
return {
|
|
304
|
-
schemaVersion: 1,
|
|
305
|
-
source: "testkit",
|
|
306
|
-
notice: "Generated file. Do not edit manually.",
|
|
307
|
-
product: {
|
|
308
|
-
name: path.basename(productDir),
|
|
309
|
-
},
|
|
310
|
-
git: {
|
|
311
|
-
branch: metadata.git?.branch || null,
|
|
312
|
-
commitSha: metadata.git?.commitSha || null,
|
|
313
|
-
},
|
|
314
|
-
testkitVersion: metadata.testkitVersion,
|
|
315
|
-
scope,
|
|
316
|
-
summary,
|
|
317
|
-
tests,
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
export function buildRunArtifact({
|
|
322
|
-
productDir,
|
|
323
|
-
results,
|
|
324
|
-
startedAt,
|
|
325
|
-
finishedAt,
|
|
326
|
-
requestedJobs,
|
|
327
|
-
workerCount,
|
|
328
|
-
suiteType,
|
|
329
|
-
suiteNames,
|
|
330
|
-
fileNames,
|
|
331
|
-
framework,
|
|
332
|
-
shard,
|
|
333
|
-
serviceFilter,
|
|
334
|
-
metadata,
|
|
335
|
-
}) {
|
|
336
|
-
const executed = results.filter((result) => !result.skipped);
|
|
337
|
-
const failedServices = executed.filter((result) => result.failed);
|
|
338
|
-
const totalSuites = executed.reduce((sum, result) => sum + result.suiteCount, 0);
|
|
339
|
-
const completedSuites = executed.reduce((sum, result) => sum + result.completedSuiteCount, 0);
|
|
340
|
-
const failedSuites = executed.reduce((sum, result) => sum + result.failedSuiteCount, 0);
|
|
341
|
-
const totalFiles = executed.reduce((sum, result) => sum + (result.totalFileCount || 0), 0);
|
|
342
|
-
const passedFiles = executed.reduce((sum, result) => sum + (result.passedFileCount || 0), 0);
|
|
343
|
-
const failedFiles = executed.reduce((sum, result) => sum + (result.failedFileCount || 0), 0);
|
|
344
|
-
const notRunFiles = executed.reduce((sum, result) => sum + (result.notRunFileCount || 0), 0);
|
|
345
|
-
const dbBackend = summarizeDbBackend(results);
|
|
346
|
-
|
|
347
|
-
return {
|
|
348
|
-
schemaVersion: 1,
|
|
349
|
-
source: "testkit",
|
|
350
|
-
generatedAt: new Date(finishedAt).toISOString(),
|
|
351
|
-
product: {
|
|
352
|
-
name: path.basename(productDir),
|
|
353
|
-
directory: productDir,
|
|
354
|
-
},
|
|
355
|
-
git: metadata.git,
|
|
356
|
-
host: metadata.host,
|
|
357
|
-
run: {
|
|
358
|
-
status: failedServices.length > 0 ? "failed" : "passed",
|
|
359
|
-
startedAt: new Date(startedAt).toISOString(),
|
|
360
|
-
finishedAt: new Date(finishedAt).toISOString(),
|
|
361
|
-
durationMs: finishedAt - startedAt,
|
|
362
|
-
requestedJobs,
|
|
363
|
-
workerCount,
|
|
364
|
-
dbBackend,
|
|
365
|
-
suiteType,
|
|
366
|
-
suiteNames,
|
|
367
|
-
fileNames,
|
|
368
|
-
framework: formatFrameworkForArtifact(framework),
|
|
369
|
-
shard,
|
|
370
|
-
serviceFilter,
|
|
371
|
-
testkitVersion: metadata.testkitVersion,
|
|
372
|
-
},
|
|
373
|
-
summary: {
|
|
374
|
-
services: {
|
|
375
|
-
total: executed.length,
|
|
376
|
-
passed: executed.length - failedServices.length,
|
|
377
|
-
failed: failedServices.length,
|
|
378
|
-
},
|
|
379
|
-
suites: {
|
|
380
|
-
total: totalSuites,
|
|
381
|
-
completed: completedSuites,
|
|
382
|
-
passed: completedSuites - failedSuites,
|
|
383
|
-
failed: failedSuites,
|
|
384
|
-
},
|
|
385
|
-
files: {
|
|
386
|
-
total: totalFiles,
|
|
387
|
-
passed: passedFiles,
|
|
388
|
-
failed: failedFiles,
|
|
389
|
-
notRun: notRunFiles,
|
|
390
|
-
},
|
|
391
|
-
},
|
|
392
|
-
services: results.map((result) => ({
|
|
393
|
-
name: result.name,
|
|
394
|
-
failed: result.failed,
|
|
395
|
-
skipped: result.skipped,
|
|
396
|
-
suiteCount: result.suiteCount,
|
|
397
|
-
completedSuiteCount: result.completedSuiteCount,
|
|
398
|
-
failedSuiteCount: result.failedSuiteCount,
|
|
399
|
-
totalFileCount: result.totalFileCount,
|
|
400
|
-
completedFileCount: result.completedFileCount,
|
|
401
|
-
passedFileCount: result.passedFileCount,
|
|
402
|
-
failedFileCount: result.failedFileCount,
|
|
403
|
-
notRunFileCount: result.notRunFileCount,
|
|
404
|
-
durationMs: result.durationMs,
|
|
405
|
-
totalTaskDurationMs: result.totalTaskDurationMs,
|
|
406
|
-
dbBackend: result.dbBackend,
|
|
407
|
-
suites: result.suites,
|
|
408
|
-
errors: result.errors,
|
|
409
|
-
})),
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
|
|
413
198
|
export function summarizeDbBackend(results) {
|
|
414
199
|
const values = [...new Set(results.map((result) => result.dbBackend).filter(Boolean))];
|
|
415
200
|
if (values.length === 0) return null;
|
|
@@ -417,36 +202,32 @@ export function summarizeDbBackend(results) {
|
|
|
417
202
|
return "mixed";
|
|
418
203
|
}
|
|
419
204
|
|
|
420
|
-
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
const notRunSuites = result.suiteCount - result.completedSuiteCount;
|
|
431
|
-
let detail = `${passedSuites}/${result.suiteCount} suites passed`;
|
|
432
|
-
if ((result.totalFileCount || 0) > 0) {
|
|
433
|
-
detail += `, ${result.passedFileCount}/${result.totalFileCount} files passed`;
|
|
434
|
-
}
|
|
435
|
-
if (notRunSuites > 0) {
|
|
436
|
-
detail += `, ${notRunSuites} ${pluralize(notRunSuites, "suite", "suites")} not run`;
|
|
437
|
-
} else if ((result.notRunFileCount || 0) > 0) {
|
|
438
|
-
detail += `, ${result.notRunFileCount} ${pluralize(result.notRunFileCount, "file", "files")} not run`;
|
|
439
|
-
}
|
|
440
|
-
return detail;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
export function formatError(error) {
|
|
444
|
-
if (error instanceof Error) return sanitizeErrorMessage(error.message);
|
|
445
|
-
return sanitizeErrorMessage(String(error));
|
|
446
|
-
}
|
|
205
|
+
function finalizeSuite(suite) {
|
|
206
|
+
const files = [...suite.fileResultsByPath.values()]
|
|
207
|
+
.sort((a, b) => a.path.localeCompare(b.path))
|
|
208
|
+
.map((file) => ({
|
|
209
|
+
path: file.path,
|
|
210
|
+
failed: file.failed,
|
|
211
|
+
status: file.status,
|
|
212
|
+
durationMs: file.durationMs,
|
|
213
|
+
error: file.error,
|
|
214
|
+
}));
|
|
447
215
|
|
|
448
|
-
|
|
449
|
-
|
|
216
|
+
return {
|
|
217
|
+
name: suite.name,
|
|
218
|
+
type: suite.type,
|
|
219
|
+
framework: formatFrameworkForArtifact(suite.framework),
|
|
220
|
+
failed: suite.failedFiles.length > 0,
|
|
221
|
+
fileCount: suite.fileCount,
|
|
222
|
+
completedFileCount: suite.completedFileCount,
|
|
223
|
+
passedFileCount: files.filter((file) => file.status === "passed").length,
|
|
224
|
+
failedFileCount: suite.failedFiles.length,
|
|
225
|
+
notRunFileCount: suite.fileCount - suite.completedFileCount,
|
|
226
|
+
failedFiles: suite.failedFiles,
|
|
227
|
+
durationMs: suite.durationMs,
|
|
228
|
+
error: suite.error,
|
|
229
|
+
files,
|
|
230
|
+
};
|
|
450
231
|
}
|
|
451
232
|
|
|
452
233
|
function normalizePathSeparators(filePath) {
|
|
@@ -457,14 +238,3 @@ function formatFrameworkForArtifact(framework) {
|
|
|
457
238
|
if (framework === "k6") return "default";
|
|
458
239
|
return framework;
|
|
459
240
|
}
|
|
460
|
-
|
|
461
|
-
function sanitizeErrorMessage(message) {
|
|
462
|
-
return message
|
|
463
|
-
.replace(/Command failed with exit code (\d+): .*?[\\/]vendor[\\/]k6 run\b/g, "Default runtime failed with exit code $1:")
|
|
464
|
-
.replace(/Command failed with exit code (\d+): k6 run\b/g, "Default runtime failed with exit code $1:")
|
|
465
|
-
.replace(/[\\/]vendor[\\/]k6\b/g, "default-runtime");
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
function pluralize(value, singular, plural) {
|
|
469
|
-
return value === 1 ? singular : plural;
|
|
470
|
-
}
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import {
|
|
3
3
|
addTrackerError,
|
|
4
|
-
buildRunArtifact,
|
|
5
|
-
buildStatusArtifact,
|
|
6
4
|
buildServiceTrackers,
|
|
7
5
|
finalizeServiceResult,
|
|
8
|
-
formatDuration,
|
|
9
|
-
formatError,
|
|
10
|
-
formatServiceSummary,
|
|
11
6
|
recordGraphError,
|
|
12
7
|
recordTaskOutcome,
|
|
13
8
|
summarizeDbBackend,
|
|
14
9
|
} from "./results.mjs";
|
|
15
10
|
|
|
16
|
-
describe("runner
|
|
11
|
+
describe("runner results", () => {
|
|
17
12
|
it("tracks task outcomes and graph errors", () => {
|
|
18
13
|
const trackers = buildServiceTrackers(
|
|
19
14
|
[
|
|
@@ -198,204 +193,9 @@ describe("runner-results", () => {
|
|
|
198
193
|
expect(result.totalTaskDurationMs).toBe(3_000);
|
|
199
194
|
});
|
|
200
195
|
|
|
201
|
-
it("
|
|
202
|
-
const results = [
|
|
203
|
-
{
|
|
204
|
-
name: "api",
|
|
205
|
-
failed: false,
|
|
206
|
-
skipped: false,
|
|
207
|
-
suiteCount: 1,
|
|
208
|
-
completedSuiteCount: 1,
|
|
209
|
-
failedSuiteCount: 0,
|
|
210
|
-
totalFileCount: 3,
|
|
211
|
-
completedFileCount: 3,
|
|
212
|
-
passedFileCount: 3,
|
|
213
|
-
failedFileCount: 0,
|
|
214
|
-
notRunFileCount: 0,
|
|
215
|
-
durationMs: 1200,
|
|
216
|
-
totalTaskDurationMs: 2400,
|
|
217
|
-
dbBackend: "local",
|
|
218
|
-
suites: [],
|
|
219
|
-
errors: [],
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
name: "frontend",
|
|
223
|
-
failed: false,
|
|
224
|
-
skipped: true,
|
|
225
|
-
suiteCount: 0,
|
|
226
|
-
completedSuiteCount: 0,
|
|
227
|
-
failedSuiteCount: 0,
|
|
228
|
-
totalFileCount: 0,
|
|
229
|
-
completedFileCount: 0,
|
|
230
|
-
passedFileCount: 0,
|
|
231
|
-
failedFileCount: 0,
|
|
232
|
-
notRunFileCount: 0,
|
|
233
|
-
durationMs: 0,
|
|
234
|
-
totalTaskDurationMs: 0,
|
|
235
|
-
dbBackend: null,
|
|
236
|
-
suites: [],
|
|
237
|
-
errors: [],
|
|
238
|
-
},
|
|
239
|
-
];
|
|
240
|
-
|
|
241
|
-
const artifact = buildRunArtifact({
|
|
242
|
-
productDir: "/tmp/my-product",
|
|
243
|
-
results,
|
|
244
|
-
startedAt: 1000,
|
|
245
|
-
finishedAt: 4000,
|
|
246
|
-
requestedJobs: 2,
|
|
247
|
-
workerCount: 1,
|
|
248
|
-
suiteType: "all",
|
|
249
|
-
suiteNames: [],
|
|
250
|
-
fileNames: [],
|
|
251
|
-
framework: "all",
|
|
252
|
-
shard: null,
|
|
253
|
-
serviceFilter: null,
|
|
254
|
-
metadata: {
|
|
255
|
-
git: {
|
|
256
|
-
branch: "main",
|
|
257
|
-
commitSha: "abc",
|
|
258
|
-
repoRoot: "/tmp",
|
|
259
|
-
},
|
|
260
|
-
host: {
|
|
261
|
-
hostname: "local",
|
|
262
|
-
username: "dev",
|
|
263
|
-
},
|
|
264
|
-
testkitVersion: "0.1.17",
|
|
265
|
-
},
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
expect(artifact.product.name).toBe("my-product");
|
|
269
|
-
expect(artifact.summary.services.total).toBe(1);
|
|
270
|
-
expect(artifact.summary.files).toEqual({
|
|
271
|
-
total: 3,
|
|
272
|
-
passed: 3,
|
|
273
|
-
failed: 0,
|
|
274
|
-
notRun: 0,
|
|
275
|
-
});
|
|
276
|
-
expect(artifact.services[0].durationMs).toBe(1200);
|
|
277
|
-
expect(artifact.services[0].totalTaskDurationMs).toBe(2400);
|
|
278
|
-
expect(summarizeDbBackend(results)).toBe("local");
|
|
279
|
-
expect(formatDuration(65_000)).toBe("1m 05s");
|
|
196
|
+
it("summarizes mixed db backends", () => {
|
|
280
197
|
expect(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
failedSuiteCount: 1,
|
|
284
|
-
suiteCount: 3,
|
|
285
|
-
totalFileCount: 6,
|
|
286
|
-
passedFileCount: 5,
|
|
287
|
-
notRunFileCount: 1,
|
|
288
|
-
})
|
|
289
|
-
).toBe("1/3 suites passed, 5/6 files passed, 1 suite not run");
|
|
290
|
-
expect(formatError(new Error("boom"))).toBe("boom");
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
it("builds deterministic status artifacts", () => {
|
|
294
|
-
const status = buildStatusArtifact({
|
|
295
|
-
productDir: "/tmp/my-product",
|
|
296
|
-
results: [
|
|
297
|
-
{
|
|
298
|
-
name: "api",
|
|
299
|
-
failed: true,
|
|
300
|
-
skipped: false,
|
|
301
|
-
suites: [
|
|
302
|
-
{
|
|
303
|
-
name: "health",
|
|
304
|
-
type: "integration",
|
|
305
|
-
framework: "k6",
|
|
306
|
-
files: [
|
|
307
|
-
{ path: "tests/api/integration/a.int.testkit.ts", status: "passed" },
|
|
308
|
-
{ path: "tests/api/integration/b.int.testkit.ts", status: "failed" },
|
|
309
|
-
],
|
|
310
|
-
},
|
|
311
|
-
],
|
|
312
|
-
},
|
|
313
|
-
],
|
|
314
|
-
suiteType: "int",
|
|
315
|
-
suiteNames: ["health"],
|
|
316
|
-
fileNames: ["tests/api/integration/b.int.testkit.ts"],
|
|
317
|
-
framework: "default",
|
|
318
|
-
shard: null,
|
|
319
|
-
serviceFilter: "api",
|
|
320
|
-
metadata: {
|
|
321
|
-
git: {
|
|
322
|
-
branch: "main",
|
|
323
|
-
commitSha: "abc123",
|
|
324
|
-
},
|
|
325
|
-
testkitVersion: "0.1.20",
|
|
326
|
-
},
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
expect(status).toEqual({
|
|
330
|
-
schemaVersion: 1,
|
|
331
|
-
source: "testkit",
|
|
332
|
-
notice: "Generated file. Do not edit manually.",
|
|
333
|
-
product: {
|
|
334
|
-
name: "my-product",
|
|
335
|
-
},
|
|
336
|
-
git: {
|
|
337
|
-
branch: "main",
|
|
338
|
-
commitSha: "abc123",
|
|
339
|
-
},
|
|
340
|
-
testkitVersion: "0.1.20",
|
|
341
|
-
scope: {
|
|
342
|
-
suiteType: "int",
|
|
343
|
-
suiteNames: ["health"],
|
|
344
|
-
fileNames: ["tests/api/integration/b.int.testkit.ts"],
|
|
345
|
-
framework: "default",
|
|
346
|
-
shard: null,
|
|
347
|
-
serviceFilter: "api",
|
|
348
|
-
isFullRun: false,
|
|
349
|
-
},
|
|
350
|
-
summary: {
|
|
351
|
-
services: {
|
|
352
|
-
total: 1,
|
|
353
|
-
passed: 0,
|
|
354
|
-
failed: 1,
|
|
355
|
-
},
|
|
356
|
-
tests: {
|
|
357
|
-
total: 2,
|
|
358
|
-
passed: 1,
|
|
359
|
-
failed: 1,
|
|
360
|
-
notRun: 0,
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
tests: [
|
|
364
|
-
{
|
|
365
|
-
service: "api",
|
|
366
|
-
type: "integration",
|
|
367
|
-
path: "tests/api/integration/a.int.testkit.ts",
|
|
368
|
-
status: "passed",
|
|
369
|
-
},
|
|
370
|
-
{
|
|
371
|
-
service: "api",
|
|
372
|
-
type: "integration",
|
|
373
|
-
path: "tests/api/integration/b.int.testkit.ts",
|
|
374
|
-
status: "failed",
|
|
375
|
-
},
|
|
376
|
-
],
|
|
377
|
-
});
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
it("marks unfiltered status artifacts as full runs", () => {
|
|
381
|
-
const status = buildStatusArtifact({
|
|
382
|
-
productDir: "/tmp/my-product",
|
|
383
|
-
results: [],
|
|
384
|
-
suiteType: "all",
|
|
385
|
-
suiteNames: [],
|
|
386
|
-
fileNames: [],
|
|
387
|
-
framework: "all",
|
|
388
|
-
shard: null,
|
|
389
|
-
serviceFilter: null,
|
|
390
|
-
metadata: {
|
|
391
|
-
git: {
|
|
392
|
-
branch: "main",
|
|
393
|
-
commitSha: "abc123",
|
|
394
|
-
},
|
|
395
|
-
testkitVersion: "0.1.20",
|
|
396
|
-
},
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
expect(status.scope.isFullRun).toBe(true);
|
|
198
|
+
summarizeDbBackend([{ dbBackend: "local" }, { dbBackend: "neon" }])
|
|
199
|
+
).toBe("mixed");
|
|
400
200
|
});
|
|
401
201
|
});
|