feat(接口场景): 场景执行&查看报告

This commit is contained in:
baiqi 2024-03-26 17:45:53 +08:00 committed by Craftsman
parent bd9abe2627
commit 22641d5620
9 changed files with 57 additions and 35 deletions

View File

@ -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 });
}

View File

@ -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'; // 批量复制接口场景

View File

@ -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))]"

View File

@ -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);

View File

@ -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);

View File

@ -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>

View File

@ -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() {

View File

@ -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

View File

@ -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
); );