From d4c0207545ab111dabe6e37d190b26f9b14088ec Mon Sep 17 00:00:00 2001 From: Martin Hoecker Date: Mon, 16 Oct 2023 13:28:58 +0200 Subject: [PATCH 1/4] feat: bru.setNextRequest() --- packages/bruno-cli/src/commands/run.js | 17 ++++++++++++- .../src/runner/run-single-request.js | 17 +++++++++---- .../bruno-electron/src/ipc/network/index.js | 24 ++++++++++++++++++- packages/bruno-js/src/bru.js | 4 ++++ .../bruno-js/src/runtime/script-runtime.js | 6 +++-- 5 files changed, 60 insertions(+), 8 deletions(-) diff --git a/packages/bruno-cli/src/commands/run.js b/packages/bruno-cli/src/commands/run.js index 78b7226ca..e9b98e9e5 100644 --- a/packages/bruno-cli/src/commands/run.js +++ b/packages/bruno-cli/src/commands/run.js @@ -357,7 +357,9 @@ const handler = async function (argv) { } } - for (const iter of bruJsons) { + let currentRequestIndex = 0; + while (currentRequestIndex < bruJsons.length) { + const iter = bruJsons[currentRequestIndex]; const { bruFilepath, bruJson } = iter; const result = await runSingleRequest( bruFilepath, @@ -370,6 +372,19 @@ const handler = async function (argv) { collectionRoot ); + const nextRequestName = result?.nextRequestName; + if (nextRequestName) { + 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++; + } + results.push(result); } diff --git a/packages/bruno-cli/src/runner/run-single-request.js b/packages/bruno-cli/src/runner/run-single-request.js index ee67f60b3..d6f3107a7 100644 --- a/packages/bruno-cli/src/runner/run-single-request.js +++ b/packages/bruno-cli/src/runner/run-single-request.js @@ -29,6 +29,7 @@ const runSingleRequest = async function ( ) { try { let request; + let nextRequestName; request = prepareRequest(bruJson.request, collectionRoot); @@ -66,7 +67,7 @@ const runSingleRequest = async function ( ]).join(os.EOL); if (requestScriptFile && requestScriptFile.length) { const scriptRuntime = new ScriptRuntime(); - await scriptRuntime.runRequestScript( + const result = await scriptRuntime.runRequestScript( decomment(requestScriptFile), request, envVariables, @@ -76,6 +77,9 @@ const runSingleRequest = async function ( processEnvVars, scriptingConfig ); + if (result?.nextRequestName) { + nextRequestName = result.nextRequestName; + } } // interpolate variables inside request @@ -187,7 +191,8 @@ const runSingleRequest = async function ( }, error: err.message, assertionResults: [], - testResults: [] + testResults: [], + nextRequestName: nextRequestName }; } } @@ -219,7 +224,7 @@ const runSingleRequest = async function ( ]).join(os.EOL); if (responseScriptFile && responseScriptFile.length) { const scriptRuntime = new ScriptRuntime(); - await scriptRuntime.runResponseScript( + const result = await scriptRuntime.runResponseScript( decomment(responseScriptFile), request, response, @@ -230,6 +235,9 @@ const runSingleRequest = async function ( processEnvVars, scriptingConfig ); + if (result?.nextRequestName) { + nextRequestName = result.nextRequestName; + } } // run assertions @@ -301,7 +309,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 ebd780ece..2995e5742 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -605,7 +605,10 @@ const registerNetworkIpc = (mainWindow) => { }); } - for (let item of folderRequests) { + let currentRequestIndex = 0; + while (currentRequestIndex < folderRequests.length) { + item = folderRequests[currentRequestIndex]; + let nextRequestName = undefined; const itemUid = item.uid; const eventData = { collectionUid, @@ -685,6 +688,10 @@ const registerNetworkIpc = (mainWindow) => { collectionVariables: result.collectionVariables, collectionUid }); + + if (result?.nextRequestName) { + nextRequestName = result.nextRequestName; + } } // interpolate variables inside request @@ -807,6 +814,10 @@ const registerNetworkIpc = (mainWindow) => { collectionVariables: result.collectionVariables, collectionUid }); + + if (result?.nextRequestName) { + nextRequestName = result.nextRequestName; + } } // run assertions @@ -963,6 +974,17 @@ const registerNetworkIpc = (mainWindow) => { ...eventData }); } + if (nextRequestName) { + 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 3cd9e8f5f..10af84a50 100644 --- a/packages/bruno-js/src/bru.js +++ b/packages/bruno-js/src/bru.js @@ -65,6 +65,10 @@ class Bru { getVar(key) { 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 391d047d5..c395bc7dd 100644 --- a/packages/bruno-js/src/runtime/script-runtime.js +++ b/packages/bruno-js/src/runtime/script-runtime.js @@ -116,7 +116,8 @@ class ScriptRuntime { return { request, envVariables: cleanJson(envVariables), - collectionVariables: cleanJson(collectionVariables) + collectionVariables: cleanJson(collectionVariables), + nextRequestName: bru.nextRequest }; } @@ -207,7 +208,8 @@ class ScriptRuntime { return { response, envVariables: cleanJson(envVariables), - collectionVariables: cleanJson(collectionVariables) + collectionVariables: cleanJson(collectionVariables), + nextRequestName: bru.nextRequest }; } } From d76253ea04bffeeada116401d38c61fb0f35c7ca Mon Sep 17 00:00:00 2001 From: Brian Dentino Date: Fri, 20 Oct 2023 12:36:05 -0400 Subject: [PATCH 2/4] Fixes for getNextRequest in UI --- .../providers/ReduxStore/slices/collections/index.js | 10 +++++----- packages/bruno-cli/src/commands/run.js | 2 +- packages/bruno-electron/src/ipc/network/index.js | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) 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 4ad30d204..e98ba45bf 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js @@ -1303,29 +1303,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 43aae38d7..51bb35704 100644 --- a/packages/bruno-cli/src/commands/run.js +++ b/packages/bruno-cli/src/commands/run.js @@ -373,7 +373,7 @@ const handler = async function (argv) { const nextRequestName = result?.nextRequestName; if (nextRequestName) { const nextRequestIdx = bruJsons.findIndex((iter) => iter.bruJson.name === nextRequestName); - if (nextRequestIdx > 0) { + if (nextRequestIdx >= 0) { currentRequestIndex = nextRequestIdx; } else { console.error("Could not find request with name '" + nextRequestName + "'"); diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 1fc8d17c0..348d7818c 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -866,7 +866,7 @@ const registerNetworkIpc = (mainWindow) => { } if (nextRequestName) { const nextRequestIdx = folderRequests.findIndex((request) => request.name === nextRequestName); - if (nextRequestIdx > 0) { + if (nextRequestIdx >= 0) { currentRequestIndex = nextRequestIdx; } else { console.error("Could not find request with name '" + nextRequestName + "'"); From 129d659628b08ccad668a7ba6f558e7028ebebb5 Mon Sep 17 00:00:00 2001 From: Martin Hoecker Date: Wed, 1 Nov 2023 23:15:54 +0100 Subject: [PATCH 3/4] Count the number of jumps to break out of infinite loops. This is especially useful for the bru cli, to make sure that test-runners that are accidentally stuck in an infinite loop still terminate in a reasonable amount of time and don't hog up resources. --- packages/bruno-cli/src/commands/run.js | 6 ++++++ packages/bruno-electron/src/ipc/network/index.js | 9 +++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/bruno-cli/src/commands/run.js b/packages/bruno-cli/src/commands/run.js index 51bb35704..5e7b8e554 100644 --- a/packages/bruno-cli/src/commands/run.js +++ b/packages/bruno-cli/src/commands/run.js @@ -356,6 +356,7 @@ const handler = async function (argv) { } 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; @@ -372,6 +373,11 @@ const handler = async function (argv) { const nextRequestName = result?.nextRequestName; if (nextRequestName) { + nJumps++; + if (nJumps > 10000) { + console.error(chalk.red(`Too many jumps, possible infinite loop`)); + process.exit(1); + } const nextRequestIdx = bruJsons.findIndex((iter) => iter.bruJson.name === nextRequestName); if (nextRequestIdx >= 0) { currentRequestIndex = nextRequestIdx; diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 00ce034e8..3a6170abe 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -673,9 +673,10 @@ const registerNetworkIpc = (mainWindow) => { } let currentRequestIndex = 0; + let nJumps = 0; // count the number of jumps to avoid infinite loops while (currentRequestIndex < folderRequests.length) { - item = folderRequests[currentRequestIndex]; - let nextRequestName = undefined; + const item = folderRequests[currentRequestIndex]; + let nextRequestName; const itemUid = item.uid; const eventData = { collectionUid, @@ -866,6 +867,10 @@ const registerNetworkIpc = (mainWindow) => { }); } if (nextRequestName) { + nJumps++; + if (nJumps > 10000) { + throw new Error('Too many jumps, possible infinite loop'); + } const nextRequestIdx = folderRequests.findIndex((request) => request.name === nextRequestName); if (nextRequestIdx >= 0) { currentRequestIndex = nextRequestIdx; From 8183ce03c51e7f8789440f3190870c4c3d1c263a Mon Sep 17 00:00:00 2001 From: Martin Hoecker Date: Wed, 1 Nov 2023 23:41:37 +0100 Subject: [PATCH 4/4] feat: bru.setNextRequest(null) breaks execution without error --- packages/bruno-cli/src/commands/run.js | 10 +++++++--- packages/bruno-cli/src/runner/run-single-request.js | 4 ++-- packages/bruno-electron/src/ipc/network/index.js | 9 ++++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/bruno-cli/src/commands/run.js b/packages/bruno-cli/src/commands/run.js index 5e7b8e554..d1eea59a8 100644 --- a/packages/bruno-cli/src/commands/run.js +++ b/packages/bruno-cli/src/commands/run.js @@ -371,13 +371,19 @@ const handler = async function (argv) { collectionRoot ); + results.push(result); + + // determine next request const nextRequestName = result?.nextRequestName; - if (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; @@ -388,8 +394,6 @@ const handler = async function (argv) { } else { currentRequestIndex++; } - - results.push(result); } 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 cc0012fc6..8a9cc0486 100644 --- a/packages/bruno-cli/src/runner/run-single-request.js +++ b/packages/bruno-cli/src/runner/run-single-request.js @@ -77,7 +77,7 @@ const runSingleRequest = async function ( processEnvVars, scriptingConfig ); - if (result?.nextRequestName) { + if (result?.nextRequestName !== undefined) { nextRequestName = result.nextRequestName; } } @@ -252,7 +252,7 @@ const runSingleRequest = async function ( processEnvVars, scriptingConfig ); - if (result?.nextRequestName) { + if (result?.nextRequestName !== undefined) { nextRequestName = result.nextRequestName; } } diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 3a6170abe..1536b8c81 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -710,7 +710,7 @@ const registerNetworkIpc = (mainWindow) => { scriptingConfig ); - if (preRequestScriptResult?.nextRequestName) { + if (preRequestScriptResult?.nextRequestName !== undefined) { nextRequestName = preRequestScriptResult.nextRequestName; } @@ -802,7 +802,7 @@ const registerNetworkIpc = (mainWindow) => { scriptingConfig ); - if (postRequestScriptResult?.nextRequestName) { + if (postRequestScriptResult?.nextRequestName !== undefined) { nextRequestName = postRequestScriptResult.nextRequestName; } @@ -866,11 +866,14 @@ const registerNetworkIpc = (mainWindow) => { ...eventData }); } - if (nextRequestName) { + 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;