forked from extern/bruno
feat: start collection runner at root
This commit is contained in:
parent
58bc247c53
commit
37b1c043eb
@ -7,6 +7,10 @@ const Wrapper = styled.div`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.test-summary {
|
||||||
|
color: ${(props) => props.theme.tabs.active.border};
|
||||||
|
}
|
||||||
|
|
||||||
/* test results */
|
/* test results */
|
||||||
.test-success {
|
.test-success {
|
||||||
color: ${(props) => props.theme.colors.text.green};
|
color: ${(props) => props.theme.colors.text.green};
|
||||||
|
@ -41,12 +41,18 @@ export default function RunnerResults({collection}) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const passedRequests = items.filter((item) => item.testStatus === 'pass');
|
||||||
|
const failedRequests = items.filter((item) => item.testStatus === 'fail');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper className='px-4'>
|
<StyledWrapper className='px-4'>
|
||||||
<div className='font-medium mt-6 mb-4 title flex items-center'>
|
<div className='font-medium mt-6 mb-4 title flex items-center'>
|
||||||
Runner
|
Runner
|
||||||
<IconRun size={20} strokeWidth={1.5} className='ml-2'/>
|
<IconRun size={20} strokeWidth={1.5} className='ml-2'/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="py-2 font-medium test-summary">
|
||||||
|
Total Requests: {items.length}, Passed: {passedRequests.length}, Failed: {failedRequests.length}
|
||||||
|
</div>
|
||||||
<div className='flex'>
|
<div className='flex'>
|
||||||
<div className='flex flex-col flex-1'>
|
<div className='flex flex-col flex-1'>
|
||||||
{items.map((item) => {
|
{items.map((item) => {
|
||||||
|
@ -3,6 +3,7 @@ import get from 'lodash/get';
|
|||||||
import Modal from 'components/Modal';
|
import Modal from 'components/Modal';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { runCollectionFolder } from 'providers/ReduxStore/slices/collections/actions';
|
import { runCollectionFolder } from 'providers/ReduxStore/slices/collections/actions';
|
||||||
|
import { showRunnerView } from 'providers/ReduxStore/slices/collections';
|
||||||
import { flattenItems } from 'utils/collections';
|
import { flattenItems } from 'utils/collections';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
@ -10,12 +11,15 @@ const RunCollectionItem = ({ collection, item, onClose }) => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const onSubmit = (recursive) => {
|
const onSubmit = (recursive) => {
|
||||||
dispatch(runCollectionFolder(collection.uid, item.uid, recursive));
|
dispatch(showRunnerView({
|
||||||
|
collectionUid: collection.uid,
|
||||||
|
}));
|
||||||
|
dispatch(runCollectionFolder(collection.uid, item ? item.uid : null, recursive));
|
||||||
onClose();
|
onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const runLength = get(item, 'items.length', 0);
|
const runLength = item ? get(item, 'items.length', 0) : get(collection, 'items.length', 0);
|
||||||
const items = flattenItems(item.items);
|
const items = flattenItems(item ? item.items : collection.items);
|
||||||
const requestItems = items.filter((item) => item.type !== 'folder');
|
const requestItems = items.filter((item) => item.type !== 'folder');
|
||||||
const recursiveRunLength = requestItems.length;
|
const recursiveRunLength = requestItems.length;
|
||||||
|
|
||||||
@ -24,7 +28,7 @@ const RunCollectionItem = ({ collection, item, onClose }) => {
|
|||||||
<Modal size="md" title='Collection Runner' hideFooter={true} handleCancel={onClose}>
|
<Modal size="md" title='Collection Runner' hideFooter={true} handleCancel={onClose}>
|
||||||
<div className='mb-1'>
|
<div className='mb-1'>
|
||||||
<span className='font-medium'>Run</span>
|
<span className='font-medium'>Run</span>
|
||||||
<span className='ml-1 text-xs'>({runLength.length} requests)</span>
|
<span className='ml-1 text-xs'>({runLength} requests)</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='mb-8'>
|
<div className='mb-8'>
|
||||||
This will only run the requests in this folder.
|
This will only run the requests in this folder.
|
||||||
@ -32,7 +36,7 @@ const RunCollectionItem = ({ collection, item, onClose }) => {
|
|||||||
|
|
||||||
<div className='mb-1'>
|
<div className='mb-1'>
|
||||||
<span className='font-medium'>Recursive Run</span>
|
<span className='font-medium'>Recursive Run</span>
|
||||||
<span className='ml-1 text-xs'>({recursiveRunLength.length} requests)</span>
|
<span className='ml-1 text-xs'>({recursiveRunLength} requests)</span>
|
||||||
</div>
|
</div>
|
||||||
<div className='mb-8'>
|
<div className='mb-8'>
|
||||||
This will run all the requests in this folder and all its subfolders.
|
This will run all the requests in this folder and all its subfolders.
|
||||||
|
@ -6,7 +6,7 @@ import { useDrag, useDrop } from 'react-dnd';
|
|||||||
import { IconChevronRight, IconDots } from '@tabler/icons';
|
import { IconChevronRight, IconDots } from '@tabler/icons';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import { addTab, focusTab } from 'providers/ReduxStore/slices/tabs';
|
import { addTab, focusTab } from 'providers/ReduxStore/slices/tabs';
|
||||||
import { collectionFolderClicked } from 'providers/ReduxStore/slices/collections';
|
import { collectionFolderClicked, hideRunnerView } from 'providers/ReduxStore/slices/collections';
|
||||||
import { moveItem } from 'providers/ReduxStore/slices/collections/actions';
|
import { moveItem } from 'providers/ReduxStore/slices/collections/actions';
|
||||||
import Dropdown from 'components/Dropdown';
|
import Dropdown from 'components/Dropdown';
|
||||||
import NewRequest from 'components/Sidebar/NewRequest';
|
import NewRequest from 'components/Sidebar/NewRequest';
|
||||||
@ -86,6 +86,9 @@ const CollectionItem = ({ item, collection, searchText }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleClick = (event) => {
|
const handleClick = (event) => {
|
||||||
|
dispatch(hideRunnerView({
|
||||||
|
collectionUid: collection.uid
|
||||||
|
}));
|
||||||
if (isItemARequest(item)) {
|
if (isItemARequest(item)) {
|
||||||
if (itemIsOpenedInTabs(item, tabs)) {
|
if (itemIsOpenedInTabs(item, tabs)) {
|
||||||
dispatch(
|
dispatch(
|
||||||
|
@ -12,6 +12,7 @@ import NewRequest from 'components/Sidebar/NewRequest';
|
|||||||
import NewFolder from 'components/Sidebar/NewFolder';
|
import NewFolder from 'components/Sidebar/NewFolder';
|
||||||
import CollectionItem from './CollectionItem';
|
import CollectionItem from './CollectionItem';
|
||||||
import RemoveCollection from './RemoveCollection';
|
import RemoveCollection from './RemoveCollection';
|
||||||
|
import RunCollectionItem from './CollectionItem/RunCollectionItem';
|
||||||
import { doesCollectionHaveItemsMatchingSearchText } from 'utils/collections/search';
|
import { doesCollectionHaveItemsMatchingSearchText } from 'utils/collections/search';
|
||||||
import { isItemAFolder, isItemARequest, transformCollectionToSaveToIdb } from 'utils/collections';
|
import { isItemAFolder, isItemARequest, transformCollectionToSaveToIdb } from 'utils/collections';
|
||||||
import exportCollection from 'utils/collections/export';
|
import exportCollection from 'utils/collections/export';
|
||||||
@ -24,6 +25,7 @@ const Collection = ({ collection, searchText }) => {
|
|||||||
const [showNewRequestModal, setShowNewRequestModal] = useState(false);
|
const [showNewRequestModal, setShowNewRequestModal] = useState(false);
|
||||||
const [showRenameCollectionModal, setShowRenameCollectionModal] = useState(false);
|
const [showRenameCollectionModal, setShowRenameCollectionModal] = useState(false);
|
||||||
const [showRemoveCollectionModal, setShowRemoveCollectionModal] = useState(false);
|
const [showRemoveCollectionModal, setShowRemoveCollectionModal] = useState(false);
|
||||||
|
const [showRunCollectionModal, setShowRunCollectionModal] = useState(false);
|
||||||
const [collectionIsCollapsed, setCollectionIsCollapsed] = useState(collection.collapsed);
|
const [collectionIsCollapsed, setCollectionIsCollapsed] = useState(collection.collapsed);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
@ -97,6 +99,7 @@ const Collection = ({ collection, searchText }) => {
|
|||||||
{showNewFolderModal && <NewFolder collection={collection} onClose={() => setShowNewFolderModal(false)} />}
|
{showNewFolderModal && <NewFolder collection={collection} onClose={() => setShowNewFolderModal(false)} />}
|
||||||
{showRenameCollectionModal && <RenameCollection collection={collection} onClose={() => setShowRenameCollectionModal(false)} />}
|
{showRenameCollectionModal && <RenameCollection collection={collection} onClose={() => setShowRenameCollectionModal(false)} />}
|
||||||
{showRemoveCollectionModal && <RemoveCollection collection={collection} onClose={() => setShowRemoveCollectionModal(false)} />}
|
{showRemoveCollectionModal && <RemoveCollection collection={collection} onClose={() => setShowRemoveCollectionModal(false)} />}
|
||||||
|
{showRunCollectionModal && <RunCollectionItem collection={collection} onClose={() => setShowRunCollectionModal(false)} />}
|
||||||
<div className="flex py-1 collection-name items-center" ref={drop}>
|
<div className="flex py-1 collection-name items-center" ref={drop}>
|
||||||
<div className="flex flex-grow items-center overflow-hidden" onClick={handleClick}>
|
<div className="flex flex-grow items-center overflow-hidden" onClick={handleClick}>
|
||||||
<IconChevronRight size={16} strokeWidth={2} className={iconClassName} style={{ width: 16, minWidth:16, color: 'rgb(160 160 160)' }} />
|
<IconChevronRight size={16} strokeWidth={2} className={iconClassName} style={{ width: 16, minWidth:16, color: 'rgb(160 160 160)' }} />
|
||||||
@ -122,6 +125,15 @@ const Collection = ({ collection, searchText }) => {
|
|||||||
>
|
>
|
||||||
New Folder
|
New Folder
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
className="dropdown-item"
|
||||||
|
onClick={(e) => {
|
||||||
|
menuDropdownTippyRef.current.hide();
|
||||||
|
setShowRunCollectionModal(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Run
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
className="dropdown-item"
|
className="dropdown-item"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
@ -151,7 +151,7 @@ export const runCollectionFolder = (collectionUid, folderUid, recursive) => (dis
|
|||||||
const collectionCopy = cloneDeep(collection);
|
const collectionCopy = cloneDeep(collection);
|
||||||
const folder = findItemInCollection(collectionCopy, folderUid);
|
const folder = findItemInCollection(collectionCopy, folderUid);
|
||||||
|
|
||||||
if (!folder) {
|
if (folderUid && !folder) {
|
||||||
return reject(new Error('Folder not found'));
|
return reject(new Error('Folder not found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +164,10 @@ export const runCollectionFolder = (collectionUid, folderUid, recursive) => (dis
|
|||||||
ipcRenderer
|
ipcRenderer
|
||||||
.invoke('renderer:run-collection-folder', folder, collectionCopy, environment, recursive)
|
.invoke('renderer:run-collection-folder', folder, collectionCopy, environment, recursive)
|
||||||
.then(resolve)
|
.then(resolve)
|
||||||
.catch(reject);
|
.catch((err) => {
|
||||||
|
toast.error(get(err, 'error.message') || 'Something went wrong!');
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -860,6 +860,22 @@ export const collectionsSlice = createSlice({
|
|||||||
collection.showRunner = !collection.showRunner;
|
collection.showRunner = !collection.showRunner;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
showRunnerView: (state, action) => {
|
||||||
|
const { collectionUid } = action.payload;
|
||||||
|
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||||
|
|
||||||
|
if (collection) {
|
||||||
|
collection.showRunner = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hideRunnerView: (state, action) => {
|
||||||
|
const { collectionUid } = action.payload;
|
||||||
|
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||||
|
|
||||||
|
if (collection) {
|
||||||
|
collection.showRunner = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
resetRunResults: (state, action) => {
|
resetRunResults: (state, action) => {
|
||||||
const { collectionUid } = action.payload;
|
const { collectionUid } = action.payload;
|
||||||
const collection = findCollectionByUid(state.collections, collectionUid);
|
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||||
@ -956,6 +972,8 @@ export const {
|
|||||||
testResultsEvent,
|
testResultsEvent,
|
||||||
collectionRenamedEvent,
|
collectionRenamedEvent,
|
||||||
toggleRunnerView,
|
toggleRunnerView,
|
||||||
|
showRunnerView,
|
||||||
|
hideRunnerView,
|
||||||
resetRunResults,
|
resetRunResults,
|
||||||
runFolderEvent
|
runFolderEvent
|
||||||
} = collectionsSlice.actions;
|
} = collectionsSlice.actions;
|
||||||
|
@ -221,7 +221,11 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
ipcMain.handle('renderer:run-collection-folder', async (event, folder, collection, environment, recursive) => {
|
ipcMain.handle('renderer:run-collection-folder', async (event, folder, collection, environment, recursive) => {
|
||||||
const collectionUid = collection.uid;
|
const collectionUid = collection.uid;
|
||||||
const collectionPath = collection.pathname;
|
const collectionPath = collection.pathname;
|
||||||
const folderUid = folder.uid;
|
const folderUid = folder ? folder.uid : null;
|
||||||
|
|
||||||
|
if(!folder) {
|
||||||
|
folder = collection;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const envVars = getEnvVars(environment);
|
const envVars = getEnvVars(environment);
|
||||||
@ -230,10 +234,6 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
if(recursive) {
|
if(recursive) {
|
||||||
let sortedFolder = sortFolder(folder);
|
let sortedFolder = sortFolder(folder);
|
||||||
folderRequests = getAllRequestsInFolderRecursively(sortedFolder);
|
folderRequests = getAllRequestsInFolderRecursively(sortedFolder);
|
||||||
console.log('-----sortedFolder------');
|
|
||||||
console.log(sortedFolder);
|
|
||||||
console.log('-----folderRequests------');
|
|
||||||
console.log(folderRequests);
|
|
||||||
} else {
|
} else {
|
||||||
each(folder.items, (item) => {
|
each(folder.items, (item) => {
|
||||||
if(item.request) {
|
if(item.request) {
|
||||||
@ -331,7 +331,6 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
|
||||||
mainWindow.webContents.send('main:run-folder-event', {
|
mainWindow.webContents.send('main:run-folder-event', {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
error,
|
error,
|
||||||
@ -342,13 +341,8 @@ 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',
|
||||||
data: {
|
error,
|
||||||
error : {
|
...eventData
|
||||||
message: error.message
|
|
||||||
},
|
|
||||||
collectionUid,
|
|
||||||
folderUid
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user