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.
Files changed (97) hide show
  1. package/dist/api/describe.d.ts +18 -0
  2. package/dist/api/describe.d.ts.map +1 -0
  3. package/dist/api/describe.js +33 -0
  4. package/dist/api/describe.js.map +1 -0
  5. package/dist/api/expect.d.ts +43 -0
  6. package/dist/api/expect.d.ts.map +1 -0
  7. package/dist/api/expect.js +167 -0
  8. package/dist/api/expect.js.map +1 -0
  9. package/dist/api/hooks.d.ts +178 -0
  10. package/dist/api/hooks.d.ts.map +1 -0
  11. package/dist/api/hooks.js +231 -0
  12. package/dist/api/hooks.js.map +1 -0
  13. package/dist/api/steps.d.ts +45 -0
  14. package/dist/api/steps.d.ts.map +1 -0
  15. package/dist/api/steps.js +106 -0
  16. package/dist/api/steps.js.map +1 -0
  17. package/dist/api/test.d.ts +101 -0
  18. package/dist/api/test.d.ts.map +1 -0
  19. package/dist/api/test.js +207 -0
  20. package/dist/api/test.js.map +1 -0
  21. package/dist/cli/index.d.ts +7 -0
  22. package/dist/cli/index.d.ts.map +1 -0
  23. package/dist/cli/index.js +203 -0
  24. package/dist/cli/index.js.map +1 -0
  25. package/dist/cli/reporter.d.ts +108 -0
  26. package/dist/cli/reporter.d.ts.map +1 -0
  27. package/dist/cli/reporter.js +368 -0
  28. package/dist/cli/reporter.js.map +1 -0
  29. package/dist/index.d.ts +15 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +24 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/plugin/index.d.ts +47 -0
  34. package/dist/plugin/index.d.ts.map +1 -0
  35. package/dist/plugin/index.js +86 -0
  36. package/dist/plugin/index.js.map +1 -0
  37. package/dist/plugin/withPlugins.d.ts +71 -0
  38. package/dist/plugin/withPlugins.d.ts.map +1 -0
  39. package/dist/plugin/withPlugins.js +101 -0
  40. package/dist/plugin/withPlugins.js.map +1 -0
  41. package/dist/recording/recorder.d.ts +45 -0
  42. package/dist/recording/recorder.d.ts.map +1 -0
  43. package/dist/recording/recorder.js +97 -0
  44. package/dist/recording/recorder.js.map +1 -0
  45. package/dist/runner/artifacts.d.ts +39 -0
  46. package/dist/runner/artifacts.d.ts.map +1 -0
  47. package/dist/runner/artifacts.js +59 -0
  48. package/dist/runner/artifacts.js.map +1 -0
  49. package/dist/runner/config.d.ts +46 -0
  50. package/dist/runner/config.d.ts.map +1 -0
  51. package/dist/runner/config.js +65 -0
  52. package/dist/runner/config.js.map +1 -0
  53. package/dist/runner/filter.d.ts +26 -0
  54. package/dist/runner/filter.d.ts.map +1 -0
  55. package/dist/runner/filter.js +88 -0
  56. package/dist/runner/filter.js.map +1 -0
  57. package/dist/runner/loader.d.ts +32 -0
  58. package/dist/runner/loader.d.ts.map +1 -0
  59. package/dist/runner/loader.js +252 -0
  60. package/dist/runner/loader.js.map +1 -0
  61. package/dist/runner/models.d.ts +261 -0
  62. package/dist/runner/models.d.ts.map +1 -0
  63. package/dist/runner/models.js +5 -0
  64. package/dist/runner/models.js.map +1 -0
  65. package/dist/runner/runner.d.ts +36 -0
  66. package/dist/runner/runner.d.ts.map +1 -0
  67. package/dist/runner/runner.js +216 -0
  68. package/dist/runner/runner.js.map +1 -0
  69. package/dist/runner/scheduler.d.ts +59 -0
  70. package/dist/runner/scheduler.d.ts.map +1 -0
  71. package/dist/runner/scheduler.js +157 -0
  72. package/dist/runner/scheduler.js.map +1 -0
  73. package/dist/runner/worker-runner.d.ts +6 -0
  74. package/dist/runner/worker-runner.d.ts.map +1 -0
  75. package/dist/runner/worker-runner.js +51 -0
  76. package/dist/runner/worker-runner.js.map +1 -0
  77. package/dist/runner/worker.d.ts +54 -0
  78. package/dist/runner/worker.d.ts.map +1 -0
  79. package/dist/runner/worker.js +112 -0
  80. package/dist/runner/worker.js.map +1 -0
  81. package/dist/terminal/session.d.ts +56 -0
  82. package/dist/terminal/session.d.ts.map +1 -0
  83. package/dist/terminal/session.js +126 -0
  84. package/dist/terminal/session.js.map +1 -0
  85. package/dist/terminal/terminal.d.ts +284 -0
  86. package/dist/terminal/terminal.d.ts.map +1 -0
  87. package/dist/terminal/terminal.js +1167 -0
  88. package/dist/terminal/terminal.js.map +1 -0
  89. package/dist/utils/dependencies.d.ts +19 -0
  90. package/dist/utils/dependencies.d.ts.map +1 -0
  91. package/dist/utils/dependencies.js +58 -0
  92. package/dist/utils/dependencies.js.map +1 -0
  93. package/dist/utils/timing.d.ts +55 -0
  94. package/dist/utils/timing.d.ts.map +1 -0
  95. package/dist/utils/timing.js +87 -0
  96. package/dist/utils/timing.js.map +1 -0
  97. 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":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAUtC;;GAEG;AACH,MAAM,OAAO,QAAS,SAAQ,YAAY;IAChC,OAAO,GAAsB,IAAI,CAAC;IAClC,MAAM,CAAiB;IACvB,SAAS,GAAG,KAAK,CAAC;IAE1B,YAAY,MAAsB;QAChC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAE3C,8BAA8B;QAC9B,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACzC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,2BAA2B;QAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9C,CAAC;QAED,IAAI,CAAC;YACH,kCAAkC;YAClC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,EAAE;gBAC/C,KAAK,EAAE,SAAS;gBAChB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;aAClB,CAAC,CAAC;YAEH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YAEtB,cAAc;YACd,0DAA0D;YAC1D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;gBAChC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;YACxD,CAAC,CAAC,CAAC;QAEL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACrC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,2EAA2E;IAC7E,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;IAC9B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,OAAO,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE;QAC7C,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,MAAM,CAAC;IAClB,OAAO,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC;AAC7B,CAAC"}
@@ -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"}