Skip to main content
Glama

mcp-github-project-manager

#!/usr/bin/env node /** * Comprehensive E2E Test Runner for MCP Tools * * This script provides an easy way to run the comprehensive E2E test suite * with various options and configurations. */ import { spawn } from 'child_process'; import { existsSync } from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // ANSI color codes for console output const colors = { reset: '\x1b[0m', bright: '\x1b[1m', red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', magenta: '\x1b[35m', cyan: '\x1b[36m' }; function colorize(text, color) { return `${colors[color]}${text}${colors.reset}`; } function printHeader() { console.log(colorize('\n🧪 MCP Tools Comprehensive E2E Test Runner', 'cyan')); console.log(colorize('=' .repeat(50), 'cyan')); } function printUsage() { console.log(colorize('\nUsage:', 'bright')); console.log(' node scripts/run-e2e-tests.js [options]'); console.log(colorize('\nOptions:', 'bright')); console.log(' --help, -h Show this help message'); console.log(' --real-api Use real APIs instead of mocks'); console.log(' --github-only Run only GitHub tool tests'); console.log(' --ai-only Run only AI tool tests'); console.log(' --workflows-only Run only workflow integration tests'); console.log(' --build Build the project before running tests'); console.log(' --verbose Enable verbose output'); console.log(' --timeout <seconds> Set test timeout (default: 60)'); console.log(colorize('\nExamples:', 'bright')); console.log(' node scripts/run-e2e-tests.js'); console.log(' node scripts/run-e2e-tests.js --real-api --github-only'); console.log(' node scripts/run-e2e-tests.js --build --verbose'); console.log(' node scripts/run-e2e-tests.js --ai-only --timeout 120'); } function checkEnvironment() { console.log(colorize('\n🔍 Checking Environment...', 'yellow')); // Check if build exists const buildPath = path.join(process.cwd(), 'build', 'index.js'); if (!existsSync(buildPath)) { console.log(colorize('⚠️ Build not found. Run with --build flag or run "npm run build" first.', 'yellow')); return false; } // Check environment variables const requiredEnvVars = ['GITHUB_TOKEN', 'GITHUB_OWNER', 'GITHUB_REPO']; const missingVars = requiredEnvVars.filter(varName => !process.env[varName]); if (missingVars.length > 0) { console.log(colorize(`⚠️ Missing environment variables: ${missingVars.join(', ')}`, 'yellow')); console.log(colorize(' Tests will run with mock values.', 'yellow')); } // Check AI API keys const aiKeys = ['ANTHROPIC_API_KEY', 'OPENAI_API_KEY', 'GOOGLE_API_KEY', 'PERPLEXITY_API_KEY']; const hasAIKey = aiKeys.some(key => process.env[key]); if (!hasAIKey) { console.log(colorize('⚠️ No AI API keys found. AI tests will use mock responses.', 'yellow')); } console.log(colorize('✅ Environment check complete.', 'green')); return true; } async function runCommand(command, args, options = {}) { return new Promise((resolve, reject) => { console.log(colorize(`\n🚀 Running: ${command} ${args.join(' ')}`, 'blue')); const child = spawn(command, args, { stdio: 'inherit', shell: true, ...options }); child.on('close', (code) => { if (code === 0) { resolve(); } else { reject(new Error(`Command failed with exit code ${code}`)); } }); child.on('error', (error) => { reject(error); }); }); } async function buildProject() { console.log(colorize('\n🔨 Building project...', 'yellow')); try { await runCommand('npm', ['run', 'build']); console.log(colorize('✅ Build completed successfully.', 'green')); } catch (error) { console.error(colorize('❌ Build failed:', 'red'), error.message); process.exit(1); } } function parseArgs() { const args = process.argv.slice(2); const options = { help: false, realApi: false, githubOnly: false, aiOnly: false, workflowsOnly: false, build: false, verbose: false, timeout: 60 }; for (let i = 0; i < args.length; i++) { const arg = args[i]; switch (arg) { case '--help': case '-h': options.help = true; break; case '--real-api': options.realApi = true; break; case '--github-only': options.githubOnly = true; break; case '--ai-only': options.aiOnly = true; break; case '--workflows-only': options.workflowsOnly = true; break; case '--build': options.build = true; break; case '--verbose': options.verbose = true; break; case '--timeout': if (i + 1 < args.length) { options.timeout = parseInt(args[i + 1], 10); i++; // Skip next argument } break; default: console.log(colorize(`⚠️ Unknown option: ${arg}`, 'yellow')); } } return options; } function buildTestCommand(options) { const baseCommand = ['node', '--experimental-vm-modules', 'node_modules/jest/bin/jest.js']; const args = [...baseCommand, '--config', 'jest.e2e.tools.config.js']; // Add test pattern based on options if (options.githubOnly) { args.push('--testPathPattern=github-project-tools'); } else if (options.aiOnly) { args.push('--testPathPattern=ai-task-tools'); } else if (options.workflowsOnly) { args.push('--testPathPattern=tool-integration-workflows'); } // Add verbose flag if (options.verbose) { args.push('--verbose'); } // Set environment variables const env = { ...process.env }; if (options.realApi) { env.E2E_REAL_API = 'true'; } if (options.timeout !== 60) { env.JEST_TIMEOUT = (options.timeout * 1000).toString(); } return { command: args[0], args: args.slice(1), env }; } async function runTests(options) { const { command, args, env } = buildTestCommand(options); console.log(colorize('\n📋 Test Configuration:', 'cyan')); console.log(` Mode: ${options.realApi ? 'Real API' : 'Mock API'}`); console.log(` Scope: ${options.githubOnly ? 'GitHub Tools' : options.aiOnly ? 'AI Tools' : options.workflowsOnly ? 'Workflows' : 'All Tools'}`); console.log(` Timeout: ${options.timeout} seconds`); console.log(` Verbose: ${options.verbose ? 'Yes' : 'No'}`); try { await runCommand(command, args, { env }); console.log(colorize('\n✅ All tests completed successfully!', 'green')); } catch (error) { console.error(colorize('\n❌ Tests failed:', 'red'), error.message); process.exit(1); } } async function main() { printHeader(); const options = parseArgs(); if (options.help) { printUsage(); return; } // Build project if requested if (options.build) { await buildProject(); } // Check environment if (!checkEnvironment()) { console.log(colorize('\n⚠️ Environment issues detected. Continuing with available configuration...', 'yellow')); } // Run tests await runTests(options); } // Handle uncaught errors process.on('uncaughtException', (error) => { console.error(colorize('\n💥 Uncaught Exception:', 'red'), error); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { console.error(colorize('\n💥 Unhandled Rejection:', 'red'), reason); process.exit(1); }); // Run the script if (import.meta.url === `file://${process.argv[1]}`) { main().catch((error) => { console.error(colorize('\n💥 Script failed:', 'red'), error); process.exit(1); }); } export { main, parseArgs, buildTestCommand };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kunwarVivek/mcp-github-project-manager'

If you have feedback or need assistance with the MCP directory API, please join our Discord server