feat(接口测试): 报告样式调整&导入同步 mock
This commit is contained in:
parent
3c5d0c3d51
commit
0e882485b7
|
@ -229,6 +229,7 @@ export interface ImportApiDefinitionRequest {
|
|||
coverModule: boolean; // 是否覆盖子目录
|
||||
coverData: boolean; // 是否覆盖数据
|
||||
syncCase: boolean; // 是否同步导入用例
|
||||
syncMock: boolean; // 是否同步导入mock
|
||||
protocol: string;
|
||||
authSwitch?: boolean;
|
||||
authUsername?: string;
|
||||
|
|
|
@ -100,6 +100,13 @@
|
|||
<a-switch v-model:model-value="importForm.syncCase" size="small" />
|
||||
{{ t('apiTestManagement.syncImportCase') }}
|
||||
</div>
|
||||
<div
|
||||
v-if="importForm.platform === RequestImportFormat.MeterSphere"
|
||||
class="mb-[16px] flex items-center gap-[4px]"
|
||||
>
|
||||
<a-switch v-model:model-value="importForm.syncMock" size="small" />
|
||||
{{ t('apiTestManagement.syncImportMock') }}
|
||||
</div>
|
||||
<a-form-item
|
||||
v-if="importForm.platform === RequestImportFormat.SWAGGER"
|
||||
:label="t('apiTestManagement.importMethod')"
|
||||
|
@ -395,6 +402,7 @@
|
|||
moduleId: '',
|
||||
coverData: false,
|
||||
syncCase: true,
|
||||
syncMock: true,
|
||||
coverModule: false,
|
||||
swaggerUrl: '',
|
||||
authSwitch: false,
|
||||
|
@ -480,6 +488,7 @@
|
|||
coverModule: importForm.value.coverModule,
|
||||
coverData: importForm.value.coverData,
|
||||
syncCase: importForm.value.syncCase,
|
||||
syncMock: importForm.value.syncMock,
|
||||
protocol: importForm.value.protocol,
|
||||
moduleId: importForm.value.moduleId,
|
||||
authSwitch: importForm.value.authSwitch,
|
||||
|
@ -496,6 +505,7 @@
|
|||
coverModule: importForm.value.coverModule,
|
||||
coverData: importForm.value.coverData,
|
||||
syncCase: importForm.value.syncCase,
|
||||
syncMock: importForm.value.syncMock,
|
||||
protocol: importForm.value.protocol,
|
||||
moduleId: importForm.value.moduleId,
|
||||
swaggerUrl: importForm.value.swaggerUrl,
|
||||
|
@ -528,6 +538,7 @@
|
|||
coverModule: importForm.value.coverModule,
|
||||
coverData: importForm.value.coverData,
|
||||
syncCase: importForm.value.syncCase,
|
||||
syncMock: importForm.value.syncMock,
|
||||
protocol: importForm.value.protocol,
|
||||
moduleId: importForm.value.moduleId,
|
||||
swaggerUrl: importForm.value.swaggerUrl,
|
||||
|
|
|
@ -84,6 +84,7 @@ export default {
|
|||
'apiTestManagement.exportCase': 'Synchronous export use case',
|
||||
'apiTestManagement.exportMock': 'Export Mock Synchronously',
|
||||
'apiTestManagement.syncImportCase': 'Sync Import API Cases',
|
||||
'apiTestManagement.syncImportMock': 'Sync Import API Mock',
|
||||
'apiTestManagement.syncUpdateDirectory': 'Sync Update API Directory',
|
||||
'apiTestManagement.importSwaggerFileTip1': 'Supports Swagger 3.0 version JSON files,',
|
||||
'apiTestManagement.importSwaggerFileTip2': '2.0 files can be converted to 3.0 on the official website',
|
||||
|
|
|
@ -80,6 +80,7 @@ export default {
|
|||
'apiTestManagement.exportCase': '同步导出用例',
|
||||
'apiTestManagement.exportMock': '同步导出 Mock',
|
||||
'apiTestManagement.syncImportCase': '同步导入接口用例',
|
||||
'apiTestManagement.syncImportMock': '同步导入 Mock',
|
||||
'apiTestManagement.syncUpdateDirectory': '同步更新接口所在目录',
|
||||
'apiTestManagement.importSwaggerFileTip1': '支持 Swagger 3.0 版本的 json 文件,',
|
||||
'apiTestManagement.importSwaggerFileTip2': '2.0 文件可以在官网一键转换 3.0',
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<!-- </a-popover> -->
|
||||
</div>
|
||||
|
||||
<div class="chart-legend grid flex-1 gap-y-3">
|
||||
<div class="chart-legend grid flex-1 gap-y-[12px]">
|
||||
<!-- 图例开始 -->
|
||||
<div v-for="item of legendData" :key="item.value" class="grid grid-cols-3">
|
||||
<div class="flex flex-nowrap items-center">
|
||||
|
|
|
@ -4,151 +4,155 @@
|
|||
<ReportDetailHeader :detail="detail" show-type="CASE" />
|
||||
<!-- 报告参数结束 -->
|
||||
<!-- 报告分析开始 -->
|
||||
<div class="analyze mb-1">
|
||||
<div class="analyze">
|
||||
<!-- 请求分析 -->
|
||||
<div class="request-analyze min-h-[110px]">
|
||||
<div class="block-title mb-4">{{ t('report.detail.api.requestAnalysis') }}</div>
|
||||
<SetReportChart
|
||||
:legend-data="legendData"
|
||||
:options="charOptions"
|
||||
:request-total="getIndicators(detail.total) || 0"
|
||||
/>
|
||||
</div>
|
||||
<!-- 耗时分析 -->
|
||||
<div class="time-analyze">
|
||||
<div class="time-card mb-2 mt-[16px] h-[40px] flex-1 gap-4">
|
||||
<div class="time-card-item flex h-full">
|
||||
<MsIcon type="icon-icon_time_outlined" class="mr-[4px] text-[var(--color-text-4)]" size="16" />
|
||||
<span class="time-card-item-title">{{ t('report.detail.api.totalTime') }}</span>
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
<span class="count">{{ getTotalTime.split('-')[0] }}</span
|
||||
><span class="time-card-item-title">{{ getTotalTime.split('-')[1] || 'ms' }}</span>
|
||||
<template #content>
|
||||
<div class="min-w-[140px] max-w-[400px] p-4 text-[14px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.totalTime') }}</div>
|
||||
<div class="mt-2 text-[var(--color-text-1)]">
|
||||
<span class="text-[18px] font-medium">{{ getTotalTime.split('-')[0] }}</span
|
||||
>{{ getTotalTime.split('-')[1] || 'ms' }}</div
|
||||
>
|
||||
<div class="block-title">{{ t('report.detail.api.requestAnalysis') }}</div>
|
||||
<div class="flex justify-between">
|
||||
<div class="request-analyze">
|
||||
<SetReportChart
|
||||
:legend-data="legendData"
|
||||
:options="charOptions"
|
||||
:request-total="getIndicators(detail.total) || 0"
|
||||
/>
|
||||
</div>
|
||||
<!-- 耗时分析 -->
|
||||
<div class="time-analyze gap-[12px]">
|
||||
<div class="time-card flex-1 gap-[12px]">
|
||||
<div class="time-card-item">
|
||||
<MsIcon type="icon-icon_time_outlined" class="mr-[4px] text-[var(--color-text-4)]" size="16" />
|
||||
<span class="time-card-item-title">{{ t('report.detail.api.totalTime') }}</span>
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
<span class="count">{{ getTotalTime.split('-')[0] }}</span
|
||||
><span class="time-card-item-title">{{ getTotalTime.split('-')[1] || 'ms' }}</span>
|
||||
<template #content>
|
||||
<div class="min-w-[140px] max-w-[400px] p-4 text-[14px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.totalTime') }}</div>
|
||||
<div class="mt-2 text-[var(--color-text-1)]">
|
||||
<span class="text-[18px] font-medium">{{ getTotalTime.split('-')[0] }}</span
|
||||
>{{ getTotalTime.split('-')[1] || 'ms' }}</div
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
</div>
|
||||
<div class="time-card-item h-full">
|
||||
<MsIcon type="icon-icon_time_outlined" class="mr-[4px] text-[var(--color-text-4)]" size="16" />
|
||||
<span class="time-card-item-title"> {{ t('report.detail.api.requestTotalTime') }}</span>
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
<div class="flex items-end">
|
||||
<div class="count">
|
||||
{{ detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[0] : '0' }}
|
||||
</div>
|
||||
<div class="time-card-item-title">
|
||||
{{ detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[1] : 'ms' }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
|
||||
<template #content>
|
||||
<div class="min-w-[140px] max-w-[400px] p-4 text-[14px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.requestTotalTime') }}</div>
|
||||
<div class="mt-2 text-[var(--color-text-1)]">
|
||||
<span class="text-[18px] font-medium">{{
|
||||
detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[0] : '0'
|
||||
}}</span
|
||||
>{{
|
||||
detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[1] : 'ms'
|
||||
}}</div
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="time-card-item h-full">
|
||||
<MsIcon type="icon-icon_time_outlined" class="mr-[4px] text-[var(--color-text-4)]" size="16" />
|
||||
<span class="time-card-item-title"> {{ t('report.detail.api.requestTotalTime') }}</span>
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
|
||||
<div class="time-card flex-1 gap-4">
|
||||
<!-- 执行率 -->
|
||||
<div v-if="detail.integrated" class="time-card-item-rote">
|
||||
<div class="time-card-item-rote-title">
|
||||
<MsIcon type="icon-icon_yes_outlined" class="mr-[4px] text-[var(--color-text-4)]" size="16" />
|
||||
{{ t('report.detail.api.executionRate') }}
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="count">{{
|
||||
detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[0] : '0'
|
||||
}}</div
|
||||
><div class="time-card-item-title">{{
|
||||
detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[1] : 'ms'
|
||||
}}</div>
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
<div class="count one-line-text max-w-[80px]"> {{ getExcuteRate() }} </div
|
||||
><span v-show="getExcuteRate() !== 'Calculating'">%</span>
|
||||
<a-divider direction="vertical" class="!h-[16px]" :margin="8"></a-divider>
|
||||
<span>{{ getIndicators(getRequestEacuteCount) }}</span>
|
||||
<span class="mx-1 text-[var(--color-text-4)]">/ {{ getIndicators(getRequestTotalCount) }}</span>
|
||||
<template #content>
|
||||
<div class="min-w-[190px] max-w-[400px] p-4 text-[14px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.executionRate') }}</div>
|
||||
<div class="mt-2 flex items-center justify-between">
|
||||
<div class="count text-[18px] font-medium">
|
||||
{{ getExcuteRate() }} <span v-show="getExcuteRate() !== 'Calculating'">%</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ getIndicators(getRequestEacuteCount) }}</span>
|
||||
<span class="mx-1 text-[var(--color-text-4)]"
|
||||
>/ {{ getIndicators(getRequestTotalCount) }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="time-card-item-rote">
|
||||
<div class="time-card-item-rote-title">
|
||||
<MsIcon type="icon-icon_yes_outlined" class="mr-[4px] text-[var(--color-text-4)]" size="16" />
|
||||
{{ t('report.detail.api.assertPass') }}
|
||||
</div>
|
||||
|
||||
<template #content>
|
||||
<div class="min-w-[140px] max-w-[400px] p-4 text-[14px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.requestTotalTime') }}</div>
|
||||
<div class="mt-2 text-[var(--color-text-1)]">
|
||||
<span class="text-[18px] font-medium">{{
|
||||
detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[0] : '0'
|
||||
}}</span
|
||||
>{{
|
||||
detail.requestDuration !== null ? formatDuration(detail.requestDuration).split('-')[1] : 'ms'
|
||||
}}</div
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="time-card flex-1 gap-4">
|
||||
<!-- 执行率 -->
|
||||
<div v-if="detail.integrated" class="time-card-item-rote">
|
||||
<div class="time-card-item-rote-title">
|
||||
<MsIcon type="icon-icon_yes_outlined" class="mr-[4px] text-[var(--color-text-4)]" size="16" />
|
||||
{{ t('report.detail.api.executionRate') }}
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
<div class="count one-line-text max-w-[80px]"> {{ getExcuteRate() }} </div
|
||||
><span v-show="getExcuteRate() !== 'Calculating'">%</span>
|
||||
<a-divider direction="vertical" class="!h-[16px]" :margin="8"></a-divider>
|
||||
<span>{{ getIndicators(getRequestEacuteCount) }}</span>
|
||||
<span class="mx-1 text-[var(--color-text-4)]">/ {{ getIndicators(getRequestTotalCount) }}</span>
|
||||
<template #content>
|
||||
<div class="min-w-[190px] max-w-[400px] p-4 text-[14px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.executionRate') }}</div>
|
||||
<div class="mt-2 flex items-center justify-between">
|
||||
<div class="count text-[18px] font-medium">
|
||||
{{ getExcuteRate() }} <span v-show="getExcuteRate() !== 'Calculating'">%</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>{{ getIndicators(getRequestEacuteCount) }}</span>
|
||||
<span class="mx-1 text-[var(--color-text-4)]">/ {{ getIndicators(getRequestTotalCount) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
<div class="flex items-center">
|
||||
<div class="count one-line-text max-w-[80px]">{{ detail.assertionPassRate || '0.00' }}</div
|
||||
><span v-show="detail.assertionPassRate !== 'Calculating'" class="ml-1">%</span>
|
||||
<a-divider direction="vertical" class="!h-[16px]" :margin="8"></a-divider>
|
||||
<div class="one-line-text max-w-[80px]">{{
|
||||
getIndicators(detail.assertionSuccessCount) !== 'Calculating'
|
||||
? addCommasToNumber(detail.assertionSuccessCount || 0)
|
||||
: getIndicators(detail.assertionSuccessCount)
|
||||
}}</div>
|
||||
<span class="mx-1 text-[var(--color-text-4)]">/</span>
|
||||
<div class="one-line-text max-w-[80px]">
|
||||
{{
|
||||
getIndicators(detail.assertionCount) !== 'Calculating'
|
||||
? addCommasToNumber(detail.assertionCount)
|
||||
: getIndicators(detail.assertionCount)
|
||||
}}</div
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="time-card-item-rote">
|
||||
<div class="time-card-item-rote-title">
|
||||
<MsIcon type="icon-icon_yes_outlined" class="mr-[4px] text-[var(--color-text-4)]" size="16" />
|
||||
{{ t('report.detail.api.assertPass') }}
|
||||
</div>
|
||||
|
||||
<div class="flex items-center">
|
||||
<a-popover position="bottom" content-class="response-popover-content">
|
||||
<div class="flex items-center">
|
||||
<div class="count one-line-text max-w-[80px]">{{ detail.assertionPassRate || '0.00' }}</div
|
||||
><span v-show="detail.assertionPassRate !== 'Calculating'" class="ml-1">%</span>
|
||||
<a-divider direction="vertical" class="!h-[16px]" :margin="8"></a-divider>
|
||||
<div class="one-line-text max-w-[80px]">{{
|
||||
getIndicators(detail.assertionSuccessCount) !== 'Calculating'
|
||||
? addCommasToNumber(detail.assertionSuccessCount || 0)
|
||||
: getIndicators(detail.assertionSuccessCount)
|
||||
}}</div>
|
||||
<span class="mx-1 text-[var(--color-text-4)]">/</span>
|
||||
<div class="one-line-text max-w-[80px]">
|
||||
{{
|
||||
getIndicators(detail.assertionCount) !== 'Calculating'
|
||||
? addCommasToNumber(detail.assertionCount)
|
||||
: getIndicators(detail.assertionCount)
|
||||
}}</div
|
||||
>
|
||||
</div>
|
||||
|
||||
<template #content>
|
||||
<div class="min-w-[190px] max-w-[400px] p-4 text-[14px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.assertPass') }}</div>
|
||||
<div class="mt-2 flex items-center justify-between">
|
||||
<div class="text-[18px] font-medium text-[var(--color-text-1)]"
|
||||
>{{ getIndicators(detail.assertionPassRate) }}
|
||||
<span v-show="detail.assertionPassRate !== 'Calculating'">%</span></div
|
||||
>
|
||||
<div>
|
||||
<span class="text-[var(--color-text-1)]">{{
|
||||
getIndicators(detail.assertionSuccessCount) !== 'Calculating'
|
||||
? addCommasToNumber(detail.assertionSuccessCount || 0)
|
||||
: getIndicators(detail.assertionSuccessCount)
|
||||
}}</span>
|
||||
<span class="text-[var(--color-text-4)]"
|
||||
><span class="mx-1">/</span>
|
||||
{{
|
||||
getIndicators(detail.assertionCount) !== 'Calculating'
|
||||
? addCommasToNumber(detail.assertionCount)
|
||||
: getIndicators(detail.assertionCount)
|
||||
}}</span
|
||||
<template #content>
|
||||
<div class="min-w-[190px] max-w-[400px] p-4 text-[14px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('report.detail.api.assertPass') }}</div>
|
||||
<div class="mt-2 flex items-center justify-between">
|
||||
<div class="text-[18px] font-medium text-[var(--color-text-1)]"
|
||||
>{{ getIndicators(detail.assertionPassRate) }}
|
||||
<span v-show="detail.assertionPassRate !== 'Calculating'">%</span></div
|
||||
>
|
||||
<div>
|
||||
<span class="text-[var(--color-text-1)]">{{
|
||||
getIndicators(detail.assertionSuccessCount) !== 'Calculating'
|
||||
? addCommasToNumber(detail.assertionSuccessCount || 0)
|
||||
: getIndicators(detail.assertionSuccessCount)
|
||||
}}</span>
|
||||
<span class="text-[var(--color-text-4)]"
|
||||
><span class="mx-1">/</span>
|
||||
{{
|
||||
getIndicators(detail.assertionCount) !== 'Calculating'
|
||||
? addCommasToNumber(detail.assertionCount)
|
||||
: getIndicators(detail.assertionCount)
|
||||
}}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-popover>
|
||||
</template>
|
||||
</a-popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -417,11 +421,12 @@
|
|||
@apply mb-4 bg-white;
|
||||
}
|
||||
.analyze {
|
||||
height: 196px;
|
||||
@apply mb-4 bg-white;
|
||||
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
@apply mb-4 flex justify-between bg-white;
|
||||
.request-analyze {
|
||||
@apply flex h-full flex-1 flex-col p-4;
|
||||
@apply flex h-full flex-1 flex-col;
|
||||
.chart-legend {
|
||||
.chart-legend-item {
|
||||
@apply grid grid-cols-3 gap-2;
|
||||
|
@ -435,28 +440,36 @@
|
|||
}
|
||||
}
|
||||
.time-analyze {
|
||||
@apply flex h-full flex-1 flex-col p-4;
|
||||
@apply flex h-full flex-1 flex-col px-4;
|
||||
.time-card {
|
||||
@apply flex items-center justify-between;
|
||||
.time-card-item {
|
||||
@apply flex flex-1 flex-grow items-end;
|
||||
|
||||
padding: 9px 12px;
|
||||
border-radius: 6px;
|
||||
background: var(--color-text-n9);
|
||||
@apply mt-4 flex flex-1 flex-grow items-center px-4;
|
||||
.time-card-item-title {
|
||||
color: var(--color-text-4);
|
||||
line-height: 16px;
|
||||
}
|
||||
.count {
|
||||
font-size: 18px;
|
||||
@apply mx-2 font-medium;
|
||||
|
||||
line-height: 22px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
.time-card-item-rote {
|
||||
@apply flex flex-1 flex-grow flex-col;
|
||||
|
||||
padding: 9px 12px;
|
||||
border-radius: 6px;
|
||||
background: var(--color-text-n9);
|
||||
@apply mt-4 flex flex-1 flex-grow flex-col p-4;
|
||||
.time-card-item-rote-title {
|
||||
@apply mb-2 flex items-center;
|
||||
|
||||
color: var(--color-text-4);
|
||||
@apply mb-2;
|
||||
}
|
||||
.count {
|
||||
font-size: 18px;
|
||||
|
@ -473,7 +486,9 @@
|
|||
}
|
||||
}
|
||||
.block-title {
|
||||
font-size: 14px;
|
||||
@apply font-medium;
|
||||
|
||||
margin-bottom: 16px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
:active-type="activeTab"
|
||||
:report-detail="detail || []"
|
||||
:is-export="props.isExport"
|
||||
class="p-[16px]"
|
||||
/>
|
||||
</div>
|
||||
<!-- 报告明细结束 -->
|
||||
|
|
|
@ -382,7 +382,7 @@
|
|||
.arco-tree-node-title {
|
||||
@apply !cursor-pointer bg-white;
|
||||
|
||||
padding: 12px 4px;
|
||||
padding: 8px 4px;
|
||||
&:hover {
|
||||
background-color: white !important;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div
|
||||
class="tiled-wrap p-4"
|
||||
class="tiled-wrap"
|
||||
:class="{
|
||||
'border border-solid border-[var(--color-text-n8)]': props.showType === 'API',
|
||||
'!max-h-max': props.isExport,
|
||||
|
|
Loading…
Reference in New Issue