Skip to main content
Glama
executor.tsβ€’5.88 kB
import { ExecutionContext, ExecutionResult, TestStatistics, TestResult, CollectionRunParams, } from './models.js'; import newman from 'newman'; export class OutputBuilder { private readonly lines: string[] = []; add(line: string): void { this.lines.push(line); } build(): string { return this.lines.join('\n'); } } export class TestTracker { private readonly assertions: TestResult[] = []; private totalTests = 0; private totalPassed = 0; private totalFailed = 0; addAssertion(assertion: TestResult): void { this.assertions.push(assertion); this.totalTests++; if (assertion.passed) { this.totalPassed++; } else { this.totalFailed++; } } displayCurrentResults(): string { if (this.assertions.length === 0) { return ''; } const lines: string[] = [' πŸ“Š Test Results:']; this.assertions.forEach((assertion) => { const status = assertion.passed ? 'βœ“' : 'βœ—'; const name = assertion.assertion || assertion.name || 'Unnamed test'; lines.push(` ${status} ${name}`); if (!assertion.passed && assertion.error) { const errorMessage = typeof assertion.error === 'string' ? assertion.error : assertion.error.message || 'Unknown error'; lines.push(` └─ Error: ${errorMessage}`); } }); const passed = this.assertions.filter((a) => a.passed).length; const failed = this.assertions.filter((a) => !a.passed).length; lines.push(` ────────────────────────────────────────`); lines.push(` ${this.assertions.length} tests | βœ“ ${passed} passed | βœ— ${failed} failed\n`); this.assertions.length = 0; return lines.join('\n'); } getTotalStats(): TestStatistics { return { total: this.totalTests, passed: this.totalPassed, failed: this.totalFailed, }; } reset(): void { this.assertions.length = 0; this.totalTests = 0; this.totalPassed = 0; this.totalFailed = 0; } } export function buildNewmanOptions( params: CollectionRunParams, collection: object, environment?: object ) { return { collection: collection, environment: environment, iterationCount: params.iterationCount || 1, timeout: params.requestTimeout || 60000, timeoutRequest: params.requestTimeout || 60000, timeoutScript: params.scriptTimeout || 5000, delayRequest: 1000, ignoreRedirects: false, insecure: false, bail: params.stopOnFailure ? ['failure'] : false, suppressExitCode: true, reporters: [], reporter: {}, color: 'off', verbose: false, requestAgents: { http: undefined, https: undefined, }, }; } export async function executeCollection(context: ExecutionContext): Promise<ExecutionResult> { const tracker = new TestTracker(); const output = new OutputBuilder(); output.add(`πŸš€ Starting collection: ${context.collection.name}`); if (context.environment) { output.add(`🌍 Using environment: ${context.environment.name}\n`); } const newmanOptions = buildNewmanOptions( context.params, context.collection.json, context.environment?.json ); const startTime = Date.now(); const summary = await runNewman(newmanOptions, tracker, output); const endTime = Date.now(); const durationMs = endTime - startTime; return { output: output.build(), testStats: tracker.getTotalStats(), summary, startTime, endTime, durationMs, }; } function runNewman(options: any, tracker: TestTracker, output: OutputBuilder): Promise<any> { return new Promise((resolve, reject) => { newman .run(options) .on('start', () => { output.add('🎯 Starting collection run...\n'); }) .on('assertion', (_err: any, args: any) => { if (args.assertion) { tracker.addAssertion({ passed: !args.error, assertion: args.assertion, name: args.assertion, error: args.error, }); } }) .on('item', (_err: any, args: any) => { if (args.item) { const testResults = tracker.displayCurrentResults(); if (testResults) { output.add(`\nπŸ“ Request: ${args.item.name}`); output.add(testResults); } } }) .on('done', (err: any, summary: any) => { if (err) { output.add('\n❌ Run error: ' + err.message); reject(err); return; } output.add('\n=== βœ… Run completed! ==='); appendSummaryToOutput(output, tracker, summary); resolve(summary); }); }); } function appendSummaryToOutput(output: OutputBuilder, tracker: TestTracker, summary: any): void { const testStats = tracker.getTotalStats(); if (testStats.total > 0) { output.add('\nπŸ“Š Overall Test Statistics:'); output.add(` Total tests: ${testStats.total}`); output.add(` Passed: ${testStats.passed} βœ…`); output.add(` Failed: ${testStats.failed} ❌`); output.add(` Success rate: ${((testStats.passed / testStats.total) * 100).toFixed(1)}%`); } if (summary?.run?.stats) { output.add('\nπŸ“ˆ Request Summary:'); output.add(` Total requests: ${summary.run.stats.requests?.total || 0}`); output.add(` Failed requests: ${summary.run.stats.requests?.failed || 0}`); output.add(` Total assertions: ${summary.run.stats.assertions?.total || 0}`); output.add(` Failed assertions: ${summary.run.stats.assertions?.failed || 0}`); if (summary.run.stats.iterations) { output.add(` Total iterations: ${summary.run.stats.iterations.total || 0}`); output.add(` Failed iterations: ${summary.run.stats.iterations.failed || 0}`); } } }

Latest Blog Posts

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/postmanlabs/postman-mcp-server'

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