feat(接口测试): 批量执行接口用例场景用例集合_报告改为执行当前用例结果

This commit is contained in:
xinxin.wu 2024-12-11 14:37:14 +08:00 committed by Craftsman
parent 1a9958b468
commit 5bc0c853b2
8 changed files with 84 additions and 27 deletions

View File

@ -281,6 +281,8 @@ export const commonRatePieOptions = {
color: [], color: [],
radius: ['65%', '80%'], radius: ['65%', '80%'],
center: [44, '50%'], center: [44, '50%'],
minAngle: 5,
minShowLabelAngle: 10,
avoidLabelOverlap: false, avoidLabelOverlap: false,
label: { label: {
show: false, show: false,

View File

@ -44,9 +44,19 @@
<CaseReportCom <CaseReportCom
v-if="!props.isScenario" v-if="!props.isScenario"
:detail-info="reportStepDetail" :detail-info="reportStepDetail"
:is-filter-step="props.isFilterStep"
:case-name="props.caseName"
:case-id="props.caseId"
:get-report-step-detail="props.getReportStepDetail"
/>
<ScenarioCom
v-else
:detail-info="reportStepDetail"
:is-filter-step="props.isFilterStep"
:case-name="props.caseName"
:case-id="props.caseId"
:get-report-step-detail="props.getReportStepDetail" :get-report-step-detail="props.getReportStepDetail"
/> />
<ScenarioCom v-else :detail-info="reportStepDetail" :get-report-step-detail="props.getReportStepDetail" />
</a-spin> </a-spin>
</MsDrawer> </MsDrawer>
</template> </template>
@ -76,6 +86,9 @@
doNotShowShare?: boolean; // doNotShowShare?: boolean; //
reportDetail?: (...args: any) => Promise<any>; // reportDetail?: (...args: any) => Promise<any>; //
getReportStepDetail?: (...args: any) => Promise<any>; // getReportStepDetail?: (...args: any) => Promise<any>; //
caseName?: string; //
caseId?: string; // id
isFilterStep?: boolean;
}>(); }>();
const appStore = useAppStore(); const appStore = useAppStore();

View File

@ -288,7 +288,13 @@
@finished="loadCaseListAndResetSelector" @finished="loadCaseListAndResetSelector"
/> />
<!-- 执行结果抽屉 --> <!-- 执行结果抽屉 -->
<caseAndScenarioReportDrawer v-model:visible="showExecuteResult" :report-id="activeReportId" /> <caseAndScenarioReportDrawer
v-model:visible="showExecuteResult"
:case-name="currentCaseName"
:case-id="currentId"
is-filter-step
:report-id="activeReportId"
/>
<!-- 同步抽屉 --> <!-- 同步抽屉 -->
<SyncModal <SyncModal
ref="syncModalRef" ref="syncModalRef"
@ -1132,10 +1138,14 @@
} }
const activeReportId = ref(''); const activeReportId = ref('');
const currentId = ref<string>('');
const currentCaseName = ref<string>('');
const showExecuteResult = ref(false); const showExecuteResult = ref(false);
async function showResult(record: ApiCaseDetail) { async function showResult(record: ApiCaseDetail) {
if (!record.lastReportId) return; if (!record.lastReportId) return;
activeReportId.value = record.lastReportId; activeReportId.value = record.lastReportId;
currentId.value = record.id;
currentCaseName.value = record.name;
showExecuteResult.value = true; showExecuteResult.value = true;
} }

View File

@ -175,9 +175,12 @@
v-model:keyword-name="keywordName" v-model:keyword-name="keywordName"
:key-words="cascaderKeywords" :key-words="cascaderKeywords"
show-type="CASE" show-type="CASE"
:case-id="props.caseId"
:case-name="props.caseName"
:active-type="activeTab" :active-type="activeTab"
:report-detail="detail || []" :report-detail="detail || []"
:get-report-step-detail="props.getReportStepDetail" :get-report-step-detail="props.getReportStepDetail"
:is-filter-step="props.isFilterStep"
:is-export="props.isExport" :is-export="props.isExport"
/> />
</div> </div>
@ -207,6 +210,9 @@
detailInfo?: ReportDetail; detailInfo?: ReportDetail;
getReportStepDetail?: (...args: any) => Promise<any>; // getReportStepDetail?: (...args: any) => Promise<any>; //
isExport?: boolean; isExport?: boolean;
isFilterStep?: boolean; //
caseName?: string; //
caseId?: string; // id
}>(); }>();
const detail = ref<ReportDetail>({ const detail = ref<ReportDetail>({
@ -250,7 +256,7 @@
}); });
const cascaderKeywords = ref<string>(''); const cascaderKeywords = ref<string>('');
const keywordName = ref<string>(''); const keywordName = ref<string>(props.caseName || '');
const getTotalTime = computed(() => { const getTotalTime = computed(() => {
if (detail.value) { if (detail.value) {

View File

@ -47,12 +47,15 @@
<TiledList <TiledList
ref="tiledListRef" ref="tiledListRef"
v-model:keyword-name="keywordName" v-model:keyword-name="keywordName"
:case-id="props.caseId"
:case-name="props.caseName"
:key-words="cascaderKeywords" :key-words="cascaderKeywords"
show-type="API" show-type="API"
:get-report-step-detail="props.getReportStepDetail" :get-report-step-detail="props.getReportStepDetail"
:active-type="activeTab" :active-type="activeTab"
:report-detail="detail || []" :report-detail="detail || []"
:is-export="props.isExport" :is-export="props.isExport"
:is-filter-step="props.isFilterStep"
class="p-[16px]" class="p-[16px]"
/> />
</div> </div>
@ -84,6 +87,9 @@
detailInfo?: ReportDetail; detailInfo?: ReportDetail;
getReportStepDetail?: (...args: any) => Promise<any>; // getReportStepDetail?: (...args: any) => Promise<any>; //
isExport?: boolean; // pdf isExport?: boolean; // pdf
isFilterStep?: boolean; //
caseName?: string; //
caseId?: string; // id
}>(); }>();
const detail = ref<ReportDetail>({ const detail = ref<ReportDetail>({
@ -149,7 +155,7 @@
} }
return ''; return '';
}); });
const keywordName = ref<string>(''); const keywordName = ref<string>(props.caseName || '');
const reportAnalysisList = computed<ReportMetricsItemModel[]>(() => [ const reportAnalysisList = computed<ReportMetricsItemModel[]>(() => [
{ {

View File

@ -76,6 +76,9 @@
keyWords: string; keyWords: string;
getReportStepDetail?: (...args: any) => Promise<any>; // getReportStepDetail?: (...args: any) => Promise<any>; //
isExport?: boolean; // pdf isExport?: boolean; // pdf
isFilterStep?: boolean; //
caseId?: string; // id
caseName?: string; //
}>(); }>();
const { t } = useI18n(); const { t } = useI18n();
@ -106,14 +109,6 @@
const expandedKeys = ref<(string | number)[]>([]); const expandedKeys = ref<(string | number)[]>([]);
const originTreeData = ref<ScenarioItemType[]>([]); const originTreeData = ref<ScenarioItemType[]>([]);
function initStepTree() {
tiledList.value = cloneDeep(props.reportDetail.children) || [];
tiledList.value.forEach((item) => {
addFoldField(item);
});
originTreeData.value = cloneDeep(tiledList.value);
}
const controlCurrent = ref(0); const controlCurrent = ref(0);
const isFailedRetry = computed(() => { const isFailedRetry = computed(() => {
// id // id
@ -145,15 +140,6 @@
}); });
}); });
watch(
() => props.reportDetail,
(val) => {
if (val && val.children) {
initStepTree();
}
},
{ deep: true, immediate: true }
);
const showApiType = ref<string[]>([ const showApiType = ref<string[]>([
ScenarioStepType.API, ScenarioStepType.API,
ScenarioStepType.API_CASE, ScenarioStepType.API_CASE,
@ -167,12 +153,14 @@
const stepType = const stepType =
splitLevel[0] === 'CUSTOM_REQUEST' ? ['API', 'API_CASE', 'CUSTOM_REQUEST'] : Object.values(ScenarioStepType); splitLevel[0] === 'CUSTOM_REQUEST' ? ['API', 'API_CASE', 'CUSTOM_REQUEST'] : Object.values(ScenarioStepType);
const nameSearch = innerKeyword.value?.toLowerCase(); // name const nameSearch = innerKeyword.value?.toLowerCase(); // name
const search = (_data: ScenarioItemType[]) => { const search = (_data: ScenarioItemType[]) => {
const result: ScenarioItemType[] = []; const result: ScenarioItemType[] = [];
_data.forEach((item) => { _data.forEach((item) => {
const isStepChildren = item.children && item?.children.length && showApiType.value.includes(item.stepType); const isStepChildren = item.children && item?.children.length && showApiType.value.includes(item.stepType);
const isFilterCaseStep =
props.isFilterStep && props.reportDetail.integrated && innerKeyword.value === props.caseName;
// //
const matchStepType = stepType.includes(item.stepType); const matchStepType = stepType.includes(item.stepType);
@ -183,9 +171,16 @@
// //
let matchesStepCondition; let matchesStepCondition;
//
if (isFilterCaseStep) {
const caseStepCondition = item.name?.toLowerCase().includes(nameSearch) && item.stepId === props.caseId;
matchesStepCondition = stepTypeStatus
? caseStepCondition && matchStepType && matchStepStatus
: caseStepCondition;
}
// name // name
if (nameSearch && stepTypeStatus) { else if (nameSearch && stepTypeStatus) {
matchesStepCondition = matchStepType && matchStepStatus && item.name?.toLowerCase().includes(nameSearch); matchesStepCondition = matchStepType && matchStepStatus && item.name?.toLowerCase().includes(nameSearch);
} }
// name // name
@ -235,6 +230,19 @@
} }
}, 300); }, 300);
function initStepTree() {
tiledList.value = cloneDeep(props.reportDetail.children) || [];
tiledList.value.forEach((item) => {
addFoldField(item);
});
originTreeData.value = cloneDeep(tiledList.value);
//
if (props.isFilterStep && props.reportDetail.integrated) {
updateDebouncedSearch();
}
}
watch( watch(
() => props.keyWords, () => props.keyWords,
(val) => { (val) => {
@ -246,6 +254,16 @@
} }
); );
watch(
() => props.reportDetail,
(val) => {
if (val && val.children) {
initStepTree();
}
},
{ deep: true, immediate: true }
);
defineExpose({ defineExpose({
updateDebouncedSearch, updateDebouncedSearch,
initStepTree, initStepTree,

View File

@ -468,6 +468,9 @@
<caseAndScenarioReportDrawer <caseAndScenarioReportDrawer
v-model:visible="showScenarioReportVisible" v-model:visible="showScenarioReportVisible"
is-scenario is-scenario
is-filter-step
:case-name="tableRecord?.name || ''"
:case-id="tableRecord?.id || ''"
:report-id="tableRecord?.lastReportId || ''" :report-id="tableRecord?.lastReportId || ''"
/> />
<!-- 场景导出--> <!-- 场景导出-->

View File

@ -597,19 +597,20 @@ export function handleUpdateTabPie(
if (hasPermission) { if (hasPermission) {
const pieBorderWidth = countList.slice(1).filter((e) => Number(e.count) > 0).length === 1 ? 0 : 1; const pieBorderWidth = countList.slice(1).filter((e) => Number(e.count) > 0).length === 1 ? 0 : 1;
lastCountList = countList.slice(1).map((item) => { lastCountList = countList.slice(1).map((item, i) => {
return { return {
value: item.count, value: item.count,
label: item.name, label: item.name,
name: item.name, name: item.name,
itemStyle: { itemStyle: {
color: defaultValueMap[typeKey][valueKey].color[i],
borderWidth: pieBorderWidth, borderWidth: pieBorderWidth,
borderColor: '#ffffff', borderColor: '#ffffff',
}, },
}; };
}); });
options.series.data = lastCountList.every((e) => e.value === 0) ? [] : lastCountList; options.series.data = lastCountList.every((e) => e.value === 0) ? [] : lastCountList.filter((e) => e.value !== 0);
options.title.text = countList[0].name ?? ''; options.title.text = countList[0].name ?? '';
options.title.subtext = `${countList[0].count ?? 0}%`; options.title.subtext = `${countList[0].count ?? 0}%`;
@ -625,8 +626,6 @@ export function handleUpdateTabPie(
options.title.subtext = '-%'; options.title.subtext = '-%';
} }
options.series.color = defaultValueMap[typeKey][valueKey].color;
const lastValueList = lastCountList.map((item, index) => { const lastValueList = lastCountList.map((item, index) => {
return { return {
...item, ...item,