fix: fixed many bugs (too many to count :) )

This commit is contained in:
Anoop M D 2023-02-01 21:21:21 +05:30 committed by Anoop M D
parent 8202182074
commit a0903a5842
14 changed files with 123 additions and 49 deletions

View File

@ -6,12 +6,22 @@ const StyledWrapper = styled.div`
border: solid 1px ${(props) => props.theme.codemirror.border}; border: solid 1px ${(props) => props.theme.codemirror.border};
} }
.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div {
background: #d2d7db;
}
textarea.cm-editor { textarea.cm-editor {
position: relative; position: relative;
} }
// Todo: dark mode temporary fix // Todo: dark mode temporary fix
// Clean this // Clean this
.CodeMirror.cm-s-monokai {
.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div {
background: #444444;
}
}
.cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute { .cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute {
color: #9cdcfe !important; color: #9cdcfe !important;
} }

View File

@ -43,6 +43,7 @@ export default class CodeEditor extends React.Component {
foldGutter: true, foldGutter: true,
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'], gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
readOnly: this.props.readOnly, readOnly: this.props.readOnly,
scrollbarStyle: "overlay",
theme: this.props.theme === 'dark' ? 'monokai' : 'default', theme: this.props.theme === 'dark' ? 'monokai' : 'default',
extraKeys: { extraKeys: {
'Cmd-Enter': () => { 'Cmd-Enter': () => {

View File

@ -6,6 +6,9 @@ const Wrapper = styled.div`
color: ${(props) => props.theme.textLink}; color: ${(props) => props.theme.textLink};
} }
} }
.danger {
color: ${(props) => props.theme.colors.text.danger};
}
.test-summary { .test-summary {
color: ${(props) => props.theme.tabs.active.border}; color: ${(props) => props.theme.tabs.active.border};

View File

@ -32,17 +32,19 @@ export default function RunnerResults({collection}) {
item.pathname = info.pathname; item.pathname = info.pathname;
item.relativePath = getRelativePath(collection.pathname, info.pathname); item.relativePath = getRelativePath(collection.pathname, info.pathname);
if(item.testResults) { if(item.status !== "error") {
const failed = item.testResults.filter((result) => result.status === 'fail'); if(item.testResults) {
const failed = item.testResults.filter((result) => result.status === 'fail');
item.testStatus = failed.length ? 'fail' : 'pass'; item.testStatus = failed.length ? 'fail' : 'pass';
} else { } else {
item.testStatus = 'pass'; item.testStatus = 'pass';
}
} }
}); });
const passedRequests = items.filter((item) => item.testStatus === 'pass'); const passedRequests = items.filter((item) => item.status !== "error" && item.testStatus === 'pass');
const failedRequests = items.filter((item) => item.testStatus === 'fail'); const failedRequests = items.filter((item) => item.status !== "error" && item.testStatus === 'fail');
return ( return (
<StyledWrapper className='px-4'> <StyledWrapper className='px-4'>
@ -61,14 +63,14 @@ export default function RunnerResults({collection}) {
<div className="item-path mt-2"> <div className="item-path mt-2">
<div className="flex items-center"> <div className="flex items-center">
<span> <span>
{item.testStatus === 'pass' ? ( {item.status !== "error" && item.testStatus === 'pass' ? (
<IconCircleCheck className="test-success" size={20} strokeWidth={1.5}/> <IconCircleCheck className="test-success" size={20} strokeWidth={1.5}/>
) : ( ) : (
<IconCircleX className="test-failure" size={20} strokeWidth={1.5}/> <IconCircleX className="test-failure" size={20} strokeWidth={1.5}/>
)} )}
</span> </span>
<span className='mr-1 ml-2'>{item.relativePath}</span> <span className={`mr-1 ml-2 ${(item.status == "error" || item.testStatus == 'fail') ? 'danger' : ''}`}>{item.relativePath}</span>
{item.status !== "completed" ? ( {(item.status !== "error" && item.status !== "completed") ? (
<IconRefresh className="animate-spin ml-1" size={18} strokeWidth={1.5}/> <IconRefresh className="animate-spin ml-1" size={18} strokeWidth={1.5}/>
) : ( ) : (
<span className='text-xs link cursor-pointer' onClick={() => setSelectedItem(item)}> <span className='text-xs link cursor-pointer' onClick={() => setSelectedItem(item)}>
@ -81,6 +83,11 @@ export default function RunnerResults({collection}) {
</span> </span>
)} )}
</div> </div>
{item.status == "error" ? (
<div className="error-message pl-8 pt-2 text-xs">
{item.error}
</div>
) : null }
<ul className="pl-8"> <ul className="pl-8">
{item.testResults ? item.testResults.map((result) => ( {item.testResults ? item.testResults.map((result) => (

View File

@ -6,12 +6,12 @@ const StyledWrapper = styled.div`
} }
.variable-name{ .variable-name{
width:100px; min-width:180px;
} }
.variable-value { .variable-value {
max-width: 500px; max-width: 600px;
inline-size: 500px; inline-size: 600px;
overflow-wrap: break-word; overflow-wrap: break-word;
} }
` `

View File

@ -1,10 +1,24 @@
import React from 'react'; import React from 'react';
import forOwn from 'lodash/forOwn';
import cloneDeep from 'lodash/cloneDeep';
import { uuid } from 'utils/common';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
const VariablesTable = ({ variables }) => { const VariablesTable = ({ variables, collectionVariables }) => {
const collectionVars = [];
forOwn(cloneDeep(collectionVariables), (value, key) => {
collectionVars.push({
uid: uuid(),
name: key,
value: value
});
});
return ( return (
<StyledWrapper> <StyledWrapper>
<div className="flex flex-col w-full"> <div className="flex flex-col w-full">
<div className='mb-2 font-medium'>Environment Variables</div>
{(variables && variables.length) ? variables.map((variable) => { {(variables && variables.length) ? variables.map((variable) => {
return ( return (
<div key={variable.uid} className="flex"> <div key={variable.uid} className="flex">
@ -13,6 +27,16 @@ const VariablesTable = ({ variables }) => {
</div> </div>
); );
}) : null} }) : null}
<div className='mt-2 font-medium'>Collection Variables</div>
{(collectionVars && collectionVars.length) ? collectionVars.map((variable) => {
return (
<div key={variable.uid} className="flex">
<div className='variable-name text-yellow-600 text-right pr-2'>{variable.name}</div>
<div className='variable-value pl-2 whitespace-normal text-left flex-grow'>{variable.value}</div>
</div>
);
}) : null}
</div> </div>
</StyledWrapper> </StyledWrapper>
); );

View File

@ -34,7 +34,7 @@ const VariablesView = ({collection}) => {
handleClose={() => setPopOverOpen(false)} handleClose={() => setPopOverOpen(false)}
> >
<div className="px-2 py-1"> <div className="px-2 py-1">
{(enabledVariables && enabledVariables.length) ? <VariablesTable variables={enabledVariables} /> : 'No variables found'} {(enabledVariables && enabledVariables.length) ? <VariablesTable variables={enabledVariables} collectionVariables={collection.collectionVariables}/> : 'No variables found'}
</div> </div>
</PopOver> </PopOver>
)} )}

View File

@ -8,11 +8,13 @@ import { useSelector } from 'react-redux';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
import 'codemirror/theme/material.css'; import 'codemirror/theme/material.css';
import 'codemirror/theme/monokai.css'; import 'codemirror/theme/monokai.css';
import 'codemirror/addon/scroll/simplescrollbars.css';
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true; const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
if (!SERVER_RENDERED) { if (!SERVER_RENDERED) {
require('codemirror/mode/javascript/javascript'); require('codemirror/mode/javascript/javascript');
require('codemirror/mode/xml/xml'); require('codemirror/mode/xml/xml');
require('codemirror/addon/scroll/simplescrollbars');
require('codemirror/addon/edit/matchbrackets'); require('codemirror/addon/edit/matchbrackets');
require('codemirror/addon/fold/brace-fold'); require('codemirror/addon/fold/brace-fold');
require('codemirror/addon/fold/foldgutter'); require('codemirror/addon/fold/foldgutter');

View File

@ -82,8 +82,13 @@ const useCollectionTreeSync = () => {
toast.success('Collection is already opened'); toast.success('Collection is already opened');
}; };
const _displayError = (message) => { const _displayError = (error) => {
toast.error(message || 'Something went wrong!'); if(typeof error === "string") {
return toast.error(error || 'Something went wrong!');
}
if(typeof message === "object") {
return toast.error(error.message || 'Something went wrong!');
}
}; };
const _httpRequestSent = (val) => { const _httpRequestSent = (val) => {

View File

@ -1,6 +1,7 @@
import path from 'path'; import path from 'path';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import trim from 'lodash/trim'; import trim from 'lodash/trim';
import get from 'lodash/get';
import filter from 'lodash/filter'; import filter from 'lodash/filter';
import { uuid } from 'utils/common'; import { uuid } from 'utils/common';
import cloneDeep from 'lodash/cloneDeep'; import cloneDeep from 'lodash/cloneDeep';

View File

@ -888,7 +888,7 @@ export const collectionsSlice = createSlice({
} }
}, },
runFolderEvent: (state, action) => { runFolderEvent: (state, action) => {
const { collectionUid, folderUid, itemUid, type } = action.payload; const { collectionUid, folderUid, itemUid, type, error } = action.payload;
const collection = findCollectionByUid(state.collections, collectionUid); const collection = findCollectionByUid(state.collections, collectionUid);
if (collection) { if (collection) {
@ -920,6 +920,13 @@ export const collectionsSlice = createSlice({
const item = collection.runnerResult.items.find((i) => i.uid === request.uid); const item = collection.runnerResult.items.find((i) => i.uid === request.uid);
item.testResults = action.payload.testResults; item.testResults = action.payload.testResults;
} }
if(type === 'error') {
const item = collection.runnerResult.items.find((i) => i.uid === request.uid);
item.error = action.payload.error;
item.responseReceived = action.payload.responseReceived;
item.status = "error";
}
} }
} }
} }

View File

@ -74,7 +74,9 @@ const openCollection = async (win, watcher, collectionPath, options = {}) => {
ipcMain.emit('main:collection-opened', win, collectionPath, uid); ipcMain.emit('main:collection-opened', win, collectionPath, uid);
} catch(err) { } catch(err) {
if(!options.dontSendDisplayErrors) { if(!options.dontSendDisplayErrors) {
win.webContents.send('main:display-error', err.message || 'An error occured while opening the local collection'); win.webContents.send('main:display-error', {
error: err.message || 'An error occured while opening the local collection'
});
} }
} }
} else { } else {

View File

@ -257,6 +257,9 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
itemUid itemUid
}; };
let timeStart;
let timeEnd;
try { try {
mainWindow.webContents.send('main:run-folder-event', { mainWindow.webContents.send('main:run-folder-event', {
type: 'request-queued', type: 'request-queued',
@ -305,9 +308,9 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
...eventData ...eventData
}); });
const timeStart = Date.now(); timeStart = Date.now();
const response = await axios(request); const response = await axios(request);
const timeEnd = Date.now(); timeEnd = Date.now();
if(request.script && request.script.length) { 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);}';
@ -346,9 +349,27 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
} }
}); });
} catch (error) { } catch (error) {
let responseReceived = {};
let duration = 0;
if(timeStart && timeEnd) {
duration = timeEnd - timeStart;
}
if(error && error.response) {
responseReceived = {
status: error.response.status,
statusText: error.response.statusText,
headers: Object.entries(error.response.headers),
duration: duration,
size: error.response.headers['content-length'] || getSize(error.response.data),
data: error.response.data,
}
}
mainWindow.webContents.send('main:run-folder-event', { mainWindow.webContents.send('main:run-folder-event', {
type: 'error', type: 'error',
error, error: error ? error.message : 'An error occurred while running the request',
responseReceived: responseReceived,
...eventData ...eventData
}); });
} }
@ -356,8 +377,7 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
} catch (error) { } catch (error) {
mainWindow.webContents.send('main:run-folder-event', { mainWindow.webContents.send('main:run-folder-event', {
type: 'error', type: 'error',
error, error
...eventData
}); });
} }
}); });

View File

@ -27,35 +27,27 @@ const interpolateVars = (request, envVars = {}, collectionVariables ={}) => {
request.headers[key] = interpolate(value); request.headers[key] = interpolate(value);
}); });
if(request.headers["content-type"] === "application/json") {
if(typeof request.data === "object") {
try {
let parsed = JSON.stringify(request.data);
parsed = interpolate(parsed);
request.data = JSON.parse(parsed);
} catch (err) {
}
}
if(typeof request.data === "string") {
if(request.data.length) {
request.data = interpolate(request.data);
}
}
}
each(request.params, (param) => { each(request.params, (param) => {
param.value = interpolate(param.value); param.value = interpolate(param.value);
}); });
// Todo: Make interpolation work with body mode json
const mode = get(request, 'body.mode');
switch (mode) {
case 'text': {
request.body.text = interpolate(request.body.text);
break;
}
case 'xml': {
request.body.text = interpolate(request.body.text);
break;
}
case 'multipartForm': {
each(request.body.multipartForm, (param) => {
param.value = interpolate(param.value);
});
break;
}
case 'formUrlEncoded': {
each(request.body.formUrlEncoded, (param) => {
param.value = interpolate(param.value);
});
break;
}
}
return request; return request;
}; };