fix(ui报告): 修改ui报告的样式
--bug=1024353 --user=宋天阳 【测试跟踪】测试计划执行报告,UI报告展示没有对齐 https://www.tapd.cn/55049933/s/1349610
This commit is contained in:
parent
094ca0b791
commit
96d88ba2de
|
@ -3,78 +3,140 @@
|
|||
<el-row>
|
||||
<el-col>
|
||||
<span v-if="!debug">
|
||||
<el-input v-if="nameIsEdit" size="mini" @blur="handleSave(report.name)" @keyup.enter.native="handleSaveKeyUp"
|
||||
style="width: 200px" v-model="report.name" maxlength="60" show-word-limit/>
|
||||
<el-input
|
||||
v-if="nameIsEdit"
|
||||
size="mini"
|
||||
@blur="handleSave(report.name)"
|
||||
@keyup.enter.native="handleSaveKeyUp"
|
||||
style="width: 200px"
|
||||
v-model="report.name"
|
||||
maxlength="60"
|
||||
show-word-limit
|
||||
/>
|
||||
<span v-else>
|
||||
<router-link v-if="isSingleScenario"
|
||||
:to="{name: isUi ? 'uiAutomation' : 'ApiAutomation', params: { dataSelectRange: 'edit:' + scenarioId }}">
|
||||
<router-link
|
||||
v-if="isSingleScenario"
|
||||
:to="{
|
||||
name: isUi ? 'uiAutomation' : 'ApiAutomation',
|
||||
params: { dataSelectRange: 'edit:' + scenarioId },
|
||||
}"
|
||||
>
|
||||
{{ report.name }}
|
||||
</router-link>
|
||||
<span v-else>
|
||||
{{ report.name }}
|
||||
</span>
|
||||
<i v-if="showCancelButton" class="el-icon-edit" style="cursor:pointer" @click="nameIsEdit = true"
|
||||
@click.stop/>
|
||||
<i
|
||||
v-if="showCancelButton"
|
||||
class="el-icon-edit"
|
||||
style="cursor: pointer"
|
||||
@click="nameIsEdit = true"
|
||||
@click.stop
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
<span v-if="report.endTime || report.createTime">
|
||||
<span style="margin-left: 10px">{{ $t('report.test_start_time') }}:</span>
|
||||
<span style="margin-left: 10px"
|
||||
>{{ $t("report.test_start_time") }}:</span
|
||||
>
|
||||
<span class="time"> {{ report.createTime | datetimeFormat }}</span>
|
||||
<span style="margin-left: 10px">{{ $t('report.test_end_time') }}:</span>
|
||||
<span style="margin-left: 10px"
|
||||
>{{ $t("report.test_end_time") }}:</span
|
||||
>
|
||||
<span class="time"> {{ report.endTime | datetimeFormat }}</span>
|
||||
</span>
|
||||
<div style="float: right">
|
||||
<el-button v-if="!isPlan && (!debug || exportFlag) && !isTemplate && !isUi"
|
||||
v-permission="['PROJECT_API_REPORT:READ+EXPORT']" :disabled="isReadOnly" class="export-button"
|
||||
plain type="primary" size="mini" @click="handleExport(report.name)" style="margin-right: 10px">
|
||||
{{ $t('test_track.plan_view.export_report') }}
|
||||
<el-button
|
||||
v-if="!isPlan && (!debug || exportFlag) && !isTemplate && !isUi"
|
||||
v-permission="['PROJECT_API_REPORT:READ+EXPORT']"
|
||||
:disabled="isReadOnly"
|
||||
class="export-button"
|
||||
plain
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click="handleExport(report.name)"
|
||||
style="margin-right: 10px"
|
||||
>
|
||||
{{ $t("test_track.plan_view.export_report") }}
|
||||
</el-button>
|
||||
|
||||
<el-popover
|
||||
v-if="!isPlan && (!debug || exportFlag) && !isTemplate"
|
||||
v-permission="['PROJECT_PERFORMANCE_REPORT:READ+EXPORT']"
|
||||
style="margin-right: 10px;float: right;"
|
||||
style="margin-right: 10px; float: right"
|
||||
placement="bottom"
|
||||
width="300">
|
||||
width="300"
|
||||
>
|
||||
<p>{{ shareUrl }}</p>
|
||||
<span style="color: red;float: left;margin-left: 10px;" v-if="application.typeValue">{{
|
||||
$t('commons.validity_period') + application.typeValue
|
||||
}}</span>
|
||||
<span
|
||||
style="color: red; float: left; margin-left: 10px"
|
||||
v-if="application.typeValue"
|
||||
>{{ $t("commons.validity_period") + application.typeValue }}</span
|
||||
>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button type="primary" size="mini" :disabled="!shareUrl"
|
||||
v-clipboard:copy="shareUrl">{{ $t("commons.copy") }}
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
:disabled="!shareUrl"
|
||||
v-clipboard:copy="shareUrl"
|
||||
>{{ $t("commons.copy") }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button slot="reference" :disabled="isReadOnly" type="danger" plain size="mini"
|
||||
@click="handleShare(report)">
|
||||
{{ $t('test_track.plan_view.share_report') }}
|
||||
<el-button
|
||||
slot="reference"
|
||||
:disabled="isReadOnly"
|
||||
type="danger"
|
||||
plain
|
||||
size="mini"
|
||||
@click="handleShare(report)"
|
||||
>
|
||||
{{ $t("test_track.plan_view.share_report") }}
|
||||
</el-button>
|
||||
</el-popover>
|
||||
|
||||
<el-button v-if="showRerunButton" class="rerun-button" plain size="mini" @click="rerun">
|
||||
{{ $t('api_test.automation.rerun') }}
|
||||
<el-button
|
||||
v-if="showRerunButton"
|
||||
class="rerun-button"
|
||||
plain
|
||||
size="mini"
|
||||
@click="rerun"
|
||||
>
|
||||
{{ $t("api_test.automation.rerun") }}
|
||||
</el-button>
|
||||
|
||||
<el-button v-if="showCancelButton" class="export-button" plain size="mini" @click="returnView">
|
||||
{{ $t('commons.cancel') }}
|
||||
<el-button
|
||||
v-if="showCancelButton"
|
||||
class="export-button"
|
||||
plain
|
||||
size="mini"
|
||||
@click="returnView"
|
||||
>
|
||||
{{ $t("commons.cancel") }}
|
||||
</el-button>
|
||||
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row v-if="showProjectEnv" type="flex">
|
||||
<span> {{ $t('commons.environment') + ':' }} </span>
|
||||
<div v-for="(values,key) in projectEnvMap" :key="key" style="margin-right: 10px">
|
||||
<span> {{ $t("commons.environment") + ":" }} </span>
|
||||
<div
|
||||
v-for="(values, key) in projectEnvMap"
|
||||
:key="key"
|
||||
style="margin-right: 10px"
|
||||
>
|
||||
{{ key + ":" }}
|
||||
<ms-tag v-for="(item,index) in values" :key="index" type="success" :content="item"
|
||||
style="margin-left: 2px"/>
|
||||
<ms-tag
|
||||
v-for="(item, index) in values"
|
||||
:key="index"
|
||||
type="success"
|
||||
:content="item"
|
||||
style="margin-left: 2px"
|
||||
/>
|
||||
</div>
|
||||
</el-row>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { generateShareInfoWithExpired, getShareRedirectUrl } from "@/api/share";
|
||||
import MsTag from "metersphere-frontend/src/components/MsTag";
|
||||
import { getCurrentProjectID } from "@/business/utils/sdk-utils";
|
||||
|
@ -99,17 +161,17 @@ export default {
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
isPlan: Boolean
|
||||
isPlan: Boolean,
|
||||
},
|
||||
computed: {
|
||||
showProjectEnv() {
|
||||
return this.projectEnvMap && JSON.stringify(this.projectEnvMap) !== '{}';
|
||||
return this.projectEnvMap && JSON.stringify(this.projectEnvMap) !== "{}";
|
||||
},
|
||||
path() {
|
||||
return "/api/test/edit?id=" + this.report.testId;
|
||||
},
|
||||
scenarioId() {
|
||||
if (typeof this.report.scenarioId === 'string') {
|
||||
if (typeof this.report.scenarioId === "string") {
|
||||
return this.report.scenarioId;
|
||||
} else {
|
||||
return "";
|
||||
|
@ -132,46 +194,45 @@ export default {
|
|||
isReadOnly: false,
|
||||
nameIsEdit: false,
|
||||
shareUrl: "",
|
||||
application: {}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
application: {},
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
handleExport(name) {
|
||||
this.$emit('reportExport', name);
|
||||
this.$emit("reportExport", name);
|
||||
},
|
||||
handleSave(name) {
|
||||
this.nameIsEdit = false;
|
||||
this.$emit('reportSave', name);
|
||||
this.$emit("reportSave", name);
|
||||
},
|
||||
handleSaveKeyUp($event) {
|
||||
$event.target.blur();
|
||||
},
|
||||
rerun() {
|
||||
let type = this.report.reportType;
|
||||
let rerunObj = {type: type, reportId: this.report.id}
|
||||
this.$post('/api/test/exec/rerun', rerunObj, res => {
|
||||
if (res.data !== 'SUCCESS') {
|
||||
let rerunObj = { type: type, reportId: this.report.id };
|
||||
this.$post("/api/test/exec/rerun", rerunObj, (res) => {
|
||||
if (res.data !== "SUCCESS") {
|
||||
this.$error(res.data);
|
||||
} else {
|
||||
this.$success(this.$t('api_test.automation.rerun_success'));
|
||||
this.$success(this.$t("api_test.automation.rerun_success"));
|
||||
this.returnView();
|
||||
}
|
||||
});
|
||||
},
|
||||
returnView() {
|
||||
if (this.isUi) {
|
||||
this.$router.push('/ui/report');
|
||||
this.$router.push("/ui/report");
|
||||
} else {
|
||||
this.$router.push('/api/automation/report');
|
||||
this.$router.push("/api/automation/report");
|
||||
}
|
||||
},
|
||||
handleShare(report) {
|
||||
this.getProjectApplication();
|
||||
let pram = {};
|
||||
pram.customData = report.id;
|
||||
pram.shareType = 'UI_REPORT';
|
||||
pram.shareType = "UI_REPORT";
|
||||
let thisHost = window.location.host;
|
||||
generateShareInfoWithExpired(pram).then((res) => {
|
||||
this.shareUrl = getShareRedirectUrl(res.data);
|
||||
|
@ -182,29 +243,38 @@ export default {
|
|||
if (this.isUi) {
|
||||
path = "/UI_SHARE_REPORT_TIME";
|
||||
}
|
||||
this.$get('/project_application/get/' + getCurrentProjectID() + path).then(res => {
|
||||
this.$get(
|
||||
"/project_application/get/" + getCurrentProjectID() + path
|
||||
).then((res) => {
|
||||
if (res.data && res.data.typeValue) {
|
||||
let quantity = res.data.typeValue.substring(0, res.data.typeValue.length - 1);
|
||||
let unit = res.data.typeValue.substring(res.data.typeValue.length - 1);
|
||||
if (unit === 'H') {
|
||||
res.data.typeValue = quantity + this.$t('commons.date_unit.hour');
|
||||
} else if (unit === 'D') {
|
||||
res.data.typeValue = quantity + this.$t('commons.date_unit.day');
|
||||
} else if (unit === 'M') {
|
||||
res.data.typeValue = quantity + this.$t('commons.workspace_unit') + this.$t('commons.date_unit.month');
|
||||
} else if (unit === 'Y') {
|
||||
res.data.typeValue = quantity + this.$t('commons.date_unit.year');
|
||||
let quantity = res.data.typeValue.substring(
|
||||
0,
|
||||
res.data.typeValue.length - 1
|
||||
);
|
||||
let unit = res.data.typeValue.substring(
|
||||
res.data.typeValue.length - 1
|
||||
);
|
||||
if (unit === "H") {
|
||||
res.data.typeValue = quantity + this.$t("commons.date_unit.hour");
|
||||
} else if (unit === "D") {
|
||||
res.data.typeValue = quantity + this.$t("commons.date_unit.day");
|
||||
} else if (unit === "M") {
|
||||
res.data.typeValue =
|
||||
quantity +
|
||||
this.$t("commons.workspace_unit") +
|
||||
this.$t("commons.date_unit.month");
|
||||
} else if (unit === "Y") {
|
||||
res.data.typeValue = quantity + this.$t("commons.date_unit.year");
|
||||
}
|
||||
this.application = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.export-button {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
|
@ -213,7 +283,10 @@ export default {
|
|||
.rerun-button {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
background-color: #F2F9EF;
|
||||
color: #87C45D;
|
||||
background-color: #f2f9ef;
|
||||
color: #87c45d;
|
||||
}
|
||||
.report-header {
|
||||
min-width: 1200px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -10,129 +10,251 @@
|
|||
</el-row>
|
||||
|
||||
<div v-if="isExport">
|
||||
<span class="ms-req ms-req-error"
|
||||
v-if="(content.error && content.error>0 )|| (content.errorCode && content.errorCode>0)|| (content.unExecute && content.unExecute>0)">
|
||||
<span class="ms-req-span"> {{ content.success + content.error + content.errorCode + content.unExecute }} {{
|
||||
isUi ? '指令' : $t('api_report.request')
|
||||
}}</span>
|
||||
<span
|
||||
class="ms-req ms-req-error"
|
||||
v-if="
|
||||
(content.error && content.error > 0) ||
|
||||
(content.errorCode && content.errorCode > 0) ||
|
||||
(content.unExecute && content.unExecute > 0)
|
||||
"
|
||||
>
|
||||
<span class="ms-req-span">
|
||||
{{
|
||||
content.success +
|
||||
content.error +
|
||||
content.errorCode +
|
||||
content.unExecute
|
||||
}}
|
||||
{{ isUi ? "指令" : $t("api_report.request") }}</span
|
||||
>
|
||||
</span>
|
||||
<span class="ms-req ms-req-success" v-else>
|
||||
<span class="ms-req-span"> {{
|
||||
content.success ? content.success + content.error : 0
|
||||
}} {{ isUi ? '指令' : $t('api_report.request') }}</span>
|
||||
<span class="ms-req-span">
|
||||
{{ content.success ? content.success + content.error : 0 }}
|
||||
{{ isUi ? "指令" : $t("api_report.request") }}</span
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
<ms-chart id="chart" ref="chart" :options="options" :height="220" style="margin-right: 10px"
|
||||
:autoresize="true" v-else/>
|
||||
<el-row type="flex" justify="center" align="middle" style="width: 150px">
|
||||
<ms-chart
|
||||
id="chart"
|
||||
ref="chart"
|
||||
:options="options"
|
||||
:height="220"
|
||||
style="margin-right: 10px"
|
||||
:autoresize="true"
|
||||
v-else
|
||||
/>
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
align="middle"
|
||||
style="width: 150px"
|
||||
>
|
||||
<div>
|
||||
<div class="metric-icon-box" style="height: 26px">
|
||||
<span class="ms-point-success" style="margin: 7px;float: left;"/>
|
||||
<span
|
||||
class="ms-point-success"
|
||||
style="margin: 7px; float: left"
|
||||
/>
|
||||
<div class="metric-box">
|
||||
<div class="value" style="font-size: 12px">{{ content.success }} {{ $t('api_report.success') }}</div>
|
||||
<div class="value" style="font-size: 12px">
|
||||
{{ content.success }} {{ $t("api_report.success") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider></el-divider>
|
||||
<div class="metric-icon-box" style="height: 26px">
|
||||
<span class="ms-point-error" style="margin: 7px;float: left;"/>
|
||||
<span class="ms-point-error" style="margin: 7px; float: left" />
|
||||
<div class="metric-box">
|
||||
<div class="value" style="font-size: 12px">{{ content.error }} {{ $t('api_report.fail') }}</div>
|
||||
<div class="value" style="font-size: 12px">
|
||||
{{ content.error }} {{ $t("api_report.fail") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider v-if="content.errorCode > 0"></el-divider>
|
||||
<div class="metric-icon-box" v-if="content.errorCode > 0" style="height: 26px">
|
||||
<span class="ms-point-error-code" style="margin: 7px;float: left;"/>
|
||||
<div
|
||||
class="metric-icon-box"
|
||||
v-if="content.errorCode > 0"
|
||||
style="height: 26px"
|
||||
>
|
||||
<span
|
||||
class="ms-point-error-code"
|
||||
style="margin: 7px; float: left"
|
||||
/>
|
||||
<div class="metric-box" v-if="content.errorCode > 0">
|
||||
<div class="value" style="font-size: 12px">{{ content.errorCode }}
|
||||
{{ $t('error_report_library.option.name') }}
|
||||
<div class="value" style="font-size: 12px">
|
||||
{{ content.errorCode }}
|
||||
{{ $t("error_report_library.option.name") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-divider v-if="content.unExecute > 0"></el-divider>
|
||||
<div class="metric-icon-box" style="height: 26px" v-if="content.unExecute > 0">
|
||||
<span class="ms-point-unexecute" style="margin: 7px;float: left;"/>
|
||||
<div
|
||||
class="metric-icon-box"
|
||||
style="height: 26px"
|
||||
v-if="content.unExecute > 0"
|
||||
>
|
||||
<span
|
||||
class="ms-point-unexecute"
|
||||
style="margin: 7px; float: left"
|
||||
/>
|
||||
<div class="metric-box">
|
||||
<div class="value" style="font-size: 12px">{{ content.unExecute }}
|
||||
{{ $t('api_test.home_page.detail_card.unexecute') }}
|
||||
<div class="value" style="font-size: 12px">
|
||||
{{ content.unExecute }}
|
||||
{{ $t("api_test.home_page.detail_card.unexecute") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</el-row>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="split"></div>
|
||||
<!-- 场景统计 -->
|
||||
<div style="width: 50%">
|
||||
<el-row type="flex" justify="center" align="middle" v-if="report.reportType !== 'API_INTEGRATED'">
|
||||
<el-row
|
||||
type="flex"
|
||||
justify="center"
|
||||
align="middle"
|
||||
v-if="report.reportType !== 'API_INTEGRATED'"
|
||||
>
|
||||
<div class="metric-box">
|
||||
<div class="value">{{ content.scenarioTotal ? content.scenarioTotal : 0 }}</div>
|
||||
<div class="name">{{ $t('api_test.scenario.scenario') }}</div>
|
||||
<div class="value">
|
||||
{{ content.scenarioTotal ? content.scenarioTotal : 0 }}
|
||||
</div>
|
||||
<div class="name">{{ $t("api_test.scenario.scenario") }}</div>
|
||||
</div>
|
||||
<span class="ms-point-success" />
|
||||
<div class="metric-box">
|
||||
<div class="value">{{ content.scenarioSuccess ? content.scenarioSuccess : 0 }}</div>
|
||||
<div class="name">{{ $t('api_report.success') }}</div>
|
||||
<div class="value">
|
||||
{{ content.scenarioSuccess ? content.scenarioSuccess : 0 }}
|
||||
</div>
|
||||
<div class="name">{{ $t("api_report.success") }}</div>
|
||||
</div>
|
||||
<span class="ms-point-error" />
|
||||
<div class="metric-box">
|
||||
<div class="value">{{ content.scenarioError ? content.scenarioError : 0 }}</div>
|
||||
<div class="name">{{ $t('api_report.fail') }}</div>
|
||||
<div class="value">
|
||||
{{ content.scenarioError ? content.scenarioError : 0 }}
|
||||
</div>
|
||||
<span class="ms-point-error-code"
|
||||
v-if="content.scenarioErrorReport > 0 || content.scenarioStepErrorReport > 0 "/>
|
||||
<div class="metric-box" v-if="content.scenarioErrorReport > 0 || content.scenarioStepErrorReport > 0 ">
|
||||
<div class="value">{{ content.scenarioErrorReport ? content.scenarioErrorReport : 0 }}</div>
|
||||
<div class="name">{{ $t('error_report_library.option.name') }}</div>
|
||||
<div class="name">{{ $t("api_report.fail") }}</div>
|
||||
</div>
|
||||
<span
|
||||
class="ms-point-error-code"
|
||||
v-if="
|
||||
content.scenarioErrorReport > 0 ||
|
||||
content.scenarioStepErrorReport > 0
|
||||
"
|
||||
/>
|
||||
<div
|
||||
class="metric-box"
|
||||
v-if="
|
||||
content.scenarioErrorReport > 0 ||
|
||||
content.scenarioStepErrorReport > 0
|
||||
"
|
||||
>
|
||||
<div class="value">
|
||||
{{
|
||||
content.scenarioErrorReport ? content.scenarioErrorReport : 0
|
||||
}}
|
||||
</div>
|
||||
<div class="name">{{ $t("error_report_library.option.name") }}</div>
|
||||
</div>
|
||||
<span v-show="showUnExecuteReport" class="ms-point-unexecute" />
|
||||
<div v-show="showUnExecuteReport" class="metric-box">
|
||||
<div class="value">{{ content.scenarioUnExecute ? content.scenarioUnExecute : 0 }}</div>
|
||||
<div class="name">{{ $t('api_test.home_page.detail_card.unexecute') }}</div>
|
||||
<div class="value">
|
||||
{{ content.scenarioUnExecute ? content.scenarioUnExecute : 0 }}
|
||||
</div>
|
||||
<div class="name">
|
||||
{{ $t("api_test.home_page.detail_card.unexecute") }}
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-divider v-if="report.reportType !== 'API_INTEGRATED'" />
|
||||
<el-row type="flex" justify="center" align="middle">
|
||||
<el-row type="flex" justify="center" align="middle">
|
||||
<div class="metric-box">
|
||||
<div class="value">{{ content.scenarioStepTotal ? content.scenarioStepTotal : 0 }}</div>
|
||||
<div class="name" v-if="report.reportType === 'API_INTEGRATED'">
|
||||
{{ $t('api_test.definition.request.case') }}
|
||||
<div class="value">
|
||||
{{ content.scenarioStepTotal ? content.scenarioStepTotal : 0 }}
|
||||
</div>
|
||||
<div class="name" v-if="report.reportType === 'API_INTEGRATED'">
|
||||
{{ $t("api_test.definition.request.case") }}
|
||||
</div>
|
||||
<div class="name" v-else>
|
||||
{{ $t("test_track.plan_view.step") }}
|
||||
</div>
|
||||
<div class="name" v-else>{{ $t('test_track.plan_view.step') }}</div>
|
||||
</div>
|
||||
<span class="ms-point-success" />
|
||||
<div class="metric-box">
|
||||
<div class="value">{{ content.scenarioStepSuccess ? content.scenarioStepSuccess : 0 }}</div>
|
||||
<div class="name">{{ $t('api_report.success') }}</div>
|
||||
<div class="value">
|
||||
{{
|
||||
content.scenarioStepSuccess ? content.scenarioStepSuccess : 0
|
||||
}}
|
||||
</div>
|
||||
<div class="name">{{ $t("api_report.success") }}</div>
|
||||
</div>
|
||||
<span class="ms-point-error" />
|
||||
<div class="metric-box">
|
||||
<div class="value">{{ content.scenarioStepError ? content.scenarioStepError : 0 }}</div>
|
||||
<div class="name">{{ $t('api_report.fail') }}</div>
|
||||
<div class="value">
|
||||
{{ content.scenarioStepError ? content.scenarioStepError : 0 }}
|
||||
</div>
|
||||
<span class="ms-point-error-code"
|
||||
v-if="content.scenarioErrorReport > 0 || content.scenarioStepErrorReport > 0 "/>
|
||||
<div class="metric-box" v-if="content.scenarioErrorReport > 0 || content.scenarioStepErrorReport > 0 ">
|
||||
<div class="value">{{ content.scenarioStepErrorReport ? content.scenarioStepErrorReport : 0 }}</div>
|
||||
<div class="name">{{ $t('error_report_library.option.name') }}</div>
|
||||
<div class="name">{{ $t("api_report.fail") }}</div>
|
||||
</div>
|
||||
<span v-show="showUnExecuteReport && !isUi" class="ms-point-unexecute"/>
|
||||
<span
|
||||
class="ms-point-error-code"
|
||||
v-if="
|
||||
content.scenarioErrorReport > 0 ||
|
||||
content.scenarioStepErrorReport > 0
|
||||
"
|
||||
/>
|
||||
<div
|
||||
class="metric-box"
|
||||
v-if="
|
||||
content.scenarioErrorReport > 0 ||
|
||||
content.scenarioStepErrorReport > 0
|
||||
"
|
||||
>
|
||||
<div class="value">
|
||||
{{
|
||||
content.scenarioStepErrorReport
|
||||
? content.scenarioStepErrorReport
|
||||
: 0
|
||||
}}
|
||||
</div>
|
||||
<div class="name">
|
||||
{{ $t("error_report_library.option.name") }}
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
v-show="showUnExecuteReport && !isUi"
|
||||
class="ms-point-unexecute"
|
||||
/>
|
||||
<div v-show="showUnExecuteReport && !isUi" class="metric-box">
|
||||
<div class="value">{{
|
||||
content.scenarioStepUnExecuteReport ? content.scenarioStepUnExecuteReport : 0
|
||||
<div class="value">
|
||||
{{
|
||||
content.scenarioStepUnExecuteReport
|
||||
? content.scenarioStepUnExecuteReport
|
||||
: 0
|
||||
}}
|
||||
</div>
|
||||
<div class="name">{{ $t('api_test.home_page.detail_card.unexecute') }}</div>
|
||||
<div class="name">
|
||||
{{ $t("api_test.home_page.detail_card.unexecute") }}
|
||||
</div>
|
||||
<span v-show="showUnExecuteReport && isUi" class="ms-point-unexecute"/>
|
||||
</div>
|
||||
<span
|
||||
v-show="showUnExecuteReport && isUi"
|
||||
class="ms-point-unexecute"
|
||||
/>
|
||||
<div v-show="showUnExecuteReport && isUi" class="metric-box">
|
||||
<div class="value">{{
|
||||
content.scenarioStepUnExecuteReport ? content.scenarioStepUnExecuteReport : 0
|
||||
<div class="value">
|
||||
{{
|
||||
content.scenarioStepUnExecuteReport
|
||||
? content.scenarioStepUnExecuteReport
|
||||
: 0
|
||||
}}
|
||||
</div>
|
||||
<div class="name">{{ $t('api_test.home_page.detail_card.unexecute') }}</div>
|
||||
<div class="name">
|
||||
{{ $t("api_test.home_page.detail_card.unexecute") }}
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
</el-row>
|
||||
|
@ -144,22 +266,24 @@
|
|||
<div class="metric-icon-box">
|
||||
<i class="el-icon-warning-outline fail"></i>
|
||||
<div class="value">{{ fail }}</div>
|
||||
<div class="name">{{ $t('api_report.fail') }}</div>
|
||||
<div class="name">{{ $t("api_report.fail") }}</div>
|
||||
</div>
|
||||
<div class="metric-icon-box">
|
||||
<i class="el-icon-document-checked assertions"></i>
|
||||
<div class="value">{{ assertions }}</div>
|
||||
<div class="name">{{ $t('api_report.assertions_pass') }}</div>
|
||||
<div class="name">{{ $t("api_report.assertions_pass") }}</div>
|
||||
</div>
|
||||
<div class="metric-icon-box" v-if="content.errorCode > 0">
|
||||
<i class="el-icon-document-checked assertions"></i>
|
||||
<div class="value">{{ errorCodeAssertions }}</div>
|
||||
<div class="name">{{ $t('error_report_library.assertion') }}</div>
|
||||
<div class="name">{{ $t("error_report_library.assertion") }}</div>
|
||||
</div>
|
||||
<div class="metric-icon-box" v-if="!isUi">
|
||||
<i class="el-icon-document-copy total"></i>
|
||||
<div class="value">{{ this.content.total }}</div>
|
||||
<div class="name">{{ isUi ? '指令' : $t('api_report.request') }}</div>
|
||||
<div class="name">
|
||||
{{ isUi ? "指令" : $t("api_report.request") }}
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
|
@ -180,7 +304,7 @@ export default {
|
|||
isExport: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -192,7 +316,7 @@ export default {
|
|||
scenarioSuccess: 0,
|
||||
scenarioError: 0,
|
||||
reqTotal: 0,
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.initTime();
|
||||
|
@ -200,25 +324,25 @@ export default {
|
|||
methods: {
|
||||
initTime() {
|
||||
this.time = this.totalTime;
|
||||
this.seconds = (this.time) / 1000;
|
||||
this.seconds = this.time / 1000;
|
||||
if (this.seconds >= 1) {
|
||||
if (this.seconds < 60) {
|
||||
this.seconds = Math.round(this.seconds * 100 / 1) / 100;
|
||||
this.time = this.seconds + "s"
|
||||
this.seconds = Math.round((this.seconds * 100) / 1) / 100;
|
||||
this.time = this.seconds + "s";
|
||||
}
|
||||
if (this.seconds > 60) {
|
||||
this.minutes = Math.round(this.seconds / 60)
|
||||
this.seconds = Math.round(this.seconds * 100 % 60) / 100;
|
||||
this.time = this.minutes + "min" + this.seconds + "s"
|
||||
this.minutes = Math.round(this.seconds / 60);
|
||||
this.seconds = Math.round((this.seconds * 100) % 60) / 100;
|
||||
this.time = this.minutes + "min" + this.seconds + "s";
|
||||
}
|
||||
if (this.minutes > 60) {
|
||||
this.hour = Math.round(this.minutes / 60)
|
||||
this.minutes = Math.round(this.minutes % 60)
|
||||
this.time = this.hour + "hour" + this.minutes + "min" + this.seconds + "s"
|
||||
this.hour = Math.round(this.minutes / 60);
|
||||
this.minutes = Math.round(this.minutes % 60);
|
||||
this.time =
|
||||
this.hour + "hour" + this.minutes + "min" + this.seconds + "s";
|
||||
}
|
||||
|
||||
} else {
|
||||
this.time = this.totalTime + "ms"
|
||||
this.time = this.totalTime + "ms";
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -241,36 +365,38 @@ export default {
|
|||
},
|
||||
options() {
|
||||
return {
|
||||
color: ['#67C23A', '#F56C6C', '#F6972A', '#9C9B9A'],
|
||||
color: ["#67C23A", "#F56C6C", "#F6972A", "#9C9B9A"],
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{b}: {c} ({d}%)'
|
||||
trigger: "item",
|
||||
formatter: "{b}: {c} ({d}%)",
|
||||
},
|
||||
title: [{
|
||||
title: [
|
||||
{
|
||||
text: this.totalCount,
|
||||
subtext: this.isUi ? '指令' : this.$t('api_report.request'),
|
||||
top: 'center',
|
||||
left: 'center',
|
||||
subtext: this.isUi ? "指令" : this.$t("api_report.request"),
|
||||
top: "center",
|
||||
left: "center",
|
||||
textStyle: {
|
||||
rich: {
|
||||
align: 'center',
|
||||
align: "center",
|
||||
value: {
|
||||
fontSize: 32,
|
||||
fontWeight: 'bold',
|
||||
padding: [10, 0]
|
||||
fontWeight: "bold",
|
||||
padding: [10, 0],
|
||||
},
|
||||
name: {
|
||||
fontSize: 14,
|
||||
fontWeight: 'normal',
|
||||
color: '#7F7F7F',
|
||||
}
|
||||
}
|
||||
}
|
||||
}],
|
||||
fontWeight: "normal",
|
||||
color: "#7F7F7F",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['80%', '90%'],
|
||||
type: "pie",
|
||||
radius: ["80%", "90%"],
|
||||
avoidLabelOverlap: false,
|
||||
hoverAnimation: false,
|
||||
label: {
|
||||
|
@ -278,24 +404,33 @@ export default {
|
|||
},
|
||||
itemStyle: {
|
||||
borderColor: "#FFF",
|
||||
shadowColor: '#E1E1E1',
|
||||
shadowBlur: 10
|
||||
shadowColor: "#E1E1E1",
|
||||
shadowBlur: 10,
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
data: [
|
||||
{value: this.content.success, name: this.$t('api_report.success')},
|
||||
{value: this.content.error, name: this.$t('api_report.fail')},
|
||||
{value: this.content.errorCode, name: this.$t('error_report_library.option.name')},
|
||||
{value: this.content.unExecute, name: this.$t('api_test.home_page.detail_card.unexecute')},
|
||||
]
|
||||
}
|
||||
]
|
||||
{
|
||||
value: this.content.success,
|
||||
name: this.$t("api_report.success"),
|
||||
},
|
||||
{ value: this.content.error, name: this.$t("api_report.fail") },
|
||||
{
|
||||
value: this.content.errorCode,
|
||||
name: this.$t("error_report_library.option.name"),
|
||||
},
|
||||
{
|
||||
value: this.content.unExecute,
|
||||
name: this.$t("api_test.home_page.detail_card.unexecute"),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
fail() {
|
||||
return (this.content.error / this.content.total * 100).toFixed(0) + "%";
|
||||
return ((this.content.error / this.content.total) * 100).toFixed(0) + "%";
|
||||
},
|
||||
assertions() {
|
||||
return this.content.passAssertions + " / " + this.content.totalAssertions;
|
||||
|
@ -307,16 +442,22 @@ export default {
|
|||
return this.report.reportType && this.report.reportType.startsWith("UI");
|
||||
},
|
||||
showUnExecuteReport() {
|
||||
return (this.content.scenarioStepUnExecuteReport && this.content.scenarioStepUnExecuteReport > 0)
|
||||
|| (this.content.scenarioUnExecute && this.content.scenarioUnExecute > 0) || (this.content.unExecute && this.content.unExecute > 0);
|
||||
return (
|
||||
(this.content.scenarioStepUnExecuteReport &&
|
||||
this.content.scenarioStepUnExecuteReport > 0) ||
|
||||
(this.content.scenarioUnExecute &&
|
||||
this.content.scenarioUnExecute > 0) ||
|
||||
(this.content.unExecute && this.content.unExecute > 0)
|
||||
);
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.metric-container {
|
||||
padding: 5px 10px;
|
||||
min-width: 1200px;
|
||||
}
|
||||
|
||||
.metric-container #chart {
|
||||
|
@ -328,25 +469,25 @@ export default {
|
|||
.metric-container .split {
|
||||
margin: 20px;
|
||||
height: 100px;
|
||||
border-left: 1px solid #D8DBE1;
|
||||
border-left: 1px solid #d8dbe1;
|
||||
}
|
||||
|
||||
.metric-container .circle {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 20px 1px rgba(200, 216, 226, .42);
|
||||
box-shadow: 0 0 20px 1px rgba(200, 216, 226, 0.42);
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.metric-container .circle.success {
|
||||
background-color: #67C23A;
|
||||
background-color: #67c23a;
|
||||
}
|
||||
|
||||
.metric-container .circle.fail {
|
||||
background-color: #F56C6C;
|
||||
background-color: #f56c6c;
|
||||
}
|
||||
|
||||
.metric-box {
|
||||
|
@ -358,18 +499,18 @@ export default {
|
|||
.metric-box .value {
|
||||
font-size: 32px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -.5px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.metric-time .value {
|
||||
font-size: 25px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -.5px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
|
||||
.metric-box .name {
|
||||
font-size: 16px;
|
||||
letter-spacing: -.2px;
|
||||
letter-spacing: -0.2px;
|
||||
color: #404040;
|
||||
}
|
||||
|
||||
|
@ -381,7 +522,7 @@ export default {
|
|||
.metric-icon-box .value {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -.4px;
|
||||
letter-spacing: -0.4px;
|
||||
line-height: 28px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
@ -389,12 +530,12 @@ export default {
|
|||
.metric-icon-box .name {
|
||||
font-size: 13px;
|
||||
letter-spacing: 1px;
|
||||
color: #BFBFBF;
|
||||
color: #bfbfbf;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.metric-icon-box .fail {
|
||||
color: #F56C6C;
|
||||
color: #f56c6c;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
|
@ -416,11 +557,11 @@ export default {
|
|||
}
|
||||
|
||||
.ms-req-error {
|
||||
border: 5px #F56C6C solid;
|
||||
border: 5px #f56c6c solid;
|
||||
}
|
||||
|
||||
.ms-req-success {
|
||||
border: 5px #67C23A solid;
|
||||
border: 5px #67c23a solid;
|
||||
}
|
||||
|
||||
.ms-req-span {
|
||||
|
@ -440,7 +581,7 @@ export default {
|
|||
vertical-align: top;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
background-color: #67C23A;
|
||||
background-color: #67c23a;
|
||||
}
|
||||
|
||||
.ms-point-error {
|
||||
|
@ -452,7 +593,7 @@ export default {
|
|||
vertical-align: top;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
background-color: #F56C6C;
|
||||
background-color: #f56c6c;
|
||||
}
|
||||
|
||||
.ms-point-error-code {
|
||||
|
@ -464,7 +605,7 @@ export default {
|
|||
vertical-align: top;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
background-color: #F6972A;
|
||||
background-color: #f6972a;
|
||||
}
|
||||
|
||||
.ms-point-unexecute {
|
||||
|
@ -476,6 +617,6 @@ export default {
|
|||
vertical-align: top;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
background-color: #9C9B9A;
|
||||
background-color: #9c9b9a;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -13,14 +13,22 @@
|
|||
:report="report"
|
||||
:project-env-map="projectEnvMap"
|
||||
@reportExport="handleExport"
|
||||
@reportSave="handleSave"/>
|
||||
@reportSave="handleSave"
|
||||
/>
|
||||
|
||||
<!-- content -->
|
||||
<main v-if="isNotRunning">
|
||||
<!-- content header chart -->
|
||||
<ms-metric-chart :content="content" :totalTime="totalTime" :report="report"/>
|
||||
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<ms-metric-chart
|
||||
:content="content"
|
||||
:totalTime="totalTime"
|
||||
:report="report"
|
||||
/>
|
||||
<el-tabs
|
||||
v-model="activeName"
|
||||
@tab-click="handleClick"
|
||||
style="min-width: 1200px"
|
||||
>
|
||||
<!-- all step-->
|
||||
<el-tab-pane :label="$t('api_report.total')" name="total">
|
||||
<ms-scenario-results
|
||||
|
@ -31,12 +39,13 @@
|
|||
:is-share="isShare"
|
||||
:share-id="shareId"
|
||||
v-on:requestResult="requestResult"
|
||||
ref="resultsTree"/>
|
||||
ref="resultsTree"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<!-- fail step -->
|
||||
<el-tab-pane name="fail">
|
||||
<template slot="label">
|
||||
<span class="fail">{{ $t('api_report.fail') }}</span>
|
||||
<span class="fail">{{ $t("api_report.fail") }}</span>
|
||||
</template>
|
||||
<ms-scenario-results
|
||||
v-on:requestResult="requestResult"
|
||||
|
@ -45,14 +54,16 @@
|
|||
:is-share="isShare"
|
||||
:is-template="isTemplate"
|
||||
:share-id="shareId"
|
||||
:treeData="fullTreeNodes" ref="failsTree"
|
||||
:errorReport="content.error"/>
|
||||
:treeData="fullTreeNodes"
|
||||
ref="failsTree"
|
||||
:errorReport="content.error"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<!--error step -->
|
||||
<el-tab-pane name="errorReport" v-if="content.errorCode > 0">
|
||||
<template slot="label">
|
||||
<span class="fail" style="color: #F6972A">
|
||||
{{ $t('error_report_library.option.name') }}
|
||||
<span class="fail" style="color: #f6972a">
|
||||
{{ $t("error_report_library.option.name") }}
|
||||
</span>
|
||||
</template>
|
||||
<ms-scenario-results
|
||||
|
@ -62,14 +73,15 @@
|
|||
:is-template="isTemplate"
|
||||
:share-id="shareId"
|
||||
:console="content.console"
|
||||
:treeData="fullTreeNodes" ref="errorReportTree"/>
|
||||
:treeData="fullTreeNodes"
|
||||
ref="errorReportTree"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<!-- Not performed step -->
|
||||
<el-tab-pane name="unExecute" v-if="content.unExecute > 0">
|
||||
<template slot="label">
|
||||
<span class="fail"
|
||||
style="color: #9C9B9A">
|
||||
{{ $t('api_test.home_page.detail_card.unexecute') }}
|
||||
<span class="fail" style="color: #9c9b9a">
|
||||
{{ $t("api_test.home_page.detail_card.unexecute") }}
|
||||
</span>
|
||||
</template>
|
||||
<ms-scenario-results
|
||||
|
@ -79,18 +91,23 @@
|
|||
:is-template="isTemplate"
|
||||
:share-id="shareId"
|
||||
:console="content.console"
|
||||
:treeData="fullTreeNodes" ref="unExecuteTree"/>
|
||||
:treeData="fullTreeNodes"
|
||||
ref="unExecuteTree"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<!-- console -->
|
||||
<el-tab-pane name="console">
|
||||
<template slot="label">
|
||||
<span class="console">{{ $t('api_test.definition.request.console') }}</span>
|
||||
<span class="console">{{
|
||||
$t("api_test.definition.request.console")
|
||||
}}</span>
|
||||
</template>
|
||||
<ms-code-edit
|
||||
:mode="'text'"
|
||||
:read-only="true"
|
||||
:data.sync="content.console"
|
||||
height="calc(100vh - 500px)"/>
|
||||
height="calc(100vh - 500px)"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</main>
|
||||
|
@ -101,7 +118,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import MsRequestResult from "./RequestResult";
|
||||
import MsRequestResultTail from "./RequestResultTail";
|
||||
import MsScenarioResult from "./ScenarioResult";
|
||||
|
@ -112,8 +128,17 @@ import MsMainContainer from "metersphere-frontend/src/components/MsMainContainer
|
|||
import MsApiReportViewHeader from "./ApiReportViewHeader";
|
||||
import { STEP } from "./Setting";
|
||||
import MsCodeEdit from "metersphere-frontend/src/components/MsCodeEdit";
|
||||
import {getCurrentProjectID, getUUID, hasLicense, windowPrint} from "@/business/utils/sdk-utils";
|
||||
import {getScenarioReport, getScenarioReportAll, getShareScenarioReport} from "@/api/ui-report";
|
||||
import {
|
||||
getCurrentProjectID,
|
||||
getUUID,
|
||||
hasLicense,
|
||||
windowPrint,
|
||||
} from "@/business/utils/sdk-utils";
|
||||
import {
|
||||
getScenarioReport,
|
||||
getScenarioReportAll,
|
||||
getShareScenarioReport,
|
||||
} from "@/api/ui-report";
|
||||
|
||||
export default {
|
||||
name: "UiShareReportDetail",
|
||||
|
@ -121,7 +146,12 @@ export default {
|
|||
MsApiReportViewHeader,
|
||||
MsMainContainer,
|
||||
MsCodeEdit,
|
||||
MsContainer, MsScenarioResults, MsRequestResultTail, MsMetricChart, MsScenarioResult, MsRequestResult
|
||||
MsContainer,
|
||||
MsScenarioResults,
|
||||
MsRequestResultTail,
|
||||
MsMetricChart,
|
||||
MsScenarioResult,
|
||||
MsRequestResult,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -139,11 +169,11 @@ export default {
|
|||
reportExportVisible: false,
|
||||
fullTreeNodes: [],
|
||||
showRerunButton: false,
|
||||
stepFilter: new STEP,
|
||||
stepFilter: new STEP(),
|
||||
exportReportIsOk: false,
|
||||
tempResult: [],
|
||||
projectEnvMap: {},
|
||||
}
|
||||
};
|
||||
},
|
||||
activated() {
|
||||
this.isRequestResult = false;
|
||||
|
@ -160,8 +190,8 @@ export default {
|
|||
isPlan: Boolean,
|
||||
showCancelButton: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
reportId() {
|
||||
|
@ -173,7 +203,7 @@ export default {
|
|||
if (this.isTemplate) {
|
||||
this.getReport();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
filter(index) {
|
||||
|
@ -198,20 +228,32 @@ export default {
|
|||
this.showRerunButton = false;
|
||||
},
|
||||
rerunVerify() {
|
||||
if (hasLicense() && this.fullTreeNodes && this.fullTreeNodes.length > 0 && !this.isShare) {
|
||||
this.fullTreeNodes.forEach(item => {
|
||||
if (
|
||||
hasLicense() &&
|
||||
this.fullTreeNodes &&
|
||||
this.fullTreeNodes.length > 0 &&
|
||||
!this.isShare
|
||||
) {
|
||||
this.fullTreeNodes.forEach((item) => {
|
||||
item.redirect = true;
|
||||
if (item.totalStatus === 'fail' || item.totalStatus === 'error' || item.unExecuteTotal > 0
|
||||
|| (item.type === "API" && item.totalStatus === 'unexecute')) {
|
||||
if (
|
||||
item.totalStatus === "fail" ||
|
||||
item.totalStatus === "error" ||
|
||||
item.unExecuteTotal > 0 ||
|
||||
(item.type === "API" && item.totalStatus === "unexecute")
|
||||
) {
|
||||
this.showRerunButton = true;
|
||||
}
|
||||
}
|
||||
)
|
||||
});
|
||||
}
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
this.isRequestResult = false;
|
||||
if (this.report && this.report.reportVersion && this.report.reportVersion > 1) {
|
||||
if (
|
||||
this.report &&
|
||||
this.report.reportVersion &&
|
||||
this.report.reportVersion > 1
|
||||
) {
|
||||
this.filter(tab.index);
|
||||
}
|
||||
},
|
||||
|
@ -219,28 +261,28 @@ export default {
|
|||
this.isActive = !this.isActive;
|
||||
},
|
||||
formatResult(res) {
|
||||
let resMap = new Map;
|
||||
let resMap = new Map();
|
||||
let array = [];
|
||||
if (res && res.scenarios) {
|
||||
res.scenarios.forEach(item => {
|
||||
res.scenarios.forEach((item) => {
|
||||
if (item && item.requestResults) {
|
||||
item.requestResults.forEach(req => {
|
||||
item.requestResults.forEach((req) => {
|
||||
req.responseResult.console = res.console;
|
||||
resMap.set(req.id + req.name, req);
|
||||
req.name = item.name + "^@~@^" + req.name + "UUID=" + getUUID();
|
||||
array.push(req);
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
this.formatTree(array, this.fullTreeNodes);
|
||||
this.sort(this.fullTreeNodes);
|
||||
this.$emit('refresh', resMap);
|
||||
this.$emit("refresh", resMap);
|
||||
},
|
||||
formatTree(array, tree) {
|
||||
array.map((item) => {
|
||||
let key = item.name;
|
||||
let nodeArray = key.split('^@~@^');
|
||||
let nodeArray = key.split("^@~@^");
|
||||
let children = tree;
|
||||
//运行场景中如果连续将1个场景引入多次,会出现运行结果合并的情况。
|
||||
//为了解决这种问题,在转hashTree的时候给场景放了个新ID,前台加载解析的时候也要做处理
|
||||
|
@ -263,11 +305,13 @@ export default {
|
|||
label: nodeArray[i],
|
||||
value: item,
|
||||
};
|
||||
if (i !== (nodeArray.length - 1)) {
|
||||
if (i !== nodeArray.length - 1) {
|
||||
node.children = [];
|
||||
} else {
|
||||
if (item.subRequestResults && item.subRequestResults.length > 0) {
|
||||
let itemChildren = this.deepFormatTreeNode(item.subRequestResults);
|
||||
let itemChildren = this.deepFormatTreeNode(
|
||||
item.subRequestResults
|
||||
);
|
||||
node.children = itemChildren;
|
||||
if (node.label.indexOf("UUID=")) {
|
||||
node.label = node.label.split("UUID=")[0];
|
||||
|
@ -281,7 +325,6 @@ export default {
|
|||
let isExist = false;
|
||||
for (let j in children) {
|
||||
if (children[j].label === node.label) {
|
||||
|
||||
let idIsPath = true;
|
||||
//判断ID是否匹配 目前发现问题的只有重复场景,而重复场景是在第二个节点开始合并的。所以这里暂时只判断第二个场景问题。
|
||||
//如果出现了其他问题,则需要检查其他问题的数据结构。暂时采用具体问题具体分析的策略
|
||||
|
@ -312,7 +355,8 @@ export default {
|
|||
if (i !== nodeArray.length - 1 && !children[j].children) {
|
||||
children[j].children = [];
|
||||
}
|
||||
children = (i === nodeArray.length - 1 ? children : children[j].children);
|
||||
children =
|
||||
i === nodeArray.length - 1 ? children : children[j].children;
|
||||
isExist = true;
|
||||
break;
|
||||
}
|
||||
|
@ -320,21 +364,27 @@ export default {
|
|||
}
|
||||
if (!isExist) {
|
||||
children.push(node);
|
||||
if (i !== nodeArray.length - 1 && !children[children.length - 1].children) {
|
||||
if (
|
||||
i !== nodeArray.length - 1 &&
|
||||
!children[children.length - 1].children
|
||||
) {
|
||||
children[children.length - 1].children = [];
|
||||
}
|
||||
children = (i === nodeArray.length - 1 ? children : children[children.length - 1].children);
|
||||
children =
|
||||
i === nodeArray.length - 1
|
||||
? children
|
||||
: children[children.length - 1].children;
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
deepFormatTreeNode(array) {
|
||||
let returnChildren = [];
|
||||
array.map((item) => {
|
||||
let children = [];
|
||||
let key = item.name.split('^@~@^')[0];
|
||||
let nodeArray = key.split('<->');
|
||||
let key = item.name.split("^@~@^")[0];
|
||||
let nodeArray = key.split("<->");
|
||||
//运行场景中如果连续将1个场景引入多次,会出现运行结果合并的情况。
|
||||
//为了解决这种问题,在转hashTree的时候给场景放了个新ID,前台加载解析的时候也要做处理
|
||||
let scenarioId = "";
|
||||
|
@ -351,17 +401,16 @@ export default {
|
|||
let node = {
|
||||
label: nodeArray[0],
|
||||
value: item,
|
||||
children: []
|
||||
children: [],
|
||||
};
|
||||
if (item.subRequestResults && item.subRequestResults.length > 0) {
|
||||
let itemChildren = this.deepFormatTreeNode(item.subRequestResults);
|
||||
node.children = itemChildren;
|
||||
}
|
||||
children.push(node);
|
||||
children.forEach(itemNode => {
|
||||
children.forEach((itemNode) => {
|
||||
returnChildren.push(itemNode);
|
||||
});
|
||||
|
||||
});
|
||||
return returnChildren;
|
||||
},
|
||||
|
@ -380,7 +429,10 @@ export default {
|
|||
// 排序
|
||||
if (scenarioDefinition[i]) {
|
||||
scenarioDefinition[i].index = Number(i) + 1;
|
||||
if (scenarioDefinition[i].children && scenarioDefinition[i].children.length > 0) {
|
||||
if (
|
||||
scenarioDefinition[i].children &&
|
||||
scenarioDefinition[i].children.length > 0
|
||||
) {
|
||||
this.recursiveSorting(scenarioDefinition[i].children);
|
||||
}
|
||||
}
|
||||
|
@ -390,7 +442,7 @@ export default {
|
|||
if (this.exportReportIsOk) {
|
||||
this.startExport();
|
||||
} else {
|
||||
getScenarioReportAll(this.reportId).then(data => {
|
||||
getScenarioReportAll(this.reportId).then((data) => {
|
||||
if (data && data.data.content) {
|
||||
let report = JSON.parse(data.data.content);
|
||||
if (report.projectEnvMap) {
|
||||
|
@ -400,7 +452,8 @@ export default {
|
|||
this.fullTreeNodes = report.steps;
|
||||
this.content.console = report.console;
|
||||
this.content.error = report.error;
|
||||
let successCount = (report.total - report.error - report.errorCode - report.unExecute);
|
||||
let successCount =
|
||||
report.total - report.error - report.errorCode - report.unExecute;
|
||||
this.content.success = successCount;
|
||||
if (this.report.endTime > 0) {
|
||||
this.totalTime = this.report.endTime - this.report.createTime;
|
||||
|
@ -409,7 +462,7 @@ export default {
|
|||
}
|
||||
}
|
||||
this.exportReportIsOk = true;
|
||||
setTimeout(this.startExport, 500)
|
||||
setTimeout(this.startExport, 500);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -426,13 +479,13 @@ export default {
|
|||
}
|
||||
} else if (this.isShare) {
|
||||
if (this.reportId) {
|
||||
getShareScenarioReport(this.shareId, this.reportId).then(data => {
|
||||
getShareScenarioReport(this.shareId, this.reportId).then((data) => {
|
||||
this.checkReport(data.data);
|
||||
this.handleGetScenarioReport(data.data);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
getScenarioReport(this.reportId).then(data => {
|
||||
getScenarioReport(this.reportId).then((data) => {
|
||||
this.checkReport(data.data);
|
||||
this.handleGetScenarioReport(data.data);
|
||||
});
|
||||
|
@ -441,7 +494,7 @@ export default {
|
|||
|
||||
checkReport(data) {
|
||||
if (!data) {
|
||||
this.$emit('reportNotExist');
|
||||
this.$emit("reportNotExist");
|
||||
}
|
||||
},
|
||||
handleGetScenarioReport(data) {
|
||||
|
@ -450,7 +503,7 @@ export default {
|
|||
if (this.report.reportVersion && this.report.reportVersion > 1) {
|
||||
this.report.status = data.status;
|
||||
if (!this.isNotRunning) {
|
||||
setTimeout(this.getReport, 2000)
|
||||
setTimeout(this.getReport, 2000);
|
||||
} else {
|
||||
if (data.content) {
|
||||
let report = JSON.parse(data.content);
|
||||
|
@ -472,7 +525,11 @@ export default {
|
|||
}
|
||||
this.content.console = report.console;
|
||||
this.content.error = report.error;
|
||||
let successCount = (report.total - report.error - report.errorCode - report.unExecute);
|
||||
let successCount =
|
||||
report.total -
|
||||
report.error -
|
||||
report.errorCode -
|
||||
report.unExecute;
|
||||
this.content.success = successCount;
|
||||
if (this.report.endTime > 0) {
|
||||
this.totalTime = this.report.endTime - this.report.createTime;
|
||||
|
@ -481,7 +538,11 @@ export default {
|
|||
}
|
||||
}
|
||||
// 增加失败重跑校验
|
||||
if (this.report && this.report.reportType === 'SCENARIO_INTEGRATED' || this.report.reportType === 'API_INTEGRATED') {
|
||||
if (
|
||||
(this.report &&
|
||||
this.report.reportType === "SCENARIO_INTEGRATED") ||
|
||||
this.report.reportType === "API_INTEGRATED"
|
||||
) {
|
||||
this.rerunVerify();
|
||||
}
|
||||
this.loading = false;
|
||||
|
@ -490,8 +551,8 @@ export default {
|
|||
this.buildReport();
|
||||
}
|
||||
} else {
|
||||
this.$emit('invisible');
|
||||
this.$warning(this.$t('commons.report_delete'));
|
||||
this.$emit("invisible");
|
||||
this.$warning(this.$t("commons.report_delete"));
|
||||
}
|
||||
},
|
||||
checkOrder(origin) {
|
||||
|
@ -500,36 +561,42 @@ export default {
|
|||
}
|
||||
if (Array.isArray(origin)) {
|
||||
this.sortChildren(origin);
|
||||
origin.forEach(v => {
|
||||
origin.forEach((v) => {
|
||||
if (v.children) {
|
||||
this.checkOrder(v.children)
|
||||
this.checkOrder(v.children);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
sortChildren(source) {
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
source.forEach(item => {
|
||||
source.forEach((item) => {
|
||||
let children = item.children;
|
||||
if (children && children.length > 0) {
|
||||
let tempArr = new Array(children.length);
|
||||
let tempMap = new Map();
|
||||
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
if (!children[i].value || !children[i].value.startTime || children[i].value.startTime === 0) {
|
||||
if (
|
||||
!children[i].value ||
|
||||
!children[i].value.startTime ||
|
||||
children[i].value.startTime === 0
|
||||
) {
|
||||
//若没有value或未执行的,则step留在当前位置
|
||||
tempArr[i] = children[i];
|
||||
//进行标识
|
||||
tempMap.set(children[i].stepId, children[i])
|
||||
tempMap.set(children[i].stepId, children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//过滤出还没有指定好位置的step
|
||||
let arr = children.filter(m => {
|
||||
let arr = children
|
||||
.filter((m) => {
|
||||
return !tempMap.get(m.stepId);
|
||||
}).sort((m, n) => {
|
||||
})
|
||||
.sort((m, n) => {
|
||||
//按时间排序
|
||||
return m.value.startTime - n.value.startTime;
|
||||
});
|
||||
|
@ -548,12 +615,11 @@ export default {
|
|||
//赋值
|
||||
item.children = tempArr;
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
buildReport() {
|
||||
if (this.report) {
|
||||
if (this.isNotRunning) {
|
||||
|
||||
this.content = JSON.parse(this.report.content);
|
||||
if (!this.content) {
|
||||
this.content = { scenarios: [] };
|
||||
|
@ -563,21 +629,21 @@ export default {
|
|||
this.computeTotalTime();
|
||||
this.loading = false;
|
||||
} else {
|
||||
setTimeout(this.getReport, 2000)
|
||||
setTimeout(this.getReport, 2000);
|
||||
}
|
||||
} else {
|
||||
this.loading = false;
|
||||
this.$error(this.$t('api_report.not_exist'));
|
||||
this.$error(this.$t("api_report.not_exist"));
|
||||
}
|
||||
},
|
||||
getFails() {
|
||||
if (this.isNotRunning) {
|
||||
this.fails = [];
|
||||
let array = [];
|
||||
this.totalTime = 0
|
||||
this.totalTime = 0;
|
||||
if (this.content.scenarios) {
|
||||
this.content.scenarios.forEach((scenario) => {
|
||||
this.totalTime = this.totalTime + Number(scenario.responseTime)
|
||||
this.totalTime = this.totalTime + Number(scenario.responseTime);
|
||||
let failScenario = Object.assign({}, scenario);
|
||||
if (scenario.error > 0) {
|
||||
this.fails.push(failScenario);
|
||||
|
@ -588,9 +654,9 @@ export default {
|
|||
failScenario.requestResults.push(failRequest);
|
||||
array.push(request);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
this.formatTree(array, this.failsTreeNodes);
|
||||
this.sort(this.failsTreeNodes);
|
||||
|
@ -611,14 +677,14 @@ export default {
|
|||
}
|
||||
let resTime;
|
||||
if (startTime === 0 || endTime === 0) {
|
||||
resTime = 0
|
||||
resTime = 0;
|
||||
} else {
|
||||
resTime = endTime - startTime
|
||||
resTime = endTime - startTime;
|
||||
}
|
||||
requestTime = requestTime + resTime;
|
||||
})
|
||||
})
|
||||
this.totalTime = requestTime
|
||||
});
|
||||
});
|
||||
this.totalTime = requestTime;
|
||||
}
|
||||
},
|
||||
requestResult(requestResult) {
|
||||
|
@ -631,8 +697,11 @@ export default {
|
|||
});
|
||||
},
|
||||
formatExportApi(array, scenario) {
|
||||
array.forEach(item => {
|
||||
if (this.stepFilter && this.stepFilter.get("AllSamplerProxy").indexOf(item.type) !== -1) {
|
||||
array.forEach((item) => {
|
||||
if (
|
||||
this.stepFilter &&
|
||||
this.stepFilter.get("AllSamplerProxy").indexOf(item.type) !== -1
|
||||
) {
|
||||
if (item.errorCode) {
|
||||
item.value.errorCode = item.errorCode;
|
||||
}
|
||||
|
@ -641,72 +710,82 @@ export default {
|
|||
if (item.children && item.children.length > 0) {
|
||||
this.formatExportApi(item.children, scenario);
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
handleExport() {
|
||||
this.getReportByExport();
|
||||
},
|
||||
startExport() {
|
||||
if (this.report.reportVersion && this.report.reportVersion > 1) {
|
||||
if (this.report.reportType === 'API_INTEGRATED' || this.report.reportType === 'UI_INTEGRATED') {
|
||||
if (
|
||||
this.report.reportType === "API_INTEGRATED" ||
|
||||
this.report.reportType === "UI_INTEGRATED"
|
||||
) {
|
||||
let scenario = { name: "", requestResults: [] };
|
||||
this.content.scenarios = [scenario];
|
||||
this.formatExportApi(this.fullTreeNodes, scenario);
|
||||
} else {
|
||||
if (this.fullTreeNodes) {
|
||||
this.fullTreeNodes.forEach(item => {
|
||||
this.fullTreeNodes.forEach((item) => {
|
||||
if (item.type === "scenario" || item.type === "UiScenario") {
|
||||
let scenario = { name: item.label, requestResults: [] };
|
||||
if (this.content.scenarios && this.content.scenarios.length > 0) {
|
||||
if (
|
||||
this.content.scenarios &&
|
||||
this.content.scenarios.length > 0
|
||||
) {
|
||||
this.content.scenarios.push(scenario);
|
||||
} else {
|
||||
this.content.scenarios = [scenario];
|
||||
}
|
||||
this.formatExportApi(item.children, scenario);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
this.reportExportVisible = true;
|
||||
let reset = this.exportReportReset;
|
||||
this.$nextTick(() => {
|
||||
windowPrint('apiTestReport', 0.57);
|
||||
windowPrint("apiTestReport", 0.57);
|
||||
reset();
|
||||
});
|
||||
},
|
||||
handleSave() {
|
||||
if (!this.report.name) {
|
||||
this.$warning(this.$t('api_test.automation.report_name_info'));
|
||||
this.$warning(this.$t("api_test.automation.report_name_info"));
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
let url = "/ui/scenario/report/reName";
|
||||
this.result = this.$post(url, {
|
||||
this.result = this.$post(
|
||||
url,
|
||||
{
|
||||
id: this.report.id,
|
||||
name: this.report.name,
|
||||
reportType: this.report.reportType
|
||||
}, response => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
reportType: this.report.reportType,
|
||||
},
|
||||
(response) => {
|
||||
this.$success(this.$t("commons.save_success"));
|
||||
this.loading = false;
|
||||
this.$emit('refresh');
|
||||
}, error => {
|
||||
this.$emit("refresh");
|
||||
},
|
||||
(error) => {
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
exportReportReset() {
|
||||
this.$router.go(0);
|
||||
},
|
||||
handleProjectChange() {
|
||||
this.$router.push('/api/automation/report');
|
||||
this.$router.push("/api/automation/report");
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.getReport();
|
||||
},
|
||||
destroyed() {
|
||||
},
|
||||
destroyed() {},
|
||||
computed: {
|
||||
path() {
|
||||
return "/api/test/edit?id=" + this.report.testId;
|
||||
|
@ -717,8 +796,8 @@ export default {
|
|||
projectId() {
|
||||
return getCurrentProjectID();
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.report-container .el-tabs__header {
|
||||
|
@ -727,7 +806,6 @@ export default {
|
|||
</style>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.report-container {
|
||||
height: calc(100vh - 155px);
|
||||
min-height: 600px;
|
||||
|
@ -748,7 +826,7 @@ export default {
|
|||
}
|
||||
|
||||
.report-container .fail {
|
||||
color: #F56C6C;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.report-container .is-active .fail {
|
||||
|
|
Loading…
Reference in New Issue