Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
576b858977
|
@ -31,6 +31,7 @@ public class ApiAutomationController {
|
|||
|
||||
|
||||
@PostMapping("/list/{goPage}/{pageSize}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||
public Pager<List<ApiScenarioDTO>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody ApiScenarioRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
|
|
|
@ -226,6 +226,7 @@
|
|||
},
|
||||
reductionApi(row) {
|
||||
row.scenarioDefinition = null;
|
||||
row.tags = null;
|
||||
let rows = [row];
|
||||
this.$post("/api/automation/reduction", rows, response => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
|
|
|
@ -224,7 +224,7 @@
|
|||
</div>
|
||||
|
||||
<!--接口列表-->
|
||||
<el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="true" :modal="false" size="90%">
|
||||
<el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :modal="false" size="90%">
|
||||
<ms-api-definition :visible="visibleRef" :currentRow="currentRow"/>
|
||||
<el-button style="float: right;margin: 0px 20px 0px" type="primary" @click="pushApiOrCase('REF')">{{$t('api_test.scenario.reference')}}</el-button>
|
||||
<el-button style="float: right;" type="primary" @click="pushApiOrCase('Copy')">{{ $t('commons.copy') }}</el-button>
|
||||
|
@ -839,7 +839,7 @@
|
|||
}
|
||||
|
||||
.ms-col-one {
|
||||
margin-top: 6px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.ms-right-buttion {
|
||||
|
|
|
@ -4,21 +4,24 @@
|
|||
<el-header style="width: 100% ;padding: 0px">
|
||||
<el-card>
|
||||
<el-row>
|
||||
<el-col :span="api.protocol==='HTTP'? 3:5">
|
||||
<el-col :span="2" class="ms-api-col">
|
||||
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="api.protocol==='HTTP'? 3:6" class="ms-api-col">
|
||||
<div class="variable-combine"> {{api.name}}</div>
|
||||
</el-col>
|
||||
<el-col :span="api.protocol==='HTTP'? 1:3">
|
||||
<el-col :span="api.protocol==='HTTP'? 1:3" class="ms-api-col">
|
||||
<el-tag size="mini" :style="{'background-color': getColor(true, api.method), border: getColor(true, api.method)}" class="api-el-tag">
|
||||
{{ api.method}}
|
||||
</el-tag>
|
||||
</el-col>
|
||||
<el-col :span="api.protocol==='HTTP'? 4:0">
|
||||
<el-col :span="api.protocol==='HTTP'? 5:0" class="ms-api-col">
|
||||
<div class="variable-combine" style="margin-left: 10px">{{api.path ===null ? " " : api.path}}</div>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-col :span="2" class="ms-api-col">
|
||||
<div>{{$t('test_track.plan_view.case_count')}}:{{apiCaseList.length}}</div>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-col :span="4">
|
||||
<div>
|
||||
<el-select size="small" :placeholder="$t('api_test.definition.request.grade_info')" v-model="priorityValue"
|
||||
class="ms-api-header-select" @change="getApiTest">
|
||||
|
@ -26,28 +29,7 @@
|
|||
</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">
|
||||
<el-col :span="4">
|
||||
<div class="ms-api-header-select">
|
||||
<el-input size="small" :placeholder="$t('api_test.definition.request.select_case')"
|
||||
v-model="name" @blur="getApiTest"/>
|
||||
|
@ -61,76 +43,67 @@
|
|||
|
||||
</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-model="item.checked" @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')}}
|
||||
<el-main v-loading="loading" style="overflow: auto;padding: 5px 10px 10px">
|
||||
<el-checkbox-group v-model="checkedIndex" @change="handleCheckedChange">
|
||||
<div v-for="(item,index) in apiCaseList" :key="index">
|
||||
<el-card style="margin-top: 5px">
|
||||
<el-row>
|
||||
<el-col :span="1" class="ms-api-col">
|
||||
<el-checkbox :key="item.id" :label="index+1"/>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<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">
|
||||
<span v-if="item.type!='create'" style="color: #303132;font-size: 13px">
|
||||
<i class="icon el-icon-arrow-right" :class="{'is-active': item.active}"
|
||||
@click="active(item)"/>
|
||||
{{item.name}}
|
||||
</span>
|
||||
<span>
|
||||
{{item.updateTime | timestampFormatDate }}
|
||||
{{item.updateUser}} {{$t('api_test.definition.request.update_info')}}
|
||||
</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<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>
|
||||
<el-col :span="6">
|
||||
<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-checkbox-group>
|
||||
|
||||
<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>
|
||||
|
@ -143,8 +116,6 @@
|
|||
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";
|
||||
|
@ -159,7 +130,6 @@
|
|||
MsTag,
|
||||
MsTipButton,
|
||||
MsApiRequestForm,
|
||||
ApiEnvironmentConfig,
|
||||
MsApiAssertions,
|
||||
MsSqlBasisParameters,
|
||||
MsTcpBasisParameters,
|
||||
|
@ -192,8 +162,12 @@
|
|||
runData: [],
|
||||
reportId: "",
|
||||
projectId: "",
|
||||
checkedCases: new Set(),
|
||||
methodColorMap: new Map(API_METHOD_COLOUR),
|
||||
|
||||
checkAll: false,
|
||||
checkedIndex: [],
|
||||
isIndeterminate: true
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -207,7 +181,6 @@
|
|||
},
|
||||
created() {
|
||||
this.projectId = getCurrentProjectID();
|
||||
this.getEnvironments();
|
||||
this.getApiTest();
|
||||
},
|
||||
methods: {
|
||||
|
@ -218,11 +191,6 @@
|
|||
return RESULT_MAP.get("default");
|
||||
}
|
||||
},
|
||||
handleCommand(e) {
|
||||
if (e === "run") {
|
||||
this.batchRun();
|
||||
}
|
||||
},
|
||||
showInput(row) {
|
||||
row.type = "create";
|
||||
row.active = true;
|
||||
|
@ -232,112 +200,12 @@
|
|||
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.api) {
|
||||
this.checkedCases = new Set();
|
||||
this.loading = true;
|
||||
if (this.currentRow) {
|
||||
this.currentRow.cases = [];
|
||||
|
@ -364,61 +232,40 @@
|
|||
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.api && 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();
|
||||
},
|
||||
|
||||
getColor(enable, method) {
|
||||
if (enable) {
|
||||
return this.methodColorMap.get(method);
|
||||
}
|
||||
},
|
||||
caseChecked(row) {
|
||||
row.protocol = this.api.protocol;
|
||||
row.hashTree = [];
|
||||
if (this.checkedCases.has(row)) {
|
||||
this.checkedCases.delete(row);
|
||||
handleCheckAllChange(val) {
|
||||
this.currentRow.cases = [];
|
||||
if (val) {
|
||||
let index = 1;
|
||||
this.apiCaseList.forEach(item => {
|
||||
this.checkedIndex.push(index);
|
||||
item.protocol = this.api.protocol;
|
||||
item.hashTree = [];
|
||||
this.currentRow.cases.push(item)
|
||||
index++;
|
||||
})
|
||||
} else {
|
||||
this.checkedCases.add(row)
|
||||
this.checkedIndex = [];
|
||||
}
|
||||
let arr = Array.from(this.checkedCases);
|
||||
this.currentRow.cases = arr;
|
||||
this.isIndeterminate = false;
|
||||
},
|
||||
handleCheckedChange(value) {
|
||||
let checkedCount = value.length;
|
||||
this.checkAll = checkedCount === this.apiCaseList.length;
|
||||
this.isIndeterminate = checkedCount > 0 && checkedCount < this.apiCaseList.length;
|
||||
this.currentRow.cases = [];
|
||||
value.forEach(i => {
|
||||
let index = i - 1;
|
||||
let item = this.apiCaseList[index];
|
||||
item.protocol = this.api.protocol;
|
||||
item.hashTree = [];
|
||||
this.currentRow.cases.push(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -449,14 +296,11 @@
|
|||
}
|
||||
|
||||
.ms-api-label {
|
||||
color: #CCCCCC;
|
||||
/*color: #CCCCCC;*/
|
||||
}
|
||||
|
||||
.ms-api-col {
|
||||
background-color: #7C3985;
|
||||
border-color: #7C3985;
|
||||
margin-right: 10px;
|
||||
color: white;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.variable-combine {
|
||||
|
@ -486,6 +330,7 @@
|
|||
.api-el-tag {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.is-selected {
|
||||
background: #EFF7FF;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue