Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 100 additions & 6 deletions packages/bruno-api-docs/e2e/tests/scripts/bru-object-scripting.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,95 @@ 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 () {
bru.setVar('host', 'example.com');
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('<a>\\n <b>1</b>\\n</a>')).to.equal('<a><b>1</b></a>');
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<void> => {
Expand All @@ -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');

Expand All @@ -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();
Expand All @@ -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.'
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
`;

Expand Down
Loading