fix(接口定义): 修复选择案例缺陷
This commit is contained in:
parent
54f5e8aad5
commit
d75477db11
|
@ -281,7 +281,7 @@
|
||||||
import MsIfController from "./IfController";
|
import MsIfController from "./IfController";
|
||||||
import MsApiAssertions from "../../definition/components/assertion/ApiAssertions";
|
import MsApiAssertions from "../../definition/components/assertion/ApiAssertions";
|
||||||
import MsApiExtract from "../../definition/components/extract/ApiExtract";
|
import MsApiExtract from "../../definition/components/extract/ApiExtract";
|
||||||
import MsApiDefinition from "../../definition/ApiDefinition";
|
import MsApiDefinition from "./api/ApiDefinition";
|
||||||
import MsApiComponent from "./ApiComponent";
|
import MsApiComponent from "./ApiComponent";
|
||||||
import {ELEMENTS, ELEMENT_TYPE} from "./Setting";
|
import {ELEMENTS, ELEMENT_TYPE} from "./Setting";
|
||||||
import MsApiCustomize from "./ApiCustomize";
|
import MsApiCustomize from "./ApiCustomize";
|
||||||
|
|
|
@ -0,0 +1,494 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-container style="padding-bottom: 200px">
|
||||||
|
<el-header style="width: 100% ;padding: 0px">
|
||||||
|
<el-card>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="api.protocol==='HTTP'? 3:5">
|
||||||
|
<div class="variable-combine"> {{api.name}}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="api.protocol==='HTTP'? 1:3">
|
||||||
|
<ms-tag v-if="api.status == 'Prepare'" type="info" effect="plain" :content="$t('test_track.plan.plan_status_prepare')"/>
|
||||||
|
<ms-tag v-if="api.status == 'Underway'" type="warning" effect="plain" :content="$t('test_track.plan.plan_status_running')"/>
|
||||||
|
<ms-tag v-if="api.status == 'Completed'" type="success" effect="plain" :content="$t('test_track.plan.plan_status_completed')"/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="api.protocol==='HTTP'? 4:0">
|
||||||
|
<div class="variable-combine" style="margin-left: 10px">{{api.path ===null ? " " : api.path}}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="2">
|
||||||
|
<div>{{$t('test_track.plan_view.case_count')}}:{{apiCaseList.length}}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<div>
|
||||||
|
<el-select size="small" :placeholder="$t('api_test.definition.request.grade_info')" v-model="priorityValue"
|
||||||
|
class="ms-api-header-select" @change="getApiTest">
|
||||||
|
<el-option v-for="grd in priority" :key="grd.id" :label="grd.name" :value="grd.id"/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div>
|
||||||
|
<el-select :disabled="isReadOnly" v-model="environment" size="small" class="ms-api-header-select"
|
||||||
|
:placeholder="$t('api_test.definition.request.run_env')"
|
||||||
|
@change="environmentChange" clearable>
|
||||||
|
<el-option v-for="(environment, index) in environments" :key="index"
|
||||||
|
:label="environment.name + (environment.config.httpConfig.socket ? (': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '')"
|
||||||
|
:value="environment.id"/>
|
||||||
|
<el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">
|
||||||
|
{{ $t('api_test.environment.environment_config') }}
|
||||||
|
</el-button>
|
||||||
|
<template v-slot:empty>
|
||||||
|
<div class="empty-environment">
|
||||||
|
<el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">
|
||||||
|
{{ $t('api_test.environment.environment_config') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="3">
|
||||||
|
<div class="ms-api-header-select">
|
||||||
|
<el-input size="small" :placeholder="$t('api_test.definition.request.select_case')"
|
||||||
|
v-model="name" @blur="getApiTest"/>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="2">
|
||||||
|
<button type="button" aria-label="Close" class="el-card-btn" @click="apiCaseClose()"><i
|
||||||
|
class="el-dialog__close el-icon el-icon-close"></i></button>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 环境 -->
|
||||||
|
<api-environment-config ref="environmentConfig" @close="environmentConfigClose"/>
|
||||||
|
</el-header>
|
||||||
|
|
||||||
|
<!-- 用例部分 -->
|
||||||
|
<el-main v-loading="loading" style="overflow: auto">
|
||||||
|
<div v-for="(item,index) in apiCaseList" :key="index">
|
||||||
|
<el-card style="margin-top: 5px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="1">
|
||||||
|
<el-checkbox v-if="visible" @change="caseChecked(item)"/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">
|
||||||
|
<div class="el-step__icon is-text ms-api-col">
|
||||||
|
<div class="el-step__icon-inner">{{index+1}}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label class="ms-api-label">{{$t('test_track.case.priority')}}</label>
|
||||||
|
<el-select size="small" v-model="item.priority" class="ms-api-select">
|
||||||
|
<el-option v-for="grd in priority" :key="grd.id" :label="grd.name" :value="grd.id"/>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="14">
|
||||||
|
<i class="icon el-icon-arrow-right" :class="{'is-active': item.active}"
|
||||||
|
@click="active(item)"/>
|
||||||
|
<el-input v-if="item.type==='create'" size="small" v-model="item.name" :name="index" :key="index"
|
||||||
|
class="ms-api-header-select" style="width: 180px"
|
||||||
|
@blur="saveTestCase(item)"/>
|
||||||
|
<span v-else>
|
||||||
|
{{item.type!= 'create' ? item.name:''}}
|
||||||
|
<i class="el-icon-edit" style="cursor:pointer" @click="showInput(item)"/>
|
||||||
|
</span>
|
||||||
|
<div v-if="item.type!='create'" style="color: #999999;font-size: 12px">
|
||||||
|
<span>
|
||||||
|
{{item.createTime | timestampFormatDate }}
|
||||||
|
{{item.createUser}} {{$t('api_test.definition.request.create_info')}}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
{{item.updateTime | timestampFormatDate }}
|
||||||
|
{{item.updateUser}} {{$t('api_test.definition.request.update_info')}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="3">
|
||||||
|
<div v-if="item.type!='create'">{{getResult(item.execResult)}}</div>
|
||||||
|
<div v-if="item.type!='create'" style="color: #999999;font-size: 12px">
|
||||||
|
<span> {{item.updateTime | timestampFormatDate }}</span>
|
||||||
|
{{item.updateUser}}
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<!-- 请求参数-->
|
||||||
|
<el-collapse-transition>
|
||||||
|
<div v-if="item.active">
|
||||||
|
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
|
||||||
|
|
||||||
|
<ms-api-request-form :is-read-only="isReadOnly" :headers="item.request.headers " :request="item.request" v-if="api.protocol==='HTTP'"/>
|
||||||
|
<ms-tcp-basis-parameters :request="item.request" v-if="api.protocol==='TCP'"/>
|
||||||
|
<ms-sql-basis-parameters :request="item.request" v-if="api.protocol==='SQL'"/>
|
||||||
|
<ms-dubbo-basis-parameters :request="item.request" v-if="api.protocol==='DUBBO'"/>
|
||||||
|
<!-- 保存操作 -->
|
||||||
|
<el-button type="primary" size="small" style="margin: 20px; float: right" @click="saveTestCase(item)">
|
||||||
|
{{$t('commons.save')}}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-collapse-transition>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</el-main>
|
||||||
|
|
||||||
|
</el-container>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import MsTag from "../../../../common/components/MsTag";
|
||||||
|
import MsTipButton from "../../../../common/components/MsTipButton";
|
||||||
|
import MsApiRequestForm from "../../../definition/components/request/http/ApiRequestForm";
|
||||||
|
import {downloadFile, getUUID, getCurrentProjectID} from "@/common/js/utils";
|
||||||
|
import {parseEnvironment} from "../../../definition/model/EnvironmentModel";
|
||||||
|
import ApiEnvironmentConfig from "../../../definition/components/environment/ApiEnvironmentConfig";
|
||||||
|
import {PRIORITY, RESULT_MAP} from "../../../definition/model/JsonData";
|
||||||
|
import MsApiAssertions from "../../../definition/components/assertion/ApiAssertions";
|
||||||
|
import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters";
|
||||||
|
import MsTcpBasisParameters from "../../../definition/components/request/tcp/BasisParameters";
|
||||||
|
import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters";
|
||||||
|
import MsApiExtendBtns from "../../../definition/components/reference/ApiExtendBtns";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ApiCaseList',
|
||||||
|
components: {
|
||||||
|
MsTag,
|
||||||
|
MsTipButton,
|
||||||
|
MsApiRequestForm,
|
||||||
|
ApiEnvironmentConfig,
|
||||||
|
MsApiAssertions,
|
||||||
|
MsSqlBasisParameters,
|
||||||
|
MsTcpBasisParameters,
|
||||||
|
MsDubboBasisParameters,
|
||||||
|
MsApiExtendBtns
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
api: {
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
|
createCase: String,
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
loaded: Boolean,
|
||||||
|
refreshSign: String,
|
||||||
|
currentRow: Object,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
grades: [],
|
||||||
|
environments: [],
|
||||||
|
environment: {},
|
||||||
|
name: "",
|
||||||
|
priorityValue: "",
|
||||||
|
isReadOnly: false,
|
||||||
|
selectedEvent: Object,
|
||||||
|
priority: PRIORITY,
|
||||||
|
apiCaseList: [],
|
||||||
|
loading: false,
|
||||||
|
runData: [],
|
||||||
|
reportId: "",
|
||||||
|
projectId: "",
|
||||||
|
checkedCases: new Set(),
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 初始化
|
||||||
|
api() {
|
||||||
|
this.getApiTest();
|
||||||
|
},
|
||||||
|
createCase() {
|
||||||
|
this.getApiTest();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.projectId = getCurrentProjectID();
|
||||||
|
this.getEnvironments();
|
||||||
|
this.getApiTest();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
sysAddition() {
|
||||||
|
let condition = {};
|
||||||
|
condition.projectId = this.api.projectId;
|
||||||
|
condition.apiDefinitionId = this.api.id;
|
||||||
|
condition.priority = this.priorityValue;
|
||||||
|
condition.name = this.name;
|
||||||
|
this.$post("/api/testcase/list", condition, response => {
|
||||||
|
for (let index in response.data) {
|
||||||
|
let test = response.data[index];
|
||||||
|
test.request = JSON.parse(test.request);
|
||||||
|
}
|
||||||
|
this.apiCaseList = response.data;
|
||||||
|
this.addCase();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getResult(data) {
|
||||||
|
if (RESULT_MAP.get(data)) {
|
||||||
|
return RESULT_MAP.get(data);
|
||||||
|
} else {
|
||||||
|
return RESULT_MAP.get("default");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleCommand(e) {
|
||||||
|
if (e === "run") {
|
||||||
|
this.batchRun();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showInput(row) {
|
||||||
|
row.type = "create";
|
||||||
|
row.active = true;
|
||||||
|
this.active(row);
|
||||||
|
},
|
||||||
|
apiCaseClose() {
|
||||||
|
this.apiCaseList = [];
|
||||||
|
this.$emit('apiCaseClose');
|
||||||
|
},
|
||||||
|
batchRun() {
|
||||||
|
if (!this.environment) {
|
||||||
|
this.$warning(this.$t('api_test.environment.select_environment'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.loading = true;
|
||||||
|
if (this.apiCaseList.length > 0) {
|
||||||
|
this.apiCaseList.forEach(item => {
|
||||||
|
if (item.type != "create") {
|
||||||
|
item.request.name = item.id;
|
||||||
|
item.request.useEnvironment = this.environment.id;
|
||||||
|
this.runData.push(item.request);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.loading = true;
|
||||||
|
/*触发执行操作*/
|
||||||
|
this.reportId = getUUID().substring(0, 8);
|
||||||
|
} else {
|
||||||
|
this.$warning("没有可执行的用例!");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
singleRun(row) {
|
||||||
|
if (!this.environment) {
|
||||||
|
this.$warning(this.$t('api_test.environment.select_environment'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.runData = [];
|
||||||
|
this.loading = true;
|
||||||
|
row.request.name = row.id;
|
||||||
|
row.request.useEnvironment = this.environment.id;
|
||||||
|
this.runData.push(row.request);
|
||||||
|
/*触发执行操作*/
|
||||||
|
this.reportId = getUUID().substring(0, 8);
|
||||||
|
},
|
||||||
|
runRefresh(data) {
|
||||||
|
this.loading = false;
|
||||||
|
this.$success(this.$t('schedule.event_success'));
|
||||||
|
this.getApiTest();
|
||||||
|
this.$emit('refresh');
|
||||||
|
},
|
||||||
|
deleteCase(index, row) {
|
||||||
|
this.$get('/api/testcase/delete/' + row.id, () => {
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
this.apiCaseList.splice(index, 1);
|
||||||
|
this.$emit('refresh');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
copyCase(data) {
|
||||||
|
let obj = {name: data.name, priority: data.priority, type: 'create', active: false, request: data.request};
|
||||||
|
this.apiCaseList.unshift(obj);
|
||||||
|
},
|
||||||
|
addCase() {
|
||||||
|
// 初始化对象
|
||||||
|
let request = {};
|
||||||
|
if (this.api.request instanceof Object) {
|
||||||
|
request = this.api.request;
|
||||||
|
} else {
|
||||||
|
request = JSON.parse(this.api.request);
|
||||||
|
}
|
||||||
|
let obj = {apiDefinitionId: this.api.id, name: '', priority: 'P0', type: 'create', active: false};
|
||||||
|
obj.request = request;
|
||||||
|
this.apiCaseList.unshift(obj);
|
||||||
|
},
|
||||||
|
|
||||||
|
active(item) {
|
||||||
|
item.active = !item.active;
|
||||||
|
},
|
||||||
|
getBodyUploadFiles(row) {
|
||||||
|
let bodyUploadFiles = [];
|
||||||
|
row.bodyUploadIds = [];
|
||||||
|
let request = row.request;
|
||||||
|
if (request.body && request.body.kvs) {
|
||||||
|
request.body.kvs.forEach(param => {
|
||||||
|
if (param.files) {
|
||||||
|
param.files.forEach(item => {
|
||||||
|
if (item.file) {
|
||||||
|
let fileId = getUUID().substring(0, 8);
|
||||||
|
item.name = item.file.name;
|
||||||
|
item.id = fileId;
|
||||||
|
row.bodyUploadIds.push(fileId);
|
||||||
|
bodyUploadFiles.push(item.file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (request.body.binary) {
|
||||||
|
request.body.binary.forEach(param => {
|
||||||
|
if (param.files) {
|
||||||
|
param.files.forEach(item => {
|
||||||
|
if (item.file) {
|
||||||
|
let fileId = getUUID().substring(0, 8);
|
||||||
|
item.name = item.file.name;
|
||||||
|
item.id = fileId;
|
||||||
|
row.bodyUploadIds.push(fileId);
|
||||||
|
bodyUploadFiles.push(item.file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bodyUploadFiles;
|
||||||
|
},
|
||||||
|
getApiTest() {
|
||||||
|
if (this.currentRow) {
|
||||||
|
this.currentRow.cases = [];
|
||||||
|
}
|
||||||
|
let condition = {};
|
||||||
|
condition.projectId = this.api.projectId;
|
||||||
|
condition.apiDefinitionId = this.api.id;
|
||||||
|
condition.priority = this.priorityValue;
|
||||||
|
condition.name = this.name;
|
||||||
|
this.$post("/api/testcase/list", condition, response => {
|
||||||
|
for (let index in response.data) {
|
||||||
|
let test = response.data[index];
|
||||||
|
test.request = JSON.parse(test.request);
|
||||||
|
}
|
||||||
|
this.apiCaseList = response.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
validate(row) {
|
||||||
|
if (!row.name) {
|
||||||
|
this.$warning(this.$t('api_test.input_name'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getEnvironments() {
|
||||||
|
if (this.projectId) {
|
||||||
|
this.$get('/api/environment/list/' + this.projectId, response => {
|
||||||
|
this.environments = response.data;
|
||||||
|
this.environments.forEach(environment => {
|
||||||
|
parseEnvironment(environment);
|
||||||
|
});
|
||||||
|
let hasEnvironment = false;
|
||||||
|
for (let i in this.environments) {
|
||||||
|
if (this.environments[i].id === this.api.environmentId) {
|
||||||
|
hasEnvironment = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasEnvironment) {
|
||||||
|
this.environment = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.environment = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openEnvironmentConfig() {
|
||||||
|
if (!this.projectId) {
|
||||||
|
this.$error(this.$t('api_test.select_project'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$refs.environmentConfig.open(this.projectId);
|
||||||
|
},
|
||||||
|
environmentChange(value) {
|
||||||
|
for (let i in this.environments) {
|
||||||
|
if (this.environments[i].id === value) {
|
||||||
|
this.environment = this.environments[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
environmentConfigClose() {
|
||||||
|
this.getEnvironments();
|
||||||
|
},
|
||||||
|
caseChecked(row) {
|
||||||
|
row.protocol = this.api.protocol;
|
||||||
|
row.hashTree = [];
|
||||||
|
if (this.checkedCases.has(row)) {
|
||||||
|
this.checkedCases.delete(row);
|
||||||
|
} else {
|
||||||
|
this.checkedCases.add(row)
|
||||||
|
}
|
||||||
|
let arr = Array.from(this.checkedCases);
|
||||||
|
this.currentRow.cases = arr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.ms-api-select {
|
||||||
|
margin-left: 20px;
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-api-header-select {
|
||||||
|
margin-left: 20px;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-card-btn {
|
||||||
|
float: right;
|
||||||
|
top: 20px;
|
||||||
|
right: 0px;
|
||||||
|
padding: 0;
|
||||||
|
background: 0 0;
|
||||||
|
border: none;
|
||||||
|
outline: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-api-label {
|
||||||
|
color: #CCCCCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-api-col {
|
||||||
|
background-color: #7C3985;
|
||||||
|
border-color: #7C3985;
|
||||||
|
margin-right: 10px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.variable-combine {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon.is-active {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
padding: 3px 5px;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 4px solid #783887;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.environment-button {
|
||||||
|
margin-left: 20px;
|
||||||
|
padding: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-selected {
|
||||||
|
background: #EFF7FF;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,151 @@
|
||||||
|
<template>
|
||||||
|
<ms-container>
|
||||||
|
<ms-aside-container>
|
||||||
|
<ms-node-tree @selectModule="selectModule" @getApiModuleTree="initTree" @changeProtocol="changeProtocol"
|
||||||
|
@refresh="refresh" @saveAsEdit="editApi" @exportAPI="exportAPI"/>
|
||||||
|
</ms-aside-container>
|
||||||
|
|
||||||
|
<ms-main-container>
|
||||||
|
<!-- 主框架列表 -->
|
||||||
|
<el-tabs v-model="apiDefaultTab">
|
||||||
|
<el-tab-pane
|
||||||
|
:key="item.name"
|
||||||
|
v-for="(item) in apiTabs"
|
||||||
|
:label="item.title"
|
||||||
|
:closable="item.closable"
|
||||||
|
:name="item.name">
|
||||||
|
<!-- 列表集合 -->
|
||||||
|
<ms-api-list
|
||||||
|
v-if="item.type === 'list'"
|
||||||
|
:current-protocol="currentProtocol"
|
||||||
|
:current-module="currentModule"
|
||||||
|
@editApi="editApi"
|
||||||
|
@handleCase="handleCase"
|
||||||
|
:visible="visible"
|
||||||
|
:currentRow="currentRow"
|
||||||
|
ref="apiList"/>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</ms-main-container>
|
||||||
|
</ms-container>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import MsNodeTree from '../../../definition/components/ApiModule';
|
||||||
|
import MsApiList from './ApiList';
|
||||||
|
import MsContainer from "../../../../common/components/MsContainer";
|
||||||
|
import MsMainContainer from "../../../../common/components/MsMainContainer";
|
||||||
|
import MsAsideContainer from "../../../../common/components/MsAsideContainer";
|
||||||
|
import {downloadFile, getCurrentUser, getUUID, getCurrentProjectID} from "@/common/js/utils";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ApiDefinition",
|
||||||
|
components: {
|
||||||
|
MsNodeTree,
|
||||||
|
MsApiList,
|
||||||
|
MsMainContainer,
|
||||||
|
MsContainer,
|
||||||
|
MsAsideContainer,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
currentRow: {
|
||||||
|
type: Object,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isHide: true,
|
||||||
|
apiDefaultTab: 'default',
|
||||||
|
currentProtocol: null,
|
||||||
|
currentModule: null,
|
||||||
|
currentApi: {},
|
||||||
|
moduleOptions: {},
|
||||||
|
runTestData: {},
|
||||||
|
apiTabs: [{
|
||||||
|
title: this.$t('api_test.definition.api_title'),
|
||||||
|
name: 'default',
|
||||||
|
type: "list",
|
||||||
|
closable: false
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
editApi(row) {
|
||||||
|
this.currentApi = row;
|
||||||
|
},
|
||||||
|
handleCase(testCase) {
|
||||||
|
this.currentApi = testCase;
|
||||||
|
this.isHide = false;
|
||||||
|
},
|
||||||
|
apiCaseClose() {
|
||||||
|
this.isHide = true;
|
||||||
|
},
|
||||||
|
selectModule(data) {
|
||||||
|
this.currentModule = data;
|
||||||
|
},
|
||||||
|
exportAPI() {
|
||||||
|
if (!this.$refs.apiList[0].tableData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let obj = {projectName: getCurrentProjectID(), protocol: this.currentProtocol, data: this.$refs.apiList[0].tableData}
|
||||||
|
downloadFile("导出API.json", JSON.stringify(obj));
|
||||||
|
},
|
||||||
|
refresh(data) {
|
||||||
|
this.$refs.apiList[0].initApiTable(data);
|
||||||
|
},
|
||||||
|
setTabTitle(data) {
|
||||||
|
for (let index in this.apiTabs) {
|
||||||
|
let tab = this.apiTabs[index];
|
||||||
|
if (tab.name === this.apiDefaultTab) {
|
||||||
|
tab.title = this.$t('api_test.definition.request.edit_api') + "-" + data.name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.runTestData = data;
|
||||||
|
},
|
||||||
|
saveApi(data) {
|
||||||
|
this.setTabTitle(data);
|
||||||
|
this.$refs.apiList[0].initApiTable(data);
|
||||||
|
},
|
||||||
|
initTree(data) {
|
||||||
|
this.moduleOptions = data;
|
||||||
|
},
|
||||||
|
changeProtocol(data) {
|
||||||
|
this.currentProtocol = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.ms-api-buttion {
|
||||||
|
position: absolute;
|
||||||
|
top: 100px;
|
||||||
|
right: 4px;
|
||||||
|
padding: 0;
|
||||||
|
background: 0 0;
|
||||||
|
border: none;
|
||||||
|
outline: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ms-api-div {
|
||||||
|
overflow-y: auto;
|
||||||
|
height: calc(100vh - 155px)
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .el-tabs__header {
|
||||||
|
margin: 0 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/deep/ .el-main {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,412 @@
|
||||||
|
<template>
|
||||||
|
<div id="svgBox" style="overflow: auto">
|
||||||
|
<div id="svgTop" style="background-color: white">
|
||||||
|
<el-card class="card-content">
|
||||||
|
<el-input placeholder="搜索" @blur="search" style="float: right ;width: 300px;margin-bottom: 20px;margin-right: 20px" size="small" v-model="condition.name"/>
|
||||||
|
|
||||||
|
<el-table border :data="tableData" row-key="id" class="test-content adjust-table"
|
||||||
|
@select-all="handleSelectAll"
|
||||||
|
@select="handleSelect" :height="screenHeight">
|
||||||
|
<el-table-column type="selection"/>
|
||||||
|
<el-table-column width="40" :resizable="false" align="center">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<show-more-btn :is-show="scope.row.showMore" :buttons="buttons" :size="selectRows.size"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column prop="name" :label="$t('api_test.definition.api_name')" show-overflow-tooltip/>
|
||||||
|
<el-table-column
|
||||||
|
prop="status"
|
||||||
|
column-key="api_status"
|
||||||
|
:label="$t('api_test.definition.api_status')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<ms-tag v-if="scope.row.status == 'Prepare'" type="info" effect="plain" :content="$t('test_track.plan.plan_status_prepare')"/>
|
||||||
|
<ms-tag v-if="scope.row.status == 'Underway'" type="warning" effect="plain" :content="$t('test_track.plan.plan_status_running')"/>
|
||||||
|
<ms-tag v-if="scope.row.status == 'Completed'" type="success" effect="plain" :content="$t('test_track.plan.plan_status_completed')"/>
|
||||||
|
<ms-tag v-if="scope.row.status == 'Trash'" type="danger" effect="plain" content="废弃"/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="method"
|
||||||
|
:label="$t('api_test.definition.api_type')"
|
||||||
|
show-overflow-tooltip>
|
||||||
|
<template v-slot:default="scope" class="request-method">
|
||||||
|
<el-tag size="mini" :style="{'background-color': getColor(true, scope.row.method)}" class="api-el-tag">
|
||||||
|
{{ scope.row.method}}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="path"
|
||||||
|
:label="$t('api_test.definition.api_path')"
|
||||||
|
show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="userName"
|
||||||
|
:label="$t('api_test.definition.api_principal')"
|
||||||
|
show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column width="160" :label="$t('api_test.definition.api_last_time')" prop="updateTime">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="caseTotal"
|
||||||
|
:label="$t('api_test.definition.api_case_number')"
|
||||||
|
show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="caseStatus"
|
||||||
|
:label="$t('api_test.definition.api_case_status')"
|
||||||
|
show-overflow-tooltip/>
|
||||||
|
|
||||||
|
<!-- <el-table-column
|
||||||
|
prop="casePassingRate"
|
||||||
|
:label="$t('api_test.definition.api_case_passing_rate')"
|
||||||
|
show-overflow-tooltip/>-->
|
||||||
|
|
||||||
|
<el-table-column :label="$t('commons.operating')" min-width="80" align="center">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<el-button type="text" @click="handleTestCase(scope.row)">用例</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<ms-table-pagination :change="initApiTable" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||||
|
:total="total"/>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<div id="svgResize"/>
|
||||||
|
<div id="svgDown">
|
||||||
|
<ms-bottom-container v-bind:enableAsideHidden="isHide">
|
||||||
|
<ms-api-case-list @apiCaseClose="apiCaseClose" @refresh="initApiTable" :visible="visible" :currentRow="currentRow" :api="selectApi"/>
|
||||||
|
</ms-bottom-container>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import MsTableHeader from '../../../../../components/common/components/MsTableHeader';
|
||||||
|
import MsTableOperator from "../../../../common/components/MsTableOperator";
|
||||||
|
import MsTableOperatorButton from "../../../../common/components/MsTableOperatorButton";
|
||||||
|
import MsTableButton from "../../../../common/components/MsTableButton";
|
||||||
|
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
|
||||||
|
import MsTablePagination from "../../../../common/pagination/TablePagination";
|
||||||
|
import MsTag from "../../../../common/components/MsTag";
|
||||||
|
import MsApiCaseList from "./ApiCaseList";
|
||||||
|
import MsContainer from "../../../../common/components/MsContainer";
|
||||||
|
import MsBottomContainer from "../../../definition/components/BottomContainer";
|
||||||
|
import ShowMoreBtn from "../../../../../components/track/case/components/ShowMoreBtn";
|
||||||
|
import {API_METHOD_COLOUR} from "../../../definition/model/JsonData";
|
||||||
|
import {getCurrentProjectID} from "@/common/js/utils";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ApiList",
|
||||||
|
components: {
|
||||||
|
MsTableButton,
|
||||||
|
MsTableOperatorButton,
|
||||||
|
MsTableOperator,
|
||||||
|
MsTableHeader,
|
||||||
|
MsTablePagination,
|
||||||
|
MsTag,
|
||||||
|
MsApiCaseList,
|
||||||
|
MsContainer,
|
||||||
|
MsBottomContainer,
|
||||||
|
ShowMoreBtn
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
condition: {},
|
||||||
|
isHide: true,
|
||||||
|
selectApi: {},
|
||||||
|
moduleId: "",
|
||||||
|
deletePath: "/test/case/delete",
|
||||||
|
selectRows: new Set(),
|
||||||
|
buttons: [{name: this.$t('api_test.definition.request.batch_delete'), handleClick: this.handleDeleteBatch}],
|
||||||
|
methodColorMap: new Map(API_METHOD_COLOUR),
|
||||||
|
tableData: [],
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
projectId: "",
|
||||||
|
screenHeight: document.documentElement.clientHeight - 330,//屏幕高度
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
currentProtocol: String,
|
||||||
|
currentModule: Object,
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
currentRow: {
|
||||||
|
type: Object,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created: function () {
|
||||||
|
this.projectId = getCurrentProjectID();
|
||||||
|
this.initApiTable();
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.dragControllerDiv();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
currentModule() {
|
||||||
|
this.initApiTable();
|
||||||
|
this.apiCaseClose();
|
||||||
|
},
|
||||||
|
currentProtocol() {
|
||||||
|
this.initApiTable();
|
||||||
|
this.apiCaseClose();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initApiTable() {
|
||||||
|
this.condition.filters = ["Prepare", "Underway", "Completed"];
|
||||||
|
if (this.currentModule != null) {
|
||||||
|
if (this.currentModule.id == "root") {
|
||||||
|
this.condition.moduleIds = [];
|
||||||
|
} else if (this.currentModule.id == "gc") {
|
||||||
|
this.condition.moduleIds = [];
|
||||||
|
this.condition.filters = ["Trash"];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.condition.moduleIds = this.currentModule.ids;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.projectId != null) {
|
||||||
|
this.condition.projectId = this.projectId;
|
||||||
|
}
|
||||||
|
if (this.currentProtocol != null) {
|
||||||
|
this.condition.protocol = this.currentProtocol;
|
||||||
|
}
|
||||||
|
this.result = this.$post("/api/definition/list/" + this.currentPage + "/" + this.pageSize, this.condition, response => {
|
||||||
|
this.total = response.data.itemCount;
|
||||||
|
this.tableData = response.data.listObject;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleSelect(selection, row) {
|
||||||
|
row.hashTree = [];
|
||||||
|
if (this.selectRows.has(row)) {
|
||||||
|
this.$set(row, "showMore", false);
|
||||||
|
this.selectRows.delete(row);
|
||||||
|
} else {
|
||||||
|
this.$set(row, "showMore", true);
|
||||||
|
this.selectRows.add(row);
|
||||||
|
}
|
||||||
|
let arr = Array.from(this.selectRows);
|
||||||
|
if (this.currentRow) {
|
||||||
|
this.currentRow.apis = arr;
|
||||||
|
}
|
||||||
|
// 选中1个以上的用例时显示更多操作
|
||||||
|
if (this.selectRows.size === 1) {
|
||||||
|
this.$set(arr[0], "showMore", false);
|
||||||
|
} else if (this.selectRows.size === 2) {
|
||||||
|
arr.forEach(row => {
|
||||||
|
this.$set(row, "showMore", true);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSelectAll(selection) {
|
||||||
|
if (selection.length > 0) {
|
||||||
|
if (selection.length === 1) {
|
||||||
|
selection.hashTree = [];
|
||||||
|
this.selectRows.add(selection[0]);
|
||||||
|
} else {
|
||||||
|
this.tableData.forEach(item => {
|
||||||
|
item.hashTree = [];
|
||||||
|
this.$set(item, "showMore", true);
|
||||||
|
this.selectRows.add(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.selectRows.clear();
|
||||||
|
this.tableData.forEach(row => {
|
||||||
|
this.$set(row, "showMore", false);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (this.currentRow) {
|
||||||
|
let arr = Array.from(this.selectRows);
|
||||||
|
this.currentRow.apis = arr;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
this.initApiTable();
|
||||||
|
},
|
||||||
|
buildPagePath(path) {
|
||||||
|
return path + "/" + this.currentPage + "/" + this.pageSize;
|
||||||
|
},
|
||||||
|
|
||||||
|
editApi(row) {
|
||||||
|
this.$emit('editApi', row);
|
||||||
|
},
|
||||||
|
reductionApi(row) {
|
||||||
|
row.status = 'Underway';
|
||||||
|
row.request = null;
|
||||||
|
row.response = null;
|
||||||
|
this.$fileUpload("/api/definition/update", null, [], row, () => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.search();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleDeleteBatch() {
|
||||||
|
if (this.currentModule != undefined && this.currentModule.id == "gc") {
|
||||||
|
this.$alert(this.$t('api_test.definition.request.delete_confirm') + "?", '', {
|
||||||
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
let ids = Array.from(this.selectRows).map(row => row.id);
|
||||||
|
this.$post('/api/definition/deleteBatch/', ids, () => {
|
||||||
|
this.selectRows.clear();
|
||||||
|
this.initApiTable();
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$alert(this.$t('api_test.definition.request.delete_confirm') + "?", '', {
|
||||||
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
let ids = Array.from(this.selectRows).map(row => row.id);
|
||||||
|
this.$post('/api/definition/removeToGc/', ids, () => {
|
||||||
|
this.selectRows.clear();
|
||||||
|
this.initApiTable();
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleTestCase(testCase) {
|
||||||
|
let h = window.screen.height;
|
||||||
|
let svgTop = document.getElementById("svgTop");
|
||||||
|
svgTop.style.height = h / 2 - 200 + "px";
|
||||||
|
|
||||||
|
let svgDown = document.getElementById("svgDown");
|
||||||
|
svgDown.style.height = h / 2 + "px";
|
||||||
|
|
||||||
|
this.selectApi = testCase;
|
||||||
|
let request = JSON.parse(testCase.request);
|
||||||
|
this.selectApi.url = request.path;
|
||||||
|
this.isHide = false;
|
||||||
|
},
|
||||||
|
handleDelete(api) {
|
||||||
|
if (this.currentModule != undefined && this.currentModule.id == "gc") {
|
||||||
|
this.$get('/api/definition/delete/' + api.id, () => {
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
this.initApiTable();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$alert(this.$t('api_test.definition.request.delete_confirm') + ' ' + api.name + " ?", '', {
|
||||||
|
confirmButtonText: this.$t('commons.confirm'),
|
||||||
|
callback: (action) => {
|
||||||
|
if (action === 'confirm') {
|
||||||
|
let ids = [api.id];
|
||||||
|
this.$post('/api/definition/removeToGc/', ids, () => {
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
this.initApiTable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
apiCaseClose() {
|
||||||
|
let h = window.screen.height;
|
||||||
|
|
||||||
|
let svgTop = document.getElementById("svgTop");
|
||||||
|
svgTop.style.height = h - 200 + "px";
|
||||||
|
|
||||||
|
let svgDown = document.getElementById("svgDown");
|
||||||
|
svgDown.style.height = 0 + "px";
|
||||||
|
this.isHide = true;
|
||||||
|
},
|
||||||
|
getColor(enable, method) {
|
||||||
|
if (enable) {
|
||||||
|
return this.methodColorMap.get(method);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dragControllerDiv: function () {
|
||||||
|
let svgResize = document.getElementById("svgResize");
|
||||||
|
let svgTop = document.getElementById("svgTop");
|
||||||
|
let svgDown = document.getElementById("svgDown");
|
||||||
|
let svgBox = document.getElementById("svgBox");
|
||||||
|
svgResize.onmousedown = function (e) {
|
||||||
|
let startY = e.clientY;
|
||||||
|
svgResize.top = svgResize.offsetTop;
|
||||||
|
document.onmousemove = function (e) {
|
||||||
|
let endY = e.clientY;
|
||||||
|
let moveLen = svgResize.top + (endY - startY);
|
||||||
|
let maxT = svgBox.clientHeight - svgResize.offsetHeight;
|
||||||
|
if (moveLen < 30) moveLen = 30;
|
||||||
|
if (moveLen > maxT - 30) moveLen = maxT - 30;
|
||||||
|
svgResize.style.top = moveLen;
|
||||||
|
svgTop.style.height = moveLen + "px";
|
||||||
|
svgDown.style.height = (svgBox.clientHeight - moveLen - 5) + "px";
|
||||||
|
}
|
||||||
|
document.onmouseup = function (evt) {
|
||||||
|
document.onmousemove = null;
|
||||||
|
document.onmouseup = null;
|
||||||
|
svgResize.releaseCapture && svgResize.releaseCapture();
|
||||||
|
}
|
||||||
|
svgResize.setCapture && svgResize.setCapture();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.operate-button > div {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.request-method {
|
||||||
|
padding: 0 5px;
|
||||||
|
color: #1E90FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-el-tag {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#svgBox {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#svgTop {
|
||||||
|
height: calc(30% - 5px);
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#svgResize {
|
||||||
|
position: relative;
|
||||||
|
height: 5px;
|
||||||
|
width: 100%;
|
||||||
|
cursor: s-resize;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#svgDown {
|
||||||
|
height: 70%;
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -23,11 +23,7 @@
|
||||||
<div v-for="(item,index) in apiCaseList" :key="index">
|
<div v-for="(item,index) in apiCaseList" :key="index">
|
||||||
<el-card style="margin-top: 5px" @click.native="selectTestCase(item,$event)">
|
<el-card style="margin-top: 5px" @click.native="selectTestCase(item,$event)">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="1">
|
<el-col :span="6">
|
||||||
<el-checkbox v-if="visible" @change="caseChecked(item)"/>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="5">
|
|
||||||
<div class="el-step__icon is-text ms-api-col">
|
<div class="el-step__icon is-text ms-api-col">
|
||||||
<div class="el-step__icon-inner">{{index+1}}</div>
|
<div class="el-step__icon-inner">{{index+1}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -139,13 +135,12 @@
|
||||||
MsApiExtendBtns
|
MsApiExtendBtns
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
api: {
|
|
||||||
type: Object
|
|
||||||
},
|
|
||||||
createCase: String,
|
createCase: String,
|
||||||
loaded: Boolean,
|
loaded: Boolean,
|
||||||
refreshSign: String,
|
refreshSign: String,
|
||||||
currentRow: Object,
|
currentApi: {
|
||||||
|
type: Object
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -162,22 +157,22 @@
|
||||||
projectId: "",
|
projectId: "",
|
||||||
checkedCases: new Set(),
|
checkedCases: new Set(),
|
||||||
visible: false,
|
visible: false,
|
||||||
condition: {}
|
condition: {},
|
||||||
|
api: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
refreshSign() {
|
refreshSign() {
|
||||||
if (this.currentRow) {
|
this.api = this.currentApi;
|
||||||
this.currentRow.cases = [];
|
|
||||||
}
|
|
||||||
this.getApiTest();
|
this.getApiTest();
|
||||||
},
|
},
|
||||||
createCase() {
|
createCase() {
|
||||||
|
this.api = this.currentApi;
|
||||||
this.sysAddition();
|
this.sysAddition();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
this.api = this.currentApi;
|
||||||
this.projectId = getCurrentProjectID();
|
this.projectId = getCurrentProjectID();
|
||||||
if (this.createCase) {
|
if (this.createCase) {
|
||||||
this.sysAddition();
|
this.sysAddition();
|
||||||
|
@ -186,21 +181,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
open() {
|
open(api) {
|
||||||
this.init();
|
this.api = api;
|
||||||
this.visible = true;
|
|
||||||
},
|
|
||||||
init() {
|
|
||||||
if (this.currentRow) {
|
|
||||||
this.currentRow.cases = [];
|
|
||||||
}
|
|
||||||
this.getApiTest();
|
this.getApiTest();
|
||||||
|
this.visible = true;
|
||||||
},
|
},
|
||||||
setEnvironment(environment) {
|
setEnvironment(environment) {
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
},
|
},
|
||||||
sysAddition() {
|
sysAddition() {
|
||||||
this.condition.projectId = this.api.projectId;
|
this.condition.projectId = this.projectId;
|
||||||
this.condition.apiDefinitionId = this.api.id;
|
this.condition.apiDefinitionId = this.api.id;
|
||||||
this.$post("/api/testcase/list", this.condition, response => {
|
this.$post("/api/testcase/list", this.condition, response => {
|
||||||
for (let index in response.data) {
|
for (let index in response.data) {
|
||||||
|
@ -332,7 +322,8 @@
|
||||||
return bodyUploadFiles;
|
return bodyUploadFiles;
|
||||||
},
|
},
|
||||||
getApiTest() {
|
getApiTest() {
|
||||||
this.condition.projectId = this.api.projectId;
|
if (this.api) {
|
||||||
|
this.condition.projectId = this.projectId;
|
||||||
this.condition.apiDefinitionId = this.api.id;
|
this.condition.apiDefinitionId = this.api.id;
|
||||||
this.result = this.$post("/api/testcase/list", this.condition, response => {
|
this.result = this.$post("/api/testcase/list", this.condition, response => {
|
||||||
for (let index in response.data) {
|
for (let index in response.data) {
|
||||||
|
@ -344,6 +335,7 @@
|
||||||
this.addCase();
|
this.addCase();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
validate(row) {
|
validate(row) {
|
||||||
if (!row.name) {
|
if (!row.name) {
|
||||||
|
@ -356,7 +348,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let bodyFiles = this.getBodyUploadFiles(row);
|
let bodyFiles = this.getBodyUploadFiles(row);
|
||||||
row.projectId = this.api.projectId;
|
row.projectId = this.projectId;
|
||||||
row.apiDefinitionId = row.apiDefinitionId || this.api.id;
|
row.apiDefinitionId = row.apiDefinitionId || this.api.id;
|
||||||
let url = "/api/testcase/create";
|
let url = "/api/testcase/create";
|
||||||
if (row.id) {
|
if (row.id) {
|
||||||
|
@ -386,17 +378,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
caseChecked(row) {
|
|
||||||
row.protocol = this.api.protocol;
|
|
||||||
row.hashTree = [];
|
|
||||||
if (this.checkedCases.has(row)) {
|
|
||||||
this.checkedCases.delete(row);
|
|
||||||
} else {
|
|
||||||
this.checkedCases.add(row)
|
|
||||||
}
|
|
||||||
let arr = Array.from(this.checkedCases);
|
|
||||||
this.currentRow.cases = arr;
|
|
||||||
},
|
|
||||||
handleClose() {
|
handleClose() {
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,26 +69,19 @@
|
||||||
:label="$t('api_test.definition.api_case_passing_rate')"
|
:label="$t('api_test.definition.api_case_passing_rate')"
|
||||||
show-overflow-tooltip/>
|
show-overflow-tooltip/>
|
||||||
|
|
||||||
|
|
||||||
<el-table-column :label="$t('commons.operating')" min-width="130" align="center">
|
<el-table-column :label="$t('commons.operating')" min-width="130" align="center">
|
||||||
<template v-slot:default="scope">
|
<template v-slot:default="scope">
|
||||||
<div v-if="currentRow!=undefined && currentRow.referenced">
|
|
||||||
<el-button type="text" @click="handleTestCase(scope.row)">用例</el-button>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<el-button type="text" @click="reductionApi(scope.row)" v-if="currentModule!=undefined && currentModule.id === 'gc'">恢复</el-button>
|
<el-button type="text" @click="reductionApi(scope.row)" v-if="currentModule!=undefined && currentModule.id === 'gc'">恢复</el-button>
|
||||||
<el-button type="text" @click="editApi(scope.row)" v-else>编辑</el-button>
|
<el-button type="text" @click="editApi(scope.row)" v-else>编辑</el-button>
|
||||||
<el-button type="text" @click="handleTestCase(scope.row)">用例</el-button>
|
<el-button type="text" @click="handleTestCase(scope.row)">用例</el-button>
|
||||||
<el-button type="text" @click="handleDelete(scope.row)" style="color: #F56C6C">删除</el-button>
|
<el-button type="text" @click="handleDelete(scope.row)" style="color: #F56C6C">删除</el-button>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<ms-table-pagination :change="initApiTable" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
<ms-table-pagination :change="initApiTable" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||||
:total="total"/>
|
:total="total"/>
|
||||||
</el-card>
|
</el-card>
|
||||||
<ms-api-case-list @refresh="initApiTable" :currentRow="currentRow"
|
<ms-api-case-list @refresh="initApiTable" :currentApi="selectApi" ref="caseList"/>
|
||||||
:api="selectApi" ref="caseList"/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
@ -146,9 +139,6 @@
|
||||||
visible: {
|
visible: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
|
||||||
currentRow: {
|
|
||||||
type: Object,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
|
@ -198,9 +188,6 @@
|
||||||
this.selectRows.add(row);
|
this.selectRows.add(row);
|
||||||
}
|
}
|
||||||
let arr = Array.from(this.selectRows);
|
let arr = Array.from(this.selectRows);
|
||||||
if (this.currentRow) {
|
|
||||||
this.currentRow.apis = arr;
|
|
||||||
}
|
|
||||||
// 选中1个以上的用例时显示更多操作
|
// 选中1个以上的用例时显示更多操作
|
||||||
if (this.selectRows.size === 1) {
|
if (this.selectRows.size === 1) {
|
||||||
this.$set(arr[0], "showMore", false);
|
this.$set(arr[0], "showMore", false);
|
||||||
|
@ -228,10 +215,6 @@
|
||||||
this.$set(row, "showMore", false);
|
this.$set(row, "showMore", false);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (this.currentRow) {
|
|
||||||
let arr = Array.from(this.selectRows);
|
|
||||||
this.currentRow.apis = arr;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
search() {
|
search() {
|
||||||
this.initApiTable();
|
this.initApiTable();
|
||||||
|
@ -283,11 +266,11 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleTestCase(testCase) {
|
handleTestCase(api) {
|
||||||
this.selectApi = testCase;
|
this.selectApi = api;
|
||||||
let request = JSON.parse(testCase.request);
|
let request = JSON.parse(api.request);
|
||||||
this.selectApi.url = request.path;
|
this.selectApi.url = request.path;
|
||||||
this.$refs.caseList.open();
|
this.$refs.caseList.open(this.selectApi);
|
||||||
},
|
},
|
||||||
handleDelete(api) {
|
handleDelete(api) {
|
||||||
if (this.currentModule != undefined && this.currentModule.id == "gc") {
|
if (this.currentModule != undefined && this.currentModule.id == "gc") {
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
<!-- 加载用例 -->
|
<!-- 加载用例 -->
|
||||||
<el-drawer :visible.sync="visible" direction="btt" :with-header="false" :modal="false" size="50%">
|
<el-drawer :visible.sync="visible" direction="btt" :with-header="false" :modal="false" size="50%">
|
||||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :api="api"
|
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :currentApi="api"
|
||||||
:loaded="loaded" :refreshSign="refreshSign" :createCase="createCase"
|
:loaded="loaded" :refreshSign="refreshSign" :createCase="createCase"
|
||||||
ref="caseList"/>
|
ref="caseList"/>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
:loaded="loaded"
|
:loaded="loaded"
|
||||||
:refreshSign="refreshSign"
|
:refreshSign="refreshSign"
|
||||||
:createCase="createCase"
|
:createCase="createCase"
|
||||||
:api="api"
|
:currentApi="api"
|
||||||
ref="caseList"/>
|
ref="caseList"/>
|
||||||
|
|
||||||
<!-- 环境 -->
|
<!-- 环境 -->
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
<!-- 加载用例 -->
|
<!-- 加载用例 -->
|
||||||
<el-drawer :visible.sync="visible" direction="btt" :with-header="false" :modal="false" size="50%">
|
<el-drawer :visible.sync="visible" direction="btt" :with-header="false" :modal="false" size="50%">
|
||||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :api="api" :refreshSign="refreshSign"
|
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :currentApi="api" :refreshSign="refreshSign"
|
||||||
:loaded="loaded" :createCase="createCase"
|
:loaded="loaded" :createCase="createCase"
|
||||||
ref="caseList"/>
|
ref="caseList"/>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
<!-- 加载用例 -->
|
<!-- 加载用例 -->
|
||||||
<el-drawer :visible.sync="visible" direction="btt" :with-header="false" :modal="false" size="50%">
|
<el-drawer :visible.sync="visible" direction="btt" :with-header="false" :modal="false" size="50%">
|
||||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :api="api" :refreshSign="refreshSign"
|
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :currentApi="api" :refreshSign="refreshSign"
|
||||||
:loaded="loaded" :createCase="createCase"
|
:loaded="loaded" :createCase="createCase"
|
||||||
ref="caseList"/>
|
ref="caseList"/>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
Loading…
Reference in New Issue