fix(测试跟踪): 修复测试计划报告连接分享,接口用例查出的是最新执行结果的问题

--bug=1022575 --user=宋天阳
【测试跟踪】github#21600,定时执行的测试计划在执行失败后将报告分享至钉钉群,但是访问钉钉群的链接发现,执行结果取的是最新执行的结果,而我们是想看当时执行失败时的接口执行信息
https://www.tapd.cn/55049933/s/1348250
This commit is contained in:
song-tianyang 2023-03-10 17:49:17 +08:00 committed by 建国
parent 2c90da097b
commit 6901eb6cda
3 changed files with 185 additions and 128 deletions

View File

@ -23,4 +23,10 @@ public class ShareTestPlanApiReportController {
shareInfoService.validate(shareId); shareInfoService.validate(shareId);
return apiDefinitionService.getDbResult(testId); return apiDefinitionService.getDbResult(testId);
} }
@GetMapping("/api/definition/report/by/id/{reportId}")
public ApiReportResult getApiReport(@PathVariable String reportId) {
return apiDefinitionService.getReportById(reportId);
}
} }

View File

@ -1,4 +1,8 @@
import {get, post, generateShareUrl} from "metersphere-frontend/src/plugins/request" import {
generateShareUrl,
get,
post,
} from "metersphere-frontend/src/plugins/request";
export function generateApiDocumentShareInfo(param) { export function generateApiDocumentShareInfo(param) {
return post("/share/generate/api/document", param); return post("/share/generate/api/document", param);
@ -18,20 +22,26 @@ export function getShareContent(shareId, stepId) {
} }
export function getShareApiReport(shareId, testId) { export function getShareApiReport(shareId, testId) {
return get('/share/api/definition/report/getReport/' + shareId + '/' + testId); return get(
"/share/api/definition/report/getReport/" + shareId + "/" + testId
);
}
export function getShareApiReportByReportId(reportId) {
return get("/share/api/definition/report/by/id/" + reportId);
} }
export function getShareInfo(id) { export function getShareInfo(id) {
return get('/share/info/get/' + id); return get("/share/info/get/" + id);
} }
export function getShareId() { export function getShareId() {
//let herfUrl = 'http://localhost:8080/sharePlanReport?shareId=bf9496ac-8577-46b4-adf9-9c7e93dd06a8'; //let herfUrl = 'http://localhost:8080/sharePlanReport?shareId=bf9496ac-8577-46b4-adf9-9c7e93dd06a8';
let herfUrl = window.location.href; let herfUrl = window.location.href;
if (herfUrl.indexOf('shareId=') > -1) { if (herfUrl.indexOf("shareId=") > -1) {
let shareId = ''; let shareId = "";
new URL(herfUrl).searchParams.forEach((value, key) => { new URL(herfUrl).searchParams.forEach((value, key) => {
if (key === 'shareId') { if (key === "shareId") {
shareId = value; shareId = value;
} }
}); });
@ -52,6 +62,6 @@ export function getShareId() {
} }
export function getShareRedirectUrl(data) { export function getShareRedirectUrl(data) {
let name = '/share-plan-report'; let name = "/share-plan-report";
return generateShareUrl(name, data.shareUrl); return generateShareUrl(name, data.shareUrl);
} }

View File

@ -1,47 +1,53 @@
<template> <template>
<el-container> <el-container>
<ms-aside-container width="500px" :default-hidden-bottom-top="200" :enable-auto-height="true"> <ms-aside-container
width="500px"
:default-hidden-bottom-top="200"
:enable-auto-height="true"
>
<el-card> <el-card>
<el-scrollbar> <el-scrollbar>
<ms-table v-loading="loading" <ms-table
:show-select-all="false" v-loading="loading"
:screen-height="null" :show-select-all="false"
:enable-selection="false" :screen-height="null"
:highlight-current-row="true" :enable-selection="false"
@refresh="getScenarioApiCase" :highlight-current-row="true"
@handleRowClick="rowClick" @refresh="getScenarioApiCase"
:data="apiCases"> @handleRowClick="rowClick"
:data="apiCases"
<ms-table-column >
:width="100" <ms-table-column :width="100" :label="$t('commons.id')" prop="num">
:label="$t('commons.id')"
prop="num">
</ms-table-column> </ms-table-column>
<ms-table-column <ms-table-column :label="$t('commons.name')" prop="name">
:label="$t('commons.name')"
prop="name">
</ms-table-column> </ms-table-column>
<el-table-column <el-table-column
prop="principalName" prop="principalName"
:label="$t('test_track.plan.plan_principal')"/> :label="$t('test_track.plan.plan_principal')"
/>
<ms-table-column <ms-table-column
:label="$t('test_track.case.priority')" :label="$t('test_track.case.priority')"
:width="80" :width="80"
prop="priority"> prop="priority"
>
<template v-slot:default="scope"> <template v-slot:default="scope">
<priority-table-item :value="scope.row.priority" ref="priority"/> <priority-table-item
:value="scope.row.priority"
ref="priority"
/>
</template> </template>
</ms-table-column> </ms-table-column>
<ms-table-column <ms-table-column
:width="80" :width="80"
:label="$t('test_track.plan_view.execute_result')" :label="$t('test_track.plan_view.execute_result')"
prop="lastResult"> prop="lastResult"
>
<template v-slot:default="scope"> <template v-slot:default="scope">
<ms-test-plan-api-status :status="scope.row.execResult"/> <ms-test-plan-api-status :status="scope.row.execResult" />
</template> </template>
</ms-table-column> </ms-table-column>
</ms-table> </ms-table>
@ -50,22 +56,27 @@
</ms-aside-container> </ms-aside-container>
<ms-main-container v-loading="responseLoading"> <ms-main-container v-loading="responseLoading">
<div v-if="showResponse"> <div v-if="showResponse">
<micro-app v-if="!isTemplate" <micro-app
route-name="ApiReportView" v-if="!isTemplate"
service="api" route-name="ApiReportView"
:route-params="{ service="api"
isTestPlan: showResponse, :route-params="{
response isTestPlan: showResponse,
}"/> response,
}"
/>
<el-card v-else> <el-card v-else>
<ms-request-result-tail :response="response" <ms-request-result-tail
:is-test-plan="showResponse" :response="response"
ref="debugResult"/> :is-test-plan="showResponse"
ref="debugResult"
/>
</el-card> </el-card>
</div> </div>
<div class="empty" v-else>{{ $t('test_track.plan.load_case.content_empty') }}</div> <div class="empty" v-else>
{{ $t("test_track.plan.load_case.content_empty") }}
</div>
</ms-main-container> </ms-main-container>
</el-container> </el-container>
</template> </template>
@ -85,14 +96,17 @@ import {
getSharePlanApiAllCase, getSharePlanApiAllCase,
getSharePlanApiErrorReportCase, getSharePlanApiErrorReportCase,
getSharePlanApiFailureCase, getSharePlanApiFailureCase,
getSharePlanApiUnExecuteCase getSharePlanApiUnExecuteCase,
} from "@/api/remote/plan/test-plan"; } from "@/api/remote/plan/test-plan";
import MsTable from "metersphere-frontend/src/components/table/MsTable"; import MsTable from "metersphere-frontend/src/components/table/MsTable";
import MsTableColumn from "metersphere-frontend/src/components/table/MsTableColumn"; import MsTableColumn from "metersphere-frontend/src/components/table/MsTableColumn";
import MsAsideContainer from "metersphere-frontend/src/components/MsAsideContainer"; import MsAsideContainer from "metersphere-frontend/src/components/MsAsideContainer";
import MsMainContainer from "metersphere-frontend/src/components/MsMainContainer"; import MsMainContainer from "metersphere-frontend/src/components/MsMainContainer";
import {getShareApiReport} from "@/api/share"; import { getShareApiReport, getShareApiReportByReportId } from "@/api/share";
import {apiDefinitionReportGet, apiDefinitionReportGetDb} from "@/api/remote/api/api-definition"; import {
apiDefinitionReportGet,
apiDefinitionReportGetDb,
} from "@/api/remote/api/api-definition";
import MicroApp from "metersphere-frontend/src/components/MicroApp"; import MicroApp from "metersphere-frontend/src/components/MicroApp";
import MsTestPlanApiStatus from "@/business/plan/view/comonents/api/TestPlanApiStatus"; import MsTestPlanApiStatus from "@/business/plan/view/comonents/api/TestPlanApiStatus";
@ -103,8 +117,13 @@ export default {
MsMainContainer, MsMainContainer,
MsAsideContainer, MsAsideContainer,
MicroApp, MicroApp,
MsTableColumn, MsTable, StatusTableItem, MethodTableItem, TypeTableItem, PriorityTableItem, MsTableColumn,
MsRequestResultTail MsTable,
StatusTableItem,
MethodTableItem,
TypeTableItem,
PriorityTableItem,
MsRequestResultTail,
}, },
props: { props: {
planId: String, planId: String,
@ -115,7 +134,7 @@ export default {
isAll: Boolean, isAll: Boolean,
isErrorReport: Boolean, isErrorReport: Boolean,
isUnExecute: Boolean, isUnExecute: Boolean,
isDb: Boolean isDb: Boolean,
}, },
data() { data() {
return { return {
@ -123,17 +142,17 @@ export default {
responseLoading: false, responseLoading: false,
loading: false, loading: false,
response: {}, response: {},
showResponse: false showResponse: false,
} };
}, },
watch: { watch: {
apiCases() { apiCases() {
if (this.apiCases) { if (this.apiCases) {
this.$emit('setSize', this.apiCases.length); this.$emit("setSize", this.apiCases.length);
} else { } else {
this.apiCases = []; this.apiCases = [];
} }
} },
}, },
mounted() { mounted() {
this.getScenarioApiCase(); this.getScenarioApiCase();
@ -142,76 +161,112 @@ export default {
getScenarioApiCase() { getScenarioApiCase() {
if (this.isTemplate || this.isDb) { if (this.isTemplate || this.isDb) {
if (this.isErrorReport) { if (this.isErrorReport) {
this.apiCases = this.report.errorReportCases ? this.report.errorReportCases : []; this.apiCases = this.report.errorReportCases
? this.report.errorReportCases
: [];
} else if (this.isUnExecute) { } else if (this.isUnExecute) {
this.apiCases = this.report.unExecuteCases ? this.report.unExecuteCases : []; this.apiCases = this.report.unExecuteCases
? this.report.unExecuteCases
: [];
} else if (this.isAll) { } else if (this.isAll) {
this.apiCases = this.report.apiAllCases ? this.report.apiAllCases : []; this.apiCases = this.report.apiAllCases
? this.report.apiAllCases
: [];
} else { } else {
this.apiCases = this.report.apiFailureCases ? this.report.apiFailureCases : []; this.apiCases = this.report.apiFailureCases
? this.report.apiFailureCases
: [];
} }
} else if (this.isShare) { } else if (this.isShare) {
if (this.isErrorReport) { if (this.isErrorReport) {
this.loading = true; this.loading = true;
getSharePlanApiErrorReportCase(this.shareId, this.planId) getSharePlanApiErrorReportCase(this.shareId, this.planId).then(
.then((r) => { (r) => {
this.loading = false; this.loading = false;
this.apiCases = r.data; this.apiCases = r.data;
}); }
);
} else if (this.isUnExecute) { } else if (this.isUnExecute) {
this.loading = true; this.loading = true;
getSharePlanApiUnExecuteCase(this.shareId, this.planId) getSharePlanApiUnExecuteCase(this.shareId, this.planId).then((r) => {
.then((r) => { this.loading = false;
this.loading = false; this.apiCases = r.data;
this.apiCases = r.data; });
});
} else if (this.isAll) { } else if (this.isAll) {
this.loading = true; this.loading = true;
getSharePlanApiAllCase(this.shareId, this.planId) getSharePlanApiAllCase(this.shareId, this.planId).then((r) => {
.then((r) => { this.loading = false;
this.loading = false; this.apiCases = r.data;
this.apiCases = r.data; });
});
} else { } else {
this.loading = true; this.loading = true;
getSharePlanApiFailureCase(this.shareId, this.planId) getSharePlanApiFailureCase(this.shareId, this.planId).then((r) => {
.then((r) => { this.loading = false;
this.loading = false; this.apiCases = r.data;
this.apiCases = r.data; });
});
} }
} else { } else {
if (this.isErrorReport) { if (this.isErrorReport) {
this.loading = true; this.loading = true;
getPlanApiErrorReportCase(this.planId) getPlanApiErrorReportCase(this.planId).then((r) => {
.then((r) => { this.loading = false;
this.loading = false; this.apiCases = r.data;
this.apiCases = r.data; });
});
} else if (this.isUnExecute) { } else if (this.isUnExecute) {
this.loading = true; this.loading = true;
getPlanApiUnExecuteCase(this.planId) getPlanApiUnExecuteCase(this.planId).then((r) => {
.then((r) => { this.loading = false;
this.loading = false; this.apiCases = r.data;
this.apiCases = r.data; });
});
} else if (this.isAll) { } else if (this.isAll) {
this.loading = true; this.loading = true;
getPlanApiAllCase(this.planId) getPlanApiAllCase(this.planId).then((r) => {
.then((r) => { this.loading = false;
this.loading = false; this.apiCases = r.data;
this.apiCases = r.data; });
});
} else { } else {
this.loading = true; this.loading = true;
getPlanApiFailureCase(this.planId) getPlanApiFailureCase(this.planId).then((r) => {
.then((r) => { this.loading = false;
this.loading = false; this.apiCases = r.data;
this.apiCases = r.data; });
});
} }
} }
}, },
selectReportContentByReportId(reportId) {
this.responseLoading = true;
apiDefinitionReportGet(reportId).then((response) => {
this.responseLoading = false;
if (response.data) {
let data = response.data;
if (data) {
this.showResponse = true;
try {
this.response = JSON.parse(data.content);
} catch (e) {
this.response = {};
}
}
}
});
},
selectShareReportContentByReportId(reportId) {
this.responseLoading = true;
getShareApiReportByReportId(reportId).then((response) => {
this.responseLoading = false;
if (response.data) {
let data = response.data;
if (data) {
this.showResponse = true;
try {
this.response = JSON.parse(data.content);
} catch (e) {
this.response = {};
}
}
}
});
},
rowClick(row) { rowClick(row) {
this.showResponse = false; this.showResponse = false;
this.$nextTick(() => { this.$nextTick(() => {
@ -221,9 +276,11 @@ export default {
this.response = JSON.parse(row.response); this.response = JSON.parse(row.response);
} }
} else if (this.isShare) { } else if (this.isShare) {
this.responseLoading = true; if (row.reportId) {
getShareApiReport(this.shareId, row.id) this.selectShareReportContentByReportId(row.reportId);
.then((r) => { } else {
this.responseLoading = true;
getShareApiReport(this.shareId, row.id).then((r) => {
this.responseLoading = false; this.responseLoading = false;
let data = r.data; let data = r.data;
if (data && data.content) { if (data && data.content) {
@ -231,49 +288,33 @@ export default {
this.response = JSON.parse(data.content); this.response = JSON.parse(data.content);
} }
}); });
}
} else { } else {
if (row.reportId) { if (row.reportId) {
this.responseLoading = true; this.selectReportContentByReportId(row.reportId);
apiDefinitionReportGet(row.reportId)
.then(response => {
this.responseLoading = false;
if (response.data) {
let data = response.data;
if (data) {
this.showResponse = true;
try {
this.response = JSON.parse(data.content);
} catch (e) {
this.response = {};
}
}
}
});
} else { } else {
this.responseLoading = true; this.responseLoading = true;
apiDefinitionReportGetDb(row.id) apiDefinitionReportGetDb(row.id).then((r) => {
.then((r) => { this.responseLoading = false;
this.responseLoading = false; let data = r.data;
let data = r.data; if (data && data.content) {
if (data && data.content) { this.showResponse = true;
this.showResponse = true; try {
try { this.response = JSON.parse(data.content);
this.response = JSON.parse(data.content); } catch (e) {
} catch (e) { this.response = {};
this.response = {};
}
} }
}); }
});
} }
} }
}); });
} },
} },
} };
</script> </script>
<style scoped> <style scoped>
.el-card :deep(.el-card__body) { .el-card :deep(.el-card__body) {
height: 550px; height: 550px;
} }