diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml
index c9f7a9ada..651443593 100644
--- a/.github/workflows/unit-tests.yml
+++ b/.github/workflows/unit-tests.yml
@@ -29,3 +29,5 @@ jobs:
run: npm run test --workspace=packages/bruno-js
- name: Test Package bruno-cli
run: npm run test --workspace=packages/bruno-cli
+ - name: Test Package bruno-electron
+ run: npm run test --workspace=packages/bruno-electron
diff --git a/.gitignore b/.gitignore
index 990068b05..a6617f355 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,7 @@ yarn-error.log*
/test-results/
/playwright-report/
/playwright/.cache/
+
+#dev editor
+bruno.iml
+.idea
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/Sidebar/index.js b/packages/bruno-app/src/components/Sidebar/index.js
index 81c8057d2..217b7e36f 100644
--- a/packages/bruno-app/src/components/Sidebar/index.js
+++ b/packages/bruno-app/src/components/Sidebar/index.js
@@ -116,7 +116,7 @@ const Sidebar = () => {
)}
-
v0.16.2
+ v0.16.3
diff --git a/packages/bruno-cli/src/runner/run-single-request.js b/packages/bruno-cli/src/runner/run-single-request.js
index ddde92a4d..5e4312b17 100644
--- a/packages/bruno-cli/src/runner/run-single-request.js
+++ b/packages/bruno-cli/src/runner/run-single-request.js
@@ -213,7 +213,7 @@ const runSingleRequest = async function (
const testFile = get(bruJson, 'request.tests');
if (testFile && testFile.length) {
const testRuntime = new TestRuntime();
- const result = testRuntime.runTests(
+ const result = await testRuntime.runTests(
testFile,
request,
response,
diff --git a/packages/bruno-electron/package.json b/packages/bruno-electron/package.json
index 8a058973e..6ff6e7f43 100644
--- a/packages/bruno-electron/package.json
+++ b/packages/bruno-electron/package.json
@@ -1,5 +1,5 @@
{
- "version": "v0.16.2",
+ "version": "v0.16.3",
"name": "bruno",
"description": "Opensource API Client for Exploring and Testing APIs",
"homepage": "https://www.usebruno.com",
diff --git a/packages/bruno-electron/src/ipc/collection.js b/packages/bruno-electron/src/ipc/collection.js
index 637a8d479..ae85558af 100644
--- a/packages/bruno-electron/src/ipc/collection.js
+++ b/packages/bruno-electron/src/ipc/collection.js
@@ -11,7 +11,8 @@ const {
isDirectory,
browseDirectory,
createDirectory,
- searchForBruFiles
+ searchForBruFiles,
+ sanitizeDirectoryName
} = require('../utils/filesystem');
const { stringifyJson } = require('../utils/common');
const { openCollectionDialog, openCollection } = require('../app/collections');
@@ -315,7 +316,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
ipcMain.handle('renderer:import-collection', async (event, collection, collectionLocation) => {
try {
- let collectionName = collection.name;
+ let collectionName = sanitizeDirectoryName(collection.name);
let collectionPath = path.join(collectionLocation, collectionName);
if (fs.existsSync(collectionPath)) {
@@ -359,7 +360,7 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
const uid = generateUidBasedOnHash(collectionPath);
const brunoConfig = {
version: '1',
- name: collection.name,
+ name: collectionName,
type: 'collection'
};
const content = await stringifyJson(brunoConfig);
diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js
index 20f35b4c9..d4cfa48b1 100644
--- a/packages/bruno-electron/src/ipc/network/index.js
+++ b/packages/bruno-electron/src/ipc/network/index.js
@@ -315,7 +315,7 @@ const registerNetworkIpc = (mainWindow) => {
const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests');
if (testFile && testFile.length) {
const testRuntime = new TestRuntime();
- const testResults = testRuntime.runTests(
+ const testResults = await testRuntime.runTests(
testFile,
request,
response,
@@ -389,7 +389,7 @@ const registerNetworkIpc = (mainWindow) => {
const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests');
if (testFile && testFile.length) {
const testRuntime = new TestRuntime();
- const testResults = testRuntime.runTests(
+ const testResults = await testRuntime.runTests(
testFile,
request,
error.response,
@@ -725,7 +725,7 @@ const registerNetworkIpc = (mainWindow) => {
const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests');
if (testFile && testFile.length) {
const testRuntime = new TestRuntime();
- const testResults = testRuntime.runTests(
+ const testResults = await testRuntime.runTests(
testFile,
request,
response,
@@ -804,7 +804,7 @@ const registerNetworkIpc = (mainWindow) => {
const testFile = item.draft ? get(item.draft, 'request.tests') : get(item, 'request.tests');
if (testFile && testFile.length) {
const testRuntime = new TestRuntime();
- const testResults = testRuntime.runTests(
+ const testResults = await testRuntime.runTests(
testFile,
request,
error.response,
diff --git a/packages/bruno-electron/src/utils/filesystem.js b/packages/bruno-electron/src/utils/filesystem.js
index daf6eaf6b..b55dfd725 100644
--- a/packages/bruno-electron/src/utils/filesystem.js
+++ b/packages/bruno-electron/src/utils/filesystem.js
@@ -114,6 +114,10 @@ const searchForBruFiles = (dir) => {
return searchForFiles(dir, '.bru');
};
+const sanitizeDirectoryName = (name) => {
+ return name.replace(/[<>:"/\\|?*\x00-\x1F]+/g, '-');
+};
+
module.exports = {
isValidPathname,
exists,
@@ -127,5 +131,6 @@ module.exports = {
createDirectory,
browseDirectory,
searchForFiles,
- searchForBruFiles
+ searchForBruFiles,
+ sanitizeDirectoryName
};
diff --git a/packages/bruno-electron/src/utils/filesystem.test.js b/packages/bruno-electron/src/utils/filesystem.test.js
new file mode 100644
index 000000000..62d7b502f
--- /dev/null
+++ b/packages/bruno-electron/src/utils/filesystem.test.js
@@ -0,0 +1,26 @@
+const { sanitizeDirectoryName } = require('./filesystem.js');
+
+describe('sanitizeDirectoryName', () => {
+ it('should replace invalid characters with hyphens', () => {
+ const input = '<>:"/\\|?*\x00-\x1F';
+ const expectedOutput = '---';
+ expect(sanitizeDirectoryName(input)).toEqual(expectedOutput);
+ });
+
+ it('should not modify valid directory names', () => {
+ const input = 'my-directory';
+ expect(sanitizeDirectoryName(input)).toEqual(input);
+ });
+
+ it('should replace multiple invalid characters with a single hyphen', () => {
+ const input = 'my<>invalid?directory';
+ const expectedOutput = 'my-invalid-directory';
+ expect(sanitizeDirectoryName(input)).toEqual(expectedOutput);
+ });
+
+ it('should handle names with slashes', () => {
+ const input = 'my/invalid/directory';
+ const expectedOutput = 'my-invalid-directory';
+ expect(sanitizeDirectoryName(input)).toEqual(expectedOutput);
+ });
+});
diff --git a/packages/bruno-js/src/runtime/test-runtime.js b/packages/bruno-js/src/runtime/test-runtime.js
index 3a7c1f9b5..47daccd62 100644
--- a/packages/bruno-js/src/runtime/test-runtime.js
+++ b/packages/bruno-js/src/runtime/test-runtime.js
@@ -10,6 +10,7 @@ const { cleanJson } = require('../utils');
// Inbuilt Library Support
const atob = require('atob');
+const axios = require('axios');
const btoa = require('btoa');
const lodash = require('lodash');
const moment = require('moment');
@@ -20,7 +21,7 @@ const CryptoJS = require('crypto-js');
class TestRuntime {
constructor() {}
- runTests(
+ async runTests(
testsFile,
request,
response,
@@ -78,6 +79,7 @@ class TestRuntime {
root: [collectionPath],
mock: {
atob,
+ axios,
btoa,
lodash,
moment,
@@ -89,7 +91,8 @@ class TestRuntime {
}
});
- vm.run(testsFile, path.join(collectionPath, 'vm.js'));
+ const asyncVM = vm.run(`module.exports = async () => { ${testsFile}}`, path.join(collectionPath, 'vm.js'));
+ await asyncVM();
return {
request,
diff --git a/packages/bruno-js/src/test.js b/packages/bruno-js/src/test.js
index 213e25252..dd449e740 100644
--- a/packages/bruno-js/src/test.js
+++ b/packages/bruno-js/src/test.js
@@ -1,6 +1,6 @@
-const Test = (__brunoTestResults, chai) => (description, callback) => {
+const Test = (__brunoTestResults, chai) => async (description, callback) => {
try {
- callback();
+ await callback();
__brunoTestResults.addResult({ description, status: 'pass' });
} catch (error) {
console.log(chai.AssertionError);
diff --git a/packages/bruno-js/tests/runtime.spec.js b/packages/bruno-js/tests/runtime.spec.js
new file mode 100644
index 000000000..b8e4dfae3
--- /dev/null
+++ b/packages/bruno-js/tests/runtime.spec.js
@@ -0,0 +1,53 @@
+const { describe, it, expect } = require('@jest/globals');
+const TestRuntime = require('../src/runtime/test-runtime');
+
+describe('runtime', () => {
+ describe('test-runtime', () => {
+ const baseRequest = {
+ method: 'GET',
+ url: 'http://localhost:3000/',
+ headers: {},
+ data: undefined
+ };
+ const baseResponse = {
+ status: 200,
+ statusText: 'OK',
+ data: [
+ {
+ id: 1
+ },
+ {
+ id: 2
+ },
+ {
+ id: 3
+ }
+ ]
+ };
+
+ it('should wait async tests', async () => {
+ const testFile = `
+ await test('async test', ()=> {
+ return new Promise((resolve)=> {
+ setTimeout(()=> {resolve()},200)
+ })
+ })
+ `;
+
+ const runtime = new TestRuntime();
+ const result = await runtime.runTests(
+ testFile,
+ { ...baseRequest },
+ { ...baseResponse },
+ {},
+ {},
+ '.',
+ null,
+ process.env
+ );
+ expect(result.results.map((el) => ({ description: el.description, status: el.status }))).toEqual([
+ { description: 'async test', status: 'pass' }
+ ]);
+ });
+ });
+});