mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-25 01:14:23 +01:00
feat: added support for collection/folder/request scripts
This commit is contained in:
parent
9c2c86baf6
commit
5fd6773f43
@ -7,7 +7,7 @@ const { runSingleRequest } = require('../runner/run-single-request');
|
||||
const { bruToEnvJson, getEnvVars } = require('../utils/bru');
|
||||
const makeJUnitOutput = require('../reporters/junit');
|
||||
const makeHtmlOutput = require('../reporters/html');
|
||||
const { rpad, uuid } = require('../utils/common');
|
||||
const { rpad } = require('../utils/common');
|
||||
const { bruToJson, getOptions, collectionBruToJson } = require('../utils/bru');
|
||||
const { dotenvToJson } = require('@usebruno/lang');
|
||||
const constants = require('../constants');
|
||||
@ -93,22 +93,19 @@ const printRunSummary = (results) => {
|
||||
};
|
||||
};
|
||||
|
||||
const getCollection = (dir, testsOnly) => {
|
||||
const environmentsPath = `${dir}/environments`;
|
||||
const getFilesInOrder = (dir) => {
|
||||
const createCollectionFromPath = (collectionPath) => {
|
||||
const environmentsPath = `${collectionPath}/environments`;
|
||||
const getFilesInOrder = (collectionPath) => {
|
||||
let collection = {
|
||||
pathname: dir
|
||||
pathname: collectionPath
|
||||
};
|
||||
|
||||
const traverse = (currentPath) => {
|
||||
const filesInCurrentDir = fs.readdirSync(currentPath);
|
||||
|
||||
if (currentPath.includes('node_modules')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const currentDirBruJsons = [];
|
||||
|
||||
const currentDirItems = [];
|
||||
for (const file of filesInCurrentDir) {
|
||||
const filePath = path.join(currentPath, file);
|
||||
const stats = fs.lstatSync(filePath);
|
||||
@ -118,7 +115,7 @@ const getCollection = (dir, testsOnly) => {
|
||||
!filePath.startsWith('.git') &&
|
||||
!filePath.startsWith('node_modules')
|
||||
) {
|
||||
let folderItem = { uid: uuid(), name: file, pathname: filePath, type: 'folder', items: traverse(filePath) }
|
||||
let folderItem = { name: file, pathname: filePath, type: 'folder', items: traverse(filePath) }
|
||||
const folderBruFilePath = path.join(filePath, 'folder.bru');
|
||||
const folderBruFileExists = fs.existsSync(folderBruFilePath);
|
||||
if(folderBruFileExists) {
|
||||
@ -126,7 +123,7 @@ const getCollection = (dir, testsOnly) => {
|
||||
let folderBruJson = collectionBruToJson(folderBruContent);
|
||||
folderItem.root = folderBruJson;
|
||||
}
|
||||
currentDirBruJsons.push(folderItem);
|
||||
currentDirItems.push(folderItem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,35 +137,19 @@ const getCollection = (dir, testsOnly) => {
|
||||
if (!stats.isDirectory() && path.extname(filePath) === '.bru') {
|
||||
const bruContent = fs.readFileSync(filePath, 'utf8');
|
||||
const bruJson = bruToJson(bruContent);
|
||||
const requestHasTests = bruJson.request?.tests;
|
||||
const requestHasActiveAsserts = bruJson.request?.assertions.some((x) => x.enabled) || false;
|
||||
|
||||
if (testsOnly) {
|
||||
if (requestHasTests || requestHasActiveAsserts) {
|
||||
currentDirBruJsons.push({
|
||||
bruFilepath: filePath,
|
||||
bruJson
|
||||
});
|
||||
}
|
||||
} else {
|
||||
currentDirBruJsons.push({
|
||||
uid: uuid(),
|
||||
name: file,
|
||||
pathname: filePath,
|
||||
...bruJson
|
||||
});
|
||||
}
|
||||
currentDirItems.push({
|
||||
name: file,
|
||||
pathname: filePath,
|
||||
...bruJson
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return currentDirBruJsons
|
||||
return currentDirItems
|
||||
};
|
||||
|
||||
collection.items = traverse(dir);
|
||||
collection.items = traverse(collectionPath);
|
||||
return collection;
|
||||
};
|
||||
|
||||
return getFilesInOrder(dir);
|
||||
return getFilesInOrder(collectionPath);
|
||||
};
|
||||
|
||||
const getBruFilesRecursively = (dir, testsOnly) => {
|
||||
@ -409,7 +390,12 @@ const handler = async function (argv) {
|
||||
const brunoConfigFile = fs.readFileSync(brunoJsonPath, 'utf8');
|
||||
const brunoConfig = JSON.parse(brunoConfigFile);
|
||||
const collectionRoot = getCollectionRoot(collectionPath);
|
||||
const collection = getCollection(collectionPath);
|
||||
let collection = createCollectionFromPath(collectionPath);
|
||||
collection = {
|
||||
brunoConfig,
|
||||
root: collectionRoot,
|
||||
...collection
|
||||
}
|
||||
|
||||
if (filename && filename.length) {
|
||||
const pathExists = await exists(filename);
|
||||
|
@ -1,5 +1,6 @@
|
||||
const { get, each, filter, find } = require('lodash');
|
||||
const { get, each, filter, find, compact } = require('lodash');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
var JSONbig = require('json-bigint');
|
||||
const decomment = require('decomment');
|
||||
|
||||
@ -114,46 +115,50 @@ const mergeVars = (collection, request, requestTreePath) => {
|
||||
}
|
||||
};
|
||||
|
||||
const mergeFolderLevelScripts = (request, requestTreePath, scriptFlow) => {
|
||||
let folderCombinedPreReqScript = [];
|
||||
let folderCombinedPostResScript = [];
|
||||
let folderCombinedTests = [];
|
||||
const mergeScripts = (collection, request, requestTreePath, scriptFlow) => {
|
||||
let collectionPreReqScript = get(collection, 'root.request.script.req', '');
|
||||
let collectionPostResScript = get(collection, 'root.request.script.res', '');
|
||||
let collectionTests = get(collection, 'root.request.tests', '');
|
||||
|
||||
let combinedPreReqScript = [];
|
||||
let combinedPostResScript = [];
|
||||
let combinedTests = [];
|
||||
for (let i of requestTreePath) {
|
||||
if (i.type === 'folder') {
|
||||
let preReqScript = get(i, 'root.request.script.req', '');
|
||||
if (preReqScript && preReqScript.trim() !== '') {
|
||||
folderCombinedPreReqScript.push(preReqScript);
|
||||
combinedPreReqScript.push(preReqScript);
|
||||
}
|
||||
|
||||
let postResScript = get(i, 'root.request.script.res', '');
|
||||
if (postResScript && postResScript.trim() !== '') {
|
||||
folderCombinedPostResScript.push(postResScript);
|
||||
combinedPostResScript.push(postResScript);
|
||||
}
|
||||
|
||||
let tests = get(i, 'root.request.tests', '');
|
||||
if (tests && tests?.trim?.() !== '') {
|
||||
folderCombinedTests.push(tests);
|
||||
combinedTests.push(tests);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (folderCombinedPreReqScript.length) {
|
||||
request.script.req = compact([...folderCombinedPreReqScript, request?.script?.req || '']).join(os.EOL);
|
||||
if (combinedPreReqScript.length) {
|
||||
request.script.req = compact([collectionPreReqScript, ...combinedPreReqScript, request?.script?.req || '']).join(os.EOL);
|
||||
}
|
||||
|
||||
if (folderCombinedPostResScript.length) {
|
||||
if (combinedPostResScript.length) {
|
||||
if (scriptFlow === 'sequential') {
|
||||
request.script.res = compact([...folderCombinedPostResScript, request?.script?.res || '']).join(os.EOL);
|
||||
request.script.res = compact([collectionPostResScript, ...combinedPostResScript, request?.script?.res || '']).join(os.EOL);
|
||||
} else {
|
||||
request.script.res = compact([request?.script?.res || '', ...folderCombinedPostResScript.reverse()]).join(os.EOL);
|
||||
request.script.res = compact([request?.script?.res || '', ...combinedPostResScript.reverse(), collectionPostResScript]).join(os.EOL);
|
||||
}
|
||||
}
|
||||
|
||||
if (folderCombinedTests.length) {
|
||||
if (combinedTests.length) {
|
||||
if (scriptFlow === 'sequential') {
|
||||
request.tests = compact([...folderCombinedTests, request?.tests || '']).join(os.EOL);
|
||||
request.tests = compact([collectionTests, ...combinedTests, request?.tests || '']).join(os.EOL);
|
||||
} else {
|
||||
request.tests = compact([request?.tests || '', ...folderCombinedTests.reverse()]).join(os.EOL);
|
||||
request.tests = compact([request?.tests || '', ...combinedTests.reverse(), collectionTests]).join(os.EOL);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -245,7 +250,7 @@ const prepareRequest = (item = {}, collection = {}) => {
|
||||
const requestTreePath = getTreePathFromCollectionToItem(collection, item);
|
||||
if (requestTreePath && requestTreePath.length > 0) {
|
||||
mergeHeaders(collection, request, requestTreePath);
|
||||
mergeFolderLevelScripts(request, requestTreePath, scriptFlow);
|
||||
mergeScripts(collection, request, requestTreePath, scriptFlow);
|
||||
mergeVars(collection, request, requestTreePath);
|
||||
}
|
||||
|
||||
@ -376,7 +381,7 @@ const prepareRequest = (item = {}, collection = {}) => {
|
||||
axiosRequest.data = graphqlQuery;
|
||||
}
|
||||
|
||||
if (request.script && request.script.length) {
|
||||
if (request.script) {
|
||||
axiosRequest.script = request.script;
|
||||
}
|
||||
|
||||
|
@ -40,14 +40,12 @@ const runSingleRequest = async function (
|
||||
try {
|
||||
let request;
|
||||
let nextRequestName;
|
||||
let item = {
|
||||
pathname: `${collectionPath}/${filename}`,
|
||||
...bruJson
|
||||
}
|
||||
|
||||
collection = {
|
||||
root: collectionRoot,
|
||||
brunoConfig,
|
||||
...collection
|
||||
};
|
||||
|
||||
request = prepareRequest({ pathname: `${collectionPath}/${filename}`, ...bruJson }, collection);
|
||||
request = prepareRequest(item, collection);
|
||||
|
||||
const scriptingConfig = get(brunoConfig, 'scripts', {});
|
||||
scriptingConfig.runtime = runtime;
|
||||
@ -68,10 +66,7 @@ const runSingleRequest = async function (
|
||||
}
|
||||
|
||||
// run pre request script
|
||||
const requestScriptFile = compact([
|
||||
get(collectionRoot, 'request.script.req'),
|
||||
get(bruJson, 'request.script.req')
|
||||
]).join(os.EOL);
|
||||
const requestScriptFile = get(request, 'script.req');
|
||||
if (requestScriptFile?.length) {
|
||||
const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime });
|
||||
const result = await scriptRuntime.runRequestScript(
|
||||
@ -288,10 +283,7 @@ const runSingleRequest = async function (
|
||||
}
|
||||
|
||||
// run post response script
|
||||
const responseScriptFile = compact([
|
||||
get(collectionRoot, 'request.script.res'),
|
||||
get(bruJson, 'request.script.res')
|
||||
]).join(os.EOL);
|
||||
const responseScriptFile = get(request, 'script.res');
|
||||
if (responseScriptFile?.length) {
|
||||
const scriptRuntime = new ScriptRuntime({ runtime: scriptingConfig?.runtime });
|
||||
const result = await scriptRuntime.runResponseScript(
|
||||
@ -336,7 +328,7 @@ const runSingleRequest = async function (
|
||||
|
||||
// run tests
|
||||
let testResults = [];
|
||||
const testFile = compact([get(collectionRoot, 'request.tests'), get(bruJson, 'request.tests')]).join(os.EOL);
|
||||
const testFile = get(request, 'tests');
|
||||
if (typeof testFile === 'string') {
|
||||
const testRuntime = new TestRuntime({ runtime: scriptingConfig?.runtime });
|
||||
const result = await testRuntime.runTests(
|
||||
|
@ -1,5 +1,3 @@
|
||||
const { customAlphabet } = require('nanoid');
|
||||
|
||||
const lpad = (str, width) => {
|
||||
let paddedStr = str;
|
||||
while (paddedStr.length < width) {
|
||||
@ -16,16 +14,7 @@ const rpad = (str, width) => {
|
||||
return paddedStr;
|
||||
};
|
||||
|
||||
const uuid = () => {
|
||||
// https://github.com/ai/nanoid/blob/main/url-alphabet/index.js
|
||||
const urlAlphabet = 'useandom26T198340PX75pxJACKVERYMINDBUSHWOLFGQZbfghjklqvwyzrict';
|
||||
const customNanoId = customAlphabet(urlAlphabet, 21);
|
||||
|
||||
return customNanoId();
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
lpad,
|
||||
rpad,
|
||||
uuid
|
||||
rpad
|
||||
};
|
||||
|
12
packages/bruno-tests/sandwich_exec/bruno.json
Normal file
12
packages/bruno-tests/sandwich_exec/bruno.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": "1",
|
||||
"name": "sandwich_exec",
|
||||
"type": "collection",
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
".git"
|
||||
],
|
||||
"scripts": {
|
||||
"flow": "sandwich"
|
||||
}
|
||||
}
|
13
packages/bruno-tests/sandwich_exec/collection.bru
Normal file
13
packages/bruno-tests/sandwich_exec/collection.bru
Normal file
@ -0,0 +1,13 @@
|
||||
script:pre-request {
|
||||
console.log("collection pre");
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
{
|
||||
console.log("collection post");
|
||||
const sequence = bru.getVar('sequence') || [];
|
||||
sequence.push(1);
|
||||
bru.setVar('sequence', sequence);
|
||||
console.log("sequence", bru.getVar('sequence'));
|
||||
}
|
||||
}
|
16
packages/bruno-tests/sandwich_exec/folder/folder.bru
Normal file
16
packages/bruno-tests/sandwich_exec/folder/folder.bru
Normal file
@ -0,0 +1,16 @@
|
||||
meta {
|
||||
name: folder
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
console.log("folder pre");
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
{
|
||||
const sequence = bru.getVar('sequence') || [];
|
||||
sequence.push(2);
|
||||
bru.setVar('sequence', sequence);
|
||||
}
|
||||
console.log("folder post");
|
||||
}
|
33
packages/bruno-tests/sandwich_exec/folder/request.bru
Normal file
33
packages/bruno-tests/sandwich_exec/folder/request.bru
Normal file
@ -0,0 +1,33 @@
|
||||
meta {
|
||||
name: request
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: https://www.example.com
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
console.log("request pre");
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
{
|
||||
console.log("request post");
|
||||
|
||||
const sequence = bru.getVar('sequence') || [];
|
||||
sequence.push(3);
|
||||
bru.setVar('sequence', sequence);
|
||||
}
|
||||
}
|
||||
|
||||
tests {
|
||||
test("sandwich script execution is proper", function() {
|
||||
const sequence = bru.getVar('sequence');
|
||||
bru.setVar('sequence', null);
|
||||
expect(sequence.toString()).to.equal([3,2,1].toString());
|
||||
});
|
||||
}
|
12
packages/bruno-tests/sequential_exec/bruno.json
Normal file
12
packages/bruno-tests/sequential_exec/bruno.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": "1",
|
||||
"name": "sequential_exec",
|
||||
"type": "collection",
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
".git"
|
||||
],
|
||||
"scripts": {
|
||||
"flow": "sequential"
|
||||
}
|
||||
}
|
12
packages/bruno-tests/sequential_exec/collection.bru
Normal file
12
packages/bruno-tests/sequential_exec/collection.bru
Normal file
@ -0,0 +1,12 @@
|
||||
script:pre-request {
|
||||
console.log("collection pre");
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
{
|
||||
console.log("collection post");
|
||||
const sequence = bru.getVar('sequence') || [];
|
||||
sequence.push(1);
|
||||
bru.setVar('sequence', sequence);
|
||||
}
|
||||
}
|
16
packages/bruno-tests/sequential_exec/folder/folder.bru
Normal file
16
packages/bruno-tests/sequential_exec/folder/folder.bru
Normal file
@ -0,0 +1,16 @@
|
||||
meta {
|
||||
name: folder
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
console.log("folder pre");
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
{
|
||||
console.log("folder post");
|
||||
const sequence = bru.getVar('sequence') || [];
|
||||
sequence.push(2);
|
||||
bru.setVar('sequence', sequence);
|
||||
}
|
||||
}
|
34
packages/bruno-tests/sequential_exec/folder/request.bru
Normal file
34
packages/bruno-tests/sequential_exec/folder/request.bru
Normal file
@ -0,0 +1,34 @@
|
||||
meta {
|
||||
name: request
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: https://www.example.com
|
||||
body: none
|
||||
auth: none
|
||||
}
|
||||
|
||||
script:pre-request {
|
||||
console.log("request pre");
|
||||
}
|
||||
|
||||
script:post-response {
|
||||
{
|
||||
console.log("request post");
|
||||
const sequence = bru.getVar('sequence') || [];
|
||||
sequence.push(3);
|
||||
bru.setVar('sequence', sequence);
|
||||
|
||||
console.log("sequence", bru.getVar('sequence'));
|
||||
}
|
||||
}
|
||||
|
||||
tests {
|
||||
test("sequential script execution is proper", function() {
|
||||
const sequence = bru.getVar('sequence');
|
||||
bru.setVar('sequence', null);
|
||||
expect(sequence.toString()).to.equal([1,2,3].toString());
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user