Skip to content

Commit

Permalink
feat: testing support has arrived !
Browse files Browse the repository at this point in the history
  • Loading branch information
helloanoop committed Jan 29, 2023
1 parent cc26132 commit c328281
Show file tree
Hide file tree
Showing 13 changed files with 256 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ const StyledWrapper = styled.div`
}
}
}
.some-tests-failed {
color: ${(props) => props.theme.colors.text.danger} !important;
}
.all-tests-passed {
color: ${(props) => props.theme.colors.text.green} !important;
}
`;

export default StyledWrapper;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import styled from 'styled-components';

const StyledWrapper = styled.div`
.test-success {
color: ${(props) => props.theme.colors.text.green};
}
.test-failure {
color: ${(props) => props.theme.colors.text.danger};
.error-message {
color: ${(props) => props.theme.colors.text.muted};
}
}
`;

export default StyledWrapper;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import StyledWrapper from './StyledWrapper';

const TestResults = ({ results }) => {
if (!results || !results.length) {
return (
<div className="px-3">
No tests found
</div>
);
}

const passedTests = results.filter((result) => result.status === 'pass');
const failedTests = results.filter((result) => result.status === 'fail');

return (
<StyledWrapper className='flex flex-col px-3'>
<div className="py-2 font-medium test-summary">
Tests ({results.length}/{results.length}), Passed: {passedTests.length}, Failed: {failedTests.length}
</div>
<ul className="">
{results.map((result, index) => (
<li key={index} className="py-1">
{result.status === 'pass' ? (
<span className="test-success">
&#x2714;&nbsp; {result.description}
</span>
) : (
<>
<span className="test-failure">
&#x2718;&nbsp; {result.description}
</span>
<br />
<span className="error-message pl-8">
{result.error}
</span>
</>
)}
</li>
))}
</ul>
</StyledWrapper>
);
};

export default TestResults;
31 changes: 31 additions & 0 deletions packages/bruno-app/src/components/ResponsePane/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,33 @@ import StatusCode from './StatusCode';
import ResponseTime from './ResponseTime';
import ResponseSize from './ResponseSize';
import Timeline from './Timeline';
import TestResults from './TestResults';
import StyledWrapper from './StyledWrapper';

const TestResultsLabel = ({ results }) => {
if(!results || !results.length) {
return 'Tests';
}

const numberOfTests = results.length;
const numberOfFailedTests = results.filter(result => result.status === 'fail').length;

return (
<div className='flex items-center'>
<div>Tests</div>
{numberOfFailedTests ? (
<sup className='sups some-tests-failed ml-1 font-medium'>
{numberOfFailedTests}
</sup>
) : (
<sup className='sups all-tests-passed ml-1 font-medium'>
{numberOfTests}
</sup>
)}
</div>
);
};

const ResponsePane = ({ rightPaneWidth, item, collection }) => {
const dispatch = useDispatch();
const tabs = useSelector((state) => state.tabs.tabs);
Expand Down Expand Up @@ -46,6 +71,9 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => {
case 'timeline': {
return <Timeline item={item} />;
}
case 'tests': {
return <TestResults results={item.testResults} />;
}

default: {
return <div>404 | Not found</div>;
Expand Down Expand Up @@ -96,6 +124,9 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => {
<div className={getTabClassname('timeline')} role="tab" onClick={() => selectTab('timeline')}>
Timeline
</div>
<div className={getTabClassname('tests')} role="tab" onClick={() => selectTab('tests')}>
<TestResultsLabel results={item.testResults} />
</div>
{!isLoading ? (
<div className="flex flex-grow justify-end items-center">
<StatusCode status={response.status} />
Expand Down
7 changes: 7 additions & 0 deletions packages/bruno-app/src/providers/App/useCollectionTreeSync.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
collectionUnlinkEnvFileEvent,
requestSentEvent,
requestQueuedEvent,
testResultsEvent,
scriptEnvironmentUpdateEvent
} from 'providers/ReduxStore/slices/collections';
import toast from 'react-hot-toast';
Expand Down Expand Up @@ -95,6 +96,10 @@ const useCollectionTreeSync = () => {
dispatch(requestQueuedEvent(val));
};

const _testResults = (val) => {
dispatch(testResultsEvent(val));
};

ipcRenderer.invoke('renderer:ready');

const removeListener1 = ipcRenderer.on('main:collection-opened', _openCollection);
Expand All @@ -104,6 +109,7 @@ const useCollectionTreeSync = () => {
const removeListener5 = ipcRenderer.on('main:http-request-sent', _httpRequestSent);
const removeListener6 = ipcRenderer.on('main:script-environment-update', _scriptEnvironmentUpdate);
const removeListener7 = ipcRenderer.on('main:http-request-queued', _httpRequestQueued);
const removeListener8 = ipcRenderer.on('main:test-results', _testResults);

return () => {
removeListener1();
Expand All @@ -113,6 +119,7 @@ const useCollectionTreeSync = () => {
removeListener5();
removeListener6();
removeListener7();
removeListener8();
};
}, [isElectron]);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,18 @@ export const collectionsSlice = createSlice({
collection.environments.push(environment);
}
}
},
testResultsEvent: (state, action) => {
const { itemUid, collectionUid, results } = action.payload;
const collection = findCollectionByUid(state.collections, collectionUid);

if (collection) {
const item = findItemInCollection(collection, itemUid);

if (item) {
item.testResults = results;
}
}
}
}
});
Expand Down Expand Up @@ -861,7 +873,8 @@ export const {
collectionChangeFileEvent,
collectionUnlinkFileEvent,
collectionUnlinkDirectoryEvent,
collectionAddEnvFileEvent
collectionAddEnvFileEvent,
testResultsEvent
} = collectionsSlice.actions;

export default collectionsSlice.reducer;
1 change: 1 addition & 0 deletions packages/bruno-electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"atob": "^2.1.2",
"axios": "^0.26.0",
"btoa": "^1.2.1",
"chai": "^4.3.7",
"chokidar": "^3.5.3",
"crypto-js": "^4.1.1",
"electron-is-dev": "^2.0.0",
Expand Down
38 changes: 25 additions & 13 deletions packages/bruno-electron/src/ipc/network/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const axios = require('axios');
const Mustache = require('mustache');
const FormData = require('form-data');
const { ipcMain } = require('electron');
const { forOwn, extend, each } = require('lodash');
const { ScriptRuntime } = require('@usebruno/js');
const { forOwn, extend, each, get } = require('lodash');
const { ScriptRuntime, TestRuntime } = require('@usebruno/js');
const prepareRequest = require('./prepare-request');
const { cancelTokens, saveCancelToken, deleteCancelToken } = require('../../utils/cancel-token');
const { uuid } = require('../../utils/common');
Expand Down Expand Up @@ -79,12 +79,12 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
const envVars = getEnvVars(environment);

if(request.script && request.script.length) {
let script = request.script + '\n if (typeof onRequest === "function") {onRequest(brunoRequest);}';
let script = request.script + '\n if (typeof onRequest === "function") {onRequest(__brunoRequest);}';
const scriptRuntime = new ScriptRuntime();
const res = scriptRuntime.runRequestScript(script, request, envVars, collectionPath);
const result = scriptRuntime.runRequestScript(script, request, envVars, collectionPath);

mainWindow.webContents.send('main:script-environment-update', {
environment: res.environment,
environment: result.environment,
collectionUid
});
}
Expand All @@ -106,26 +106,38 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
cancelTokenUid
});

const result = await axios(request);
const response = await axios(request);

if(request.script && request.script.length) {
let script = request.script + '\n if (typeof onResponse === "function") {onResponse(brunoResponse);}';
let script = request.script + '\n if (typeof onResponse === "function") {onResponse(__brunoResponse);}';
const scriptRuntime = new ScriptRuntime();
const res = scriptRuntime.runResponseScript(script, result, envVars, collectionPath);
const result = scriptRuntime.runResponseScript(script, response, envVars, collectionPath);

mainWindow.webContents.send('main:script-environment-update', {
environment: res.environment,
environment: result.environment,
collectionUid
});
}

const testFile = get(item, 'request.tests');
if(testFile && testFile.length) {
const testRuntime = new TestRuntime();
const result = testRuntime.runTests(testFile, request, response, envVars, collectionPath);

mainWindow.webContents.send('main:test-results', {
results: result.results,
itemUid: item.uid,
collectionUid
});
}

deleteCancelToken(cancelTokenUid);

return {
status: result.status,
statusText: result.statusText,
headers: result.headers,
data: result.data
status: response.status,
statusText: response.statusText,
headers: response.headers,
data: response.data
};
} catch (error) {
// todo: better error handling
Expand Down
7 changes: 6 additions & 1 deletion packages/bruno-js/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ const {
ScriptRuntime
} = require('./scripts/script-runtime');

const {
TestRuntime
} = require('./scripts/test-runtime');

module.exports = {
ScriptRuntime
ScriptRuntime,
TestRuntime
};
8 changes: 4 additions & 4 deletions packages/bruno-js/src/scripts/script-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ class ScriptRuntime {

runRequestScript(script, request, environment, collectionPath) {
const bru = new Bru(environment);
const brunoRequest = new BrunoRequest(request);
const __brunoRequest = new BrunoRequest(request);

const context = {
bru,
brunoRequest
__brunoRequest
};
const vm = new NodeVM({
sandbox: context,
Expand All @@ -35,11 +35,11 @@ class ScriptRuntime {

runResponseScript(script, response, environment, collectionPath) {
const bru = new Bru(environment);
const brunoResponse = new BrunoResponse(response);
const __brunoResponse = new BrunoResponse(response);

const context = {
bru,
brunoResponse
__brunoResponse
};
const vm = new NodeVM({
sandbox: context,
Expand Down
15 changes: 15 additions & 0 deletions packages/bruno-js/src/scripts/test-results.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class TestResults {
constructor() {
this.results = [];
}

addResult(result) {
this.results.push(result);
}

getResults() {
return this.results;
}
}

module.exports = TestResults;
55 changes: 55 additions & 0 deletions packages/bruno-js/src/scripts/test-runtime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const { NodeVM } = require('vm2');
const chai = require('chai');
const path = require('path');
const Bru = require('./bru');
const BrunoRequest = require('./bruno-request');
const BrunoResponse = require('./bruno-response');
const Test = require('./test');
const TestResults = require('./test-results');

class TestRuntime {
constructor() {
}

runTests(testsFile, request, response, environment, collectionPath) {
const bru = new Bru(environment);
const req = new BrunoRequest(request);
const res = new BrunoResponse(response);

const __brunoTestResults = new TestResults();
const test = Test(__brunoTestResults, chai);

const context = {
bru,
req,
res,
test,
expect: chai.expect,
assert: chai.assert,
__brunoTestResults: __brunoTestResults
};

const vm = new NodeVM({
sandbox: context,
require: {
context: 'sandbox',
external: true,
root: [collectionPath]
}
});
console.log(__brunoTestResults);

vm.run(testsFile, path.join(collectionPath, 'vm.js'));

return {
request,
response,
environment,
results: __brunoTestResults.getResults()
};
}
}

module.exports = {
TestRuntime
};
Loading

0 comments on commit c328281

Please sign in to comment.