Skip to content

Commit dd4a4ff

Browse files
authored
feat(tests): add new test-agent script for end-to-end testing of the naive pipeline and remove the old test-naive-pipeline script for better organization and clarity (#26)
fix(package.json): update test:agent script path to point to the new test-agent script location
1 parent 71f6066 commit dd4a4ff

File tree

3 files changed

+176
-213
lines changed

3 files changed

+176
-213
lines changed

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@
2020
"test": "jest",
2121
"test:watch": "jest --watch",
2222
"test:coverage": "jest --coverage",
23-
"test:agent": "npx tsx -r dotenv/config lib/llm/test-agent.ts",
24-
"test:naive": "npx tsx -r dotenv/config scripts/test-naive-pipeline.ts",
23+
"test:agent": "npx tsx -r dotenv/config scripts/test-agent.ts",
2524
"test:context": "npx tsx -r dotenv/config scripts/test-context.ts",
2625
"docker:cleanup": "node scripts/cleanup-docker.js"
2726
},

scripts/test-agent.ts

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import { db } from '../lib/db/drizzle';
2+
import { users } from '../lib/db/schema';
3+
import { eq } from 'drizzle-orm';
4+
import { createProject as dbCreateProject, getProjectById } from '../lib/db/projects';
5+
import { Agent } from '../lib/llm/core/agent';
6+
import { getProjectPath, listFilesRecursively } from '../lib/fs/operations';
7+
import { scaffoldProject } from '../lib/fs/scaffold';
8+
9+
/**
10+
* Debug logger function that provides timestamps and colors
11+
*/
12+
const debug = {
13+
log: (message: string, ...args: unknown[]) => {
14+
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
15+
console.log(`[${timestamp}] ${message}`, ...args);
16+
},
17+
info: (message: string, ...args: unknown[]) => {
18+
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
19+
console.log(`[${timestamp}] ℹ️ ${message}`, ...args);
20+
},
21+
success: (message: string, ...args: unknown[]) => {
22+
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
23+
console.log(`[${timestamp}] ✅ ${message}`, ...args);
24+
},
25+
warn: (message: string, ...args: unknown[]) => {
26+
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
27+
console.warn(`[${timestamp}] ⚠️ ${message}`, ...args);
28+
},
29+
error: (message: string, ...args: unknown[]) => {
30+
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
31+
console.error(`[${timestamp}] ❌ ${message}`, ...args);
32+
},
33+
pipeline: (message: string, ...args: unknown[]) => {
34+
const timestamp = new Date().toISOString().split('T')[1].split('.')[0];
35+
console.log(`[${timestamp}] 🚀 PIPELINE: ${message}`, ...args);
36+
},
37+
};
38+
39+
/**
40+
* This script tests the naive pipeline end-to-end by:
41+
* 1. Either using an existing project ID or creating a new test project
42+
* 2. Triggering the naive pipeline with a test prompt
43+
* 3. Directly validating the app/page.tsx contains the expected text
44+
*/
45+
async function main() {
46+
try {
47+
debug.log('🚀 Starting end-to-end test of naive pipeline...');
48+
49+
// Parse command line arguments
50+
const args = process.argv.slice(2);
51+
let projectId: string | undefined;
52+
let testPrompt =
53+
"Change the home page to display a big 'Hello World' in the middle of the page.";
54+
55+
// Check if arguments were provided
56+
if (args.length > 0) {
57+
// First argument could be a project ID
58+
if (/^\d+$/.test(args[0])) {
59+
projectId = args[0];
60+
debug.info(`Using existing project with ID: ${projectId}`);
61+
62+
// If there's a second argument, it's the test prompt
63+
if (args.length > 1) {
64+
testPrompt = args[1];
65+
}
66+
} else {
67+
// If first argument is not a number, treat it as the prompt
68+
testPrompt = args[0];
69+
}
70+
}
71+
72+
debug.log(`💬 Using test prompt: "${testPrompt}"`);
73+
74+
let project;
75+
let projectDirPath;
76+
77+
// Either use existing project or create a new test project
78+
if (projectId) {
79+
// Use existing project
80+
project = await getProjectById(Number(projectId));
81+
82+
if (!project) {
83+
debug.error(`Project with ID ${projectId} not found.`);
84+
process.exit(1);
85+
}
86+
87+
debug.success(`Using existing project: ${project.name} (ID: ${project.id})`);
88+
projectDirPath = getProjectPath(project.id);
89+
} else {
90+
// Create a new test project
91+
// 1. Find the admin user
92+
debug.log('🔍 Looking for [email protected] user...');
93+
const [adminUser] = await db.select().from(users).where(eq(users.email, '[email protected]'));
94+
95+
if (!adminUser) {
96+
debug.error('Admin user not found. Please run the seed script first with: npm run db:seed');
97+
process.exit(1);
98+
}
99+
100+
debug.success(`Found admin user with ID: ${adminUser.id}`);
101+
102+
// 2. Create a test project
103+
const testProjectName = `Test Project ${new Date().toISOString()}`;
104+
debug.log(`📁 Creating test project: ${testProjectName}...`);
105+
106+
// First create the project in the database
107+
debug.info('Creating project in database...');
108+
project = await dbCreateProject({
109+
name: testProjectName,
110+
description: 'Automated test project for testing the naive pipeline',
111+
userId: adminUser.id,
112+
createdBy: adminUser.id,
113+
});
114+
115+
debug.success(`Created project in database with ID: ${project.id}`);
116+
117+
// Then scaffold the project like the real application would
118+
debug.info('Scaffolding project files...');
119+
try {
120+
await scaffoldProject(project.id, testProjectName, {
121+
additionalDependencies: {},
122+
});
123+
debug.success('Project scaffolding completed');
124+
} catch (scaffoldError) {
125+
debug.error('Error scaffolding project:', scaffoldError);
126+
process.exit(1);
127+
}
128+
129+
projectDirPath = getProjectPath(project.id);
130+
131+
// List files in the project directory to verify scaffolding
132+
try {
133+
debug.info('Verifying initial scaffolded files...');
134+
const initialFiles = await listFilesRecursively(projectDirPath);
135+
debug.success(`Initial project has ${initialFiles.length} files from template`);
136+
137+
// Log a few key initial files for verification
138+
const keyInitialFiles = initialFiles.filter(file => {
139+
return (
140+
file.endsWith('package.json') ||
141+
file.endsWith('next.config.js') ||
142+
file.endsWith('README.md')
143+
);
144+
});
145+
debug.info('Key initial files:', keyInitialFiles);
146+
} catch (listError) {
147+
debug.warn('Could not list initial files:', listError);
148+
}
149+
}
150+
151+
// 3. Trigger the naive pipeline directly without saving messages to the database
152+
debug.pipeline('Initializing naive pipeline agent...');
153+
const agent = new Agent(project.id);
154+
155+
debug.pipeline('Running agent with prompt...');
156+
157+
// Start pipeline execution with timeout monitoring
158+
const startTime = Date.now();
159+
const result = await agent.run(testPrompt);
160+
const endTime = Date.now();
161+
debug.success(
162+
`Agent run completed in ${(endTime - startTime) / 1000}s with result: ${JSON.stringify(result)}`
163+
);
164+
process.exit(0);
165+
} catch (error) {
166+
debug.error('Error during test:', error);
167+
process.exit(1);
168+
}
169+
}
170+
171+
// Run the test
172+
main().catch(error => {
173+
console.error('❌ Fatal error:', error);
174+
process.exit(1);
175+
});

scripts/test-naive-pipeline.ts

Lines changed: 0 additions & 211 deletions
This file was deleted.

0 commit comments

Comments
 (0)