@finos/legend-application-studio
Version:
Legend Studio application core
200 lines • 26.2 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/**
* Copyright (c) 2020-present, Goldman Sachs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ContextMenu, PlusIcon, ResizablePanel, ResizablePanelGroup, ResizablePanelSplitter, ResizablePanelSplitterLine, MenuContent, MenuContentItem, clsx, FlaskIcon, RunAllIcon, RunErrorsIcon, CheckCircleIcon, TimesCircleIcon, TestTubeIcon, CustomSelectorInput, Dialog, RefreshIcon, TimesIcon, FilledWindowMaximizeIcon, PlayIcon, } from '@finos/legend-art';
import { PrimitiveInstanceValue, PrimitiveType, PureMultiExecution, resolveServiceQueryRawLambda, } from '@finos/legend-graph';
import { BasicValueSpecificationEditor, instanceValue_setValue, } from '@finos/legend-query-builder';
import { filterByType, guaranteeNonNullable, prettyCONSTName, } from '@finos/legend-shared';
import { flowResult } from 'mobx';
import { observer } from 'mobx-react-lite';
import { forwardRef, useEffect, useState } from 'react';
import { ServiceValueSpecificationTestParameterState, } from '../../../../../stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.js';
import { TESTABLE_TEST_TAB } from '../../../../../stores/editor/editor-state/element-editor-state/testable/TestableEditorState.js';
import { atomicTest_setId, testAssertion_setId, } from '../../../../../stores/graph-modifier/Testable_GraphModifierHelper.js';
import { getTestableResultFromTestResult, TESTABLE_RESULT, } from '../../../../../stores/editor/sidebar-state/testable/GlobalTestRunnerState.js';
import { getTestableResultIcon } from '../../../side-bar/testable/GlobalTestRunner.js';
import { ExternalFormatParameterEditorModal, RenameModal, TestAssertionEditor, TestAssertionItem, } from '../../testable/TestableSharedComponents.js';
import { LEGEND_STUDIO_TEST_ID } from '../../../../../__lib__/LegendStudioTesting.js';
import { getContentTypeWithParamFromQuery, } from '../../../../../stores/editor/utils/TestableUtils.js';
export const NewParameterModal = observer((props) => {
const { setupState, isReadOnly } = props;
const applicationStore = setupState.editorStore.applicationStore;
const currentOption = {
value: setupState.newParameterValueName,
label: setupState.newParameterValueName,
};
const options = setupState.newParamOptions;
const closeModal = () => setupState.setShowNewParameterModal(false);
const onChange = (val) => {
if (val === null) {
setupState.setNewParameterValueName('');
}
else if (val.value !== setupState.newParameterValueName) {
setupState.setNewParameterValueName(val.value);
}
};
return (_jsx(Dialog, { open: setupState.showNewParameterModal, onClose: closeModal, classes: { container: 'search-modal__container' }, PaperProps: { classes: { root: 'search-modal__inner-container' } }, children: _jsxs("form", { onSubmit: (event) => {
event.preventDefault();
setupState.addParameterValue();
}, className: "modal modal--dark search-modal", children: [_jsx("div", { className: "modal__title", children: "New Test Parameter Value " }), _jsx(CustomSelectorInput, { className: "panel__content__form__section__dropdown", options: options, onChange: onChange, value: currentOption, escapeClearsValue: true, darkMode: !applicationStore.layoutService
.TEMPORARY__isLightColorThemeEnabled, disabled: isReadOnly }), _jsx("div", { className: "search-modal__actions", children: _jsx("button", { className: "btn btn--dark", disabled: isReadOnly, children: "Add" }) })] }) }));
});
const ServiceTestParameterEditor = observer((props) => {
const { serviceTestState, paramState, isReadOnly, contentTypeParamPair } = props;
const [showPopUp, setShowPopUp] = useState(false);
const setupState = serviceTestState.setupState;
const paramIsRequired = paramState.varExpression.multiplicity.lowerBound > 0;
const type = contentTypeParamPair
? contentTypeParamPair.contentType
: (paramState.varExpression.genericType?.value.rawType.name ?? 'unknown');
const paramValue = paramState.varExpression.genericType?.value.rawType === PrimitiveType.BYTE
? atob(paramState.valueSpec
.values[0])
: paramState.valueSpec
.values[0];
const openInPopUp = () => setShowPopUp(!showPopUp);
const closePopUp = () => setShowPopUp(false);
const updateParamValue = (val) => {
if (paramState.valueSpec instanceof PrimitiveInstanceValue) {
instanceValue_setValue(paramState.valueSpec, paramState.varExpression.genericType?.value.rawType ===
PrimitiveType.BYTE
? btoa(val)
: val, 0, setupState.editorStore.changeDetectionState.observerContext);
paramState.updateValueSpecification(paramState.valueSpec);
}
};
return (_jsxs("div", { className: "panel__content__form__section", children: [_jsxs("div", { className: "panel__content__form__section__header__label", children: [paramState.parameterValue.name, _jsx("button", { className: clsx('type-tree__node__type__label', {}), tabIndex: -1, title: type, children: type })] }), _jsx(_Fragment, { children: contentTypeParamPair ? (_jsxs("div", { className: "service-test-editor__setup__parameter__code-editor", children: [_jsx("textarea", { className: "panel__content__form__section__textarea value-spec-editor__input", spellCheck: false, value: paramValue, placeholder: paramState.valueSpec
.values[0] === ''
? '(empty)'
: undefined, onChange: (event) => {
updateParamValue(event.target.value);
} }), showPopUp && (_jsx(ExternalFormatParameterEditorModal, { valueSpec: paramState.valueSpec, varExpression: paramState.varExpression, isReadOnly: isReadOnly, onClose: closePopUp, updateParamValue: updateParamValue, contentTypeParamPair: contentTypeParamPair })), _jsxs("div", { className: "service-test-editor__setup__parameter__value__actions", children: [_jsx("button", { className: clsx('service-test-editor__setup__parameter__code-editor__expand-btn'), onClick: openInPopUp, tabIndex: -1, title: "Open in a popup...", children: _jsx(FilledWindowMaximizeIcon, {}) }), _jsx("button", { className: clsx('btn--icon btn--dark btn--sm service-test-editor__setup__parameter__code-editor__expand-btn'), disabled: isReadOnly || paramIsRequired, onClick: () => setupState.removeParamValueState(paramState), tabIndex: -1, title: paramIsRequired ? 'Parameter Required' : 'Remove Parameter', children: _jsx(TimesIcon, {}) })] })] })) : (_jsxs("div", { className: "service-test-editor__setup__parameter__value", children: [_jsx(BasicValueSpecificationEditor, { valueSpecification: paramState.valueSpec, setValueSpecification: (val) => {
paramState.updateValueSpecification(val);
}, graph: setupState.editorStore.graphManagerState.graph, observerContext: setupState.editorStore.changeDetectionState.observerContext, typeCheckOption: {
expectedType: paramState.varExpression.genericType?.value.rawType ??
PrimitiveType.STRING,
}, className: "query-builder__parameters__value__editor", resetValue: () => {
paramState.resetValueSpec();
} }), _jsx("div", { className: "service-test-editor__setup__parameter__value__actions", children: _jsx("button", { className: "btn--icon btn--dark btn--sm", disabled: isReadOnly || paramIsRequired, onClick: () => setupState.removeParamValueState(paramState), tabIndex: -1, title: paramIsRequired ? 'Parameter Required' : 'Remove Parameter', children: _jsx(TimesIcon, {}) }) })] })) })] }, paramState.parameterValue.name));
});
const ServiceTestSetupEditor = observer((props) => {
const { serviceTestState } = props;
const setupState = serviceTestState.setupState;
const applicationStore = setupState.editorStore.applicationStore;
const test = serviceTestState.test;
const format = test.serializationFormat;
const selectedSerializationFormat = setupState.getSelectedFormatOption();
const options = setupState.options;
const keyOptions = setupState.keyOptions;
const selectedKeys = setupState.getSelectedKeyOptions();
const isReadOnly = serviceTestState.suiteState.testableState.serviceEditorState.isReadOnly;
const onSerializationFormatChange = (val) => {
if (val === null) {
setupState.changeSerializationFormat(undefined);
}
else if (val.value !== format) {
setupState.changeSerializationFormat(val.value);
}
};
const onKeyOptionChange = (val) => {
setupState.addServiceTestAssertKeys(val.map((op) => op.value));
};
const addParameter = () => {
setupState.setShowNewParameterModal(true);
};
const generateParameterValues = () => {
setupState.generateTestParameterValues();
};
useEffect(() => {
setupState.syncWithQuery();
}, [setupState]);
return (_jsxs("div", { "data-testid": LEGEND_STUDIO_TEST_ID.SERVICE_TEST_EDITOR__SETUP, className: "panel service-test-editor", children: [_jsx("div", { className: "panel__header", children: _jsx("div", { className: "service-test-suite-editor__header__title", children: _jsx("div", { className: "service-test-suite-editor__header__title__label", children: "setup" }) }) }), _jsx("div", { className: "service-test-editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "horizontal", children: [_jsx(ResizablePanel, { size: 230, minSize: 28, children: _jsxs("div", { className: "service-test-data-editor panel", children: [_jsx("div", { className: "service-test-suite-editor__header", children: _jsx("div", { className: "service-test-suite-editor__header__title", children: _jsx("div", { className: "service-test-suite-editor__header__title__label", children: "configuration" }) }) }), _jsxs("div", { className: "service-test-editor__setup__configuration", children: [_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Serialization Format" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "Format to serialize execution result" }), _jsx(CustomSelectorInput, { className: "panel__content__form__section__dropdown", options: options, onChange: onSerializationFormatChange, value: selectedSerializationFormat, isClearable: true, escapeClearsValue: true, darkMode: !applicationStore.layoutService
.TEMPORARY__isLightColorThemeEnabled, disabled: isReadOnly })] }), setupState.testState.testable.execution instanceof
PureMultiExecution && (_jsxs("div", { className: "panel__content__form__section", children: [_jsx("div", { className: "panel__content__form__section__header__label", children: "Keys" }), _jsx("div", { className: "panel__content__form__section__header__prompt", children: "Specify keys for each test to run assertions against selected env keys" }), _jsx(CustomSelectorInput, { className: "panel__content__form__section__dropdown", options: keyOptions, onChange: onKeyOptionChange, value: selectedKeys, isClearable: true, escapeClearsValue: true, darkMode: !applicationStore.layoutService
.TEMPORARY__isLightColorThemeEnabled, isMulti: true, disabled: isReadOnly, placeholder: "Choose keys..." })] }))] })] }) }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { minSize: 56, children: _jsxs("div", { "data-testid": LEGEND_STUDIO_TEST_ID.SERVICE_TEST_EDITOR__SETUP__PARAMETERS, className: "service-test-data-editor panel", children: [_jsxs("div", { className: "service-test-suite-editor__header", children: [_jsx("div", { className: "service-test-suite-editor__header__title", children: _jsx("div", { className: "service-test-suite-editor__header__title__label", children: "parameters" }) }), _jsxs("div", { className: "panel__header__actions", children: [_jsx("button", { className: "panel__header__action service-execution-editor__test-data__generate-btn", onClick: generateParameterValues, title: "Generate test parameter values", tabIndex: -1, children: _jsxs("div", { className: "service-execution-editor__test-data__generate-btn__label", children: [_jsx(RefreshIcon, { className: "service-execution-editor__test-data__generate-btn__label__icon" }), _jsx("div", { className: "service-execution-editor__test-data__generate-btn__label__title", children: "Generate" })] }) }), _jsx("button", { className: "panel__header__action", tabIndex: -1, disabled: !setupState.newParamOptions.length, onClick: addParameter, title: "Add Parameter Value", children: _jsx(PlusIcon, {}) })] })] }), _jsx("div", { className: "service-test-editor__setup__parameters", children: setupState.parameterValueStates
.filter(filterByType(ServiceValueSpecificationTestParameterState))
.map((paramState) => (_jsx(ServiceTestParameterEditor, { isReadOnly: isReadOnly, paramState: paramState, serviceTestState: serviceTestState, contentTypeParamPair: getContentTypeWithParamFromQuery(resolveServiceQueryRawLambda(serviceTestState.service), serviceTestState.editorStore).find((pair) => pair.param === paramState.parameterValue.name) }, paramState.uuid))) }), setupState.showNewParameterModal && (_jsx(NewParameterModal, { setupState: setupState, isReadOnly: false }))] }) })] }) })] }));
});
const TestAssertionsEditor = observer((props) => {
const { serviceTestState } = props;
const isReadOnly = serviceTestState.suiteState.testableState.serviceEditorState.isReadOnly;
const editorStore = serviceTestState.editorStore;
const selectedAsertionState = serviceTestState.selectedAsertionState;
const hideExplorer = serviceTestState.test.assertions.length === 1 &&
serviceTestState.selectedAsertionState?.assertion.id ===
serviceTestState.test.assertions[0]?.id;
const addAssertion = () => serviceTestState.addAssertion();
const renameAssertion = (val) => testAssertion_setId(guaranteeNonNullable(serviceTestState.assertionToRename), val);
const runTest = () => {
flowResult(serviceTestState.runTest()).catch(editorStore.applicationStore.alertUnhandledError);
};
return (_jsx("div", { className: "panel service-test-editor", children: hideExplorer && selectedAsertionState ? (_jsx(TestAssertionEditor, { testAssertionState: selectedAsertionState })) : (_jsx("div", { className: "service-test-editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsxs(ResizablePanel, { minSize: 100, size: 200, children: [_jsxs("div", { className: "binding-editor__header", children: [_jsxs("div", { className: "binding-editor__header__title", children: [_jsxs("div", { className: "testable-test-assertion-explorer__header__summary", children: [_jsx("div", { className: "testable-test-assertion-explorer__header__summary__icon testable-test-assertion-explorer__header__summary__icon--assertion", children: _jsx(TestTubeIcon, {}) }), _jsx("div", { children: serviceTestState.assertionCount })] }), _jsxs("div", { className: "testable-test-assertion-explorer__header__summary", children: [_jsx("div", { className: "testable-test-assertion-explorer__header__summary__icon testable-test-assertion-explorer__header__summary__icon--passed", children: _jsx(CheckCircleIcon, {}) }), _jsx("div", { children: serviceTestState.assertionPassed })] }), _jsxs("div", { className: "testable-test-assertion-explorer__header__summary", children: [_jsx("div", { className: "testable-test-assertion-explorer__header__summary__icon testable-test-assertion-explorer__header__summary__icon--failed", children: _jsx(TimesCircleIcon, {}) }), _jsx("div", { children: serviceTestState.assertionFailed })] })] }), _jsxs("div", { className: "panel__header__actions", children: [_jsx("button", { className: "panel__header__action testable-test-explorer__play__all__icon", tabIndex: -1, onClick: runTest, title: "Run All Assertions", children: _jsx(RunAllIcon, {}) }), _jsx("button", { className: "panel__header__action", tabIndex: -1, onClick: addAssertion, title: "Add Test Assertion", children: _jsx(PlusIcon, {}) })] })] }), _jsx("div", { children: serviceTestState.assertionEditorStates.map((assertionState) => (_jsx(TestAssertionItem, { testableTestState: serviceTestState, testAssertionEditorState: assertionState, isReadOnly: serviceTestState.suiteState.testableState
.serviceEditorState.isReadOnly }, assertionState.assertion.id))) }), serviceTestState.assertionToRename && (_jsx(RenameModal, { val: serviceTestState.assertionToRename.id, isReadOnly: isReadOnly, showModal: true, closeModal: () => serviceTestState.setAssertionToRename(undefined), setValue: renameAssertion }))] }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: selectedAsertionState && (_jsx(TestAssertionEditor, { testAssertionState: selectedAsertionState })) })] }) })) }));
});
const ServiceTestEditor = observer((props) => {
const { serviceTestState } = props;
const selectedTab = serviceTestState.selectedTab;
return (_jsxs("div", { className: "service-test-editor panel", children: [_jsx("div", { className: "panel__header", children: _jsx("div", { className: "panel__header service-test-editor__header--with-tabs", children: _jsx("div", { className: "uml-element-editor__tabs", children: Object.values(TESTABLE_TEST_TAB).map((tab) => (_jsx("div", { onClick: () => serviceTestState.setSelectedTab(tab), className: clsx('service-test-editor__tab', {
'service-test-editor__tab--active': tab === serviceTestState.selectedTab,
}), children: prettyCONSTName(tab) }, tab))) }) }) }), _jsxs("div", { className: "service-test-editor", children: [selectedTab === TESTABLE_TEST_TAB.SETUP && (_jsx(ServiceTestSetupEditor, { serviceTestState: serviceTestState })), selectedTab === TESTABLE_TEST_TAB.ASSERTION && (_jsx(TestAssertionsEditor, { serviceTestState: serviceTestState }))] })] }));
});
const ServiceTestDataContextMenu = observer(forwardRef(function TestContainerContextMenu(props, ref) {
const { suiteState, serviceTestState } = props;
const addTest = () => {
suiteState.addServiceTest();
};
const remove = () => suiteState.deleteTest(serviceTestState);
const rename = () => suiteState.setTestToRename(serviceTestState.test);
const runTest = serviceTestState.editorStore.applicationStore.guardUnhandledError(() => flowResult(serviceTestState.runTest()));
return (_jsxs(MenuContent, { ref: ref, children: [_jsx(MenuContentItem, { disabled: suiteState.runningTestState.isInProgress ||
serviceTestState.runningTestAction.isInProgress, onClick: runTest, children: "Run test" }), _jsx(MenuContentItem, { onClick: rename, children: "Rename" }), _jsx(MenuContentItem, { onClick: remove, children: "Delete" }), _jsx(MenuContentItem, { onClick: addTest, children: "Add test" })] }));
}));
const ServiceTestItem = observer((props) => {
const { serviceTestState, suiteState } = props;
const serviceTest = serviceTestState.test;
const isRunning = serviceTestState.runningTestAction.isInProgress;
const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] = useState(false);
const isReadOnly = suiteState.testableState.serviceEditorState.isReadOnly;
const openTest = () => suiteState.setSelectedTestState(serviceTestState);
const isActive = suiteState.selectedTestState?.test === serviceTest;
const _testableResult = getTestableResultFromTestResult(serviceTestState.testResultState.result);
const testableResult = isRunning
? TESTABLE_RESULT.IN_PROGRESS
: _testableResult;
const resultIcon = getTestableResultIcon(testableResult);
const onContextMenuOpen = () => setIsSelectedFromContextMenu(true);
const onContextMenuClose = () => setIsSelectedFromContextMenu(false);
const runTest = serviceTestState.editorStore.applicationStore.guardUnhandledError(() => flowResult(serviceTestState.runTest()));
return (_jsx(ContextMenu, { disabled: isReadOnly, content: _jsx(ServiceTestDataContextMenu, { suiteState: suiteState, serviceTestState: serviceTestState }), menuProps: { elevation: 7 }, onOpen: onContextMenuOpen, onClose: onContextMenuClose, children: _jsxs("div", { className: clsx('testable-test-explorer__item', {
'testable-test-explorer__item--selected-from-context-menu': !isActive && isSelectedFromContextMenu,
}, { 'testable-test-explorer__item--active': isActive }), children: [_jsxs("button", { className: clsx('testable-test-explorer__item__label'), onClick: openTest, tabIndex: -1, children: [_jsx("div", { className: "testable-test-explorer__item__label__icon", children: resultIcon }), _jsx("div", { className: "testable-test-explorer__item__label__text", children: serviceTest.id })] }), _jsx("div", { className: "mapping-test-explorer__item__actions", children: _jsx("button", { className: "mapping-test-explorer__item__action mapping-test-explorer__run-test-btn", onClick: runTest, disabled: suiteState.runningTestState.isInProgress ||
serviceTestState.runningTestAction.isInProgress, tabIndex: -1, title: `Run ${serviceTest.id}`, children: _jsx(PlayIcon, {}) }) })] }) }));
});
export const ServiceTestsEditor = observer((props) => {
const { suiteState } = props;
const editorStore = suiteState.editorStore;
const isReadOnly = suiteState.testableState.serviceEditorState.isReadOnly;
const addTest = () => suiteState.addServiceTest();
const runSuite = () => {
flowResult(suiteState.runSuite()).catch(editorStore.applicationStore.alertUnhandledError);
};
const runFailingTests = () => {
flowResult(suiteState.runFailingTests()).catch(editorStore.applicationStore.alertUnhandledError);
};
const renameTest = (val) => atomicTest_setId(guaranteeNonNullable(suiteState.testToRename), val);
return (_jsxs("div", { "data-testid": LEGEND_STUDIO_TEST_ID.SERVICE_TEST_EDITOR, className: "panel service-test-editor", children: [_jsx("div", { className: "service-test-suite-editor__header", children: _jsx("div", { className: "service-test-suite-editor__header__title", children: _jsx("div", { className: "service-test-suite-editor__header__title__label service-test-suite-editor__header__title__label--tests", children: "tests" }) }) }), _jsx("div", { className: "service-test-editor__content", children: _jsxs(ResizablePanelGroup, { orientation: "vertical", children: [_jsxs(ResizablePanel, { minSize: 100, size: 300, children: [_jsxs("div", { className: "binding-editor__header", children: [_jsxs("div", { className: "binding-editor__header__title", children: [_jsxs("div", { className: "testable-test-assertion-explorer__header__summary", children: [_jsx("div", { className: "testable-test-assertion-explorer__header__summary__icon testable-test-assertion-explorer__header__summary__icon--test", children: _jsx(FlaskIcon, {}) }), _jsx("div", { children: suiteState.testCount })] }), _jsxs("div", { className: "testable-test-assertion-explorer__header__summary", children: [_jsx("div", { className: "testable-test-assertion-explorer__header__summary__icon testable-test-assertion-explorer__header__summary__icon--passed", children: _jsx(CheckCircleIcon, {}) }), _jsx("div", { children: suiteState.testPassed })] }), _jsxs("div", { className: "testable-test-assertion-explorer__header__summary", children: [_jsx("div", { className: "testable-test-assertion-explorer__header__summary__icon testable-test-assertion-explorer__header__summary__icon--failed", children: _jsx(TimesCircleIcon, {}) }), _jsx("div", { children: suiteState.testFailed })] })] }), _jsxs("div", { className: "panel__header__actions", children: [_jsx("button", { className: "panel__header__action testable-test-explorer__play__all__icon", tabIndex: -1, onClick: runSuite, title: "Run Suite Tests", children: _jsx(RunAllIcon, {}) }), _jsx("button", { className: "panel__header__action testable-test-explorer__play__all__icon", tabIndex: -1, onClick: runFailingTests, title: "Run All Failing Tests", children: _jsx(RunErrorsIcon, {}) }), _jsx("button", { className: "panel__header__action", tabIndex: -1, onClick: addTest, title: "Add Service Test", children: _jsx(PlusIcon, {}) })] })] }), _jsx("div", { children: suiteState.testStates.map((testState) => (_jsx(ServiceTestItem, { suiteState: suiteState, serviceTestState: testState }, testState.test.id))) }), suiteState.testToRename && (_jsx(RenameModal, { val: suiteState.testToRename.id, isReadOnly: isReadOnly, showModal: true, closeModal: () => suiteState.setTestToRename(undefined), setValue: renameTest }))] }), _jsx(ResizablePanelSplitter, { children: _jsx(ResizablePanelSplitterLine, { color: "var(--color-dark-grey-200)" }) }), _jsx(ResizablePanel, { children: suiteState.selectedTestState && (_jsx(ServiceTestEditor, { serviceTestState: suiteState.selectedTestState })) })] }) })] }));
});
//# sourceMappingURL=ServiceTestsEditor.js.map