Skip to content

Commit

Permalink
feature(frontend): Adding Test Execution Deep Link (#2747)
Browse files Browse the repository at this point in the history
  • Loading branch information
xoscar committed Jun 16, 2023
1 parent 65a7fa4 commit bbb642c
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 14 deletions.
3 changes: 3 additions & 0 deletions web/src/components/Router/Router.tsx
Expand Up @@ -9,6 +9,7 @@ import Settings from 'pages/Settings';
import Test from 'pages/Test';
import Transaction from 'pages/Transaction';
import TransactionRunDetail from 'pages/TransactionRunDetail';
import AutomatedTestRun from 'pages/AutomatedTestRun';
import Env from 'utils/Env';

const serverPathPrefix = Env.get('serverPathPrefix');
Expand All @@ -28,6 +29,8 @@ const Router = () => (
<Route path=":mode" element={<RunDetail />} />
</Route>

<Route path="/test/:testId/version/:version/run" element={<AutomatedTestRun />} />

<Route path="/transaction/:transactionId" element={<Transaction />} />
<Route path="/transaction/:transactionId/run/:runId" element={<TransactionRunDetail />} />

Expand Down
2 changes: 1 addition & 1 deletion web/src/components/RunDetailLayout/HeaderRight.tsx
Expand Up @@ -48,7 +48,7 @@ const HeaderRight = ({testId, testVersion}: IProps) => {
</S.StateContainer>
)}
{!isDraftMode && state && isRunStateFinished(state) && (
<Button data-cy="run-test-button" ghost onClick={() => onRun(run.id)} type="primary">
<Button data-cy="run-test-button" ghost onClick={() => onRun()} type="primary">
Run Test
</Button>
)}
Expand Down
23 changes: 23 additions & 0 deletions web/src/pages/AutomatedTestRun/AutomatedTestRun.tsx
@@ -0,0 +1,23 @@
import {useParams} from 'react-router-dom';

import Layout from 'components/Layout';
import TestSpecFormProvider from 'components/TestSpecForm/TestSpecForm.provider';
import withAnalytics from 'components/WithAnalytics/WithAnalytics';
import TestProvider from 'providers/Test/Test.provider';
import Content from './Content';

const AutomatedTestRun = () => {
const {testId = '', version = '1'} = useParams();

return (
<Layout hasMenu>
<TestProvider testId={testId} version={Number(version)}>
<TestSpecFormProvider testId={testId}>
<Content />
</TestSpecFormProvider>
</TestProvider>
</Layout>
);
};

export default withAnalytics(AutomatedTestRun, 'automated-test-run');
17 changes: 17 additions & 0 deletions web/src/pages/AutomatedTestRun/Content.tsx
@@ -0,0 +1,17 @@
import {useEffect} from 'react';
import {useSearchParams} from 'react-router-dom';
import useAutomatedTestRun from './hooks/useAutomatedTestRun';
import TestContent from '../Test/Content';

const Content = () => {
const [query] = useSearchParams();
const onAutomatedRun = useAutomatedTestRun(query);

useEffect(() => {
onAutomatedRun();
}, [onAutomatedRun]);

return <TestContent />;
};

export default Content;
41 changes: 41 additions & 0 deletions web/src/pages/AutomatedTestRun/hooks/useAutomatedTestRun.ts
@@ -0,0 +1,41 @@
import {useCallback} from 'react';
import {TEnvironmentValue} from 'models/Environment.model';
import {useTest} from 'providers/Test/Test.provider';
import {useEnvironment} from 'providers/Environment/Environment.provider';
import {useNavigate} from 'react-router-dom';

const getParsedVariables = (rawVars: string): TEnvironmentValue[] => {
try {
const variables = JSON.parse(rawVars) as TEnvironmentValue[];

return Array.isArray(variables) ? variables : [];
} catch (err) {
return [];
}
};

const useAutomatedTestRun = (query: URLSearchParams) => {
const {
onRun,
test: {id: testId},
} = useTest();
const {selectedEnvironment} = useEnvironment();
const navigate = useNavigate();

const onAutomatedRun = useCallback(() => {
const variables = getParsedVariables(query.get('variables') ?? '[]');
const environmentId = query.get('environmentId') ?? selectedEnvironment?.id;

onRun({
variables,
environmentId,
onCancel() {
navigate(`/test/${testId}`, {replace: true});
},
});
}, [navigate, onRun, query, selectedEnvironment?.id, testId]);

return onAutomatedRun;
};

export default useAutomatedTestRun;
2 changes: 2 additions & 0 deletions web/src/pages/AutomatedTestRun/index.ts
@@ -0,0 +1,2 @@
// eslint-disable-next-line no-restricted-exports
export {default} from './AutomatedTestRun';
2 changes: 1 addition & 1 deletion web/src/pages/Home/Resources.tsx
Expand Up @@ -40,7 +40,7 @@ const Resources = () => {

const handleOnRun = useCallback(
(resource: Transaction | Test, type: ResourceType) => {
if (type === ResourceType.Test) runTest(resource as Test);
if (type === ResourceType.Test) runTest({test: resource as Test});
else if (type === ResourceType.Transaction) runTransaction(resource as Transaction);
},
[runTest, runTransaction]
Expand Down
2 changes: 1 addition & 1 deletion web/src/pages/Test/Content.tsx
Expand Up @@ -41,7 +41,7 @@ const Content = () => {
data-cy="test-details-run-test-button"
ghost
loading={isLoadingRunTest}
onClick={() => runTest(test)}
onClick={() => runTest({test})}
type="primary"
>
Run Test
Expand Down
2 changes: 1 addition & 1 deletion web/src/providers/CreateTest/CreateTest.provider.tsx
Expand Up @@ -71,7 +71,7 @@ const CreateTestProvider = ({children}: IProps) => {
async (draft: TDraftTest) => {
const rawTest = await TestService.getRequest(plugin, draft);
const test = await createTest(rawTest).unwrap();
runTest(test);
runTest({test});
},
[createTest, plugin, runTest]
);
Expand Down
Expand Up @@ -10,6 +10,7 @@ type TOnOPenProps = {
missingVariables: MissingVariables;
name: string;
onSubmit(draft: TEnvironmentValue[]): void;
onCancel?(): void;
testList: Test[];
};

Expand All @@ -28,9 +29,10 @@ interface IProps {
export const useMissingVariablesModal = () => useContext(Context);

const MissingVariablesModalProvider = ({children}: IProps) => {
const [{missingVariables = [], testList = [], onSubmit, name}, setProps] = useState<TOnOPenProps>({
const [{missingVariables = [], testList = [], onSubmit, onCancel = noop, name}, setProps] = useState<TOnOPenProps>({
missingVariables: [],
onSubmit: noop,
onCancel: noop,
name: '',
testList: [],
});
Expand Down Expand Up @@ -61,7 +63,10 @@ const MissingVariablesModalProvider = ({children}: IProps) => {
{children}
<MissingVariablesModal
testVariables={testVariables}
onClose={() => setIsOpen(false)}
onClose={() => {
setIsOpen(false);
onCancel();
}}
onSubmit={handleSubmit}
isOpen={isOpen}
name={name}
Expand Down
12 changes: 8 additions & 4 deletions web/src/providers/Test/Test.provider.tsx
Expand Up @@ -5,11 +5,11 @@ import {TDraftTest} from 'types/Test.types';
import VersionMismatchModal from 'components/VersionMismatchModal';
import TestService from 'services/Test.service';
import Test from 'models/Test.model';
import useTestCrud from './hooks/useTestCrud';
import useTestCrud, {TTestRunRequest} from './hooks/useTestCrud';

interface IContext {
onEdit(values: TDraftTest): void;
onRun(runId?: string): void;
onRun(runRequest?: Partial<TTestRunRequest>): void;
isLoading: boolean;
isError: boolean;
test: Test;
Expand Down Expand Up @@ -70,8 +70,12 @@ const TestProvider = ({children, testId, version = 0}: IProps) => {
);

const onRun = useCallback(
(runId?: string) => {
if (isLatestVersion) runTest(test!, runId);
(request: Partial<TTestRunRequest> = {}) => {
if (isLatestVersion)
runTest({
test: test!,
...request,
});
else {
setAction('run');
setIsVersionModalOpen(true);
Expand Down
19 changes: 15 additions & 4 deletions web/src/providers/Test/hooks/useTestCrud.ts
@@ -1,4 +1,5 @@
import {useCallback} from 'react';
import {noop} from 'lodash';
import {useMatch, useNavigate} from 'react-router-dom';
import {useAppDispatch} from 'redux/hooks';
import {reset} from 'redux/slices/TestSpecs.slice';
Expand All @@ -16,6 +17,13 @@ import {TEnvironmentValue} from 'models/Environment.model';
import Test from 'models/Test.model';
import RunError from 'models/RunError.model';

export type TTestRunRequest = {
test: Test;
environmentId?: string;
variables?: TEnvironmentValue[];
onCancel?(): void;
};

const useTestCrud = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
Expand All @@ -28,11 +36,11 @@ const useTestCrud = () => {
const {onOpen} = useMissingVariablesModal();

const runTest = useCallback(
async (test: Test, runId?: string, environmentId = selectedEnvironment?.id) => {
const run = async (variables: TEnvironmentValue[] = []) => {
async ({test, environmentId = selectedEnvironment?.id, variables = [], onCancel = noop}: TTestRunRequest) => {
const run = async (updatedVars: TEnvironmentValue[] = variables) => {
try {
TestAnalyticsService.onRunTest();
const {id} = await runTestAction({testId: test.id, environmentId, variables}).unwrap();
const {id} = await runTestAction({testId: test.id, environmentId, variables: updatedVars}).unwrap();
dispatch(reset());

const mode = match?.params.mode || 'trigger';
Expand All @@ -47,6 +55,7 @@ const useTestCrud = () => {
onSubmit(missing) {
run(missing);
},
onCancel,
});
else throw error;
}
Expand All @@ -69,7 +78,9 @@ const useTestCrud = () => {
testId,
}).unwrap();

runTest(test);
runTest({
test,
});
},
[editTest, runTest, updateIsInitialized]
);
Expand Down

0 comments on commit bbb642c

Please sign in to comment.