Skip to main content
Glama

Puppeteer Real Browser MCP Server

by withLinda
test-runner.js7.27 kB
#!/usr/bin/env node /** * Unified Test Runner with Dashboard * * Provides a single interface to run all test categories with unified reporting */ const { spawn } = require('child_process'); const fs = require('fs'); const path = require('path'); class TestRunner { constructor() { this.results = { quick: null, full: null, performance: null, debug: null }; this.startTime = Date.now(); } async runAll(selectedTests = ['quick', 'full', 'performance']) { console.log('🧪 MCP Server Test Suite'); console.log('=' .repeat(50)); console.log(`Running: ${selectedTests.join(', ')} tests\n`); for (const testType of selectedTests) { await this.runTestType(testType); } this.generateDashboard(); } async runTestType(testType) { const configs = { quick: { name: 'Quick Tests (Jest)', command: 'npm', args: ['run', 'test:quick'], timeout: 60000 }, full: { name: 'Full Functional Tests', command: 'npm', args: ['run', 'test:full'], timeout: 600000 }, performance: { name: 'Performance Tests', command: 'npm', args: ['run', 'test:performance'], timeout: 300000 }, debug: { name: 'Debug Diagnostics', command: 'npm', args: ['run', 'test:debug'], timeout: 30000 } }; const config = configs[testType]; if (!config) { console.log(`❌ Unknown test type: ${testType}`); return; } console.log(`🔄 Running ${config.name}...`); const startTime = Date.now(); try { const result = await this.executeTest(config); const duration = Date.now() - startTime; this.results[testType] = { name: config.name, status: result.code === 0 ? 'passed' : 'failed', duration, output: result.output, error: result.error }; const statusIcon = result.code === 0 ? '✅' : '❌'; console.log(`${statusIcon} ${config.name} - ${duration}ms\n`); } catch (error) { const duration = Date.now() - startTime; this.results[testType] = { name: config.name, status: 'error', duration, error: error.message }; console.log(`💥 ${config.name} - Error: ${error.message}\n`); } } executeTest(config) { return new Promise((resolve, reject) => { const process = spawn(config.command, config.args, { stdio: ['inherit', 'pipe', 'pipe'], shell: true }); let output = ''; let error = ''; process.stdout?.on('data', (data) => { output += data.toString(); }); process.stderr?.on('data', (data) => { error += data.toString(); }); process.on('close', (code) => { resolve({ code, output, error }); }); process.on('error', (err) => { reject(err); }); // Timeout handling setTimeout(() => { process.kill('SIGTERM'); reject(new Error(`Test timeout after ${config.timeout}ms`)); }, config.timeout); }); } generateDashboard() { const totalDuration = Date.now() - this.startTime; console.log('\n📊 Test Results Dashboard'); console.log('=' .repeat(50)); // Summary table console.log('\n📋 Summary:'); console.log('-'.repeat(50)); Object.entries(this.results).forEach(([type, result]) => { if (!result) return; const statusIcon = { 'passed': '✅', 'failed': '❌', 'error': '💥' }[result.status] || '❓'; const durationStr = `${result.duration}ms`.padEnd(8); const nameStr = result.name.padEnd(25); console.log(`${statusIcon} ${nameStr} ${durationStr} ${result.status.toUpperCase()}`); }); // Overall status const runTests = Object.values(this.results).filter(r => r !== null); const passedTests = runTests.filter(r => r.status === 'passed'); const failedTests = runTests.filter(r => r.status === 'failed'); const errorTests = runTests.filter(r => r.status === 'error'); console.log('\n🎯 Overall Results:'); console.log('-'.repeat(50)); console.log(`Total Tests Run: ${runTests.length}`); console.log(`✅ Passed: ${passedTests.length}`); console.log(`❌ Failed: ${failedTests.length}`); console.log(`💥 Errors: ${errorTests.length}`); console.log(`⏱️ Total Duration: ${totalDuration}ms`); const overallStatus = failedTests.length === 0 && errorTests.length === 0 ? 'PASSED' : 'FAILED'; const overallIcon = overallStatus === 'PASSED' ? '🎉' : '⚠️'; console.log(`\n${overallIcon} Overall Status: ${overallStatus}`); // Recommendations if (failedTests.length > 0 || errorTests.length > 0) { console.log('\n💡 Recommendations:'); console.log('-'.repeat(50)); if (errorTests.some(t => t.name.includes('Debug'))) { console.log('• Run debug diagnostics: npm run test:debug'); } if (failedTests.some(t => t.name.includes('Quick'))) { console.log('• Check protocol compliance issues'); } if (failedTests.some(t => t.name.includes('Full'))) { console.log('• Check browser operations and error recovery'); } if (failedTests.some(t => t.name.includes('Performance'))) { console.log('• Check system resources and network connectivity'); } } // Save results to file this.saveResults(); } saveResults() { const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const filename = `test-results-${timestamp}.json`; const report = { timestamp: new Date().toISOString(), totalDuration: Date.now() - this.startTime, results: this.results, summary: { total: Object.values(this.results).filter(r => r !== null).length, passed: Object.values(this.results).filter(r => r?.status === 'passed').length, failed: Object.values(this.results).filter(r => r?.status === 'failed').length, errors: Object.values(this.results).filter(r => r?.status === 'error').length } }; try { if (!fs.existsSync('test-results')) { fs.mkdirSync('test-results'); } fs.writeFileSync(path.join('test-results', filename), JSON.stringify(report, null, 2)); console.log(`\n💾 Results saved to: test-results/${filename}`); } catch (error) { console.log(`\n⚠️ Could not save results: ${error.message}`); } } } // CLI interface if (require.main === module) { const args = process.argv.slice(2); const runner = new TestRunner(); if (args.length === 0) { // Default: run all but debug runner.runAll(['quick', 'full', 'performance']).catch(console.error); } else if (args[0] === 'all') { runner.runAll(['quick', 'full', 'performance', 'debug']).catch(console.error); } else if (args[0] === 'quick') { runner.runAll(['quick']).catch(console.error); } else if (args[0] === 'ci') { runner.runAll(['quick']).catch(console.error); } else { runner.runAll(args).catch(console.error); } } module.exports = TestRunner;

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/withLinda/puppeteer-real-browser-mcp-server'

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