@elench/testkit 0.1.76 → 0.1.78
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 +49 -30
- package/lib/app/doctor.mjs +43 -0
- package/lib/config/runtime.test.mjs +2 -2
- package/lib/config-api/index.d.ts +226 -78
- package/lib/config-api/index.mjs +137 -271
- package/lib/config-api/index.test.mjs +347 -155
- package/lib/config-api/profiles.mjs +640 -0
- package/lib/coverage/index.test.mjs +2 -2
- package/lib/shared/build-config.test.mjs +1 -1
- package/lib/shared/configured-steps.mjs +9 -7
- package/lib/shared/configured-steps.test.mjs +3 -3
- package/node_modules/@elench/next-analysis/package.json +1 -1
- package/node_modules/@elench/testkit-bridge/package.json +2 -2
- package/node_modules/@elench/testkit-protocol/package.json +1 -1
- package/node_modules/@elench/ts-analysis/package.json +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -147,14 +147,11 @@ Create `testkit.config.ts` at repo root:
|
|
|
147
147
|
|
|
148
148
|
```ts
|
|
149
149
|
import {
|
|
150
|
+
app,
|
|
151
|
+
database,
|
|
150
152
|
defineConfig,
|
|
151
153
|
defineFile,
|
|
152
|
-
|
|
153
|
-
nodeToolchain,
|
|
154
|
-
nodeApp,
|
|
155
|
-
seedCommand,
|
|
156
|
-
templateDatabase,
|
|
157
|
-
verifyModule,
|
|
154
|
+
toolchain,
|
|
158
155
|
} from "@elench/testkit/config";
|
|
159
156
|
|
|
160
157
|
export default defineConfig({
|
|
@@ -171,38 +168,41 @@ export default defineConfig({
|
|
|
171
168
|
},
|
|
172
169
|
},
|
|
173
170
|
toolchains: {
|
|
174
|
-
frontendNode:
|
|
171
|
+
frontendNode: toolchain.node({
|
|
175
172
|
cwd: "frontend",
|
|
176
173
|
detect: "auto",
|
|
177
174
|
install: "download",
|
|
178
175
|
}),
|
|
179
176
|
},
|
|
180
177
|
services: {
|
|
181
|
-
api:
|
|
178
|
+
api: app.node({
|
|
182
179
|
cwd: ".",
|
|
183
180
|
entry: "src/index.ts",
|
|
184
181
|
port: 3004,
|
|
185
182
|
envFiles: [".env.testkit"],
|
|
186
|
-
database:
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
183
|
+
database: database.postgres({
|
|
184
|
+
template: {
|
|
185
|
+
inputs: ["db/schema.sql", "scripts/seed.ts"],
|
|
186
|
+
schema: "db/schema.sql",
|
|
187
|
+
seed: [{ kind: "command", run: "npm run db:seed" }],
|
|
188
|
+
verify: [{ kind: "module", target: "src/testkit/verify-seed.ts#verifySeed" }],
|
|
189
|
+
},
|
|
191
190
|
}),
|
|
192
191
|
runtime: {
|
|
193
192
|
instances: 1,
|
|
194
193
|
maxConcurrentTasks: 4,
|
|
195
194
|
},
|
|
196
195
|
}),
|
|
197
|
-
frontend:
|
|
196
|
+
frontend: app.next({
|
|
198
197
|
cwd: "frontend",
|
|
199
198
|
mode: "start",
|
|
200
199
|
port: 3000,
|
|
201
200
|
dependsOn: ["api"],
|
|
202
201
|
envFiles: ["frontend/.env.testkit"],
|
|
203
202
|
env: {
|
|
204
|
-
|
|
205
|
-
|
|
203
|
+
values: {
|
|
204
|
+
NEXT_PUBLIC_API_URL: "{baseUrl:api}",
|
|
205
|
+
},
|
|
206
206
|
},
|
|
207
207
|
runtime: {
|
|
208
208
|
instances: 1,
|
|
@@ -258,17 +258,13 @@ state. It always executes in three explicit phases:
|
|
|
258
258
|
- `seed`
|
|
259
259
|
- `verify`
|
|
260
260
|
|
|
261
|
-
For most repos, prefer
|
|
261
|
+
For most repos, prefer declarative step objects directly inside
|
|
262
|
+
`database.postgres({ template: ... })` and `runtime.prepare.steps`.
|
|
263
|
+
The supported shapes are:
|
|
262
264
|
|
|
263
|
-
- `
|
|
264
|
-
- `
|
|
265
|
-
- `
|
|
266
|
-
- `verifyCommand(...)`
|
|
267
|
-
- `verifyModule(...)`
|
|
268
|
-
- `templateDatabase(...)`
|
|
269
|
-
|
|
270
|
-
Use raw `commandStep(...)`, `sqlFileStep(...)`, and `moduleStep(...)` arrays when
|
|
271
|
-
you need lower-level control over the exact stage layout.
|
|
265
|
+
- `{ kind: "command", run: "..." }`
|
|
266
|
+
- `{ kind: "sql-file", path: "..." }`
|
|
267
|
+
- `{ kind: "module", target: "file.ts#exportName" }`
|
|
272
268
|
|
|
273
269
|
`runtime.toolchain` is the first-class way to make those prepare/start commands
|
|
274
270
|
run under the correct Node toolchain instead of whatever `node`/`npm` happened
|
|
@@ -290,14 +286,14 @@ Example:
|
|
|
290
286
|
|
|
291
287
|
```ts
|
|
292
288
|
toolchains: {
|
|
293
|
-
frontendNode:
|
|
289
|
+
frontendNode: toolchain.node({
|
|
294
290
|
cwd: "frontend",
|
|
295
291
|
detect: "auto",
|
|
296
292
|
install: "download",
|
|
297
293
|
}),
|
|
298
294
|
},
|
|
299
295
|
services: {
|
|
300
|
-
frontend:
|
|
296
|
+
frontend: app.next({
|
|
301
297
|
cwd: "frontend",
|
|
302
298
|
port: 3000,
|
|
303
299
|
runtime: {
|
|
@@ -369,8 +365,31 @@ Named HTTP profiles live in `testkit.config.ts` and can be referenced by name:
|
|
|
369
365
|
|
|
370
366
|
```ts
|
|
371
367
|
import { defineHttpSuite } from "@elench/testkit";
|
|
368
|
+
import { defineConfig, profiles } from "@elench/testkit/config";
|
|
369
|
+
|
|
370
|
+
export default defineConfig({
|
|
371
|
+
profiles: {
|
|
372
|
+
http: {
|
|
373
|
+
defaultAuth: profiles.localJson({
|
|
374
|
+
password: "password",
|
|
375
|
+
identities: {
|
|
376
|
+
primary: {
|
|
377
|
+
email: "test@example.com",
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
session: {
|
|
381
|
+
authCookie: "session",
|
|
382
|
+
},
|
|
383
|
+
headers: {
|
|
384
|
+
contentTypeJson: true,
|
|
385
|
+
forwardedFor: "deterministic",
|
|
386
|
+
},
|
|
387
|
+
}).session(),
|
|
388
|
+
},
|
|
389
|
+
},
|
|
390
|
+
});
|
|
372
391
|
|
|
373
|
-
const suite = defineHttpSuite({ profile: "
|
|
392
|
+
const suite = defineHttpSuite({ profile: "defaultAuth" }, ({ req, setupData }) => {
|
|
374
393
|
req("GET", "/api/auth/session", setupData);
|
|
375
394
|
});
|
|
376
395
|
```
|
|
@@ -508,7 +527,7 @@ Git metadata.
|
|
|
508
527
|
## Local Databases
|
|
509
528
|
|
|
510
529
|
`@elench/testkit` provisions Docker-managed local Postgres automatically for
|
|
511
|
-
services that define `database:
|
|
530
|
+
services that define `database: database.postgres(...)`.
|
|
512
531
|
|
|
513
532
|
- template databases are cached
|
|
514
533
|
- runtime databases are cloned from templates when binding is `per-runtime`
|
package/lib/app/doctor.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import ts from "typescript";
|
|
|
4
4
|
import { discoverTests } from "../discovery/index.mjs";
|
|
5
5
|
import { loadConfigContext } from "../config/index.mjs";
|
|
6
6
|
import { runTestkitTypecheck } from "./typecheck.mjs";
|
|
7
|
+
import { findConfigFile } from "../config/config-loader.mjs";
|
|
7
8
|
|
|
8
9
|
export async function runDoctor(options = {}) {
|
|
9
10
|
const checks = [];
|
|
@@ -39,6 +40,17 @@ export async function runDoctor(options = {}) {
|
|
|
39
40
|
details: playwrightViolations,
|
|
40
41
|
});
|
|
41
42
|
|
|
43
|
+
const configImportViolations = findConfigImportViolations(productDir);
|
|
44
|
+
checks.push({
|
|
45
|
+
code: "config-import-hygiene",
|
|
46
|
+
level: configImportViolations.length === 0 ? "pass" : "fail",
|
|
47
|
+
message:
|
|
48
|
+
configImportViolations.length === 0
|
|
49
|
+
? "Repo config does not import __testkit__ helper modules"
|
|
50
|
+
: `Found ${configImportViolations.length} repo config import violation(s)`,
|
|
51
|
+
details: configImportViolations,
|
|
52
|
+
});
|
|
53
|
+
|
|
42
54
|
const hasBrowserOrNextWork = discovery.files.some((entry) => entry.selectionType === "pw");
|
|
43
55
|
if (hasBrowserOrNextWork) {
|
|
44
56
|
const nodeCount = discovery.coverageGraph?.nodes?.length || 0;
|
|
@@ -113,6 +125,31 @@ function findPlaywrightRuntimeImportViolations(productDir) {
|
|
|
113
125
|
return violations;
|
|
114
126
|
}
|
|
115
127
|
|
|
128
|
+
function findConfigImportViolations(productDir) {
|
|
129
|
+
const configFile = findConfigFile(productDir);
|
|
130
|
+
if (!configFile || !fs.existsSync(configFile)) return [];
|
|
131
|
+
|
|
132
|
+
const sourceText = fs.readFileSync(configFile, "utf8");
|
|
133
|
+
const sourceFile = ts.createSourceFile(configFile, sourceText, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
134
|
+
const violations = [];
|
|
135
|
+
|
|
136
|
+
for (const statement of sourceFile.statements) {
|
|
137
|
+
if (!ts.isImportDeclaration(statement)) continue;
|
|
138
|
+
if (!ts.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
139
|
+
const specifier = statement.moduleSpecifier.text;
|
|
140
|
+
if (!isRepoLocalConfigImportViolation(specifier)) continue;
|
|
141
|
+
const position = sourceFile.getLineAndCharacterOfPosition(statement.getStart(sourceFile));
|
|
142
|
+
violations.push({
|
|
143
|
+
file: path.relative(productDir, configFile).split(path.sep).join("/"),
|
|
144
|
+
line: position.line + 1,
|
|
145
|
+
specifier,
|
|
146
|
+
snippet: statement.getText(sourceFile),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return violations;
|
|
151
|
+
}
|
|
152
|
+
|
|
116
153
|
function collectFiles(rootDir, out = []) {
|
|
117
154
|
if (!fs.existsSync(rootDir)) return out;
|
|
118
155
|
for (const entry of fs.readdirSync(rootDir, { withFileTypes: true })) {
|
|
@@ -129,6 +166,12 @@ function collectFiles(rootDir, out = []) {
|
|
|
129
166
|
return out.sort((left, right) => left.localeCompare(right));
|
|
130
167
|
}
|
|
131
168
|
|
|
169
|
+
function isRepoLocalConfigImportViolation(specifier) {
|
|
170
|
+
if (typeof specifier !== "string") return false;
|
|
171
|
+
if (!specifier.startsWith(".") && !specifier.startsWith("/")) return false;
|
|
172
|
+
return specifier.includes("__testkit__");
|
|
173
|
+
}
|
|
174
|
+
|
|
132
175
|
function relativeViolation(productDir, absolutePath, sourceFile, statement) {
|
|
133
176
|
const position = sourceFile.getLineAndCharacterOfPosition(statement.getStart(sourceFile));
|
|
134
177
|
return {
|
|
@@ -19,7 +19,7 @@ describe("config runtime helpers", () => {
|
|
|
19
19
|
normalizeRuntimePrepareConfig(
|
|
20
20
|
{
|
|
21
21
|
inputs: ["fixtures/users.json"],
|
|
22
|
-
steps: [{ kind: "module",
|
|
22
|
+
steps: [{ kind: "module", target: "./scripts/setup.mjs#run", inputs: ["fixtures/users.json"] }],
|
|
23
23
|
},
|
|
24
24
|
"web"
|
|
25
25
|
)
|
|
@@ -73,7 +73,7 @@ describe("config runtime helpers", () => {
|
|
|
73
73
|
|
|
74
74
|
it("rejects malformed lifecycle steps and empty step inputs", () => {
|
|
75
75
|
expect(() => normalizeTemplateLifecycleStep({ kind: "module" }, "runtime.prepare.steps[0]")).toThrow(
|
|
76
|
-
/
|
|
76
|
+
/target must be a non-empty string/
|
|
77
77
|
);
|
|
78
78
|
expect(() => normalizeTemplateStepInputs([""], "runtime.prepare.steps[0]")).toThrow(
|
|
79
79
|
/must be a non-empty string/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { HttpSuiteConfig, RuntimeEnv, RuntimeOptions } from "../index";
|
|
2
2
|
|
|
3
3
|
export interface DatabaseTemplateConfig {
|
|
4
4
|
inputs?: string[];
|
|
@@ -22,7 +22,7 @@ export interface TemplateStepBaseConfig {
|
|
|
22
22
|
|
|
23
23
|
export interface TemplateCommandStepConfig extends TemplateStepBaseConfig {
|
|
24
24
|
kind: "command";
|
|
25
|
-
|
|
25
|
+
run: string;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export interface TemplateSqlFileStepConfig extends TemplateStepBaseConfig {
|
|
@@ -32,7 +32,7 @@ export interface TemplateSqlFileStepConfig extends TemplateStepBaseConfig {
|
|
|
32
32
|
|
|
33
33
|
export interface TemplateModuleStepConfig extends TemplateStepBaseConfig {
|
|
34
34
|
kind: "module";
|
|
35
|
-
|
|
35
|
+
target: string;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export type TemplateLifecycleStepConfig =
|
|
@@ -177,18 +177,209 @@ export interface ServiceConfig {
|
|
|
177
177
|
skip?: SkipConfig;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
export interface DatabaseBindingEnvConfig {
|
|
181
|
+
prefix: string;
|
|
182
|
+
service: string;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface PresetEnvConfig {
|
|
186
|
+
values?: Record<string, string>;
|
|
187
|
+
databases?: Record<string, DatabaseBindingEnvConfig>;
|
|
188
|
+
}
|
|
189
|
+
|
|
180
190
|
export interface TestkitFileMetadata {
|
|
181
191
|
locks?: string[];
|
|
182
192
|
skip?: string | { reason: string };
|
|
183
193
|
}
|
|
184
194
|
|
|
185
|
-
export interface
|
|
195
|
+
export interface ProfileRequestContext {
|
|
196
|
+
actor: string;
|
|
197
|
+
actorIndex: number;
|
|
198
|
+
env: RuntimeEnv;
|
|
199
|
+
phase: string;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export type ProfileValueFactory<TValue> =
|
|
203
|
+
| TValue
|
|
204
|
+
| ((context: ProfileRequestContext) => TValue);
|
|
205
|
+
|
|
206
|
+
export interface ProfileRequestConfig {
|
|
207
|
+
body?: ProfileValueFactory<unknown>;
|
|
208
|
+
contentTypeJson?: boolean;
|
|
209
|
+
expect?: number | number[];
|
|
210
|
+
headers?: ProfileValueFactory<Record<string, string>>;
|
|
211
|
+
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
212
|
+
path: string;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export interface SessionAuthSourceConfig {
|
|
216
|
+
key: string;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export interface SessionAuthHeaderConfig {
|
|
220
|
+
header?: string;
|
|
221
|
+
prefix?: string;
|
|
222
|
+
source: SessionAuthSourceConfig;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface SessionCaptureConfig {
|
|
226
|
+
auth?: SessionAuthHeaderConfig;
|
|
227
|
+
cookies?: Record<string, string>;
|
|
228
|
+
fields?: Record<string, string>;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export interface SessionActorConfig {
|
|
232
|
+
bootstrap?: ProfileRequestConfig | ProfileRequestConfig[];
|
|
233
|
+
login: ProfileRequestConfig;
|
|
234
|
+
session: SessionCaptureConfig;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export interface ProfileHeaderContext<TSession = unknown> {
|
|
238
|
+
actor: string | null;
|
|
239
|
+
env: RuntimeEnv;
|
|
240
|
+
session: TSession | null;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export interface ProfileSessionHeaderConfig {
|
|
244
|
+
actor?: string;
|
|
245
|
+
field: string;
|
|
246
|
+
header: string;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface DeterministicForwardedForConfig {
|
|
250
|
+
actor?: string;
|
|
251
|
+
header?: string;
|
|
252
|
+
seed?: string;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export interface ProfileHeaderConfig<TSession = unknown> {
|
|
256
|
+
contentTypeJson?: boolean;
|
|
257
|
+
forwardedFor?: "deterministic" | DeterministicForwardedForConfig;
|
|
258
|
+
fromSession?: ProfileSessionHeaderConfig[];
|
|
259
|
+
values?: Record<string, string> | ((context: ProfileHeaderContext<TSession>) => Record<string, string>);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface RawHttpProfileOptions {
|
|
263
|
+
env?: RuntimeEnv;
|
|
264
|
+
headers?: ProfileHeaderConfig;
|
|
265
|
+
options?: RuntimeOptions;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface SessionHttpProfileOptions {
|
|
269
|
+
actor: SessionActorConfig;
|
|
270
|
+
env?: RuntimeEnv;
|
|
271
|
+
headers?: ProfileHeaderConfig<Record<string, unknown>>;
|
|
272
|
+
options?: RuntimeOptions;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export interface MultiActorHttpProfileOptions {
|
|
276
|
+
actors: Record<string, SessionActorConfig>;
|
|
277
|
+
env?: RuntimeEnv;
|
|
278
|
+
headers?: ProfileHeaderConfig<Record<string, Record<string, unknown>>>;
|
|
279
|
+
options?: RuntimeOptions;
|
|
280
|
+
primaryActor?: string;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export interface LocalJsonIdentityContext {
|
|
284
|
+
actor: string;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export type LocalJsonIdentityValue = string | ((context: LocalJsonIdentityContext) => string);
|
|
288
|
+
|
|
289
|
+
export interface LocalJsonActorIdentityConfig {
|
|
290
|
+
email?: LocalJsonIdentityValue;
|
|
291
|
+
loginBody?: Record<string, unknown>;
|
|
292
|
+
name?: LocalJsonIdentityValue;
|
|
293
|
+
organizationName?: LocalJsonIdentityValue;
|
|
294
|
+
password?: LocalJsonIdentityValue;
|
|
295
|
+
signupBody?: Record<string, unknown>;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export interface LocalJsonSessionAuthOptions {
|
|
299
|
+
header?: string;
|
|
300
|
+
prefix?: string;
|
|
301
|
+
sourceKey?: string;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export interface LocalJsonSessionOptions {
|
|
305
|
+
auth?: LocalJsonSessionAuthOptions;
|
|
306
|
+
authCookie?: string;
|
|
307
|
+
cookies?: Record<string, string>;
|
|
308
|
+
fields?: Record<string, string>;
|
|
309
|
+
organizationIdPath?: string;
|
|
310
|
+
refreshCookie?: string;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export interface LocalJsonOrganizationHeaderConfig {
|
|
314
|
+
actor?: string;
|
|
315
|
+
field?: string;
|
|
316
|
+
header?: string;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export interface LocalJsonHeaderOptions {
|
|
320
|
+
contentTypeJson?: boolean;
|
|
321
|
+
forwardedFor?: "deterministic" | DeterministicForwardedForConfig;
|
|
322
|
+
organization?: false | string | LocalJsonOrganizationHeaderConfig;
|
|
323
|
+
values?: Record<string, string> | ((context: ProfileHeaderContext<unknown>) => Record<string, string>);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface LocalJsonSignupOptions {
|
|
327
|
+
enabled?: boolean;
|
|
328
|
+
expect?: number | number[];
|
|
329
|
+
path?: string;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export interface LocalJsonLoginOptions {
|
|
333
|
+
expect?: number | number[];
|
|
334
|
+
path?: string;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export interface LocalJsonProfileOptions {
|
|
338
|
+
env?: RuntimeEnv;
|
|
339
|
+
headers?: LocalJsonHeaderOptions;
|
|
340
|
+
identities?: Record<string, LocalJsonActorIdentityConfig>;
|
|
341
|
+
login?: LocalJsonLoginOptions;
|
|
342
|
+
options?: RuntimeOptions;
|
|
343
|
+
password?: LocalJsonIdentityValue;
|
|
344
|
+
session?: LocalJsonSessionOptions;
|
|
345
|
+
signup?: false | LocalJsonSignupOptions;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export interface LocalJsonSessionProfileOptions {
|
|
349
|
+
actor?: string;
|
|
350
|
+
env?: RuntimeEnv;
|
|
351
|
+
headers?: LocalJsonHeaderOptions;
|
|
352
|
+
identity?: LocalJsonActorIdentityConfig;
|
|
353
|
+
options?: RuntimeOptions;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export interface LocalJsonMultiActorProfileOptions {
|
|
357
|
+
actors?: string[] | Record<string, LocalJsonActorIdentityConfig>;
|
|
358
|
+
env?: RuntimeEnv;
|
|
359
|
+
headers?: LocalJsonHeaderOptions;
|
|
360
|
+
options?: RuntimeOptions;
|
|
361
|
+
primaryActor?: string;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export interface LocalJsonRawProfileOptions {
|
|
365
|
+
env?: RuntimeEnv;
|
|
366
|
+
headers?: LocalJsonHeaderOptions;
|
|
367
|
+
options?: RuntimeOptions;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export interface LocalJsonProfileBuilder {
|
|
371
|
+
multiActor(options?: LocalJsonMultiActorProfileOptions): HttpSuiteConfig<Record<string, Record<string, unknown>>>;
|
|
372
|
+
raw(options?: LocalJsonRawProfileOptions): HttpSuiteConfig<any>;
|
|
373
|
+
session(options?: LocalJsonSessionProfileOptions): HttpSuiteConfig<Record<string, unknown>>;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export interface NodeAppOptions extends Omit<ServiceConfig, "local" | "runtime" | "env"> {
|
|
186
377
|
baseUrl?: string;
|
|
187
378
|
build?: BuildConfig | null;
|
|
188
379
|
buildInputs?: string[];
|
|
189
380
|
cwd?: string;
|
|
190
381
|
entry?: string;
|
|
191
|
-
env?:
|
|
382
|
+
env?: PresetEnvConfig;
|
|
192
383
|
outDir?: string;
|
|
193
384
|
port: number;
|
|
194
385
|
readyPath?: string;
|
|
@@ -200,12 +391,12 @@ export interface NodeAppOptions extends Omit<ServiceConfig, "local" | "runtime">
|
|
|
200
391
|
tsconfig?: string;
|
|
201
392
|
}
|
|
202
393
|
|
|
203
|
-
export interface NextAppOptions extends Omit<ServiceConfig, "local" | "runtime"> {
|
|
394
|
+
export interface NextAppOptions extends Omit<ServiceConfig, "local" | "runtime" | "env"> {
|
|
204
395
|
baseUrl?: string;
|
|
205
396
|
build?: BuildConfig | null;
|
|
206
397
|
buildInputs?: string[];
|
|
207
398
|
cwd?: string;
|
|
208
|
-
env?:
|
|
399
|
+
env?: PresetEnvConfig;
|
|
209
400
|
mode?: "dev" | "start";
|
|
210
401
|
port: number;
|
|
211
402
|
readyTimeoutMs?: number;
|
|
@@ -236,78 +427,35 @@ export interface TestkitConfig {
|
|
|
236
427
|
}
|
|
237
428
|
|
|
238
429
|
export declare function defineConfig<T extends TestkitConfig>(config: T): T;
|
|
239
|
-
export declare function defineHttpProfile<T extends HttpSuiteConfig>(profile: T): T;
|
|
240
430
|
export declare function defineFile<T extends TestkitFileMetadata>(metadata: T): T;
|
|
241
|
-
export declare
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
):
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
options?:
|
|
261
|
-
|
|
262
|
-
export declare
|
|
263
|
-
|
|
264
|
-
options?:
|
|
265
|
-
):
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
): TemplateCommandStepConfig;
|
|
270
|
-
export declare function verifyModule(
|
|
271
|
-
specifier: string,
|
|
272
|
-
options?: Omit<TemplateModuleStepConfig, "kind" | "specifier">
|
|
273
|
-
): TemplateModuleStepConfig;
|
|
274
|
-
export declare function templateDatabase(
|
|
275
|
-
options?: DatabaseTemplateOptions & Omit<LocalDatabaseConfig, "provider" | "template">
|
|
276
|
-
): LocalDatabaseConfig;
|
|
277
|
-
export declare function postgresFixture(
|
|
278
|
-
options?: Omit<LocalDatabaseConfig, "provider"> & {
|
|
279
|
-
discovery?: DiscoveryConfig;
|
|
280
|
-
envFiles?: string[];
|
|
281
|
-
}
|
|
282
|
-
): ServiceConfig;
|
|
283
|
-
export declare function databaseServiceEnv(
|
|
284
|
-
prefix: string,
|
|
285
|
-
serviceName: string
|
|
286
|
-
): Record<string, string>;
|
|
287
|
-
export declare function nodeToolchain(options?: NodeToolchainConfig): NodeToolchainConfig;
|
|
288
|
-
export declare function tscBuild(options?: Omit<TscBuildConfig, "kind">): TscBuildConfig;
|
|
289
|
-
export declare function scriptBuild(
|
|
290
|
-
script: string,
|
|
291
|
-
options?: Omit<ScriptBuildConfig, "kind" | "script">
|
|
292
|
-
): ScriptBuildConfig;
|
|
293
|
-
export declare function stepsBuild(options?: Omit<StepsBuildConfig, "kind">): StepsBuildConfig;
|
|
294
|
-
export declare function nextBuild(options?: Omit<NextBuildConfig, "kind">): NextBuildConfig;
|
|
295
|
-
export declare function nodeApp(options: NodeAppOptions): ServiceConfig;
|
|
296
|
-
export declare function nextApp(options: NextAppOptions): ServiceConfig;
|
|
297
|
-
export declare function clerkSessionProfile(options?: {
|
|
298
|
-
apiBase?: string;
|
|
299
|
-
needsAuth?: boolean;
|
|
300
|
-
secretKeyEnv?: string;
|
|
301
|
-
}): HttpSuiteConfig;
|
|
302
|
-
export declare function jsonSessionProfile(options?: {
|
|
303
|
-
body?: (context: { env: Record<string, string> }) => unknown;
|
|
304
|
-
cookieName?: string;
|
|
305
|
-
headers?: Record<string, string>;
|
|
306
|
-
loginPath?: string;
|
|
307
|
-
passwordEnv?: string;
|
|
308
|
-
successStatus?: number;
|
|
309
|
-
usernameEnv?: string;
|
|
310
|
-
}): HttpSuiteConfig;
|
|
431
|
+
export declare const app: {
|
|
432
|
+
node(options: NodeAppOptions): ServiceConfig;
|
|
433
|
+
next(options: NextAppOptions): ServiceConfig;
|
|
434
|
+
};
|
|
435
|
+
export declare const database: {
|
|
436
|
+
postgres(
|
|
437
|
+
options?: Omit<LocalDatabaseConfig, "provider" | "template"> & {
|
|
438
|
+
template?: DatabaseTemplateOptions;
|
|
439
|
+
}
|
|
440
|
+
): LocalDatabaseConfig;
|
|
441
|
+
fixture(
|
|
442
|
+
options?: Omit<LocalDatabaseConfig, "provider" | "template"> & {
|
|
443
|
+
template?: DatabaseTemplateOptions;
|
|
444
|
+
discovery?: DiscoveryConfig;
|
|
445
|
+
envFiles?: string[];
|
|
446
|
+
}
|
|
447
|
+
): ServiceConfig;
|
|
448
|
+
};
|
|
449
|
+
export declare const toolchain: {
|
|
450
|
+
node(options?: NodeToolchainConfig): NodeToolchainConfig;
|
|
451
|
+
};
|
|
452
|
+
export declare const profiles: {
|
|
453
|
+
custom<T extends HttpSuiteConfig>(profile: T): T;
|
|
454
|
+
localJson(options?: LocalJsonProfileOptions): LocalJsonProfileBuilder;
|
|
455
|
+
multiActor(options: MultiActorHttpProfileOptions): HttpSuiteConfig<Record<string, Record<string, unknown>>>;
|
|
456
|
+
raw(options?: RawHttpProfileOptions): HttpSuiteConfig<any>;
|
|
457
|
+
session(options: SessionHttpProfileOptions): HttpSuiteConfig<Record<string, unknown>>;
|
|
458
|
+
};
|
|
311
459
|
|
|
312
460
|
export declare function registerRepoConfig(config: unknown): void;
|
|
313
461
|
export declare function getRepoConfig(): unknown;
|