mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-15 20:01:28 +00:00
add runRequest and runner utils functions to cli
~ add bru.runRequest support for cli ~ add bru.runner.skipRequest, bru.runner.stopExecution support for cli
This commit is contained in:
@@ -11,6 +11,7 @@ const { rpad } = require('../utils/common');
|
||||
const { bruToJson, getOptions, collectionBruToJson } = require('../utils/bru');
|
||||
const { dotenvToJson } = require('@usebruno/lang');
|
||||
const constants = require('../constants');
|
||||
const { findItemInCollection } = require('../utils/collection');
|
||||
const command = 'run [filename]';
|
||||
const desc = 'Run a request';
|
||||
|
||||
@@ -18,6 +19,7 @@ const printRunSummary = (results) => {
|
||||
let totalRequests = 0;
|
||||
let passedRequests = 0;
|
||||
let failedRequests = 0;
|
||||
let skippedRequests = 0;
|
||||
let totalAssertions = 0;
|
||||
let passedAssertions = 0;
|
||||
let failedAssertions = 0;
|
||||
@@ -49,7 +51,10 @@ const printRunSummary = (results) => {
|
||||
failedAssertions += 1;
|
||||
}
|
||||
}
|
||||
if (!hasAnyTestsOrAssertions && result.error) {
|
||||
if (!hasAnyTestsOrAssertions && result.skipped) {
|
||||
skippedRequests += 1;
|
||||
}
|
||||
else if (!hasAnyTestsOrAssertions && result.error) {
|
||||
failedRequests += 1;
|
||||
} else {
|
||||
passedRequests += 1;
|
||||
@@ -62,6 +67,9 @@ const printRunSummary = (results) => {
|
||||
if (failedRequests > 0) {
|
||||
requestSummary += `, ${chalk.red(`${failedRequests} failed`)}`;
|
||||
}
|
||||
if (skippedRequests > 0) {
|
||||
requestSummary += `, ${chalk.magenta(`${skippedRequests} skipped`)}`;
|
||||
}
|
||||
requestSummary += `, ${totalRequests} total`;
|
||||
|
||||
let assertSummary = `${rpad('Tests:', maxLength)} ${chalk.green(`${passedTests} passed`)}`;
|
||||
@@ -84,6 +92,7 @@ const printRunSummary = (results) => {
|
||||
totalRequests,
|
||||
passedRequests,
|
||||
failedRequests,
|
||||
skippedRequests,
|
||||
totalAssertions,
|
||||
passedAssertions,
|
||||
failedAssertions,
|
||||
@@ -144,7 +153,7 @@ const createCollectionFromPath = (collectionPath) => {
|
||||
});
|
||||
}
|
||||
}
|
||||
return currentDirItems
|
||||
return currentDirItems;
|
||||
};
|
||||
collection.items = traverse(collectionPath);
|
||||
return collection;
|
||||
@@ -634,6 +643,34 @@ const handler = async function (argv) {
|
||||
}
|
||||
|
||||
const runtime = getJsSandboxRuntime(sandbox);
|
||||
|
||||
const runSingleRequestByPathname = async (relativeItemPathname) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let itemPathname = path.join(collectionPath, relativeItemPathname);
|
||||
if (itemPathname && !itemPathname?.endsWith('.bru')) {
|
||||
itemPathname = `${itemPathname}.bru`;
|
||||
}
|
||||
const bruJson = cloneDeep(findItemInCollection(collection, itemPathname));
|
||||
if (bruJson) {
|
||||
const res = await runSingleRequest(
|
||||
itemPathname,
|
||||
bruJson,
|
||||
collectionPath,
|
||||
runtimeVariables,
|
||||
envVars,
|
||||
processEnvVars,
|
||||
brunoConfig,
|
||||
collectionRoot,
|
||||
runtime,
|
||||
collection,
|
||||
runSingleRequestByPathname
|
||||
);
|
||||
resolve(res?.response);
|
||||
}
|
||||
reject(`bru.runRequest: invalid request path - ${itemPathname}`);
|
||||
});
|
||||
}
|
||||
|
||||
let currentRequestIndex = 0;
|
||||
let nJumps = 0; // count the number of jumps to avoid infinite loops
|
||||
while (currentRequestIndex < bruJsons.length) {
|
||||
@@ -651,7 +688,8 @@ const handler = async function (argv) {
|
||||
brunoConfig,
|
||||
collectionRoot,
|
||||
runtime,
|
||||
collection
|
||||
collection,
|
||||
runSingleRequestByPathname
|
||||
);
|
||||
|
||||
results.push({
|
||||
@@ -701,6 +739,11 @@ const handler = async function (argv) {
|
||||
|
||||
// determine next request
|
||||
const nextRequestName = result?.nextRequestName;
|
||||
|
||||
if (result?.shouldStopRunnerExecution) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextRequestName !== undefined) {
|
||||
nJumps++;
|
||||
if (nJumps > 10000) {
|
||||
|
||||
@@ -40,11 +40,13 @@ const runSingleRequest = async function (
|
||||
brunoConfig,
|
||||
collectionRoot,
|
||||
runtime,
|
||||
collection
|
||||
collection,
|
||||
runSingleRequestByPathname
|
||||
) {
|
||||
try {
|
||||
let request;
|
||||
let nextRequestName;
|
||||
let shouldStopRunnerExecution = false;
|
||||
let item = {
|
||||
pathname: path.join(collectionPath, filename),
|
||||
...bruJson
|
||||
@@ -68,11 +70,41 @@ const runSingleRequest = async function (
|
||||
collectionPath,
|
||||
onConsoleLog,
|
||||
processEnvVars,
|
||||
scriptingConfig
|
||||
scriptingConfig,
|
||||
runSingleRequestByPathname
|
||||
);
|
||||
if (result?.nextRequestName !== undefined) {
|
||||
nextRequestName = result.nextRequestName;
|
||||
}
|
||||
|
||||
if (result?.stopExecution) {
|
||||
shouldStopRunnerExecution = true;
|
||||
}
|
||||
|
||||
if (result?.skipRequest) {
|
||||
return {
|
||||
test: {
|
||||
filename: filename
|
||||
},
|
||||
request: {
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
headers: request.headers,
|
||||
data: request.data
|
||||
},
|
||||
response: {
|
||||
status: 'skipped',
|
||||
statusText: 'request skipped via pre-request script',
|
||||
data: null,
|
||||
responseTime: 0
|
||||
},
|
||||
error: 'Request has been skipped from pre-request script',
|
||||
skipped: true,
|
||||
assertionResults: [],
|
||||
testResults: [],
|
||||
shouldStopRunnerExecution
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// interpolate variables inside request
|
||||
@@ -323,7 +355,8 @@ const runSingleRequest = async function (
|
||||
error: err?.message || err?.errors?.map(e => e?.message)?.at(0) || err?.code || 'Request Failed!',
|
||||
assertionResults: [],
|
||||
testResults: [],
|
||||
nextRequestName: nextRequestName
|
||||
nextRequestName: nextRequestName,
|
||||
shouldStopRunnerExecution
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -363,11 +396,16 @@ const runSingleRequest = async function (
|
||||
collectionPath,
|
||||
null,
|
||||
processEnvVars,
|
||||
scriptingConfig
|
||||
scriptingConfig,
|
||||
runSingleRequestByPathname
|
||||
);
|
||||
if (result?.nextRequestName !== undefined) {
|
||||
nextRequestName = result.nextRequestName;
|
||||
}
|
||||
|
||||
if (result?.stopExecution) {
|
||||
shouldStopRunnerExecution = true;
|
||||
}
|
||||
}
|
||||
|
||||
// run assertions
|
||||
@@ -408,13 +446,18 @@ const runSingleRequest = async function (
|
||||
collectionPath,
|
||||
null,
|
||||
processEnvVars,
|
||||
scriptingConfig
|
||||
scriptingConfig,
|
||||
runSingleRequestByPathname
|
||||
);
|
||||
testResults = get(result, 'results', []);
|
||||
|
||||
if (result?.nextRequestName !== undefined) {
|
||||
nextRequestName = result.nextRequestName;
|
||||
}
|
||||
|
||||
if (result?.stopExecution) {
|
||||
shouldStopRunnerExecution = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (testResults?.length) {
|
||||
@@ -447,7 +490,8 @@ const runSingleRequest = async function (
|
||||
error: null,
|
||||
assertionResults,
|
||||
testResults,
|
||||
nextRequestName: nextRequestName
|
||||
nextRequestName: nextRequestName,
|
||||
shouldStopRunnerExecution
|
||||
};
|
||||
} catch (err) {
|
||||
console.log(chalk.red(stripExtension(filename)) + chalk.dim(` (${err.message})`));
|
||||
|
||||
@@ -204,5 +204,6 @@ module.exports = {
|
||||
mergeHeaders,
|
||||
mergeVars,
|
||||
mergeScripts,
|
||||
findItemInCollection,
|
||||
getTreePathFromCollectionToItem
|
||||
}
|
||||
15
packages/bruno-tests/collection/ping-another-one.bru
Normal file
15
packages/bruno-tests/collection/ping-another-one.bru
Normal file
@@ -0,0 +1,15 @@
|
||||
meta {
|
||||
name: ping-another-one
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{host}}/ping
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
throw new Error('this should not execute in a collection run');
|
||||
}
|
||||
@@ -9,3 +9,7 @@ get {
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
bru.runner.stopExecution();
|
||||
}
|
||||
|
||||
@@ -43,7 +43,10 @@ tests {
|
||||
|
||||
test("should get global env var set in runRequest-2", function() {
|
||||
const val = bru.getGlobalEnvVar("run-request-global-env-var");
|
||||
expect(val).to.equal("run-request-global-env-var-value");
|
||||
const executionMode = req.getExecutionMode();
|
||||
if (executionMode == 'runner') {
|
||||
expect(val).to.equal("run-request-global-env-var-value");
|
||||
}
|
||||
});
|
||||
|
||||
test("should get response of runRequest-2", function() {
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
meta {
|
||||
name: runRequest
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
post {
|
||||
url: {{host}}/api/echo/json
|
||||
body: json
|
||||
auth: none
|
||||
}
|
||||
|
||||
headers {
|
||||
foo: bar
|
||||
}
|
||||
|
||||
auth:basic {
|
||||
username: asd
|
||||
password: j
|
||||
}
|
||||
|
||||
auth:bearer {
|
||||
token:
|
||||
}
|
||||
|
||||
body:json {
|
||||
{
|
||||
"hello": "bruno"
|
||||
}
|
||||
}
|
||||
|
||||
assert {
|
||||
res.status: eq 200
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
bru.setVar("runRequest-ping-res-1", null);
|
||||
bru.setVar("runRequest-ping-res-2", null);
|
||||
bru.setVar("runRequest-ping-res-3", null);
|
||||
|
||||
let pingRes = await bru.runRequest('ping');
|
||||
bru.setVar('runRequest-ping-res-1', {
|
||||
data: pingRes?.data,
|
||||
statusText: pingRes?.statusText,
|
||||
status: pingRes?.status
|
||||
});
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
let pingRes = await bru.runRequest('ping');
|
||||
bru.setVar('runRequest-ping-res-2', {
|
||||
data: pingRes?.data,
|
||||
statusText: pingRes?.statusText,
|
||||
status: pingRes?.status
|
||||
});
|
||||
}
|
||||
|
||||
tests {
|
||||
const pingRes = await bru.runRequest('ping');
|
||||
bru.setVar('runRequest-ping-res-3', {
|
||||
data: pingRes?.data,
|
||||
statusText: pingRes?.statusText,
|
||||
status: pingRes?.status
|
||||
});
|
||||
|
||||
test("should run request and return valid response in pre-request script", function() {
|
||||
const expectedPingRes = {
|
||||
data: "pong",
|
||||
statusText: "OK",
|
||||
status: 200
|
||||
};
|
||||
const pingRes = bru.getVar('runRequest-ping-res-1');
|
||||
expect(pingRes).to.eql(expectedPingRes);
|
||||
});
|
||||
|
||||
test("should run request and return valid response in post-response script", function() {
|
||||
const expectedPingRes = {
|
||||
data: "pong",
|
||||
statusText: "OK",
|
||||
status: 200
|
||||
};
|
||||
const pingRes = bru.getVar('runRequest-ping-res-2');
|
||||
expect(pingRes).to.eql(expectedPingRes);
|
||||
});
|
||||
|
||||
test("should run request and return valid response in tests script", function() {
|
||||
const expectedPingRes = {
|
||||
data: "pong",
|
||||
statusText: "OK",
|
||||
status: 200
|
||||
};
|
||||
const pingRes = bru.getVar('runRequest-ping-res-3');
|
||||
expect(pingRes).to.eql(expectedPingRes);
|
||||
});
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
meta {
|
||||
name: 1
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://echo.usebruno.com
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
bru.setVar('bru-runner-req', 1);
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
bru.setVar('bru.runner.skipRequest', true);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
meta {
|
||||
name: 2
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://echo.usebruno.com
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
bru.runner.skipRequest();
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
bru.setVar('bru.runner.skipRequest', false);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
meta {
|
||||
name: 3
|
||||
type: http
|
||||
seq: 3
|
||||
}
|
||||
|
||||
post {
|
||||
url: https://echo.usebruno.com
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
Reference in New Issue
Block a user