tryassay 0.20.3 → 0.21.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.
@@ -0,0 +1,545 @@
1
+ // ============================================================
2
+ // Functional Tester — HTTP-level testing of generated apps
3
+ // Starts the dev server, generates tests from the architecture plan,
4
+ // runs them via fetch(), and feeds failures to CodeAgent for repair.
5
+ // ============================================================
6
+ import { spawn } from 'node:child_process';
7
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
8
+ import { join, dirname } from 'node:path';
9
+ import { randomUUID } from 'node:crypto';
10
+ import { CodeAgent } from './agents/code-agent.js';
11
+ import { MessageBus } from './message-bus.js';
12
+ // ── Functional Tester ────────────────────────────────────────
13
+ export class FunctionalTester {
14
+ projectPath;
15
+ plan;
16
+ maxRepairAttempts;
17
+ testTimeoutMs;
18
+ serverStartTimeoutMs;
19
+ codeModel;
20
+ framework;
21
+ constructor(projectPath, plan, options) {
22
+ this.projectPath = projectPath;
23
+ this.plan = plan;
24
+ this.maxRepairAttempts = options?.maxRepairAttempts ?? 3;
25
+ this.testTimeoutMs = options?.testTimeoutMs ?? 10_000;
26
+ this.serverStartTimeoutMs = options?.serverStartTimeoutMs ?? 30_000;
27
+ this.codeModel = options?.codeModel;
28
+ this.framework = (options?.framework ?? 'next.js').toLowerCase();
29
+ }
30
+ /** Run functional tests with repair loop. */
31
+ async test() {
32
+ const start = Date.now();
33
+ // Skip for Electron (no HTTP server)
34
+ if (this.framework === 'electron') {
35
+ return {
36
+ status: 'skipped',
37
+ tests: [],
38
+ passedCount: 0,
39
+ failedCount: 0,
40
+ repairAttempts: [],
41
+ serverPort: null,
42
+ totalDurationMs: Date.now() - start,
43
+ };
44
+ }
45
+ // Generate test cases from the plan
46
+ const tests = this.generateTests();
47
+ if (tests.length === 0) {
48
+ return {
49
+ status: 'skipped',
50
+ tests: [],
51
+ passedCount: 0,
52
+ failedCount: 0,
53
+ repairAttempts: [],
54
+ serverPort: null,
55
+ totalDurationMs: Date.now() - start,
56
+ };
57
+ }
58
+ // Start dev server
59
+ let serverProcess = null;
60
+ let port = null;
61
+ try {
62
+ const serverInfo = await this.startDevServer();
63
+ serverProcess = serverInfo.process;
64
+ port = serverInfo.port;
65
+ }
66
+ catch (err) {
67
+ // Server failed to start — return fail with no tests run
68
+ return {
69
+ status: 'fail',
70
+ tests: [],
71
+ passedCount: 0,
72
+ failedCount: 0,
73
+ repairAttempts: [],
74
+ serverPort: null,
75
+ totalDurationMs: Date.now() - start,
76
+ };
77
+ }
78
+ try {
79
+ // Run tests
80
+ let executions = await this.runTests(tests, port);
81
+ const repairAttempts = [];
82
+ let failures = executions.filter(e => e.status !== 'pass');
83
+ let attempt = 0;
84
+ // Repair loop
85
+ while (failures.length > 0 && attempt < this.maxRepairAttempts) {
86
+ attempt++;
87
+ const repairStart = Date.now();
88
+ const repairResult = await this.runRepair(failures, port);
89
+ repairAttempts.push({
90
+ attempt,
91
+ failures,
92
+ filesModified: repairResult.filesModified,
93
+ repairSucceeded: repairResult.filesModified.length > 0,
94
+ durationMs: Date.now() - repairStart,
95
+ });
96
+ if (repairResult.filesModified.length === 0) {
97
+ break; // Repair couldn't modify anything, stop trying
98
+ }
99
+ // Re-run only failed tests
100
+ const failedTests = failures.map(f => f.test);
101
+ executions = [
102
+ ...executions.filter(e => e.status === 'pass'),
103
+ ...await this.runTests(failedTests, port),
104
+ ];
105
+ failures = executions.filter(e => e.status !== 'pass');
106
+ }
107
+ const passedCount = executions.filter(e => e.status === 'pass').length;
108
+ const failedCount = executions.filter(e => e.status !== 'pass').length;
109
+ const status = failedCount === 0 ? (repairAttempts.length > 0 ? 'repaired' : 'pass') : 'fail';
110
+ return {
111
+ status,
112
+ tests: executions,
113
+ passedCount,
114
+ failedCount,
115
+ repairAttempts,
116
+ serverPort: port,
117
+ totalDurationMs: Date.now() - start,
118
+ };
119
+ }
120
+ finally {
121
+ // Always kill the server
122
+ if (serverProcess) {
123
+ serverProcess.kill('SIGTERM');
124
+ // Give it a moment, then force kill
125
+ setTimeout(() => {
126
+ if (serverProcess && !serverProcess.killed) {
127
+ serverProcess.kill('SIGKILL');
128
+ }
129
+ }, 3000);
130
+ }
131
+ }
132
+ }
133
+ // ── Test Generation ──────────────────────────────────────────
134
+ /** Generate test cases from the architecture plan. */
135
+ generateTests() {
136
+ const tests = [];
137
+ // API route tests
138
+ for (const route of this.plan.apiRoutes) {
139
+ const body = route.method !== 'GET' && route.method !== 'DELETE'
140
+ ? this.generateSamplePayload(route.path, route.featureId)
141
+ : undefined;
142
+ tests.push({
143
+ id: `api-${route.method.toLowerCase()}-${route.path.replace(/\//g, '-')}`,
144
+ type: 'api_route',
145
+ name: `${route.method} ${route.path}`,
146
+ method: route.method,
147
+ path: route.path,
148
+ body,
149
+ expectedStatusRange: [200, 499], // 2xx-4xx are valid responses; 5xx = server error
150
+ errorPatterns: [
151
+ 'Internal Server Error',
152
+ 'TypeError',
153
+ 'ReferenceError',
154
+ 'Cannot read properties of',
155
+ 'is not a function',
156
+ 'ECONNREFUSED',
157
+ 'MODULE_NOT_FOUND',
158
+ ],
159
+ featureId: route.featureId,
160
+ });
161
+ }
162
+ // Page load tests
163
+ for (const page of this.plan.pages) {
164
+ tests.push({
165
+ id: `page-${page.path.replace(/\//g, '-') || 'root'}`,
166
+ type: 'page_load',
167
+ name: `GET ${page.path || '/'}`,
168
+ method: 'GET',
169
+ path: page.path || '/',
170
+ expectedStatusRange: [200, 399], // Pages should return 2xx or redirect
171
+ errorPatterns: [
172
+ 'Internal Server Error',
173
+ 'Application error',
174
+ 'Error: ',
175
+ 'TypeError',
176
+ 'Unhandled Runtime Error',
177
+ 'Module not found',
178
+ '500',
179
+ ],
180
+ featureId: page.featureId,
181
+ });
182
+ }
183
+ // Auth flow tests (if auth is configured)
184
+ if (this.plan.authPlan) {
185
+ // Test signup route exists and doesn't crash
186
+ const signupRoutes = this.plan.apiRoutes.filter(r => r.path.includes('signup') || r.path.includes('register'));
187
+ for (const route of signupRoutes) {
188
+ tests.push({
189
+ id: `auth-signup-${route.path.replace(/\//g, '-')}`,
190
+ type: 'auth_flow',
191
+ name: `Auth: POST ${route.path}`,
192
+ method: 'POST',
193
+ path: route.path,
194
+ body: {
195
+ email: 'test@example.com',
196
+ password: 'TestPassword123!',
197
+ },
198
+ expectedStatusRange: [200, 499], // Auth may return 4xx for duplicate etc
199
+ errorPatterns: [
200
+ 'Internal Server Error',
201
+ 'TypeError',
202
+ 'Cannot read properties of',
203
+ 'ECONNREFUSED',
204
+ ],
205
+ featureId: route.featureId,
206
+ });
207
+ }
208
+ // Test login route
209
+ const loginRoutes = this.plan.apiRoutes.filter(r => r.path.includes('login') || r.path.includes('signin'));
210
+ for (const route of loginRoutes) {
211
+ tests.push({
212
+ id: `auth-login-${route.path.replace(/\//g, '-')}`,
213
+ type: 'auth_flow',
214
+ name: `Auth: POST ${route.path}`,
215
+ method: 'POST',
216
+ path: route.path,
217
+ body: {
218
+ email: 'test@example.com',
219
+ password: 'TestPassword123!',
220
+ },
221
+ expectedStatusRange: [200, 499],
222
+ errorPatterns: [
223
+ 'Internal Server Error',
224
+ 'TypeError',
225
+ 'Cannot read properties of',
226
+ 'ECONNREFUSED',
227
+ ],
228
+ featureId: route.featureId,
229
+ });
230
+ }
231
+ }
232
+ return tests;
233
+ }
234
+ /** Generate a minimal sample payload for a POST/PUT route based on schema. */
235
+ generateSamplePayload(routePath, featureId) {
236
+ // Try to find the schema entity for this feature
237
+ if (featureId) {
238
+ const feature = this.plan.features.find(f => f.id === featureId);
239
+ if (feature && feature.schemaEntities.length > 0) {
240
+ const entityName = feature.schemaEntities[0];
241
+ const entity = this.plan.schema.find(e => e.name === entityName);
242
+ if (entity) {
243
+ const payload = {};
244
+ for (const field of entity.fields) {
245
+ if (field.primaryKey)
246
+ continue; // Skip auto-generated IDs
247
+ if (field.name === 'created_at' || field.name === 'updated_at')
248
+ continue;
249
+ payload[field.name] = this.sampleValueForType(field.type, field.name);
250
+ }
251
+ return payload;
252
+ }
253
+ }
254
+ }
255
+ // Fallback: extract resource name from path
256
+ const parts = routePath.split('/').filter(Boolean);
257
+ const resource = parts[parts.length - 1] ?? 'item';
258
+ return {
259
+ name: `Test ${resource}`,
260
+ description: `Test ${resource} description`,
261
+ };
262
+ }
263
+ /** Generate a sample value for a schema field type. */
264
+ sampleValueForType(type, name) {
265
+ const t = type.toLowerCase();
266
+ if (t.includes('int') || t.includes('number') || t.includes('decimal') || t.includes('float'))
267
+ return 42;
268
+ if (t.includes('bool'))
269
+ return true;
270
+ if (t.includes('date') || t.includes('timestamp'))
271
+ return new Date().toISOString();
272
+ if (t.includes('json') || t.includes('object'))
273
+ return {};
274
+ if (t.includes('array'))
275
+ return [];
276
+ // String types
277
+ if (name.includes('email'))
278
+ return 'test@example.com';
279
+ if (name.includes('url'))
280
+ return 'https://example.com';
281
+ if (name.includes('phone'))
282
+ return '+12025551234';
283
+ return `test-${name}`;
284
+ }
285
+ // ── Server Management ────────────────────────────────────────
286
+ /** Start the dev server and detect the port. */
287
+ startDevServer() {
288
+ return new Promise((resolve, reject) => {
289
+ const command = this.framework.includes('next') ? 'npx' : 'npm';
290
+ const args = this.framework.includes('next')
291
+ ? ['next', 'dev', '--port', '0'] // port 0 = auto-assign
292
+ : ['run', 'dev'];
293
+ const proc = spawn(command, args, {
294
+ cwd: this.projectPath,
295
+ env: { ...process.env, NODE_ENV: 'development', PORT: '0' },
296
+ stdio: ['ignore', 'pipe', 'pipe'],
297
+ });
298
+ let stdout = '';
299
+ let stderr = '';
300
+ let resolved = false;
301
+ const timeout = setTimeout(() => {
302
+ if (!resolved) {
303
+ resolved = true;
304
+ proc.kill('SIGTERM');
305
+ reject(new Error(`Server failed to start within ${this.serverStartTimeoutMs}ms. stdout: ${stdout.slice(-500)}, stderr: ${stderr.slice(-500)}`));
306
+ }
307
+ }, this.serverStartTimeoutMs);
308
+ const tryExtractPort = (data) => {
309
+ if (resolved)
310
+ return;
311
+ // Match common patterns: "localhost:3000", "port 3000", ":3000"
312
+ const portMatch = data.match(/(?:localhost|127\.0\.0\.1|0\.0\.0\.0):(\d+)/i)
313
+ ?? data.match(/port\s+(\d+)/i)
314
+ ?? data.match(/:(\d{4,5})\b/);
315
+ if (portMatch) {
316
+ const port = parseInt(portMatch[1], 10);
317
+ if (port > 0 && port < 65536) {
318
+ resolved = true;
319
+ clearTimeout(timeout);
320
+ resolve({ process: proc, port });
321
+ }
322
+ }
323
+ };
324
+ proc.stdout?.on('data', (chunk) => {
325
+ const data = chunk.toString();
326
+ stdout += data;
327
+ tryExtractPort(data);
328
+ });
329
+ proc.stderr?.on('data', (chunk) => {
330
+ const data = chunk.toString();
331
+ stderr += data;
332
+ tryExtractPort(data);
333
+ });
334
+ proc.on('error', (err) => {
335
+ if (!resolved) {
336
+ resolved = true;
337
+ clearTimeout(timeout);
338
+ reject(err);
339
+ }
340
+ });
341
+ proc.on('exit', (code) => {
342
+ if (!resolved) {
343
+ resolved = true;
344
+ clearTimeout(timeout);
345
+ reject(new Error(`Server exited with code ${code} before starting. stderr: ${stderr.slice(-500)}`));
346
+ }
347
+ });
348
+ });
349
+ }
350
+ // ── Test Execution ───────────────────────────────────────────
351
+ /** Run a batch of functional tests against the running server. */
352
+ async runTests(tests, port) {
353
+ const results = [];
354
+ for (const test of tests) {
355
+ const execution = await this.runSingleTest(test, port);
356
+ results.push(execution);
357
+ }
358
+ return results;
359
+ }
360
+ /** Run a single functional test. */
361
+ async runSingleTest(test, port) {
362
+ const url = `http://localhost:${port}${test.path}`;
363
+ const start = Date.now();
364
+ try {
365
+ const controller = new AbortController();
366
+ const timeoutId = setTimeout(() => controller.abort(), this.testTimeoutMs);
367
+ const fetchOptions = {
368
+ method: test.method ?? 'GET',
369
+ signal: controller.signal,
370
+ headers: {
371
+ 'Content-Type': 'application/json',
372
+ 'Accept': 'application/json, text/html',
373
+ },
374
+ };
375
+ if (test.body && test.method !== 'GET') {
376
+ fetchOptions.body = JSON.stringify(test.body);
377
+ }
378
+ const response = await fetch(url, fetchOptions);
379
+ clearTimeout(timeoutId);
380
+ const statusCode = response.status;
381
+ let responseBody;
382
+ try {
383
+ responseBody = await response.text();
384
+ }
385
+ catch {
386
+ responseBody = '';
387
+ }
388
+ // Check status code range
389
+ const [minStatus, maxStatus] = test.expectedStatusRange;
390
+ if (statusCode < minStatus || statusCode > maxStatus) {
391
+ return {
392
+ test,
393
+ status: 'fail',
394
+ statusCode,
395
+ responseBody: responseBody.slice(0, 2000),
396
+ errorMatch: `Status ${statusCode} outside expected range [${minStatus}, ${maxStatus}]`,
397
+ durationMs: Date.now() - start,
398
+ };
399
+ }
400
+ // Check for 5xx errors specifically (server bugs)
401
+ if (statusCode >= 500) {
402
+ return {
403
+ test,
404
+ status: 'fail',
405
+ statusCode,
406
+ responseBody: responseBody.slice(0, 2000),
407
+ errorMatch: `Server error: ${statusCode}`,
408
+ durationMs: Date.now() - start,
409
+ };
410
+ }
411
+ // Check response body for error patterns
412
+ for (const pattern of test.errorPatterns) {
413
+ if (responseBody.includes(pattern)) {
414
+ return {
415
+ test,
416
+ status: 'fail',
417
+ statusCode,
418
+ responseBody: responseBody.slice(0, 2000),
419
+ errorMatch: `Response contains error pattern: "${pattern}"`,
420
+ durationMs: Date.now() - start,
421
+ };
422
+ }
423
+ }
424
+ return {
425
+ test,
426
+ status: 'pass',
427
+ statusCode,
428
+ responseBody: responseBody.slice(0, 500),
429
+ durationMs: Date.now() - start,
430
+ };
431
+ }
432
+ catch (err) {
433
+ if (err instanceof Error && err.name === 'AbortError') {
434
+ return {
435
+ test,
436
+ status: 'timeout',
437
+ statusCode: null,
438
+ responseBody: '',
439
+ errorMatch: `Request timed out after ${this.testTimeoutMs}ms`,
440
+ durationMs: Date.now() - start,
441
+ };
442
+ }
443
+ return {
444
+ test,
445
+ status: 'error',
446
+ statusCode: null,
447
+ responseBody: '',
448
+ errorMatch: err instanceof Error ? err.message : String(err),
449
+ durationMs: Date.now() - start,
450
+ };
451
+ }
452
+ }
453
+ // ── Repair Loop ──────────────────────────────────────────────
454
+ /** Feed test failures to CodeAgent for repair. */
455
+ async runRepair(failures, port) {
456
+ const filesModified = [];
457
+ // Group failures by feature to batch repairs
458
+ const failuresByFeature = new Map();
459
+ for (const failure of failures) {
460
+ const featureId = failure.test.featureId ?? 'unknown';
461
+ const existing = failuresByFeature.get(featureId) ?? [];
462
+ existing.push(failure);
463
+ failuresByFeature.set(featureId, existing);
464
+ }
465
+ for (const [featureId, featureFailures] of failuresByFeature) {
466
+ // Build the repair goal with failure details
467
+ const failureDetails = featureFailures.map(f => {
468
+ return `- ${f.test.name}: ${f.status} — ${f.errorMatch ?? 'Unknown error'}
469
+ Status code: ${f.statusCode ?? 'N/A'}
470
+ Response: ${f.responseBody.slice(0, 500)}`;
471
+ }).join('\n');
472
+ // Try to read the source files for the failing routes/pages
473
+ const sourceContext = await this.readFailingSourceFiles(featureFailures);
474
+ const repairGoal = `Fix functional test failures in the generated application.
475
+
476
+ The following HTTP tests failed against the running dev server:
477
+
478
+ ${failureDetails}
479
+
480
+ ${sourceContext ? `Current source code for the failing endpoints:\n\n${sourceContext}` : ''}
481
+
482
+ Fix the code so these endpoints return valid responses without server errors.
483
+ Do NOT add placeholder stubs — implement the actual logic.
484
+ The dev server is running at http://localhost:${port}.`;
485
+ const messageBus = new MessageBus();
486
+ const codeAgent = new CodeAgent(messageBus, { model: this.codeModel });
487
+ try {
488
+ const result = await codeAgent.executeTask({
489
+ taskId: `repair-${featureId}-${randomUUID().slice(0, 8)}`,
490
+ goal: repairGoal,
491
+ constraints: [
492
+ `Framework: ${this.framework}`,
493
+ 'Fix the actual bug — do not add stubs or TODO comments',
494
+ ],
495
+ dependencies: [],
496
+ contextRefs: [],
497
+ });
498
+ if (result.status === 'completed' && result.artifacts.length > 0) {
499
+ for (const artifact of result.artifacts) {
500
+ if (!artifact.path)
501
+ continue;
502
+ const absPath = join(this.projectPath, artifact.path);
503
+ try {
504
+ await mkdir(dirname(absPath), { recursive: true });
505
+ await writeFile(absPath, artifact.content, 'utf-8');
506
+ filesModified.push(artifact.path);
507
+ }
508
+ catch {
509
+ // Best-effort write
510
+ }
511
+ }
512
+ }
513
+ }
514
+ catch {
515
+ // Repair agent failed — continue with remaining features
516
+ }
517
+ }
518
+ return { filesModified };
519
+ }
520
+ /** Read source files for failing test endpoints. */
521
+ async readFailingSourceFiles(failures) {
522
+ const sections = [];
523
+ for (const failure of failures) {
524
+ const path = failure.test.path;
525
+ const filePath = this.routeToFilePath(path);
526
+ try {
527
+ const content = await readFile(join(this.projectPath, filePath), 'utf-8');
528
+ sections.push(`--- ${filePath} ---\n${content}\n`);
529
+ }
530
+ catch {
531
+ // File doesn't exist
532
+ }
533
+ }
534
+ return sections.join('\n');
535
+ }
536
+ /** Map a route path to its expected file path (mirrors orchestrator logic). */
537
+ routeToFilePath(routePath) {
538
+ if (this.framework.includes('next')) {
539
+ return `app${routePath}/route.ts`;
540
+ }
541
+ const parts = routePath.replace(/^\/api/, '').replace(/^\//, '');
542
+ return `src/routes/${parts || 'index'}.ts`;
543
+ }
544
+ }
545
+ //# sourceMappingURL=functional-tester.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functional-tester.js","sourceRoot":"","sources":["../../src/runtime/functional-tester.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { AppDescription, ArchitecturePlan, PlanSummary, PlanModification } from './types.js';
2
+ export declare class PlanRefiner {
3
+ private description;
4
+ constructor(description: AppDescription);
5
+ /** Generate a human-readable summary of the architecture plan. */
6
+ generateSummary(plan: ArchitecturePlan): PlanSummary;
7
+ /** Validate plan against heuristics. Returns warnings that should block auto-approval. */
8
+ validatePlan(plan: ArchitecturePlan): {
9
+ valid: boolean;
10
+ warnings: string[];
11
+ };
12
+ /** Apply modifications to a plan (e.g., remove features). Returns a new plan object. */
13
+ applyModifications(plan: ArchitecturePlan, modifications: readonly PlanModification[]): ArchitecturePlan;
14
+ }