API报告页面
This commit is contained in:
parent
ae288e8ace
commit
2a7be35de1
|
@ -43,9 +43,9 @@ public class APIReportController {
|
||||||
return PageUtils.setPageInfo(page, apiReportService.list(request));
|
return PageUtils.setPageInfo(page, apiReportService.list(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/get/{testId}")
|
@GetMapping("/get/{reportId}")
|
||||||
public ApiTestReport get(@PathVariable String testId) {
|
public APIReportResult get(@PathVariable String reportId) {
|
||||||
return apiReportService.get(testId);
|
return apiReportService.get(reportId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/delete")
|
@PostMapping("/delete")
|
||||||
|
|
|
@ -9,5 +9,7 @@ import lombok.Setter;
|
||||||
@Getter
|
@Getter
|
||||||
public class APIReportResult extends ApiTestReport {
|
public class APIReportResult extends ApiTestReport {
|
||||||
|
|
||||||
|
private String testName;
|
||||||
|
|
||||||
private String projectName;
|
private String projectName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,8 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestResult requestResult = getRequestResult(result);
|
RequestResult requestResult = getRequestResult(result);
|
||||||
scenarioResult.getRequestResult().add(requestResult);
|
scenarioResult.getRequestResults().add(requestResult);
|
||||||
|
scenarioResult.addResponseTime(result.getTime());
|
||||||
|
|
||||||
testResult.addPassAssertions(requestResult.getPassAssertions());
|
testResult.addPassAssertions(requestResult.getPassAssertions());
|
||||||
testResult.addTotalAssertions(requestResult.getTotalAssertions());
|
testResult.addTotalAssertions(requestResult.getTotalAssertions());
|
||||||
|
@ -110,14 +111,18 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
|
||||||
}
|
}
|
||||||
|
|
||||||
private RequestResult getRequestResult(SampleResult result) {
|
private RequestResult getRequestResult(SampleResult result) {
|
||||||
|
String body = result.getSamplerData();
|
||||||
|
String method = StringUtils.substringBefore(body, " ");
|
||||||
|
|
||||||
RequestResult requestResult = new RequestResult();
|
RequestResult requestResult = new RequestResult();
|
||||||
requestResult.setName(result.getSampleLabel());
|
requestResult.setName(result.getSampleLabel());
|
||||||
requestResult.setUrl(result.getUrlAsString());
|
requestResult.setUrl(result.getUrlAsString());
|
||||||
requestResult.setSuccess(result.isSuccessful());
|
requestResult.setMethod(method);
|
||||||
requestResult.setBody(result.getSamplerData());
|
requestResult.setBody(body);
|
||||||
requestResult.setHeaders(result.getRequestHeaders());
|
requestResult.setHeaders(result.getRequestHeaders());
|
||||||
requestResult.setRequestSize(result.getSentBytes());
|
requestResult.setRequestSize(result.getSentBytes());
|
||||||
requestResult.setTotalAssertions(result.getAssertionResults().length);
|
requestResult.setTotalAssertions(result.getAssertionResults().length);
|
||||||
|
requestResult.setSuccess(result.isSuccessful());
|
||||||
|
|
||||||
ResponseResult responseResult = requestResult.getResponseResult();
|
ResponseResult responseResult = requestResult.getResponseResult();
|
||||||
responseResult.setBody(result.getResponseDataAsString());
|
responseResult.setBody(result.getResponseDataAsString());
|
||||||
|
|
|
@ -9,6 +9,8 @@ public class RequestResult {
|
||||||
|
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
|
private String method;
|
||||||
|
|
||||||
private long requestSize;
|
private long requestSize;
|
||||||
|
|
||||||
private boolean success;
|
private boolean success;
|
||||||
|
|
|
@ -22,7 +22,11 @@ public class ScenarioResult {
|
||||||
|
|
||||||
private int passAssertions = 0;
|
private int passAssertions = 0;
|
||||||
|
|
||||||
private final List<RequestResult> requestResult = new ArrayList<>();
|
private final List<RequestResult> requestResults = new ArrayList<>();
|
||||||
|
|
||||||
|
public void addResponseTime(long time) {
|
||||||
|
this.responseTime += time;
|
||||||
|
}
|
||||||
|
|
||||||
public void addError() {
|
public void addError() {
|
||||||
this.error++;
|
this.error++;
|
||||||
|
|
|
@ -38,8 +38,8 @@ public class APIReportService {
|
||||||
return extApiTestReportMapper.list(request);
|
return extApiTestReportMapper.list(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApiTestReport get(String id) {
|
public APIReportResult get(String reportId) {
|
||||||
return apiTestReportMapper.selectByPrimaryKey(id);
|
return extApiTestReportMapper.get(reportId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<APIReportResult> listByTestId(String testId) {
|
public List<APIReportResult> listByTestId(String testId) {
|
||||||
|
|
|
@ -13,4 +13,6 @@ public interface ExtApiTestReportMapper {
|
||||||
|
|
||||||
List<APIReportResult> listByTestId(@Param("testId") String testId);
|
List<APIReportResult> listByTestId(@Param("testId") String testId);
|
||||||
|
|
||||||
|
APIReportResult get(@Param("id") String id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,13 @@
|
||||||
|
|
||||||
<resultMap id="BaseResultMap" type="io.metersphere.api.dto.APIReportResult"
|
<resultMap id="BaseResultMap" type="io.metersphere.api.dto.APIReportResult"
|
||||||
extends="io.metersphere.base.mapper.ApiTestReportMapper.BaseResultMap">
|
extends="io.metersphere.base.mapper.ApiTestReportMapper.BaseResultMap">
|
||||||
|
<result column="test_name" property="testName"/>
|
||||||
<result column="project_name" property="projectName"/>
|
<result column="project_name" property="projectName"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<select id="list" resultMap="BaseResultMap">
|
<select id="list" resultMap="BaseResultMap">
|
||||||
SELECT t.name, t.description,
|
SELECT t.name AS test_name,
|
||||||
r.id, r.test_id, r.create_time, r.update_time, r.status,
|
r.name, r.description, r.id, r.test_id, r.create_time, r.update_time, r.status,
|
||||||
project.name AS project_name
|
project.name AS project_name
|
||||||
FROM api_test_report r JOIN api_test t ON r.test_id = t.id
|
FROM api_test_report r JOIN api_test t ON r.test_id = t.id
|
||||||
JOIN project ON project.id = t.project_id
|
JOIN project ON project.id = t.project_id
|
||||||
|
@ -30,8 +31,8 @@
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="listByTestId" resultMap="BaseResultMap">
|
<select id="listByTestId" resultMap="BaseResultMap">
|
||||||
SELECT t.name, t.description,
|
SELECT c,
|
||||||
r.id, r.test_id, r.create_time, r.update_time, r.status,
|
r.name, r.description, r.id, r.test_id, r.create_time, r.update_time, r.status,
|
||||||
project.name AS project_name
|
project.name AS project_name
|
||||||
FROM api_test_report r JOIN api_test t ON r.test_id = t.id
|
FROM api_test_report r JOIN api_test t ON r.test_id = t.id
|
||||||
JOIN project ON project.id = t.project_id
|
JOIN project ON project.id = t.project_id
|
||||||
|
@ -41,4 +42,14 @@
|
||||||
ORDER BY r.update_time DESC
|
ORDER BY r.update_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="get" resultMap="BaseResultMap">
|
||||||
|
SELECT r.*, t.name AS test_name, project.name AS project_name
|
||||||
|
FROM api_test_report r JOIN api_test t ON r.test_id = t.id
|
||||||
|
JOIN project ON project.id = t.project_id
|
||||||
|
<where>
|
||||||
|
r.id = #{id}
|
||||||
|
</where>
|
||||||
|
ORDER BY r.update_time DESC
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
|
@ -23,8 +23,8 @@
|
||||||
<el-divider/>
|
<el-divider/>
|
||||||
<ms-show-all :index="'/api/test/list/all'"/>
|
<ms-show-all :index="'/api/test/list/all'"/>
|
||||||
<ms-create-button :index="'/api/test/create'" :title="$t('load_test.create')"/>
|
<ms-create-button :index="'/api/test/create'" :title="$t('load_test.create')"/>
|
||||||
<!-- <el-menu-item :index="testCaseProjectPath" class="blank_item"></el-menu-item>-->
|
<!-- <el-menu-item :index="testCaseProjectPath" class="blank_item"></el-menu-item>-->
|
||||||
<!-- <el-menu-item :index="testEditPath" class="blank_item"></el-menu-item>-->
|
<!-- <el-menu-item :index="testEditPath" class="blank_item"></el-menu-item>-->
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
|
|
||||||
<el-submenu v-if="isCurrentWorkspaceUser"
|
<el-submenu v-if="isCurrentWorkspaceUser"
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
<ms-recent-list :options="reportRecent"/>
|
<ms-recent-list :options="reportRecent"/>
|
||||||
<el-divider/>
|
<el-divider/>
|
||||||
<ms-show-all :index="'/api/report/list/all'"/>
|
<ms-show-all :index="'/api/report/list/all'"/>
|
||||||
<!-- <el-menu-item :index="reportViewPath" class="blank_item"></el-menu-item>-->
|
<!-- <el-menu-item :index="reportViewPath" class="blank_item"></el-menu-item>-->
|
||||||
</el-submenu>
|
</el-submenu>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
title: this.$t('report.recent'),
|
title: this.$t('report.recent'),
|
||||||
url: "/api/report/recent/5",
|
url: "/api/report/recent/5",
|
||||||
index: function (item) {
|
index: function (item) {
|
||||||
return '/api/report/view?id=' + item.id;
|
return '/api/report/view/' + item.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,38 @@
|
||||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
:label="$t('commons.status')">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
<el-tag size="mini" type="info" v-if="row.status === 'Saved'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="primary" v-else-if="row.status === 'Starting'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="success" v-else-if="row.status === 'Running'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="warning" v-else-if="row.status === 'Reporting'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="info" v-else-if="row.status === 'Completed'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tooltip placement="top" v-else-if="row.status === 'Error'" effect="light">
|
||||||
|
<template v-slot:content>
|
||||||
|
<div>{{row.description}}</div>
|
||||||
|
</template>
|
||||||
|
<el-tag size="mini" type="danger">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
</el-tooltip>
|
||||||
|
<span v-else>
|
||||||
|
{{ row.status }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
width="150"
|
width="150"
|
||||||
:label="$t('commons.operating')">
|
:label="$t('commons.operating')">
|
||||||
|
@ -101,7 +133,7 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
handleDelete(report) {
|
handleDelete(report) {
|
||||||
this.$alert(this.$t('load_test.delete_confirm') + report.name + "?", '', {
|
this.$alert(this.$t('api_report.delete_confirm') + report.name + "?", '', {
|
||||||
confirmButtonText: this.$t('commons.confirm'),
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
callback: (action) => {
|
callback: (action) => {
|
||||||
if (action === 'confirm') {
|
if (action === 'confirm') {
|
||||||
|
|
|
@ -1,117 +1,113 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-loading="result.loading" class="report-view-container">
|
<div class="container" v-loading="result.loading">
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<el-card>
|
<el-card>
|
||||||
<el-row>
|
<section class="report-container">
|
||||||
<el-col :span="16">
|
<header class="report-header" v-if="this.report.testId">
|
||||||
<el-row>
|
<span>{{report.projectName}} / </span>
|
||||||
<el-breadcrumb separator-class="el-icon-arrow-right">
|
<router-link :to="path">{{report.testName}}</router-link>
|
||||||
<el-breadcrumb-item :to="{ path: '/' }">{{report.projectName}}</el-breadcrumb-item>
|
</header>
|
||||||
<el-breadcrumb-item>{{report.testName}}</el-breadcrumb-item>
|
<main>
|
||||||
<el-breadcrumb-item>{{report.name}}</el-breadcrumb-item>
|
<div class="scenario-chart">
|
||||||
</el-breadcrumb>
|
<ms-metric-chart :content="content"></ms-metric-chart>
|
||||||
</el-row>
|
</div>
|
||||||
<el-row class="ms-report-view-btns">
|
<el-card>
|
||||||
<el-button type="primary" plain size="mini">立即停止</el-button>
|
<div class="scenario-header">
|
||||||
<el-button type="success" plain size="mini">再次执行</el-button>
|
<el-row :gutter="10">
|
||||||
<el-button type="info" plain size="mini">导出</el-button>
|
<el-col :span="16">
|
||||||
<el-button type="warning" plain size="mini">比较</el-button>
|
{{$t('api_report.scenario_name')}}
|
||||||
</el-row>
|
</el-col>
|
||||||
</el-col>
|
<el-col :span="2">
|
||||||
<el-col :span="8">
|
{{$t('api_report.response_time')}}
|
||||||
<span class="ms-report-time-desc">
|
</el-col>
|
||||||
持续时间: 30 分钟
|
<el-col :span="2">
|
||||||
</span>
|
{{$t('api_report.error')}}
|
||||||
<span class="ms-report-time-desc">
|
</el-col>
|
||||||
开始时间: 2020-3-10 12:00:00
|
<el-col :span="2">
|
||||||
</span>
|
{{$t('api_report.assertions')}}
|
||||||
<span class="ms-report-time-desc">
|
</el-col>
|
||||||
结束时间: 2020-3-10 12:30:00
|
<el-col :span="2">
|
||||||
</span>
|
{{$t('api_report.result')}}
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
</div>
|
||||||
<el-divider></el-divider>
|
<ms-scenario-result v-for="(scenario, index) in content.scenarios" :key="index" :scenario="scenario"/>
|
||||||
|
</el-card>
|
||||||
<el-tabs v-model="active" type="border-card" :stretch="true">
|
</main>
|
||||||
<el-tab-pane :label="$t('report.test_details')">
|
</section>
|
||||||
<result-details />
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane :label="$t('report.test_log_details')">
|
|
||||||
<ms-report-log-details />
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MsReportLogDetails from './components/LogDetails';
|
|
||||||
import ResultDetails from './components/ResultDetails';
|
import MsRequestResult from "./components/RequestResult";
|
||||||
|
import MsScenarioResult from "./components/ScenarioResult";
|
||||||
|
import MsMetricChart from "./components/MetricChart";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ApiReportView",
|
name: "MsApiReportView",
|
||||||
components: {
|
components: {MsMetricChart, MsScenarioResult, MsRequestResult},
|
||||||
MsReportLogDetails,
|
|
||||||
ResultDetails
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
content: {},
|
||||||
|
report: {},
|
||||||
result: {},
|
result: {},
|
||||||
active: '0',
|
|
||||||
videoPath: '',
|
|
||||||
report: {}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
initBreadcrumb() {
|
getReport() {
|
||||||
if(this.reportId){
|
if (this.reportId) {
|
||||||
this.result = this.$get("/api/report/test/pro/info/" + this.reportId, res => {
|
let url = "/api/report/get/" + this.reportId;
|
||||||
let data = res.data;
|
this.result = this.$get(url, response => {
|
||||||
if(data){
|
this.report = response.data || {};
|
||||||
this.report = data;
|
this.content = JSON.parse(this.report.content);
|
||||||
this.report.content = JSON.parse(this.report.content);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
|
||||||
this.initBreadcrumb();
|
watch: {
|
||||||
|
'$route': 'getReport',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.getReport();
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
reportId: function () {
|
reportId: function () {
|
||||||
return this.$route.params.reportId;
|
return this.$route.params.reportId;
|
||||||
|
},
|
||||||
|
path() {
|
||||||
|
return "/api/test/edit?id=" + this.report.testId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.report-view-container {
|
.report-container {
|
||||||
float: none;
|
height: calc(100vh - 150px);
|
||||||
text-align: center;
|
min-height: 600px;
|
||||||
padding: 15px;
|
overflow-y: auto;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.report-view-container .main-content {
|
.report-header {
|
||||||
margin: 0 auto;
|
font-size: 15px;
|
||||||
width: 100%;
|
|
||||||
max-width: 1200px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.ms-report-view-btns {
|
.report-header a {
|
||||||
margin-top: 15px;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ms-report-time-desc {
|
.scenario-header {
|
||||||
text-align: left;
|
border: 1px solid #EBEEF5;
|
||||||
display: block;
|
background-color: #F9FCFF;
|
||||||
color: #5C7878;
|
border-left: 0;
|
||||||
|
border-right: 0;
|
||||||
|
padding: 5px 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<el-table :data="assertions" style="width: 100%">
|
||||||
|
<el-table-column prop="name" :label="$t('api_report.assertions_name')" width="300">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="message" :label="$t('api_report.assertions_message')">
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="pass" :label="$t('api_report.assertions_is_success')" width="180">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
<el-tag size="mini" type="success" v-if="row.pass">
|
||||||
|
{{$t('api_report.success')}}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="danger" v-else>
|
||||||
|
{{$t('api_report.fail')}}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "MsAssertionResults",
|
||||||
|
|
||||||
|
props: {
|
||||||
|
assertions: Array
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,202 @@
|
||||||
|
<template>
|
||||||
|
<div class="metric-container">
|
||||||
|
<el-row type="flex" align="middle">
|
||||||
|
<div style="width: 50%">
|
||||||
|
<el-row type="flex" justify="center" align="middle">
|
||||||
|
<chart id="chart" ref="chart" :options="options" :autoresize="true"></chart>
|
||||||
|
<el-row type="flex" justify="center" align="middle">
|
||||||
|
<i class="circle success"/>
|
||||||
|
<div class="metric-box">
|
||||||
|
<div class="value">{{content.success}}</div>
|
||||||
|
<div class="name">{{$t('api_report.success')}}</div>
|
||||||
|
</div>
|
||||||
|
<div style="width: 40px"></div>
|
||||||
|
<i class="circle fail"/>
|
||||||
|
<div class="metric-box">
|
||||||
|
<div class="value">{{content.error}}</div>
|
||||||
|
<div class="name">{{$t('api_report.fail')}}</div>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<div class="split"></div>
|
||||||
|
<div style="width: 50%">
|
||||||
|
<el-row type="flex" justify="space-around" align="middle">
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
|
<div class="metric-icon-box">
|
||||||
|
<i class="el-icon-document-copy total"></i>
|
||||||
|
<div class="value">{{this.content.total}}</div>
|
||||||
|
<div class="name">{{$t('api_report.request')}}</div>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "MsMetricChart",
|
||||||
|
|
||||||
|
props: {
|
||||||
|
content: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
options() {
|
||||||
|
return {
|
||||||
|
color: ['#67C23A', '#F56C6C'],
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: '{b}: {c} ({d}%)'
|
||||||
|
},
|
||||||
|
title: [{
|
||||||
|
text: '{value|' + this.content.total + '}\n{name|' + this.$t('api_report.request') + '}',
|
||||||
|
top: 'center',
|
||||||
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
rich: {
|
||||||
|
align: 'center',
|
||||||
|
value: {
|
||||||
|
fontSize: 32,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
padding: [10, 0]
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: 'normal',
|
||||||
|
color: '#7F7F7F',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['80%', '90%'],
|
||||||
|
avoidLabelOverlap: false,
|
||||||
|
hoverAnimation: false,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
borderColor: "#FFF",
|
||||||
|
shadowColor: '#E1E1E1',
|
||||||
|
shadowBlur: 10
|
||||||
|
}
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{value: this.content.success, name: this.$t('api_report.success')},
|
||||||
|
{value: this.content.error, name: this.$t('api_report.fail')},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
return (this.content.error / this.content.total).toFixed(0) + "%";
|
||||||
|
},
|
||||||
|
assertions() {
|
||||||
|
return this.content.passAssertions + " / " + this.content.totalAssertions;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.metric-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-container #chart {
|
||||||
|
width: 140px;
|
||||||
|
height: 140px;
|
||||||
|
margin-right: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-container .split {
|
||||||
|
margin: 20px;
|
||||||
|
height: 100px;
|
||||||
|
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);
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 10px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-container .circle.success {
|
||||||
|
background-color: #67C23A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-container .circle.fail {
|
||||||
|
background-color: #F56C6C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-box {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-box .value {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: -.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-box .name {
|
||||||
|
font-size: 16px;
|
||||||
|
letter-spacing: -.2px;
|
||||||
|
color: #404040;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-icon-box {
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-icon-box .value {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: -.4px;
|
||||||
|
line-height: 28px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-icon-box .name {
|
||||||
|
font-size: 13px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
color: #BFBFBF;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-icon-box .fail {
|
||||||
|
color: #F56C6C;
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-icon-box .assertions {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric-icon-box .total {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,101 @@
|
||||||
|
<template>
|
||||||
|
<div class="metric-container">
|
||||||
|
<el-row type="flex">
|
||||||
|
<div class="metric">
|
||||||
|
<div class="value">{{request.responseResult.responseTime}} ms</div>
|
||||||
|
<div class="name">{{$t('api_report.response_time')}}</div>
|
||||||
|
<br>
|
||||||
|
<div class="value">{{request.responseResult.latency}} ms</div>
|
||||||
|
<div class="name">{{$t('api_report.latency')}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="metric">
|
||||||
|
<div class="value">{{request.requestSize}} bytes</div>
|
||||||
|
<div class="name">{{$t('api_report.request_size')}}</div>
|
||||||
|
<br>
|
||||||
|
<div class="value">{{request.responseResult.responseSize}} bytes</div>
|
||||||
|
<div class="name">{{$t('api_report.response_size')}}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="metric horizontal">
|
||||||
|
<el-row type="flex">
|
||||||
|
<div class="code">
|
||||||
|
<div class="value" :class="{'error': error}">{{request.responseResult.responseCode}}</div>
|
||||||
|
<div class="name">{{$t('api_report.response_code')}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="split"></div>
|
||||||
|
<div class="message">
|
||||||
|
<div class="value">{{request.responseResult.responseMessage}}</div>
|
||||||
|
<div class="name">{{$t('api_report.response_message')}}</div>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "MsRequestMetric",
|
||||||
|
|
||||||
|
props: {
|
||||||
|
request: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
error() {
|
||||||
|
return this.request.responseResult.responseCode >= 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.metric-container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric {
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
min-width: 120px;
|
||||||
|
height: 114px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric + .metric {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric .value {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric .name {
|
||||||
|
color: #404040;
|
||||||
|
opacity: 0.5;
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric.horizontal {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric .code {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric .code .value {
|
||||||
|
color: #67C23A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric .code .value.error {
|
||||||
|
color: #F56C6C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metric .split {
|
||||||
|
height: 114px;
|
||||||
|
border-left: 1px solid #EBEEF5;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,122 @@
|
||||||
|
<template>
|
||||||
|
<div class="request-result">
|
||||||
|
<div @click="active">
|
||||||
|
<el-row :gutter="10" type="flex" align="middle" class="info">
|
||||||
|
<el-col :span="4">
|
||||||
|
<div class="method">
|
||||||
|
{{request.method}}
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<div class="name">{{request.name}}</div>
|
||||||
|
<div class="url">{{request.url}}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
<div class="time">
|
||||||
|
{{request.responseResult.responseTime}}
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
{{error}}
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
{{request.passAssertions}} / {{request.totalAssertions}}
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
<el-tag size="mini" type="success" v-if="request.success">
|
||||||
|
{{$t('api_report.success')}}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="danger" v-else>
|
||||||
|
{{$t('api_report.fail')}}
|
||||||
|
</el-tag>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<el-collapse-transition>
|
||||||
|
<div v-show="isActive">
|
||||||
|
<ms-request-metric :request="request"/>
|
||||||
|
<ms-request-text :request="request"/>
|
||||||
|
<br>
|
||||||
|
<ms-response-text :response="request.responseResult"/>
|
||||||
|
</div>
|
||||||
|
</el-collapse-transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsRequestMetric from "./RequestMetric";
|
||||||
|
import MsAssertionResults from "./AssertionResults";
|
||||||
|
import MsRequestText from "./RequestText";
|
||||||
|
import MsResponseText from "./ResponseText";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsRequestResult",
|
||||||
|
components: {MsResponseText, MsRequestText, MsAssertionResults, MsRequestMetric},
|
||||||
|
props: {
|
||||||
|
request: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isActive: false,
|
||||||
|
activeName: "request",
|
||||||
|
activeName2: "body",
|
||||||
|
activeName3: "body",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
active() {
|
||||||
|
this.isActive = !this.isActive;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
error() {
|
||||||
|
return this.request.totalAssertions - this.request.passAssertions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.request-result {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 40px;
|
||||||
|
padding: 2px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-result .info {
|
||||||
|
background-color: #F9F9F9;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-result .method {
|
||||||
|
/*border-left: 5px solid #1E90FF;*/
|
||||||
|
color: #1E90FF;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 40px;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-result .url {
|
||||||
|
color: #7f7f7f;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-top: 4px;
|
||||||
|
overflow: auto;
|
||||||
|
white-space: normal;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-result .tab .el-tabs__header {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-result .text {
|
||||||
|
height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,69 @@
|
||||||
|
<template>
|
||||||
|
<div class="text-container">
|
||||||
|
<div @click="active" class="collapse">
|
||||||
|
<i class="icon el-icon-arrow-right" :class="{'is-active': isActive}"/>
|
||||||
|
{{$t('api_report.request')}}
|
||||||
|
</div>
|
||||||
|
<el-collapse-transition>
|
||||||
|
<el-tabs v-model="activeName" v-show="isActive">
|
||||||
|
<el-tab-pane label="Body" name="body" class="pane">
|
||||||
|
<pre>{{request.body}}</pre>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="Headers" name="headers" class="pane">
|
||||||
|
<pre>{{request.headers}}</pre>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="Cookies" name="cookies" class="pane">
|
||||||
|
<pre>{{request.cookies}}</pre>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-collapse-transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "MsRequestText",
|
||||||
|
|
||||||
|
props: {
|
||||||
|
request: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isActive: false,
|
||||||
|
activeName: "body",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
active() {
|
||||||
|
this.isActive = !this.isActive;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.text-container .icon {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-container .icon.is-active {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-container .collapse:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-container .pane {
|
||||||
|
background-color: #F9F9F9;
|
||||||
|
padding: 10px;
|
||||||
|
height: 250px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,73 @@
|
||||||
|
<template>
|
||||||
|
<div class="text-container">
|
||||||
|
<div @click="active" class="collapse">
|
||||||
|
<i class="icon el-icon-arrow-right" :class="{'is-active': isActive}"/>
|
||||||
|
{{$t('api_report.response')}}
|
||||||
|
</div>
|
||||||
|
<el-collapse-transition>
|
||||||
|
<el-tabs v-model="activeName" v-show="isActive">
|
||||||
|
<el-tab-pane label="Body" name="body" class="pane">
|
||||||
|
<div>{{response.body}}</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="Headers" name="headers" class="pane">
|
||||||
|
<pre>{{response.headers}}</pre>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane :label="$t('api_report.assertions')" name="assertions" class="pane">
|
||||||
|
<ms-assertion-results :assertions="response.assertions"/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</el-collapse-transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsAssertionResults from "./AssertionResults";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsResponseText",
|
||||||
|
|
||||||
|
components: {MsAssertionResults},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
response: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isActive: false,
|
||||||
|
activeName: "body",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
active() {
|
||||||
|
this.isActive = !this.isActive;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.text-container .icon {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-container .icon.is-active {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-container .collapse:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-container .pane {
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
padding: 0 10px;
|
||||||
|
height: 250px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,94 @@
|
||||||
|
<template>
|
||||||
|
<div class="scenario-result">
|
||||||
|
<div @click="active">
|
||||||
|
<el-row :gutter="10" type="flex" align="middle" class="info">
|
||||||
|
<el-col :span="16">
|
||||||
|
<i class="icon el-icon-arrow-right" :class="{'is-active': isActive}"/>
|
||||||
|
{{scenario.name}}
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
{{scenario.responseTime}}
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
{{scenario.error}}
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
{{assertion}}
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
<el-tag size="mini" type="success" v-if="success">
|
||||||
|
{{$t('api_report.success')}}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="danger" v-else>
|
||||||
|
{{$t('api_report.fail')}}
|
||||||
|
</el-tag>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<el-collapse-transition>
|
||||||
|
<div v-show="isActive">
|
||||||
|
<ms-request-result v-for="(request, index) in scenario.requestResults" :key="index" :request="request"/>
|
||||||
|
</div>
|
||||||
|
</el-collapse-transition>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsRequestResult from "./RequestResult";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MsScenarioResult",
|
||||||
|
|
||||||
|
components: {MsRequestResult},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
scenario: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isActive: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
active() {
|
||||||
|
this.isActive = !this.isActive;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
assertion() {
|
||||||
|
return this.scenario.passAssertions - this.scenario.totalAssertions;
|
||||||
|
},
|
||||||
|
success() {
|
||||||
|
return this.scenario.error === 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.scenario-result {
|
||||||
|
width: 100%;
|
||||||
|
padding: 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scenario-result + .scenario-result {
|
||||||
|
border-top: 1px solid #EBEEF5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scenario-result .info {
|
||||||
|
height: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scenario-result .icon {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scenario-result .icon.is-active {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
|
@ -38,6 +38,38 @@
|
||||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
:label="$t('commons.status')">
|
||||||
|
<template v-slot:default="{row}">
|
||||||
|
<el-tag size="mini" type="info" v-if="row.status === 'Saved'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="primary" v-else-if="row.status === 'Starting'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="success" v-else-if="row.status === 'Running'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="warning" v-else-if="row.status === 'Reporting'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tag size="mini" type="info" v-else-if="row.status === 'Completed'">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
<el-tooltip placement="top" v-else-if="row.status === 'Error'" effect="light">
|
||||||
|
<template v-slot:content>
|
||||||
|
<div>{{row.description}}</div>
|
||||||
|
</template>
|
||||||
|
<el-tag size="mini" type="danger">
|
||||||
|
{{ row.status }}
|
||||||
|
</el-tag>
|
||||||
|
</el-tooltip>
|
||||||
|
<span v-else>
|
||||||
|
{{ row.status }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
width="150"
|
width="150"
|
||||||
:label="$t('commons.operating')">
|
:label="$t('commons.operating')">
|
||||||
|
|
|
@ -234,6 +234,30 @@ export default {
|
||||||
extract: "提取",
|
extract: "提取",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
api_report: {
|
||||||
|
request: "请求",
|
||||||
|
request_body: "请求内容",
|
||||||
|
request_headers: "请求头",
|
||||||
|
request_cookie: "Cookie",
|
||||||
|
response: "响应",
|
||||||
|
delete_confirm: '确认删除报告: ',
|
||||||
|
scenario_name: "场景名称",
|
||||||
|
response_time: "响应时间(ms)",
|
||||||
|
latency: "网络延迟",
|
||||||
|
request_size: "请求大小",
|
||||||
|
response_size: "响应大小",
|
||||||
|
response_code: "状态码",
|
||||||
|
response_message: "响应报文",
|
||||||
|
error: "错误",
|
||||||
|
assertions: "断言",
|
||||||
|
assertions_pass: "成功断言",
|
||||||
|
assertions_name: "断言名称",
|
||||||
|
assertions_message: "断言信息",
|
||||||
|
assertions_is_success: "是否成功",
|
||||||
|
result: "结果",
|
||||||
|
success: "成功",
|
||||||
|
fail: "失败",
|
||||||
|
},
|
||||||
test_track: {
|
test_track: {
|
||||||
test_track: "测试跟踪",
|
test_track: "测试跟踪",
|
||||||
confirm: "确 定",
|
confirm: "确 定",
|
||||||
|
|
Loading…
Reference in New Issue