From b101e534e429e5a9a50ece7b29fe8119b124a0ad Mon Sep 17 00:00:00 2001 From: lokesh-bruno Date: Fri, 11 Sep 2026 17:42:48 +0530 Subject: [PATCH] Covered scripting methods --- .../scripts/bru-object-scripting.spec.ts | 106 +++++++++++++++++- .../scripts/request-object-scripting.spec.ts | 90 ++++++++++++++- 2 files changed, 184 insertions(+), 12 deletions(-) diff --git a/packages/bruno-api-docs/e2e/tests/scripts/bru-object-scripting.spec.ts b/packages/bruno-api-docs/e2e/tests/scripts/bru-object-scripting.spec.ts index d3bf3041..0225a9cc 100644 --- a/packages/bruno-api-docs/e2e/tests/scripts/bru-object-scripting.spec.ts +++ b/packages/bruno-api-docs/e2e/tests/scripts/bru-object-scripting.spec.ts @@ -3,13 +3,58 @@ import type { Page } from '@playwright/test'; import type { CodeEditorComponent } from '../../components/code-editor/code-editor.component'; const BRU_TESTS_SCRIPT = ` -test('bru variable stores round-trip', function () { +test('bru runtime variables round-trip, delete, and deleteAll', function () { bru.setVar('token', 'abc'); expect(bru.getVar('token')).to.equal('abc'); expect(bru.hasVar('token')).to.equal(true); expect(bru.getAllVars().token).to.equal('abc'); - bru.setCollectionVar('cv', '1'); - expect(bru.getCollectionVar('cv')).to.equal('1'); + + bru.deleteVar('token'); + expect(bru.hasVar('token')).to.equal(false); + + bru.setVar('a', '1'); + bru.setVar('b', '2'); + bru.deleteAllVars(); + expect(bru.getAllVars()).to.deep.equal({}); +}); + +test('bru collection variables round-trip with has/delete helpers', function () { + expect(bru.getCollectionName()).to.equal('Bruno Testbench'); + expect(bru.getCollectionVar('collection_pre_var')).to.equal('collection_pre_var_value'); + expect(bru.hasCollectionVar('collection_pre_var')).to.equal(true); + + bru.setCollectionVar('cv_e2e', '1'); + expect(bru.getCollectionVar('cv_e2e')).to.equal('1'); + expect(bru.hasCollectionVar('cv_e2e')).to.equal(true); + + bru.deleteCollectionVar('cv_e2e'); + expect(bru.hasCollectionVar('cv_e2e')).to.equal(false); + + bru.setCollectionVar('cv_temp', 'x'); + bru.deleteAllCollectionVars(); + expect(bru.hasCollectionVar('cv_temp')).to.equal(false); + expect(bru.hasCollectionVar('collection_pre_var')).to.equal(false); +}); + +test('bru environment variables read, write, and delete in the active env', function () { + expect(bru.getEnvName()).to.equal('Local'); + expect(bru.hasEnvVar('host')).to.equal(true); + expect(bru.getEnvVar('host')).to.contain('localhost'); + expect(bru.getAllEnvVars()).to.have.property('host'); + + bru.setEnvVar('e2e_env', 'yes'); + expect(bru.getEnvVar('e2e_env')).to.equal('yes'); + expect(bru.hasEnvVar('e2e_env')).to.equal(true); + + bru.deleteEnvVar('e2e_env'); + expect(bru.hasEnvVar('e2e_env')).to.equal(false); +}); + +test('bru folder, request, and secret variable readers run', function () { + // Top-level "get users" has no folder/request vars — readers still resolve safely. + expect(bru.getFolderVar('missing_folder_var')).to.equal(undefined); + expect(bru.getRequestVar('missing_request_var')).to.equal(undefined); + expect(bru.getSecretVar('host')).to.contain('localhost'); }); test('bru.interpolate resolves {{var}} from the runtime store', function () { @@ -17,10 +62,36 @@ test('bru.interpolate resolves {{var}} from the runtime store', function () { expect(bru.interpolate('https://{{host}}/api')).to.equal('https://example.com/api'); }); -test('bru.utils.minifyJson and bru.isSafeMode run in the sandbox', function () { +test('bru.utils and bru.isSafeMode run in the sandbox', function () { expect(bru.utils.minifyJson('{ "a": 1 }')).to.equal('{"a":1}'); + expect(bru.utils.minifyXml('\\n 1\\n')).to.equal('1'); expect(bru.isSafeMode()).to.equal(true); }); + +test('bru.sleep, sendRequest, getTestResults, getAssertionResults, and runRequest run', async function () { + await bru.sleep(1); + + var sent = await bru.sendRequest({ + method: 'GET', + url: 'http://localhost:8081/api/users' + }); + expect(sent.status).to.equal(200); + expect(sent.data.users[0].name).to.equal('Ada'); + + var tests = await bru.getTestResults(); + expect(tests).to.be.an('object'); + expect(tests.summary).to.be.an('object'); + expect(Array.isArray(tests.results)).to.equal(true); + + var asserts = await bru.getAssertionResults(); + expect(asserts).to.be.an('object'); + expect(asserts.summary).to.be.an('object'); + expect(Array.isArray(asserts.results)).to.equal(true); + + var missing = await bru.runRequest('__no_such_request__'); + expect(missing).to.be.an('object'); + expect(missing.message).to.be.a('string'); +}); `; const setEditorScript = async (page: Page, editor: CodeEditorComponent, script: string): Promise => { @@ -45,7 +116,7 @@ test.describe('The bru object available to scripts (end-to-end in the playground ); }); - test('bru variable, interpolate and utils methods run in a tests script with no failures', async ({ page, playground, responsePane }) => { + test('bru variable, env, utils and request helpers run in a tests script with no failures', async ({ page, playground, responsePane }) => { await page.goto('/#/?pg=1&dock=bottom'); await playground.openSidebarItem('get users'); @@ -66,9 +137,26 @@ test.describe('The bru object available to scripts (end-to-end in the playground await playground.selectTab('tests'); await setEditorScript(page, playground.testsEditor, [ 'bru.visualize(\'html\', { content: \'x\' });', + 'bru.clearVisualizations();', + 'bru.cwd();', + 'bru.getProcessEnv();', + 'bru.getOauth2CredentialVar();', + 'bru.resetOauth2Credential();', + 'bru.setNextRequest(\'Next\');', + 'bru.runner.setNextRequest(\'Next\');', 'bru.runner.skipRequest();', + 'bru.runner.stopExecution();', 'bru.runner.iterationIndex;', - 'bru.getAllGlobalEnvVars();' + 'bru.runner.totalIterations;', + 'bru.runner.iterationData.get();', + 'bru.cookies.get();', + 'bru.cookies.jar();', + 'bru.getAllGlobalEnvVars();', + 'bru.hasGlobalEnvVar();', + 'bru.getGlobalEnvVar();', + 'bru.setGlobalEnvVar();', + 'bru.deleteGlobalEnvVar();', + 'bru.deleteAllGlobalEnvVars();' ].join('\n')); await responsePane.send(); @@ -87,5 +175,11 @@ test.describe('The bru object available to scripts (end-to-end in the playground await expect(banner).toContainText( 'bru.getAllGlobalEnvVars is not currently supported in the Bruno playground. Please use the Bruno desktop app.' ); + await expect(banner).toContainText( + 'bru.cookies.jar is not currently supported in the Bruno playground. Please use the Bruno desktop app.' + ); + await expect(banner).toContainText( + 'bru.setNextRequest is not currently supported in the Bruno playground. Please use the Bruno desktop app.' + ); }); }); diff --git a/packages/bruno-api-docs/e2e/tests/scripts/request-object-scripting.spec.ts b/packages/bruno-api-docs/e2e/tests/scripts/request-object-scripting.spec.ts index 6451d59e..ba088da3 100644 --- a/packages/bruno-api-docs/e2e/tests/scripts/request-object-scripting.spec.ts +++ b/packages/bruno-api-docs/e2e/tests/scripts/request-object-scripting.spec.ts @@ -13,33 +13,111 @@ test('req read methods return the right types', function () { expect(req.getHeaders()).to.be.an('object'); expect(Array.isArray(req.getPathParams())).to.equal(true); expect(Array.isArray(req.getTags())).to.equal(true); + expect(req.getName()).to.be.a('string'); }); -test('req.getUrl reflects the request URL', function () { +test('req.getUrl and req.getName reflect the open request', function () { expect(req.getUrl()).to.contain('/api/users'); + expect(req.getName()).to.equal('get users'); + expect(req.getTags()).to.include('users'); }); -test('req.headerList reads the header list: all, toObject, toString, count', function () { +test('req.setUrl and req.setMethod write through and are readable back', function () { + req.setUrl('https://example.com/v2/items?x=1'); + req.setMethod('PATCH'); + expect(req.getUrl()).to.equal('https://example.com/v2/items?x=1'); + expect(req.getMethod()).to.equal('PATCH'); + expect(req.getHost()).to.equal('example.com'); + expect(req.getPath()).to.equal('/v2/items'); + expect(req.getQueryString()).to.equal('x=1'); +}); + +test('req.setHeader, setHeaders, deleteHeader, and deleteHeaders mutate headers', function () { + req.setHeader('X-Script', 'yes'); + expect(req.getHeader('X-Script')).to.equal('yes'); + + req.setHeaders({ 'X-Batch-A': '1', 'X-Batch-B': '2' }); + expect(req.getHeader('X-Batch-A')).to.equal('1'); + expect(req.getHeader('X-Batch-B')).to.equal('2'); + + req.deleteHeader('X-Batch-A'); + expect(req.getHeader('X-Batch-A')).to.equal(undefined); + + req.deleteHeaders(['X-Batch-B', 'X-Script']); + expect(req.getHeader('X-Batch-B')).to.equal(undefined); + expect(req.getHeader('X-Script')).to.equal(undefined); +}); + +test('req.setBody and req.getBody round-trip JSON payloads', function () { + req.setBody({ hello: 'world', n: 2 }); + expect(req.getBody().hello).to.equal('world'); + expect(req.getBody().n).to.equal(2); + expect(req.getBody({ raw: true })).to.be.a('string'); +}); + +test('req.getTimeout, setTimeout, getExecutionMode, and disableParsingResponseJson run', function () { + var before = req.getTimeout(); + req.setTimeout(1234); + expect(req.getTimeout()).to.equal(1234); + if (before !== undefined && before !== null) { + req.setTimeout(before); + } + + expect(req.getExecutionMode()).to.equal('standalone'); + req.disableParsingResponseJson(); +}); + +test('req.headerList reads the header list: all, toObject, toString, toJSON, count', function () { expect(Array.isArray(req.headerList.all())).to.equal(true); expect(req.headerList.toObject()).to.be.an('object'); expect(req.headerList.toString()).to.be.a('string'); + expect(Array.isArray(req.headerList.toJSON())).to.equal(true); expect(req.headerList.count()).to.be.at.least(0); }); -test('req.setHeader and req.headerList add/remove a header, readable via getHeader and has', function () { - req.setHeader('X-Script', 'yes'); - expect(req.getHeader('X-Script')).to.equal('yes'); +test('req.headerList add, upsert, remove, has, find, filter, and indexOf', function () { req.headerList.add('X-Added', '1'); expect(req.headerList.has('x-added')).to.equal(true); + expect(req.headerList.get('X-Added')).to.equal('1'); + expect(req.headerList.one('x-added').value).to.equal('1'); + + expect(req.headerList.upsert('x-added', '2')).to.equal(false); + expect(req.headerList.get('x-added')).to.equal('2'); + expect(req.headerList.upsert('X-New', 'n')).to.equal(true); + + expect(req.headerList.find(function (h) { return h.key === 'x-added'; }).value).to.equal('2'); + expect(req.headerList.filter(function (h) { return h.key === 'x-added'; }).length).to.equal(1); + expect(req.headerList.indexOf('X-Added')).to.be.at.least(0); + req.headerList.remove('x-added'); expect(req.headerList.has('x-added')).to.equal(false); }); -test('req.headerList iterators run their callbacks across the sandbox', function () { +test('req.headerList iterators and reduce run their callbacks across the sandbox', function () { + req.headerList.add('X-Iter', '1'); expect(Array.isArray(req.headerList.map(function (h) { return h.key; }))).to.equal(true); var count = 0; req.headerList.each(function () { count++; }); expect(count).to.equal(req.headerList.count()); + var summed = req.headerList.reduce(function (acc) { return acc + 1; }, 0); + expect(summed).to.equal(req.headerList.count()); +}); + +test('req.headerList populate, repopulate, assimilate, and clear rewrite the list', function () { + req.headerList.repopulate([{ key: 'X-Only', value: '1' }]); + expect(req.headerList.has('x-only')).to.equal(true); + expect(req.headerList.count()).to.equal(1); + + req.headerList.populate([{ key: 'X-Pop', value: '2' }, { key: 'X-Only', value: 'ignored' }]); + expect(req.headerList.has('x-pop')).to.equal(true); + expect(req.headerList.get('x-only')).to.equal('1'); + + req.headerList.assimilate([{ key: 'X-Merged', value: '3' }], true); + expect(req.headerList.has('x-merged')).to.equal(true); + expect(req.headerList.has('x-only')).to.equal(false); + + req.headerList.clear(); + expect(req.headerList.count()).to.equal(0); }); `;