fix(测试计划): 接口用例列表点击id跳转&测试集字段&执行结果字段

This commit is contained in:
teukkk 2024-06-17 20:05:09 +08:00 committed by Craftsman
parent 26bedb326c
commit 813de4894c
9 changed files with 113 additions and 53 deletions

View File

@ -167,6 +167,7 @@ export interface PlanDetailFeatureCaseItem {
customFields: customFieldsItem[]; // 自定义字段集合
caseId: string;
testPlanId: string;
testPlanCollectionName: string; // 测试集名称
bugList: {
bugId: string;
id: string;
@ -300,6 +301,8 @@ export interface PlanDetailApiCaseItem {
environmentId: string;
environmentName: string;
testPlanCollectionId: string; // 测试集id
testPlanCollectionName: string; // 测试集名称
apiTestCaseId: string; // 接口用例id
}
export interface BatchApiCaseParams extends BatchActionQueryParams {
@ -345,6 +348,7 @@ export interface PlanDetailApiScenarioItem {
executeUserName: string;
lastExecReportId: string; // 报告id
testPlanCollectionId: string; // 测试集id
testPlanCollectionName: string; // 测试集名称
apiScenarioId: string; // 场景id
}

View File

@ -2,6 +2,8 @@ import { cloneDeep } from 'lodash-es';
import { EQUAL } from '@/components/pure/ms-advance-filter';
import { useI18n } from '@/hooks/useI18n';
import {
EnableKeyValueParam,
ExecuteBody,
@ -29,9 +31,12 @@ import {
ResponseBodyXPathAssertionFormat,
ResponseComposition,
} from '@/enums/apiEnum';
import { ReportStatus } from '@/enums/reportEnum';
import type { ExpressionConfig } from './fastExtraction/moreSetting.vue';
const { t } = useI18n();
// 请求 body 参数表格默认行的值
export const defaultBodyParamsItem: ExecuteRequestFormBodyFormValue = {
key: '',
@ -413,3 +418,13 @@ export const matchRuleOptions = [
];
// mock 参数为文件类型的匹配规则选项
export const mockFileMatchRules = ['EQUALS', 'NOT_EQUALS', 'IS_EMPTY', 'IS_NOT_EMPTY'];
// 执行结果筛选下拉
export const lastReportStatusListOptions = computed(() => {
return Object.keys(ReportStatus).map((key) => {
return {
value: key,
label: t(ReportStatus[key].label),
};
});
});

View File

@ -4,11 +4,7 @@
title-align="start"
body-class="p-0"
:cancel-button-props="{ disabled: batchLoading }"
:ok-loading="batchLoading"
:ok-button-props="{ disabled: batchUpdateExecutorDisabled }"
:ok-text="t('common.update')"
@before-ok="handleBatchUpdateExecutor"
@close="resetBatchForm"
@close="handleCancel"
>
<template #title>
{{ t('testPlan.featureCase.batchChangeExecutor') }}
@ -39,6 +35,18 @@
/>
</a-form-item>
</a-form>
<template #footer>
<a-button type="secondary" @click="handleCancel">{{ t('common.cancel') }}</a-button>
<a-button
class="ml-[12px]"
:disabled="batchUpdateExecutorDisabled"
type="primary"
:loading="batchLoading"
@click="handleBatchUpdateExecutor"
>
{{ t('common.update') }}
</a-button>
</template>
</a-modal>
</template>
@ -90,7 +98,12 @@
}
}
async function handleBatchUpdateExecutor(done: (closed: boolean) => void) {
function handleCancel() {
visible.value = false;
batchUpdateExecutorForm.value = { userId: '' };
}
async function handleBatchUpdateExecutor() {
batchUpdateExecutorFormRef.value?.validate(async (errors) => {
if (!errors) {
try {
@ -99,25 +112,19 @@
...props.params,
...batchUpdateExecutorForm.value,
});
handleCancel();
Message.success(t('common.updateSuccess'));
emit('loadList');
done(true);
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
done(false);
} finally {
batchLoading.value = false;
done(false);
}
}
});
}
function resetBatchForm() {
batchUpdateExecutorForm.value = { userId: '' };
}
onBeforeMount(() => {
initUserOptions();
});

View File

@ -104,7 +104,11 @@
<IconQuestionCircle class="h-[16px] w-[16px] text-[--color-text-4] hover:text-[rgb(var(--primary-5))]" />
</a-tooltip>
</div>
<a-form-item field="passThreshold" :label="t('testPlan.planForm.passThreshold')">
<a-form-item
field="passThreshold"
:label="t('testPlan.planForm.passThreshold')"
:rules="[{ required: true, message: t('testPlan.planForm.passThresholdRequired') }]"
>
<a-input-number
v-model:model-value="form.passThreshold"
size="small"

View File

@ -24,6 +24,9 @@
@filter-change="getModuleCount"
@module-change="loadCaseList(false)"
>
<template #num="{ record }">
<MsButton type="text" @click="toDetail(record)">{{ record.num }}</MsButton>
</template>
<template #protocol="{ record }">
<ApiMethodName :method="record.protocol" />
</template>
@ -33,15 +36,14 @@
<template #caseLevel="{ record }">
<CaseLevel :case-level="record.priority" />
</template>
<template #[FilterSlotNameEnum.CASE_MANAGEMENT_EXECUTE_RESULT]="{ filterContent }">
<ExecuteResult :execute-result="filterContent.key" />
<template #[FilterSlotNameEnum.API_TEST_CASE_API_LAST_EXECUTE_STATUS]="{ filterContent }">
<ExecutionStatus :module-type="ReportEnum.API_REPORT" :status="filterContent.value" />
</template>
<template #lastExecResult="{ record }">
<ExecuteResult
:execute-result="record.lastExecResult"
:class="[
!record.lastExecReportId || record.lastExecResult === LastExecuteResults.PENDING ? '' : 'cursor-pointer',
]"
<ExecutionStatus
:module-type="ReportEnum.API_REPORT"
:status="record.lastExecResult"
:class="[!record.lastExecReportId ? '' : 'cursor-pointer']"
@click="showReport(record)"
/>
</template>
@ -107,10 +109,10 @@
} from '@/components/pure/ms-table/type';
import useTable from '@/components/pure/ms-table/useTable';
import CaseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
import ExecuteResult from '@/components/business/ms-case-associate/executeResult.vue';
import ApiMethodName from '@/views/api-test/components/apiMethodName.vue';
import apiStatus from '@/views/api-test/components/apiStatus.vue';
import CaseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue';
import ExecutionStatus from '@/views/api-test/report/component/reportStatus.vue';
import BatchApiMoveModal from '@/views/test-plan/testPlan/components/batchApiMoveModal.vue';
import {
@ -126,6 +128,7 @@
} from '@/api/modules/test-plan/testPlan';
import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
import useOpenNewPage from '@/hooks/useOpenNewPage';
import useTableStore from '@/hooks/useTableStore';
import useAppStore from '@/store/modules/app';
import { characterLimit } from '@/utils';
@ -133,12 +136,13 @@
import { DragSortParams, ModuleTreeNode } from '@/models/common';
import type { PlanDetailApiCaseItem, PlanDetailApiCaseQueryParams } from '@/models/testPlan/testPlan';
import { LastExecuteResults } from '@/enums/caseEnum';
import { ReportEnum } from '@/enums/reportEnum';
import { ApiTestRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { casePriorityOptions } from '@/views/api-test/components/config';
import { executionResultMap, getModules } from '@/views/case-management/caseManagementFeature/components/utils';
import { casePriorityOptions, lastReportStatusListOptions } from '@/views/api-test/components/config';
import { getModules } from '@/views/case-management/caseManagementFeature/components/utils';
const props = defineProps<{
modulesCount: Record<string, number>; //
@ -162,6 +166,7 @@
const appStore = useAppStore();
const tableStore = useTableStore();
const { openModal } = useModal();
const { openNewPage } = useOpenNewPage();
const keyword = ref('');
const moduleNamePath = computed(() => {
@ -175,13 +180,14 @@
{
title: 'ID',
dataIndex: 'num',
slotName: 'num',
sortIndex: 1,
sortable: {
sortDirections: ['ascend', 'descend'],
sorter: true,
},
fixed: 'left',
width: 100,
width: 150,
showTooltip: true,
columnSelectorDisabled: true,
},
@ -203,6 +209,13 @@
width: 150,
showDrag: true,
},
{
title: 'ms.minders.testSet',
dataIndex: 'testPlanCollectionName',
width: 150,
showTooltip: true,
showDrag: true,
},
{
title: 'case.caseLevel',
dataIndex: 'priority',
@ -219,10 +232,8 @@
dataIndex: 'lastExecResult',
slotName: 'lastExecResult',
filterConfig: {
valueKey: 'key',
labelKey: 'statusText',
options: Object.values(executionResultMap),
filterSlotName: FilterSlotNameEnum.CASE_MANAGEMENT_EXECUTE_RESULT,
options: lastReportStatusListOptions.value,
filterSlotName: FilterSlotNameEnum.API_TEST_CASE_API_LAST_EXECUTE_STATUS,
},
width: 150,
showDrag: true,
@ -261,6 +272,7 @@
title: 'report.detail.api.executeEnv',
dataIndex: 'environmentName',
width: 150,
showTooltip: true,
showInTable: false,
showDrag: true,
},
@ -304,7 +316,6 @@
(record) => {
return {
...record,
lastExecResult: record.lastExecResult ?? LastExecuteResults.PENDING,
moduleId: getModules(record.moduleId, props.moduleTree),
};
}
@ -418,7 +429,7 @@
const reportVisible = ref(false);
const reportId = ref('');
function showReport(record: PlanDetailApiCaseItem) {
if (!record.lastExecReportId || record.lastExecResult === LastExecuteResults.PENDING) return;
if (!record.lastExecReportId) return;
reportVisible.value = true;
reportId.value = record.lastExecReportId;
}
@ -579,6 +590,13 @@
}
}
//
function toDetail(record: PlanDetailApiCaseItem) {
openNewPage(ApiTestRouteEnum.API_TEST_MANAGEMENT, {
cId: record.apiTestCaseId,
});
}
defineExpose({
resetSelector,
loadCaseList,

View File

@ -33,15 +33,14 @@
<template #caseLevel="{ record }">
<CaseLevel :case-level="record.priority" />
</template>
<template #[FilterSlotNameEnum.CASE_MANAGEMENT_EXECUTE_RESULT]="{ filterContent }">
<ExecuteResult :execute-result="filterContent.key" />
<template #[FilterSlotNameEnum.API_TEST_CASE_API_LAST_EXECUTE_STATUS]="{ filterContent }">
<ExecutionStatus :module-type="ReportEnum.API_REPORT" :status="filterContent.value" />
</template>
<template #lastExecResult="{ record }">
<ExecuteResult
:execute-result="record.lastExecResult"
:class="[
!record.lastExecReportId || record.lastExecResult === LastExecuteResults.PENDING ? '' : 'cursor-pointer',
]"
<ExecutionStatus
:module-type="ReportEnum.API_REPORT"
:status="record.lastExecResult"
:class="[!record.lastExecReportId ? '' : 'cursor-pointer']"
@click="showReport(record)"
/>
</template>
@ -108,9 +107,9 @@
} from '@/components/pure/ms-table/type';
import useTable from '@/components/pure/ms-table/useTable';
import CaseLevel from '@/components/business/ms-case-associate/caseLevel.vue';
import ExecuteResult from '@/components/business/ms-case-associate/executeResult.vue';
import apiStatus from '@/views/api-test/components/apiStatus.vue';
import CaseAndScenarioReportDrawer from '@/views/api-test/components/caseAndScenarioReportDrawer.vue';
import ExecutionStatus from '@/views/api-test/report/component/reportStatus.vue';
import BatchApiMoveModal from '@/views/test-plan/testPlan/components/batchApiMoveModal.vue';
import {
@ -134,13 +133,13 @@
import { DragSortParams, ModuleTreeNode } from '@/models/common';
import type { PlanDetailApiScenarioItem, PlanDetailApiScenarioQueryParams } from '@/models/testPlan/testPlan';
import { LastExecuteResults } from '@/enums/caseEnum';
import { ReportEnum } from '@/enums/reportEnum';
import { ApiTestRouteEnum } from '@/enums/routeEnum';
import { TableKeyEnum } from '@/enums/tableEnum';
import { FilterSlotNameEnum } from '@/enums/tableFilterEnum';
import { casePriorityOptions } from '@/views/api-test/components/config';
import { executionResultMap, getModules } from '@/views/case-management/caseManagementFeature/components/utils';
import { casePriorityOptions, lastReportStatusListOptions } from '@/views/api-test/components/config';
import { getModules } from '@/views/case-management/caseManagementFeature/components/utils';
const props = defineProps<{
modulesCount: Record<string, number>; //
@ -184,7 +183,7 @@
sorter: true,
},
fixed: 'left',
width: 100,
width: 150,
showTooltip: true,
columnSelectorDisabled: true,
},
@ -199,6 +198,13 @@
showTooltip: true,
columnSelectorDisabled: true,
},
{
title: 'ms.minders.testSet',
dataIndex: 'testPlanCollectionName',
width: 150,
showTooltip: true,
showDrag: true,
},
{
title: 'case.caseLevel',
dataIndex: 'priority',
@ -215,10 +221,8 @@
dataIndex: 'lastExecResult',
slotName: 'lastExecResult',
filterConfig: {
valueKey: 'key',
labelKey: 'statusText',
options: Object.values(executionResultMap),
filterSlotName: FilterSlotNameEnum.CASE_MANAGEMENT_EXECUTE_RESULT,
options: lastReportStatusListOptions.value,
filterSlotName: FilterSlotNameEnum.API_TEST_CASE_API_LAST_EXECUTE_STATUS,
},
width: 150,
showDrag: true,
@ -229,6 +233,7 @@
slotName: 'status',
width: 150,
showDrag: true,
showInTable: false,
},
{
title: 'common.belongModule',
@ -236,7 +241,6 @@
showTooltip: true,
width: 200,
showDrag: true,
showInTable: false,
},
{
title: 'common.belongProject',
@ -244,13 +248,14 @@
showTooltip: true,
showDrag: true,
width: 150,
showInTable: false,
},
{
title: 'report.detail.api.executeEnv',
dataIndex: 'environmentName',
width: 150,
showDrag: true,
showTooltip: true,
showInTable: false,
},
{
title: 'case.tableColumnCreateUser',
@ -258,7 +263,6 @@
showTooltip: true,
width: 130,
showDrag: true,
showInTable: false,
},
{
title: 'testPlan.featureCase.executor',
@ -293,7 +297,6 @@
(record) => {
return {
...record,
lastExecResult: record.lastExecResult ?? LastExecuteResults.PENDING,
moduleId: getModules(record.moduleId, props.moduleTree),
};
}
@ -409,7 +412,7 @@
const reportVisible = ref(false);
const reportId = ref('');
function showReport(record: PlanDetailApiScenarioItem) {
if (!record.lastExecReportId || record.lastExecResult === LastExecuteResults.PENDING) return;
if (!record.lastExecReportId) return;
reportVisible.value = true;
reportId.value = record.lastExecReportId;
}

View File

@ -242,6 +242,13 @@
width: 180,
columnSelectorDisabled: true,
},
{
title: 'ms.minders.testSet',
dataIndex: 'testPlanCollectionName',
width: 150,
showTooltip: true,
showDrag: true,
},
{
title: 'case.caseLevel',
dataIndex: 'caseLevel',

View File

@ -87,6 +87,7 @@ export default {
'testPlan.planForm.planStartAndEndTime': 'Planned start and end time',
'testPlan.planForm.associateRepeatCase': 'Allow associated duplicate cases',
'testPlan.planForm.passThreshold': 'Pass threshold',
'testPlan.planForm.passThresholdRequired': 'Pass threshold cannot be empty',
'testPlan.planForm.createTo': 'Create to',
'testPlan.planForm.selectPlanGroup': 'Select plan group',
'testPlan.planForm.repeatCaseTip1': 'Enable: Repeatedly associate the same case',

View File

@ -82,6 +82,7 @@ export default {
'testPlan.planForm.planStartAndEndTime': '计划起止时间',
'testPlan.planForm.associateRepeatCase': '允许关联重复用例',
'testPlan.planForm.passThreshold': '通过阀值',
'testPlan.planForm.passThresholdRequired': '通过阀值不能为空',
'testPlan.planForm.createTo': '创建到',
'testPlan.planForm.selectPlanGroup': '选择计划组',
'testPlan.planForm.repeatCaseTip1': '开启:可重复关联同一个用例',