repterm 0.1.0
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/api/describe.d.ts +18 -0
- package/dist/api/describe.d.ts.map +1 -0
- package/dist/api/describe.js +33 -0
- package/dist/api/describe.js.map +1 -0
- package/dist/api/expect.d.ts +43 -0
- package/dist/api/expect.d.ts.map +1 -0
- package/dist/api/expect.js +167 -0
- package/dist/api/expect.js.map +1 -0
- package/dist/api/hooks.d.ts +178 -0
- package/dist/api/hooks.d.ts.map +1 -0
- package/dist/api/hooks.js +231 -0
- package/dist/api/hooks.js.map +1 -0
- package/dist/api/steps.d.ts +45 -0
- package/dist/api/steps.d.ts.map +1 -0
- package/dist/api/steps.js +106 -0
- package/dist/api/steps.js.map +1 -0
- package/dist/api/test.d.ts +101 -0
- package/dist/api/test.d.ts.map +1 -0
- package/dist/api/test.js +207 -0
- package/dist/api/test.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +203 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/reporter.d.ts +108 -0
- package/dist/cli/reporter.d.ts.map +1 -0
- package/dist/cli/reporter.js +368 -0
- package/dist/cli/reporter.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/index.d.ts +47 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +86 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/withPlugins.d.ts +71 -0
- package/dist/plugin/withPlugins.d.ts.map +1 -0
- package/dist/plugin/withPlugins.js +101 -0
- package/dist/plugin/withPlugins.js.map +1 -0
- package/dist/recording/recorder.d.ts +45 -0
- package/dist/recording/recorder.d.ts.map +1 -0
- package/dist/recording/recorder.js +97 -0
- package/dist/recording/recorder.js.map +1 -0
- package/dist/runner/artifacts.d.ts +39 -0
- package/dist/runner/artifacts.d.ts.map +1 -0
- package/dist/runner/artifacts.js +59 -0
- package/dist/runner/artifacts.js.map +1 -0
- package/dist/runner/config.d.ts +46 -0
- package/dist/runner/config.d.ts.map +1 -0
- package/dist/runner/config.js +65 -0
- package/dist/runner/config.js.map +1 -0
- package/dist/runner/filter.d.ts +26 -0
- package/dist/runner/filter.d.ts.map +1 -0
- package/dist/runner/filter.js +88 -0
- package/dist/runner/filter.js.map +1 -0
- package/dist/runner/loader.d.ts +32 -0
- package/dist/runner/loader.d.ts.map +1 -0
- package/dist/runner/loader.js +252 -0
- package/dist/runner/loader.js.map +1 -0
- package/dist/runner/models.d.ts +261 -0
- package/dist/runner/models.d.ts.map +1 -0
- package/dist/runner/models.js +5 -0
- package/dist/runner/models.js.map +1 -0
- package/dist/runner/runner.d.ts +36 -0
- package/dist/runner/runner.d.ts.map +1 -0
- package/dist/runner/runner.js +216 -0
- package/dist/runner/runner.js.map +1 -0
- package/dist/runner/scheduler.d.ts +59 -0
- package/dist/runner/scheduler.d.ts.map +1 -0
- package/dist/runner/scheduler.js +157 -0
- package/dist/runner/scheduler.js.map +1 -0
- package/dist/runner/worker-runner.d.ts +6 -0
- package/dist/runner/worker-runner.d.ts.map +1 -0
- package/dist/runner/worker-runner.js +51 -0
- package/dist/runner/worker-runner.js.map +1 -0
- package/dist/runner/worker.d.ts +54 -0
- package/dist/runner/worker.d.ts.map +1 -0
- package/dist/runner/worker.js +112 -0
- package/dist/runner/worker.js.map +1 -0
- package/dist/terminal/session.d.ts +56 -0
- package/dist/terminal/session.d.ts.map +1 -0
- package/dist/terminal/session.js +126 -0
- package/dist/terminal/session.js.map +1 -0
- package/dist/terminal/terminal.d.ts +284 -0
- package/dist/terminal/terminal.d.ts.map +1 -0
- package/dist/terminal/terminal.js +1167 -0
- package/dist/terminal/terminal.js.map +1 -0
- package/dist/utils/dependencies.d.ts +19 -0
- package/dist/utils/dependencies.d.ts.map +1 -0
- package/dist/utils/dependencies.js +58 -0
- package/dist/utils/dependencies.js.map +1 -0
- package/dist/utils/timing.d.ts +55 -0
- package/dist/utils/timing.d.ts.map +1 -0
- package/dist/utils/timing.js +87 -0
- package/dist/utils/timing.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Integration Helpers
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities to seamlessly integrate plugins with the test framework,
|
|
5
|
+
* eliminating the need for manual initialization in every test case.
|
|
6
|
+
*/
|
|
7
|
+
import { test as baseTest } from '../api/test.js';
|
|
8
|
+
import { describe as describeFromDescribe } from '../api/describe.js';
|
|
9
|
+
/**
|
|
10
|
+
* Creates a test function that automatically initializes plugins
|
|
11
|
+
*
|
|
12
|
+
* @param config - The plugin runtime configuration
|
|
13
|
+
* @returns A wrapped test function with automatic plugin initialization
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { defineConfig } from 'repterm';
|
|
18
|
+
* import { createTestWithPlugins } from 'repterm/plugin/withPlugins';
|
|
19
|
+
* import { loggerPlugin } from './plugins/logger';
|
|
20
|
+
*
|
|
21
|
+
* const config = defineConfig({
|
|
22
|
+
* plugins: [loggerPlugin()] as const,
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* const test = createTestWithPlugins(config);
|
|
26
|
+
*
|
|
27
|
+
* test('my test', async (ctx) => {
|
|
28
|
+
* // ctx automatically includes all plugins!
|
|
29
|
+
* ctx.logger.info('Hello!');
|
|
30
|
+
* ctx.plugins.logger.log('info', 'World!');
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export function createTestWithPlugins(config) {
|
|
35
|
+
/**
|
|
36
|
+
* Wrapped test function with automatic plugin initialization
|
|
37
|
+
*/
|
|
38
|
+
function testWithPlugins(name, fn) {
|
|
39
|
+
baseTest(name, async ({ terminal }) => {
|
|
40
|
+
// Create plugin factory for new terminals
|
|
41
|
+
const pluginFactory = (newTerminal) => {
|
|
42
|
+
// Initialize plugins with new terminal context
|
|
43
|
+
const newCtx = config.initialize({ terminal: newTerminal });
|
|
44
|
+
return newCtx.plugins;
|
|
45
|
+
};
|
|
46
|
+
// Inject plugin factory into terminal
|
|
47
|
+
terminal.setPluginFactory?.(pluginFactory);
|
|
48
|
+
// Initialize plugins with test context
|
|
49
|
+
const augmentedCtx = config.initialize({ terminal });
|
|
50
|
+
// Run beforeTest hooks
|
|
51
|
+
await config.runBeforeTestHooks({ terminal });
|
|
52
|
+
try {
|
|
53
|
+
// Execute the test with augmented context
|
|
54
|
+
await fn(augmentedCtx);
|
|
55
|
+
// Run afterTest hooks (success)
|
|
56
|
+
await config.runAfterTestHooks({ terminal });
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
// Run afterTest hooks (failure)
|
|
60
|
+
await config.runAfterTestHooks({ terminal }, error);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return testWithPlugins;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Creates a describe block where all tests automatically have plugin access
|
|
69
|
+
*
|
|
70
|
+
* @param config - The plugin runtime configuration
|
|
71
|
+
* @param name - The describe block name
|
|
72
|
+
* @param fn - The describe block callback
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* import { defineConfig } from 'repterm';
|
|
77
|
+
* import { describeWithPlugins } from 'repterm/plugin/withPlugins';
|
|
78
|
+
* import { loggerPlugin } from './plugins/logger';
|
|
79
|
+
*
|
|
80
|
+
* const config = defineConfig({
|
|
81
|
+
* plugins: [loggerPlugin()] as const,
|
|
82
|
+
* });
|
|
83
|
+
*
|
|
84
|
+
* describeWithPlugins(config, 'My Suite', ({ test }) => {
|
|
85
|
+
* test('test 1', async (ctx) => {
|
|
86
|
+
* ctx.logger.info('Auto-initialized!');
|
|
87
|
+
* });
|
|
88
|
+
*
|
|
89
|
+
* test('test 2', async (ctx) => {
|
|
90
|
+
* ctx.logger.debug('Same here!');
|
|
91
|
+
* });
|
|
92
|
+
* });
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export function describeWithPlugins(config, name, fn) {
|
|
96
|
+
describeFromDescribe(name, () => {
|
|
97
|
+
const test = createTestWithPlugins(config);
|
|
98
|
+
fn({ test, describe: describeFromDescribe });
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=withPlugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"withPlugins.js","sourceRoot":"","sources":["../../src/plugin/withPlugins.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAUtE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,qBAAqB,CACjC,MAA+B;IAE/B;;OAEG;IACH,SAAS,eAAe,CACpB,IAAY,EACZ,EAAgC;QAEhC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;YAClC,0CAA0C;YAC1C,MAAM,aAAa,GAAG,CAAC,WAA4B,EAAE,EAAE;gBACnD,+CAA+C;gBAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC5D,OAAO,MAAM,CAAC,OAAO,CAAC;YAC1B,CAAC,CAAC;YAEF,sCAAsC;YACtC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,aAAa,CAAC,CAAC;YAE3C,uCAAuC;YACvC,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;YAErD,uBAAuB;YACvB,MAAM,MAAM,CAAC,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;YAE9C,IAAI,CAAC;gBACD,0CAA0C;gBAC1C,MAAM,EAAE,CAAC,YAAY,CAAC,CAAC;gBAEvB,gCAAgC;gBAChC,MAAM,MAAM,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,gCAAgC;gBAChC,MAAM,MAAM,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,EAAE,KAAc,CAAC,CAAC;gBAC7D,MAAM,KAAK,CAAC;YAChB,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,OAAO,eAAe,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,mBAAmB,CAC/B,MAA+B,EAC/B,IAAY,EACZ,EAGU;IAEV,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE;QAC5B,MAAM,IAAI,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAC3C,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asciinema recording mode implementation
|
|
3
|
+
* Manages asciinema session control and artifacts
|
|
4
|
+
*/
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
export interface RecorderConfig {
|
|
7
|
+
castFile: string;
|
|
8
|
+
cols?: number;
|
|
9
|
+
rows?: number;
|
|
10
|
+
command?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Asciinema recorder wrapper
|
|
14
|
+
*/
|
|
15
|
+
export declare class Recorder extends EventEmitter {
|
|
16
|
+
private process;
|
|
17
|
+
private config;
|
|
18
|
+
private recording;
|
|
19
|
+
constructor(config: RecorderConfig);
|
|
20
|
+
/**
|
|
21
|
+
* Start recording
|
|
22
|
+
*/
|
|
23
|
+
start(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Stop recording
|
|
26
|
+
*/
|
|
27
|
+
stop(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Check if currently recording
|
|
30
|
+
*/
|
|
31
|
+
isRecording(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Get the cast file path
|
|
34
|
+
*/
|
|
35
|
+
getCastFile(): string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create a recorder instance
|
|
39
|
+
*/
|
|
40
|
+
export declare function createRecorder(config: RecorderConfig): Recorder;
|
|
41
|
+
/**
|
|
42
|
+
* Check if asciinema is available
|
|
43
|
+
*/
|
|
44
|
+
export declare function checkAsciinemaAvailable(): Promise<boolean>;
|
|
45
|
+
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/recording/recorder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,YAAY;IACxC,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,cAAc;IAKlC;;OAEG;IACH,KAAK,IAAI,IAAI;IA2Cb;;OAEG;IACH,IAAI,IAAI,IAAI;IAUZ;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,WAAW,IAAI,MAAM;CAGtB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAE/D;AAED;;GAEG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC,CAQhE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asciinema recording mode implementation
|
|
3
|
+
* Manages asciinema session control and artifacts
|
|
4
|
+
*/
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
/**
|
|
7
|
+
* Asciinema recorder wrapper
|
|
8
|
+
*/
|
|
9
|
+
export class Recorder extends EventEmitter {
|
|
10
|
+
process = null;
|
|
11
|
+
config;
|
|
12
|
+
recording = false;
|
|
13
|
+
constructor(config) {
|
|
14
|
+
super();
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Start recording
|
|
19
|
+
*/
|
|
20
|
+
start() {
|
|
21
|
+
if (this.recording) {
|
|
22
|
+
throw new Error('Recording already started');
|
|
23
|
+
}
|
|
24
|
+
const args = ['rec', this.config.castFile];
|
|
25
|
+
// Add dimensions if specified
|
|
26
|
+
if (this.config.cols && this.config.rows) {
|
|
27
|
+
args.push('--cols', this.config.cols.toString());
|
|
28
|
+
args.push('--rows', this.config.rows.toString());
|
|
29
|
+
}
|
|
30
|
+
// Add command if specified
|
|
31
|
+
if (this.config.command) {
|
|
32
|
+
args.push('--command', this.config.command);
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
// Start asciinema using Bun.spawn
|
|
36
|
+
this.process = Bun.spawn(['asciinema', ...args], {
|
|
37
|
+
stdin: 'inherit',
|
|
38
|
+
stdout: 'inherit',
|
|
39
|
+
stderr: 'inherit',
|
|
40
|
+
});
|
|
41
|
+
this.recording = true;
|
|
42
|
+
// Handle exit
|
|
43
|
+
// Bun.spawn doesn't have .on('exit'), use .exited promise
|
|
44
|
+
this.process.exited.then((code) => {
|
|
45
|
+
this.recording = false;
|
|
46
|
+
this.emit('exit', code);
|
|
47
|
+
}).catch((err) => {
|
|
48
|
+
console.error("Error waiting for process exit:", err);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
this.recording = false;
|
|
53
|
+
this.emit('error', error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Stop recording
|
|
58
|
+
*/
|
|
59
|
+
stop() {
|
|
60
|
+
if (!this.recording || !this.process) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.process.kill('SIGTERM');
|
|
64
|
+
this.recording = false;
|
|
65
|
+
// Note: The 'exit' event will be emitted by the .exited handler in start()
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if currently recording
|
|
69
|
+
*/
|
|
70
|
+
isRecording() {
|
|
71
|
+
return this.recording;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get the cast file path
|
|
75
|
+
*/
|
|
76
|
+
getCastFile() {
|
|
77
|
+
return this.config.castFile;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create a recorder instance
|
|
82
|
+
*/
|
|
83
|
+
export function createRecorder(config) {
|
|
84
|
+
return new Recorder(config);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check if asciinema is available
|
|
88
|
+
*/
|
|
89
|
+
export async function checkAsciinemaAvailable() {
|
|
90
|
+
const proc = Bun.spawn(['which', 'asciinema'], {
|
|
91
|
+
stdout: 'ignore',
|
|
92
|
+
stderr: 'ignore',
|
|
93
|
+
});
|
|
94
|
+
await proc.exited;
|
|
95
|
+
return proc.exitCode === 0;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/recording/recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact directory manager and path helpers
|
|
3
|
+
* Manages test artifacts (recordings)
|
|
4
|
+
*/
|
|
5
|
+
export interface ArtifactConfig {
|
|
6
|
+
baseDir: string;
|
|
7
|
+
runId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class ArtifactManager {
|
|
10
|
+
private baseDir;
|
|
11
|
+
private runId;
|
|
12
|
+
private runDir;
|
|
13
|
+
constructor(config: ArtifactConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Initialize artifact directory structure
|
|
16
|
+
*/
|
|
17
|
+
init(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Get path for a cast recording artifact
|
|
20
|
+
*/
|
|
21
|
+
getCastPath(testId: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Get the base artifacts directory
|
|
24
|
+
*/
|
|
25
|
+
getBaseDir(): string;
|
|
26
|
+
/**
|
|
27
|
+
* Get the run ID
|
|
28
|
+
*/
|
|
29
|
+
getRunId(): string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Generate a unique run ID
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateRunId(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Create artifact manager for a new run
|
|
37
|
+
*/
|
|
38
|
+
export declare function createArtifactManager(baseDir?: string): ArtifactManager;
|
|
39
|
+
//# sourceMappingURL=artifacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../src/runner/artifacts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,cAAc;IAMlC;;OAEG;IACH,IAAI,IAAI,IAAI;IAMZ;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAInC;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;OAEG;IACH,QAAQ,IAAI,MAAM;CAGnB;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,MAAuB,GAAG,eAAe,CAGvF"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Artifact directory manager and path helpers
|
|
3
|
+
* Manages test artifacts (recordings)
|
|
4
|
+
*/
|
|
5
|
+
import { mkdirSync, existsSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { randomBytes } from 'crypto';
|
|
8
|
+
export class ArtifactManager {
|
|
9
|
+
baseDir;
|
|
10
|
+
runId;
|
|
11
|
+
runDir;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.baseDir = config.baseDir;
|
|
14
|
+
this.runId = config.runId;
|
|
15
|
+
this.runDir = join(this.baseDir, this.runId);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Initialize artifact directory structure
|
|
19
|
+
*/
|
|
20
|
+
init() {
|
|
21
|
+
if (!existsSync(this.runDir)) {
|
|
22
|
+
mkdirSync(this.runDir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get path for a cast recording artifact
|
|
27
|
+
*/
|
|
28
|
+
getCastPath(testId) {
|
|
29
|
+
return join(this.runDir, `${testId}.cast`);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the base artifacts directory
|
|
33
|
+
*/
|
|
34
|
+
getBaseDir() {
|
|
35
|
+
return this.baseDir;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get the run ID
|
|
39
|
+
*/
|
|
40
|
+
getRunId() {
|
|
41
|
+
return this.runId;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Generate a unique run ID
|
|
46
|
+
*/
|
|
47
|
+
export function generateRunId() {
|
|
48
|
+
const timestamp = Date.now().toString(36);
|
|
49
|
+
const random = randomBytes(4).toString('hex');
|
|
50
|
+
return `${timestamp}-${random}`;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create artifact manager for a new run
|
|
54
|
+
*/
|
|
55
|
+
export function createArtifactManager(baseDir = '/tmp/repterm') {
|
|
56
|
+
const runId = generateRunId();
|
|
57
|
+
return new ArtifactManager({ baseDir, runId });
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/runner/artifacts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAOrC,MAAM,OAAO,eAAe;IAClB,OAAO,CAAS;IAChB,KAAK,CAAS;IACd,MAAM,CAAS;IAEvB,YAAY,MAAsB;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,MAAc;QACxB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,GAAG,SAAS,IAAI,MAAM,EAAE,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,UAAkB,cAAc;IACpE,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,OAAO,IAAI,eAAe,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run configuration loader
|
|
3
|
+
* Handles timeouts, recording mode, and parallel execution settings
|
|
4
|
+
*/
|
|
5
|
+
export interface RunConfig {
|
|
6
|
+
timeouts: {
|
|
7
|
+
suiteMs: number;
|
|
8
|
+
testMs: number;
|
|
9
|
+
};
|
|
10
|
+
record: {
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
castFile?: string;
|
|
13
|
+
};
|
|
14
|
+
parallel: {
|
|
15
|
+
workers: number;
|
|
16
|
+
};
|
|
17
|
+
terminal: {
|
|
18
|
+
promptLineCount?: number;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface ConfigOptions {
|
|
22
|
+
timeouts?: {
|
|
23
|
+
suiteMs?: number;
|
|
24
|
+
testMs?: number;
|
|
25
|
+
};
|
|
26
|
+
record?: {
|
|
27
|
+
enabled?: boolean;
|
|
28
|
+
castFile?: string;
|
|
29
|
+
};
|
|
30
|
+
parallel?: {
|
|
31
|
+
workers?: number;
|
|
32
|
+
};
|
|
33
|
+
terminal?: {
|
|
34
|
+
promptLineCount?: number;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Load and validate run configuration
|
|
39
|
+
* Merges user options with defaults
|
|
40
|
+
*/
|
|
41
|
+
export declare function loadConfig(options?: ConfigOptions): RunConfig;
|
|
42
|
+
/**
|
|
43
|
+
* Get default configuration
|
|
44
|
+
*/
|
|
45
|
+
export declare function getDefaultConfig(): RunConfig;
|
|
46
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/runner/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,MAAM,EAAE;QACN,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,EAAE;QACR,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAkBD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,aAAkB,GAAG,SAAS,CAsBjE;AAoBD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,SAAS,CAE5C"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run configuration loader
|
|
3
|
+
* Handles timeouts, recording mode, and parallel execution settings
|
|
4
|
+
*/
|
|
5
|
+
const DEFAULT_CONFIG = {
|
|
6
|
+
timeouts: {
|
|
7
|
+
suiteMs: 1500000, // 15 minutes
|
|
8
|
+
testMs: 300000, // 5 minutes
|
|
9
|
+
},
|
|
10
|
+
record: {
|
|
11
|
+
enabled: false,
|
|
12
|
+
},
|
|
13
|
+
parallel: {
|
|
14
|
+
workers: 1,
|
|
15
|
+
},
|
|
16
|
+
terminal: {
|
|
17
|
+
promptLineCount: undefined, // 自动检测
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Load and validate run configuration
|
|
22
|
+
* Merges user options with defaults
|
|
23
|
+
*/
|
|
24
|
+
export function loadConfig(options = {}) {
|
|
25
|
+
const config = {
|
|
26
|
+
timeouts: {
|
|
27
|
+
suiteMs: options.timeouts?.suiteMs ?? DEFAULT_CONFIG.timeouts.suiteMs,
|
|
28
|
+
testMs: options.timeouts?.testMs ?? DEFAULT_CONFIG.timeouts.testMs,
|
|
29
|
+
},
|
|
30
|
+
record: {
|
|
31
|
+
enabled: options.record?.enabled ?? DEFAULT_CONFIG.record.enabled,
|
|
32
|
+
castFile: options.record?.castFile,
|
|
33
|
+
},
|
|
34
|
+
parallel: {
|
|
35
|
+
workers: options.parallel?.workers ?? DEFAULT_CONFIG.parallel.workers,
|
|
36
|
+
},
|
|
37
|
+
terminal: {
|
|
38
|
+
promptLineCount: options.terminal?.promptLineCount,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
// Validate configuration
|
|
42
|
+
validateConfig(config);
|
|
43
|
+
return config;
|
|
44
|
+
}
|
|
45
|
+
function validateConfig(config) {
|
|
46
|
+
if (config.timeouts.suiteMs <= 0) {
|
|
47
|
+
throw new Error('Suite timeout must be a positive integer');
|
|
48
|
+
}
|
|
49
|
+
if (config.timeouts.testMs <= 0) {
|
|
50
|
+
throw new Error('Test timeout must be a positive integer');
|
|
51
|
+
}
|
|
52
|
+
if (config.parallel.workers < 1) {
|
|
53
|
+
throw new Error('Worker count must be at least 1');
|
|
54
|
+
}
|
|
55
|
+
if (config.timeouts.testMs > config.timeouts.suiteMs) {
|
|
56
|
+
throw new Error('Test timeout cannot exceed suite timeout');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get default configuration
|
|
61
|
+
*/
|
|
62
|
+
export function getDefaultConfig() {
|
|
63
|
+
return { ...DEFAULT_CONFIG };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/runner/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoCH,MAAM,cAAc,GAAc;IAChC,QAAQ,EAAE;QACR,OAAO,EAAE,OAAO,EAAE,aAAa;QAC/B,MAAM,EAAE,MAAM,EAAE,YAAY;KAC7B;IACD,MAAM,EAAE;QACN,OAAO,EAAE,KAAK;KACf;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,CAAC;KACX;IACD,QAAQ,EAAE;QACR,eAAe,EAAE,SAAS,EAAG,OAAO;KACrC;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,UAAyB,EAAE;IACpD,MAAM,MAAM,GAAc;QACxB,QAAQ,EAAE;YACR,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,IAAI,cAAc,CAAC,QAAQ,CAAC,OAAO;YACrE,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM;SACnE;QACD,MAAM,EAAE;YACN,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,OAAO;YACjE,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ;SACnC;QACD,QAAQ,EAAE;YACR,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,IAAI,cAAc,CAAC,QAAQ,CAAC,OAAO;SACtE;QACD,QAAQ,EAAE;YACR,eAAe,EAAE,OAAO,CAAC,QAAQ,EAAE,eAAe;SACnD;KACF,CAAC;IAEF,yBAAyB;IACzB,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,MAAiB;IACvC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test filtering logic
|
|
3
|
+
* Filters tests based on --record flag and record configuration
|
|
4
|
+
*/
|
|
5
|
+
import type { TestCase, TestSuite } from './models.js';
|
|
6
|
+
/**
|
|
7
|
+
* 判断测试是否应该在当前模式下运行
|
|
8
|
+
*
|
|
9
|
+
* 运行策略:
|
|
10
|
+
* - recordMode = false(普通模式):运行所有测试(包括 record: true 的测试)
|
|
11
|
+
* - recordMode = true(录制模式):只运行标注了 record: true 的测试
|
|
12
|
+
*
|
|
13
|
+
* @param testCase 测试用例
|
|
14
|
+
* @param suite 测试套件
|
|
15
|
+
* @param recordMode 是否为录制模式(--record)
|
|
16
|
+
*/
|
|
17
|
+
export declare function shouldRunTest(testCase: TestCase, suite: TestSuite, recordMode: boolean): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* 过滤测试套件,移除不应运行的测试
|
|
20
|
+
*/
|
|
21
|
+
export declare function filterSuites(suites: TestSuite[], recordMode: boolean): TestSuite[];
|
|
22
|
+
/**
|
|
23
|
+
* 统计测试数量(包括嵌套套件)
|
|
24
|
+
*/
|
|
25
|
+
export declare function countTests(suites: TestSuite[]): number;
|
|
26
|
+
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../src/runner/filter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEvD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,OAAO,GAClB,OAAO,CAWT;AAoBD;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,SAAS,EAAE,EACnB,UAAU,EAAE,OAAO,GAClB,SAAS,EAAE,CAIb;AAiCD;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAWtD"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test filtering logic
|
|
3
|
+
* Filters tests based on --record flag and record configuration
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 判断测试是否应该在当前模式下运行
|
|
7
|
+
*
|
|
8
|
+
* 运行策略:
|
|
9
|
+
* - recordMode = false(普通模式):运行所有测试(包括 record: true 的测试)
|
|
10
|
+
* - recordMode = true(录制模式):只运行标注了 record: true 的测试
|
|
11
|
+
*
|
|
12
|
+
* @param testCase 测试用例
|
|
13
|
+
* @param suite 测试套件
|
|
14
|
+
* @param recordMode 是否为录制模式(--record)
|
|
15
|
+
*/
|
|
16
|
+
export function shouldRunTest(testCase, suite, recordMode) {
|
|
17
|
+
// 确定测试的 record 配置:test > suite > undefined
|
|
18
|
+
const testRecordConfig = testCase.options?.record ?? getInheritedRecordConfig(suite);
|
|
19
|
+
// 普通模式下运行所有测试
|
|
20
|
+
if (!recordMode) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
// 录制模式下只运行标注了 record: true 的测试
|
|
24
|
+
return testRecordConfig === true;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 获取从 suite 继承的 record 配置
|
|
28
|
+
* 递归向上查找父 suite 的配置
|
|
29
|
+
*/
|
|
30
|
+
function getInheritedRecordConfig(suite) {
|
|
31
|
+
// 先检查当前 suite 的配置
|
|
32
|
+
if (suite.options?.record !== undefined) {
|
|
33
|
+
return suite.options.record;
|
|
34
|
+
}
|
|
35
|
+
// 向上查找父 suite
|
|
36
|
+
if (suite.parent) {
|
|
37
|
+
return getInheritedRecordConfig(suite.parent);
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 过滤测试套件,移除不应运行的测试
|
|
43
|
+
*/
|
|
44
|
+
export function filterSuites(suites, recordMode) {
|
|
45
|
+
return suites
|
|
46
|
+
.map(suite => filterSuite(suite, recordMode))
|
|
47
|
+
.filter(suite => hasTests(suite));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 过滤单个测试套件
|
|
51
|
+
*/
|
|
52
|
+
function filterSuite(suite, recordMode) {
|
|
53
|
+
const filteredTests = suite.tests.filter(test => shouldRunTest(test, suite, recordMode));
|
|
54
|
+
const filteredSubSuites = suite.suites
|
|
55
|
+
?.map(s => filterSuite(s, recordMode))
|
|
56
|
+
.filter(s => hasTests(s));
|
|
57
|
+
return {
|
|
58
|
+
...suite,
|
|
59
|
+
tests: filteredTests,
|
|
60
|
+
suites: filteredSubSuites,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 检查套件是否有测试(包括嵌套套件)
|
|
65
|
+
*/
|
|
66
|
+
function hasTests(suite) {
|
|
67
|
+
if (suite.tests.length > 0) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
if (suite.suites && suite.suites.length > 0) {
|
|
71
|
+
return suite.suites.some(s => hasTests(s));
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 统计测试数量(包括嵌套套件)
|
|
77
|
+
*/
|
|
78
|
+
export function countTests(suites) {
|
|
79
|
+
let count = 0;
|
|
80
|
+
for (const suite of suites) {
|
|
81
|
+
count += suite.tests.length;
|
|
82
|
+
if (suite.suites) {
|
|
83
|
+
count += countTests(suite.suites);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return count;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../src/runner/filter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAkB,EAClB,KAAgB,EAChB,UAAmB;IAEnB,2CAA2C;IAC3C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,wBAAwB,CAAC,KAAK,CAAC,CAAC;IAErF,cAAc;IACd,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+BAA+B;IAC/B,OAAO,gBAAgB,KAAK,IAAI,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,SAAS,wBAAwB,CAAC,KAAgB;IAChD,kBAAkB;IAClB,IAAI,KAAK,CAAC,OAAO,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED,cAAc;IACd,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,wBAAwB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAmB,EACnB,UAAmB;IAEnB,OAAO,MAAM;SACV,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;SAC5C,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,KAAgB,EAAE,UAAmB;IACxD,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IACzF,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM;QACpC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;SACrC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5B,OAAO;QACL,GAAG,KAAK;QACR,KAAK,EAAE,aAAa;QACpB,MAAM,EAAE,iBAAiB;KAC1B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,KAAgB;IAChC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;QAC5B,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test file discovery and loading
|
|
3
|
+
* Handles finding and importing test files with directory-level setup support
|
|
4
|
+
*/
|
|
5
|
+
import type { TestSuite } from './models.js';
|
|
6
|
+
export interface LoaderOptions {
|
|
7
|
+
pattern?: RegExp;
|
|
8
|
+
recursive?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Discover test files in a directory or direct file paths
|
|
12
|
+
*/
|
|
13
|
+
export declare function discoverTests(paths: string[], options?: LoaderOptions): Promise<string[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Load a test file and execute it to register tests
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadTestFile(filePath: string): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Load multiple test files
|
|
20
|
+
*/
|
|
21
|
+
export declare function loadTestFiles(filePaths: string[]): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Load a directory with setup.ts support
|
|
24
|
+
* Creates directory-level suites and executes setup files
|
|
25
|
+
*/
|
|
26
|
+
export declare function loadDirectory(dirPath: string, parentSuite?: TestSuite | null, pattern?: RegExp): Promise<TestSuite>;
|
|
27
|
+
/**
|
|
28
|
+
* Load test files with directory-level setup support
|
|
29
|
+
* This is the enhanced version that supports setup.ts files
|
|
30
|
+
*/
|
|
31
|
+
export declare function loadTestsWithSetup(paths: string[], options?: LoaderOptions): Promise<TestSuite[]>;
|
|
32
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/runner/loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAgBD;;GAEG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,EAAE,CAAC,CA6BnB;AAoCD;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BlE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAItE;AA6DD;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,SAAS,GAAG,IAAW,EACpC,OAAO,GAAE,MAAwB,GAChC,OAAO,CAAC,SAAS,CAAC,CA+CpB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,SAAS,EAAE,CAAC,CA+BtB"}
|