import newman from 'newman';
export class OutputBuilder {
lines = [];
add(line) {
this.lines.push(line);
}
build() {
return this.lines.join('\n');
}
}
export class TestTracker {
assertions = [];
totalTests = 0;
totalPassed = 0;
totalFailed = 0;
addAssertion(assertion) {
this.assertions.push(assertion);
this.totalTests++;
if (assertion.passed) {
this.totalPassed++;
}
else {
this.totalFailed++;
}
}
displayCurrentResults() {
if (this.assertions.length === 0) {
return '';
}
const lines = [' š 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() {
return {
total: this.totalTests,
passed: this.totalPassed,
failed: this.totalFailed,
};
}
reset() {
this.assertions.length = 0;
this.totalTests = 0;
this.totalPassed = 0;
this.totalFailed = 0;
}
}
export function buildNewmanOptions(params, collection, environment) {
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) {
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, tracker, output) {
return new Promise((resolve, reject) => {
newman
.run(options)
.on('start', () => {
output.add('šÆ Starting collection run...\n');
})
.on('assertion', (_err, args) => {
if (args.assertion) {
tracker.addAssertion({
passed: !args.error,
assertion: args.assertion,
name: args.assertion,
error: args.error,
});
}
})
.on('item', (_err, args) => {
if (args.item) {
const testResults = tracker.displayCurrentResults();
if (testResults) {
output.add(`\nš Request: ${args.item.name}`);
output.add(testResults);
}
}
})
.on('done', (err, summary) => {
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, tracker, summary) {
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}`);
}
}
}