feat(接口测试): 批量执行接口用例场景用例集合_报告改为执行当前用例结果
This commit is contained in:
parent
1a9958b468
commit
5bc0c853b2
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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[]>(() => [
|
||||||
{
|
{
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 || ''"
|
||||||
/>
|
/>
|
||||||
<!-- 场景导出-->
|
<!-- 场景导出-->
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue