@elench/testkit 0.1.51 → 0.1.53
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 +42 -7
- package/bin/testkit.mjs +4 -6
- package/lib/cli/command-helpers.mjs +170 -0
- package/lib/cli/commands/artifacts.mjs +45 -0
- package/lib/cli/commands/cleanup.mjs +15 -0
- package/lib/cli/commands/db/snapshot/capture.mjs +22 -0
- package/lib/cli/commands/destroy.mjs +15 -0
- package/lib/cli/commands/known-failures/render.mjs +19 -0
- package/lib/cli/commands/known-failures/validate.mjs +20 -0
- package/lib/cli/commands/logs.mjs +47 -0
- package/lib/cli/commands/run.mjs +23 -0
- package/lib/cli/commands/show.mjs +47 -0
- package/lib/cli/commands/status.mjs +15 -0
- package/lib/cli/commands/watch.mjs +23 -0
- package/lib/cli/entrypoint.mjs +83 -0
- package/lib/cli/index.mjs +6 -116
- package/lib/cli/presentation/run-reporter.mjs +91 -0
- package/lib/cli/tui/watch-app.mjs +104 -0
- package/lib/cli/viewer.mjs +163 -0
- package/lib/runner/artifacts.mjs +35 -0
- package/lib/runner/default-runtime-runner.mjs +44 -10
- package/lib/runner/formatting.mjs +97 -0
- package/lib/runner/formatting.test.mjs +4 -6
- package/lib/runner/logs.mjs +72 -0
- package/lib/runner/orchestrator.mjs +41 -19
- package/lib/runner/playwright-runner.mjs +15 -7
- package/lib/runner/processes.mjs +9 -11
- package/lib/runner/reporting.mjs +5 -1
- package/lib/runner/reporting.test.mjs +4 -1
- package/lib/runner/runtime-contexts.mjs +7 -3
- package/lib/runner/runtime-manager.mjs +8 -2
- package/lib/runner/runtime-preparation.mjs +9 -4
- package/lib/runner/services.mjs +25 -8
- package/lib/runner/template-steps.mjs +4 -3
- package/lib/runner/worker-loop.mjs +8 -7
- package/lib/setup/index.d.ts +46 -13
- package/lib/setup/index.mjs +47 -0
- package/lib/setup/index.test.mjs +109 -1
- package/lib/toolchains/index.mjs +6 -3
- package/package.json +11 -3
package/lib/runner/services.mjs
CHANGED
|
@@ -6,16 +6,16 @@ import {
|
|
|
6
6
|
} from "../toolchains/index.mjs";
|
|
7
7
|
import { buildExecutionEnv, numericPortFromUrl } from "./template.mjs";
|
|
8
8
|
import { DEFAULT_READY_TIMEOUT_MS, assertLocalServicePortsAvailable, isPortInUse, waitForReady } from "./readiness.mjs";
|
|
9
|
-
import {
|
|
9
|
+
import { captureOutput, killChildProcess, startDetachedCommand, stopChildProcess, sleep } from "./processes.mjs";
|
|
10
10
|
import { readDatabaseUrl } from "./state-io.mjs";
|
|
11
11
|
|
|
12
|
-
export async function startLocalServices(runtimeConfigs, lifecycle) {
|
|
12
|
+
export async function startLocalServices(runtimeConfigs, lifecycle, options = {}) {
|
|
13
13
|
const started = [];
|
|
14
14
|
|
|
15
15
|
try {
|
|
16
16
|
for (const config of runtimeConfigs) {
|
|
17
17
|
if (!config.testkit.local) continue;
|
|
18
|
-
const proc = await startLocalService(config, lifecycle);
|
|
18
|
+
const proc = await startLocalService(config, lifecycle, options);
|
|
19
19
|
started.push(proc);
|
|
20
20
|
}
|
|
21
21
|
} catch (error) {
|
|
@@ -26,10 +26,10 @@ export async function startLocalServices(runtimeConfigs, lifecycle) {
|
|
|
26
26
|
return started;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export async function startLocalService(config, lifecycle) {
|
|
29
|
+
export async function startLocalService(config, lifecycle, options = {}) {
|
|
30
30
|
const cwd = resolveServiceCwd(config.productDir, config.testkit.local.cwd);
|
|
31
31
|
const resolvedToolchain = await resolveConfiguredToolchain(config);
|
|
32
|
-
await announceResolvedToolchain(config, resolvedToolchain);
|
|
32
|
+
await announceResolvedToolchain(config, resolvedToolchain, options.reporter);
|
|
33
33
|
const env = applyToolchainEnv(
|
|
34
34
|
buildExecutionEnv(config, config.testkit.local.env, process.env),
|
|
35
35
|
resolvedToolchain
|
|
@@ -46,12 +46,29 @@ export async function startLocalService(config, lifecycle) {
|
|
|
46
46
|
|
|
47
47
|
await assertLocalServicePortsAvailable(config, isPortInUse);
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
options.reporter?.localServiceStarting?.(config, config.testkit.local.start);
|
|
50
50
|
const child = startDetachedCommand(config.testkit.local.start, cwd, env);
|
|
51
|
+
const logRecord = options.logRegistry?.ensureServiceLogRecord(config);
|
|
52
|
+
const liveWriter =
|
|
53
|
+
options.reporter?.outputMode === "debug"
|
|
54
|
+
? (line) => options.reporter.writeDebugLine?.(line)
|
|
55
|
+
: null;
|
|
51
56
|
|
|
52
57
|
const outputDrains = [
|
|
53
|
-
|
|
54
|
-
|
|
58
|
+
captureOutput(child.stdout, {
|
|
59
|
+
livePrefix: `[${config.runtimeLabel}:${config.name}]`,
|
|
60
|
+
liveWriter,
|
|
61
|
+
onLine(line) {
|
|
62
|
+
if (logRecord) options.logRegistry.append(logRecord, "stdout", line);
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
captureOutput(child.stderr, {
|
|
66
|
+
livePrefix: `[${config.runtimeLabel}:${config.name}]`,
|
|
67
|
+
liveWriter,
|
|
68
|
+
onLine(line) {
|
|
69
|
+
if (logRecord) options.logRegistry.append(logRecord, "stderr", line);
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
55
72
|
];
|
|
56
73
|
lifecycle.registerService(config, child, cwd, () => {
|
|
57
74
|
killChildProcess(child, "SIGTERM");
|
|
@@ -23,14 +23,15 @@ const MODULE_RUNNER_ENTRY = path.join(
|
|
|
23
23
|
"template-step-module-runner.mjs"
|
|
24
24
|
);
|
|
25
25
|
|
|
26
|
-
export async function runConfiguredSteps({ config, steps = [], env, labelPrefix }) {
|
|
26
|
+
export async function runConfiguredSteps({ config, steps = [], env, labelPrefix, reporter = null }) {
|
|
27
27
|
if (steps.length === 0) return;
|
|
28
28
|
const resolvedToolchain = await resolveConfiguredToolchain(config);
|
|
29
|
-
await announceResolvedToolchain(config, resolvedToolchain);
|
|
29
|
+
await announceResolvedToolchain(config, resolvedToolchain, reporter);
|
|
30
30
|
|
|
31
31
|
for (const [index, step] of steps.entries()) {
|
|
32
32
|
const label = `${labelPrefix}:${config.name}:${index + 1}`;
|
|
33
|
-
|
|
33
|
+
if (reporter?.phaseStarted) reporter.phaseStarted(label);
|
|
34
|
+
else console.log(`\n── ${label} ──`);
|
|
34
35
|
await runConfiguredStep(config, step, env, resolvedToolchain);
|
|
35
36
|
}
|
|
36
37
|
}
|
|
@@ -23,10 +23,10 @@ export async function runWorker(
|
|
|
23
23
|
lifecycle,
|
|
24
24
|
claimNextTask,
|
|
25
25
|
recordTaskOutcome,
|
|
26
|
-
recordGraphError
|
|
26
|
+
recordGraphError,
|
|
27
|
+
reporter = null
|
|
27
28
|
) {
|
|
28
29
|
const startedAt = Date.now();
|
|
29
|
-
console.log(`\n══ worker ${worker.workerId} ══`);
|
|
30
30
|
const errors = [];
|
|
31
31
|
|
|
32
32
|
try {
|
|
@@ -69,8 +69,9 @@ export async function runWorker(
|
|
|
69
69
|
}
|
|
70
70
|
worker.currentGraphKey = task.graphKey;
|
|
71
71
|
lease = await runtimeManager.acquire(task);
|
|
72
|
-
const outcome = await runTask(lease.context, task, lifecycle, lease);
|
|
72
|
+
const outcome = await runTask(lease.context, task, lifecycle, lease, reporter);
|
|
73
73
|
recordTaskOutcome(trackers, outcome.task, outcome);
|
|
74
|
+
reporter?.taskFinished?.(outcome.task, outcome);
|
|
74
75
|
timingUpdates.push({
|
|
75
76
|
key: outcome.task.timingKey,
|
|
76
77
|
durationMs: outcome.durationMs,
|
|
@@ -100,20 +101,20 @@ export async function runWorker(
|
|
|
100
101
|
};
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
async function runTask(context, task, lifecycle, lease) {
|
|
104
|
+
async function runTask(context, task, lifecycle, lease, reporter = null) {
|
|
104
105
|
const targetConfig = context.configByName.get(task.targetName);
|
|
105
106
|
if (!targetConfig) {
|
|
106
107
|
throw new Error(`Runtime instance is missing target config "${task.targetName}"`);
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
if (task.framework === "playwright") {
|
|
110
|
-
return runPlaywrightTask(targetConfig, task, lifecycle, lease);
|
|
111
|
+
return runPlaywrightTask(targetConfig, task, lifecycle, lease, reporter);
|
|
111
112
|
}
|
|
112
113
|
if (task.type === "dal") {
|
|
113
|
-
return runDalTask(targetConfig, task, lifecycle, lease);
|
|
114
|
+
return runDalTask(targetConfig, task, lifecycle, lease, reporter);
|
|
114
115
|
}
|
|
115
116
|
if (task.framework === "k6" && HTTP_K6_TYPES.has(task.type)) {
|
|
116
|
-
return runHttpK6Task(targetConfig, task, lifecycle, lease);
|
|
117
|
+
return runHttpK6Task(targetConfig, task, lifecycle, lease, reporter);
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
throw new Error(
|
package/lib/setup/index.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import type { AuthAdapter, HeaderBuilder, HttpSuiteConfig } from "../index";
|
|
2
2
|
|
|
3
|
-
export interface
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
3
|
+
export interface DatabaseTemplateConfig {
|
|
4
|
+
inputs?: string[];
|
|
5
|
+
migrate?: TemplateLifecycleStepConfig[];
|
|
6
|
+
seed?: TemplateLifecycleStepConfig[];
|
|
7
|
+
verify?: TemplateLifecycleStepConfig[];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface SeededDatabaseTemplateOptions {
|
|
11
|
+
inputs?: string[];
|
|
12
|
+
schema?: string | TemplateSqlFileStepConfig;
|
|
13
|
+
migrate?: TemplateLifecycleStepConfig | TemplateLifecycleStepConfig[];
|
|
14
|
+
seed?: TemplateLifecycleStepConfig | TemplateLifecycleStepConfig[];
|
|
15
|
+
verify?: TemplateLifecycleStepConfig | TemplateLifecycleStepConfig[];
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export interface TemplateStepBaseConfig {
|
|
@@ -40,6 +40,16 @@ export type TemplateLifecycleStepConfig =
|
|
|
40
40
|
| TemplateSqlFileStepConfig
|
|
41
41
|
| TemplateModuleStepConfig;
|
|
42
42
|
|
|
43
|
+
export interface LocalDatabaseConfig {
|
|
44
|
+
provider: "local";
|
|
45
|
+
binding?: "shared" | "per-runtime";
|
|
46
|
+
image?: string;
|
|
47
|
+
password?: string;
|
|
48
|
+
reset?: boolean;
|
|
49
|
+
template?: DatabaseTemplateConfig;
|
|
50
|
+
user?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
43
53
|
export interface SkipFileRule {
|
|
44
54
|
path: string;
|
|
45
55
|
reason: string;
|
|
@@ -161,6 +171,29 @@ export declare function moduleStep(
|
|
|
161
171
|
specifier: string,
|
|
162
172
|
options?: Omit<TemplateModuleStepConfig, "kind" | "specifier">
|
|
163
173
|
): TemplateModuleStepConfig;
|
|
174
|
+
export declare function schemaSql(
|
|
175
|
+
filePath: string,
|
|
176
|
+
options?: Omit<TemplateSqlFileStepConfig, "kind" | "path">
|
|
177
|
+
): TemplateSqlFileStepConfig;
|
|
178
|
+
export declare function seedCommand(
|
|
179
|
+
cmd: string,
|
|
180
|
+
options?: Omit<TemplateCommandStepConfig, "kind" | "cmd">
|
|
181
|
+
): TemplateCommandStepConfig;
|
|
182
|
+
export declare function seedModule(
|
|
183
|
+
specifier: string,
|
|
184
|
+
options?: Omit<TemplateModuleStepConfig, "kind" | "specifier">
|
|
185
|
+
): TemplateModuleStepConfig;
|
|
186
|
+
export declare function verifyCommand(
|
|
187
|
+
cmd: string,
|
|
188
|
+
options?: Omit<TemplateCommandStepConfig, "kind" | "cmd">
|
|
189
|
+
): TemplateCommandStepConfig;
|
|
190
|
+
export declare function verifyModule(
|
|
191
|
+
specifier: string,
|
|
192
|
+
options?: Omit<TemplateModuleStepConfig, "kind" | "specifier">
|
|
193
|
+
): TemplateModuleStepConfig;
|
|
194
|
+
export declare function seededDatabaseTemplate(
|
|
195
|
+
options?: SeededDatabaseTemplateOptions
|
|
196
|
+
): DatabaseTemplateConfig;
|
|
164
197
|
export declare function nodeToolchain(options?: NodeToolchainConfig): NodeToolchainConfig;
|
|
165
198
|
export declare function goService(options: ServiceConfig["local"] & {
|
|
166
199
|
command?: string;
|
package/lib/setup/index.mjs
CHANGED
|
@@ -56,6 +56,40 @@ export function moduleStep(specifier, options = {}) {
|
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
export function schemaSql(filePath, options = {}) {
|
|
60
|
+
return sqlFileStep(filePath, options);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function seedCommand(cmd, options = {}) {
|
|
64
|
+
return commandStep(cmd, options);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function seedModule(specifier, options = {}) {
|
|
68
|
+
return moduleStep(specifier, options);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function verifyCommand(cmd, options = {}) {
|
|
72
|
+
return commandStep(cmd, options);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function verifyModule(specifier, options = {}) {
|
|
76
|
+
return moduleStep(specifier, options);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function seededDatabaseTemplate(options = {}) {
|
|
80
|
+
const migrate = normalizeTemplateStepList(options.migrate);
|
|
81
|
+
const seed = normalizeTemplateStepList(options.seed);
|
|
82
|
+
const verify = normalizeTemplateStepList(options.verify);
|
|
83
|
+
const schema = normalizeSchemaStep(options.schema);
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
inputs: Array.isArray(options.inputs) ? [...options.inputs] : undefined,
|
|
87
|
+
migrate: schema ? [schema, ...migrate] : migrate,
|
|
88
|
+
seed,
|
|
89
|
+
verify,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
59
93
|
export function nodeToolchain(options = {}) {
|
|
60
94
|
return {
|
|
61
95
|
kind: "node",
|
|
@@ -218,6 +252,19 @@ function requiredNumber(value, label) {
|
|
|
218
252
|
return value;
|
|
219
253
|
}
|
|
220
254
|
|
|
255
|
+
function normalizeTemplateStepList(value) {
|
|
256
|
+
if (value == null) return [];
|
|
257
|
+
return Array.isArray(value) ? [...value] : [value];
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function normalizeSchemaStep(value) {
|
|
261
|
+
if (value == null) return null;
|
|
262
|
+
if (typeof value === "string") {
|
|
263
|
+
return sqlFileStep(value);
|
|
264
|
+
}
|
|
265
|
+
return value;
|
|
266
|
+
}
|
|
267
|
+
|
|
221
268
|
function envValue(name) {
|
|
222
269
|
const env = getRuntimeEnv();
|
|
223
270
|
const value = env?.rawEnv?.[name] || env?.[name];
|
package/lib/setup/index.test.mjs
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
goService,
|
|
4
|
+
nextService,
|
|
5
|
+
nodeToolchain,
|
|
6
|
+
schemaSql,
|
|
7
|
+
seedCommand,
|
|
8
|
+
seedModule,
|
|
9
|
+
seededDatabaseTemplate,
|
|
10
|
+
tsxService,
|
|
11
|
+
verifyCommand,
|
|
12
|
+
verifyModule,
|
|
13
|
+
} from "./index.mjs";
|
|
3
14
|
|
|
4
15
|
describe("setup helpers", () => {
|
|
5
16
|
it("emits plain next start commands without an exec prefix", () => {
|
|
@@ -31,4 +42,101 @@ describe("setup helpers", () => {
|
|
|
31
42
|
install: "download",
|
|
32
43
|
});
|
|
33
44
|
});
|
|
45
|
+
|
|
46
|
+
it("emits semantic database template steps using the underlying step shapes", () => {
|
|
47
|
+
expect(schemaSql("db/schema.sql")).toEqual({
|
|
48
|
+
kind: "sql-file",
|
|
49
|
+
path: "db/schema.sql",
|
|
50
|
+
cwd: undefined,
|
|
51
|
+
inputs: undefined,
|
|
52
|
+
});
|
|
53
|
+
expect(seedCommand("npm run db:seed")).toEqual({
|
|
54
|
+
kind: "command",
|
|
55
|
+
cmd: "npm run db:seed",
|
|
56
|
+
cwd: undefined,
|
|
57
|
+
inputs: undefined,
|
|
58
|
+
});
|
|
59
|
+
expect(seedModule("scripts/seed.ts#seed")).toEqual({
|
|
60
|
+
kind: "module",
|
|
61
|
+
specifier: "scripts/seed.ts#seed",
|
|
62
|
+
cwd: undefined,
|
|
63
|
+
inputs: undefined,
|
|
64
|
+
});
|
|
65
|
+
expect(verifyCommand("npm run db:verify")).toEqual({
|
|
66
|
+
kind: "command",
|
|
67
|
+
cmd: "npm run db:verify",
|
|
68
|
+
cwd: undefined,
|
|
69
|
+
inputs: undefined,
|
|
70
|
+
});
|
|
71
|
+
expect(verifyModule("scripts/verify.ts#verify")).toEqual({
|
|
72
|
+
kind: "module",
|
|
73
|
+
specifier: "scripts/verify.ts#verify",
|
|
74
|
+
cwd: undefined,
|
|
75
|
+
inputs: undefined,
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("builds a seeded database template from schema, seed, and verify intents", () => {
|
|
80
|
+
expect(
|
|
81
|
+
seededDatabaseTemplate({
|
|
82
|
+
inputs: ["db/schema.sql", "scripts/seed.ts"],
|
|
83
|
+
schema: "db/schema.sql",
|
|
84
|
+
seed: seedCommand("npm run db:seed"),
|
|
85
|
+
verify: verifyModule("scripts/verify.ts#verifySeed"),
|
|
86
|
+
})
|
|
87
|
+
).toEqual({
|
|
88
|
+
inputs: ["db/schema.sql", "scripts/seed.ts"],
|
|
89
|
+
migrate: [
|
|
90
|
+
{
|
|
91
|
+
kind: "sql-file",
|
|
92
|
+
path: "db/schema.sql",
|
|
93
|
+
cwd: undefined,
|
|
94
|
+
inputs: undefined,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
seed: [
|
|
98
|
+
{
|
|
99
|
+
kind: "command",
|
|
100
|
+
cmd: "npm run db:seed",
|
|
101
|
+
cwd: undefined,
|
|
102
|
+
inputs: undefined,
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
verify: [
|
|
106
|
+
{
|
|
107
|
+
kind: "module",
|
|
108
|
+
specifier: "scripts/verify.ts#verifySeed",
|
|
109
|
+
cwd: undefined,
|
|
110
|
+
inputs: undefined,
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("prepends schema before explicit migrate steps and normalizes singletons to arrays", () => {
|
|
117
|
+
expect(
|
|
118
|
+
seededDatabaseTemplate({
|
|
119
|
+
schema: schemaSql("db/schema.sql", { cwd: "db" }),
|
|
120
|
+
migrate: seedCommand("echo migrate"),
|
|
121
|
+
})
|
|
122
|
+
).toEqual({
|
|
123
|
+
inputs: undefined,
|
|
124
|
+
migrate: [
|
|
125
|
+
{
|
|
126
|
+
kind: "sql-file",
|
|
127
|
+
path: "db/schema.sql",
|
|
128
|
+
cwd: "db",
|
|
129
|
+
inputs: undefined,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
kind: "command",
|
|
133
|
+
cmd: "echo migrate",
|
|
134
|
+
cwd: undefined,
|
|
135
|
+
inputs: undefined,
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
seed: [],
|
|
139
|
+
verify: [],
|
|
140
|
+
});
|
|
141
|
+
});
|
|
34
142
|
});
|
package/lib/toolchains/index.mjs
CHANGED
|
@@ -84,12 +84,15 @@ export async function resolveConfiguredToolchain(config, options = {}) {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
export async function announceResolvedToolchain(config, resolvedToolchain) {
|
|
87
|
+
export async function announceResolvedToolchain(config, resolvedToolchain, reporter = null) {
|
|
88
88
|
if (!resolvedToolchain || announcedToolchains.has(config)) return;
|
|
89
89
|
announcedToolchains.add(config);
|
|
90
|
+
if (reporter?.toolchainResolved) {
|
|
91
|
+
reporter.toolchainResolved(config, resolvedToolchain);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
90
94
|
console.log(
|
|
91
|
-
`[testkit] ${config.runtimeLabel || config.name}:${config.name} toolchain `
|
|
92
|
-
`${resolvedToolchain.summary}`
|
|
95
|
+
`[testkit] ${config.runtimeLabel || config.name}:${config.name} toolchain ${resolvedToolchain.summary}`
|
|
93
96
|
);
|
|
94
97
|
}
|
|
95
98
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elench/testkit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.53",
|
|
4
4
|
"description": "CLI for discovering and running local HTTP, DAL, and Playwright test suites",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -26,6 +26,12 @@
|
|
|
26
26
|
"bin": {
|
|
27
27
|
"testkit": "bin/testkit.mjs"
|
|
28
28
|
},
|
|
29
|
+
"oclif": {
|
|
30
|
+
"bin": "testkit",
|
|
31
|
+
"commands": "./lib/cli/commands",
|
|
32
|
+
"default": "run",
|
|
33
|
+
"topicSeparator": " "
|
|
34
|
+
},
|
|
29
35
|
"scripts": {
|
|
30
36
|
"test": "vitest run",
|
|
31
37
|
"test:unit": "vitest run lib",
|
|
@@ -42,9 +48,11 @@
|
|
|
42
48
|
"vitest": "^3.2.4"
|
|
43
49
|
},
|
|
44
50
|
"dependencies": {
|
|
45
|
-
"
|
|
51
|
+
"@oclif/core": "^4.10.6",
|
|
46
52
|
"esbuild": "^0.25.11",
|
|
47
|
-
"execa": "^9.5.0"
|
|
53
|
+
"execa": "^9.5.0",
|
|
54
|
+
"ink": "^7.0.1",
|
|
55
|
+
"react": "^19.2.5"
|
|
48
56
|
},
|
|
49
57
|
"engines": {
|
|
50
58
|
"node": ">=18"
|