diff --git a/packages/bruno-cli/src/runner/run-single-request.js b/packages/bruno-cli/src/runner/run-single-request.js index 72ad5c19d..c6566805f 100644 --- a/packages/bruno-cli/src/runner/run-single-request.js +++ b/packages/bruno-cli/src/runner/run-single-request.js @@ -224,18 +224,12 @@ const runSingleRequest = async function ( preRequestTestResults = result?.results || []; } catch (error) { + // Pre-request errors are treated as request errors (we return early with status: 'error'), not as failures. Unlike post-response and test script errors, we do not add a synthetic fail and continue. console.error('Pre-request script execution error:', error); + console.log(chalk.red(stripExtension(relativeItemPathname)) + chalk.dim(` (${error.message})`)); // Extract partial results from the error (tests that passed before the error) - const partialResults = error?.partialResults?.results || []; - preRequestTestResults = [ - ...partialResults, - { - status: 'fail', - description: 'Pre-Request Script Error', - error: error.message || 'An error occurred while executing the pre-request script.' - } - ]; + preRequestTestResults = error?.partialResults?.results || []; // Preserve nextRequestName if it was set before the error if (error?.partialResults?.nextRequestName !== undefined) { @@ -248,6 +242,35 @@ const runSingleRequest = async function ( } logResults(preRequestTestResults, 'Pre-Request Tests'); + + // Pre-request script error: execution didn't complete (request never sent). Return early so we don't run the HTTP request, post-response script, assertions, or tests. + return { + test: { + filename: relativeItemPathname + }, + request: { + method: request.method, + url: request.url, + headers: request.headers, + data: request.data + }, + response: { + status: 'error', + statusText: null, + headers: null, + data: null, + url: null, + responseTime: 0 + }, + error: error?.message || 'An error occurred while executing the pre-request script.', + status: 'error', + assertionResults: [], + testResults: [], + preRequestTestResults, + postResponseTestResults: [], + nextRequestName: nextRequestName, + shouldStopRunnerExecution + }; } } @@ -734,7 +757,8 @@ const runSingleRequest = async function ( { status: 'fail', description: 'Post-Response Script Error', - error: error.message || 'An error occurred while executing the post-response script.' + error: error.message || 'An error occurred while executing the post-response script.', + isScriptError: true } ]; @@ -803,7 +827,8 @@ const runSingleRequest = async function ( { status: 'fail', description: 'Test Script Error', - error: error.message || 'An error occurred while executing the test script.' + error: error.message || 'An error occurred while executing the test script.', + isScriptError: true } ]; diff --git a/packages/bruno-common/src/runner/runner-summary.ts b/packages/bruno-common/src/runner/runner-summary.ts index 3e99e676f..13f448a1d 100644 --- a/packages/bruno-common/src/runner/runner-summary.ts +++ b/packages/bruno-common/src/runner/runner-summary.ts @@ -23,10 +23,10 @@ export const getRunnerSummary = (results: T_RunnerRequestExecutionResult[]): T_R for (const result of results || []) { const { status, testResults, assertionResults, preRequestTestResults, postResponseTestResults } = result; totalRequests += 1; - totalTests += Number(testResults?.length) || 0; + totalTests += Number(testResults?.filter((r) => !r.isScriptError).length) || 0; totalAssertions += Number(assertionResults?.length) || 0; - totalPreRequestTests += Number(preRequestTestResults?.length) || 0; - totalPostResponseTests += Number(postResponseTestResults?.length) || 0; + totalPreRequestTests += Number(preRequestTestResults?.filter((r) => !r.isScriptError).length) || 0; + totalPostResponseTests += Number(postResponseTestResults?.filter((r) => !r.isScriptError).length) || 0; if (status === 'skipped') { skippedRequests += 1; @@ -35,6 +35,10 @@ export const getRunnerSummary = (results: T_RunnerRequestExecutionResult[]): T_R let anyFailed = false; for (const testResult of testResults || []) { + if (testResult.isScriptError) { + anyFailed = true; + continue; + } if (testResult.status === 'pass') { passedTests += 1; } else { @@ -59,6 +63,10 @@ export const getRunnerSummary = (results: T_RunnerRequestExecutionResult[]): T_R } } for (const postResponseTestResult of postResponseTestResults || []) { + if (postResponseTestResult.isScriptError) { + anyFailed = true; + continue; + } if (postResponseTestResult.status === 'pass') { passedPostResponseTests += 1; } else { diff --git a/packages/bruno-common/src/runner/types/index.ts b/packages/bruno-common/src/runner/types/index.ts index 1b696ba12..0d9b40eb5 100644 --- a/packages/bruno-common/src/runner/types/index.ts +++ b/packages/bruno-common/src/runner/types/index.ts @@ -23,6 +23,7 @@ type T_TestPassResult = { status: string; description: string; uid?: string; + isScriptError?: boolean; }; type T_TestFailResult = { @@ -30,6 +31,7 @@ type T_TestFailResult = { description: string; error: string; uid?: string; + isScriptError?: boolean; }; type T_TestResult = T_TestPassResult | T_TestFailResult;