sf-agent-framework
Version:
AI Agent Orchestration Framework for Salesforce Development - Two-phase architecture with 70% context reduction
366 lines (305 loc) • 12.3 kB
JavaScript
/**
* Integration Test for Simulation Engine
* Tests the complete simulation flow with actual workflows and agents
*/
const path = require('path');
const fs = require('fs').promises;
const yaml = require('js-yaml');
const { OrchestratorSimulation, SimulationCommands } = require('./index');
// ANSI color codes for output
const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
cyan: '\x1b[36m',
};
class IntegrationTest {
constructor() {
this.testResults = [];
this.orchestratorSim = null;
}
/**
* Run all integration tests
*/
async runAllTests() {
console.log(`${colors.cyan}${colors.bright}
╔══════════════════════════════════════════════════════════════════════════╗
║ SIMULATION ENGINE INTEGRATION TEST SUITE ║
╚══════════════════════════════════════════════════════════════════════════╝
${colors.reset}`);
try {
// Test 1: Initialize Simulation
await this.testInitialization();
// Test 2: Load Real Workflow
await this.testWorkflowLoading();
// Test 3: Team Generation
await this.testTeamGeneration();
// Test 4: Progress Tracking
await this.testProgressTracking();
// Test 5: Error Handling
await this.testErrorHandling();
// Test 6: Command Controls
await this.testCommandControls();
// Test 7: Full Workflow Simulation
await this.testFullWorkflowSimulation();
// Show results
this.showTestResults();
} catch (error) {
console.error(`${colors.red}Test suite failed: ${error.message}${colors.reset}`);
process.exit(1);
}
}
/**
* Test 1: Simulation Initialization
*/
async testInitialization() {
console.log(`\n${colors.yellow}Test 1: Simulation Initialization${colors.reset}`);
try {
this.orchestratorSim = new OrchestratorSimulation('sf-orchestrator', {
enabled: true,
visualizationType: 'text', // Use text for cleaner test output
realTimeSync: true,
});
await this.orchestratorSim.initialize();
if (this.orchestratorSim.isEnabled()) {
this.addResult('Initialization', true, 'Simulation engine initialized successfully');
} else {
this.addResult('Initialization', false, 'Simulation not enabled');
}
} catch (error) {
this.addResult('Initialization', false, error.message);
}
}
/**
* Test 2: Load Real Workflow
*/
async testWorkflowLoading() {
console.log(`\n${colors.yellow}Test 2: Loading Real Workflow${colors.reset}`);
try {
// Load actual workflow from sf-core
const workflowPath = path.join(__dirname, '..', 'workflows', 'security-audit-workflow.yaml');
const workflowContent = await fs.readFile(workflowPath, 'utf8');
const workflowData = yaml.load(workflowContent);
if (workflowData && workflowData.workflow) {
this.workflowData = workflowData.workflow;
this.addResult('Workflow Loading', true, `Loaded: ${this.workflowData.name}`);
} else {
throw new Error('Invalid workflow structure');
}
} catch (error) {
this.addResult('Workflow Loading', false, error.message);
}
}
/**
* Test 3: Team Generation from Real Agents
*/
async testTeamGeneration() {
console.log(`\n${colors.yellow}Test 3: Virtual Team Generation${colors.reset}`);
try {
// Load actual team configuration
const teamPath = path.join(__dirname, '..', 'agent-teams', 'salesforce-core-team.yaml');
const teamContent = await fs.readFile(teamPath, 'utf8');
const teamData = yaml.load(teamContent);
// Extract first few agents for testing
const testTeam = {
name: teamData.bundle.name,
agents: teamData.agents.slice(0, 4), // Use first 4 agents
};
// Start workflow with team
const workflow = await this.orchestratorSim.startWorkflow(this.workflowData, testTeam);
this.workflowHandle = workflow;
if (workflow.simulation && workflow.simulation.team) {
const teamSize = workflow.simulation.team.length;
this.addResult('Team Generation', true, `Generated ${teamSize} virtual team members`);
// Show team members
console.log(' Generated team members:');
workflow.simulation.team.forEach((member) => {
console.log(` ${member.icon} ${member.name} - ${member.role}`);
});
} else {
throw new Error('No team generated');
}
} catch (error) {
this.addResult('Team Generation', false, error.message);
}
}
/**
* Test 4: Progress Tracking with Real Updates
*/
async testProgressTracking() {
console.log(`\n${colors.yellow}Test 4: Progress Tracking${colors.reset}`);
if (!this.workflowHandle) {
this.addResult('Progress Tracking', false, 'No workflow handle available');
return;
}
try {
// Simulate real progress updates
const progressUpdates = [
{ phase: 'audit_preparation', progress: 10 },
{ task: { name: 'scope_definition', agent: 'sf-security', progress: 50 } },
{ completedTask: { name: 'scope_definition' }, progress: 25 },
{ task: { name: 'information_gathering', agent: 'sf-security', progress: 100 } },
{ completedTask: { name: 'information_gathering' }, progress: 50 },
{ phase: 'security_assessment', progress: 60 },
{ progress: 100, status: 'complete' },
];
for (const update of progressUpdates) {
this.workflowHandle.updateProgress(update);
await this.delay(500); // Small delay between updates
}
this.addResult('Progress Tracking', true, 'All progress updates processed');
} catch (error) {
this.addResult('Progress Tracking', false, error.message);
}
}
/**
* Test 5: Error Handling
*/
async testErrorHandling() {
console.log(`\n${colors.yellow}Test 5: Error Handling${colors.reset}`);
try {
// Create a new workflow for error testing
const errorWorkflow = await this.orchestratorSim.startWorkflow(
{ name: 'Error Test Workflow', id: 'error-test' },
{ name: 'test-team', agents: ['sf-admin'] }
);
// Simulate an error
errorWorkflow.error(new Error('Test error: Security validation failed'));
// Give time for error to be processed
await this.delay(1000);
this.addResult('Error Handling', true, 'Error handled correctly');
} catch (error) {
this.addResult('Error Handling', false, error.message);
}
}
/**
* Test 6: Command Controls
*/
async testCommandControls() {
console.log(`\n${colors.yellow}Test 6: Simulation Commands${colors.reset}`);
try {
const commands = new SimulationCommands();
// Test various commands
const tests = [
{ cmd: 'simulation-status', expected: 'object' },
{ cmd: 'simulation-visual', args: ['ascii'], expected: 'string' },
{ cmd: 'simulation-off', expected: 'string' },
{ cmd: 'simulation-on', expected: 'string' },
];
let allPassed = true;
for (const test of tests) {
const result = await commands.handleCommand(test.cmd, test.args);
if (typeof result !== test.expected) {
allPassed = false;
console.log(` ❌ Command ${test.cmd} failed`);
} else {
console.log(` ✅ Command ${test.cmd} passed`);
}
}
if (allPassed) {
this.addResult('Command Controls', true, 'All commands working');
} else {
this.addResult('Command Controls', false, 'Some commands failed');
}
} catch (error) {
this.addResult('Command Controls', false, error.message);
}
}
/**
* Test 7: Full Workflow Simulation
*/
async testFullWorkflowSimulation() {
console.log(`\n${colors.yellow}Test 7: Full Workflow Simulation${colors.reset}`);
try {
// Re-enable simulation with ASCII visualization
this.orchestratorSim.toggle(true);
this.orchestratorSim.engine.options.visualizationType = 'ascii';
// Load agile sprint workflow for variety
const sprintPath = path.join(__dirname, '..', 'workflows', 'agile-sprint.yaml');
const sprintContent = await fs.readFile(sprintPath, 'utf8');
const sprintData = yaml.load(sprintContent);
// Use deployment team
const deployTeam = {
name: 'deployment-team',
agents: ['sf-devops', 'sf-qa', 'sf-developer', 'sf-admin'],
};
console.log('\n Starting Agile Sprint workflow with full visualization...\n');
const sprintWorkflow = await this.orchestratorSim.startWorkflow(
sprintData.workflow,
deployTeam
);
// Simulate sprint progress
const sprintUpdates = [
{ phase: 'sprint_planning', task: { name: 'Story refinement', progress: 25 } },
{ task: { name: 'Story refinement', progress: 100 } },
{ phase: 'development', task: { name: 'Feature development', progress: 50 } },
{ task: { name: 'Testing', progress: 30 } },
{ completedTask: { name: 'Feature development' } },
{ completedTask: { name: 'Testing' } },
{ phase: 'review', progress: 90 },
{ progress: 100, status: 'complete', result: 'Sprint completed successfully!' },
];
for (const update of sprintUpdates) {
sprintWorkflow.updateProgress(update);
await this.delay(1500);
}
this.addResult('Full Workflow', true, 'Complete workflow simulated');
} catch (error) {
this.addResult('Full Workflow', false, error.message);
}
}
/**
* Helper: Add test result
*/
addResult(testName, passed, message) {
this.testResults.push({ testName, passed, message });
const icon = passed ? `${colors.green}✅` : `${colors.red}❌`;
console.log(` ${icon} ${testName}: ${message}${colors.reset}`);
}
/**
* Helper: Delay function
*/
delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Show final test results
*/
showTestResults() {
console.log(`\n${colors.cyan}${colors.bright}
╔══════════════════════════════════════════════════════════════════════════╗
║ TEST RESULTS SUMMARY ║
╚══════════════════════════════════════════════════════════════════════════╝
${colors.reset}`);
const passed = this.testResults.filter((r) => r.passed).length;
const failed = this.testResults.filter((r) => !r.passed).length;
const total = this.testResults.length;
this.testResults.forEach((result) => {
const icon = result.passed ? `${colors.green}✅` : `${colors.red}❌`;
const status = result.passed ? `${colors.green}PASSED` : `${colors.red}FAILED`;
console.log(` ${icon} ${result.testName.padEnd(20)} ${status}${colors.reset}`);
});
console.log(
`\n ${colors.bright}Total: ${total} | Passed: ${colors.green}${passed}${colors.reset}${colors.bright} | Failed: ${colors.red}${failed}${colors.reset}`
);
if (failed === 0) {
console.log(
`\n${colors.green}${colors.bright}🎉 All tests passed! The simulation engine is working correctly.${colors.reset}`
);
} else {
console.log(
`\n${colors.yellow}⚠️ Some tests failed. Please review the output above.${colors.reset}`
);
}
}
}
// Run the integration test
if (require.main === module) {
const test = new IntegrationTest();
test.runAllTests().catch(console.error);
}
module.exports = IntegrationTest;