refactor(接口场景): 场景执行状态优化&部分表格筛选状态初始化为空

This commit is contained in:
baiqi 2024-03-28 18:25:12 +08:00 committed by Craftsman
parent 7fe24a0d27
commit 9f67d9fb6b
27 changed files with 371 additions and 263 deletions

View File

@ -185,8 +185,8 @@ export function calculateMaxDepth(arr?: Node[], depth = 0) {
}
export interface TreeNode<T> {
[key: string]: any;
children?: TreeNode<T>[];
[key: string]: any;
}
/**

View File

@ -504,9 +504,9 @@
];
const methodFilterVisible = ref(false);
const methodFilters = ref(Object.keys(RequestMethods));
const methodFilters = ref<string[]>([]);
const statusFilterVisible = ref(false);
const statusFilters = ref(Object.keys(RequestDefinitionStatus));
const statusFilters = ref<string[]>([]);
const tableStore = useTableStore();
async function getModuleIds() {
@ -529,9 +529,8 @@
moduleIds,
protocol: props.protocol,
filter: {
status:
statusFilters.value.length === Object.keys(RequestDefinitionStatus).length ? undefined : statusFilters.value,
method: methodFilters.value.length === Object.keys(RequestMethods).length ? undefined : methodFilters.value,
status: statusFilters.value,
method: methodFilters.value,
},
};
setLoadListParams(params);

View File

@ -560,7 +560,7 @@
];
const statusFilterVisible = ref(false);
const statusFilters = ref(Object.keys(RequestDefinitionStatus));
const statusFilters = ref<string[]>([]);
const caseLevelFields = ref<Record<string, any>>({});
const caseFilterVisible = ref(false);
const caseFilters = ref<string[]>([]);
@ -571,7 +571,7 @@
const lastReportStatusList = computed(() => {
return Object.keys(ReportStatus[ReportEnum.API_REPORT]);
});
const lastReportStatusFilters = ref<string[]>(Object.keys(ReportStatus[ReportEnum.API_REPORT]));
const lastReportStatusFilters = ref<string[]>([]);
async function getModuleIds() {
let moduleIds: string[] = [];

View File

@ -118,10 +118,10 @@
import { ApiCaseExecuteHistoryItem } from '@/models/apiTest/management';
import { ReportEnum, ReportStatus, TriggerModeLabel } from '@/enums/reportEnum';
const triggerModeListFilters = ref<string[]>(Object.keys(TriggerModeLabel));
const triggerModeListFilters = ref<string[]>();
const triggerModeFilterVisible = ref(false);
const statusFilterVisible = ref(false);
const statusFilters = ref<string[]>(Object.keys(ReportStatus[ReportEnum.API_REPORT]));
const statusFilters = ref<string[]>();
const statusList = computed(() => {
return Object.keys(ReportStatus[ReportEnum.API_REPORT]);
});

View File

@ -256,9 +256,9 @@
};
const methodFilterVisible = ref(false);
const methodFilters = ref(Object.keys(RequestMethods));
const methodFilters = ref<string[]>([]);
const statusFilterVisible = ref(false);
const statusFilters = ref(Object.keys(RequestDefinitionStatus));
const statusFilters = ref<string[]>([]);
const moduleIds = computed(() => {
if (props.activeModule === 'all') {
return [];

View File

@ -366,7 +366,7 @@
};
const statusFilterVisible = ref(false);
const statusFilters = ref(Object.keys(RequestDefinitionStatus));
const statusFilters = ref<string[]>([]);
const caseLevelFields = ref<Record<string, any>>({});
const caseFilterVisible = ref(false);
const caseFilters = ref<string[]>([]);
@ -375,7 +375,7 @@
});
const lastReportStatusFilterVisible = ref(false);
const lastReportStatusList = ['error', 'FakeError', 'success'];
const lastReportStatusFilters = ref<string[]>([...lastReportStatusList]);
const lastReportStatusFilters = ref<string[]>([]);
const moduleIds = computed(() => {
return props.activeModule === 'all' ? [] : [props.activeModule];

View File

@ -174,8 +174,8 @@
const statusFilterVisible = ref(false);
const triggerModeFilterVisible = ref(false);
const statusListFilters = ref<string[]>(Object.keys(ReportStatus[props.moduleType]));
const triggerModeListFilters = ref<string[]>(Object.keys(TriggerModeLabel));
const statusListFilters = ref<string[]>([]);
const triggerModeListFilters = ref<string[]>([]);
type ReportShowType = 'All' | 'INDEPENDENT' | 'INTEGRATED';
const showType = ref<ReportShowType>('All');
@ -287,7 +287,7 @@
moduleType: props.moduleType,
filter: {
status: statusListFilters.value,
integrated: showType.value === 'All' ? undefined : Array.of((showType.value === 'INTEGRATED').toString()),
integrated: Array.of((showType.value === 'INTEGRATED').toString()),
triggerMode: triggerModeListFilters.value,
},
});

View File

@ -10,13 +10,13 @@
@close="handleClose"
>
<template #title>
<div class="flex items-center gap-[8px]">
<stepTypeVue
v-if="props.step"
v-show="props.step.stepType !== ScenarioStepType.CUSTOM_REQUEST"
:step="props.step"
/>
{{ title }}
<div class="flex max-w-[60%] items-center gap-[8px]">
<stepTypeVue v-if="props.step" :step="props.step" />
<a-tooltip :content="title" position="bottom">
<div class="one-line-text">
{{ title }}
</div>
</a-tooltip>
</div>
<div
v-if="!props.step || props.step?.stepType === ScenarioStepType.CUSTOM_REQUEST"
@ -475,7 +475,7 @@
if (_stepType.value.isCopyApi || _stepType.value.isQuoteApi) {
return props.step?.name;
}
return t('apiScenario.customApi');
return props.step?.name || t('apiScenario.customApi');
});
const showEnvPrefix = computed(
() =>

View File

@ -24,7 +24,7 @@
<div v-show="!isShowEditStepNameInput" class="flex flex-1 items-center justify-between">
<div class="flex items-center gap-[8px]">
<a-tooltip :content="activeStep?.name">
<span> {{ characterLimit(activeStep?.name) }}</span>
<div class="one-line-text max-w-[300px]"> {{ characterLimit(activeStep?.name) }}</div>
</a-tooltip>
<MsIcon type="icon-icon_edit_outlined" class="edit-script-name-icon" @click="showEditScriptNameInput" />
</div>

View File

@ -38,8 +38,8 @@
text: 'common.success',
},
[ScenarioExecuteStatus.UN_EXECUTE]: {
bgColor: 'var(--color-text-4)',
color: 'var(--color-text-n9)',
bgColor: 'var(--color-text-n8)',
color: 'var(--color-text-1)',
text: 'apiScenario.unExecute',
},
};

View File

@ -259,9 +259,9 @@
});
const methodFilterVisible = ref(false);
const methodFilters = ref(Object.keys(RequestMethods));
const methodFilters = ref<string[]>([]);
const statusFilterVisible = ref(false);
const statusFilters = ref(Object.keys(RequestDefinitionStatus));
const statusFilters = ref<string[]>([]);
const tableSelectedData = ref<MsTableDataItem<ApiCaseDetail | ApiDefinitionDetail | ApiScenarioTableItem>[]>([]);
const tableSelectedKeys = computed(() => {
return tableSelectedData.value.map((e) => e.id);
@ -332,11 +332,8 @@
moduleIds: ids || props.moduleIds,
protocol: props.protocol,
filter: {
status:
statusFilters.value.length === Object.keys(RequestDefinitionStatus).length
? undefined
: statusFilters.value,
method: methodFilters.value.length === Object.keys(RequestMethods).length ? undefined : methodFilters.value,
status: statusFilters.value,
method: methodFilters.value,
},
});
currentTable.value.loadList();
@ -377,8 +374,8 @@
function resetTable() {
currentTable.value.resetSelector();
keyword.value = '';
methodFilters.value = Object.keys(RequestMethods);
statusFilters.value = Object.keys(RequestDefinitionStatus);
methodFilters.value = [];
statusFilters.value = [];
loadPage();
}

View File

@ -101,10 +101,10 @@
import { ExecuteStatusFilters } from '@/enums/apiEnum';
import { TriggerModeLabel } from '@/enums/reportEnum';
const triggerModeListFilters = ref<string[]>(Object.keys(TriggerModeLabel));
const triggerModeListFilters = ref<string[]>([]);
const triggerModeFilterVisible = ref(false);
const statusFilterVisible = ref(false);
const statusFilters = ref(Object.keys(ExecuteStatusFilters));
const statusFilters = ref<string[]>([]);
const tableQueryParams = ref<any>();
const keyword = ref('');

View File

@ -368,7 +368,7 @@
}>();
const lastReportStatusFilterVisible = ref(false);
const lastReportStatusListFilters = ref<string[]>(Object.keys(ReportStatus[ReportEnum.API_SCENARIO_REPORT]));
const lastReportStatusListFilters = ref<string[]>([]);
const lastReportStatusFilters = computed(() => {
return Object.keys(ReportStatus[ReportEnum.API_SCENARIO_REPORT]);
});
@ -586,7 +586,7 @@
];
const statusFilterVisible = ref(false);
const statusFilters = ref(Object.keys(ApiScenarioStatus));
const statusFilters = ref<string[]>([]);
const tableStore = useTableStore();
const activeModules = computed(() => {
@ -621,7 +621,7 @@
moduleIds,
filter: {
lastReportStatus: lastReportStatusListFilters.value,
status: statusFilters.value.length === Object.keys(ApiScenarioStatus).length ? undefined : statusFilters.value,
status: statusFilters.value,
},
};
setLoadListParams(params);

View File

@ -168,18 +168,30 @@
stepTreeRef.value?.checkAll(checkedAll.value);
}
watch(checkedKeys, (val) => {
if (val.length === 0) {
checkedAll.value = false;
indeterminate.value = false;
} else if (val.length === totalStepCount.value) {
checkedAll.value = true;
indeterminate.value = false;
} else {
checkedAll.value = false;
indeterminate.value = true;
watch(
() => checkedKeys.value,
(val) => {
if (val.length === 0) {
checkedAll.value = false;
indeterminate.value = false;
} else if (val.length === totalStepCount.value) {
checkedAll.value = true;
indeterminate.value = false;
} else {
checkedAll.value = false;
indeterminate.value = true;
}
}
});
);
watch(
() => scenario.value.steps.length,
() => {
checkedKeys.value = [];
checkedAll.value = false;
indeterminate.value = false;
}
);
function expandAllStep() {
isExpandAll.value = !isExpandAll.value;
@ -259,14 +271,19 @@
if (!node.enable) {
// id便waitingDebugStepDetails
checkedKeysSet.delete(node.id);
node.executeStatus = undefined;
} else if (
[ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST].includes(node.stepType)
) {
//
node.executeStatus = ScenarioExecuteStatus.EXECUTING;
} else {
//
node.executeStatus = undefined;
}
return !!node.enable;
}
node.executeStatus = undefined; //
return false;
});
const waitingDebugStepDetails = {};

View File

@ -179,8 +179,14 @@
<template #extraEnd="step">
<a-popover
v-if="
getExecuteStatus(step) === ScenarioExecuteStatus.SUCCESS ||
getExecuteStatus(step) === ScenarioExecuteStatus.FAILED
![
ScenarioStepType.LOOP_CONTROLLER,
ScenarioStepType.IF_CONTROLLER,
ScenarioStepType.ONCE_ONLY_CONTROLLER,
ScenarioStepType.CONSTANT_TIMER,
].includes(step.stepType) &&
(getExecuteStatus(step) === ScenarioExecuteStatus.SUCCESS ||
getExecuteStatus(step) === ScenarioExecuteStatus.FAILED)
"
position="br"
content-class="scenario-step-response-popover"

View File

@ -0,0 +1,66 @@
import { RequestResult } from '@/models/apiTest/common';
import { ScenarioStepItem } from '@/models/apiTest/scenario';
import { ScenarioExecuteStatus, ScenarioStepType } from '@/enums/apiEnum';
/**
*
* @param steps
*/
export default function updateStepStatus(
steps: ScenarioStepItem[],
stepResponses: Record<string | number, RequestResult>
) {
for (let i = 0; i < steps.length; i++) {
const node = steps[i];
if (
[
ScenarioStepType.LOOP_CONTROLLER,
ScenarioStepType.IF_CONTROLLER,
ScenarioStepType.ONCE_ONLY_CONTROLLER,
].includes(node.stepType)
) {
// 逻辑控制器内部可以放入任意步骤,所以它的最终执行结果是根据内部步骤的执行结果来判断的
let hasNotExecuted = false;
let hasFailure = false;
if (!node.children || node.children.length === 0) {
// 逻辑控制器内无步骤,则直接是未执行
node.executeStatus = ScenarioExecuteStatus.UN_EXECUTE;
} else {
for (let j = 0; j < node.children.length; j++) {
const childNode = node.children[j];
updateStepStatus([childNode], stepResponses);
if (
childNode.executeStatus &&
[ScenarioExecuteStatus.EXECUTING, ScenarioExecuteStatus.UN_EXECUTE].includes(childNode.executeStatus)
) {
// 子节点未执行或正在执行,则逻辑控制器也是未执行
hasNotExecuted = true;
} else if (childNode.executeStatus === ScenarioExecuteStatus.FAILED) {
// 子节点有一个失败,逻辑控制器就是失败
hasFailure = true;
}
}
// 递归完子节点后,判断当前逻辑控制器的状态
if (hasFailure) {
node.executeStatus = ScenarioExecuteStatus.FAILED;
} else if (hasNotExecuted) {
node.executeStatus = ScenarioExecuteStatus.UN_EXECUTE;
} else {
node.executeStatus = ScenarioExecuteStatus.SUCCESS;
}
}
} else if (node.stepType === ScenarioStepType.CONSTANT_TIMER) {
// 等待时间直接设置为成功
node.executeStatus = ScenarioExecuteStatus.SUCCESS;
} else if (node.executeStatus === ScenarioExecuteStatus.EXECUTING) {
// 非逻辑控制器直接更改本身状态
if (stepResponses[node.id]) {
node.executeStatus = stepResponses[node.id].isSuccessful
? ScenarioExecuteStatus.SUCCESS
: ScenarioExecuteStatus.FAILED;
} else {
node.executeStatus = ScenarioExecuteStatus.UN_EXECUTE;
}
}
}
}

View File

@ -15,7 +15,7 @@
</a-tooltip>
</template>
</MsEditableTab>
<div v-if="activeScenarioTab.id !== 'all'" class="flex items-center gap-[8px]">
<div v-show="activeScenarioTab.id !== 'all'" class="flex items-center gap-[8px]">
<environmentSelect v-model:current-env-config="currentEnvConfig" />
<a-button type="primary" :loading="saveLoading" @click="saveScenario">
{{ t('common.save') }}
@ -124,10 +124,11 @@
} from '@/models/apiTest/scenario';
import { ModuleTreeNode } from '@/models/common';
import { EnvConfig } from '@/models/projectManagement/environmental';
import { ScenarioExecuteStatus, ScenarioStepRefType, ScenarioStepType } from '@/enums/apiEnum';
import { ScenarioExecuteStatus, ScenarioStepType } from '@/enums/apiEnum';
import { ApiTestRouteEnum } from '@/enums/routeEnum';
import { defaultScenario } from './components/config';
import updateStepStatus from './components/utils';
//
const detail = defineAsyncComponent(() => import('./detail/index.vue'));
@ -147,11 +148,215 @@
} as ScenarioParams,
]);
const activeScenarioTab = ref<ScenarioParams>(scenarioTabs.value[0] as ScenarioParams);
const currentEnvConfig = ref<EnvConfig>();
const executeButtonRef = ref<InstanceType<typeof executeButton>>();
const websocket = ref<WebSocket>();
const temporaryScenarioReportMap = {}; // websockettab
function setStepExecuteStatus() {
updateStepStatus(activeScenarioTab.value.steps, activeScenarioTab.value.stepResponses);
// activeScenarioTab.value.steps = mapTree<ScenarioStepItem>(activeScenarioTab.value.steps, (step) => {
// if (step.executeStatus === ScenarioExecuteStatus.EXECUTING) {
// //
// step.executeStatus = ScenarioExecuteStatus.UN_EXECUTE;
// }
// return step;
// });
}
/**
* 开启websocket监听接收执行结果
*/
function debugSocket(reportId?: string | number, executeType?: 'localExec' | 'serverExec', localExecuteUrl?: string) {
websocket.value = getSocket(
reportId || '',
executeType === 'localExec' ? '/ws/debug' : '',
executeType === 'localExec' ? localExecuteUrl : ''
);
websocket.value.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
if (data.msgType === 'EXEC_RESULT') {
if (activeScenarioTab.value.reportId === data.reportId) {
// tabtab
data.taskResult.requestResults.forEach((result) => {
activeScenarioTab.value.stepResponses[result.stepId] = {
...result,
console: data.taskResult.console,
};
if (result.isSuccessful) {
activeScenarioTab.value.executeSuccessCount += 1;
} else {
activeScenarioTab.value.executeFailCount += 1;
}
});
} else {
// tab
data.taskResult.requestResults.forEach((result) => {
if (activeScenarioTab.value.reportId) {
if (temporaryScenarioReportMap[activeScenarioTab.value.reportId] === undefined) {
temporaryScenarioReportMap[activeScenarioTab.value.reportId] = {};
}
temporaryScenarioReportMap[activeScenarioTab.value.reportId][result.stepId] = {
...result,
console: data.taskResult.console,
};
}
});
}
} else if (data.msgType === 'EXEC_END') {
// websocket
websocket.value?.close();
if (activeScenarioTab.value.reportId === data.reportId) {
activeScenarioTab.value.executeLoading = false;
activeScenarioTab.value.isExecute = false;
setStepExecuteStatus();
}
}
});
}
/**
* 实际执行函数
* @param executeParams 执行参数
* @param isExecute 是否执行否则是调试
* @param executeType 执行类型
* @param localExecuteUrl 本地执行地址
*/
async function realExecute(
executeParams: Pick<ApiScenarioDebugRequest, 'steps' | 'stepDetails' | 'reportId'>,
isExecute?: boolean,
executeType?: 'localExec' | 'serverExec',
localExecuteUrl?: string
) {
try {
activeScenarioTab.value.executeLoading = true;
debugSocket(executeParams.reportId, executeType, localExecuteUrl); // websocket
//
activeScenarioTab.value.executeTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
activeScenarioTab.value.executeSuccessCount = 0;
activeScenarioTab.value.executeFailCount = 0;
activeScenarioTab.value.stepResponses = {};
activeScenarioTab.value.reportId = executeParams.reportId; // ID
activeScenarioTab.value.isDebug = !isExecute;
let res;
if (isExecute && executeType !== 'localExec' && !activeScenarioTab.value.isNew) {
//
res = await executeScenario({
id: activeScenarioTab.value.id,
grouped: false,
environmentId: currentEnvConfig.value?.id || '',
projectId: appStore.currentProjectId,
scenarioConfig: activeScenarioTab.value.scenarioConfig,
uploadFileIds: activeScenarioTab.value.uploadFileIds,
linkFileIds: activeScenarioTab.value.linkFileIds,
...executeParams,
steps: mapTree(executeParams.steps, (node) => {
return {
...node,
parent: null, // axios
};
}),
});
} else {
res = await debugScenario({
id: activeScenarioTab.value.id,
grouped: false,
environmentId: currentEnvConfig.value?.id || '',
projectId: appStore.currentProjectId,
scenarioConfig: activeScenarioTab.value.scenarioConfig,
uploadFileIds: activeScenarioTab.value.uploadFileIds,
linkFileIds: activeScenarioTab.value.linkFileIds,
frontendDebug: executeType === 'localExec',
...executeParams,
steps: mapTree(executeParams.steps, (node) => {
return {
...node,
parent: null, // axios
};
}),
});
}
if (executeType === 'localExec' && localExecuteUrl) {
// debug
await localExecuteApiDebug(localExecuteUrl, res);
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
websocket.value?.close();
activeScenarioTab.value.executeLoading = false;
setStepExecuteStatus();
}
}
/**
* 执行场景
* @param executeType 执行类型
* @param localExecuteUrl 本地执行地址
*/
function handleExecute(executeType?: 'localExec' | 'serverExec', localExecuteUrl?: string) {
const waitingDebugStepDetails = {};
const waitTingDebugSteps = filterTree(activeScenarioTab.value.steps, (node) => {
if (node.enable) {
node.executeStatus = ScenarioExecuteStatus.EXECUTING;
waitingDebugStepDetails[node.id] = activeScenarioTab.value.stepDetails[node.id];
if (
[ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST].includes(node.stepType)
) {
//
node.executeStatus = ScenarioExecuteStatus.EXECUTING;
}
}
return !!node.enable;
});
realExecute(
{
steps: waitTingDebugSteps,
stepDetails: waitingDebugStepDetails,
reportId: getGenerateId(),
},
true,
executeType,
localExecuteUrl
);
}
function handleStopExecute() {
websocket.value?.close();
activeScenarioTab.value.executeLoading = false;
setStepExecuteStatus();
}
watch(
() => activeScenarioTab.value.id,
(val) => {
if (val !== 'all' && activeScenarioTab.value.reportId && !activeScenarioTab.value.executeLoading) {
// tab tab ID
const cacheReport = temporaryScenarioReportMap[activeScenarioTab.value.reportId];
if (cacheReport) {
//
Object.keys(cacheReport).forEach((stepId) => {
const result = cacheReport[stepId];
activeScenarioTab.value.stepResponses[stepId] = result;
if (result.isSuccessful) {
activeScenarioTab.value.executeSuccessCount += 1;
} else {
activeScenarioTab.value.executeFailCount += 1;
}
});
activeScenarioTab.value.executeLoading = false;
delete temporaryScenarioReportMap[activeScenarioTab.value.reportId]; //
setStepExecuteStatus();
}
}
}
);
function newTab(defaultScenarioInfo?: Scenario, action?: 'copy' | 'execute') {
if (defaultScenarioInfo) {
const isCopy = action === 'copy';
let copySteps = defaultScenarioInfo.steps;
let copySteps: ScenarioStepItem[] = [];
if (isCopy) {
copySteps = mapTree(defaultScenarioInfo.steps, (node) => {
return {
@ -160,6 +365,8 @@
id: getGenerateId(),
};
});
} else {
copySteps = mapTree(defaultScenarioInfo.steps);
}
scenarioTabs.value.push({
...defaultScenarioInfo,
@ -168,9 +375,14 @@
label: isCopy ? `copy-${defaultScenarioInfo.name}` : defaultScenarioInfo.name,
name: isCopy ? `copy-${defaultScenarioInfo.name}` : defaultScenarioInfo.name,
isNew: isCopy,
isExecute: action === 'execute',
stepResponses: {},
});
if (action === 'execute') {
nextTick(() => {
// tab
handleExecute(executeButtonRef.value?.isPriorityLocalExec ? 'localExec' : 'serverExec');
});
}
} else {
scenarioTabs.value.push({
...cloneDeep(defaultScenario),
@ -190,8 +402,6 @@
const activeFolder = ref<string>('all');
const offspringIds = ref<string[]>([]);
const isShowScenario = ref(false);
const executeButtonRef = ref<InstanceType<typeof executeButton>>();
const currentEnvConfig = ref<EnvConfig>();
//
const getActiveClass = (type: string) => {
@ -320,181 +530,6 @@
}
});
const websocket = ref<WebSocket>();
const temporaryScenarioReportMap = {}; // websockettab
/**
* 开启websocket监听接收执行结果
*/
function debugSocket(reportId?: string | number, executeType?: 'localExec' | 'serverExec', localExecuteUrl?: string) {
websocket.value = getSocket(
reportId || '',
executeType === 'localExec' ? '/ws/debug' : '',
executeType === 'localExec' ? localExecuteUrl : ''
);
websocket.value.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
if (data.msgType === 'EXEC_RESULT') {
if (activeScenarioTab.value.reportId === data.reportId) {
// tabtab
data.taskResult.requestResults.forEach((result) => {
activeScenarioTab.value.stepResponses[result.stepId] = {
...result,
console: data.taskResult.console,
};
if (result.isSuccessful) {
activeScenarioTab.value.executeSuccessCount += 1;
} else {
activeScenarioTab.value.executeFailCount += 1;
}
});
} else {
// tab
data.taskResult.requestResults.forEach((result) => {
if (activeScenarioTab.value.reportId) {
if (temporaryScenarioReportMap[activeScenarioTab.value.reportId] === undefined) {
temporaryScenarioReportMap[activeScenarioTab.value.reportId] = {};
}
temporaryScenarioReportMap[activeScenarioTab.value.reportId][result.stepId] = {
...result,
console: data.taskResult.console,
};
}
});
}
} else if (data.msgType === 'EXEC_END') {
// websocket
websocket.value?.close();
if (activeScenarioTab.value.reportId === data.reportId) {
activeScenarioTab.value.executeLoading = false;
activeScenarioTab.value.isExecute = false;
}
}
});
}
async function realExecute(
executeParams: Pick<ApiScenarioDebugRequest, 'steps' | 'stepDetails' | 'reportId'>,
isExecute?: boolean,
executeType?: 'localExec' | 'serverExec',
localExecuteUrl?: string
) {
try {
activeScenarioTab.value.executeLoading = true;
debugSocket(executeParams.reportId, executeType, localExecuteUrl); // websocket
//
activeScenarioTab.value.executeTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
activeScenarioTab.value.executeSuccessCount = 0;
activeScenarioTab.value.executeFailCount = 0;
activeScenarioTab.value.stepResponses = {};
activeScenarioTab.value.reportId = executeParams.reportId; // ID
activeScenarioTab.value.isDebug = !isExecute;
let res;
if (isExecute && executeType !== 'localExec' && !activeScenarioTab.value.isNew) {
//
res = await executeScenario({
id: activeScenarioTab.value.id,
grouped: false,
environmentId: currentEnvConfig.value?.id || '',
projectId: appStore.currentProjectId,
scenarioConfig: activeScenarioTab.value.scenarioConfig,
uploadFileIds: activeScenarioTab.value.uploadFileIds,
linkFileIds: activeScenarioTab.value.linkFileIds,
...executeParams,
steps: mapTree(executeParams.steps, (node) => {
return {
...node,
parent: null, // axios
};
}),
});
} else {
res = await debugScenario({
id: activeScenarioTab.value.id,
grouped: false,
environmentId: currentEnvConfig.value?.id || '',
projectId: appStore.currentProjectId,
scenarioConfig: activeScenarioTab.value.scenarioConfig,
uploadFileIds: activeScenarioTab.value.uploadFileIds,
linkFileIds: activeScenarioTab.value.linkFileIds,
frontendDebug: executeType === 'localExec',
...executeParams,
steps: mapTree(executeParams.steps, (node) => {
return {
...node,
parent: null, // axios
};
}),
});
}
if (executeType === 'localExec' && localExecuteUrl) {
// debug
await localExecuteApiDebug(localExecuteUrl, res);
}
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
websocket.value?.close();
activeScenarioTab.value.executeLoading = false;
}
}
function handleExecute(executeType?: 'localExec' | 'serverExec', localExecuteUrl?: string) {
const waitingDebugStepDetails = {};
const waitTingDebugSteps = filterTree(activeScenarioTab.value.steps, (node) => {
if (node.enable) {
node.executeStatus = ScenarioExecuteStatus.EXECUTING;
waitingDebugStepDetails[node.id] = activeScenarioTab.value.stepDetails[node.id];
if (
[ScenarioStepType.API, ScenarioStepType.API_CASE, ScenarioStepType.CUSTOM_REQUEST].includes(node.stepType)
) {
//
node.executeStatus = ScenarioExecuteStatus.EXECUTING;
}
}
return !!node.enable;
});
realExecute(
{
steps: waitTingDebugSteps,
stepDetails: waitingDebugStepDetails,
reportId: getGenerateId(),
},
true,
executeType,
localExecuteUrl
);
}
function handleStopExecute() {
websocket.value?.close();
activeScenarioTab.value.executeLoading = false;
}
watch(
() => activeScenarioTab.value.id,
(val) => {
if (val !== 'all' && activeScenarioTab.value.reportId && !activeScenarioTab.value.executeLoading) {
// tab tab ID
const cacheReport = temporaryScenarioReportMap[activeScenarioTab.value.reportId];
if (cacheReport) {
//
Object.keys(cacheReport).forEach((stepId) => {
const result = cacheReport[stepId];
activeScenarioTab.value.stepResponses[stepId] = result;
if (result.isSuccessful) {
activeScenarioTab.value.executeSuccessCount += 1;
} else {
activeScenarioTab.value.executeFailCount += 1;
}
});
activeScenarioTab.value.executeLoading = false;
delete temporaryScenarioReportMap[activeScenarioTab.value.reportId]; //
}
}
}
);
const isPriorityLocalExec = computed(() => executeButtonRef.value?.isPriorityLocalExec);
const scenarioId = computed(() => activeScenarioTab.value.id);
const scenarioExecuteLoading = computed(() => activeScenarioTab.value.executeLoading);

View File

@ -162,7 +162,7 @@
}>();
const lastReportStatusFilterVisible = ref(false);
const lastReportStatusListFilters = ref<string[]>(Object.keys(ReportStatus[ReportEnum.API_SCENARIO_REPORT]));
const lastReportStatusListFilters = ref<string[]>([]);
const lastReportStatusFilters = computed(() => {
return Object.keys(ReportStatus[ReportEnum.API_SCENARIO_REPORT]);
});
@ -335,7 +335,7 @@
};
const statusFilterVisible = ref(false);
const statusFilters = ref(Object.keys(ApiScenarioStatus));
const statusFilters = ref<string[]>([]);
const tableStore = useTableStore();
async function loadScenarioList(refreshTreeCount?: boolean) {
@ -354,7 +354,7 @@
moduleIds,
filter: {
lastReportStatus: lastReportStatusListFilters.value,
status: statusFilters.value.length === Object.keys(ApiScenarioStatus).length ? undefined : statusFilters.value,
status: statusFilters.value,
},
};
setLoadListParams(params);

View File

@ -876,9 +876,9 @@
excludeIds: [],
currentSelectCount: 0,
});
const statusFilters = ref<string[]>(Object.keys(statusIconMap));
const statusFilters = ref<string[]>([]);
const caseFilters = ref<string[]>([]);
const executeResultFilters = ref(Object.keys(executionResultMap));
const executeResultFilters = ref<string[]>([]);
async function initTableParams() {
let moduleIds: string[] = [];

View File

@ -633,14 +633,14 @@
});
//
const statusFilters = ref<string[]>(Object.keys(statusIconMap));
const statusFilters = ref<string[]>([]);
const caseLevelFields = ref<Record<string, any>>({});
const caseFilterVisible = ref(false);
const caseLevelList = computed(() => {
return caseLevelFields.value?.options || [];
});
const caseFilters = ref<string[]>([]);
const executeResultFilters = ref(Object.keys(executionResultMap));
const executeResultFilters = ref<string[]>([]);
const updateUserFilters = ref<string[]>([]);
const createUserFilters = ref<string[]>([]);
const deleteUserFilters = ref<string[]>([]);

View File

@ -240,9 +240,8 @@
import useFeatureCaseStore from '@/store/modules/case/featureCase';
import { hasAnyPermission } from '@/utils/permission';
import { BugListItem, BugOptionItem } from '@/models/bug-management';
import { BugOptionItem } from '@/models/bug-management';
import type { TableQueryParams } from '@/models/common';
import { CommonList } from '@/models/common';
const featureCaseStore = useFeatureCaseStore();

View File

@ -473,7 +473,7 @@
async function initFilter() {
await featureStore.getDefaultTemplate();
caseLevelList.value = featureStore.getSystemCaseLevelFields();
caseFilters.value = caseLevelList.value.map((item) => item.value);
caseFilters.value = [];
}
watch(

View File

@ -350,7 +350,7 @@
const tableParams = ref<Record<string, any>>({});
const statusFilterVisible = ref(false);
const statusFilters = ref<string[]>(Object.keys(reviewResultMap));
const statusFilters = ref<string[]>([]);
const hasOperationPermission = computed(() =>
hasAnyPermission(['CASE_REVIEW:READ+REVIEW', 'CASE_REVIEW:READ+RELEVANCE'])

View File

@ -495,7 +495,7 @@
};
const statusFilterVisible = ref(false);
const statusFilters = ref<string[]>(Object.keys(reviewStatusMap));
const statusFilters = ref<string[]>([]);
const tableQueryParams = ref<any>();
async function searchReview(filter?: FilterResult) {
let moduleIds: string[] = [];

View File

@ -107,7 +107,6 @@
import useTable from '@/components/pure/ms-table/useTable';
import MsTableMoreAction from '@/components/pure/ms-table-more-action/index.vue';
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
import MsTag from '@/components/pure/ms-tag/ms-tag.vue';
import AddScriptDrawer from '@/components/business/ms-common-script/ms-addScriptDrawer.vue';
import commonScriptStatus from './components/commonScriptStatus.vue';
import ScriptDetailDrawer from './components/scriptDetailDrawer.vue';
@ -129,7 +128,7 @@
ParamsRequestType,
} from '@/models/projectManagement/commonScript';
import { CommonScriptStatusEnum } from '@/enums/commonScriptStatusEnum';
import { ColumnEditTypeEnum, TableKeyEnum } from '@/enums/tableEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
const appStore = useAppStore();
const currentProjectId = computed(() => appStore.currentProjectId);
@ -141,7 +140,7 @@
const { t } = useI18n();
const statusFilterVisible = ref(false);
const keyword = ref<string>('');
const statusFilters = ref<string[]>(Object.keys(CommonScriptStatusEnum));
const statusFilters = ref<string[]>([]);
const hasOperationPermission = computed(() =>
hasAnyPermission(['PROJECT_CUSTOM_FUNCTION:READ+UPDATE', 'PROJECT_CUSTOM_FUNCTION:READ+DELETE'])

View File

@ -112,7 +112,6 @@
} from '@/api/modules/project-management/taskCenter';
import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
import useOpenNewPage from '@/hooks/useOpenNewPage';
import { useTableStore } from '@/store';
import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
@ -135,16 +134,7 @@
}>();
const keyword = ref<string>('');
const statusFilterVisible = ref(false);
const statusListFilters = ref<string[]>(Object.keys(TaskStatus[props.moduleType]));
const { openNewPage } = useOpenNewPage();
const filterOptions = computed(() => {
return statusListFilters.value.map((item) => {
return {
label: item,
value: item,
};
});
});
const statusListFilters = ref<string[]>([]);
const permissionsMap = {
organization: {

View File

@ -218,7 +218,7 @@
const keyword = ref<string>('');
const scrollWidth = ref<number>(3400);
const statusFilterVisible = ref(false);
const statusFilters = ref<string[]>(Object.keys(reviewStatusMap));
const statusFilters = ref<string[]>([]);
const tableBatchActions = {
baseAction: [