This commit is contained in:
chenjianxing 2020-12-23 17:21:47 +08:00
commit 576b858977
4 changed files with 103 additions and 256 deletions

View File

@ -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());

View File

@ -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'));

View File

@ -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 {

View File

@ -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;
}