fix(接口测试): 场景步骤的 schema 执行报错修复
This commit is contained in:
parent
3db5da7499
commit
d516ffa1f1
|
@ -8,11 +8,16 @@ import useAppStore from '@/store/modules/app';
|
||||||
import { findNodeByKey, getGenerateId, mapTree, traverseTree } from '@/utils';
|
import { findNodeByKey, getGenerateId, mapTree, traverseTree } from '@/utils';
|
||||||
|
|
||||||
import type { RequestResult } from '@/models/apiTest/common';
|
import type { RequestResult } from '@/models/apiTest/common';
|
||||||
import type { ApiScenarioDebugRequest, Scenario, ScenarioStepItem } from '@/models/apiTest/scenario';
|
import type {
|
||||||
|
ApiScenarioDebugRequest,
|
||||||
|
Scenario,
|
||||||
|
ScenarioStepDetails,
|
||||||
|
ScenarioStepItem,
|
||||||
|
} from '@/models/apiTest/scenario';
|
||||||
import { ScenarioExecuteStatus, ScenarioStepRefType, ScenarioStepType } from '@/enums/apiEnum';
|
import { ScenarioExecuteStatus, ScenarioStepRefType, ScenarioStepType } from '@/enums/apiEnum';
|
||||||
|
|
||||||
import type { RequestParam } from '../common/customApiDrawer.vue';
|
import type { RequestParam } from '../common/customApiDrawer.vue';
|
||||||
import updateStepStatus, { getScenarioFileParams } from '../utils';
|
import updateStepStatus, { getScenarioFileParams, getStepDetails } from '../utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 步骤执行逻辑
|
* 步骤执行逻辑
|
||||||
|
@ -27,7 +32,7 @@ export default function useStepExecute({
|
||||||
}: {
|
}: {
|
||||||
scenario: Ref<Scenario>;
|
scenario: Ref<Scenario>;
|
||||||
steps: Ref<ScenarioStepItem[]>;
|
steps: Ref<ScenarioStepItem[]>;
|
||||||
stepDetails: Ref<Record<string, any>>;
|
stepDetails: Ref<Record<string, ScenarioStepDetails>>;
|
||||||
activeStep: Ref<ScenarioStepItem | undefined>;
|
activeStep: Ref<ScenarioStepItem | undefined>;
|
||||||
isPriorityLocalExec: Ref<boolean> | undefined;
|
isPriorityLocalExec: Ref<boolean> | undefined;
|
||||||
localExecuteUrl: Ref<string> | undefined;
|
localExecuteUrl: Ref<string> | undefined;
|
||||||
|
@ -89,6 +94,7 @@ export default function useStepExecute({
|
||||||
...getScenarioFileParams(scenario.value),
|
...getScenarioFileParams(scenario.value),
|
||||||
},
|
},
|
||||||
...executeParams,
|
...executeParams,
|
||||||
|
stepDetails: getStepDetails(executeParams.steps, executeParams.stepDetails),
|
||||||
steps: mapTree(executeParams.steps, (node) => {
|
steps: mapTree(executeParams.steps, (node) => {
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { RequestResult } from '@/models/apiTest/common';
|
import { RequestResult } from '@/models/apiTest/common';
|
||||||
import { type Scenario, ScenarioStepItem } from '@/models/apiTest/scenario';
|
import { type Scenario, type ScenarioStepDetails, ScenarioStepItem } from '@/models/apiTest/scenario';
|
||||||
import { ScenarioExecuteStatus, ScenarioStepType } from '@/enums/apiEnum';
|
import { ScenarioExecuteStatus, ScenarioStepType } from '@/enums/apiEnum';
|
||||||
|
|
||||||
|
import type { RequestParam } from './common/customApiDrawer.vue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调试或执行结束后,调用本方法更新步骤的执行状态
|
* 调试或执行结束后,调用本方法更新步骤的执行状态
|
||||||
* @param steps 响应式的步骤列表
|
* @param steps 响应式的步骤列表
|
||||||
|
@ -114,3 +116,34 @@ export function getScenarioFileParams(scenario: Scenario) {
|
||||||
uploadFileIds: Array.from(uploadFileIds),
|
uploadFileIds: Array.from(uploadFileIds),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取步骤详情参数集合
|
||||||
|
* @param details 传入指定的详情映射
|
||||||
|
*/
|
||||||
|
export function getStepDetails(steps: ScenarioStepItem[], details: Record<string, ScenarioStepDetails>) {
|
||||||
|
const newStepDetails: Record<string, ScenarioStepDetails> = {};
|
||||||
|
steps.forEach((step) => {
|
||||||
|
const currentDetail = details[step.id] as RequestParam;
|
||||||
|
if (
|
||||||
|
currentDetail &&
|
||||||
|
[ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST].includes(step.stepType)
|
||||||
|
) {
|
||||||
|
// 接口类型需要处理 json-schema 的循环引用
|
||||||
|
newStepDetails[step.id] = {
|
||||||
|
...currentDetail,
|
||||||
|
body: {
|
||||||
|
...currentDetail.body,
|
||||||
|
jsonBody: {
|
||||||
|
...currentDetail.body.jsonBody,
|
||||||
|
jsonSchema: currentDetail.body.jsonBody.jsonSchema,
|
||||||
|
jsonSchemaTableData: [], // 原树形结构存在循环引用,这里要去掉以免 axios 序列化失败
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
newStepDetails[step.id] = details[step.id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return newStepDetails;
|
||||||
|
}
|
||||||
|
|
|
@ -112,7 +112,6 @@
|
||||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||||
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
|
import MsSplitBox from '@/components/pure/ms-split-box/index.vue';
|
||||||
import MsEnvironmentSelect from '@/components/business/ms-environment-select/index.vue';
|
import MsEnvironmentSelect from '@/components/business/ms-environment-select/index.vue';
|
||||||
import { RequestParam } from './components/common/customApiDrawer.vue';
|
|
||||||
import scenarioModuleTree from './components/scenarioModuleTree.vue';
|
import scenarioModuleTree from './components/scenarioModuleTree.vue';
|
||||||
import executeButton from '@/views/api-test/components/executeButton.vue';
|
import executeButton from '@/views/api-test/components/executeButton.vue';
|
||||||
import ScenarioTable from '@/views/api-test/scenario/components/scenarioTable.vue';
|
import ScenarioTable from '@/views/api-test/scenario/components/scenarioTable.vue';
|
||||||
|
@ -148,7 +147,7 @@
|
||||||
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||||
|
|
||||||
import { defaultCsvParamItem, defaultNormalParamItem, defaultScenario } from './components/config';
|
import { defaultCsvParamItem, defaultNormalParamItem, defaultScenario } from './components/config';
|
||||||
import updateStepStatus, { getScenarioFileParams } from './components/utils';
|
import updateStepStatus, { getScenarioFileParams, getStepDetails } from './components/utils';
|
||||||
import {
|
import {
|
||||||
filterAssertions,
|
filterAssertions,
|
||||||
filterConditionsSqlValidParams,
|
filterConditionsSqlValidParams,
|
||||||
|
@ -262,6 +261,7 @@
|
||||||
projectId: appStore.currentProjectId,
|
projectId: appStore.currentProjectId,
|
||||||
scenarioConfig: activeScenarioTab.value.scenarioConfig,
|
scenarioConfig: activeScenarioTab.value.scenarioConfig,
|
||||||
...executeParams,
|
...executeParams,
|
||||||
|
stepDetails: getStepDetails(executeParams.steps, executeParams.stepDetails),
|
||||||
stepFileParam: activeScenarioTab.value.stepFileParam,
|
stepFileParam: activeScenarioTab.value.stepFileParam,
|
||||||
fileParam: {
|
fileParam: {
|
||||||
...getScenarioFileParams(activeScenarioTab.value),
|
...getScenarioFileParams(activeScenarioTab.value),
|
||||||
|
@ -286,6 +286,7 @@
|
||||||
},
|
},
|
||||||
frontendDebug: executeType === 'localExec',
|
frontendDebug: executeType === 'localExec',
|
||||||
...executeParams,
|
...executeParams,
|
||||||
|
stepDetails: getStepDetails(executeParams.steps, executeParams.stepDetails),
|
||||||
steps: mapTree(executeParams.steps, (node) => {
|
steps: mapTree(executeParams.steps, (node) => {
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
|
@ -531,33 +532,6 @@
|
||||||
apiTableRef.value?.loadScenarioList();
|
apiTableRef.value?.loadScenarioList();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStepDetails() {
|
|
||||||
const stepDetails: Record<string, ScenarioStepDetails> = {};
|
|
||||||
activeScenarioTab.value.steps.forEach((step) => {
|
|
||||||
const currentDetail = activeScenarioTab.value.stepDetails[step.id] as RequestParam;
|
|
||||||
if (
|
|
||||||
currentDetail &&
|
|
||||||
[ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST].includes(step.stepType)
|
|
||||||
) {
|
|
||||||
// 接口类型需要处理 json-schema 的循环引用
|
|
||||||
stepDetails[step.id] = {
|
|
||||||
...currentDetail,
|
|
||||||
body: {
|
|
||||||
...currentDetail.body,
|
|
||||||
jsonBody: {
|
|
||||||
...currentDetail.body.jsonBody,
|
|
||||||
jsonSchema: currentDetail.body.jsonBody.jsonSchema,
|
|
||||||
jsonSchemaTableData: [], // 原树形结构存在循环引用,这里要去掉以免 axios 序列化失败
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
stepDetails[step.id] = activeScenarioTab.value.stepDetails[step.id];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return stepDetails;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function realSaveScenario() {
|
async function realSaveScenario() {
|
||||||
try {
|
try {
|
||||||
saveLoading.value = true;
|
saveLoading.value = true;
|
||||||
|
@ -565,7 +539,7 @@
|
||||||
if (activeScenarioTab.value.isNew) {
|
if (activeScenarioTab.value.isNew) {
|
||||||
const res = await addScenario({
|
const res = await addScenario({
|
||||||
...activeScenarioTab.value,
|
...activeScenarioTab.value,
|
||||||
stepDetails: getStepDetails(),
|
stepDetails: getStepDetails(activeScenarioTab.value.steps, activeScenarioTab.value.stepDetails),
|
||||||
steps: mapTree(activeScenarioTab.value.steps, (node) => {
|
steps: mapTree(activeScenarioTab.value.steps, (node) => {
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
|
@ -635,6 +609,7 @@
|
||||||
} else {
|
} else {
|
||||||
await updateScenario({
|
await updateScenario({
|
||||||
...activeScenarioTab.value,
|
...activeScenarioTab.value,
|
||||||
|
stepDetails: getStepDetails(activeScenarioTab.value.steps, activeScenarioTab.value.stepDetails),
|
||||||
scenarioConfig: {
|
scenarioConfig: {
|
||||||
...activeScenarioTab.value.scenarioConfig,
|
...activeScenarioTab.value.scenarioConfig,
|
||||||
assertionConfig: { ...assertionConfig, assertions: filterAssertions(assertionConfig) },
|
assertionConfig: { ...assertionConfig, assertions: filterAssertions(assertionConfig) },
|
||||||
|
|
Loading…
Reference in New Issue