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..b2badd45 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);
});
+
+await 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.failed).to.equal(0);
+ expect(tests.results[0].status).to.equal('pass');
+
+ 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.contain('invalid request path');
+});
`;
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);
});
`;