fix(场景步骤): 场景交互优化
This commit is contained in:
parent
6bccc40e9c
commit
c6ee982ab8
|
@ -332,14 +332,14 @@
|
|||
</paramsTable>
|
||||
</div>
|
||||
<!-- 正则结束 -->
|
||||
<fastExtraction
|
||||
v-model:visible="fastExtractionVisible"
|
||||
:config="activeRecord"
|
||||
:response="props.response"
|
||||
:is-show-more-setting="false"
|
||||
@apply="handleFastExtractionApply"
|
||||
/>
|
||||
</div>
|
||||
<fastExtraction
|
||||
v-model:visible="fastExtractionVisible"
|
||||
:config="activeRecord"
|
||||
:response="props.response"
|
||||
:is-show-more-setting="false"
|
||||
@apply="handleFastExtractionApply"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
|
@ -257,15 +257,13 @@
|
|||
formalParameterVars,
|
||||
JMeterAllGroup,
|
||||
JMeterAllVars,
|
||||
JMeterVariableGroup,
|
||||
mockAllGroup,
|
||||
mockAllParams,
|
||||
mockFunctions,
|
||||
sameFuncNameVars,
|
||||
} from './config';
|
||||
import type { MockParamInputGroupItem, MockParamItem } from './types';
|
||||
import type { AutoComplete, CascaderOption, FormInstance } from '@arco-design/web-vue';
|
||||
import { string } from 'fast-glob/out/utils';
|
||||
import type { AutoComplete, FormInstance } from '@arco-design/web-vue';
|
||||
|
||||
const props = defineProps<{
|
||||
value: string;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<a-tooltip :content="tagsTooltip">
|
||||
<div class="flex max-w-[440px] flex-row">
|
||||
<div class="flex max-w-[440px] flex-row" @click="emit('click')">
|
||||
<MsTag v-for="tag of showTagList" :key="tag.id" :width="getTagWidth(tag)" :size="props.size" v-bind="attrs">
|
||||
{{ props.isStringTag ? tag : tag[props.nameKey] }}
|
||||
</MsTag>
|
||||
|
@ -30,6 +30,9 @@
|
|||
size: 'medium',
|
||||
}
|
||||
);
|
||||
const emit = defineEmits<{
|
||||
(e: 'click'): void;
|
||||
}>();
|
||||
|
||||
const attrs = useAttrs();
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
:readonly="props.readonly"
|
||||
:class="props.inputClass"
|
||||
:size="props.size"
|
||||
:disabled="props.disabled"
|
||||
@press-enter="tagInputEnter"
|
||||
@blur="tagInputBlur"
|
||||
@clear="emit('clear')"
|
||||
|
@ -53,6 +54,7 @@
|
|||
class?: string;
|
||||
inputClass?: string;
|
||||
size?: 'small' | 'large' | 'medium' | 'mini';
|
||||
disabled?: boolean;
|
||||
}>(),
|
||||
{
|
||||
retainInputValue: true,
|
||||
|
|
|
@ -310,7 +310,6 @@ export type ScenarioStepDetail = Partial<
|
|||
ScenarioStepConfig & {
|
||||
protocol: string;
|
||||
method: RequestMethods;
|
||||
isRefScenarioStep?: boolean; // 是否是完全引用的场景下的步骤,是的话不允许启用禁用
|
||||
}
|
||||
>;
|
||||
export interface ScenarioStepItem {
|
||||
|
@ -340,6 +339,8 @@ export interface ScenarioStepItem {
|
|||
executeStatus?: ScenarioExecuteStatus;
|
||||
isExecuting?: boolean; // 是否正在执行
|
||||
reportId?: string | number; // 步骤单个调试时的报告id
|
||||
isQuoteScenarioStep?: boolean; // 是否是引用场景下的步骤(不分是不是完全引用,只要是引用类型就是),不可修改引用 api 的参数值
|
||||
isRefScenarioStep?: boolean; // 是否是完全引用的场景下的步骤,是的话不允许启用禁用
|
||||
}
|
||||
// 场景
|
||||
export interface Scenario {
|
||||
|
|
|
@ -546,7 +546,6 @@
|
|||
import { groupCategoryEnvList, groupProjectEnv } from '@/api/modules/project-management/envManagement';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useAppStore from '@/store/modules/app';
|
||||
import { isArray, isEmptyObject, isObject, isString } from '@/utils/is';
|
||||
|
||||
import { ModuleTreeNode, TransferFileParams } from '@/models/common';
|
||||
import { HttpForm, ProjectOptionItem } from '@/models/projectManagement/environmental';
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<template>
|
||||
<assertion v-model:params="assertionConfig.assertions" :is-definition="false" :assertion-config="assertionConfig" />
|
||||
<assertion
|
||||
v-model:params="assertionConfig.assertions"
|
||||
:is-definition="false"
|
||||
:assertion-config="assertionConfig"
|
||||
@change="emit('change')"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
@ -7,6 +12,10 @@
|
|||
|
||||
import { AssertionConfig } from '@/models/apiTest/scenario';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'change'): void;
|
||||
}>();
|
||||
|
||||
const assertionConfig = defineModel<AssertionConfig>('assertionConfig', {
|
||||
required: true,
|
||||
});
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
v-model:model-value="requestVModel.name"
|
||||
:max-length="255"
|
||||
:placeholder="t('apiTestManagement.apiNamePlaceholder')"
|
||||
:disabled="!isEditableApi"
|
||||
:disabled="!isEditableApi || isQuoteScenarioStep"
|
||||
allow-clear
|
||||
class="mt-[8px]"
|
||||
/>
|
||||
|
@ -179,6 +179,7 @@
|
|||
<httpHeader
|
||||
v-if="requestVModel.activeTab === RequestComposition.HEADER"
|
||||
v-model:params="requestVModel.headers"
|
||||
:disabled-param-value="isQuoteScenarioStep"
|
||||
:disabled-except-param="!isEditableApi"
|
||||
:layout="activeLayout"
|
||||
:second-box-height="secondBoxHeight"
|
||||
|
@ -188,6 +189,7 @@
|
|||
v-else-if="requestVModel.activeTab === RequestComposition.BODY"
|
||||
v-model:params="requestVModel.body"
|
||||
:layout="activeLayout"
|
||||
:disabled-param-value="isQuoteScenarioStep"
|
||||
:disabled-except-param="!isEditableApi"
|
||||
:second-box-height="secondBoxHeight"
|
||||
:upload-temp-file-api="uploadTempFile"
|
||||
|
@ -200,6 +202,7 @@
|
|||
v-else-if="requestVModel.activeTab === RequestComposition.QUERY"
|
||||
v-model:params="requestVModel.query"
|
||||
:layout="activeLayout"
|
||||
:disabled-param-value="isQuoteScenarioStep"
|
||||
:disabled-except-param="!isEditableApi"
|
||||
:second-box-height="secondBoxHeight"
|
||||
@change="handleActiveDebugChange"
|
||||
|
@ -208,6 +211,7 @@
|
|||
v-else-if="requestVModel.activeTab === RequestComposition.REST"
|
||||
v-model:params="requestVModel.rest"
|
||||
:layout="activeLayout"
|
||||
:disabled-param-value="isQuoteScenarioStep"
|
||||
:disabled-except-param="!isEditableApi"
|
||||
:second-box-height="secondBoxHeight"
|
||||
@change="handleActiveDebugChange"
|
||||
|
@ -216,7 +220,7 @@
|
|||
v-else-if="requestVModel.activeTab === RequestComposition.PRECONDITION"
|
||||
v-model:config="requestVModel.children[0].preProcessorConfig"
|
||||
is-definition
|
||||
:disabled="!isEditableApi"
|
||||
:disabled="!isEditableApi || isQuoteScenarioStep"
|
||||
@change="handleActiveDebugChange"
|
||||
/>
|
||||
<postcondition
|
||||
|
@ -224,7 +228,7 @@
|
|||
v-model:config="requestVModel.children[0].postProcessorConfig"
|
||||
:response="props.stepResponses?.[requestVModel.stepId]?.responseResult.body"
|
||||
:layout="activeLayout"
|
||||
:disabled="!isEditableApi"
|
||||
:disabled="!isEditableApi || isQuoteScenarioStep"
|
||||
:second-box-height="secondBoxHeight"
|
||||
is-definition
|
||||
@change="handleActiveDebugChange"
|
||||
|
@ -234,19 +238,19 @@
|
|||
v-model:params="requestVModel.children[0].assertionConfig.assertions"
|
||||
:response="props.stepResponses?.[requestVModel.stepId]?.responseResult.body"
|
||||
is-definition
|
||||
:disabled="!isEditableApi"
|
||||
:disabled="!isEditableApi || isQuoteScenarioStep"
|
||||
:assertion-config="requestVModel.children[0].assertionConfig"
|
||||
/>
|
||||
<auth
|
||||
v-else-if="requestVModel.activeTab === RequestComposition.AUTH"
|
||||
v-model:params="requestVModel.authConfig"
|
||||
:disabled="!isEditableApi"
|
||||
:disabled="!isEditableApi || isQuoteScenarioStep"
|
||||
@change="handleActiveDebugChange"
|
||||
/>
|
||||
<setting
|
||||
v-else-if="requestVModel.activeTab === RequestComposition.SETTING"
|
||||
v-model:params="requestVModel.otherConfig"
|
||||
:disabled="!isEditableApi"
|
||||
:disabled="!isEditableApi || isQuoteScenarioStep"
|
||||
@change="handleActiveDebugChange"
|
||||
/>
|
||||
</div>
|
||||
|
@ -501,6 +505,8 @@
|
|||
() => _stepType.value.isCopyApi || props.step?.stepType === ScenarioStepType.CUSTOM_REQUEST || !props.step
|
||||
);
|
||||
const isHttpProtocol = computed(() => requestVModel.value.protocol === 'HTTP');
|
||||
const isQuoteScenarioStep = computed(() => props.step?.isQuoteScenarioStep);
|
||||
|
||||
const isInitPluginForm = ref(false);
|
||||
|
||||
function handleActiveDebugChange() {
|
||||
|
@ -945,6 +951,7 @@
|
|||
protocol: requestVModel.value.protocol,
|
||||
method: isHttpProtocol.value ? requestVModel.value.method : requestVModel.value.protocol,
|
||||
name: requestVModel.value.name,
|
||||
unSaved: requestVModel.value.unSaved,
|
||||
customizeRequest: props.step?.stepType === ScenarioStepType.CUSTOM_REQUEST || !props.request,
|
||||
customizeRequestEnvEnable: requestVModel.value.customizeRequestEnvEnable,
|
||||
children: [
|
||||
|
@ -1031,7 +1038,8 @@
|
|||
responseActiveTab: ResponseComposition.BODY,
|
||||
...parseRequestBodyResult,
|
||||
};
|
||||
if (_stepType.value.isQuoteApi && props.request && isHttpProtocol.value) {
|
||||
if (_stepType.value.isQuoteApi && props.request && isHttpProtocol.value && !props.step?.isQuoteScenarioStep) {
|
||||
// 是引用 api、并且传入了请求参数、且不是插件、且不是引用场景下的步骤
|
||||
// 初始化引用的详情后,需要要把外面传入的数据的请求头、请求体、query、rest里面的参数值写入
|
||||
['headers', 'query', 'rest'].forEach((type) => {
|
||||
props.request?.[type]?.forEach((item) => {
|
||||
|
|
|
@ -260,11 +260,9 @@
|
|||
return {
|
||||
...node,
|
||||
copyFromStepId: node.id,
|
||||
config: {
|
||||
...node.config,
|
||||
isRefScenarioStep: true, // 默认是完全引用的
|
||||
},
|
||||
id: getGenerateId(),
|
||||
isQuoteScenarioStep: true,
|
||||
isRefScenarioStep: true, // 默认是完全引用的
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -69,12 +69,13 @@ export const defaultStepItemCommon = {
|
|||
id: '',
|
||||
name: '',
|
||||
enable: true,
|
||||
isRefScenarioStep: false,
|
||||
},
|
||||
createActionsVisible: false,
|
||||
responsePopoverVisible: false,
|
||||
isExecuting: false,
|
||||
executeStatus: undefined,
|
||||
isRefScenarioStep: false,
|
||||
isQuoteScenarioStep: false,
|
||||
};
|
||||
|
||||
export const defaultScenario: Scenario = {
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<template>
|
||||
<div class="condition">
|
||||
<div>
|
||||
<precondition v-model:config="preProcessorConfig" :is-definition="false" />
|
||||
<precondition v-model:config="preProcessorConfig" :is-definition="false" @change="emit('change')" />
|
||||
</div>
|
||||
<a-divider class="my-[8px]" type="dashed" />
|
||||
<div>
|
||||
<postcondition v-model:config="postProcessorConfig" :is-definition="false" :layout="activeLayout" />
|
||||
<postcondition
|
||||
v-model:config="postProcessorConfig"
|
||||
:is-definition="false"
|
||||
:layout="activeLayout"
|
||||
@change="emit('change')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -16,6 +21,10 @@
|
|||
|
||||
import { ExecuteConditionConfig } from '@/models/apiTest/common';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'change');
|
||||
}>();
|
||||
|
||||
const activeLayout = ref<'horizontal' | 'vertical'>('vertical');
|
||||
const preProcessorConfig = defineModel<ExecuteConditionConfig>('preProcessorConfig', {
|
||||
required: true,
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
</a-tooltip>
|
||||
</div>
|
||||
<div class="mb-[16px] mt-[10px] flex items-center gap-[8px]">
|
||||
<a-switch v-model:model-value="form.enableGlobalCookie" type="line" size="small" />
|
||||
<a-switch v-model:model-value="form.enableGlobalCookie" type="line" size="small" @change="emit('change')" />
|
||||
{{ t('apiScenario.setting.environment.cookie') }}
|
||||
</div>
|
||||
<div class="mb-[16px] flex items-center gap-[8px]">
|
||||
<a-switch v-model:model-value="form.enableCookieShare" type="line" size="small" />
|
||||
<a-switch v-model:model-value="form.enableCookieShare" type="line" size="small" @change="emit('change')" />
|
||||
{{ t('apiScenario.setting.share.cookie') }}
|
||||
<a-tooltip :content="t('apiScenario.setting.share.cookie.tip')" position="right">
|
||||
<div>
|
||||
|
@ -31,7 +31,7 @@
|
|||
{{ t('apiScenario.setting.run.config') }}
|
||||
</div>
|
||||
<div class="mb-[16px] mt-[10px] flex items-center gap-[8px]">
|
||||
<a-switch v-model:model-value="form.enableStepWait" type="line" size="small" />
|
||||
<a-switch v-model:model-value="form.enableStepWait" type="line" size="small" @change="emit('change')" />
|
||||
{{ t('apiScenario.setting.step.waitTime') }}
|
||||
<a-tooltip :content="t('apiScenario.setting.waitTime.tip')">
|
||||
<div>
|
||||
|
@ -50,7 +50,14 @@
|
|||
<div class="text-[var(--color-text-brand)]">(ms)</div>
|
||||
</div>
|
||||
</template>
|
||||
<a-input-number v-model:model-value="form.stepWaitTime" mode="button" :step="100" :min="0" class="w-[160px]" />
|
||||
<a-input-number
|
||||
v-model:model-value="form.stepWaitTime"
|
||||
mode="button"
|
||||
:step="100"
|
||||
:min="0"
|
||||
class="w-[160px]"
|
||||
@change="emit('change')"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item class="flex-1">
|
||||
|
@ -59,7 +66,7 @@
|
|||
{{ t('apiScenario.setting.step.rule') }}
|
||||
</div>
|
||||
</template>
|
||||
<a-radio-group v-model:model-value="form.failureStrategy">
|
||||
<a-radio-group v-model:model-value="form.failureStrategy" @change="emit('change')">
|
||||
<a-radio :value="ScenarioFailureStrategy.CONTINUE">{{ t('apiScenario.setting.step.rule.ignore') }}</a-radio>
|
||||
<a-radio :value="ScenarioFailureStrategy.STOP">{{ t('apiScenario.setting.step.rule.stop') }}</a-radio>
|
||||
</a-radio-group>
|
||||
|
@ -73,6 +80,10 @@
|
|||
import { OtherConfig } from '@/models/apiTest/scenario';
|
||||
import { ScenarioFailureStrategy } from '@/enums/apiEnum';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'change'): void;
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const form = defineModel<OtherConfig>('otherConfig', {
|
||||
|
|
|
@ -54,11 +54,7 @@
|
|||
import { ScenarioAddStepActionType, ScenarioStepRefType, ScenarioStepType } from '@/enums/apiEnum';
|
||||
|
||||
import useCreateActions from './useCreateActions';
|
||||
import {
|
||||
defaultConditionController,
|
||||
defaultLoopController,
|
||||
defaultStepItemCommon,
|
||||
} from '@/views/api-test/scenario/components/config';
|
||||
import { defaultStepItemCommon } from '@/views/api-test/scenario/components/config';
|
||||
import { DropdownPosition } from '@arco-design/web-vue/es/dropdown/interface';
|
||||
|
||||
const props = defineProps<{
|
||||
|
@ -76,6 +72,7 @@
|
|||
| ScenarioAddStepActionType.SCRIPT_OPERATION,
|
||||
step?: ScenarioStepItem
|
||||
);
|
||||
(e: 'addDone');
|
||||
}>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
@ -126,6 +123,7 @@
|
|||
)[0]
|
||||
);
|
||||
}
|
||||
emit('addDone');
|
||||
break;
|
||||
case ScenarioAddStepActionType.CONDITION_CONTROL:
|
||||
if (step.value && props.createStepAction) {
|
||||
|
@ -151,6 +149,7 @@
|
|||
)[0]
|
||||
);
|
||||
}
|
||||
emit('addDone');
|
||||
break;
|
||||
case ScenarioAddStepActionType.ONLY_ONCE_CONTROL:
|
||||
if (step.value && props.createStepAction) {
|
||||
|
@ -176,6 +175,7 @@
|
|||
)[0]
|
||||
);
|
||||
}
|
||||
emit('addDone');
|
||||
break;
|
||||
case ScenarioAddStepActionType.WAIT_TIME:
|
||||
if (step.value && props.createStepAction) {
|
||||
|
@ -201,6 +201,7 @@
|
|||
)[0]
|
||||
);
|
||||
}
|
||||
emit('addDone');
|
||||
break;
|
||||
case ScenarioAddStepActionType.IMPORT_SYSTEM_API:
|
||||
case ScenarioAddStepActionType.CUSTOM_API:
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
:popup-translate="[-7, -10]"
|
||||
@other-create="(type, step) => emit('otherCreate', type, step, activeCreateAction)"
|
||||
@close="handleActionsClose"
|
||||
@add-done="emit('addDone')"
|
||||
>
|
||||
<span></span>
|
||||
</createStepActions>
|
||||
|
@ -85,6 +86,7 @@
|
|||
step?: ScenarioStepItem,
|
||||
activeCreateAction?: CreateStepAction
|
||||
);
|
||||
(e: 'addDone');
|
||||
}>();
|
||||
|
||||
const { t } = useI18n();
|
||||
|
|
|
@ -135,8 +135,9 @@ export default function useCreateActions() {
|
|||
config: {
|
||||
...defaultStepItemCommon.config,
|
||||
...config,
|
||||
isRefScenarioStep: item.config?.isRefScenarioStep || false,
|
||||
},
|
||||
isQuoteScenarioStep: item.config?.isQuoteScenarioStep || false,
|
||||
isRefScenarioStep: item.config?.isRefScenarioStep || false,
|
||||
children: item.children || [],
|
||||
stepType,
|
||||
refType,
|
||||
|
|
|
@ -229,7 +229,7 @@
|
|||
});
|
||||
} else {
|
||||
scenario.value.steps = mapTree(scenario.value.steps, (node) => {
|
||||
if (ids.has(node.id) && node.config.isRefScenarioStep !== true) {
|
||||
if (ids.has(node.id) && node.isRefScenarioStep !== true) {
|
||||
// 如果是完全引用的场景下的子孙步骤,则不允许操作启用禁用
|
||||
node.enable = isBatchEnable.value;
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
<div class="mr-[8px] flex items-center gap-[8px]">
|
||||
<!-- 步骤启用/禁用,完全引用的场景下的子孙步骤不可禁用 -->
|
||||
<a-switch
|
||||
v-show="step.config.isRefScenarioStep !== true"
|
||||
v-show="step.isRefScenarioStep !== true"
|
||||
v-model:model-value="step.enable"
|
||||
size="small"
|
||||
@click.stop="handleStepToggleEnable(step)"
|
||||
|
@ -174,6 +174,7 @@
|
|||
@click="setFocusNodeKey(step.id)"
|
||||
@other-create="handleOtherCreate"
|
||||
@close="setFocusNodeKey('')"
|
||||
@add-done="scenario.unSaved = true"
|
||||
/>
|
||||
</template>
|
||||
<template #extraEnd="step">
|
||||
|
@ -224,7 +225,12 @@
|
|||
</template>
|
||||
</MsTree>
|
||||
</a-spin>
|
||||
<createStepActions v-model:selected-keys="selectedKeys" v-model:steps="steps" @other-create="handleOtherCreate">
|
||||
<createStepActions
|
||||
v-model:selected-keys="selectedKeys"
|
||||
v-model:steps="steps"
|
||||
@add-done="scenario.unSaved = true"
|
||||
@other-create="handleOtherCreate"
|
||||
>
|
||||
<a-button type="dashed" class="add-step-btn" long>
|
||||
<div class="flex items-center gap-[8px]">
|
||||
<icon-plus />
|
||||
|
@ -716,14 +722,15 @@
|
|||
realStep.children = mapTree<ScenarioStepItem>(realStep.children || [], (child) => {
|
||||
// 更新子孙步骤是否完全引用
|
||||
if (scenarioConfigForm.value.refType === ScenarioStepRefType.REF) {
|
||||
child.config.isRefScenarioStep = true;
|
||||
child.isRefScenarioStep = true;
|
||||
child.enable = true;
|
||||
} else {
|
||||
child.config.isRefScenarioStep = false;
|
||||
child.isRefScenarioStep = false;
|
||||
}
|
||||
return child;
|
||||
});
|
||||
Message.success(t('apiScenario.setSuccess'));
|
||||
scenario.value.unSaved = true;
|
||||
cancelScenarioConfig();
|
||||
}
|
||||
}
|
||||
|
@ -765,6 +772,7 @@
|
|||
}
|
||||
return {
|
||||
...cloneDeep(childNode),
|
||||
executeStatus: undefined,
|
||||
copyFromStepId: childCopyFromStepId,
|
||||
id: childId,
|
||||
};
|
||||
|
@ -780,6 +788,7 @@
|
|||
checkedIfNeed,
|
||||
'id'
|
||||
);
|
||||
scenario.value.unSaved = true;
|
||||
break;
|
||||
case 'config':
|
||||
activeStep.value = node as ScenarioStepItem;
|
||||
|
@ -791,6 +800,7 @@
|
|||
break;
|
||||
case 'delete':
|
||||
deleteNode(steps.value, node.id, 'id');
|
||||
scenario.value.unSaved = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -802,7 +812,7 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* 处理步骤名称编辑
|
||||
* 处理api、case、场景步骤名称编辑
|
||||
*/
|
||||
const showStepNameEditInputStepId = ref<string | number>('');
|
||||
const tempStepName = ref('');
|
||||
|
@ -822,10 +832,11 @@
|
|||
realStep.name = tempStepName.value;
|
||||
}
|
||||
showStepNameEditInputStepId.value = '';
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理步骤名称编辑
|
||||
* 处理非 api、case、场景步骤名称编辑
|
||||
*/
|
||||
const showStepDescEditInputStepId = ref<string | number>('');
|
||||
const tempStepDesc = ref('');
|
||||
|
@ -845,6 +856,7 @@
|
|||
realStep.name = tempStepDesc.value;
|
||||
}
|
||||
showStepDescEditInputStepId.value = '';
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
|
||||
function handleStepContentChange($event, step: ScenarioStepItem) {
|
||||
|
@ -853,6 +865,7 @@
|
|||
Object.keys($event).forEach((key) => {
|
||||
realStep.config[key] = $event[key];
|
||||
});
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -870,6 +883,7 @@
|
|||
const realStep = findNodeByKey<ScenarioStepItem>(steps.value, data.id, 'id');
|
||||
if (realStep) {
|
||||
realStep.enable = !realStep.enable;
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1218,6 +1232,7 @@
|
|||
} else {
|
||||
steps.value = steps.value.concat(insertSteps);
|
||||
}
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1260,12 +1275,16 @@
|
|||
projectId: appStore.currentProjectId,
|
||||
});
|
||||
}
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* API 详情抽屉关闭时应用更改
|
||||
*/
|
||||
function applyApiStep(request: RequestParam | CaseRequestParam) {
|
||||
if (request.unSaved) {
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
if (activeStep.value) {
|
||||
request.isNew = false;
|
||||
stepDetails.value[activeStep.value?.id] = request;
|
||||
|
@ -1282,6 +1301,7 @@
|
|||
customCaseDrawerVisible.value = false;
|
||||
deleteNode(steps.value, step.id, 'id');
|
||||
activeStep.value = undefined;
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1314,6 +1334,7 @@
|
|||
projectId: appStore.currentProjectId,
|
||||
});
|
||||
}
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1383,6 +1404,7 @@
|
|||
const dragResult = handleTreeDragDrop(steps.value, dragNode, dropNode, dropPosition, 'id');
|
||||
if (dragResult) {
|
||||
Message.success(t('common.moveSuccess'));
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
|
@ -1432,6 +1454,7 @@
|
|||
}
|
||||
showQuickInput.value = false;
|
||||
clearQuickInput();
|
||||
scenario.value.unSaved = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
<params
|
||||
v-if="activeKey === ScenarioDetailComposition.PARAMS"
|
||||
v-model:params="scenario.scenarioConfig.variable.commonVariables"
|
||||
@change="scenario.unSaved = true"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane
|
||||
|
@ -64,6 +65,7 @@
|
|||
v-if="activeKey === ScenarioDetailComposition.PRE_POST"
|
||||
v-model:post-processor-config="scenario.scenarioConfig.postProcessorConfig"
|
||||
v-model:pre-processor-config="scenario.scenarioConfig.preProcessorConfig"
|
||||
@change="scenario.unSaved = true"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane
|
||||
|
@ -74,6 +76,7 @@
|
|||
<assertion
|
||||
v-if="activeKey === ScenarioDetailComposition.ASSERTION"
|
||||
v-model:assertion-config="scenario.scenarioConfig.assertionConfig"
|
||||
@change="scenario.unSaved = true"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane
|
||||
|
@ -108,6 +111,7 @@
|
|||
<setting
|
||||
v-if="activeKey === ScenarioDetailComposition.SETTING"
|
||||
v-model:other-config="scenario.scenarioConfig.otherConfig"
|
||||
@change="scenario.unSaved = true"
|
||||
/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
|
|
@ -129,7 +129,7 @@
|
|||
} from '@/models/apiTest/scenario';
|
||||
import { ModuleTreeNode } from '@/models/common';
|
||||
import { EnvConfig } from '@/models/projectManagement/environmental';
|
||||
import { ScenarioExecuteStatus, ScenarioStepType } from '@/enums/apiEnum';
|
||||
import { ScenarioExecuteStatus, ScenarioStepRefType, ScenarioStepType } from '@/enums/apiEnum';
|
||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||
|
||||
import { defaultScenario } from './components/config';
|
||||
|
@ -371,7 +371,22 @@
|
|||
};
|
||||
});
|
||||
} else {
|
||||
copySteps = mapTree(defaultScenarioInfo.steps);
|
||||
copySteps = mapTree(defaultScenarioInfo.steps, (node) => {
|
||||
if (
|
||||
node.parent &&
|
||||
node.parent.stepType === ScenarioStepType.API_SCENARIO &&
|
||||
[ScenarioStepRefType.REF, ScenarioStepRefType.PARTIAL_REF].includes(node.parent.refType)
|
||||
) {
|
||||
// 如果父节点是引用场景
|
||||
node.isQuoteScenarioStep = true; // 标记为引用场景下的子步骤
|
||||
node.isRefScenarioStep = node.parent.refType === ScenarioStepRefType.REF; // 标记为引用场景下的子步骤
|
||||
} else if (node.parent) {
|
||||
// 如果有父节点
|
||||
node.isQuoteScenarioStep = node.parent.isQuoteScenarioStep; // 复用父节点的引用场景标记
|
||||
node.isRefScenarioStep = node.parent.isRefScenarioStep; // 复用父节点的是否完全引用场景标记
|
||||
}
|
||||
return node;
|
||||
});
|
||||
}
|
||||
scenarioTabs.value.push({
|
||||
...defaultScenarioInfo,
|
||||
|
|
Loading…
Reference in New Issue