This commit is contained in:
shiziyuan9527 2020-12-08 15:19:28 +08:00
commit c0eeab33ba
24 changed files with 488 additions and 103 deletions

View File

@ -1,5 +1,6 @@
package io.metersphere.api.dto.automation;
import io.metersphere.api.dto.definition.request.MsTestElement;
import lombok.Getter;
import lombok.Setter;
@ -36,7 +37,7 @@ public class SaveApiScenarioRequest {
private String description;
private String scenarioDefinition;
private MsTestElement scenarioDefinition;
List<String> bodyUploadIds;
}

View File

@ -7,6 +7,7 @@ import com.alibaba.fastjson.annotation.JSONType;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.metersphere.api.dto.scenario.KeyValue;
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.api.service.ApiTestEnvironmentService;
@ -36,6 +37,9 @@ public class MsScenario extends MsTestElement {
@JSONField(ordinal = 12)
private String environmentId;
@JSONField(ordinal = 13)
private List<KeyValue> variables;
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, EnvironmentConfig config) {
if (environmentId != null) {
ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);

View File

@ -60,6 +60,14 @@ public class MsTestElement {
@JSONField(ordinal = 3)
private String label;
@JSONField(ordinal = 4)
private String resourceId;
@JSONField(ordinal = 5)
private String referenced;
@JSONField(ordinal = 6)
private boolean active;
@JSONField(ordinal = 7)
private String index;
@JSONField(ordinal = 8)
private LinkedList<MsTestElement> hashTree;
// 公共环境逐层传递如果自身有环境 以自身引用环境为准否则以公共环境作为请求环境

View File

@ -5,12 +5,21 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import io.metersphere.api.dto.ApiTestImportRequest;
import io.metersphere.api.dto.definition.ApiDefinitionResult;
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
import io.metersphere.api.dto.scenario.Body;
import io.metersphere.api.dto.scenario.KeyValue;
import io.metersphere.api.dto.scenario.request.RequestType;
import io.metersphere.commons.constants.MsRequestBodyType;
import org.apache.commons.lang3.StringUtils;
import io.metersphere.api.service.ApiModuleService;
import io.metersphere.base.domain.ApiModule;
import io.metersphere.commons.utils.CommonBeanFactory;
import org.apache.commons.collections.CollectionUtils;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MsParser extends ApiImportAbstractParser {
@ -18,43 +27,72 @@ public class MsParser extends ApiImportAbstractParser {
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
String testStr = getApiTestStr(source);
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
if (testObject.get("projectName") == null) {
testStr = parsePluginFormat(testObject);
apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
this.projectId = request.getProjectId();
if (testObject.get("projectName") != null) {
return parseMsFormat(testStr, request);
} else {
return parsePluginFormat(testObject);
}
ApiDefinitionImport apiImport = JSON.parseObject(testStr, ApiDefinitionImport.class);
}
private ApiDefinitionImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) {
ApiDefinitionImport apiDefinitionImport = JSON.parseObject(testStr, ApiDefinitionImport.class);
List<ApiDefinitionResult> data = apiDefinitionImport.getData();
data.forEach(apiDefinition -> {
String id = UUID.randomUUID().toString();
apiDefinition.setModuleId(null);
apiDefinition.setId(id);
apiDefinition.setProjectId(this.projectId);
String request = apiDefinition.getRequest();
JSONObject requestObj = JSONObject.parseObject(request);
requestObj.put("id", id);
apiDefinition.setRequest(JSONObject.toJSONString(requestObj));
});
return apiDefinitionImport;
}
private ApiDefinitionImport parsePluginFormat(JSONObject testObject) {
List<ApiDefinitionResult> results = new ArrayList<>();
ApiDefinitionImport apiImport = new ApiDefinitionImport();
apiImport.setProtocol(RequestType.HTTP);
apiImport.setData(results);
testObject.keySet().forEach(tag -> {
ApiModule module = apiModuleService.getNewModule(tag, this.projectId, 1);
createModule(module);
JSONObject requests = testObject.getJSONObject(tag);
requests.keySet().forEach(requestName -> {
JSONObject requestObject = requests.getJSONObject(requestName);
String path = requestObject.getString("url");
String method = requestObject.getString("method");
MsHTTPSamplerProxy request = buildRequest(requestName, path, method);
ApiDefinitionResult apiDefinition = buildApiDefinition(request.getId(), requestName, path, method);
apiDefinition.setModuleId(module.getId());
apiDefinition.setProjectId(this.projectId);
parseBody(requestObject, request.getBody());
parseHeader(requestObject, request.getHeaders());
apiDefinition.setRequest(JSONObject.toJSONString(request));
results.add(apiDefinition);
});
});
return apiImport;
}
private String parsePluginFormat( JSONObject testObject) {
//插件格式
JSONArray scenarios = new JSONArray();
testObject.keySet().forEach(scenarioName -> {
JSONObject scenario = new JSONObject();
scenario.put("name", scenarioName);
JSONArray requestsObjects = new JSONArray();
JSONObject requestsObject = testObject.getJSONObject(scenarioName);
requestsObject.keySet().forEach(requestName -> {
JSONObject requestObject = new JSONObject(true);
JSONObject requestTmpObject = requestsObject.getJSONObject(requestName);
//排序确保type在第一个否则转换失败
if (StringUtils.isBlank(requestTmpObject.getString("type"))) {
requestObject.put("type", RequestType.HTTP);
}
requestTmpObject.keySet().forEach(key -> requestObject.put(key, requestTmpObject.get(key)));
requestObject.put("name", requestName);
parseBody(requestObject);
requestsObjects.add(requestObject);
});
scenario.put("requests", requestsObjects);
scenarios.add(scenario);
});
JSONObject result = new JSONObject();
result.put("scenarios", scenarios);
return result.toJSONString();
private void parseHeader(JSONObject requestObject, List<KeyValue> msHeaders) {
JSONArray headers = requestObject.getJSONArray("headers");
if (CollectionUtils.isNotEmpty(headers)) {
for (int i = 0; i < headers.size(); i++) {
JSONObject header = headers.getJSONObject(i);
msHeaders.add(new KeyValue(header.getString("name"), header.getString("value")));
}
}
}
private void parseBody(JSONObject requestObject) {
private void parseBody(JSONObject requestObject, Body msBody) {
if (requestObject.containsKey("body")) {
Object body = requestObject.get("body");
if (body instanceof JSONArray) {
@ -65,25 +103,18 @@ public class MsParser extends ApiImportAbstractParser {
String tmp = bodies.getString(i);
bodyStr.append(tmp);
}
JSONObject bodyObject = new JSONObject();
bodyObject.put("raw", bodyStr);
bodyObject.put("type", MsRequestBodyType.RAW.value());
requestObject.put("body", bodyObject);
msBody.setType(Body.RAW);
msBody.setRaw(bodyStr.toString());
}
} else if (body instanceof JSONObject) {
JSONObject bodyObj = requestObject.getJSONObject("body");
if (bodyObj != null) {
JSONArray kvs = new JSONArray();
ArrayList<KeyValue> kvs = new ArrayList<>();
bodyObj.keySet().forEach(key -> {
JSONObject kv = new JSONObject();
kv.put("name", key);
kv.put("value", bodyObj.getString(key));
kvs.add(kv);
kvs.add(new KeyValue(key, bodyObj.getString(key)));
});
JSONObject bodyRes = new JSONObject();
bodyRes.put("kvs", kvs);
bodyRes.put("type", MsRequestBodyType.KV.value());
requestObject.put("body", bodyRes);
msBody.setKvs(kvs);
msBody.setType(Body.WWW_FROM);
}
}
}

View File

@ -156,9 +156,9 @@ public class Swagger2Parser extends ApiImportAbstractParser {
case "application/xml":
bodyType = Body.XML;
break;
// case "": //todo binary 啥类型
// bodyType = Body.BINARY;
// break;
case "":
bodyType = Body.BINARY;
break;
default:
bodyType = Body.RAW;
}
@ -235,7 +235,6 @@ public class Swagger2Parser extends ApiImportAbstractParser {
refSet.add(simpleRef);
if (model != null) {
JSONObject bodyParameters = getBodyParameters(model.getProperties(), refSet);
//body.setRaw(bodyParameters.toJSONString());
return bodyParameters.toJSONString();
}
} else if (schema instanceof ArrayModel) {
@ -250,7 +249,6 @@ public class Swagger2Parser extends ApiImportAbstractParser {
Model model = definitions.get(simpleRef);
JSONArray propertyList = new JSONArray();
propertyList.add(getBodyParameters(model.getProperties(), refSet));
// body.setRaw(propertyList.toString());
return propertyList.toString();
}
}

View File

@ -101,7 +101,7 @@ public class ApiAutomationService {
scenario.setFollowPeople(request.getFollowPeople());
scenario.setPrincipal(request.getPrincipal());
scenario.setStepTotal(request.getStepTotal());
scenario.setScenarioDefinition(request.getScenarioDefinition());
scenario.setScenarioDefinition(JSON.toJSONString(request.getScenarioDefinition()));
scenario.setCreateTime(System.currentTimeMillis());
scenario.setUpdateTime(System.currentTimeMillis());
if (StringUtils.isNotEmpty(request.getStatus())) {
@ -137,7 +137,7 @@ public class ApiAutomationService {
scenario.setFollowPeople(request.getFollowPeople());
scenario.setPrincipal(request.getPrincipal());
scenario.setStepTotal(request.getStepTotal());
scenario.setScenarioDefinition(request.getScenarioDefinition());
scenario.setScenarioDefinition(JSON.toJSONString(request.getScenarioDefinition()));
scenario.setUpdateTime(System.currentTimeMillis());
if (StringUtils.isNotEmpty(request.getStatus())) {
scenario.setStatus(request.getStatus());

View File

@ -86,6 +86,7 @@ export default {
background-color: rgb(44, 42, 72);
color: rgb(245, 245, 245);
font-size: 14px;
height: 40px;
}
.logo {

View File

@ -56,7 +56,7 @@
},
editApi(row) {
let name = this.request.name;
Object.assign(this.request, JSON.parse(row.request));
Object.assign(this.request, row.request);
this.request.name = name;
this.request.resourceId = getUUID();
this.$emit('addCustomizeApi', this.request);

View File

@ -0,0 +1,111 @@
<template>
<div>
<span class="kv-description" v-if="description">
{{description}}
</span>
<div class="kv-row" v-for="(item, index) in items" :key="index">
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
<el-col class="kv-checkbox">
<input type="checkbox" v-if="!isDisable(index)" @change="change" :value="item.uuid" v-model="item.enable"
:disabled="isDisable(index) || isReadOnly"/>
</el-col>
<el-col>
<ms-api-variable-input :show-copy="showCopy" :show-variable="showVariable" :is-read-only="isReadOnly" v-model="item.name" size="small" maxlength="200" @change="change"
:placeholder="$t('api_test.variable_name')" show-word-limit/>
</el-col>
<el-col>
<el-input :disabled="isReadOnly" v-model="item.value" size="small" @change="change"
:placeholder="$t('api_test.value')" show-word-limit/>
</el-col>
<el-col class="kv-delete">
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"
:disabled="isDisable(index) || isReadOnly"/>
</el-col>
</el-row>
</div>
</div>
</template>
<script>
import {KeyValue} from "../../definition/model/ApiTestModel";
import MsApiVariableInput from "./ApiVariableInput";
export default {
name: "MsApiScenarioVariables",
components: {MsApiVariableInput},
props: {
description: String,
items: Array,
isReadOnly: {
type: Boolean,
default: false
},
showVariable: {
type: Boolean,
default: true
},
showCopy: {
type: Boolean,
default: true
},
},
data() {
return {
}
},
methods: {
remove: function (index) {
this.items.splice(index, 1);
this.$emit('change', this.items);
},
change: function () {
let isNeedCreate = true;
let removeIndex = -1;
this.items.forEach((item, index) => {
if (!item.name && !item.value) {
//
if (index !== this.items.length - 1) {
removeIndex = index;
}
//
isNeedCreate = false;
}
});
if (isNeedCreate) {
this.items.push(new KeyValue({enable: true}));
}
this.$emit('change', this.items);
// TODO key
},
isDisable: function (index) {
return this.items.length - 1 === index;
}
},
created() {
if (this.items.length === 0) {
this.items.push(new KeyValue({enable: true}));
}
}
}
</script>
<style scoped>
.kv-description {
font-size: 13px;
}
.kv-checkbox {
width: 20px;
margin-right: 10px;
}
.kv-row {
margin-top: 10px;
}
.kv-delete {
width: 60px;
}
</style>

View File

@ -0,0 +1,123 @@
<template>
<div class="variable-input" :class="{'show-copy': !showCopy}">
<el-input class="el-input__inner_pd" :disabled="isReadOnly" :value="value" v-bind="$attrs" :size="size" @change="change" @input="input"/>
<div :class="{'hidden': !showVariable}" class="variable-combine" v-if="value">
<div v-if="showCopy" class="variable">{{variable}}</div>
<el-tooltip v-if="showCopy" :content="$t('api_test.copied')" manual v-model="visible" placement="top" :visible-arrow="false">
<i class="el-icon-copy-document copy" @click="copy"/>
</el-tooltip>
</div>
</div>
</template>
<script>
export default {
name: "MsApiVariableInput",
props: {
value: String,
size: String,
isReadOnly: {
type: Boolean,
default: false
},
showVariable: {
type: Boolean,
default: true
},
showCopy: {
type: Boolean,
default: true
},
showCopyTipWithMultiple: {
type: Boolean,
default: false
},
},
data() {
return {
visible: false
}
},
methods: {
copy() {
let input = document.createElement("input");
document.body.appendChild(input);
input.value = this.variable;
input.select();
if (input.setSelectionRange) {
input.setSelectionRange(0, input.value.length);
}
document.execCommand("copy");
document.body.removeChild(input);
this.visible = true;
setTimeout(() => {
this.visible = false;
}, 1000);
},
change(value) {
this.$emit('change', value);
},
input(value) {
this.$emit('input', value);
}
},
computed: {
variable() {
return "${" + (this.showCopyTipWithMultiple ? (this.value + "_n") : this.value) + "}";
}
}
}
</script>
<style scoped>
.variable-input {
position: relative;
}
.el-input__inner_pd >>> .el-input__inner {
padding-right: 135px;
}
.show-copy .el-input__inner_pd >>> .el-input__inner {
padding-right: 0px;
}
.variable-combine {
color: #7F7F7F;
max-width: 80px;
line-height: 32px;
position: absolute;
top: 0;
right: 70px;
margin-right: -20px;
display: flex;
align-items: center;
}
.variable-combine .variable {
display: inline-block;
max-width: 60px;
margin-right: 10px;
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.variable-combine .copy {
font-size: 14px;
cursor: pointer;
color: #1E90FF;
}
.hidden {
visibility: hidden;
}
</style>

View File

@ -125,10 +125,12 @@
{{currentScenario.name ===undefined || ''? $t('api_test.scenario.name') : currentScenario.name}}
</el-col>
<el-col :span="4" class="ms-col-one">
{{$t('api_test.automation.step_total')}}:{{scenarioDefinition.length}}
{{$t('api_test.automation.step_total')}}{{scenarioDefinition.length}}
</el-col>
<el-col :span="4" class="ms-col-one">
{{$t('api_test.automation.scenario_total')}}:
<el-link style="font-size: 13px" @click="showScenarioParameters">{{$t('api_test.automation.scenario_total')}}
{{this.currentScenario.variables!=undefined?this.currentScenario.variables.length-1: 0}}
</el-link>
</el-col>
<el-col :span="8">
{{$t('api_test.definition.request.run_env')}}:
@ -263,6 +265,9 @@
<el-drawer :visible.sync="debugVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('test_track.plan_view.test_result')" :modal="false" size="90%">
<ms-api-report-detail :report-id="reportId" :currentProjectId="currentProject.id"/>
</el-drawer>
<!--场景公共参数-->
<ms-scenario-parameters :currentScenario="currentScenario" @addParameters="addParameters" ref="scenarioParameters"/>
</div>
</el-card>
</template>
@ -288,6 +293,7 @@
import MsImportApiScenario from "./ImportApiScenario";
import MsApiScenarioComponent from "./ApiScenarioComponent";
import MsApiReportDetail from "../report/ApiReportDetail";
import MsScenarioParameters from "./ScenarioParameters";
export default {
@ -297,7 +303,15 @@
currentProject: {},
currentScenario: {},
},
components: {ApiEnvironmentConfig, MsApiReportDetail, MsAddTag, MsRun, MsApiScenarioComponent, MsImportApiScenario, MsJsr233Processor, MsConstantTimer, MsIfController, MsApiAssertions, MsApiExtract, MsApiDefinition, MsApiComponent, MsApiCustomize},
components: {
ApiEnvironmentConfig, MsScenarioParameters,
MsApiReportDetail, MsAddTag, MsRun,
MsApiScenarioComponent, MsImportApiScenario,
MsJsr233Processor, MsConstantTimer,
MsIfController, MsApiAssertions,
MsApiExtract, MsApiDefinition,
MsApiComponent, MsApiCustomize
},
data() {
return {
props: {
@ -648,9 +662,6 @@
if (valid) {
this.setParameter();
let bodyFiles = this.getBodyUploadFiles(this.currentScenario);
console.log(bodyFiles)
console.log(this.currentScenario.bodyUploadIds)
this.$fileUpload(this.path, null, bodyFiles, this.currentScenario, () => {
this.$success(this.$t('commons.save_success'));
this.path = "/api/automation/update";
@ -685,7 +696,7 @@
this.currentScenario.modulePath = this.getPath(this.currentScenario.apiScenarioModuleId);
// 便
let scenario = {id: this.currentScenario.id, name: this.currentScenario.name, type: "scenario", referenced: 'Created', environmentId: this.currentEnvironmentId, hashTree: this.scenarioDefinition};
this.currentScenario.scenarioDefinition = JSON.stringify(scenario);
this.currentScenario.scenarioDefinition = scenario;
this.currentScenario.tagId = JSON.stringify(this.currentScenario.tagId);
if (this.currentModule != null) {
this.currentScenario.modulePath = this.currentModule.method !== undefined ? this.currentModule.method : null;
@ -695,6 +706,13 @@
runRefresh() {
this.debugVisible = true;
this.isReloadData = false;
},
showScenarioParameters() {
this.$refs.scenarioParameters.open(this.currentScenario.variables);
},
addParameters(data) {
this.currentScenario.variables = data;
this.reload();
}
}
}

View File

@ -0,0 +1,55 @@
<template>
<el-dialog :close-on-click-modal="false" :title="$t('api_test.scenario.variables')"
:visible.sync="visible" class="environment-dialog" width="60%"
@close="close">
<el-container>
<ms-api-scenario-variables :items="variables"
:description="$t('api_test.scenario.kv_description')"/>
</el-container>
<template v-slot:footer>
<ms-dialog-footer
@cancel="close"
@confirm="saveParameters"/>
</template>
</el-dialog>
</template>
<script>
import MsApiScenarioVariables from "./ApiScenarioVariables";
import {KeyValue} from "../../definition/model/ApiTestModel";
import MsDialogFooter from "../../../common/components/MsDialogFooter";
export default {
name: "MsScenarioParameters",
components: {
MsApiScenarioVariables,
MsDialogFooter
},
data() {
return {
variables: [new KeyValue()],
visible: false,
}
},
methods: {
open: function (v) {
this.visible = true;
if(v){
this.variables = v;
}
},
close() {
this.visible = false;
},
saveParameters() {
this.visible = false;
this.$emit('addParameters', this.variables);
}
}
}
</script>
<style scoped>
</style>

View File

@ -190,6 +190,7 @@
api: {
type: Object
},
createCase: String,
visible: {
type: Boolean,
default: false,
@ -217,7 +218,6 @@
}
},
watch: {
//
api() {
@ -237,13 +237,35 @@
this.currentRow.cases = [];
}
this.getApiTest();
},
createCase() {
this.sysAddition();
}
},
created() {
this.getApiTest();
this.getEnvironments();
if (this.createCase) {
this.sysAddition();
} else {
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);

View File

@ -91,35 +91,38 @@
this.maintainerOptions = response.data;
});
},
initSql() {
setRequest() {
if (this.currentApi.request != undefined && this.currentApi.request != null) {
this.request = JSON.parse(this.currentApi.request);
if (Object.prototype.toString.call(this.currentApi.request).match(/\[object (\w+)\]/)[1].toLowerCase() === 'object') {
this.request = this.currentApi.request;
} else {
this.request = JSON.parse(this.currentApi.request);
}
this.currentApi.request = this.request;
} else {
return true;
}
return false;
},
initSql() {
if (!this.setRequest()) {
this.request = createComponent("JDBCSampler");
this.currentApi.request = this.request;
}
},
initDubbo() {
if (this.currentApi.request != undefined && this.currentApi.request != null) {
this.request = JSON.parse(this.currentApi.request);
this.currentApi.request = this.request;
} else {
if (!this.setRequest()) {
this.request = createComponent("DubboSampler");
this.currentApi.request = this.request;
}
},
initTcp() {
if (this.currentApi.request != undefined && this.currentApi.request != null) {
this.request = JSON.parse(this.currentApi.request);
this.currentApi.request = this.request;
} else {
if (!this.setRequest()) {
this.request = createComponent("TCPSampler");
this.currentApi.request = this.request;
}
},
initHttp() {
if (this.currentApi.request != undefined && this.currentApi.request != null) {
this.request = JSON.parse(this.currentApi.request);
this.currentApi.request = this.request;
} else {
if (!this.setRequest()) {
this.request = createComponent("HTTPSamplerProxy");
this.currentApi.request = this.request;
}

View File

@ -97,7 +97,7 @@
this.$refs.debugResult.reload();
},
saveAs() {
let obj = {request: JSON.stringify(this.request)};
let obj = {request: this.request};
this.$emit('saveAs', obj);
}
}

View File

@ -120,7 +120,7 @@
saveAs() {
this.$refs['debugForm'].validate((valid) => {
if (valid) {
this.debugForm.request = JSON.stringify(this.request);
this.debugForm.request = this.request;
this.debugForm.userId = getCurrentUser().id;
this.debugForm.status = "Underway";
this.debugForm.protocol = this.currentProtocol;

View File

@ -99,7 +99,7 @@
this.$refs.debugResult.reload();
},
saveAs() {
let obj = {request: JSON.stringify(this.request)};
let obj = {request: this.request};
this.$emit('saveAs', obj);
}
}

View File

@ -98,7 +98,7 @@
this.$refs.debugResult.reload();
},
saveAs() {
let obj = {request: JSON.stringify(this.request)};
let obj = {request: this.request};
this.$emit('saveAs', obj);
}
}

View File

@ -31,7 +31,7 @@
<!-- 加载用例 -->
<el-drawer :visible.sync="visible" direction="btt" :with-header="false" :modal="false" size="50%">
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :api="api"
:currentProject="currentProject" :loaded="loaded" :refreshSign="refreshSign"
:currentProject="currentProject" :loaded="loaded" :refreshSign="refreshSign" :createCase="createCase"
ref="caseList"/>
</el-drawer>
>
@ -78,6 +78,7 @@
loaded: false,
loading: false,
currentRequest: {},
createCase: "",
refreshSign: "",
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
reqOptions: REQ_METHOD,
@ -153,9 +154,10 @@
return bodyUploadFiles;
},
saveAsCase() {
this.visible = false;
//
this.createCase = getUUID();
this.visible = true;
this.loaded = false;
this.$refs.caseList.addCase();
},
saveAsApi() {
let data = {};

View File

@ -70,9 +70,9 @@
</el-card>
<!-- 加载用例 -->
<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%" ref="drawer">
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :api="api" :refreshSign="refreshSign"
:currentProject="currentProject" :loaded="loaded"
:currentProject="currentProject" :loaded="loaded" :createCase="createCase"
ref="caseList"/>
</el-drawer>
@ -113,8 +113,9 @@
api: {},
loaded: false,
loading: false,
createCase: "",
currentRequest: {},
refreshSign:"",
refreshSign: "",
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
reqOptions: REQ_METHOD,
environments: [],
@ -194,7 +195,9 @@
return bodyUploadFiles;
},
saveAsCase() {
this.visible = false;
//
this.createCase = getUUID();
this.visible = true;
this.loaded = false;
},
saveAsApi() {
@ -301,7 +304,8 @@
border-radius: 4px;
border-left: 4px solid #783887;
}
/deep/.el-drawer{
/deep/ .el-drawer {
overflow: auto;
}
</style>

View File

@ -30,9 +30,10 @@
<!-- 加载用例 -->
<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"
:currentProject="currentProject" :loaded="loaded"
:currentProject="currentProject" :loaded="loaded" :createCase="createCase"
ref="caseList"/>
</el-drawer>>
</el-drawer>
>
<!-- 环境 -->
<api-environment-config ref="environmentConfig" @close="environmentConfigClose"/>
@ -79,6 +80,7 @@
responseData: {type: 'HTTP', responseResult: {}, subRequestResults: []},
reqOptions: REQ_METHOD,
refreshSign: "",
createCase: "",
environments: [],
rules: {
method: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
@ -151,9 +153,9 @@
return bodyUploadFiles;
},
saveAsCase() {
this.visible = false;
this.createCase = getUUID();
this.visible = true;
this.loaded = false;
this.$refs.caseList.addCase();
},
saveAsApi() {
let data = {};
@ -249,7 +251,8 @@
border-radius: 4px;
border-left: 4px solid #783887;
}
/deep/.el-drawer{
/deep/ .el-drawer {
overflow: auto;
}
</style>

View File

@ -31,7 +31,7 @@
<!-- 加载用例 -->
<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"
:currentProject="currentProject" :loaded="loaded"
:currentProject="currentProject" :loaded="loaded" :createCase="createCase"
ref="caseList"/>
</el-drawer>
<!-- 环境 -->
@ -80,6 +80,7 @@
reqOptions: REQ_METHOD,
environments: [],
refreshSign: "",
createCase: "",
rules: {
method: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
url: [{required: true, message: this.$t('api_test.definition.request.path_info'), trigger: 'blur'}],
@ -151,9 +152,9 @@
return bodyUploadFiles;
},
saveAsCase() {
this.visible = false;
this.createCase = getUUID();
this.visible = true;
this.loaded = false;
this.$refs.caseList.addCase();
},
saveAsApi() {
let data = {};

View File

@ -1,7 +1,7 @@
<template>
<div id="menu-bar" v-if="isRouterAlive">
<el-row type="flex">
<el-col :span="10">
<el-col :span="14">
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" router :default-active='$route.path'>
<el-submenu :class="{'deactivation':!isProjectActivation}" v-permission="['test_manager','test_user','test_viewer']" index="3">
@ -54,12 +54,12 @@
</el-menu-item>
</el-menu>
</el-col>
<el-col :span="8">
<el-col :span="6">
<el-row type="flex" justify="center">
<ms-create-test :to="'/api/test/create'"/>
</el-row>
</el-col>
<el-col :span="6"/>
<el-col :span="4"/>
</el-row>
</div>

View File

@ -56,7 +56,7 @@
.el-menu >>> .el-menu-item {
box-sizing: border-box;
height: 37px;
height: 40px;
}
</style>