@plune-ai/cli 0.17.0 → 0.17.1
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 +116 -1
- package/dist/cli.cjs +875 -223
- package/dist/index.cjs +105 -42
- package/dist/index.d.cts +188 -1
- package/dist/index.d.ts +188 -1
- package/dist/index.js +101 -41
- package/dist/reporter-core.cjs +244 -40
- package/dist/reporter-core.d.cts +35 -0
- package/dist/reporter-core.d.ts +35 -0
- package/dist/reporter-core.js +240 -36
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -35,19 +35,22 @@ __export(src_exports, {
|
|
|
35
35
|
SyncFileError: () => SyncFileError,
|
|
36
36
|
SyncHttpError: () => SyncHttpError,
|
|
37
37
|
SyncNetworkError: () => SyncNetworkError,
|
|
38
|
+
TEST_CASE_SCHEMA_VERSION: () => TEST_CASE_SCHEMA_VERSION,
|
|
38
39
|
TokenRejectedError: () => TokenRejectedError,
|
|
39
40
|
assertionConfigSchema: () => assertionConfigSchema,
|
|
40
|
-
assertionResultRecordSchema: () =>
|
|
41
|
+
assertionResultRecordSchema: () => assertionResultRecordSchema2,
|
|
41
42
|
binaryVerdictSchema: () => binaryVerdictSchema,
|
|
42
43
|
formatIngestResult: () => formatIngestResult,
|
|
43
44
|
ingest: () => handleIngest,
|
|
44
45
|
parseRunResult: () => parseRunResult,
|
|
46
|
+
parseTestCase: () => parseTestCase,
|
|
45
47
|
readCairnRun: () => readCairnRun,
|
|
46
48
|
reportIngestFailure: () => reportIngestFailure,
|
|
47
49
|
reportSyncFailure: () => reportSyncFailure,
|
|
48
50
|
run: () => handleRun,
|
|
49
51
|
runResultSchema: () => runResultSchema,
|
|
50
|
-
sync: () => handleSync
|
|
52
|
+
sync: () => handleSync,
|
|
53
|
+
testCaseSchema: () => testCaseSchema
|
|
51
54
|
});
|
|
52
55
|
module.exports = __toCommonJS(src_exports);
|
|
53
56
|
|
|
@@ -1552,59 +1555,116 @@ var fs6 = __toESM(require("fs"), 1);
|
|
|
1552
1555
|
var path5 = __toESM(require("path"), 1);
|
|
1553
1556
|
|
|
1554
1557
|
// src/types/run-result-schema.ts
|
|
1558
|
+
var import_zod3 = require("zod");
|
|
1559
|
+
|
|
1560
|
+
// src/types/test-case-schema.ts
|
|
1555
1561
|
var import_zod2 = require("zod");
|
|
1556
|
-
var
|
|
1557
|
-
var
|
|
1558
|
-
|
|
1559
|
-
|
|
1562
|
+
var TEST_CASE_SCHEMA_VERSION = 2;
|
|
1563
|
+
var externalKeySchema = import_zod2.z.object({
|
|
1564
|
+
kind: import_zod2.z.enum(["playwright-id", "path-title", "allure-history", "cairn-stable", "eval-id", "qase", "testrail"]),
|
|
1565
|
+
value: import_zod2.z.string().min(1)
|
|
1566
|
+
});
|
|
1567
|
+
var manualStepSchema = import_zod2.z.object({
|
|
1568
|
+
action: import_zod2.z.string().min(1),
|
|
1569
|
+
expected: import_zod2.z.string().min(1).optional()
|
|
1560
1570
|
});
|
|
1561
1571
|
var assertionResultRecordSchema = import_zod2.z.object({
|
|
1562
|
-
type: import_zod2.z.string(),
|
|
1572
|
+
type: import_zod2.z.string().min(1),
|
|
1563
1573
|
passed: import_zod2.z.boolean(),
|
|
1564
1574
|
score: import_zod2.z.number().optional(),
|
|
1565
|
-
reason: import_zod2.z.string().optional()
|
|
1566
|
-
|
|
1575
|
+
reason: import_zod2.z.string().optional()
|
|
1576
|
+
});
|
|
1577
|
+
var manualCaseSchema = import_zod2.z.object({
|
|
1578
|
+
type: import_zod2.z.literal("manual"),
|
|
1579
|
+
steps: import_zod2.z.array(manualStepSchema).min(1),
|
|
1580
|
+
expected: import_zod2.z.string().min(1).optional()
|
|
1581
|
+
});
|
|
1582
|
+
var automatedCaseSchema = import_zod2.z.object({
|
|
1583
|
+
type: import_zod2.z.literal("automated"),
|
|
1584
|
+
specRef: import_zod2.z.string().min(1)
|
|
1585
|
+
});
|
|
1586
|
+
var evalCaseSchema = import_zod2.z.object({
|
|
1587
|
+
type: import_zod2.z.literal("eval"),
|
|
1588
|
+
prompt: import_zod2.z.string().min(1),
|
|
1589
|
+
goldenSetId: import_zod2.z.string().min(1).optional(),
|
|
1590
|
+
assertions: import_zod2.z.array(assertionResultRecordSchema).min(1)
|
|
1591
|
+
});
|
|
1592
|
+
var testCaseBaseSchema = import_zod2.z.object({
|
|
1593
|
+
schemaVersion: import_zod2.z.literal(TEST_CASE_SCHEMA_VERSION),
|
|
1594
|
+
id: import_zod2.z.string().min(1),
|
|
1595
|
+
externalKeys: import_zod2.z.array(externalKeySchema).optional(),
|
|
1596
|
+
/** ADR 0045 / plune#1246 — optional, purely additive; schemaVersion stays 2. */
|
|
1597
|
+
is_flaky: import_zod2.z.boolean().optional(),
|
|
1598
|
+
/** ADR 0045 / plune#1246 — optional, purely additive; schemaVersion stays 2. */
|
|
1599
|
+
is_muted: import_zod2.z.boolean().optional()
|
|
1600
|
+
});
|
|
1601
|
+
var testCaseSchema = import_zod2.z.discriminatedUnion("type", [
|
|
1602
|
+
testCaseBaseSchema.merge(manualCaseSchema),
|
|
1603
|
+
testCaseBaseSchema.merge(automatedCaseSchema),
|
|
1604
|
+
testCaseBaseSchema.merge(evalCaseSchema)
|
|
1605
|
+
]);
|
|
1606
|
+
function parseTestCase(value) {
|
|
1607
|
+
return testCaseSchema.parse(value);
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
// src/types/results.ts
|
|
1611
|
+
var ROW_INCONCLUSIVE = ["blocked", "skipped"];
|
|
1612
|
+
|
|
1613
|
+
// src/types/run-result-schema.ts
|
|
1614
|
+
var RUN_RESULT_SCHEMA_VERSION = 1;
|
|
1615
|
+
var binaryVerdictSchema = import_zod3.z.object({
|
|
1616
|
+
question: import_zod3.z.string().min(1),
|
|
1617
|
+
passed: import_zod3.z.boolean()
|
|
1618
|
+
});
|
|
1619
|
+
var assertionResultRecordSchema2 = import_zod3.z.object({
|
|
1620
|
+
type: import_zod3.z.string(),
|
|
1621
|
+
passed: import_zod3.z.boolean(),
|
|
1622
|
+
score: import_zod3.z.number().optional(),
|
|
1623
|
+
reason: import_zod3.z.string().optional(),
|
|
1624
|
+
binaryVerdicts: import_zod3.z.array(binaryVerdictSchema).optional()
|
|
1567
1625
|
});
|
|
1568
|
-
var usageSchema =
|
|
1569
|
-
input_tokens:
|
|
1570
|
-
output_tokens:
|
|
1571
|
-
cost_usd:
|
|
1626
|
+
var usageSchema = import_zod3.z.object({
|
|
1627
|
+
input_tokens: import_zod3.z.number(),
|
|
1628
|
+
output_tokens: import_zod3.z.number(),
|
|
1629
|
+
cost_usd: import_zod3.z.number()
|
|
1572
1630
|
});
|
|
1573
|
-
var runErrorSchema =
|
|
1574
|
-
code:
|
|
1575
|
-
message:
|
|
1631
|
+
var runErrorSchema = import_zod3.z.object({
|
|
1632
|
+
code: import_zod3.z.string(),
|
|
1633
|
+
message: import_zod3.z.string()
|
|
1576
1634
|
});
|
|
1577
|
-
var rowResultSchema =
|
|
1578
|
-
vars:
|
|
1579
|
-
output:
|
|
1580
|
-
cached:
|
|
1635
|
+
var rowResultSchema = import_zod3.z.object({
|
|
1636
|
+
vars: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown()),
|
|
1637
|
+
output: import_zod3.z.string().nullable(),
|
|
1638
|
+
cached: import_zod3.z.boolean(),
|
|
1581
1639
|
usage: usageSchema.optional(),
|
|
1582
|
-
latency_ms:
|
|
1640
|
+
latency_ms: import_zod3.z.number().optional(),
|
|
1583
1641
|
error: runErrorSchema.optional(),
|
|
1584
|
-
assertions:
|
|
1642
|
+
assertions: import_zod3.z.array(assertionResultRecordSchema2),
|
|
1643
|
+
/** ADR 0045. Optional and additive — the same enum the platform validates on `POST /v1/runs`. */
|
|
1644
|
+
inconclusive: import_zod3.z.enum(ROW_INCONCLUSIVE).optional()
|
|
1585
1645
|
});
|
|
1586
|
-
var summarySchema =
|
|
1587
|
-
total:
|
|
1588
|
-
passed:
|
|
1589
|
-
failed:
|
|
1590
|
-
errored:
|
|
1591
|
-
cost_usd:
|
|
1592
|
-
duration_ms:
|
|
1646
|
+
var summarySchema = import_zod3.z.object({
|
|
1647
|
+
total: import_zod3.z.number(),
|
|
1648
|
+
passed: import_zod3.z.number(),
|
|
1649
|
+
failed: import_zod3.z.number(),
|
|
1650
|
+
errored: import_zod3.z.number(),
|
|
1651
|
+
cost_usd: import_zod3.z.number(),
|
|
1652
|
+
duration_ms: import_zod3.z.number()
|
|
1593
1653
|
});
|
|
1594
|
-
var evalResultSchema =
|
|
1595
|
-
id:
|
|
1596
|
-
tags:
|
|
1597
|
-
rows:
|
|
1598
|
-
passed:
|
|
1654
|
+
var evalResultSchema = import_zod3.z.object({
|
|
1655
|
+
id: import_zod3.z.string(),
|
|
1656
|
+
tags: import_zod3.z.array(import_zod3.z.string()),
|
|
1657
|
+
rows: import_zod3.z.array(rowResultSchema),
|
|
1658
|
+
passed: import_zod3.z.boolean()
|
|
1599
1659
|
});
|
|
1600
|
-
var runResultSchema =
|
|
1601
|
-
schemaVersion:
|
|
1602
|
-
plune_version:
|
|
1603
|
-
started_at:
|
|
1604
|
-
finished_at:
|
|
1605
|
-
config_hash:
|
|
1660
|
+
var runResultSchema = import_zod3.z.object({
|
|
1661
|
+
schemaVersion: import_zod3.z.literal(RUN_RESULT_SCHEMA_VERSION),
|
|
1662
|
+
plune_version: import_zod3.z.string(),
|
|
1663
|
+
started_at: import_zod3.z.string(),
|
|
1664
|
+
finished_at: import_zod3.z.string(),
|
|
1665
|
+
config_hash: import_zod3.z.string(),
|
|
1606
1666
|
summary: summarySchema,
|
|
1607
|
-
evals:
|
|
1667
|
+
evals: import_zod3.z.array(evalResultSchema)
|
|
1608
1668
|
});
|
|
1609
1669
|
function parseRunResult(value) {
|
|
1610
1670
|
return runResultSchema.parse(value);
|
|
@@ -1988,6 +2048,7 @@ function formatIngestResult(r) {
|
|
|
1988
2048
|
SyncFileError,
|
|
1989
2049
|
SyncHttpError,
|
|
1990
2050
|
SyncNetworkError,
|
|
2051
|
+
TEST_CASE_SCHEMA_VERSION,
|
|
1991
2052
|
TokenRejectedError,
|
|
1992
2053
|
assertionConfigSchema,
|
|
1993
2054
|
assertionResultRecordSchema,
|
|
@@ -1995,10 +2056,12 @@ function formatIngestResult(r) {
|
|
|
1995
2056
|
formatIngestResult,
|
|
1996
2057
|
ingest,
|
|
1997
2058
|
parseRunResult,
|
|
2059
|
+
parseTestCase,
|
|
1998
2060
|
readCairnRun,
|
|
1999
2061
|
reportIngestFailure,
|
|
2000
2062
|
reportSyncFailure,
|
|
2001
2063
|
run,
|
|
2002
2064
|
runResultSchema,
|
|
2003
|
-
sync
|
|
2065
|
+
sync,
|
|
2066
|
+
testCaseSchema
|
|
2004
2067
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -23,6 +23,54 @@ interface RunError {
|
|
|
23
23
|
code: string;
|
|
24
24
|
message: string;
|
|
25
25
|
}
|
|
26
|
+
interface ManualStep {
|
|
27
|
+
action: string;
|
|
28
|
+
expected?: string;
|
|
29
|
+
}
|
|
30
|
+
interface ExternalKey {
|
|
31
|
+
kind: 'playwright-id' | 'path-title' | 'allure-history' | 'cairn-stable' | 'eval-id' | 'qase' | 'testrail';
|
|
32
|
+
value: string;
|
|
33
|
+
}
|
|
34
|
+
type ManualCase = {
|
|
35
|
+
type: 'manual';
|
|
36
|
+
steps: {
|
|
37
|
+
action: string;
|
|
38
|
+
expected?: string;
|
|
39
|
+
}[];
|
|
40
|
+
expected?: string;
|
|
41
|
+
};
|
|
42
|
+
type AutomatedCase = {
|
|
43
|
+
type: 'automated';
|
|
44
|
+
specRef: string;
|
|
45
|
+
};
|
|
46
|
+
type EvalCase = {
|
|
47
|
+
type: 'eval';
|
|
48
|
+
prompt: string;
|
|
49
|
+
goldenSetId?: string;
|
|
50
|
+
assertions: AssertionResultRecord[];
|
|
51
|
+
};
|
|
52
|
+
interface TestCaseBase {
|
|
53
|
+
schemaVersion: 2;
|
|
54
|
+
id: string;
|
|
55
|
+
externalKeys?: ExternalKey[];
|
|
56
|
+
is_flaky?: boolean;
|
|
57
|
+
is_muted?: boolean;
|
|
58
|
+
}
|
|
59
|
+
type TestCase = TestCaseBase & (ManualCase | AutomatedCase | EvalCase);
|
|
60
|
+
/**
|
|
61
|
+
* The two words a row may use to say the product was never judged (ADR 0045).
|
|
62
|
+
*
|
|
63
|
+
* Both are already statuses this system has — they are `RESULT_STATUSES` entries — and neither was
|
|
64
|
+
* reachable through this contract: a row could only report `passed`, `failed` or `broken`. So a
|
|
65
|
+
* runner whose row was stopped by something outside the test had exactly one word left, `failed`,
|
|
66
|
+
* and the word was wrong. A red build because a dependency fell over reads identically to a red
|
|
67
|
+
* build because the code is broken, and those are two different pieces of work.
|
|
68
|
+
*
|
|
69
|
+
* `invalid` is deliberately absent: Qase's `invalid` is our `broken`, and a second word for one
|
|
70
|
+
* idea would fork the contract at both ends.
|
|
71
|
+
*/
|
|
72
|
+
declare const ROW_INCONCLUSIVE: readonly ["blocked", "skipped"];
|
|
73
|
+
type RowInconclusive = (typeof ROW_INCONCLUSIVE)[number];
|
|
26
74
|
interface RowResult {
|
|
27
75
|
vars: Record<string, unknown>;
|
|
28
76
|
output: string | null;
|
|
@@ -31,6 +79,14 @@ interface RowResult {
|
|
|
31
79
|
latency_ms?: number;
|
|
32
80
|
error?: RunError;
|
|
33
81
|
assertions: AssertionResultRecord[];
|
|
82
|
+
/**
|
|
83
|
+
* ADR 0045. Say it when the test was never judged, rather than letting `failed` stand for both
|
|
84
|
+
* "the environment broke" and "the code is wrong".
|
|
85
|
+
*
|
|
86
|
+
* Optional and purely additive: a producer that does not send it validates exactly as before,
|
|
87
|
+
* which is why `schemaVersion` stays 1.
|
|
88
|
+
*/
|
|
89
|
+
inconclusive?: RowInconclusive;
|
|
34
90
|
}
|
|
35
91
|
interface EvalResult {
|
|
36
92
|
id: string;
|
|
@@ -404,6 +460,10 @@ declare const runResultSchema: z.ZodObject<{
|
|
|
404
460
|
passed: z.ZodBoolean;
|
|
405
461
|
}, z.core.$strip>>>;
|
|
406
462
|
}, z.core.$strip>>;
|
|
463
|
+
inconclusive: z.ZodOptional<z.ZodEnum<{
|
|
464
|
+
blocked: "blocked";
|
|
465
|
+
skipped: "skipped";
|
|
466
|
+
}>>;
|
|
407
467
|
}, z.core.$strip>>;
|
|
408
468
|
passed: z.ZodBoolean;
|
|
409
469
|
}, z.core.$strip>>;
|
|
@@ -417,6 +477,133 @@ type BinaryVerdict = z.infer<typeof binaryVerdictSchema>;
|
|
|
417
477
|
/** Parse + validate an unknown value as a RunResult. Throws ZodError on failure. */
|
|
418
478
|
declare function parseRunResult(value: unknown): ParsedRunResult;
|
|
419
479
|
|
|
480
|
+
/**
|
|
481
|
+
* Runtime validation for the TestCase contract — the JSON that `plune run import` emits
|
|
482
|
+
* or that the platform accepts on `POST /v1/test-cases`.
|
|
483
|
+
*
|
|
484
|
+
* The canonical TypeScript shape is owned by `./results.ts` (`TEST_CASE_SCHEMA_VERSION: 2`).
|
|
485
|
+
* This module is its zod mirror: the validator for anything that has to *ingest* that
|
|
486
|
+
* output rather than produce it. `plune sync` validates the local case file with it
|
|
487
|
+
* before uploading, and the Plune platform validates the same body on
|
|
488
|
+
* `POST /v1/test-cases` — one schema, both ends.
|
|
489
|
+
*/
|
|
490
|
+
declare const TEST_CASE_SCHEMA_VERSION: TestCase['schemaVersion'];
|
|
491
|
+
declare const testCaseSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
492
|
+
schemaVersion: z.ZodLiteral<2>;
|
|
493
|
+
id: z.ZodString;
|
|
494
|
+
externalKeys: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
495
|
+
kind: z.ZodEnum<{
|
|
496
|
+
"playwright-id": "playwright-id";
|
|
497
|
+
"path-title": "path-title";
|
|
498
|
+
"allure-history": "allure-history";
|
|
499
|
+
"cairn-stable": "cairn-stable";
|
|
500
|
+
"eval-id": "eval-id";
|
|
501
|
+
qase: "qase";
|
|
502
|
+
testrail: "testrail";
|
|
503
|
+
}>;
|
|
504
|
+
value: z.ZodString;
|
|
505
|
+
}, z.core.$strip>>>;
|
|
506
|
+
is_flaky: z.ZodOptional<z.ZodBoolean>;
|
|
507
|
+
is_muted: z.ZodOptional<z.ZodBoolean>;
|
|
508
|
+
type: z.ZodLiteral<"manual">;
|
|
509
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
510
|
+
action: z.ZodString;
|
|
511
|
+
expected: z.ZodOptional<z.ZodString>;
|
|
512
|
+
}, z.core.$strip>>;
|
|
513
|
+
expected: z.ZodOptional<z.ZodString>;
|
|
514
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
515
|
+
schemaVersion: z.ZodLiteral<2>;
|
|
516
|
+
id: z.ZodString;
|
|
517
|
+
externalKeys: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
518
|
+
kind: z.ZodEnum<{
|
|
519
|
+
"playwright-id": "playwright-id";
|
|
520
|
+
"path-title": "path-title";
|
|
521
|
+
"allure-history": "allure-history";
|
|
522
|
+
"cairn-stable": "cairn-stable";
|
|
523
|
+
"eval-id": "eval-id";
|
|
524
|
+
qase: "qase";
|
|
525
|
+
testrail: "testrail";
|
|
526
|
+
}>;
|
|
527
|
+
value: z.ZodString;
|
|
528
|
+
}, z.core.$strip>>>;
|
|
529
|
+
is_flaky: z.ZodOptional<z.ZodBoolean>;
|
|
530
|
+
is_muted: z.ZodOptional<z.ZodBoolean>;
|
|
531
|
+
type: z.ZodLiteral<"automated">;
|
|
532
|
+
specRef: z.ZodString;
|
|
533
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
534
|
+
schemaVersion: z.ZodLiteral<2>;
|
|
535
|
+
id: z.ZodString;
|
|
536
|
+
externalKeys: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
537
|
+
kind: z.ZodEnum<{
|
|
538
|
+
"playwright-id": "playwright-id";
|
|
539
|
+
"path-title": "path-title";
|
|
540
|
+
"allure-history": "allure-history";
|
|
541
|
+
"cairn-stable": "cairn-stable";
|
|
542
|
+
"eval-id": "eval-id";
|
|
543
|
+
qase: "qase";
|
|
544
|
+
testrail: "testrail";
|
|
545
|
+
}>;
|
|
546
|
+
value: z.ZodString;
|
|
547
|
+
}, z.core.$strip>>>;
|
|
548
|
+
is_flaky: z.ZodOptional<z.ZodBoolean>;
|
|
549
|
+
is_muted: z.ZodOptional<z.ZodBoolean>;
|
|
550
|
+
type: z.ZodLiteral<"eval">;
|
|
551
|
+
prompt: z.ZodString;
|
|
552
|
+
goldenSetId: z.ZodOptional<z.ZodString>;
|
|
553
|
+
assertions: z.ZodArray<z.ZodObject<{
|
|
554
|
+
type: z.ZodString;
|
|
555
|
+
passed: z.ZodBoolean;
|
|
556
|
+
score: z.ZodOptional<z.ZodNumber>;
|
|
557
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
558
|
+
}, z.core.$strip>>;
|
|
559
|
+
}, z.core.$strip>], "type">;
|
|
560
|
+
/** Parse + validate an unknown value as a TestCase. Throws ZodError on failure. */
|
|
561
|
+
declare function parseTestCase(value: unknown): {
|
|
562
|
+
schemaVersion: 2;
|
|
563
|
+
id: string;
|
|
564
|
+
type: "manual";
|
|
565
|
+
steps: {
|
|
566
|
+
action: string;
|
|
567
|
+
expected?: string | undefined;
|
|
568
|
+
}[];
|
|
569
|
+
externalKeys?: {
|
|
570
|
+
kind: "playwright-id" | "path-title" | "allure-history" | "cairn-stable" | "eval-id" | "qase" | "testrail";
|
|
571
|
+
value: string;
|
|
572
|
+
}[] | undefined;
|
|
573
|
+
is_flaky?: boolean | undefined;
|
|
574
|
+
is_muted?: boolean | undefined;
|
|
575
|
+
expected?: string | undefined;
|
|
576
|
+
} | {
|
|
577
|
+
schemaVersion: 2;
|
|
578
|
+
id: string;
|
|
579
|
+
type: "automated";
|
|
580
|
+
specRef: string;
|
|
581
|
+
externalKeys?: {
|
|
582
|
+
kind: "playwright-id" | "path-title" | "allure-history" | "cairn-stable" | "eval-id" | "qase" | "testrail";
|
|
583
|
+
value: string;
|
|
584
|
+
}[] | undefined;
|
|
585
|
+
is_flaky?: boolean | undefined;
|
|
586
|
+
is_muted?: boolean | undefined;
|
|
587
|
+
} | {
|
|
588
|
+
schemaVersion: 2;
|
|
589
|
+
id: string;
|
|
590
|
+
type: "eval";
|
|
591
|
+
prompt: string;
|
|
592
|
+
assertions: {
|
|
593
|
+
type: string;
|
|
594
|
+
passed: boolean;
|
|
595
|
+
score?: number | undefined;
|
|
596
|
+
reason?: string | undefined;
|
|
597
|
+
}[];
|
|
598
|
+
externalKeys?: {
|
|
599
|
+
kind: "playwright-id" | "path-title" | "allure-history" | "cairn-stable" | "eval-id" | "qase" | "testrail";
|
|
600
|
+
value: string;
|
|
601
|
+
}[] | undefined;
|
|
602
|
+
is_flaky?: boolean | undefined;
|
|
603
|
+
is_muted?: boolean | undefined;
|
|
604
|
+
goldenSetId?: string | undefined;
|
|
605
|
+
};
|
|
606
|
+
|
|
420
607
|
interface IngestDeps {
|
|
421
608
|
/** The Cairn run directory to read. Omit it and the newest run under `runsDir` is used. */
|
|
422
609
|
dir?: string;
|
|
@@ -485,4 +672,4 @@ interface ReadCairnRunDeps {
|
|
|
485
672
|
*/
|
|
486
673
|
declare function readCairnRun(dir: string, deps?: ReadCairnRunDeps): Promise<CairnIngestPayload>;
|
|
487
674
|
|
|
488
|
-
export { type AssertionResultRecord, type BinaryVerdict, type CairnIngestCase, type CairnIngestPayload, type Config, type EvalResult, type IngestDeps, type IngestResult, NotLoggedInError, type ParsedRunResult, RUN_RESULT_SCHEMA_VERSION, type RowResult, type RunError, type RunOptions, type RunResult, type Summary, type SyncDeps, SyncFileError, SyncHttpError, SyncNetworkError, type SyncResult, TokenRejectedError, type Usage, assertionConfigSchema, assertionResultRecordSchema, binaryVerdictSchema, formatIngestResult, handleIngest as ingest, parseRunResult, readCairnRun, reportIngestFailure, reportSyncFailure, handleRun as run, runResultSchema, handleSync as sync };
|
|
675
|
+
export { type AssertionResultRecord, type BinaryVerdict, type CairnIngestCase, type CairnIngestPayload, type Config, type EvalResult, type ExternalKey, type IngestDeps, type IngestResult, type ManualStep, NotLoggedInError, type ParsedRunResult, RUN_RESULT_SCHEMA_VERSION, type RowResult, type RunError, type RunOptions, type RunResult, type Summary, type SyncDeps, SyncFileError, SyncHttpError, SyncNetworkError, type SyncResult, TEST_CASE_SCHEMA_VERSION, type TestCase, TokenRejectedError, type Usage, assertionConfigSchema, assertionResultRecordSchema, binaryVerdictSchema, formatIngestResult, handleIngest as ingest, parseRunResult, parseTestCase, readCairnRun, reportIngestFailure, reportSyncFailure, handleRun as run, runResultSchema, handleSync as sync, testCaseSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,54 @@ interface RunError {
|
|
|
23
23
|
code: string;
|
|
24
24
|
message: string;
|
|
25
25
|
}
|
|
26
|
+
interface ManualStep {
|
|
27
|
+
action: string;
|
|
28
|
+
expected?: string;
|
|
29
|
+
}
|
|
30
|
+
interface ExternalKey {
|
|
31
|
+
kind: 'playwright-id' | 'path-title' | 'allure-history' | 'cairn-stable' | 'eval-id' | 'qase' | 'testrail';
|
|
32
|
+
value: string;
|
|
33
|
+
}
|
|
34
|
+
type ManualCase = {
|
|
35
|
+
type: 'manual';
|
|
36
|
+
steps: {
|
|
37
|
+
action: string;
|
|
38
|
+
expected?: string;
|
|
39
|
+
}[];
|
|
40
|
+
expected?: string;
|
|
41
|
+
};
|
|
42
|
+
type AutomatedCase = {
|
|
43
|
+
type: 'automated';
|
|
44
|
+
specRef: string;
|
|
45
|
+
};
|
|
46
|
+
type EvalCase = {
|
|
47
|
+
type: 'eval';
|
|
48
|
+
prompt: string;
|
|
49
|
+
goldenSetId?: string;
|
|
50
|
+
assertions: AssertionResultRecord[];
|
|
51
|
+
};
|
|
52
|
+
interface TestCaseBase {
|
|
53
|
+
schemaVersion: 2;
|
|
54
|
+
id: string;
|
|
55
|
+
externalKeys?: ExternalKey[];
|
|
56
|
+
is_flaky?: boolean;
|
|
57
|
+
is_muted?: boolean;
|
|
58
|
+
}
|
|
59
|
+
type TestCase = TestCaseBase & (ManualCase | AutomatedCase | EvalCase);
|
|
60
|
+
/**
|
|
61
|
+
* The two words a row may use to say the product was never judged (ADR 0045).
|
|
62
|
+
*
|
|
63
|
+
* Both are already statuses this system has — they are `RESULT_STATUSES` entries — and neither was
|
|
64
|
+
* reachable through this contract: a row could only report `passed`, `failed` or `broken`. So a
|
|
65
|
+
* runner whose row was stopped by something outside the test had exactly one word left, `failed`,
|
|
66
|
+
* and the word was wrong. A red build because a dependency fell over reads identically to a red
|
|
67
|
+
* build because the code is broken, and those are two different pieces of work.
|
|
68
|
+
*
|
|
69
|
+
* `invalid` is deliberately absent: Qase's `invalid` is our `broken`, and a second word for one
|
|
70
|
+
* idea would fork the contract at both ends.
|
|
71
|
+
*/
|
|
72
|
+
declare const ROW_INCONCLUSIVE: readonly ["blocked", "skipped"];
|
|
73
|
+
type RowInconclusive = (typeof ROW_INCONCLUSIVE)[number];
|
|
26
74
|
interface RowResult {
|
|
27
75
|
vars: Record<string, unknown>;
|
|
28
76
|
output: string | null;
|
|
@@ -31,6 +79,14 @@ interface RowResult {
|
|
|
31
79
|
latency_ms?: number;
|
|
32
80
|
error?: RunError;
|
|
33
81
|
assertions: AssertionResultRecord[];
|
|
82
|
+
/**
|
|
83
|
+
* ADR 0045. Say it when the test was never judged, rather than letting `failed` stand for both
|
|
84
|
+
* "the environment broke" and "the code is wrong".
|
|
85
|
+
*
|
|
86
|
+
* Optional and purely additive: a producer that does not send it validates exactly as before,
|
|
87
|
+
* which is why `schemaVersion` stays 1.
|
|
88
|
+
*/
|
|
89
|
+
inconclusive?: RowInconclusive;
|
|
34
90
|
}
|
|
35
91
|
interface EvalResult {
|
|
36
92
|
id: string;
|
|
@@ -404,6 +460,10 @@ declare const runResultSchema: z.ZodObject<{
|
|
|
404
460
|
passed: z.ZodBoolean;
|
|
405
461
|
}, z.core.$strip>>>;
|
|
406
462
|
}, z.core.$strip>>;
|
|
463
|
+
inconclusive: z.ZodOptional<z.ZodEnum<{
|
|
464
|
+
blocked: "blocked";
|
|
465
|
+
skipped: "skipped";
|
|
466
|
+
}>>;
|
|
407
467
|
}, z.core.$strip>>;
|
|
408
468
|
passed: z.ZodBoolean;
|
|
409
469
|
}, z.core.$strip>>;
|
|
@@ -417,6 +477,133 @@ type BinaryVerdict = z.infer<typeof binaryVerdictSchema>;
|
|
|
417
477
|
/** Parse + validate an unknown value as a RunResult. Throws ZodError on failure. */
|
|
418
478
|
declare function parseRunResult(value: unknown): ParsedRunResult;
|
|
419
479
|
|
|
480
|
+
/**
|
|
481
|
+
* Runtime validation for the TestCase contract — the JSON that `plune run import` emits
|
|
482
|
+
* or that the platform accepts on `POST /v1/test-cases`.
|
|
483
|
+
*
|
|
484
|
+
* The canonical TypeScript shape is owned by `./results.ts` (`TEST_CASE_SCHEMA_VERSION: 2`).
|
|
485
|
+
* This module is its zod mirror: the validator for anything that has to *ingest* that
|
|
486
|
+
* output rather than produce it. `plune sync` validates the local case file with it
|
|
487
|
+
* before uploading, and the Plune platform validates the same body on
|
|
488
|
+
* `POST /v1/test-cases` — one schema, both ends.
|
|
489
|
+
*/
|
|
490
|
+
declare const TEST_CASE_SCHEMA_VERSION: TestCase['schemaVersion'];
|
|
491
|
+
declare const testCaseSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
492
|
+
schemaVersion: z.ZodLiteral<2>;
|
|
493
|
+
id: z.ZodString;
|
|
494
|
+
externalKeys: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
495
|
+
kind: z.ZodEnum<{
|
|
496
|
+
"playwright-id": "playwright-id";
|
|
497
|
+
"path-title": "path-title";
|
|
498
|
+
"allure-history": "allure-history";
|
|
499
|
+
"cairn-stable": "cairn-stable";
|
|
500
|
+
"eval-id": "eval-id";
|
|
501
|
+
qase: "qase";
|
|
502
|
+
testrail: "testrail";
|
|
503
|
+
}>;
|
|
504
|
+
value: z.ZodString;
|
|
505
|
+
}, z.core.$strip>>>;
|
|
506
|
+
is_flaky: z.ZodOptional<z.ZodBoolean>;
|
|
507
|
+
is_muted: z.ZodOptional<z.ZodBoolean>;
|
|
508
|
+
type: z.ZodLiteral<"manual">;
|
|
509
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
510
|
+
action: z.ZodString;
|
|
511
|
+
expected: z.ZodOptional<z.ZodString>;
|
|
512
|
+
}, z.core.$strip>>;
|
|
513
|
+
expected: z.ZodOptional<z.ZodString>;
|
|
514
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
515
|
+
schemaVersion: z.ZodLiteral<2>;
|
|
516
|
+
id: z.ZodString;
|
|
517
|
+
externalKeys: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
518
|
+
kind: z.ZodEnum<{
|
|
519
|
+
"playwright-id": "playwright-id";
|
|
520
|
+
"path-title": "path-title";
|
|
521
|
+
"allure-history": "allure-history";
|
|
522
|
+
"cairn-stable": "cairn-stable";
|
|
523
|
+
"eval-id": "eval-id";
|
|
524
|
+
qase: "qase";
|
|
525
|
+
testrail: "testrail";
|
|
526
|
+
}>;
|
|
527
|
+
value: z.ZodString;
|
|
528
|
+
}, z.core.$strip>>>;
|
|
529
|
+
is_flaky: z.ZodOptional<z.ZodBoolean>;
|
|
530
|
+
is_muted: z.ZodOptional<z.ZodBoolean>;
|
|
531
|
+
type: z.ZodLiteral<"automated">;
|
|
532
|
+
specRef: z.ZodString;
|
|
533
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
534
|
+
schemaVersion: z.ZodLiteral<2>;
|
|
535
|
+
id: z.ZodString;
|
|
536
|
+
externalKeys: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
537
|
+
kind: z.ZodEnum<{
|
|
538
|
+
"playwright-id": "playwright-id";
|
|
539
|
+
"path-title": "path-title";
|
|
540
|
+
"allure-history": "allure-history";
|
|
541
|
+
"cairn-stable": "cairn-stable";
|
|
542
|
+
"eval-id": "eval-id";
|
|
543
|
+
qase: "qase";
|
|
544
|
+
testrail: "testrail";
|
|
545
|
+
}>;
|
|
546
|
+
value: z.ZodString;
|
|
547
|
+
}, z.core.$strip>>>;
|
|
548
|
+
is_flaky: z.ZodOptional<z.ZodBoolean>;
|
|
549
|
+
is_muted: z.ZodOptional<z.ZodBoolean>;
|
|
550
|
+
type: z.ZodLiteral<"eval">;
|
|
551
|
+
prompt: z.ZodString;
|
|
552
|
+
goldenSetId: z.ZodOptional<z.ZodString>;
|
|
553
|
+
assertions: z.ZodArray<z.ZodObject<{
|
|
554
|
+
type: z.ZodString;
|
|
555
|
+
passed: z.ZodBoolean;
|
|
556
|
+
score: z.ZodOptional<z.ZodNumber>;
|
|
557
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
558
|
+
}, z.core.$strip>>;
|
|
559
|
+
}, z.core.$strip>], "type">;
|
|
560
|
+
/** Parse + validate an unknown value as a TestCase. Throws ZodError on failure. */
|
|
561
|
+
declare function parseTestCase(value: unknown): {
|
|
562
|
+
schemaVersion: 2;
|
|
563
|
+
id: string;
|
|
564
|
+
type: "manual";
|
|
565
|
+
steps: {
|
|
566
|
+
action: string;
|
|
567
|
+
expected?: string | undefined;
|
|
568
|
+
}[];
|
|
569
|
+
externalKeys?: {
|
|
570
|
+
kind: "playwright-id" | "path-title" | "allure-history" | "cairn-stable" | "eval-id" | "qase" | "testrail";
|
|
571
|
+
value: string;
|
|
572
|
+
}[] | undefined;
|
|
573
|
+
is_flaky?: boolean | undefined;
|
|
574
|
+
is_muted?: boolean | undefined;
|
|
575
|
+
expected?: string | undefined;
|
|
576
|
+
} | {
|
|
577
|
+
schemaVersion: 2;
|
|
578
|
+
id: string;
|
|
579
|
+
type: "automated";
|
|
580
|
+
specRef: string;
|
|
581
|
+
externalKeys?: {
|
|
582
|
+
kind: "playwright-id" | "path-title" | "allure-history" | "cairn-stable" | "eval-id" | "qase" | "testrail";
|
|
583
|
+
value: string;
|
|
584
|
+
}[] | undefined;
|
|
585
|
+
is_flaky?: boolean | undefined;
|
|
586
|
+
is_muted?: boolean | undefined;
|
|
587
|
+
} | {
|
|
588
|
+
schemaVersion: 2;
|
|
589
|
+
id: string;
|
|
590
|
+
type: "eval";
|
|
591
|
+
prompt: string;
|
|
592
|
+
assertions: {
|
|
593
|
+
type: string;
|
|
594
|
+
passed: boolean;
|
|
595
|
+
score?: number | undefined;
|
|
596
|
+
reason?: string | undefined;
|
|
597
|
+
}[];
|
|
598
|
+
externalKeys?: {
|
|
599
|
+
kind: "playwright-id" | "path-title" | "allure-history" | "cairn-stable" | "eval-id" | "qase" | "testrail";
|
|
600
|
+
value: string;
|
|
601
|
+
}[] | undefined;
|
|
602
|
+
is_flaky?: boolean | undefined;
|
|
603
|
+
is_muted?: boolean | undefined;
|
|
604
|
+
goldenSetId?: string | undefined;
|
|
605
|
+
};
|
|
606
|
+
|
|
420
607
|
interface IngestDeps {
|
|
421
608
|
/** The Cairn run directory to read. Omit it and the newest run under `runsDir` is used. */
|
|
422
609
|
dir?: string;
|
|
@@ -485,4 +672,4 @@ interface ReadCairnRunDeps {
|
|
|
485
672
|
*/
|
|
486
673
|
declare function readCairnRun(dir: string, deps?: ReadCairnRunDeps): Promise<CairnIngestPayload>;
|
|
487
674
|
|
|
488
|
-
export { type AssertionResultRecord, type BinaryVerdict, type CairnIngestCase, type CairnIngestPayload, type Config, type EvalResult, type IngestDeps, type IngestResult, NotLoggedInError, type ParsedRunResult, RUN_RESULT_SCHEMA_VERSION, type RowResult, type RunError, type RunOptions, type RunResult, type Summary, type SyncDeps, SyncFileError, SyncHttpError, SyncNetworkError, type SyncResult, TokenRejectedError, type Usage, assertionConfigSchema, assertionResultRecordSchema, binaryVerdictSchema, formatIngestResult, handleIngest as ingest, parseRunResult, readCairnRun, reportIngestFailure, reportSyncFailure, handleRun as run, runResultSchema, handleSync as sync };
|
|
675
|
+
export { type AssertionResultRecord, type BinaryVerdict, type CairnIngestCase, type CairnIngestPayload, type Config, type EvalResult, type ExternalKey, type IngestDeps, type IngestResult, type ManualStep, NotLoggedInError, type ParsedRunResult, RUN_RESULT_SCHEMA_VERSION, type RowResult, type RunError, type RunOptions, type RunResult, type Summary, type SyncDeps, SyncFileError, SyncHttpError, SyncNetworkError, type SyncResult, TEST_CASE_SCHEMA_VERSION, type TestCase, TokenRejectedError, type Usage, assertionConfigSchema, assertionResultRecordSchema, binaryVerdictSchema, formatIngestResult, handleIngest as ingest, parseRunResult, parseTestCase, readCairnRun, reportIngestFailure, reportSyncFailure, handleRun as run, runResultSchema, handleSync as sync, testCaseSchema };
|