@flowriki/agent 0.1.0-beta.42 → 0.1.0-beta.44
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/{chunk-FKD5OAUV.js → chunk-E24RRF2Q.js} +484 -425
- package/dist/cli.js +189 -1
- package/dist/engine.js +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ import os from "os";
|
|
|
6
6
|
import path from "path";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
8
|
import { spawnSync } from "child_process";
|
|
9
|
-
var AGENT_VERSION = "0.1.0-beta.
|
|
9
|
+
var AGENT_VERSION = "0.1.0-beta.44";
|
|
10
10
|
async function prepareBrowsers() {
|
|
11
11
|
if (browsersReady()) {
|
|
12
12
|
return { ok: true, already: true, message: "chromium is already installed" };
|
|
@@ -1008,6 +1008,8 @@ import { z as z42 } from "zod";
|
|
|
1008
1008
|
import { z as z5 } from "zod";
|
|
1009
1009
|
import { z as z6 } from "zod";
|
|
1010
1010
|
import { z as z7 } from "zod";
|
|
1011
|
+
import { z as z8 } from "zod";
|
|
1012
|
+
import { z as z9 } from "zod";
|
|
1011
1013
|
var EngineSchema = z4.enum(["chromium", "firefox", "webkit"]);
|
|
1012
1014
|
var CapabilitySchema = z4.object({
|
|
1013
1015
|
id: z4.string(),
|
|
@@ -1036,18 +1038,44 @@ var ExecutionConfigSchema = z4.object({
|
|
|
1036
1038
|
})
|
|
1037
1039
|
).default({})
|
|
1038
1040
|
});
|
|
1039
|
-
var
|
|
1041
|
+
var BUSINESS_KEYWORDS = ["Given", "When", "Then", "And", "But"];
|
|
1042
|
+
var BusinessStepSchema = z22.object({
|
|
1043
|
+
keyword: z22.enum(BUSINESS_KEYWORDS),
|
|
1044
|
+
text: z22.string().min(1).max(2e3)
|
|
1045
|
+
}).strict();
|
|
1046
|
+
var TestCaseOriginSchema = z22.object({
|
|
1047
|
+
kind: z22.enum(["import", "assistant"]),
|
|
1048
|
+
at: z22.string(),
|
|
1049
|
+
by: z22.string().default(""),
|
|
1050
|
+
/** The file it was imported from, and its row or id there. */
|
|
1051
|
+
file: z22.string().max(300).optional(),
|
|
1052
|
+
row: z22.string().max(200).optional()
|
|
1053
|
+
}).strict();
|
|
1054
|
+
var KEYWORD = /^\s*(given|when|then|and|but)\b[\s:]*(.*)$/i;
|
|
1055
|
+
var keywordOf = (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
1056
|
+
function parseGherkin(text) {
|
|
1057
|
+
const lines = text.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).filter((l) => !/^(scenario|scenario outline|feature|background|examples)\s*:/i.test(l) && !l.startsWith("|"));
|
|
1058
|
+
if (!lines.length) return null;
|
|
1059
|
+
const steps = [];
|
|
1060
|
+
for (const line of lines) {
|
|
1061
|
+
const m = KEYWORD.exec(line);
|
|
1062
|
+
if (!m || !m[2].trim()) return null;
|
|
1063
|
+
steps.push({ keyword: keywordOf(m[1]), text: m[2].trim() });
|
|
1064
|
+
}
|
|
1065
|
+
return steps;
|
|
1066
|
+
}
|
|
1067
|
+
var FlowOccurrenceSchema = z32.object({
|
|
1040
1068
|
/** This copy's own identity. Not the source flow's — a flow added twice is
|
|
1041
1069
|
* two occurrences, and editing, breakpoints, results and deletion must be
|
|
1042
1070
|
* able to tell them apart. */
|
|
1043
|
-
occurrenceId:
|
|
1044
|
-
actorId:
|
|
1071
|
+
occurrenceId: z32.string().min(1),
|
|
1072
|
+
actorId: z32.string().optional(),
|
|
1045
1073
|
/** Editable, and initially the source flow's name. */
|
|
1046
|
-
name:
|
|
1074
|
+
name: z32.string().min(1),
|
|
1047
1075
|
/** Where this copy starts, when it is told to navigate before running.
|
|
1048
1076
|
* Absent means continue from wherever the previous row left the browser. */
|
|
1049
|
-
startPath:
|
|
1050
|
-
baseUrl:
|
|
1077
|
+
startPath: z32.string().optional(),
|
|
1078
|
+
baseUrl: z32.string().url().optional(),
|
|
1051
1079
|
/** GO SOMEWHERE FIRST, or carry on where the last row ended.
|
|
1052
1080
|
*
|
|
1053
1081
|
* SUPERSEDED BY `start`, and still read so that every case written before
|
|
@@ -1057,7 +1085,7 @@ var FlowOccurrenceSchema = z22.object({
|
|
|
1057
1085
|
* Off by default, because a case is a sequence in one browser: re-entering
|
|
1058
1086
|
* each flow's original starting URL would sign the tester out between rows
|
|
1059
1087
|
* and is exactly the behaviour composing flows is meant to avoid. */
|
|
1060
|
-
navigateFirst:
|
|
1088
|
+
navigateFirst: z32.boolean().default(false),
|
|
1061
1089
|
/** WHICH BROWSER THIS ROW RUNS IN.
|
|
1062
1090
|
*
|
|
1063
1091
|
* Two answers, because there are two: carry on in the browser this
|
|
@@ -1080,7 +1108,7 @@ var FlowOccurrenceSchema = z22.object({
|
|
|
1080
1108
|
* A participant's FIRST row is always fresh in effect: there is nothing to
|
|
1081
1109
|
* continue from. That is not stored, because it is a fact about the order
|
|
1082
1110
|
* rather than about the row — moving the row changes the answer. */
|
|
1083
|
-
start:
|
|
1111
|
+
start: z32.enum(["continue", "navigate", "fresh"]).optional(),
|
|
1084
1112
|
/** WHETHER THIS COPY DOES ITS OWN SIGNING IN.
|
|
1085
1113
|
*
|
|
1086
1114
|
* A flow recorded with "sign in before recording" keeps that sign-in as its
|
|
@@ -1099,28 +1127,28 @@ var FlowOccurrenceSchema = z22.object({
|
|
|
1099
1127
|
* the two agree on the account and is refused where they do not — so a case
|
|
1100
1128
|
* written before this keeps its meaning, and a contradiction stays a
|
|
1101
1129
|
* contradiction until somebody actually resolves it. */
|
|
1102
|
-
ownSignIn:
|
|
1103
|
-
steps:
|
|
1130
|
+
ownSignIn: z32.enum(["skip", "run"]).optional(),
|
|
1131
|
+
steps: z32.array(RecordedStepSchema),
|
|
1104
1132
|
environment: ExecutionEnvironmentSchema.optional(),
|
|
1105
1133
|
/** Where this copy came from, so the editor can say whether the source has
|
|
1106
1134
|
* moved on — informational only, never a trigger to rewrite anything. */
|
|
1107
|
-
origin:
|
|
1108
|
-
flowId:
|
|
1135
|
+
origin: z32.object({
|
|
1136
|
+
flowId: z32.string(),
|
|
1109
1137
|
/** The schema the source was written in, which may be older than today's. */
|
|
1110
|
-
schemaVersion:
|
|
1138
|
+
schemaVersion: z32.number().int().nonnegative(),
|
|
1111
1139
|
/** The source's own revision counter at the moment it was copied. */
|
|
1112
|
-
revision:
|
|
1140
|
+
revision: z32.number().int().nonnegative(),
|
|
1113
1141
|
/** The commit the copy was taken from, when one was known. */
|
|
1114
|
-
commit:
|
|
1115
|
-
featureId:
|
|
1142
|
+
commit: z32.string().optional(),
|
|
1143
|
+
featureId: z32.string(),
|
|
1116
1144
|
/** Names as they were, so an old case still reads correctly after the
|
|
1117
1145
|
* source is renamed, moved or deleted. */
|
|
1118
|
-
featureName:
|
|
1119
|
-
flowName:
|
|
1146
|
+
featureName: z32.string(),
|
|
1147
|
+
flowName: z32.string(),
|
|
1120
1148
|
/** Source step id → the id it was given here. Kept so a later comparison
|
|
1121
1149
|
* against the source can line the two up; nothing depends on it to run. */
|
|
1122
|
-
stepIds:
|
|
1123
|
-
copiedAt:
|
|
1150
|
+
stepIds: z32.record(z32.string(), z32.string()).default({}),
|
|
1151
|
+
copiedAt: z32.string()
|
|
1124
1152
|
}),
|
|
1125
1153
|
/** WHICH OF THIS ROW'S STEPS ARE WHAT RUNS BEFORE ITS FLOW — the flow's
|
|
1126
1154
|
* sign-in and the prerequisites copied in with it — so the row can be shown
|
|
@@ -1131,24 +1159,24 @@ var FlowOccurrenceSchema = z22.object({
|
|
|
1131
1159
|
* id, so editing or deleting one of them leaves the rest still grouped.
|
|
1132
1160
|
* Absent on every row copied before this existed, which simply show flat.
|
|
1133
1161
|
* Never sent to a machine — see `withoutFolding`. */
|
|
1134
|
-
before:
|
|
1162
|
+
before: z32.object({
|
|
1135
1163
|
/** The flow's own sign-in, when the copy brought one. */
|
|
1136
|
-
signInStepId:
|
|
1137
|
-
flows:
|
|
1138
|
-
flowId:
|
|
1139
|
-
name:
|
|
1140
|
-
stepIds:
|
|
1164
|
+
signInStepId: z32.string().optional(),
|
|
1165
|
+
flows: z32.array(z32.object({
|
|
1166
|
+
flowId: z32.string(),
|
|
1167
|
+
name: z32.string(),
|
|
1168
|
+
stepIds: z32.array(z32.string())
|
|
1141
1169
|
}).strict()).default([])
|
|
1142
1170
|
}).strict().optional()
|
|
1143
1171
|
}).strict();
|
|
1144
1172
|
var CASE_SCHEMA_VERSION = 1;
|
|
1145
|
-
var TestCaseSchema =
|
|
1146
|
-
schemaVersion:
|
|
1147
|
-
id:
|
|
1148
|
-
folderId:
|
|
1149
|
-
slug:
|
|
1150
|
-
name:
|
|
1151
|
-
description:
|
|
1173
|
+
var TestCaseSchema = z32.object({
|
|
1174
|
+
schemaVersion: z32.literal(CASE_SCHEMA_VERSION),
|
|
1175
|
+
id: z32.string().min(1),
|
|
1176
|
+
folderId: z32.string().min(1),
|
|
1177
|
+
slug: z32.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
1178
|
+
name: z32.string().min(1),
|
|
1179
|
+
description: z32.string().default(""),
|
|
1152
1180
|
/** NO LONGER USED, and kept only so that a case written while they were
|
|
1153
1181
|
* parses.
|
|
1154
1182
|
*
|
|
@@ -1161,19 +1189,25 @@ var TestCaseSchema = z22.object({
|
|
|
1161
1189
|
*
|
|
1162
1190
|
* Every row now starts where its own flow says, which is the same answer
|
|
1163
1191
|
* whatever the order. */
|
|
1164
|
-
startPath:
|
|
1165
|
-
useStartPath:
|
|
1166
|
-
baseUrl:
|
|
1192
|
+
startPath: z32.string().default("/"),
|
|
1193
|
+
useStartPath: z32.boolean().default(false),
|
|
1194
|
+
baseUrl: z32.string().url().optional(),
|
|
1167
1195
|
environment: ExecutionEnvironmentSchema.optional(),
|
|
1168
|
-
actors:
|
|
1169
|
-
defaultActorId:
|
|
1170
|
-
occurrences:
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1196
|
+
actors: z32.array(ActorDefinitionSchema).optional(),
|
|
1197
|
+
defaultActorId: z32.string().optional(),
|
|
1198
|
+
occurrences: z32.array(FlowOccurrenceSchema).default([]),
|
|
1199
|
+
/** WHAT IT CHECKS, IN WORDS: Given / When / Then. Written for a case that is
|
|
1200
|
+
* not automated yet — imported, or written by the assistant — and kept when
|
|
1201
|
+
* it is. Never sent to a machine — see `withoutFolding`. */
|
|
1202
|
+
businessSteps: z32.array(BusinessStepSchema).optional(),
|
|
1203
|
+
/** Where it came from, when not recorded here. */
|
|
1204
|
+
origin: TestCaseOriginSchema.optional(),
|
|
1205
|
+
createdAt: z32.string(),
|
|
1206
|
+
createdBy: z32.string().default(""),
|
|
1207
|
+
updatedAt: z32.string(),
|
|
1174
1208
|
/** The same optimistic-concurrency counter a flow carries, so an edit made
|
|
1175
1209
|
* against a stale copy is refused rather than overwriting. */
|
|
1176
|
-
revision:
|
|
1210
|
+
revision: z32.number().int().nonnegative().default(0)
|
|
1177
1211
|
}).strict().superRefine((testCase, ctx) => {
|
|
1178
1212
|
const seen = /* @__PURE__ */ new Set();
|
|
1179
1213
|
testCase.occurrences.forEach((occurrence, i) => {
|
|
@@ -1202,47 +1236,47 @@ var TestCaseSchema = z22.object({
|
|
|
1202
1236
|
const { defaultActorId: _gone, ...rest } = testCase;
|
|
1203
1237
|
return rest;
|
|
1204
1238
|
});
|
|
1205
|
-
var CaseFolderSchema =
|
|
1206
|
-
schemaVersion:
|
|
1207
|
-
id:
|
|
1208
|
-
slug:
|
|
1209
|
-
name:
|
|
1210
|
-
description:
|
|
1211
|
-
order:
|
|
1212
|
-
createdAt:
|
|
1213
|
-
createdBy:
|
|
1239
|
+
var CaseFolderSchema = z32.object({
|
|
1240
|
+
schemaVersion: z32.literal(1),
|
|
1241
|
+
id: z32.string().min(1),
|
|
1242
|
+
slug: z32.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
1243
|
+
name: z32.string().min(1),
|
|
1244
|
+
description: z32.string().default(""),
|
|
1245
|
+
order: z32.number().int().default(0),
|
|
1246
|
+
createdAt: z32.string(),
|
|
1247
|
+
createdBy: z32.string().default("")
|
|
1214
1248
|
}).strict();
|
|
1215
1249
|
var SUITE_SCHEMA_VERSION = 1;
|
|
1216
|
-
var SuiteEntrySchema =
|
|
1217
|
-
entryId:
|
|
1218
|
-
kind:
|
|
1250
|
+
var SuiteEntrySchema = z32.object({
|
|
1251
|
+
entryId: z32.string().min(1),
|
|
1252
|
+
kind: z32.enum(["flow", "testCase"]),
|
|
1219
1253
|
/** The document's ID — never its name or path, so renaming or moving what it
|
|
1220
1254
|
* points at cannot break the reference. */
|
|
1221
|
-
ref:
|
|
1222
|
-
enabled:
|
|
1223
|
-
order:
|
|
1255
|
+
ref: z32.string().min(1),
|
|
1256
|
+
enabled: z32.boolean().default(true),
|
|
1257
|
+
order: z32.number().int().nonnegative(),
|
|
1224
1258
|
/** What it was called when it was added, so a result stays readable after the
|
|
1225
1259
|
* source is renamed or deleted. */
|
|
1226
|
-
nameSnapshot:
|
|
1260
|
+
nameSnapshot: z32.string().default("")
|
|
1227
1261
|
}).strict();
|
|
1228
|
-
var SuiteSchema =
|
|
1229
|
-
schemaVersion:
|
|
1230
|
-
id:
|
|
1231
|
-
slug:
|
|
1232
|
-
name:
|
|
1233
|
-
description:
|
|
1234
|
-
entries:
|
|
1235
|
-
defaults:
|
|
1236
|
-
headless:
|
|
1262
|
+
var SuiteSchema = z32.object({
|
|
1263
|
+
schemaVersion: z32.literal(SUITE_SCHEMA_VERSION),
|
|
1264
|
+
id: z32.string().min(1),
|
|
1265
|
+
slug: z32.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
1266
|
+
name: z32.string().min(1),
|
|
1267
|
+
description: z32.string().default(""),
|
|
1268
|
+
entries: z32.array(SuiteEntrySchema).default([]),
|
|
1269
|
+
defaults: z32.object({
|
|
1270
|
+
headless: z32.boolean().optional(),
|
|
1237
1271
|
/** Carry on through the remaining entries, or stop at the first failure.
|
|
1238
1272
|
* Continuing is the default: a suite is a list of independent things and
|
|
1239
1273
|
* one failure rarely invalidates the rest. */
|
|
1240
|
-
failurePolicy:
|
|
1274
|
+
failurePolicy: z32.enum(["continue", "stop"]).default("continue")
|
|
1241
1275
|
}).default({ failurePolicy: "continue" }),
|
|
1242
|
-
createdAt:
|
|
1243
|
-
createdBy:
|
|
1244
|
-
updatedAt:
|
|
1245
|
-
revision:
|
|
1276
|
+
createdAt: z32.string(),
|
|
1277
|
+
createdBy: z32.string().default(""),
|
|
1278
|
+
updatedAt: z32.string(),
|
|
1279
|
+
revision: z32.number().int().nonnegative().default(0)
|
|
1246
1280
|
}).strict().superRefine((suite, ctx) => {
|
|
1247
1281
|
const seen = /* @__PURE__ */ new Set();
|
|
1248
1282
|
suite.entries.forEach((entry, i) => {
|
|
@@ -1433,19 +1467,19 @@ function restoreDebugCase(testCase, owners, steps) {
|
|
|
1433
1467
|
}
|
|
1434
1468
|
return { ...testCase, occurrences };
|
|
1435
1469
|
}
|
|
1436
|
-
var AuthNavigationSchema =
|
|
1470
|
+
var AuthNavigationSchema = z42.discriminatedUnion("kind", [
|
|
1437
1471
|
/** Act from wherever the browser already is — a "Log in" link in the header.
|
|
1438
1472
|
* The only kind that is safe part-way through a journey. */
|
|
1439
|
-
|
|
1473
|
+
z42.object({ kind: z42.literal("continue") }),
|
|
1440
1474
|
/** Open the procedure's own starting page first. Right when signing in is
|
|
1441
1475
|
* the first thing that happens; it abandons a journey in progress. */
|
|
1442
|
-
|
|
1476
|
+
z42.object({ kind: z42.literal("open"), path: z42.string().min(1) })
|
|
1443
1477
|
]);
|
|
1444
|
-
var AuthFieldSchema =
|
|
1478
|
+
var AuthFieldSchema = z42.object({
|
|
1445
1479
|
/** The step in the recorded procedure this value is typed into. Where a
|
|
1446
1480
|
* recording types into the same box more than once, this is the FIRST of
|
|
1447
1481
|
* them — the one an account's values are keyed by. */
|
|
1448
|
-
stepId:
|
|
1482
|
+
stepId: z42.string().min(1),
|
|
1449
1483
|
/** EVERY step that types into this box, when there is more than one.
|
|
1450
1484
|
*
|
|
1451
1485
|
* A login typed twice — a first attempt with a typo, a page that re-rendered
|
|
@@ -1457,47 +1491,47 @@ var AuthFieldSchema = z32.object({
|
|
|
1457
1491
|
*
|
|
1458
1492
|
* Empty means the one step in `stepId`, so every profile written before this
|
|
1459
1493
|
* reads correctly without being migrated. */
|
|
1460
|
-
stepIds:
|
|
1494
|
+
stepIds: z42.array(z42.string().min(1)).default([]),
|
|
1461
1495
|
/** What it is called where somebody fills it in — the field's own name on
|
|
1462
1496
|
* the page, so an account form reads "Username" rather than "st_9f2a". */
|
|
1463
|
-
label:
|
|
1497
|
+
label: z42.string().min(1),
|
|
1464
1498
|
/** A secret arrives as a reference and is never written into a document. */
|
|
1465
|
-
secret:
|
|
1499
|
+
secret: z42.boolean().default(false),
|
|
1466
1500
|
/** What the recording typed. Empty for a secret, whose value never travels.
|
|
1467
1501
|
* Kept so the first account can be made from what was recorded, with
|
|
1468
1502
|
* nothing to fill in. */
|
|
1469
|
-
recorded:
|
|
1503
|
+
recorded: z42.string().default("")
|
|
1470
1504
|
}).strict();
|
|
1471
1505
|
var AUTH_PROFILE_SCHEMA_VERSION = 2;
|
|
1472
|
-
var AuthProfileSchema =
|
|
1473
|
-
schemaVersion:
|
|
1474
|
-
id:
|
|
1475
|
-
slug:
|
|
1476
|
-
name:
|
|
1477
|
-
description:
|
|
1506
|
+
var AuthProfileSchema = z42.object({
|
|
1507
|
+
schemaVersion: z42.literal(AUTH_PROFILE_SCHEMA_VERSION),
|
|
1508
|
+
id: z42.string().min(1),
|
|
1509
|
+
slug: z42.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
1510
|
+
name: z42.string().min(1),
|
|
1511
|
+
description: z42.string().default(""),
|
|
1478
1512
|
/** The recorded sign-in. A flow like any other, so it is edited, debugged
|
|
1479
1513
|
* and replayed by everything that already knows how. */
|
|
1480
|
-
flowId:
|
|
1514
|
+
flowId: z42.string().min(1),
|
|
1481
1515
|
/** Which of the values it types differ per identity. */
|
|
1482
|
-
fields:
|
|
1516
|
+
fields: z42.array(AuthFieldSchema).default([]),
|
|
1483
1517
|
/** Optional, and its own procedure with its own proof — most profiles will
|
|
1484
1518
|
* not have one at first. The proof is read off that flow, the same way. */
|
|
1485
|
-
signOutFlowId:
|
|
1519
|
+
signOutFlowId: z42.string().optional(),
|
|
1486
1520
|
/** Descriptive only — "admin", "staff". Never used to decide anything, so
|
|
1487
1521
|
* two profiles may share a tag without becoming interchangeable. */
|
|
1488
|
-
tags:
|
|
1489
|
-
createdAt:
|
|
1490
|
-
createdBy:
|
|
1491
|
-
updatedAt:
|
|
1492
|
-
revision:
|
|
1522
|
+
tags: z42.array(z42.string()).default([]),
|
|
1523
|
+
createdAt: z42.string(),
|
|
1524
|
+
createdBy: z42.string().default(""),
|
|
1525
|
+
updatedAt: z42.string(),
|
|
1526
|
+
revision: z42.number().int().nonnegative().default(0)
|
|
1493
1527
|
}).strict();
|
|
1494
1528
|
var ACCOUNT_BINDING_SCHEMA_VERSION = 3;
|
|
1495
|
-
var AccountBindingSchema =
|
|
1496
|
-
schemaVersion:
|
|
1497
|
-
id:
|
|
1498
|
-
slug:
|
|
1499
|
-
name:
|
|
1500
|
-
profileId:
|
|
1529
|
+
var AccountBindingSchema = z42.object({
|
|
1530
|
+
schemaVersion: z42.literal(ACCOUNT_BINDING_SCHEMA_VERSION),
|
|
1531
|
+
id: z42.string().min(1),
|
|
1532
|
+
slug: z42.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
1533
|
+
name: z42.string().min(1),
|
|
1534
|
+
profileId: z42.string().min(1),
|
|
1501
1535
|
/** Which environments of the APPLICATION UNDER TEST these credentials work
|
|
1502
1536
|
* in — never Flowriki's own dev or staging.
|
|
1503
1537
|
*
|
|
@@ -1509,47 +1543,47 @@ var AccountBindingSchema = z32.object({
|
|
|
1509
1543
|
* duplicate account — same name, same password, same everything — for each
|
|
1510
1544
|
* deployment the identity existed in, or a blank "works anywhere" that also
|
|
1511
1545
|
* claimed environments it had never been created in. Neither was true. */
|
|
1512
|
-
environments:
|
|
1546
|
+
environments: z42.array(z42.string().min(1)).default([]),
|
|
1513
1547
|
/** Step id → what this identity types there. Ordinary values: a username is
|
|
1514
1548
|
* not a credential, and keeping it here is what lets somebody read an
|
|
1515
1549
|
* account and know who it is. */
|
|
1516
|
-
values:
|
|
1550
|
+
values: z42.record(z42.string(), z42.string()).default({}),
|
|
1517
1551
|
/** Step id → secret REFERENCE. The value is sealed in the vault and never
|
|
1518
1552
|
* enters the repository, whatever form it was typed into. */
|
|
1519
|
-
secrets:
|
|
1553
|
+
secrets: z42.record(z42.string(), z42.string().regex(/^[a-z][a-z0-9_]*$/i)).default({}),
|
|
1520
1554
|
/** What this identity should look like once signed in — a displayed name, a
|
|
1521
1555
|
* tenant. Not secret, and checked so that an already-authenticated browser
|
|
1522
1556
|
* holding the WRONG account is reported rather than accepted. */
|
|
1523
|
-
identity:
|
|
1524
|
-
label:
|
|
1525
|
-
tenant:
|
|
1557
|
+
identity: z42.object({
|
|
1558
|
+
label: z42.string().optional(),
|
|
1559
|
+
tenant: z42.string().optional()
|
|
1526
1560
|
}).default({}),
|
|
1527
|
-
createdAt:
|
|
1528
|
-
createdBy:
|
|
1529
|
-
updatedAt:
|
|
1530
|
-
revision:
|
|
1561
|
+
createdAt: z42.string(),
|
|
1562
|
+
createdBy: z42.string().default(""),
|
|
1563
|
+
updatedAt: z42.string(),
|
|
1564
|
+
revision: z42.number().int().nonnegative().default(0)
|
|
1531
1565
|
}).strict();
|
|
1532
|
-
var AuthReferenceSchema =
|
|
1533
|
-
profileId:
|
|
1566
|
+
var AuthReferenceSchema = z42.object({
|
|
1567
|
+
profileId: z42.string().min(1),
|
|
1534
1568
|
/** Where this use of it begins. See the step's own field. */
|
|
1535
|
-
from:
|
|
1569
|
+
from: z42.enum(["loginPage", "here"]).optional(),
|
|
1536
1570
|
/** Absent means "the only account bound to this profile for the selected
|
|
1537
1571
|
* environment", which is resolved before a browser opens and refused when
|
|
1538
1572
|
* it is ambiguous — a silent choice between two identities is the failure
|
|
1539
1573
|
* this field exists to prevent. */
|
|
1540
|
-
accountId:
|
|
1574
|
+
accountId: z42.string().optional()
|
|
1541
1575
|
}).strict();
|
|
1542
1576
|
var ActorSchema = ActorDefinitionSchema;
|
|
1543
|
-
var DeliveredAuthSchema =
|
|
1544
|
-
profileId:
|
|
1545
|
-
accountId:
|
|
1546
|
-
name:
|
|
1547
|
-
accountName:
|
|
1548
|
-
steps:
|
|
1577
|
+
var DeliveredAuthSchema = z42.object({
|
|
1578
|
+
profileId: z42.string().min(1),
|
|
1579
|
+
accountId: z42.string().min(1),
|
|
1580
|
+
name: z42.string(),
|
|
1581
|
+
accountName: z42.string(),
|
|
1582
|
+
steps: z42.array(RecordedStepSchema),
|
|
1549
1583
|
navigation: AuthNavigationSchema,
|
|
1550
|
-
success:
|
|
1551
|
-
secretRefs:
|
|
1552
|
-
signOut:
|
|
1584
|
+
success: z42.array(RecordedAssertionSchema),
|
|
1585
|
+
secretRefs: z42.record(z42.string(), z42.string()),
|
|
1586
|
+
signOut: z42.object({ steps: z42.array(RecordedStepSchema), success: z42.array(RecordedAssertionSchema) }).optional()
|
|
1553
1587
|
}).strict();
|
|
1554
1588
|
function actorPreparations(actors = []) {
|
|
1555
1589
|
return actors.flatMap((actor) => actor.startSignedIn ? [{
|
|
@@ -1666,8 +1700,8 @@ function expandForRun(flow, lookup) {
|
|
|
1666
1700
|
return { ...rest, steps: [...signIn ? [signIn] : [], ...steps, ...flow.steps] };
|
|
1667
1701
|
}
|
|
1668
1702
|
var HELPER_SCHEMA_VERSION = 1;
|
|
1669
|
-
var SecretRef =
|
|
1670
|
-
var PatternSchema =
|
|
1703
|
+
var SecretRef = z5.string().regex(/^[a-z][a-z0-9_]*$/i);
|
|
1704
|
+
var PatternSchema = z5.string().max(500).refine((source) => {
|
|
1671
1705
|
try {
|
|
1672
1706
|
new RegExp(source);
|
|
1673
1707
|
return true;
|
|
@@ -1675,88 +1709,88 @@ var PatternSchema = z42.string().max(500).refine((source) => {
|
|
|
1675
1709
|
return false;
|
|
1676
1710
|
}
|
|
1677
1711
|
}, "that is not a valid pattern");
|
|
1678
|
-
var MailboxHelperSchema =
|
|
1679
|
-
kind:
|
|
1712
|
+
var MailboxHelperSchema = z5.object({
|
|
1713
|
+
kind: z5.literal("mailbox"),
|
|
1680
1714
|
/** IMAP, which every provider offers: Gmail, Outlook, Zoho, Fastmail… */
|
|
1681
|
-
host:
|
|
1682
|
-
port:
|
|
1683
|
-
secure:
|
|
1684
|
-
username:
|
|
1715
|
+
host: z5.string().min(1),
|
|
1716
|
+
port: z5.number().int().positive().default(993),
|
|
1717
|
+
secure: z5.boolean().default(true),
|
|
1718
|
+
username: z5.string().min(1),
|
|
1685
1719
|
passwordRef: SecretRef,
|
|
1686
|
-
folder:
|
|
1720
|
+
folder: z5.string().min(1).default("INBOX"),
|
|
1687
1721
|
/** Which email. All optional; the newest that matches every one given. */
|
|
1688
|
-
match:
|
|
1689
|
-
to:
|
|
1690
|
-
from:
|
|
1691
|
-
subject:
|
|
1722
|
+
match: z5.object({
|
|
1723
|
+
to: z5.string().default(""),
|
|
1724
|
+
from: z5.string().default(""),
|
|
1725
|
+
subject: z5.string().default("")
|
|
1692
1726
|
}).strict().default({}),
|
|
1693
1727
|
/** What to take out of it. */
|
|
1694
|
-
extract:
|
|
1695
|
-
take:
|
|
1728
|
+
extract: z5.object({
|
|
1729
|
+
take: z5.enum(["code", "link", "subject", "body"]).default("code"),
|
|
1696
1730
|
/** For a code: the pattern, first group if it has one. Default: 4–8 digits.
|
|
1697
1731
|
* For a link: only links containing this text. */
|
|
1698
|
-
pattern:
|
|
1732
|
+
pattern: z5.string().max(500).default("")
|
|
1699
1733
|
}).strict().default({}),
|
|
1700
1734
|
/** How long to wait for the email to arrive. */
|
|
1701
|
-
waitSeconds:
|
|
1735
|
+
waitSeconds: z5.number().int().min(0).max(300).default(60)
|
|
1702
1736
|
}).strict();
|
|
1703
|
-
var TotpHelperSchema =
|
|
1704
|
-
kind:
|
|
1737
|
+
var TotpHelperSchema = z5.object({
|
|
1738
|
+
kind: z5.literal("totp"),
|
|
1705
1739
|
/** The authenticator secret (base32, from the QR code's "manual entry"). */
|
|
1706
1740
|
secretRef: SecretRef,
|
|
1707
|
-
digits:
|
|
1708
|
-
period:
|
|
1709
|
-
algorithm:
|
|
1741
|
+
digits: z5.union([z5.literal(6), z5.literal(8)]).default(6),
|
|
1742
|
+
period: z5.number().int().min(10).max(120).default(30),
|
|
1743
|
+
algorithm: z5.enum(["SHA1", "SHA256", "SHA512"]).default("SHA1")
|
|
1710
1744
|
}).strict();
|
|
1711
|
-
var SmsHelperSchema =
|
|
1712
|
-
kind:
|
|
1713
|
-
provider:
|
|
1714
|
-
accountSid:
|
|
1745
|
+
var SmsHelperSchema = z5.object({
|
|
1746
|
+
kind: z5.literal("sms"),
|
|
1747
|
+
provider: z5.literal("twilio").default("twilio"),
|
|
1748
|
+
accountSid: z5.string().regex(/^AC[0-9a-f]{32}$/i, "a Twilio account SID starts with AC followed by 32 characters"),
|
|
1715
1749
|
authTokenRef: SecretRef,
|
|
1716
1750
|
/** The Twilio number the application texts. */
|
|
1717
|
-
to:
|
|
1718
|
-
match:
|
|
1719
|
-
from:
|
|
1720
|
-
contains:
|
|
1751
|
+
to: z5.string().min(3),
|
|
1752
|
+
match: z5.object({
|
|
1753
|
+
from: z5.string().default(""),
|
|
1754
|
+
contains: z5.string().default("")
|
|
1721
1755
|
}).strict().default({}),
|
|
1722
|
-
extract:
|
|
1723
|
-
waitSeconds:
|
|
1756
|
+
extract: z5.object({ pattern: z5.string().max(500).default("") }).strict().default({}),
|
|
1757
|
+
waitSeconds: z5.number().int().min(0).max(300).default(60)
|
|
1724
1758
|
}).strict();
|
|
1725
|
-
var HttpHelperSchema =
|
|
1726
|
-
kind:
|
|
1727
|
-
method:
|
|
1728
|
-
url:
|
|
1759
|
+
var HttpHelperSchema = z5.object({
|
|
1760
|
+
kind: z5.literal("http"),
|
|
1761
|
+
method: z5.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).default("POST"),
|
|
1762
|
+
url: z5.string().min(1),
|
|
1729
1763
|
/** Plain headers, in the repository. */
|
|
1730
|
-
headers:
|
|
1764
|
+
headers: z5.record(z5.string(), z5.string()).default({}),
|
|
1731
1765
|
/** Header name → vault reference, for tokens and keys. */
|
|
1732
|
-
secretHeaders:
|
|
1733
|
-
body:
|
|
1766
|
+
secretHeaders: z5.record(z5.string(), SecretRef).default({}),
|
|
1767
|
+
body: z5.string().max(2e4).default(""),
|
|
1734
1768
|
/** Refused unless the response has this status. 0 means any 2xx. */
|
|
1735
|
-
expectStatus:
|
|
1736
|
-
extract:
|
|
1737
|
-
take:
|
|
1769
|
+
expectStatus: z5.number().int().min(0).max(599).default(0),
|
|
1770
|
+
extract: z5.object({
|
|
1771
|
+
take: z5.enum(["json", "pattern", "status", "nothing"]).default("nothing"),
|
|
1738
1772
|
/** For json: a dot path — `data.order.id`, `items.0.code`. */
|
|
1739
|
-
path:
|
|
1740
|
-
pattern:
|
|
1773
|
+
path: z5.string().max(300).default(""),
|
|
1774
|
+
pattern: z5.string().max(500).default("")
|
|
1741
1775
|
}).strict().default({})
|
|
1742
1776
|
}).strict();
|
|
1743
|
-
var HelperConfigSchema =
|
|
1777
|
+
var HelperConfigSchema = z5.discriminatedUnion("kind", [
|
|
1744
1778
|
MailboxHelperSchema,
|
|
1745
1779
|
TotpHelperSchema,
|
|
1746
1780
|
SmsHelperSchema,
|
|
1747
1781
|
HttpHelperSchema
|
|
1748
1782
|
]);
|
|
1749
|
-
var HelperSchema =
|
|
1750
|
-
schemaVersion:
|
|
1751
|
-
id:
|
|
1752
|
-
slug:
|
|
1753
|
-
name:
|
|
1754
|
-
description:
|
|
1783
|
+
var HelperSchema = z5.object({
|
|
1784
|
+
schemaVersion: z5.literal(HELPER_SCHEMA_VERSION),
|
|
1785
|
+
id: z5.string().min(1),
|
|
1786
|
+
slug: z5.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
1787
|
+
name: z5.string().min(1).max(120),
|
|
1788
|
+
description: z5.string().max(1e3).default(""),
|
|
1755
1789
|
config: HelperConfigSchema,
|
|
1756
|
-
createdAt:
|
|
1757
|
-
createdBy:
|
|
1758
|
-
updatedAt:
|
|
1759
|
-
revision:
|
|
1790
|
+
createdAt: z5.string(),
|
|
1791
|
+
createdBy: z5.string().default(""),
|
|
1792
|
+
updatedAt: z5.string(),
|
|
1793
|
+
revision: z5.number().int().nonnegative().default(0)
|
|
1760
1794
|
}).strict().superRefine((helper, ctx) => {
|
|
1761
1795
|
const patterns = [
|
|
1762
1796
|
helper.config.kind === "mailbox" && helper.config.extract.take === "code" ? helper.config.extract.pattern : "",
|
|
@@ -1769,9 +1803,9 @@ var HelperSchema = z42.object({
|
|
|
1769
1803
|
}
|
|
1770
1804
|
}
|
|
1771
1805
|
});
|
|
1772
|
-
var DeliveredHelperSchema =
|
|
1773
|
-
id:
|
|
1774
|
-
name:
|
|
1806
|
+
var DeliveredHelperSchema = z5.object({
|
|
1807
|
+
id: z5.string().min(1),
|
|
1808
|
+
name: z5.string(),
|
|
1775
1809
|
config: HelperConfigSchema
|
|
1776
1810
|
}).strict();
|
|
1777
1811
|
var LIBRARY_CASE_SCHEMA_VERSION = 1;
|
|
@@ -1779,83 +1813,83 @@ var TEST_TYPES = ["functional", "negative", "edge", "regression", "smoke", "acce
|
|
|
1779
1813
|
var PRIORITIES = ["P0", "P1", "P2", "P3"];
|
|
1780
1814
|
var CASE_STATUSES = ["draft", "ready", "deprecated"];
|
|
1781
1815
|
var AUTOMATION_STATES = ["none", "planned", "automated", "not-automatable"];
|
|
1782
|
-
var LibraryStepSchema =
|
|
1783
|
-
id:
|
|
1784
|
-
action:
|
|
1816
|
+
var LibraryStepSchema = z6.object({
|
|
1817
|
+
id: z6.string().min(1),
|
|
1818
|
+
action: z6.string().min(1),
|
|
1785
1819
|
/** What to type or choose, when the action needs it. */
|
|
1786
|
-
data:
|
|
1820
|
+
data: z6.string().optional(),
|
|
1787
1821
|
/** What should happen. Absent for a step that only gets somewhere. */
|
|
1788
|
-
expected:
|
|
1822
|
+
expected: z6.string().optional()
|
|
1789
1823
|
}).strict();
|
|
1790
|
-
var AutomationLinkSchema =
|
|
1791
|
-
automationId:
|
|
1792
|
-
caseRevision:
|
|
1824
|
+
var AutomationLinkSchema = z6.object({
|
|
1825
|
+
automationId: z6.string().min(1),
|
|
1826
|
+
caseRevision: z6.number().int().nonnegative(),
|
|
1793
1827
|
/** The automation's revision when the link was made or last confirmed —
|
|
1794
1828
|
* an automation edited since may no longer check what the case says. */
|
|
1795
|
-
automationRevision:
|
|
1796
|
-
at:
|
|
1797
|
-
by:
|
|
1829
|
+
automationRevision: z6.number().int().nonnegative().optional(),
|
|
1830
|
+
at: z6.string(),
|
|
1831
|
+
by: z6.string().default("")
|
|
1798
1832
|
}).strict();
|
|
1799
|
-
var CaseOriginSchema =
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
kind:
|
|
1833
|
+
var CaseOriginSchema = z6.discriminatedUnion("kind", [
|
|
1834
|
+
z6.object({ kind: z6.literal("manual") }).strict(),
|
|
1835
|
+
z6.object({
|
|
1836
|
+
kind: z6.literal("import"),
|
|
1803
1837
|
/** "csv", "xlsx", "testrail", "zephyr", "xray", "text"… */
|
|
1804
|
-
format:
|
|
1805
|
-
file:
|
|
1838
|
+
format: z6.string().min(1),
|
|
1839
|
+
file: z6.string().min(1),
|
|
1806
1840
|
/** Row or item in that file, to find it again. */
|
|
1807
|
-
row:
|
|
1841
|
+
row: z6.string().optional()
|
|
1808
1842
|
}).strict(),
|
|
1809
|
-
|
|
1810
|
-
kind:
|
|
1811
|
-
sourceId:
|
|
1812
|
-
sourceVersion:
|
|
1813
|
-
requirementIds:
|
|
1843
|
+
z6.object({
|
|
1844
|
+
kind: z6.literal("generated"),
|
|
1845
|
+
sourceId: z6.string().min(1),
|
|
1846
|
+
sourceVersion: z6.number().int().positive(),
|
|
1847
|
+
requirementIds: z6.array(z6.string().min(1)).default([])
|
|
1814
1848
|
}).strict()
|
|
1815
1849
|
]);
|
|
1816
|
-
var TestDataSchema =
|
|
1817
|
-
name:
|
|
1818
|
-
value:
|
|
1819
|
-
secretRef:
|
|
1850
|
+
var TestDataSchema = z6.object({
|
|
1851
|
+
name: z6.string().min(1),
|
|
1852
|
+
value: z6.string().optional(),
|
|
1853
|
+
secretRef: z6.string().regex(/^[a-z][a-z0-9_]*$/i).optional()
|
|
1820
1854
|
}).strict();
|
|
1821
|
-
var LibraryCaseSchema =
|
|
1822
|
-
schemaVersion:
|
|
1823
|
-
id:
|
|
1855
|
+
var LibraryCaseSchema = z6.object({
|
|
1856
|
+
schemaVersion: z6.literal(LIBRARY_CASE_SCHEMA_VERSION),
|
|
1857
|
+
id: z6.string().regex(/^tcs_[A-Za-z0-9]+$/),
|
|
1824
1858
|
/** "TC-142": what people say out loud. The id is what links point at. */
|
|
1825
|
-
key:
|
|
1859
|
+
key: z6.string().regex(/^TC-[1-9][0-9]*$/),
|
|
1826
1860
|
/** The same features flows are filed under (`f_<slug>`), so one feature
|
|
1827
1861
|
* holds both what to test and what tests it. */
|
|
1828
|
-
featureId:
|
|
1829
|
-
slug:
|
|
1830
|
-
title:
|
|
1831
|
-
description:
|
|
1832
|
-
type:
|
|
1833
|
-
priority:
|
|
1834
|
-
status:
|
|
1835
|
-
preconditions:
|
|
1836
|
-
steps:
|
|
1837
|
-
testData:
|
|
1838
|
-
tags:
|
|
1862
|
+
featureId: z6.string().min(1),
|
|
1863
|
+
slug: z6.string().regex(/^[a-z0-9][a-z0-9-]*$/),
|
|
1864
|
+
title: z6.string().min(1).max(300),
|
|
1865
|
+
description: z6.string().default(""),
|
|
1866
|
+
type: z6.enum(TEST_TYPES).default("functional"),
|
|
1867
|
+
priority: z6.enum(PRIORITIES).default("P2"),
|
|
1868
|
+
status: z6.enum(CASE_STATUSES).default("draft"),
|
|
1869
|
+
preconditions: z6.array(z6.string().min(1)).default([]),
|
|
1870
|
+
steps: z6.array(LibraryStepSchema).default([]),
|
|
1871
|
+
testData: z6.array(TestDataSchema).default([]),
|
|
1872
|
+
tags: z6.array(z6.string().min(1)).default([]),
|
|
1839
1873
|
/** Requirement ids (Flowriki storage). The text is not copied here. */
|
|
1840
|
-
covers:
|
|
1841
|
-
automation:
|
|
1842
|
-
state:
|
|
1874
|
+
covers: z6.array(z6.string().min(1)).default([]),
|
|
1875
|
+
automation: z6.object({
|
|
1876
|
+
state: z6.enum(AUTOMATION_STATES).default("none"),
|
|
1843
1877
|
/** Why it cannot be automated, when it cannot. */
|
|
1844
|
-
reason:
|
|
1878
|
+
reason: z6.string().optional(),
|
|
1845
1879
|
/** The plan for automating it: flows to reuse, flows to record, checks to
|
|
1846
1880
|
* switch on, accounts and helpers it needs, and what cannot be automated.
|
|
1847
1881
|
* Written (usually by the assistant) and approved before anything is
|
|
1848
1882
|
* recorded. */
|
|
1849
|
-
plan:
|
|
1850
|
-
planApproved:
|
|
1851
|
-
links:
|
|
1883
|
+
plan: z6.string().max(2e4).optional(),
|
|
1884
|
+
planApproved: z6.boolean().optional(),
|
|
1885
|
+
links: z6.array(AutomationLinkSchema).default([])
|
|
1852
1886
|
}).strict().default({}),
|
|
1853
1887
|
origin: CaseOriginSchema.default({ kind: "manual" }),
|
|
1854
|
-
createdAt:
|
|
1855
|
-
createdBy:
|
|
1856
|
-
updatedAt:
|
|
1857
|
-
updatedBy:
|
|
1858
|
-
revision:
|
|
1888
|
+
createdAt: z6.string(),
|
|
1889
|
+
createdBy: z6.string().default(""),
|
|
1890
|
+
updatedAt: z6.string(),
|
|
1891
|
+
updatedBy: z6.string().default(""),
|
|
1892
|
+
revision: z6.number().int().nonnegative().default(0)
|
|
1859
1893
|
}).strict().superRefine((doc, ctx) => {
|
|
1860
1894
|
const seen = /* @__PURE__ */ new Set();
|
|
1861
1895
|
doc.steps.forEach((step, i) => {
|
|
@@ -1874,144 +1908,167 @@ var LibraryCaseSchema = z5.object({
|
|
|
1874
1908
|
}
|
|
1875
1909
|
});
|
|
1876
1910
|
var SOURCE_KINDS = ["upload", "jira", "figma", "confluence", "linear", "github-issue", "notion", "url"];
|
|
1877
|
-
var SourceVersionSchema =
|
|
1878
|
-
v:
|
|
1879
|
-
hash:
|
|
1880
|
-
extractedText:
|
|
1911
|
+
var SourceVersionSchema = z6.object({
|
|
1912
|
+
v: z6.number().int().positive(),
|
|
1913
|
+
hash: z6.string().min(1),
|
|
1914
|
+
extractedText: z6.string(),
|
|
1881
1915
|
/** Where an uploaded file WAS kept. Only text is kept since 2026-10-11;
|
|
1882
1916
|
* read so older records still parse, and cleared at start-up. */
|
|
1883
|
-
originalKey:
|
|
1884
|
-
mediaType:
|
|
1885
|
-
at:
|
|
1886
|
-
by:
|
|
1917
|
+
originalKey: z6.string().optional(),
|
|
1918
|
+
mediaType: z6.string().optional(),
|
|
1919
|
+
at: z6.string(),
|
|
1920
|
+
by: z6.string().default("")
|
|
1887
1921
|
}).strict();
|
|
1888
|
-
var SourceSchema =
|
|
1889
|
-
id:
|
|
1890
|
-
projectId:
|
|
1891
|
-
title:
|
|
1892
|
-
kind:
|
|
1893
|
-
versions:
|
|
1894
|
-
integrationId:
|
|
1895
|
-
externalId:
|
|
1896
|
-
externalUrl:
|
|
1897
|
-
createdAt:
|
|
1898
|
-
createdBy:
|
|
1922
|
+
var SourceSchema = z6.object({
|
|
1923
|
+
id: z6.string().regex(/^src_[A-Za-z0-9]+$/),
|
|
1924
|
+
projectId: z6.string().min(1),
|
|
1925
|
+
title: z6.string().min(1).max(300),
|
|
1926
|
+
kind: z6.enum(SOURCE_KINDS),
|
|
1927
|
+
versions: z6.array(SourceVersionSchema).min(1),
|
|
1928
|
+
integrationId: z6.string().optional(),
|
|
1929
|
+
externalId: z6.string().optional(),
|
|
1930
|
+
externalUrl: z6.string().url().optional(),
|
|
1931
|
+
createdAt: z6.string(),
|
|
1932
|
+
createdBy: z6.string().default("")
|
|
1899
1933
|
}).strict();
|
|
1900
|
-
var RequirementSchema =
|
|
1901
|
-
id:
|
|
1902
|
-
projectId:
|
|
1903
|
-
sourceId:
|
|
1904
|
-
sourceVersion:
|
|
1934
|
+
var RequirementSchema = z6.object({
|
|
1935
|
+
id: z6.string().regex(/^req_[A-Za-z0-9]+$/),
|
|
1936
|
+
projectId: z6.string().min(1),
|
|
1937
|
+
sourceId: z6.string().min(1),
|
|
1938
|
+
sourceVersion: z6.number().int().positive(),
|
|
1905
1939
|
/** Where in the source: a heading path, a Jira key, a Figma node. */
|
|
1906
|
-
anchor:
|
|
1907
|
-
text:
|
|
1908
|
-
featureId:
|
|
1940
|
+
anchor: z6.string().min(1),
|
|
1941
|
+
text: z6.string().min(1),
|
|
1942
|
+
featureId: z6.string().optional(),
|
|
1909
1943
|
/** As of the source's latest version: new in it, changed by it, unchanged
|
|
1910
1944
|
* ("active"), or gone from it. */
|
|
1911
|
-
state:
|
|
1912
|
-
history:
|
|
1913
|
-
sourceVersion:
|
|
1914
|
-
text:
|
|
1915
|
-
state:
|
|
1945
|
+
state: z6.enum(["new", "active", "changed", "removed"]).default("new"),
|
|
1946
|
+
history: z6.array(z6.object({
|
|
1947
|
+
sourceVersion: z6.number().int().positive(),
|
|
1948
|
+
text: z6.string(),
|
|
1949
|
+
state: z6.enum(["new", "active", "changed", "removed"])
|
|
1916
1950
|
}).strict()).default([])
|
|
1917
1951
|
}).strict();
|
|
1918
1952
|
var MANUAL_OUTCOMES = ["untested", "passed", "failed", "blocked", "skipped"];
|
|
1919
|
-
var EvidenceSchema =
|
|
1920
|
-
id:
|
|
1953
|
+
var EvidenceSchema = z7.object({
|
|
1954
|
+
id: z7.string().regex(/^ev_[A-Za-z0-9]+$/),
|
|
1921
1955
|
/** A file kept in Flowriki's evidence storage, or a link to one elsewhere. */
|
|
1922
|
-
kind:
|
|
1923
|
-
name:
|
|
1924
|
-
mediaType:
|
|
1925
|
-
size:
|
|
1926
|
-
url:
|
|
1956
|
+
kind: z7.enum(["file", "link"]),
|
|
1957
|
+
name: z7.string().min(1).max(200),
|
|
1958
|
+
mediaType: z7.string().optional(),
|
|
1959
|
+
size: z7.number().int().nonnegative().optional(),
|
|
1960
|
+
url: z7.string().url().optional(),
|
|
1927
1961
|
/** The step it shows, when it belongs to one. */
|
|
1928
|
-
stepId:
|
|
1929
|
-
at:
|
|
1930
|
-
by:
|
|
1962
|
+
stepId: z7.string().optional(),
|
|
1963
|
+
at: z7.string(),
|
|
1964
|
+
by: z7.string().default("")
|
|
1931
1965
|
}).strict();
|
|
1932
|
-
var StepOutcomeSchema =
|
|
1933
|
-
stepId:
|
|
1934
|
-
outcome:
|
|
1966
|
+
var StepOutcomeSchema = z7.object({
|
|
1967
|
+
stepId: z7.string().min(1),
|
|
1968
|
+
outcome: z7.enum(MANUAL_OUTCOMES),
|
|
1935
1969
|
/** What actually happened, when it was not what was expected. */
|
|
1936
|
-
actual:
|
|
1970
|
+
actual: z7.string().max(4e3).optional()
|
|
1937
1971
|
}).strict();
|
|
1938
|
-
var ManualResultSchema =
|
|
1939
|
-
outcome:
|
|
1940
|
-
steps:
|
|
1941
|
-
note:
|
|
1942
|
-
evidence:
|
|
1943
|
-
bugIds:
|
|
1944
|
-
tester:
|
|
1945
|
-
at:
|
|
1972
|
+
var ManualResultSchema = z7.object({
|
|
1973
|
+
outcome: z7.enum(MANUAL_OUTCOMES),
|
|
1974
|
+
steps: z7.array(StepOutcomeSchema).default([]),
|
|
1975
|
+
note: z7.string().max(8e3).default(""),
|
|
1976
|
+
evidence: z7.array(EvidenceSchema).default([]),
|
|
1977
|
+
bugIds: z7.array(z7.string().min(1)).default([]),
|
|
1978
|
+
tester: z7.string().default(""),
|
|
1979
|
+
at: z7.string()
|
|
1946
1980
|
}).strict();
|
|
1947
|
-
var CycleEntrySchema =
|
|
1948
|
-
testCaseId:
|
|
1949
|
-
key:
|
|
1950
|
-
title:
|
|
1951
|
-
featureId:
|
|
1952
|
-
priority:
|
|
1981
|
+
var CycleEntrySchema = z7.object({
|
|
1982
|
+
testCaseId: z7.string().min(1),
|
|
1983
|
+
key: z7.string().min(1),
|
|
1984
|
+
title: z7.string().min(1),
|
|
1985
|
+
featureId: z7.string().min(1),
|
|
1986
|
+
priority: z7.enum(PRIORITIES),
|
|
1953
1987
|
/** The case revision snapshot, so "the case changed since" is answerable. */
|
|
1954
|
-
caseRevision:
|
|
1955
|
-
preconditions:
|
|
1956
|
-
steps:
|
|
1957
|
-
assignee:
|
|
1988
|
+
caseRevision: z7.number().int().nonnegative(),
|
|
1989
|
+
preconditions: z7.array(z7.string()).default([]),
|
|
1990
|
+
steps: z7.array(z7.object({ id: z7.string(), action: z7.string(), data: z7.string().optional(), expected: z7.string().optional() }).strict()).default([]),
|
|
1991
|
+
assignee: z7.string().optional(),
|
|
1958
1992
|
result: ManualResultSchema.nullable().default(null),
|
|
1959
1993
|
/** Earlier results for this case in this cycle, newest last — a retest
|
|
1960
1994
|
* keeps what the first attempt found. */
|
|
1961
|
-
history:
|
|
1995
|
+
history: z7.array(ManualResultSchema).default([])
|
|
1962
1996
|
}).strict();
|
|
1963
|
-
var TestCycleSchema =
|
|
1964
|
-
id:
|
|
1965
|
-
projectId:
|
|
1966
|
-
name:
|
|
1967
|
-
description:
|
|
1968
|
-
status:
|
|
1997
|
+
var TestCycleSchema = z7.object({
|
|
1998
|
+
id: z7.string().regex(/^cyc_[A-Za-z0-9]+$/),
|
|
1999
|
+
projectId: z7.string().min(1),
|
|
2000
|
+
name: z7.string().min(1).max(200),
|
|
2001
|
+
description: z7.string().max(4e3).default(""),
|
|
2002
|
+
status: z7.enum(["open", "closed"]).default("open"),
|
|
1969
2003
|
/** Which branch the cases were read from; null for the published tests. */
|
|
1970
|
-
changeId:
|
|
1971
|
-
entries:
|
|
1972
|
-
createdAt:
|
|
1973
|
-
createdBy:
|
|
1974
|
-
updatedAt:
|
|
1975
|
-
closedAt:
|
|
2004
|
+
changeId: z7.string().nullable().default(null),
|
|
2005
|
+
entries: z7.array(CycleEntrySchema).default([]),
|
|
2006
|
+
createdAt: z7.string(),
|
|
2007
|
+
createdBy: z7.string().default(""),
|
|
2008
|
+
updatedAt: z7.string(),
|
|
2009
|
+
closedAt: z7.string().nullable().default(null)
|
|
1976
2010
|
}).strict();
|
|
1977
2011
|
var BUG_STATUSES = ["open", "in-progress", "fixed", "verified", "closed", "wont-fix"];
|
|
1978
2012
|
var SEVERITIES = ["critical", "major", "minor", "trivial"];
|
|
1979
|
-
var BugSchema =
|
|
1980
|
-
id:
|
|
1981
|
-
key:
|
|
1982
|
-
projectId:
|
|
1983
|
-
title:
|
|
1984
|
-
description:
|
|
1985
|
-
severity:
|
|
1986
|
-
status:
|
|
1987
|
-
tracker:
|
|
1988
|
-
externalKey:
|
|
1989
|
-
url:
|
|
2013
|
+
var BugSchema = z7.object({
|
|
2014
|
+
id: z7.string().regex(/^bug_[A-Za-z0-9]+$/),
|
|
2015
|
+
key: z7.string().regex(/^BUG-[1-9][0-9]*$/),
|
|
2016
|
+
projectId: z7.string().min(1),
|
|
2017
|
+
title: z7.string().min(1).max(300),
|
|
2018
|
+
description: z7.string().max(2e4).default(""),
|
|
2019
|
+
severity: z7.enum(SEVERITIES).default("major"),
|
|
2020
|
+
status: z7.enum(BUG_STATUSES).default("open"),
|
|
2021
|
+
tracker: z7.enum(["flowriki", "jira", "linear", "github"]).default("flowriki"),
|
|
2022
|
+
externalKey: z7.string().optional(),
|
|
2023
|
+
url: z7.string().url().optional(),
|
|
1990
2024
|
/** Where it was found: a case, the step in it, the cycle that ran it. */
|
|
1991
|
-
testCaseIds:
|
|
1992
|
-
cycleIds:
|
|
1993
|
-
runIds:
|
|
1994
|
-
automationIds:
|
|
1995
|
-
foundAt:
|
|
1996
|
-
createdAt:
|
|
1997
|
-
createdBy:
|
|
1998
|
-
updatedAt:
|
|
2025
|
+
testCaseIds: z7.array(z7.string()).default([]),
|
|
2026
|
+
cycleIds: z7.array(z7.string()).default([]),
|
|
2027
|
+
runIds: z7.array(z7.string()).default([]),
|
|
2028
|
+
automationIds: z7.array(z7.string()).default([]),
|
|
2029
|
+
foundAt: z7.object({ cycleId: z7.string(), testCaseId: z7.string(), stepId: z7.string().optional() }).strict().optional(),
|
|
2030
|
+
createdAt: z7.string(),
|
|
2031
|
+
createdBy: z7.string().default(""),
|
|
2032
|
+
updatedAt: z7.string()
|
|
1999
2033
|
}).strict();
|
|
2000
2034
|
var STOP = new Set("a an the and or of to in on for with by is are be as at it this that from user users can should must shall will when then given".split(" "));
|
|
2001
|
-
var ConversationSchema =
|
|
2002
|
-
id:
|
|
2003
|
-
projectId:
|
|
2035
|
+
var ConversationSchema = z8.object({
|
|
2036
|
+
id: z8.string().regex(/^conv_[A-Za-z0-9]+$/),
|
|
2037
|
+
projectId: z8.string().min(1),
|
|
2004
2038
|
/** Whose: conversations are personal. */
|
|
2005
|
-
userId:
|
|
2006
|
-
title:
|
|
2007
|
-
mode:
|
|
2039
|
+
userId: z8.string().min(1),
|
|
2040
|
+
title: z8.string().min(1).max(200),
|
|
2041
|
+
mode: z8.enum(["ask", "do"]).default("ask"),
|
|
2008
2042
|
/** The assistant's own session, to continue where it left off. */
|
|
2009
|
-
sessionId:
|
|
2043
|
+
sessionId: z8.string().optional(),
|
|
2010
2044
|
/** The conversation as the dashboard draws it. Kept as given: the shape
|
|
2011
2045
|
* belongs to the screen, and the service only stores and returns it. */
|
|
2012
|
-
lines:
|
|
2013
|
-
createdAt:
|
|
2014
|
-
updatedAt:
|
|
2046
|
+
lines: z8.array(z8.unknown()).max(2e3).default([]),
|
|
2047
|
+
createdAt: z8.string(),
|
|
2048
|
+
updatedAt: z8.string()
|
|
2049
|
+
}).strict();
|
|
2050
|
+
var IMPORT_DRAFT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
2051
|
+
var ImportDraftCaseSchema = z9.object({
|
|
2052
|
+
name: z9.string().min(1).max(120),
|
|
2053
|
+
description: z9.string().max(4e3).default(""),
|
|
2054
|
+
businessSteps: z9.array(BusinessStepSchema).max(200),
|
|
2055
|
+
/** Its id or row in the file. */
|
|
2056
|
+
row: z9.string().max(200).default("")
|
|
2057
|
+
}).strict();
|
|
2058
|
+
var ImportDraftSchema = z9.object({
|
|
2059
|
+
id: z9.string().regex(/^imp_[A-Za-z0-9]+$/),
|
|
2060
|
+
projectId: z9.string().min(1),
|
|
2061
|
+
userId: z9.string().min(1),
|
|
2062
|
+
file: z9.string().max(300),
|
|
2063
|
+
/** Every sheet, every cell as text. */
|
|
2064
|
+
sheets: z9.array(z9.object({ name: z9.string().max(200), rows: z9.array(z9.array(z9.string())) }).strict()).max(200),
|
|
2065
|
+
status: z9.enum(["waiting", "converting", "done", "failed"]).default("waiting"),
|
|
2066
|
+
/** What the assistant made of it: features, each with its cases. */
|
|
2067
|
+
result: z9.array(z9.object({ feature: z9.string().min(1).max(120), cases: z9.array(ImportDraftCaseSchema) }).strict()).default([]),
|
|
2068
|
+
/** The assistant's word on anything it could not convert. */
|
|
2069
|
+
note: z9.string().max(4e3).default(""),
|
|
2070
|
+
createdAt: z9.string(),
|
|
2071
|
+
updatedAt: z9.string()
|
|
2015
2072
|
}).strict();
|
|
2016
2073
|
|
|
2017
2074
|
// ../engine-playwright/dist/index.js
|
|
@@ -6937,8 +6994,8 @@ async function fieldNames(page) {
|
|
|
6937
6994
|
}
|
|
6938
6995
|
|
|
6939
6996
|
// ../results/dist/chunk-LYCTVHPR.js
|
|
6940
|
-
import { z as
|
|
6941
|
-
var RunStatusSchema =
|
|
6997
|
+
import { z as z10 } from "zod";
|
|
6998
|
+
var RunStatusSchema = z10.enum([
|
|
6942
6999
|
"queued",
|
|
6943
7000
|
"running",
|
|
6944
7001
|
"passed",
|
|
@@ -6946,7 +7003,7 @@ var RunStatusSchema = z8.enum([
|
|
|
6946
7003
|
"cancelled",
|
|
6947
7004
|
"errored"
|
|
6948
7005
|
]);
|
|
6949
|
-
var TaskStatusSchema =
|
|
7006
|
+
var TaskStatusSchema = z10.enum([
|
|
6950
7007
|
"queued",
|
|
6951
7008
|
"running",
|
|
6952
7009
|
"passed",
|
|
@@ -6955,7 +7012,7 @@ var TaskStatusSchema = z8.enum([
|
|
|
6955
7012
|
"cancelled",
|
|
6956
7013
|
"errored"
|
|
6957
7014
|
]);
|
|
6958
|
-
var FailureKindSchema =
|
|
7015
|
+
var FailureKindSchema = z10.enum([
|
|
6959
7016
|
"not_found",
|
|
6960
7017
|
"ambiguous",
|
|
6961
7018
|
"timeout",
|
|
@@ -6964,30 +7021,30 @@ var FailureKindSchema = z8.enum([
|
|
|
6964
7021
|
"crash",
|
|
6965
7022
|
"unknown"
|
|
6966
7023
|
]);
|
|
6967
|
-
var RunCheckSchema =
|
|
6968
|
-
id:
|
|
6969
|
-
assertionId:
|
|
6970
|
-
kind:
|
|
6971
|
-
expected:
|
|
6972
|
-
actual:
|
|
6973
|
-
ok:
|
|
7024
|
+
var RunCheckSchema = z10.object({
|
|
7025
|
+
id: z10.string(),
|
|
7026
|
+
assertionId: z10.string().nullable(),
|
|
7027
|
+
kind: z10.string(),
|
|
7028
|
+
expected: z10.string().nullable(),
|
|
7029
|
+
actual: z10.string().nullable(),
|
|
7030
|
+
ok: z10.boolean(),
|
|
6974
7031
|
/** A failed soft check is reported but does not fail its step, so a run can
|
|
6975
7032
|
* be green and still carry findings. Stored per check rather than derived,
|
|
6976
7033
|
* because the flow it came from can be edited afterwards and history has to
|
|
6977
7034
|
* keep saying what actually happened. */
|
|
6978
|
-
soft:
|
|
6979
|
-
detail:
|
|
7035
|
+
soft: z10.boolean().default(false),
|
|
7036
|
+
detail: z10.string().nullable()
|
|
6980
7037
|
});
|
|
6981
|
-
var RunStepSchema =
|
|
6982
|
-
id:
|
|
6983
|
-
ordinal:
|
|
7038
|
+
var RunStepSchema = z10.object({
|
|
7039
|
+
id: z10.string(),
|
|
7040
|
+
ordinal: z10.number().int().nonnegative(),
|
|
6984
7041
|
/** The STABLE document step id — this is what joins runs across time and
|
|
6985
7042
|
* makes flake-rate a view over existing columns rather than a migration. */
|
|
6986
|
-
stepId:
|
|
6987
|
-
action:
|
|
6988
|
-
targetRole:
|
|
6989
|
-
targetName:
|
|
6990
|
-
targetScope:
|
|
7043
|
+
stepId: z10.string(),
|
|
7044
|
+
action: z10.string(),
|
|
7045
|
+
targetRole: z10.string().nullable(),
|
|
7046
|
+
targetName: z10.string().nullable(),
|
|
7047
|
+
targetScope: z10.string().nullable(),
|
|
6991
7048
|
/** What the step typed, chose or pressed.
|
|
6992
7049
|
*
|
|
6993
7050
|
* A report that says `fill "Password"` and nothing else cannot tell you
|
|
@@ -6996,100 +7053,100 @@ var RunStepSchema = z8.object({
|
|
|
6996
7053
|
*
|
|
6997
7054
|
* NEVER set for a secret — see `secret` below. A run report is the thing
|
|
6998
7055
|
* people paste into a ticket. */
|
|
6999
|
-
value:
|
|
7056
|
+
value: z10.string().nullable().default(null),
|
|
7000
7057
|
/** The step typed a secret, so `value` is deliberately absent rather than
|
|
7001
7058
|
* merely unknown. Stored, because "no value" and "a value withheld" render
|
|
7002
7059
|
* differently and history has to keep saying which it was. */
|
|
7003
|
-
secret:
|
|
7004
|
-
status:
|
|
7060
|
+
secret: z10.boolean().default(false),
|
|
7061
|
+
status: z10.enum(["passed", "failed", "skipped"]),
|
|
7005
7062
|
failureKind: FailureKindSchema.nullable(),
|
|
7006
|
-
detail:
|
|
7063
|
+
detail: z10.string().nullable(),
|
|
7007
7064
|
/** WHICH WAY FOUND IT, when the first way did not.
|
|
7008
7065
|
*
|
|
7009
7066
|
* A step carries several routes to its element and takes the first that
|
|
7010
7067
|
* matches. Passing on a later one is not a failure, but it does mean the
|
|
7011
7068
|
* page has moved under the step — and a suite that repairs itself quietly
|
|
7012
7069
|
* drifts away from the application it tests. Null is the ordinary case. */
|
|
7013
|
-
foundBy:
|
|
7014
|
-
durationMs:
|
|
7070
|
+
foundBy: z10.string().nullable().default(null),
|
|
7071
|
+
durationMs: z10.number().int().nonnegative().nullable(),
|
|
7015
7072
|
/** Where the browser was when this step ran. Recorded on failure, and
|
|
7016
7073
|
* frequently the whole answer — the element is missing because a step
|
|
7017
7074
|
* before it navigated somewhere unexpected, not because it was renamed. */
|
|
7018
|
-
pageUrl:
|
|
7019
|
-
pageTitle:
|
|
7020
|
-
checks:
|
|
7075
|
+
pageUrl: z10.string().nullable().default(null),
|
|
7076
|
+
pageTitle: z10.string().nullable().default(null),
|
|
7077
|
+
checks: z10.array(RunCheckSchema).default([])
|
|
7021
7078
|
});
|
|
7022
|
-
var RunTaskSchema =
|
|
7023
|
-
id:
|
|
7024
|
-
ordinal:
|
|
7025
|
-
caseName:
|
|
7026
|
-
rowId:
|
|
7079
|
+
var RunTaskSchema = z10.object({
|
|
7080
|
+
id: z10.string(),
|
|
7081
|
+
ordinal: z10.number().int().nonnegative(),
|
|
7082
|
+
caseName: z10.string(),
|
|
7083
|
+
rowId: z10.string().nullable(),
|
|
7027
7084
|
capability: CapabilitySchema,
|
|
7028
|
-
provider:
|
|
7029
|
-
attempt:
|
|
7030
|
-
maxAttempts:
|
|
7085
|
+
provider: z10.string(),
|
|
7086
|
+
attempt: z10.number().int().positive().default(1),
|
|
7087
|
+
maxAttempts: z10.number().int().positive().default(1),
|
|
7031
7088
|
status: TaskStatusSchema,
|
|
7032
|
-
workerId:
|
|
7089
|
+
workerId: z10.string().nullable(),
|
|
7033
7090
|
/** Cloud provider's own session, so a failure is one click from their video. */
|
|
7034
|
-
sessionId:
|
|
7035
|
-
sessionUrl:
|
|
7036
|
-
detail:
|
|
7037
|
-
stepsRun:
|
|
7038
|
-
stepsTotal:
|
|
7039
|
-
durationMs:
|
|
7040
|
-
steps:
|
|
7091
|
+
sessionId: z10.string().nullable(),
|
|
7092
|
+
sessionUrl: z10.string().nullable(),
|
|
7093
|
+
detail: z10.string().nullable(),
|
|
7094
|
+
stepsRun: z10.number().int().nonnegative().default(0),
|
|
7095
|
+
stepsTotal: z10.number().int().nonnegative().default(0),
|
|
7096
|
+
durationMs: z10.number().int().nonnegative().nullable(),
|
|
7097
|
+
steps: z10.array(RunStepSchema).default([])
|
|
7041
7098
|
});
|
|
7042
|
-
var ArtifactKindSchema =
|
|
7043
|
-
var ArtifactSchema =
|
|
7044
|
-
id:
|
|
7045
|
-
runId:
|
|
7046
|
-
runStepId:
|
|
7099
|
+
var ArtifactKindSchema = z10.enum(["screenshot", "video", "trace", "console", "har"]);
|
|
7100
|
+
var ArtifactSchema = z10.object({
|
|
7101
|
+
id: z10.string(),
|
|
7102
|
+
runId: z10.string(),
|
|
7103
|
+
runStepId: z10.string().nullable(),
|
|
7047
7104
|
kind: ArtifactKindSchema,
|
|
7048
|
-
relPath:
|
|
7049
|
-
bytes:
|
|
7050
|
-
masked:
|
|
7051
|
-
createdAt:
|
|
7105
|
+
relPath: z10.string(),
|
|
7106
|
+
bytes: z10.number().int().nonnegative().nullable(),
|
|
7107
|
+
masked: z10.boolean().default(false),
|
|
7108
|
+
createdAt: z10.string()
|
|
7052
7109
|
});
|
|
7053
|
-
var RunSummarySchema =
|
|
7054
|
-
id:
|
|
7055
|
-
projectId:
|
|
7110
|
+
var RunSummarySchema = z10.object({
|
|
7111
|
+
id: z10.string(),
|
|
7112
|
+
projectId: z10.string(),
|
|
7056
7113
|
/** What the run was FOR.
|
|
7057
7114
|
*
|
|
7058
7115
|
* `flake` is a deliberate repetition of one flow to measure how often it
|
|
7059
7116
|
* passes. It is kept out of pass-rate statistics: a 98/100 flakiness check is
|
|
7060
7117
|
* a useful finding, not a failing suite, and counting it as one would make
|
|
7061
7118
|
* measuring reliability look like losing it. */
|
|
7062
|
-
kind:
|
|
7063
|
-
trigger:
|
|
7119
|
+
kind: z10.enum(["smoke", "test", "adhoc", "flake"]),
|
|
7120
|
+
trigger: z10.enum(["ui", "cli", "ci"]),
|
|
7064
7121
|
status: RunStatusSchema,
|
|
7065
|
-
flowId:
|
|
7066
|
-
flowName:
|
|
7067
|
-
gitSha:
|
|
7068
|
-
gitBranch:
|
|
7069
|
-
gitDirty:
|
|
7070
|
-
env:
|
|
7071
|
-
concurrency:
|
|
7072
|
-
tasksTotal:
|
|
7073
|
-
tasksPassed:
|
|
7074
|
-
tasksFailed:
|
|
7122
|
+
flowId: z10.string().nullable(),
|
|
7123
|
+
flowName: z10.string().nullable(),
|
|
7124
|
+
gitSha: z10.string().nullable(),
|
|
7125
|
+
gitBranch: z10.string().nullable(),
|
|
7126
|
+
gitDirty: z10.boolean().default(false),
|
|
7127
|
+
env: z10.string().nullable(),
|
|
7128
|
+
concurrency: z10.number().int().positive().nullable(),
|
|
7129
|
+
tasksTotal: z10.number().int().nonnegative().default(0),
|
|
7130
|
+
tasksPassed: z10.number().int().nonnegative().default(0),
|
|
7131
|
+
tasksFailed: z10.number().int().nonnegative().default(0),
|
|
7075
7132
|
/** Rolled up from the run's tasks rather than stored on the run, so they
|
|
7076
7133
|
* cannot drift from the step rows they describe. "9 of 12" in a list is
|
|
7077
7134
|
* what tells a reader where a run died; "1 of 1 tasks" tells them nothing
|
|
7078
7135
|
* until there is more than one browser in play. */
|
|
7079
|
-
stepsRun:
|
|
7080
|
-
stepsTotal:
|
|
7081
|
-
queuedAt:
|
|
7082
|
-
startedAt:
|
|
7083
|
-
finishedAt:
|
|
7084
|
-
durationMs:
|
|
7136
|
+
stepsRun: z10.number().int().nonnegative().default(0),
|
|
7137
|
+
stepsTotal: z10.number().int().nonnegative().default(0),
|
|
7138
|
+
queuedAt: z10.string(),
|
|
7139
|
+
startedAt: z10.string().nullable(),
|
|
7140
|
+
finishedAt: z10.string().nullable(),
|
|
7141
|
+
durationMs: z10.number().int().nonnegative().nullable()
|
|
7085
7142
|
});
|
|
7086
7143
|
var RunDetailSchema = RunSummarySchema.extend({
|
|
7087
|
-
errorMessage:
|
|
7088
|
-
artifactsDir:
|
|
7089
|
-
tasks:
|
|
7144
|
+
errorMessage: z10.string().nullable(),
|
|
7145
|
+
artifactsDir: z10.string().nullable(),
|
|
7146
|
+
tasks: z10.array(RunTaskSchema).default([]),
|
|
7090
7147
|
/** Screenshots and the like, addressed by `runStepId`. Kept flat rather than
|
|
7091
7148
|
* nested inside each step: an artifact can belong to the run as a whole. */
|
|
7092
|
-
artifacts:
|
|
7149
|
+
artifacts: z10.array(ArtifactSchema).default([]),
|
|
7093
7150
|
/** The document as it was executed — a flow, or a test case with the copies
|
|
7094
7151
|
* it held that day.
|
|
7095
7152
|
*
|
|
@@ -7098,7 +7155,7 @@ var RunDetailSchema = RunSummarySchema.extend({
|
|
|
7098
7155
|
* edited, and without surfacing it the promise was only half kept: the bytes
|
|
7099
7156
|
* were there and nothing could reach them. Null for runs recorded before a
|
|
7100
7157
|
* snapshot was taken. */
|
|
7101
|
-
flowSnapshot:
|
|
7158
|
+
flowSnapshot: z10.unknown().nullable().default(null)
|
|
7102
7159
|
});
|
|
7103
7160
|
|
|
7104
7161
|
// ../results/dist/chunk-IW3PJWP6.js
|
|
@@ -11370,6 +11427,7 @@ var ASK_MODE_TOOLS = [
|
|
|
11370
11427
|
"project_brief",
|
|
11371
11428
|
"knowledge_search",
|
|
11372
11429
|
"knowledge_read",
|
|
11430
|
+
"read_test_cases",
|
|
11373
11431
|
"list_my_branches"
|
|
11374
11432
|
];
|
|
11375
11433
|
function buildAskArgs(opts) {
|
|
@@ -12040,6 +12098,7 @@ export {
|
|
|
12040
12098
|
connect,
|
|
12041
12099
|
RecordedStepSchema,
|
|
12042
12100
|
mirrorCheckTargets,
|
|
12101
|
+
parseGherkin,
|
|
12043
12102
|
runtimeValue,
|
|
12044
12103
|
authenticationResolver,
|
|
12045
12104
|
checkAssertion,
|