Feat/support missing env apis (#7069)

* feat: add support for new variable management functions in Bruno

- Implemented methods to retrieve and delete all environment and global variables.
- Added corresponding translations for new functions in Postman and Bruno converters.
- Updated request handling to include header deletion functionality.
- Enhanced test cases to cover new variable management features.

* feat: add new scripts for environment and global variable management

- Introduced scripts to delete all environment and global variables.
- Added functionality to retrieve all environment and global variables.
- Implemented tests to validate the behavior of new variable management features.

* feat: implement collection variable management in Bruno

- Added methods for managing collection variables: set, get, has, delete, and retrieve all.
- Updated Postman translation functions to reflect new collection variable methods.
- Enhanced tests to validate the functionality of collection variable management.
- Refactored existing code to replace environment variable references with collection variable equivalents.

* feat: enhance collection variable translations in Bruno

- Updated translation functions for collection variable management to align with Postman API.
- Added tests for new collection variable methods: set, has, delete, retrieve all, and clear.
- Refactored existing tests to ensure accurate translation of collection variable operations.

* feat: expand API hints for variable management in Bruno

* fix: test cases

* fix: remove unnecessary return in deleteEnvVar function
This commit is contained in:
sanish chirayath
2026-02-12 18:38:25 +05:30
committed by GitHub
parent 91467f699c
commit e03cf9a519
29 changed files with 605 additions and 42 deletions

View File

@@ -23,6 +23,7 @@ const STATIC_API_HINTS = {
'req.getHeaders()',
'req.setHeader(name, value)',
'req.setHeaders(data)',
'req.deleteHeader(name)',
'req.getBody()',
'req.setBody(data)',
'req.setMaxRedirects(maxRedirects)',
@@ -65,14 +66,22 @@ const STATIC_API_HINTS = {
'bru.getEnvVar(key)',
'bru.getFolderVar(key)',
'bru.getCollectionVar(key)',
'bru.setCollectionVar(key, value)',
'bru.hasCollectionVar(key)',
'bru.deleteCollectionVar(key)',
'bru.deleteAllCollectionVars()',
'bru.getAllCollectionVars()',
'bru.setEnvVar(key, value)',
'bru.setEnvVar(key, value, options)',
'bru.deleteEnvVar(key)',
'bru.getAllEnvVars()',
'bru.deleteAllEnvVars()',
'bru.hasVar(key)',
'bru.getVar(key)',
'bru.setVar(key,value)',
'bru.deleteVar(key)',
'bru.deleteAllVars()',
'bru.getAllVars()',
'bru.setNextRequest(requestName)',
'bru.getRequestVar(key)',
'bru.runRequest(requestPathName)',
@@ -83,8 +92,12 @@ const STATIC_API_HINTS = {
'bru.sleep(ms)',
'bru.getCollectionName()',
'bru.isSafeMode()',
'bru.getOauth2CredentialVar(key)',
'bru.getGlobalEnvVar(key)',
'bru.setGlobalEnvVar(key, value)',
'bru.deleteGlobalEnvVar(key)',
'bru.getAllGlobalEnvVars()',
'bru.deleteAllGlobalEnvVars()',
'bru.runner',
'bru.runner.setNextRequest(requestName)',
'bru.runner.skipRequest()',

View File

@@ -6,10 +6,12 @@ const replacements = {
'pm\\.variables\\.get\\(': 'bru.getVar(',
'pm\\.variables\\.set\\(': 'bru.setVar(',
'pm\\.variables\\.replaceIn\\(': 'bru.interpolate(',
'pm\\.collectionVariables\\.get\\(': 'bru.getVar(',
'pm\\.collectionVariables\\.set\\(': 'bru.setVar(',
'pm\\.collectionVariables\\.has\\(': 'bru.hasVar(',
'pm\\.collectionVariables\\.unset\\(': 'bru.deleteVar(',
'pm\\.collectionVariables\\.get\\(': 'bru.getCollectionVar(',
'pm\\.collectionVariables\\.set\\(': 'bru.setCollectionVar(',
'pm\\.collectionVariables\\.has\\(': 'bru.hasCollectionVar(',
'pm\\.collectionVariables\\.unset\\(': 'bru.deleteCollectionVar(',
'pm\\.collectionVariables\\.clear\\(': 'bru.deleteAllCollectionVars(',
'pm\\.collectionVariables\\.toObject\\(': 'bru.getAllCollectionVars(',
'pm\\.setNextRequest\\(': 'bru.setNextRequest(',
'pm\\.test\\(': 'test(',
'pm.response.to.have\\.status\\(': 'expect(res.getStatus()).to.equal(',
@@ -23,6 +25,13 @@ const replacements = {
'pm\\.response\\.responseTime': 'res.getResponseTime()',
'pm\\.globals\\.set\\(': 'bru.setGlobalEnvVar(',
'pm\\.globals\\.get\\(': 'bru.getGlobalEnvVar(',
'pm\\.globals\\.unset\\(': 'bru.deleteGlobalEnvVar(',
'pm\\.globals\\.toObject\\(': 'bru.getAllGlobalEnvVars(',
'pm\\.globals\\.clear\\(': 'bru.deleteAllGlobalEnvVars(',
'pm\\.environment\\.toObject\\(': 'bru.getAllEnvVars(',
'pm\\.environment\\.clear\\(': 'bru.deleteAllEnvVars(',
'pm\\.variables\\.toObject\\(': 'bru.getAllVars(',
'pm\\.request\\.headers\\.remove\\(': 'req.deleteHeader(',
'pm\\.response\\.headers\\.get\\(': 'res.getHeader(',
'pm\\.response\\.to\\.have\\.body\\(': 'expect(res.getBody()).to.equal(',
'pm\\.response\\.to\\.have\\.header\\(': 'expect(res.getHeaders()).to.have.property(',

View File

@@ -17,12 +17,17 @@ const simpleTranslations = {
// Global variables
'bru.getGlobalEnvVar': 'pm.globals.get',
'bru.setGlobalEnvVar': 'pm.globals.set',
'bru.deleteGlobalEnvVar': 'pm.globals.unset',
'bru.getAllGlobalEnvVars': 'pm.globals.toObject',
'bru.deleteAllGlobalEnvVars': 'pm.globals.clear',
// Environment variables
'bru.getEnvVar': 'pm.environment.get',
'bru.setEnvVar': 'pm.environment.set',
'bru.hasEnvVar': 'pm.environment.has',
'bru.deleteEnvVar': 'pm.environment.unset',
'bru.getAllEnvVars': 'pm.environment.toObject',
'bru.deleteAllEnvVars': 'pm.environment.clear',
// Note: bru.getEnvName() is handled in complexTransformations because it's a function -> property conversion
// Runtime variables
@@ -30,11 +35,16 @@ const simpleTranslations = {
'bru.setVar': 'pm.variables.set',
'bru.hasVar': 'pm.variables.has',
'bru.deleteVar': 'pm.variables.unset',
'bru.getAllVars': 'pm.variables.toObject',
// 'bru.deleteAllVars': Postman does not have a way to delete all variables
// Collection variables
'bru.getCollectionVar': 'pm.variables.get',
/* Bruno does not have a way to set, has or delete collection variables */
'bru.getCollectionVar': 'pm.collectionVariables.get',
'bru.setCollectionVar': 'pm.collectionVariables.set',
'bru.hasCollectionVar': 'pm.collectionVariables.has',
'bru.deleteCollectionVar': 'pm.collectionVariables.unset',
'bru.getAllCollectionVars': 'pm.collectionVariables.toObject',
'bru.deleteAllCollectionVars': 'pm.collectionVariables.clear',
// Folder variables
'bru.getFolderVar': 'pm.variables.get',
@@ -61,6 +71,7 @@ const simpleTranslations = {
'req.body': 'pm.request.body',
'req.getHeader': 'pm.request.headers.get',
'req.setHeader': 'pm.request.headers.set',
'req.deleteHeader': 'pm.request.headers.remove',
// URL helper methods
'req.getHost': 'pm.request.url.getHost',

View File

@@ -9,6 +9,9 @@ const simpleTranslations = {
'pm.globals.get': 'bru.getGlobalEnvVar',
'pm.globals.set': 'bru.setGlobalEnvVar',
'pm.globals.replaceIn': 'bru.interpolate',
'pm.globals.unset': 'bru.deleteGlobalEnvVar',
'pm.globals.toObject': 'bru.getAllGlobalEnvVars',
'pm.globals.clear': 'bru.deleteAllGlobalEnvVars',
// Environment variables
'pm.environment.get': 'bru.getEnvVar',
@@ -16,18 +19,23 @@ const simpleTranslations = {
'pm.environment.name': 'bru.getEnvName()',
'pm.environment.unset': 'bru.deleteEnvVar',
'pm.environment.replaceIn': 'bru.interpolate',
'pm.environment.toObject': 'bru.getAllEnvVars',
'pm.environment.clear': 'bru.deleteAllEnvVars',
// Variables
'pm.variables.get': 'bru.getVar',
'pm.variables.set': 'bru.setVar',
'pm.variables.has': 'bru.hasVar',
'pm.variables.toObject': 'bru.getAllVars',
'pm.variables.replaceIn': 'bru.interpolate',
// Collection variables
'pm.collectionVariables.get': 'bru.getVar',
'pm.collectionVariables.set': 'bru.setVar',
'pm.collectionVariables.has': 'bru.hasVar',
'pm.collectionVariables.unset': 'bru.deleteVar',
'pm.collectionVariables.get': 'bru.getCollectionVar',
'pm.collectionVariables.set': 'bru.setCollectionVar',
'pm.collectionVariables.has': 'bru.hasCollectionVar',
'pm.collectionVariables.unset': 'bru.deleteCollectionVar',
'pm.collectionVariables.replaceIn': 'bru.interpolate',
'pm.collectionVariables.clear': 'bru.deleteAllCollectionVars',
'pm.collectionVariables.toObject': 'bru.getAllCollectionVars',
// Request flow control
'pm.setNextRequest': 'bru.setNextRequest',
@@ -40,6 +48,9 @@ const simpleTranslations = {
// Info
'pm.info.requestName': 'req.getName()',
// Request headers
'pm.request.headers.remove': 'req.deleteHeader',
// Request properties (pm.request.*)
'pm.request.url.getHost': 'req.getHost',
'pm.request.url.getPath': 'req.getPath',

View File

@@ -55,7 +55,37 @@ describe('Bruno to Postman Variables Translation', () => {
it('should translate bru.getCollectionVar', () => {
const code = 'bru.getCollectionVar("baseUrl");';
const translatedCode = translateBruToPostman(code);
expect(translatedCode).toBe('pm.variables.get("baseUrl");');
expect(translatedCode).toBe('pm.collectionVariables.get("baseUrl");');
});
it('should translate bru.setCollectionVar', () => {
const code = 'bru.setCollectionVar("baseUrl", "https://api.example.com");';
const translatedCode = translateBruToPostman(code);
expect(translatedCode).toBe('pm.collectionVariables.set("baseUrl", "https://api.example.com");');
});
it('should translate bru.hasCollectionVar', () => {
const code = 'bru.hasCollectionVar("baseUrl");';
const translatedCode = translateBruToPostman(code);
expect(translatedCode).toBe('pm.collectionVariables.has("baseUrl");');
});
it('should translate bru.deleteCollectionVar', () => {
const code = 'bru.deleteCollectionVar("baseUrl");';
const translatedCode = translateBruToPostman(code);
expect(translatedCode).toBe('pm.collectionVariables.unset("baseUrl");');
});
it('should translate bru.getAllCollectionVars', () => {
const code = 'const vars = bru.getAllCollectionVars();';
const translatedCode = translateBruToPostman(code);
expect(translatedCode).toBe('const vars = pm.collectionVariables.toObject();');
});
it('should translate bru.deleteAllCollectionVars', () => {
const code = 'bru.deleteAllCollectionVars();';
const translatedCode = translateBruToPostman(code);
expect(translatedCode).toBe('pm.collectionVariables.clear();');
});
// Folder variables tests

View File

@@ -10,14 +10,14 @@ describe('postmanTranslations - comment handling', () => {
const expectedOutput = `
console.log('This script does not contain pm commands.');
const data = bru.getEnvVar('key');
bru.setVar('key', data);
bru.setCollectionVar('key', data);
`;
expect(postmanTranslation(inputScript)).toBe(expectedOutput);
});
test('should comment non-translated pm commands', () => {
const inputScript = 'pm.test(\'random test\', () => pm.globals.clear());';
const expectedOutput = '// test(\'random test\', () => pm.globals.clear());';
const inputScript = 'pm.test(\'random test\', () => pm.vault.get(secretPath));';
const expectedOutput = '// test(\'random test\', () => pm.vault.get(secretPath));';
expect(postmanTranslation(inputScript)).toBe(expectedOutput);
});

View File

@@ -29,13 +29,13 @@ describe('postmanTranslations - edge cases', () => {
value: bru.getVar('value')
},
{
key: bru.getVar('key'),
value: bru.getVar('value')
key: bru.getCollectionVar('key'),
value: bru.getCollectionVar('value')
}
];
const dataTesting = Object.entries(sampleObjects || {}).reduce((acc, [key, value]) => {
// this is a comment
acc[key] = bru.getVar(bru.getEnvVar(value));
acc[key] = bru.getCollectionVar(bru.getEnvVar(value));
return acc; // Return the accumulator
}, {});
Object.values(dataTesting).forEach((data) => {

View File

@@ -16,8 +16,8 @@ describe('postmanTranslations - variables commands', () => {
bru.setEnvVar('key', 'value');
bru.getVar('key');
bru.setVar('key', 'value');
bru.getVar('key');
bru.setVar('key', 'value');
bru.getCollectionVar('key');
bru.setCollectionVar('key', 'value');
expect(bru.getEnvVar('key') !== undefined && bru.getEnvVar('key') !== null).to.be.true;
`;
expect(postmanTranslation(inputScript)).toBe(expectedOutput);

View File

@@ -99,7 +99,7 @@ describe('Combined API Features Translation', () => {
expect(translatedCode).toContain('const response = res.getBody();');
expect(translatedCode).toContain('expect(response.authenticated).to.be.true;');
expect(translatedCode).toContain('bru.setEnvVar("userId", response.user.id);');
expect(translatedCode).toContain('bru.setVar("sessionId", response.session.id);');
expect(translatedCode).toContain('bru.setCollectionVar("sessionId", response.session.id);');
});
// Nested expressions
@@ -112,7 +112,7 @@ describe('Combined API Features Translation', () => {
it('should handle more complex nested expressions', () => {
const code = 'pm.collectionVariables.set("fullPath", pm.environment.get("baseUrl") + pm.variables.get("endpoint"));';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('bru.setVar("fullPath", bru.getEnvVar("baseUrl") + bru.getVar("endpoint"));');
expect(translatedCode).toBe('bru.setCollectionVar("fullPath", bru.getEnvVar("baseUrl") + bru.getVar("endpoint"));');
});
// Unrelated code
@@ -352,7 +352,7 @@ describe('Combined API Features Translation', () => {
test("Status code is 200", function() { expect(res.getStatus()).to.equal(200); });
bru.setEnvVar("userId", res.getBody().userId);
bru.setVar("token", res.getBody().token);
bru.setVar("sessionId", res.getBody().sessionId);
bru.setCollectionVar("sessionId", res.getBody().sessionId);
}
`);
});
@@ -366,7 +366,7 @@ describe('Combined API Features Translation', () => {
`;
const translatedCode = translateCode(code);
expect(translatedCode).toBe(`
bru.getVar(bru.getEnvVar('key'))
bru.getCollectionVar(bru.getEnvVar('key'))
test("Status code is 200", function() {
expect(res.getStatus()).to.equal(200);
});

View File

@@ -43,8 +43,8 @@ describe('Multiline Syntax Handling', () => {
`;
const translatedCode = translateCode(code);
expect(translatedCode).toBe(`
const apiKey = bru.getVar("apiKey");
bru.setVar("lastRun", new Date().toISOString());
const apiKey = bru.getCollectionVar("apiKey");
bru.setCollectionVar("lastRun", new Date().toISOString());
`);
});
@@ -265,7 +265,7 @@ describe('Multiline Syntax Handling', () => {
expect(translatedCode).toContain('bru.setVar("timestamp", new Date().toISOString())');
// Check collection variables
expect(translatedCode).toContain('bru.setVar("lastRun", new Date())');
expect(translatedCode).toContain('bru.setCollectionVar("lastRun", new Date())');
// Check complex conditionals
expect(translatedCode).toContain('if (bru.getEnvVar("apiKey") !== undefined && bru.getEnvVar("apiKey") !== null &&');

View File

@@ -281,7 +281,7 @@ describe('Response Translation', () => {
const translatedCode = translateCode(code);
expect(translatedCode).toContain('const items = res.getBody().items;');
expect(translatedCode).toContain('bru.setVar("item_" + i, items[i].id);');
expect(translatedCode).toContain('bru.setCollectionVar("item_" + i, items[i].id);');
});
it('should handle response JSON with optional chaining and nullish coalescing', () => {

View File

@@ -67,7 +67,7 @@ describe('Testing Framework Translation', () => {
expect(translatedCode).toContain('const response = res.getBody();');
expect(translatedCode).toContain('expect(response.authenticated).to.be.true;');
expect(translatedCode).toContain('bru.setEnvVar("userId", response.user.id);');
expect(translatedCode).toContain('bru.setVar("sessionId", response.session.id);');
expect(translatedCode).toContain('bru.setCollectionVar("sessionId", response.session.id);');
});
it('should translate pm.test with arrow functions', () => {

View File

@@ -68,28 +68,28 @@ describe('Variables Translation', () => {
const code = 'pm.collectionVariables.get("apiUrl");';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('bru.getVar("apiUrl");');
expect(translatedCode).toBe('bru.getCollectionVar("apiUrl");');
});
it('should translate pm.collectionVariables.set', () => {
const code = 'pm.collectionVariables.set("token", jsonData.token);';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('bru.setVar("token", jsonData.token);');
expect(translatedCode).toBe('bru.setCollectionVar("token", jsonData.token);');
});
it('should translate pm.collectionVariables.has', () => {
const code = 'pm.collectionVariables.has("authToken");';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('bru.hasVar("authToken");');
expect(translatedCode).toBe('bru.hasCollectionVar("authToken");');
});
it('should translate pm.collectionVariables.unset', () => {
const code = 'pm.collectionVariables.unset("tempVar");';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('bru.deleteVar("tempVar");');
expect(translatedCode).toBe('bru.deleteCollectionVar("tempVar");');
});
it('should handle pm.globals.get', () => {
@@ -135,10 +135,10 @@ describe('Variables Translation', () => {
const translatedCode = translateCode(code);
expect(translatedCode).toBe(`
const has = bru.hasVar("test");
const set = bru.setVar("test", "value");
const get = bru.getVar("test");
const unset = bru.deleteVar("test");
const has = bru.hasCollectionVar("test");
const set = bru.setCollectionVar("test", "value");
const get = bru.getCollectionVar("test");
const unset = bru.deleteCollectionVar("test");
`);
});
@@ -192,17 +192,17 @@ describe('Variables Translation', () => {
`;
const translatedCode = translateCode(code);
expect(translatedCode).toContain('const hasApiUrl = bru.hasVar("apiUrl");');
expect(translatedCode).toContain('const apiUrl = bru.getVar("apiUrl");');
expect(translatedCode).toContain('bru.setVar("requestTime", new Date().toISOString());');
expect(translatedCode).toContain('bru.deleteVar("tempVar");');
expect(translatedCode).toContain('const hasApiUrl = bru.hasCollectionVar("apiUrl");');
expect(translatedCode).toContain('const apiUrl = bru.getCollectionVar("apiUrl");');
expect(translatedCode).toContain('bru.setCollectionVar("requestTime", new Date().toISOString());');
expect(translatedCode).toContain('bru.deleteCollectionVar("tempVar");');
});
it('should handle more complex nested expressions with variables', () => {
const code = 'pm.collectionVariables.set("fullPath", pm.environment.get("baseUrl") + pm.variables.get("endpoint"));';
const translatedCode = translateCode(code);
expect(translatedCode).toBe('bru.setVar("fullPath", bru.getEnvVar("baseUrl") + bru.getVar("endpoint"));');
expect(translatedCode).toBe('bru.setCollectionVar("fullPath", bru.getEnvVar("baseUrl") + bru.getVar("endpoint"));');
});
// replaceIn tests for different variable scopes

View File

@@ -225,6 +225,24 @@ class Bru {
delete this.envVariables[key];
}
getAllEnvVars() {
const vars = Object.assign({}, this.envVariables);
delete vars.__name__;
return vars;
}
deleteAllEnvVars() {
const envName = this.envVariables.__name__;
for (let key in this.envVariables) {
if (this.envVariables.hasOwnProperty(key)) {
delete this.envVariables[key];
}
}
if (envName !== undefined) {
this.envVariables.__name__ = envName;
}
}
getGlobalEnvVar(key) {
return this.interpolate(this.globalEnvironmentVariables[key]);
}
@@ -237,6 +255,22 @@ class Bru {
this.globalEnvironmentVariables[key] = value;
}
deleteGlobalEnvVar(key) {
delete this.globalEnvironmentVariables[key];
}
getAllGlobalEnvVars() {
return Object.assign({}, this.globalEnvironmentVariables);
}
deleteAllGlobalEnvVars() {
for (let key in this.globalEnvironmentVariables) {
if (this.globalEnvironmentVariables.hasOwnProperty(key)) {
delete this.globalEnvironmentVariables[key];
}
}
}
getOauth2CredentialVar(key) {
return this.interpolate(this.oauth2CredentialVariables[key]);
}
@@ -283,10 +317,49 @@ class Bru {
}
}
getAllVars() {
return Object.assign({}, this.runtimeVariables);
}
getCollectionVar(key) {
return this.interpolate(this.collectionVariables[key]);
}
setCollectionVar(key, value) {
if (!key) {
throw new Error('Creating a variable without specifying a name is not allowed.');
}
if (variableNameRegex.test(key) === false) {
throw new Error(
`Variable name: "${key}" contains invalid characters!`
+ ' Names must only contain alpha-numeric characters, "-", "_", "."'
);
}
this.collectionVariables[key] = value;
}
hasCollectionVar(key) {
return Object.hasOwn(this.collectionVariables, key);
}
deleteCollectionVar(key) {
delete this.collectionVariables[key];
}
deleteAllCollectionVars() {
for (let key in this.collectionVariables) {
if (this.collectionVariables.hasOwnProperty(key)) {
delete this.collectionVariables[key];
}
}
}
getAllCollectionVars() {
return Object.assign({}, this.collectionVariables);
}
getFolderVar(key) {
return this.interpolate(this.folderVariables[key]);
}

View File

@@ -134,6 +134,11 @@ class BrunoRequest {
this.req.headers[name] = value;
}
deleteHeader(name) {
delete this.headers[name];
delete this.req.headers[name];
}
hasJSONContentType(headers) {
const contentType = headers?.['Content-Type'] || headers?.['content-type'] || '';
return contentType.includes('json');

View File

@@ -60,11 +60,23 @@ const addBruShimToContext = (vm, bru) => {
setEnvVar.dispose();
let deleteEnvVar = vm.newFunction('deleteEnvVar', function (key) {
return marshallToVm(bru.deleteEnvVar(vm.dump(key)), vm);
bru.deleteEnvVar(vm.dump(key));
});
vm.setProp(bruObject, 'deleteEnvVar', deleteEnvVar);
deleteEnvVar.dispose();
let getAllEnvVars = vm.newFunction('getAllEnvVars', function () {
return marshallToVm(bru.getAllEnvVars(), vm);
});
vm.setProp(bruObject, 'getAllEnvVars', getAllEnvVars);
getAllEnvVars.dispose();
let deleteAllEnvVars = vm.newFunction('deleteAllEnvVars', function () {
bru.deleteAllEnvVars();
});
vm.setProp(bruObject, 'deleteAllEnvVars', deleteAllEnvVars);
deleteAllEnvVars.dispose();
let getGlobalEnvVar = vm.newFunction('getGlobalEnvVar', function (key) {
return marshallToVm(bru.getGlobalEnvVar(vm.dump(key)), vm);
});
@@ -83,6 +95,24 @@ const addBruShimToContext = (vm, bru) => {
vm.setProp(bruObject, 'setGlobalEnvVar', setGlobalEnvVar);
setGlobalEnvVar.dispose();
let deleteGlobalEnvVar = vm.newFunction('deleteGlobalEnvVar', function (key) {
bru.deleteGlobalEnvVar(vm.dump(key));
});
vm.setProp(bruObject, 'deleteGlobalEnvVar', deleteGlobalEnvVar);
deleteGlobalEnvVar.dispose();
let getAllGlobalEnvVars = vm.newFunction('getAllGlobalEnvVars', function () {
return marshallToVm(bru.getAllGlobalEnvVars(), vm);
});
vm.setProp(bruObject, 'getAllGlobalEnvVars', getAllGlobalEnvVars);
getAllGlobalEnvVars.dispose();
let deleteAllGlobalEnvVars = vm.newFunction('deleteAllGlobalEnvVars', function () {
bru.deleteAllGlobalEnvVars();
});
vm.setProp(bruObject, 'deleteAllGlobalEnvVars', deleteAllGlobalEnvVars);
deleteAllGlobalEnvVars.dispose();
let hasVar = vm.newFunction('hasVar', function (key) {
return marshallToVm(bru.hasVar(vm.dump(key)), vm);
});
@@ -113,6 +143,12 @@ const addBruShimToContext = (vm, bru) => {
vm.setProp(bruObject, 'deleteAllVars', deleteAllVars);
deleteAllVars.dispose();
let getAllVars = vm.newFunction('getAllVars', function () {
return marshallToVm(bru.getAllVars(), vm);
});
vm.setProp(bruObject, 'getAllVars', getAllVars);
getAllVars.dispose();
let setNextRequest = vm.newFunction('setNextRequest', function (nextRequest) {
bru.setNextRequest(vm.dump(nextRequest));
});
@@ -167,6 +203,36 @@ const addBruShimToContext = (vm, bru) => {
vm.setProp(bruObject, 'getCollectionVar', getCollectionVar);
getCollectionVar.dispose();
let setCollectionVar = vm.newFunction('setCollectionVar', function (key, value) {
bru.setCollectionVar(vm.dump(key), vm.dump(value));
});
vm.setProp(bruObject, 'setCollectionVar', setCollectionVar);
setCollectionVar.dispose();
let hasCollectionVar = vm.newFunction('hasCollectionVar', function (key) {
return marshallToVm(bru.hasCollectionVar(vm.dump(key)), vm);
});
vm.setProp(bruObject, 'hasCollectionVar', hasCollectionVar);
hasCollectionVar.dispose();
let deleteCollectionVar = vm.newFunction('deleteCollectionVar', function (key) {
bru.deleteCollectionVar(vm.dump(key));
});
vm.setProp(bruObject, 'deleteCollectionVar', deleteCollectionVar);
deleteCollectionVar.dispose();
let deleteAllCollectionVars = vm.newFunction('deleteAllCollectionVars', function () {
bru.deleteAllCollectionVars();
});
vm.setProp(bruObject, 'deleteAllCollectionVars', deleteAllCollectionVars);
deleteAllCollectionVars.dispose();
let getAllCollectionVars = vm.newFunction('getAllCollectionVars', function () {
return marshallToVm(bru.getAllCollectionVars(), vm);
});
vm.setProp(bruObject, 'getAllCollectionVars', getAllCollectionVars);
getAllCollectionVars.dispose();
let getTestResults = vm.newFunction('getTestResults', () => {
const promise = vm.newPromise();
bru

View File

@@ -114,6 +114,12 @@ const addBrunoRequestShimToContext = (vm, req) => {
vm.setProp(reqObject, 'setHeader', setHeader);
setHeader.dispose();
let deleteHeader = vm.newFunction('deleteHeader', function (name) {
req.deleteHeader(vm.dump(name));
});
vm.setProp(reqObject, 'deleteHeader', deleteHeader);
deleteHeader.dispose();
let getBody = vm.newFunction('getBody', function (options = {}) {
return marshallToVm(req.getBody(vm.dump(options)), vm);
});

View File

@@ -0,0 +1,33 @@
meta {
name: deleteAllCollectionVars
type: http
seq: 28
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:pre-request {
bru.setCollectionVar("testDelAllCollectionA", "a");
bru.setCollectionVar("testDelAllCollectionB", "b");
}
tests {
const savedCollectionVars = bru.getAllCollectionVars();
bru.deleteAllCollectionVars();
test("should delete all collection vars", function() {
const valA = bru.getCollectionVar("testDelAllCollectionA");
const valB = bru.getCollectionVar("testDelAllCollectionB");
expect(valA).to.be.undefined;
expect(valB).to.be.undefined;
});
// Restore collection vars for subsequent requests
for (const [key, value] of Object.entries(savedCollectionVars)) {
bru.setCollectionVar(key, value);
}
}

View File

@@ -0,0 +1,35 @@
meta {
name: deleteAllEnvVars
type: http
seq: 23
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:pre-request {
bru.setEnvVar("testDelAllEnvVar", "to-be-deleted");
}
tests {
const savedEnvVars = bru.getAllEnvVars();
bru.deleteAllEnvVars();
test("should delete all env vars", function() {
const val = bru.getEnvVar("testDelAllEnvVar");
expect(val).to.be.undefined;
});
test("should preserve env name after deleting all vars", function() {
const envName = bru.getEnvName();
expect(envName).to.equal("Prod");
});
// Restore env vars for subsequent requests
for (const [key, value] of Object.entries(savedEnvVars)) {
bru.setEnvVar(key, value);
}
}

View File

@@ -0,0 +1,33 @@
meta {
name: deleteAllGlobalEnvVars
type: http
seq: 21
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:pre-request {
bru.setGlobalEnvVar("testDelAllGlobalA", "a");
bru.setGlobalEnvVar("testDelAllGlobalB", "b");
}
tests {
const savedGlobalEnvVars = bru.getAllGlobalEnvVars();
bru.deleteAllGlobalEnvVars();
test("should delete all global env vars", function() {
const valA = bru.getGlobalEnvVar("testDelAllGlobalA");
const valB = bru.getGlobalEnvVar("testDelAllGlobalB");
expect(valA).to.be.undefined;
expect(valB).to.be.undefined;
});
// Restore global env vars for subsequent requests
for (const [key, value] of Object.entries(savedGlobalEnvVars)) {
bru.setGlobalEnvVar(key, value);
}
}

View File

@@ -0,0 +1,23 @@
meta {
name: deleteCollectionVar
type: http
seq: 27
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:pre-request {
bru.setCollectionVar("testDeleteCollectionVar", "to-be-deleted");
bru.deleteCollectionVar("testDeleteCollectionVar");
}
tests {
test("should delete collection var", function() {
const val = bru.getCollectionVar("testDeleteCollectionVar");
expect(val).to.be.undefined;
});
}

View File

@@ -0,0 +1,23 @@
meta {
name: deleteGlobalEnvVar
type: http
seq: 19
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:pre-request {
bru.setGlobalEnvVar("testDeleteGlobalEnvVar", "to-be-deleted");
bru.deleteGlobalEnvVar("testDeleteGlobalEnvVar");
}
tests {
test("should delete global env var", function() {
const val = bru.getGlobalEnvVar("testDeleteGlobalEnvVar");
expect(val).to.be.undefined;
});
}

View File

@@ -0,0 +1,31 @@
meta {
name: getAllCollectionVars
type: http
seq: 29
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:pre-request {
bru.setCollectionVar("testCollectionA", "valueA");
bru.setCollectionVar("testCollectionB", "valueB");
}
tests {
test("should return all collection vars", function() {
const vars = bru.getAllCollectionVars();
expect(vars.testCollectionA).to.equal("valueA");
expect(vars.testCollectionB).to.equal("valueB");
});
test("should return a shallow copy", function() {
const vars = bru.getAllCollectionVars();
vars.testCollectionA = "mutated";
const vars2 = bru.getAllCollectionVars();
expect(vars2.testCollectionA).to.equal("valueA");
});
}

View File

@@ -0,0 +1,23 @@
meta {
name: getAllEnvVars
type: http
seq: 22
}
get {
url: {{host}}/ping
body: none
auth: none
}
tests {
test("should return all env vars including host", function() {
const vars = bru.getAllEnvVars();
expect(vars.host).to.be.a("string");
});
test("should not include __name__ in result", function() {
const vars = bru.getAllEnvVars();
expect(vars.__name__).to.be.undefined;
});
}

View File

@@ -0,0 +1,31 @@
meta {
name: getAllGlobalEnvVars
type: http
seq: 20
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:pre-request {
bru.setGlobalEnvVar("testGlobalA", "valueA");
bru.setGlobalEnvVar("testGlobalB", "valueB");
}
tests {
test("should return all global env vars", function() {
const vars = bru.getAllGlobalEnvVars();
expect(vars.testGlobalA).to.equal("valueA");
expect(vars.testGlobalB).to.equal("valueB");
});
test("should return a shallow copy", function() {
const vars = bru.getAllGlobalEnvVars();
vars.testGlobalA = "mutated";
const vars2 = bru.getAllGlobalEnvVars();
expect(vars2.testGlobalA).to.equal("valueA");
});
}

View File

@@ -0,0 +1,31 @@
meta {
name: getAllVars
type: http
seq: 24
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:pre-request {
bru.setVar("testGetAllVarsA", "alphaValue");
bru.setVar("testGetAllVarsB", "betaValue");
}
tests {
test("should return all runtime vars", function() {
const vars = bru.getAllVars();
expect(vars.testGetAllVarsA).to.equal("alphaValue");
expect(vars.testGetAllVarsB).to.equal("betaValue");
});
test("should return a shallow copy", function() {
const vars = bru.getAllVars();
vars.testGetAllVarsA = "mutated";
const vars2 = bru.getAllVars();
expect(vars2.testGetAllVarsA).to.equal("alphaValue");
});
}

View File

@@ -0,0 +1,23 @@
meta {
name: hasCollectionVar
type: http
seq: 26
}
get {
url: {{host}}/ping
body: none
auth: none
}
tests {
test("should return true for existing collection var", function() {
const exists = bru.hasCollectionVar("collection-var");
expect(exists).to.be.true;
});
test("should return false for nonexistent collection var", function() {
const exists = bru.hasCollectionVar("nonexistent-collection-var");
expect(exists).to.be.false;
});
}

View File

@@ -0,0 +1,22 @@
meta {
name: setCollectionVar
type: http
seq: 25
}
get {
url: {{host}}/ping
body: none
auth: none
}
script:post-response {
bru.setCollectionVar("testSetCollectionVar", "collection-test-value")
}
tests {
test("should set collection var in scripts", function() {
const testSetCollectionVar = bru.getCollectionVar("testSetCollectionVar");
expect(testSetCollectionVar).to.equal("collection-test-value");
});
}

View File

@@ -0,0 +1,31 @@
meta {
name: deleteHeader
type: http
seq: 12
}
get {
url: {{host}}/ping
body: none
auth: none
}
headers {
bruno: is-awesome
}
assert {
res.status: eq 200
res.body: eq pong
}
script:pre-request {
req.deleteHeader('bruno');
}
tests {
test("req.deleteHeader(name)", function() {
const h = req.getHeader('bruno');
expect(h).to.be.undefined;
});
}