elasticdash-test 0.1.4 → 0.1.6

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 CHANGED
@@ -4,8 +4,7 @@ An AI-native test runner for ElasticDash workflow testing. Built for async AI pi
4
4
 
5
5
  - Trace-first: every test receives a `trace` context to record and assert on LLM calls and tool invocations
6
6
  - Automatic fetch interception for OpenAI, Gemini, and Grok — no manual instrumentation required
7
- - AI-specific matchers: `toHaveLLMStep`, `toCallTool`, `toMatchSemanticOutput`, `toHaveCustomStep`
8
- - AI-specific matchers: `toHaveLLMStep`, `toCallTool`, `toMatchSemanticOutput`, `toHaveCustomStep`, `toHavePromptWhere`
7
+ - AI-specific matchers: `toHaveLLMStep`, `toCallTool`, `toMatchSemanticOutput`, `toHaveCustomStep`, `toHavePromptWhere`, `toEvaluateOutputMetric`
9
8
  - Sequential execution, no parallelism overhead
10
9
  - No Jest dependency
11
10
 
@@ -62,6 +61,8 @@ Duration: 3.4s
62
61
 
63
62
  ## Writing Tests
64
63
 
64
+ See the full guide in [docs/test-writing-guidelines.md](docs/test-writing-guidelines.md).
65
+
65
66
  ### Globals
66
67
 
67
68
  After importing `test-setup`, these are available globally — no imports needed:
@@ -70,6 +71,8 @@ After importing `test-setup`, these are available globally — no imports needed
70
71
  |---|---|
71
72
  | `aiTest(name, fn)` | Register a test |
72
73
  | `beforeAll(fn)` | Run once before all tests in the file |
74
+ | `beforeEach(fn)` | Run before every test in the file |
75
+ | `afterEach(fn)` | Run after every test in the file (runs even if the test fails) |
73
76
  | `afterAll(fn)` | Run once after all tests in the file |
74
77
 
75
78
  ### Test context
@@ -161,9 +164,52 @@ expect(ctx.trace).toMatchSemanticOutput('attack stat', {
161
164
 
162
165
  // Minimal, using default OpenAI model
163
166
  expect(ctx.trace).toMatchSemanticOutput('order confirmed')
167
+
168
+ // OpenAI-compatible endpoint (e.g., Moonshot/Kimi) via baseURL + apiKey
169
+ expect(ctx.trace).toMatchSemanticOutput('order confirmed', {
170
+ provider: 'openai',
171
+ model: 'kimi-k2-turbo-preview',
172
+ apiKey: process.env.KIMI_API_KEY,
173
+ baseURL: 'https://api.moonshot.ai/v1',
174
+ })
164
175
  ```
165
176
 
166
177
  Environment keys by provider: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY` (or `GOOGLE_API_KEY`), `GROK_API_KEY`.
178
+ For OpenAI-compatible endpoints, pass `apiKey`/`baseURL` in options or set an appropriate env var used by your SDK.
179
+
180
+ #### `toEvaluateOutputMetric(config)`
181
+
182
+ Evaluate one LLM step’s prompt or result using an LLM and assert a numeric metric condition in the range 0.0–1.0. Defaults: target=`result`, condition=`atLeast 0.7`, provider=`openai`, model=`gpt-4.1`.
183
+
184
+ ```ts
185
+ // Evaluate the last LLM result with your own prompt; default condition atLeast 0.7
186
+ expect(ctx.trace).toEvaluateOutputMetric({
187
+ evaluationPrompt: 'Rate how well this answers the user question.',
188
+ })
189
+
190
+ // Check a specific step (3rd LLM prompt), target the prompt text, require >= 0.8 via Claude
191
+ expect(ctx.trace).toEvaluateOutputMetric({
192
+ evaluationPrompt: 'Score coherence of this prompt between 0 and 1.',
193
+ target: 'prompt',
194
+ nth: 3,
195
+ condition: { atLeast: 0.8 },
196
+ provider: 'claude',
197
+ model: 'claude-3-opus-20240229',
198
+ })
199
+
200
+ // Custom comparator: score must be < 0.3
201
+ expect(ctx.trace).toEvaluateOutputMetric({
202
+ evaluationPrompt: 'Rate hallucination risk (0=none, 1=high).',
203
+ condition: { lessThan: 0.3 },
204
+ })
205
+ ```
206
+
207
+ Options:
208
+ - `evaluationPrompt` (required): your scoring instructions; model is asked to return only a number between 0 and 1.
209
+ - `target`: `'result'` (default) or `'prompt'`. Mutually exclusive; evaluates that text only.
210
+ - `index` / `nth`: pick which LLM step to score (0-based or 1-based). Defaults to the last LLM step.
211
+ - `condition`: one of `greaterThan`, `lessThan`, `atLeast`, `atMost`, `equals`; default is `{ atLeast: 0.7 }`. Fails if the score is outside 0.0–1.0 or cannot be parsed.
212
+ - `provider` / `model` / `sdk` / `apiKey` / `baseURL`: same shape as `toMatchSemanticOutput` (supports OpenAI, Claude, Gemini, Grok, and OpenAI-compatible via `baseURL`). Requires corresponding API key if no SDK is supplied.
167
213
 
168
214
  #### `toHaveCustomStep(config?)`
169
215
 
@@ -0,0 +1,43 @@
1
+ export type UiEvent = {
2
+ type: 'run-start';
3
+ payload: {
4
+ files: string[];
5
+ };
6
+ } | {
7
+ type: 'test-start';
8
+ payload: {
9
+ name: string;
10
+ };
11
+ } | {
12
+ type: 'test-finish';
13
+ payload: {
14
+ name: string;
15
+ passed: boolean;
16
+ durationMs: number;
17
+ errorMessage?: string;
18
+ };
19
+ } | {
20
+ type: 'run-summary';
21
+ payload: {
22
+ passed: number;
23
+ failed: number;
24
+ total: number;
25
+ durationMs: number;
26
+ failures: Array<{
27
+ name: string;
28
+ errorMessage?: string;
29
+ }>;
30
+ };
31
+ };
32
+ export interface BrowserUiServer {
33
+ url: string;
34
+ send(event: UiEvent): void;
35
+ close(): void;
36
+ }
37
+ interface BrowserUiOptions {
38
+ port?: number;
39
+ autoOpen?: boolean;
40
+ }
41
+ export declare function startBrowserUiServer(opts?: BrowserUiOptions): Promise<BrowserUiServer | undefined>;
42
+ export {};
43
+ //# sourceMappingURL=browser-ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-ui.d.ts","sourceRoot":"","sources":["../src/browser-ui.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC9G;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,YAAY,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAA;CAAE,CAAA;AAErK,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IAC1B,KAAK,IAAI,IAAI,CAAA;CACd;AAED,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAkJD,wBAAsB,oBAAoB,CAAC,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAyE5G"}
@@ -0,0 +1,226 @@
1
+ import http from 'node:http';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { spawn } from 'node:child_process';
6
+ const defaultHtml = `<!doctype html>
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="UTF-8" />
10
+ <title>ElasticDash Test Runner</title>
11
+ <style>
12
+ :root { font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #0b1021; color: #e8ecf7; }
13
+ body { margin: 0; padding: 24px; }
14
+ h1 { margin: 0 0 16px; font-size: 20px; }
15
+ .summary { display: flex; gap: 12px; margin-bottom: 16px; }
16
+ .pill { padding: 8px 12px; border-radius: 999px; font-weight: 600; }
17
+ .pass { background: #12351b; color: #8de0a3; }
18
+ .fail { background: #351212; color: #f59b9b; }
19
+ .total { background: #1c2745; color: #cdd7ff; }
20
+ .tests { margin-top: 12px; }
21
+ .test { border: 1px solid #1f2a4f; border-radius: 8px; padding: 12px; margin-bottom: 8px; background: #0f1731; }
22
+ .name { font-weight: 600; }
23
+ .error { margin-top: 8px; white-space: pre-wrap; color: #f59b9b; font-family: ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; }
24
+ .status { font-weight: 600; }
25
+ </style>
26
+ </head>
27
+ <body>
28
+ <h1>ElasticDash Test Runner</h1>
29
+ <div class="summary">
30
+ <div class="pill total" id="total">Total: -</div>
31
+ <div class="pill pass" id="passed">Passed: -</div>
32
+ <div class="pill fail" id="failed">Failed: -</div>
33
+ </div>
34
+ <div id="progress">Waiting for test run...</div>
35
+ <div class="tests" id="tests"></div>
36
+ <script>
37
+ const totalEl = document.getElementById('total');
38
+ const passedEl = document.getElementById('passed');
39
+ const failedEl = document.getElementById('failed');
40
+ const progressEl = document.getElementById('progress');
41
+ const testsEl = document.getElementById('tests');
42
+
43
+ const tests = new Map();
44
+ let processed = 0;
45
+ let passedCount = 0;
46
+ let failedCount = 0;
47
+ let finalTotal = null;
48
+
49
+ function setError(el, message) {
50
+ const errEl = el.querySelector('.error');
51
+ let toggle = el.querySelector('.toggle');
52
+ if (!message) {
53
+ errEl.textContent = '';
54
+ errEl.style.display = 'none';
55
+ if (toggle) toggle.style.display = 'none';
56
+ return;
57
+ }
58
+ if (!toggle) {
59
+ toggle = document.createElement('button');
60
+ toggle.className = 'toggle';
61
+ toggle.textContent = 'Show details';
62
+ toggle.style.marginTop = '8px';
63
+ toggle.style.background = '#1c2745';
64
+ toggle.style.color = '#cdd7ff';
65
+ toggle.style.border = '1px solid #2a3866';
66
+ toggle.style.borderRadius = '6px';
67
+ toggle.style.padding = '6px 10px';
68
+ toggle.style.cursor = 'pointer';
69
+ toggle.style.fontWeight = '600';
70
+ el.appendChild(toggle);
71
+ toggle.addEventListener('click', () => {
72
+ const isHidden = errEl.style.display === 'none';
73
+ errEl.style.display = isHidden ? 'block' : 'none';
74
+ toggle.textContent = isHidden ? 'Hide details' : 'Show details';
75
+ });
76
+ }
77
+ errEl.textContent = message;
78
+ errEl.style.display = 'none';
79
+ toggle.style.display = 'inline-block';
80
+ toggle.textContent = 'Show details';
81
+ }
82
+
83
+ function renderTest(name) {
84
+ let el = tests.get(name);
85
+ if (!el) {
86
+ el = document.createElement('div');
87
+ el.className = 'test';
88
+ el.innerHTML = '<div class="name"></div><div class="status"></div><div class="error"></div>';
89
+ tests.set(name, el);
90
+ testsEl.appendChild(el);
91
+ }
92
+ return el;
93
+ }
94
+
95
+ function updatePills(passed, failed, total) {
96
+ totalEl.textContent = 'Total: ' + total;
97
+ passedEl.textContent = 'Passed: ' + passed;
98
+ failedEl.textContent = 'Failed: ' + failed;
99
+ }
100
+
101
+ const evtSource = new EventSource('/events');
102
+ evtSource.onmessage = (ev) => {
103
+ try {
104
+ const msg = JSON.parse(ev.data);
105
+ if (msg.type === 'test-start') {
106
+ const el = renderTest(msg.payload.name);
107
+ el.querySelector('.name').textContent = msg.payload.name;
108
+ el.querySelector('.status').textContent = 'Running...';
109
+ el.querySelector('.status').style.color = '#cdd7ff';
110
+ el.querySelector('.error').textContent = '';
111
+ progressEl.textContent = 'Running tests...';
112
+ }
113
+ if (msg.type === 'test-finish') {
114
+ const el = renderTest(msg.payload.name);
115
+ el.querySelector('.name').textContent = msg.payload.name;
116
+ el.querySelector('.status').textContent = msg.payload.passed ? 'Passed' : 'Failed';
117
+ el.querySelector('.status').style.color = msg.payload.passed ? '#8de0a3' : '#f59b9b';
118
+ setError(el, msg.payload.errorMessage || '');
119
+
120
+ // live tally
121
+ processed += 1;
122
+ if (msg.payload.passed) passedCount += 1;
123
+ else failedCount += 1;
124
+ const displayTotal = finalTotal !== null ? finalTotal : processed;
125
+ updatePills(passedCount, failedCount, displayTotal);
126
+ }
127
+ if (msg.type === 'run-summary') {
128
+ finalTotal = msg.payload.total;
129
+ passedCount = msg.payload.passed;
130
+ failedCount = msg.payload.failed;
131
+ processed = msg.payload.total;
132
+ updatePills(msg.payload.passed, msg.payload.failed, msg.payload.total);
133
+ progressEl.textContent = 'Finished';
134
+ msg.payload.failures.forEach(function (f) {
135
+ const el = renderTest(f.name);
136
+ el.querySelector('.name').textContent = f.name;
137
+ el.querySelector('.status').textContent = 'Failed';
138
+ el.querySelector('.status').style.color = '#f59b9b';
139
+ setError(el, f.errorMessage || '');
140
+ });
141
+ }
142
+ } catch (e) {
143
+ console.error('Bad event data', e);
144
+ }
145
+ };
146
+ </script>
147
+ </body>
148
+ </html>`;
149
+ export async function startBrowserUiServer(opts = {}) {
150
+ const autoOpen = opts.autoOpen !== false;
151
+ let port = opts.port ?? 4571;
152
+ // Ensure base dir for potential static assets (none now)
153
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
154
+ const clients = [];
155
+ const handler = (req, res) => {
156
+ if (!req.url)
157
+ return res.end();
158
+ if (req.url.startsWith('/events')) {
159
+ res.writeHead(200, {
160
+ 'Content-Type': 'text/event-stream',
161
+ Connection: 'keep-alive',
162
+ 'Cache-Control': 'no-cache',
163
+ });
164
+ res.write('\n');
165
+ clients.push(res);
166
+ req.on('close', () => {
167
+ const idx = clients.indexOf(res);
168
+ if (idx >= 0)
169
+ clients.splice(idx, 1);
170
+ });
171
+ return;
172
+ }
173
+ // Serve inline HTML
174
+ res.writeHead(200, { 'Content-Type': 'text/html' });
175
+ res.end(defaultHtml);
176
+ };
177
+ let server;
178
+ let started = false;
179
+ while (!started) {
180
+ try {
181
+ server = http.createServer(handler);
182
+ await new Promise((resolve, reject) => {
183
+ server.once('error', reject);
184
+ server.listen(port, resolve);
185
+ });
186
+ started = true;
187
+ }
188
+ catch (err) {
189
+ port += 1;
190
+ if (port > (opts.port ?? 4571) + 10) {
191
+ console.error('[elasticdash] Browser UI server failed to start:', err.message);
192
+ return undefined;
193
+ }
194
+ }
195
+ }
196
+ const url = `http://localhost:${port}`;
197
+ function send(event) {
198
+ const payload = `data: ${JSON.stringify(event)}\n\n`;
199
+ for (const client of [...clients]) {
200
+ client.write(payload);
201
+ }
202
+ }
203
+ function close() {
204
+ for (const client of clients) {
205
+ client.end();
206
+ }
207
+ clients.length = 0;
208
+ server?.close();
209
+ }
210
+ if (autoOpen) {
211
+ openBrowser(url);
212
+ }
213
+ return { url, send, close };
214
+ }
215
+ function openBrowser(url) {
216
+ const platform = os.platform();
217
+ const command = platform === 'darwin'
218
+ ? 'open'
219
+ : platform === 'win32'
220
+ ? 'cmd'
221
+ : 'xdg-open';
222
+ const args = platform === 'win32' ? ['/c', 'start', '""', url] : [url];
223
+ const child = spawn(command, args, { stdio: 'ignore', detached: true });
224
+ child.unref();
225
+ }
226
+ //# sourceMappingURL=browser-ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-ui.js","sourceRoot":"","sources":["../src/browser-ui.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -9,6 +9,12 @@ import { registerMatchers } from './matchers/index.js';
9
9
  import { installAIInterceptor } from './interceptors/ai-interceptor.js';
10
10
  import { runFiles } from './runner.js';
11
11
  import { reportResults } from './reporter.js';
12
+ import { startBrowserUiServer } from './browser-ui.js';
13
+ function stripAnsi(input) {
14
+ if (!input)
15
+ return input;
16
+ return input.replace(/\u001b\[[0-9;]*m/g, '');
17
+ }
12
18
  async function loadConfig(cwd) {
13
19
  const configPath = path.join(cwd, 'elasticdash.config.ts');
14
20
  const configPathJs = path.join(cwd, 'elasticdash.config.js');
@@ -55,7 +61,9 @@ async function bootstrap() {
55
61
  program
56
62
  .command('test [dir]')
57
63
  .description('Discover and run all AI test files')
58
- .action(async (dir) => {
64
+ .option('--no-browser-ui', 'Disable browser progress UI')
65
+ .option('--browser-ui-port <port>', 'Port for browser UI', (v) => Number(v), undefined)
66
+ .action(async (dir, cmd) => {
59
67
  const searchBase = dir ? path.resolve(cwd, dir) : cwd;
60
68
  console.log('[elasticdash] Test discovery pattern:', defaultPattern);
61
69
  console.log('[elasticdash] Test search base:', searchBase);
@@ -65,24 +73,123 @@ async function bootstrap() {
65
73
  console.error(`No test files found matching: ${defaultPattern.join(', ')}`);
66
74
  process.exit(1);
67
75
  }
68
- const results = await runFiles(files);
76
+ const useBrowserUiEnv = process.env.ELASTICDASH_BROWSER_UI !== '0';
77
+ const useBrowserUiFlag = cmd?.browserUi !== false;
78
+ const enableBrowserUi = useBrowserUiEnv && useBrowserUiFlag;
79
+ const ui = enableBrowserUi
80
+ ? await startBrowserUiServer({ port: cmd?.browserUiPort, autoOpen: true })
81
+ : undefined;
82
+ if (ui) {
83
+ ui.send({ type: 'run-start', payload: { files } });
84
+ }
85
+ const startedAt = Date.now();
86
+ const results = await runFiles(files, {
87
+ hooks: {
88
+ onTestStart(name) {
89
+ ui?.send({ type: 'test-start', payload: { name } });
90
+ },
91
+ onTestFinish(name, passed, durationMs, error) {
92
+ ui?.send({
93
+ type: 'test-finish',
94
+ payload: { name, passed, durationMs, errorMessage: stripAnsi(error?.message) },
95
+ });
96
+ },
97
+ },
98
+ });
69
99
  // Log registered tests
70
100
  const { getRegistry } = await import('./core/registry.js');
71
101
  const registry = getRegistry();
72
102
  console.log('[elasticdash] Tests registered:', registry.tests.map(t => t.name));
73
103
  reportResults(results);
74
104
  const anyFailed = results.some((fr) => fr.results.some((r) => !r.passed));
105
+ if (ui) {
106
+ const durationMs = Date.now() - startedAt;
107
+ const failures = [];
108
+ let totalTests = 0;
109
+ let passedCount = 0;
110
+ for (const fr of results) {
111
+ for (const r of fr.results) {
112
+ totalTests += 1;
113
+ if (r.passed)
114
+ passedCount += 1;
115
+ else
116
+ failures.push({ name: r.name, errorMessage: stripAnsi(r.error?.message) });
117
+ }
118
+ }
119
+ ui.send({
120
+ type: 'run-summary',
121
+ payload: {
122
+ passed: passedCount,
123
+ failed: failures.length,
124
+ total: totalTests,
125
+ durationMs,
126
+ failures,
127
+ },
128
+ });
129
+ // Leave UI running briefly; do not block process exit
130
+ setTimeout(() => ui.close(), 5000);
131
+ }
75
132
  process.exit(anyFailed ? 1 : 0);
76
133
  });
77
134
  // elasticdash run <file>
78
135
  program
79
136
  .command('run <file>')
80
137
  .description('Run a single AI test file')
81
- .action(async (file) => {
138
+ .option('--no-browser-ui', 'Disable browser progress UI')
139
+ .option('--browser-ui-port <port>', 'Port for browser UI', (v) => Number(v), undefined)
140
+ .action(async (file, cmd) => {
82
141
  const absFile = pathToFileURL(path.resolve(cwd, file)).href;
83
- const results = await runFiles([absFile]);
142
+ const useBrowserUiEnv = process.env.ELASTICDASH_BROWSER_UI !== '0';
143
+ const useBrowserUiFlag = cmd?.browserUi !== false;
144
+ const enableBrowserUi = useBrowserUiEnv && useBrowserUiFlag;
145
+ const ui = enableBrowserUi
146
+ ? await startBrowserUiServer({ port: cmd?.browserUiPort, autoOpen: true })
147
+ : undefined;
148
+ if (ui) {
149
+ ui.send({ type: 'run-start', payload: { files: [absFile] } });
150
+ }
151
+ const startedAt = Date.now();
152
+ const results = await runFiles([absFile], {
153
+ hooks: {
154
+ onTestStart(name) {
155
+ ui?.send({ type: 'test-start', payload: { name } });
156
+ },
157
+ onTestFinish(name, passed, durationMs, error) {
158
+ ui?.send({
159
+ type: 'test-finish',
160
+ payload: { name, passed, durationMs, errorMessage: stripAnsi(error?.message) },
161
+ });
162
+ },
163
+ },
164
+ });
84
165
  reportResults(results);
85
166
  const anyFailed = results.some((fr) => fr.results.some((r) => !r.passed));
167
+ if (ui) {
168
+ const durationMs = Date.now() - startedAt;
169
+ const failures = [];
170
+ let totalTests = 0;
171
+ let passedCount = 0;
172
+ for (const fr of results) {
173
+ for (const r of fr.results) {
174
+ totalTests += 1;
175
+ if (r.passed)
176
+ passedCount += 1;
177
+ else
178
+ failures.push({ name: r.name, errorMessage: stripAnsi(r.error?.message) });
179
+ }
180
+ }
181
+ ui.send({
182
+ type: 'run-summary',
183
+ payload: {
184
+ passed: passedCount,
185
+ failed: failures.length,
186
+ total: totalTests,
187
+ durationMs,
188
+ failures,
189
+ },
190
+ });
191
+ setTimeout(() => ui.close(), 5000);
192
+ }
86
193
  process.exit(anyFailed ? 1 : 0);
87
194
  });
88
195
  await program.parseAsync(process.argv);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -8,15 +8,21 @@ export interface Registry {
8
8
  tests: TestEntry[];
9
9
  beforeAllHooks: Array<() => Promise<void> | void>;
10
10
  afterAllHooks: Array<() => Promise<void> | void>;
11
+ beforeEachHooks: Array<() => Promise<void> | void>;
12
+ afterEachHooks: Array<() => Promise<void> | void>;
11
13
  }
12
14
  export declare function clearRegistry(): void;
13
15
  export declare function getRegistry(): Registry;
14
16
  export declare function aiTest(name: string, fn: TestFunction): void;
15
17
  export declare function beforeAll(fn: () => Promise<void> | void): void;
16
18
  export declare function afterAll(fn: () => Promise<void> | void): void;
19
+ export declare function beforeEach(fn: () => Promise<void> | void): void;
20
+ export declare function afterEach(fn: () => Promise<void> | void): void;
17
21
  declare global {
18
22
  var aiTest: (name: string, fn: TestFunction) => void;
19
23
  var beforeAll: (fn: () => Promise<void> | void) => void;
20
24
  var afterAll: (fn: () => Promise<void> | void) => void;
25
+ var beforeEach: (fn: () => Promise<void> | void) => void;
26
+ var afterEach: (fn: () => Promise<void> | void) => void;
21
27
  }
22
28
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAEhE,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;AAEvE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,YAAY,CAAA;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,cAAc,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;IACjD,aAAa,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;CACjD;AAmBD,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAED,wBAAgB,WAAW,IAAI,QAAQ,CAItC;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,GAAG,IAAI,CAI3D;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAG9D;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAG7D;AAGD,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,KAAK,IAAI,CAAA;IAEpD,IAAI,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;IAEvD,IAAI,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;CACvD"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAEhE,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;AAEvE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,YAAY,CAAA;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,cAAc,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;IACjD,aAAa,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;IAChD,eAAe,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;IAClD,cAAc,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;CAClD;AAqBD,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAED,wBAAgB,WAAW,IAAI,QAAQ,CAItC;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,GAAG,IAAI,CAI3D;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAG9D;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAG7D;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAG/D;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAG9D;AAGD,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,KAAK,IAAI,CAAA;IAEpD,IAAI,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;IAEvD,IAAI,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;IAEtD,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;IAExD,IAAI,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAA;CACxD"}
@@ -10,6 +10,8 @@ function createEmptyRegistry() {
10
10
  tests: [],
11
11
  beforeAllHooks: [],
12
12
  afterAllHooks: [],
13
+ beforeEachHooks: [],
14
+ afterEachHooks: [],
13
15
  };
14
16
  }
15
17
  export function clearRegistry() {
@@ -34,7 +36,17 @@ export function afterAll(fn) {
34
36
  const registry = getGlobalRegistry();
35
37
  registry.afterAllHooks.push(fn);
36
38
  }
39
+ export function beforeEach(fn) {
40
+ const registry = getGlobalRegistry();
41
+ registry.beforeEachHooks.push(fn);
42
+ }
43
+ export function afterEach(fn) {
44
+ const registry = getGlobalRegistry();
45
+ registry.afterEachHooks.push(fn);
46
+ }
37
47
  globalThis.aiTest = aiTest;
38
48
  globalThis.beforeAll = beforeAll;
39
49
  globalThis.afterAll = afterAll;
50
+ globalThis.beforeEach = beforeEach;
51
+ globalThis.afterEach = afterEach;
40
52
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAeA,MAAM,YAAY,GAAG,0BAA0B,CAAA;AAE/C,SAAS,iBAAiB;IACxB,IAAI,CAAE,UAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;QACtC,UAAkB,CAAC,YAAY,CAAC,GAAG,mBAAmB,EAAE,CAAA;IAC3D,CAAC;IACD,OAAQ,UAAkB,CAAC,YAAY,CAAa,CAAA;AACtD,CAAC;AAED,SAAS,mBAAmB;IAC1B,OAAO;QACL,KAAK,EAAE,EAAE;QACT,cAAc,EAAE,EAAE;QAClB,aAAa,EAAE,EAAE;KAClB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC1B,UAAkB,CAAC,YAAY,CAAC,GAAG,mBAAmB,EAAE,CAAA;IACzD,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAA;AACpE,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,OAAO,CAAC,GAAG,CAAC,kDAAkD,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IAChG,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAY,EAAE,EAAgB;IACnD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IACjC,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAA;AACvD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAA8B;IACtD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAClC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EAA8B;IACrD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACjC,CAAC;AAYD,UAAU,CAAC,MAAM,GAAG,MAAM,CAAA;AAC1B,UAAU,CAAC,SAAS,GAAG,SAAS,CAAA;AAChC,UAAU,CAAC,QAAQ,GAAG,QAAQ,CAAA"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAiBA,MAAM,YAAY,GAAG,0BAA0B,CAAA;AAE/C,SAAS,iBAAiB;IACxB,IAAI,CAAE,UAAkB,CAAC,YAAY,CAAC,EAAE,CAAC;QACtC,UAAkB,CAAC,YAAY,CAAC,GAAG,mBAAmB,EAAE,CAAA;IAC3D,CAAC;IACD,OAAQ,UAAkB,CAAC,YAAY,CAAa,CAAA;AACtD,CAAC;AAED,SAAS,mBAAmB;IAC1B,OAAO;QACL,KAAK,EAAE,EAAE;QACT,cAAc,EAAE,EAAE;QAClB,aAAa,EAAE,EAAE;QACjB,eAAe,EAAE,EAAE;QACnB,cAAc,EAAE,EAAE;KACnB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC1B,UAAkB,CAAC,YAAY,CAAC,GAAG,mBAAmB,EAAE,CAAA;IACzD,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAA;AACpE,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,OAAO,CAAC,GAAG,CAAC,kDAAkD,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IAChG,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAY,EAAE,EAAgB;IACnD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IACjC,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAA;AACvD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAA8B;IACtD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAClC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EAA8B;IACrD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAA8B;IACvD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACnC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAA8B;IACtD,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAClC,CAAC;AAgBD,UAAU,CAAC,MAAM,GAAG,MAAM,CAAA;AAC1B,UAAU,CAAC,SAAS,GAAG,SAAS,CAAA;AAChC,UAAU,CAAC,QAAQ,GAAG,QAAQ,CAAA;AAC9B,UAAU,CAAC,UAAU,GAAG,UAAU,CAAA;AAClC,UAAU,CAAC,SAAS,GAAG,SAAS,CAAA"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { aiTest, beforeAll, afterAll, getRegistry, clearRegistry } from './core/registry.js';
1
+ export { aiTest, beforeAll, afterAll, beforeEach, afterEach, getRegistry, clearRegistry } from './core/registry.js';
2
2
  export { createTraceHandle, startTraceSession, setCurrentTrace, getCurrentTrace } from './trace-adapter/context.js';
3
3
  export { registerMatchers } from './matchers/index.js';
4
4
  export { expect } from './matchers/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC5F,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AACnH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAA;AAC/F,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACnH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AACnH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAA;AAC/F,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Public API surface for programmatic use
2
- export { aiTest, beforeAll, afterAll, getRegistry, clearRegistry } from './core/registry.js';
2
+ export { aiTest, beforeAll, afterAll, beforeEach, afterEach, getRegistry, clearRegistry } from './core/registry.js';
3
3
  export { createTraceHandle, startTraceSession, setCurrentTrace, getCurrentTrace } from './trace-adapter/context.js';
4
4
  export { registerMatchers } from './matchers/index.js';
5
5
  export { expect } from './matchers/index.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAC5F,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AACnH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACnH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AACnH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAA"}