diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js index 2e4d6b87..e360e26b 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js @@ -1322,29 +1322,29 @@ export const collectionsSlice = createSlice({ } if (type === 'request-sent') { - const item = collection.runnerResult.items.find((i) => i.uid === request.uid); + const item = collection.runnerResult.items.find((i) => i.uid === request.uid && i.status === 'queued'); item.status = 'running'; item.requestSent = action.payload.requestSent; } if (type === 'response-received') { - const item = collection.runnerResult.items.find((i) => i.uid === request.uid); + const item = collection.runnerResult.items.find((i) => i.uid === request.uid && i.status === 'running'); item.status = 'completed'; item.responseReceived = action.payload.responseReceived; } if (type === 'test-results') { - const item = collection.runnerResult.items.find((i) => i.uid === request.uid); + const item = collection.runnerResult.items.find((i) => i.uid === request.uid && i.status === 'running'); item.testResults = action.payload.testResults; } if (type === 'assertion-results') { - const item = collection.runnerResult.items.find((i) => i.uid === request.uid); + const item = collection.runnerResult.items.find((i) => i.uid === request.uid && i.status === 'running'); item.assertionResults = action.payload.assertionResults; } if (type === 'error') { - const item = collection.runnerResult.items.find((i) => i.uid === request.uid); + const item = collection.runnerResult.items.find((i) => i.uid === request.uid && i.status === 'running'); item.error = action.payload.error; item.responseReceived = action.payload.responseReceived; item.status = 'error'; diff --git a/packages/bruno-cli/src/commands/run.js b/packages/bruno-cli/src/commands/run.js index 4ddad069..d1eea59a 100644 --- a/packages/bruno-cli/src/commands/run.js +++ b/packages/bruno-cli/src/commands/run.js @@ -355,7 +355,10 @@ const handler = async function (argv) { } } - for (const iter of bruJsons) { + let currentRequestIndex = 0; + let nJumps = 0; // count the number of jumps to avoid infinite loops + while (currentRequestIndex < bruJsons.length) { + const iter = bruJsons[currentRequestIndex]; const { bruFilepath, bruJson } = iter; const result = await runSingleRequest( bruFilepath, @@ -369,6 +372,28 @@ const handler = async function (argv) { ); results.push(result); + + // determine next request + const nextRequestName = result?.nextRequestName; + if (nextRequestName !== undefined) { + nJumps++; + if (nJumps > 10000) { + console.error(chalk.red(`Too many jumps, possible infinite loop`)); + process.exit(1); + } + if (nextRequestName === null) { + break; + } + const nextRequestIdx = bruJsons.findIndex((iter) => iter.bruJson.name === nextRequestName); + if (nextRequestIdx >= 0) { + currentRequestIndex = nextRequestIdx; + } else { + console.error("Could not find request with name '" + nextRequestName + "'"); + currentRequestIndex++; + } + } else { + currentRequestIndex++; + } } const summary = printRunSummary(results); diff --git a/packages/bruno-cli/src/runner/run-single-request.js b/packages/bruno-cli/src/runner/run-single-request.js index 9b12e86a..b19289ee 100644 --- a/packages/bruno-cli/src/runner/run-single-request.js +++ b/packages/bruno-cli/src/runner/run-single-request.js @@ -31,6 +31,7 @@ const runSingleRequest = async function ( ) { try { let request; + let nextRequestName; request = prepareRequest(bruJson.request, collectionRoot); @@ -68,7 +69,7 @@ const runSingleRequest = async function ( ]).join(os.EOL); if (requestScriptFile?.length) { const scriptRuntime = new ScriptRuntime(); - await scriptRuntime.runRequestScript( + const result = await scriptRuntime.runRequestScript( decomment(requestScriptFile), request, envVariables, @@ -78,6 +79,9 @@ const runSingleRequest = async function ( processEnvVars, scriptingConfig ); + if (result?.nextRequestName !== undefined) { + nextRequestName = result.nextRequestName; + } } // interpolate variables inside request @@ -211,7 +215,8 @@ const runSingleRequest = async function ( }, error: err.message, assertionResults: [], - testResults: [] + testResults: [], + nextRequestName: nextRequestName }; } } @@ -245,7 +250,7 @@ const runSingleRequest = async function ( ]).join(os.EOL); if (responseScriptFile?.length) { const scriptRuntime = new ScriptRuntime(); - await scriptRuntime.runResponseScript( + const result = await scriptRuntime.runResponseScript( decomment(responseScriptFile), request, response, @@ -256,6 +261,9 @@ const runSingleRequest = async function ( processEnvVars, scriptingConfig ); + if (result?.nextRequestName !== undefined) { + nextRequestName = result.nextRequestName; + } } // run assertions @@ -327,7 +335,8 @@ const runSingleRequest = async function ( }, error: null, assertionResults, - testResults + testResults, + nextRequestName: nextRequestName }; } catch (err) { console.log(chalk.red(stripExtension(filename)) + chalk.dim(` (${err.message})`)); diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index c4577bf3..4e8e301d 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -258,10 +258,11 @@ const registerNetworkIpc = (mainWindow) => { } // run pre-request script + let scriptResult; const requestScript = compact([get(collectionRoot, 'request.script.req'), get(request, 'script.req')]).join(os.EOL); if (requestScript?.length) { const scriptRuntime = new ScriptRuntime(); - const result = await scriptRuntime.runRequestScript( + scriptResult = await scriptRuntime.runRequestScript( decomment(requestScript), request, envVars, @@ -273,8 +274,8 @@ const registerNetworkIpc = (mainWindow) => { ); mainWindow.webContents.send('main:script-environment-update', { - envVariables: result.envVariables, - collectionVariables: result.collectionVariables, + envVariables: scriptResult.envVariables, + collectionVariables: scriptResult.collectionVariables, requestUid, collectionUid }); @@ -293,6 +294,8 @@ const registerNetworkIpc = (mainWindow) => { if (request.headers['content-type'] === 'application/x-www-form-urlencoded') { request.data = qs.stringify(request.data); } + + return scriptResult; }; const runPostResponse = async ( @@ -332,12 +335,13 @@ const registerNetworkIpc = (mainWindow) => { } // run post-response script + let scriptResult; const responseScript = compact([get(collectionRoot, 'request.script.res'), get(request, 'script.res')]).join( os.EOL ); if (responseScript?.length) { const scriptRuntime = new ScriptRuntime(); - const result = await scriptRuntime.runResponseScript( + scriptResult = await scriptRuntime.runResponseScript( decomment(responseScript), request, response, @@ -350,12 +354,13 @@ const registerNetworkIpc = (mainWindow) => { ); mainWindow.webContents.send('main:script-environment-update', { - envVariables: result.envVariables, - collectionVariables: result.collectionVariables, + envVariables: scriptResult.envVariables, + collectionVariables: scriptResult.collectionVariables, requestUid, collectionUid }); } + return scriptResult; }; // handler for sending http request @@ -696,7 +701,11 @@ const registerNetworkIpc = (mainWindow) => { }); } - for (let item of folderRequests) { + let currentRequestIndex = 0; + let nJumps = 0; // count the number of jumps to avoid infinite loops + while (currentRequestIndex < folderRequests.length) { + const item = folderRequests[currentRequestIndex]; + let nextRequestName; const itemUid = item.uid; const eventData = { collectionUid, @@ -718,7 +727,7 @@ const registerNetworkIpc = (mainWindow) => { const processEnvVars = getProcessEnvVars(collectionUid); try { - await runPreRequest( + const preRequestScriptResult = await runPreRequest( request, requestUid, envVars, @@ -730,6 +739,10 @@ const registerNetworkIpc = (mainWindow) => { scriptingConfig ); + if (preRequestScriptResult?.nextRequestName !== undefined) { + nextRequestName = preRequestScriptResult.nextRequestName; + } + // todo: // i have no clue why electron can't send the request object // without safeParseJSON(safeStringifyJSON(request.data)) @@ -805,7 +818,7 @@ const registerNetworkIpc = (mainWindow) => { } } - await runPostResponse( + const postRequestScriptResult = await runPostResponse( request, response, requestUid, @@ -818,6 +831,10 @@ const registerNetworkIpc = (mainWindow) => { scriptingConfig ); + if (postRequestScriptResult?.nextRequestName !== undefined) { + nextRequestName = postRequestScriptResult.nextRequestName; + } + // run assertions const assertions = get(item, 'request.assertions'); if (assertions) { @@ -878,6 +895,24 @@ const registerNetworkIpc = (mainWindow) => { ...eventData }); } + if (nextRequestName !== undefined) { + nJumps++; + if (nJumps > 10000) { + throw new Error('Too many jumps, possible infinite loop'); + } + if (nextRequestName === null) { + break; + } + const nextRequestIdx = folderRequests.findIndex((request) => request.name === nextRequestName); + if (nextRequestIdx >= 0) { + currentRequestIndex = nextRequestIdx; + } else { + console.error("Could not find request with name '" + nextRequestName + "'"); + currentRequestIndex++; + } + } else { + currentRequestIndex++; + } } mainWindow.webContents.send('main:run-folder-event', { diff --git a/packages/bruno-js/src/bru.js b/packages/bruno-js/src/bru.js index ffab6ec1..964d7b60 100644 --- a/packages/bruno-js/src/bru.js +++ b/packages/bruno-js/src/bru.js @@ -76,6 +76,10 @@ class Bru { return this.collectionVariables[key]; } + + setNextRequest(nextRequest) { + this.nextRequest = nextRequest; + } } module.exports = Bru; diff --git a/packages/bruno-js/src/runtime/script-runtime.js b/packages/bruno-js/src/runtime/script-runtime.js index f8776851..8df51d79 100644 --- a/packages/bruno-js/src/runtime/script-runtime.js +++ b/packages/bruno-js/src/runtime/script-runtime.js @@ -123,7 +123,8 @@ class ScriptRuntime { return { request, envVariables: cleanJson(envVariables), - collectionVariables: cleanJson(collectionVariables) + collectionVariables: cleanJson(collectionVariables), + nextRequestName: bru.nextRequest }; } @@ -215,7 +216,8 @@ class ScriptRuntime { return { response, envVariables: cleanJson(envVariables), - collectionVariables: cleanJson(collectionVariables) + collectionVariables: cleanJson(collectionVariables), + nextRequestName: bru.nextRequest }; } }