feat(接口场景): 场景执行&查看报告
This commit is contained in:
parent
bd9abe2627
commit
22641d5620
|
@ -13,6 +13,7 @@ import {
|
||||||
DeleteModuleUrl,
|
DeleteModuleUrl,
|
||||||
DeleteScenarioUrl,
|
DeleteScenarioUrl,
|
||||||
ExecuteHistoryUrl,
|
ExecuteHistoryUrl,
|
||||||
|
ExecuteScenarioUrl,
|
||||||
GetModuleCountUrl,
|
GetModuleCountUrl,
|
||||||
GetModuleTreeUrl,
|
GetModuleTreeUrl,
|
||||||
GetScenarioStepUrl,
|
GetScenarioStepUrl,
|
||||||
|
@ -225,3 +226,8 @@ export function uploadTempFile(file: File) {
|
||||||
export function debugScenario(data: ApiScenarioDebugRequest) {
|
export function debugScenario(data: ApiScenarioDebugRequest) {
|
||||||
return MSR.post({ url: DebugScenarioUrl, data });
|
return MSR.post({ url: DebugScenarioUrl, data });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 场景执行
|
||||||
|
export function executeScenario(data: ApiScenarioDebugRequest) {
|
||||||
|
return MSR.post({ url: ExecuteScenarioUrl, data });
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ export const RecycleScenarioUrl = '/api/scenario/delete-to-gc'; // 删除接口
|
||||||
export const ScenarioUploadTempFileUrl = '/api/scenario/upload/temp/file'; // 接口场景上传临时文件
|
export const ScenarioUploadTempFileUrl = '/api/scenario/upload/temp/file'; // 接口场景上传临时文件
|
||||||
export const ScenarioTransferFileUrl = '/api/scenario/transfer'; // 接口场景临时文件转存
|
export const ScenarioTransferFileUrl = '/api/scenario/transfer'; // 接口场景临时文件转存
|
||||||
export const ScenarioTransferModuleOptionsUrl = '/api/scenario/transfer/options'; // 接口场景临时文件转存目录
|
export const ScenarioTransferModuleOptionsUrl = '/api/scenario/transfer/options'; // 接口场景临时文件转存目录
|
||||||
export const DebugScenarioUrl = '/api/scenario/debug'; // 接口场景调试
|
export const DebugScenarioUrl = '/api/scenario/debug'; // 接口场景调试(不保存报告)
|
||||||
|
export const ExecuteScenarioUrl = '/api/scenario/run'; // 接口场景执行(保存报告)
|
||||||
export const BatchRecycleScenarioUrl = '/api/scenario/batch-operation/delete-gc'; // 批量删除接口场景
|
export const BatchRecycleScenarioUrl = '/api/scenario/batch-operation/delete-gc'; // 批量删除接口场景
|
||||||
export const BatchMoveScenarioUrl = '/api/scenario/batch-operation/move'; // 批量移动接口场景
|
export const BatchMoveScenarioUrl = '/api/scenario/batch-operation/move'; // 批量移动接口场景
|
||||||
export const BatchCopyScenarioUrl = '/api/scenario/batch-operation/copy'; // 批量复制接口场景
|
export const BatchCopyScenarioUrl = '/api/scenario/batch-operation/copy'; // 批量复制接口场景
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
item-key-field="id"
|
item-key-field="id"
|
||||||
:disabled="props.disabled"
|
:disabled="props.disabled"
|
||||||
:item-border="false"
|
:item-border="false"
|
||||||
class="h-full rounded-[var(--border-radius-small)] bg-[var(--color-text-n9)] p-[12px]"
|
class="h-full overflow-hidden rounded-[var(--border-radius-small)] bg-[var(--color-text-n9)] p-[12px]"
|
||||||
item-class="mb-[4px] bg-white !p-[4px_8px]"
|
item-class="mb-[4px] bg-white !p-[4px_8px]"
|
||||||
:item-more-actions="moreActions"
|
:item-more-actions="moreActions"
|
||||||
active-item-class="!bg-[rgb(var(--primary-1))] text-[rgb(var(--primary-5))]"
|
active-item-class="!bg-[rgb(var(--primary-1))] text-[rgb(var(--primary-5))]"
|
||||||
|
|
|
@ -443,13 +443,6 @@
|
||||||
|
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
height: calc(100% - 88px);
|
height: calc(100% - 88px);
|
||||||
.response-header-pre {
|
|
||||||
@apply h-full overflow-auto bg-white;
|
|
||||||
.ms-scroll-bar();
|
|
||||||
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-radius: var(--border-radius-small);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
:deep(.arco-table-th) {
|
:deep(.arco-table-th) {
|
||||||
background-color: var(--color-text-n9);
|
background-color: var(--color-text-n9);
|
||||||
|
|
|
@ -127,13 +127,6 @@
|
||||||
.response-container {
|
.response-container {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
height: calc(100% - 48px);
|
height: calc(100% - 48px);
|
||||||
.response-header-pre {
|
|
||||||
@apply h-full overflow-auto bg-white;
|
|
||||||
.ms-scroll-bar();
|
|
||||||
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-radius: var(--border-radius-small);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
:deep(.arco-table-th) {
|
:deep(.arco-table-th) {
|
||||||
background-color: var(--color-text-n9);
|
background-color: var(--color-text-n9);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="h-full rounded-[var(--border-radius-small)] bg-[var(--color-text-n9)] p-[12px]">
|
<div class="h-full overflow-hidden rounded-[var(--border-radius-small)] bg-[var(--color-text-n9)] p-[12px]">
|
||||||
<pre class="response-header-pre">{{ getResponsePreContent(props.activeTab) }}</pre>
|
<pre class="response-header-pre">{{ getResponsePreContent(props.activeTab) }}</pre>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -8,8 +8,6 @@
|
||||||
/**
|
/**
|
||||||
* @description (共用) 请求头 || 提取 || 真实请求
|
* @description (共用) 请求头 || 提取 || 真实请求
|
||||||
*/
|
*/
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
|
||||||
import { RequestResult } from '@/models/apiTest/common';
|
import { RequestResult } from '@/models/apiTest/common';
|
||||||
|
@ -40,4 +38,12 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style lang="less" scoped>
|
||||||
|
.response-header-pre {
|
||||||
|
@apply h-full overflow-auto bg-white;
|
||||||
|
.ms-scroll-bar();
|
||||||
|
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: var(--border-radius-small);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -124,11 +124,13 @@
|
||||||
import stepTree from './stepTree.vue';
|
import stepTree from './stepTree.vue';
|
||||||
|
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import useOpenNewPage from '@/hooks/useOpenNewPage';
|
||||||
import { deleteNodes, filterTree, getGenerateId } from '@/utils';
|
import { deleteNodes, filterTree, getGenerateId } from '@/utils';
|
||||||
import { countNodes } from '@/utils/tree';
|
import { countNodes } from '@/utils/tree';
|
||||||
|
|
||||||
import { ApiScenarioDebugRequest, Scenario } from '@/models/apiTest/scenario';
|
import { ApiScenarioDebugRequest, Scenario } from '@/models/apiTest/scenario';
|
||||||
import { ScenarioExecuteStatus } from '@/enums/apiEnum';
|
import { ScenarioExecuteStatus } from '@/enums/apiEnum';
|
||||||
|
import { ApiTestRouteEnum } from '@/enums/routeEnum';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
isNew?: boolean; // 是否新建
|
isNew?: boolean; // 是否新建
|
||||||
|
@ -138,6 +140,7 @@
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { openNewPage } = useOpenNewPage();
|
||||||
|
|
||||||
const scenario = defineModel<Scenario>('scenario', {
|
const scenario = defineModel<Scenario>('scenario', {
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -226,7 +229,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkReport() {
|
function checkReport() {
|
||||||
console.log('查看报告');
|
openNewPage(ApiTestRouteEnum.API_TEST_REPORT, {
|
||||||
|
reportId: scenario.value.reportId,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshStepInfo() {
|
function refreshStepInfo() {
|
||||||
|
|
|
@ -179,7 +179,7 @@
|
||||||
<responseResult
|
<responseResult
|
||||||
:active-tab="ResponseComposition.BODY"
|
:active-tab="ResponseComposition.BODY"
|
||||||
:request-result="props.stepResponses?.[step.id]"
|
:request-result="props.stepResponses?.[step.id]"
|
||||||
:console="props.stepResponses?.[step.id].console"
|
:console="props.stepResponses?.[step.id]?.console"
|
||||||
:show-empty="false"
|
:show-empty="false"
|
||||||
:is-edit="false"
|
:is-edit="false"
|
||||||
is-definition
|
is-definition
|
||||||
|
|
|
@ -70,11 +70,11 @@
|
||||||
ref="createRef"
|
ref="createRef"
|
||||||
v-model:scenario="activeScenarioTab"
|
v-model:scenario="activeScenarioTab"
|
||||||
:module-tree="folderTree"
|
:module-tree="folderTree"
|
||||||
@batch-debug="realExecute"
|
@batch-debug="realExecute($event, false)"
|
||||||
></create>
|
></create>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="pageWrap">
|
<div v-else class="pageWrap">
|
||||||
<detail v-model:scenario="activeScenarioTab" @batch-debug="realExecute"></detail>
|
<detail v-model:scenario="activeScenarioTab" @batch-debug="realExecute($event, false)"></detail>
|
||||||
</div>
|
</div>
|
||||||
</MsCard>
|
</MsCard>
|
||||||
</template>
|
</template>
|
||||||
|
@ -102,6 +102,7 @@
|
||||||
import {
|
import {
|
||||||
addScenario,
|
addScenario,
|
||||||
debugScenario,
|
debugScenario,
|
||||||
|
executeScenario,
|
||||||
getScenarioDetail,
|
getScenarioDetail,
|
||||||
getTrashModuleCount,
|
getTrashModuleCount,
|
||||||
updateScenario,
|
updateScenario,
|
||||||
|
@ -336,6 +337,7 @@
|
||||||
|
|
||||||
async function realExecute(
|
async function realExecute(
|
||||||
executeParams: Pick<ApiScenarioDebugRequest, 'steps' | 'stepDetails' | 'reportId'>,
|
executeParams: Pick<ApiScenarioDebugRequest, 'steps' | 'stepDetails' | 'reportId'>,
|
||||||
|
isExecute?: boolean,
|
||||||
executeType?: 'localExec' | 'serverExec',
|
executeType?: 'localExec' | 'serverExec',
|
||||||
localExecuteUrl?: string
|
localExecuteUrl?: string
|
||||||
) {
|
) {
|
||||||
|
@ -348,17 +350,32 @@
|
||||||
activeScenarioTab.value.executeFailCount = 0;
|
activeScenarioTab.value.executeFailCount = 0;
|
||||||
activeScenarioTab.value.stepResponses = {};
|
activeScenarioTab.value.stepResponses = {};
|
||||||
activeScenarioTab.value.reportId = executeParams.reportId; // 存储报告ID
|
activeScenarioTab.value.reportId = executeParams.reportId; // 存储报告ID
|
||||||
activeScenarioTab.value.isDebug = true;
|
activeScenarioTab.value.isDebug = !isExecute;
|
||||||
const res = await debugScenario({
|
let res;
|
||||||
id: activeScenarioTab.value.id,
|
if (isExecute && executeType !== 'localExec') {
|
||||||
grouped: false,
|
res = await executeScenario({
|
||||||
environmentId: currentEnvConfig.value?.id || '',
|
id: activeScenarioTab.value.id,
|
||||||
projectId: appStore.currentProjectId,
|
grouped: false,
|
||||||
scenarioConfig: activeScenarioTab.value.scenarioConfig,
|
environmentId: currentEnvConfig.value?.id || '',
|
||||||
uploadFileIds: activeScenarioTab.value.uploadFileIds,
|
projectId: appStore.currentProjectId,
|
||||||
linkFileIds: activeScenarioTab.value.linkFileIds,
|
scenarioConfig: activeScenarioTab.value.scenarioConfig,
|
||||||
...executeParams,
|
uploadFileIds: activeScenarioTab.value.uploadFileIds,
|
||||||
});
|
linkFileIds: activeScenarioTab.value.linkFileIds,
|
||||||
|
...executeParams,
|
||||||
|
});
|
||||||
|
} 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,
|
||||||
|
});
|
||||||
|
}
|
||||||
if (executeType === 'localExec' && localExecuteUrl) {
|
if (executeType === 'localExec' && localExecuteUrl) {
|
||||||
await localExecuteApiDebug(localExecuteUrl, res);
|
await localExecuteApiDebug(localExecuteUrl, res);
|
||||||
}
|
}
|
||||||
|
@ -385,6 +402,7 @@
|
||||||
stepDetails: waitingDebugStepDetails,
|
stepDetails: waitingDebugStepDetails,
|
||||||
reportId: getGenerateId(),
|
reportId: getGenerateId(),
|
||||||
},
|
},
|
||||||
|
true,
|
||||||
executeType,
|
executeType,
|
||||||
localExecuteUrl
|
localExecuteUrl
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue