feat (接口自动化): 完成优化需求2
--story=1002974 --user=赵勇 2.环境匹配,模块支持... https://www.tapd.cn/55049933/s/1045479
This commit is contained in:
parent
9b1c6b0978
commit
20127bc205
|
@ -328,7 +328,12 @@ public class ApiAutomationController {
|
||||||
|
|
||||||
@PostMapping(value = "/stop/batch")
|
@PostMapping(value = "/stop/batch")
|
||||||
public String stopBatch(@RequestBody List<TaskRequest> reportIds) {
|
public String stopBatch(@RequestBody List<TaskRequest> reportIds) {
|
||||||
return taskService.stop(reportIds);
|
return taskService.stop(reportIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/setDomain")
|
||||||
|
public String setDomain(@RequestBody ApiScenarioEnvRequest request) {
|
||||||
|
return apiAutomationService.setDomain(request.getDefinition());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
package io.metersphere.api.dto.definition.request;
|
package io.metersphere.api.dto.definition.request;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import io.metersphere.api.dto.definition.request.controller.MsLoopController;
|
import io.metersphere.api.dto.definition.request.controller.MsLoopController;
|
||||||
import io.metersphere.api.dto.definition.request.controller.MsTransactionController;
|
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||||
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
|
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
|
||||||
import io.metersphere.api.dto.mockconfig.MockConfigStaticData;
|
import io.metersphere.api.dto.mockconfig.MockConfigStaticData;
|
||||||
import io.metersphere.api.dto.scenario.KeyValue;
|
import io.metersphere.api.dto.scenario.KeyValue;
|
||||||
|
@ -16,6 +17,8 @@ import io.metersphere.commons.constants.MsTestElementConstants;
|
||||||
import io.metersphere.commons.exception.MSException;
|
import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||||
import io.metersphere.commons.utils.FileUtils;
|
import io.metersphere.commons.utils.FileUtils;
|
||||||
|
import io.metersphere.commons.utils.LogUtil;
|
||||||
|
import io.metersphere.plugin.core.MsParameter;
|
||||||
import io.metersphere.plugin.core.MsTestElement;
|
import io.metersphere.plugin.core.MsTestElement;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -23,6 +26,7 @@ import org.apache.jmeter.config.Arguments;
|
||||||
import org.apache.jmeter.config.CSVDataSet;
|
import org.apache.jmeter.config.CSVDataSet;
|
||||||
import org.apache.jmeter.config.RandomVariableConfig;
|
import org.apache.jmeter.config.RandomVariableConfig;
|
||||||
import org.apache.jmeter.modifiers.CounterConfig;
|
import org.apache.jmeter.modifiers.CounterConfig;
|
||||||
|
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||||
import org.apache.jmeter.save.SaveService;
|
import org.apache.jmeter.save.SaveService;
|
||||||
import org.apache.jmeter.testelement.TestElement;
|
import org.apache.jmeter.testelement.TestElement;
|
||||||
import org.apache.jorphan.collections.HashTree;
|
import org.apache.jorphan.collections.HashTree;
|
||||||
|
@ -286,4 +290,32 @@ public class ElementUtil {
|
||||||
dataFormatting(elementJSONArray);
|
dataFormatting(elementJSONArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void dataSetDomain(JSONArray hashTree, MsParameter msParameter) {
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < hashTree.size(); i++) {
|
||||||
|
JSONObject element = hashTree.getJSONObject(i);
|
||||||
|
if (element != null && element.get("type").toString().equals("HTTPSamplerProxy")) {
|
||||||
|
MsHTTPSamplerProxy httpSamplerProxy = JSON.toJavaObject(element, MsHTTPSamplerProxy.class);
|
||||||
|
if (httpSamplerProxy != null
|
||||||
|
&& (!httpSamplerProxy.isCustomizeReq() || (httpSamplerProxy.isCustomizeReq() && httpSamplerProxy.getIsRefEnvironment()))) {
|
||||||
|
HashTree tmpHashTree = new HashTree();
|
||||||
|
httpSamplerProxy.toHashTree(tmpHashTree, null, msParameter);
|
||||||
|
if (tmpHashTree != null && tmpHashTree.getArray().length > 0) {
|
||||||
|
HTTPSamplerProxy object = (HTTPSamplerProxy) tmpHashTree.getArray()[0];
|
||||||
|
if (object != null && StringUtils.isNotEmpty(object.getDomain())) {
|
||||||
|
element.fluentPut("domain", StringUtils.isNotEmpty(object.getProtocol()) ? object.getProtocol() + "://" + object.getDomain() : object.getDomain());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (element.containsKey("hashTree")) {
|
||||||
|
JSONArray elementJSONArray = element.getJSONArray("hashTree");
|
||||||
|
dataSetDomain(elementJSONArray, msParameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -600,6 +600,30 @@ public class ApiAutomationService {
|
||||||
return apiScenarioMapper.selectByPrimaryKey(id);
|
return apiScenarioMapper.selectByPrimaryKey(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String setDomain(String scenarioDefinition) {
|
||||||
|
JSONObject element = JSON.parseObject(scenarioDefinition);
|
||||||
|
ParameterConfig config = new ParameterConfig();
|
||||||
|
Map<String, EnvironmentConfig> envConfig = new HashMap<>(16);
|
||||||
|
Map<String, String> environmentMap = (Map<String, String>) element.get("environmentMap");
|
||||||
|
if (environmentMap != null && !environmentMap.isEmpty()) {
|
||||||
|
environmentMap.keySet().forEach(projectId -> {
|
||||||
|
ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
|
||||||
|
ApiTestEnvironmentWithBLOBs environment = environmentService.get(environmentMap.get(projectId));
|
||||||
|
if (environment != null && environment.getConfig() != null) {
|
||||||
|
EnvironmentConfig env = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class);
|
||||||
|
env.setApiEnvironmentid(environment.getId());
|
||||||
|
envConfig.put(projectId, env);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
config.setConfig(envConfig);
|
||||||
|
}
|
||||||
|
if (config.getConfig() != null && !config.getConfig().isEmpty()) {
|
||||||
|
ElementUtil.dataSetDomain(element.getJSONArray("hashTree"), config);
|
||||||
|
}
|
||||||
|
return JSON.toJSONString(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public LinkedList<MsTestElement> getScenarioHashTree(String definition) {
|
public LinkedList<MsTestElement> getScenarioHashTree(String definition) {
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
@ -2518,6 +2542,7 @@ public class ApiAutomationService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用例自定义排序
|
* 用例自定义排序
|
||||||
|
*
|
||||||
* @param request
|
* @param request
|
||||||
*/
|
*/
|
||||||
public void updateOrder(ResetOrderRequest request) {
|
public void updateOrder(ResetOrderRequest request) {
|
||||||
|
|
|
@ -450,6 +450,7 @@ export default {
|
||||||
messageWebSocket: {},
|
messageWebSocket: {},
|
||||||
buttonData: [],
|
buttonData: [],
|
||||||
stepFilter: new STEP,
|
stepFilter: new STEP,
|
||||||
|
plugins: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -464,6 +465,7 @@ export default {
|
||||||
this.getWsProjects();
|
this.getWsProjects();
|
||||||
this.getMaintainerOptions();
|
this.getMaintainerOptions();
|
||||||
this.getApiScenario();
|
this.getApiScenario();
|
||||||
|
this.getPlugins();
|
||||||
this.initPlugins();
|
this.initPlugins();
|
||||||
this.buttonData = buttons(this);
|
this.buttonData = buttons(this);
|
||||||
},
|
},
|
||||||
|
@ -482,27 +484,53 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
setDomain() {
|
||||||
|
if (this.projectEnvMap && this.projectEnvMap.size > 0) {
|
||||||
|
let scenario = {
|
||||||
|
id: this.currentScenario.id,
|
||||||
|
enableCookieShare: this.enableCookieShare,
|
||||||
|
name: this.currentScenario.name,
|
||||||
|
type: "scenario",
|
||||||
|
clazzName: TYPE_TO_C.get("scenario"),
|
||||||
|
variables: this.currentScenario.variables,
|
||||||
|
headers: this.currentScenario.headers,
|
||||||
|
referenced: 'Created',
|
||||||
|
environmentMap: strMapToObj(this.projectEnvMap),
|
||||||
|
hashTree: this.scenarioDefinition,
|
||||||
|
onSampleError: this.onSampleError,
|
||||||
|
projectId: this.currentScenario.projectId ? this.currentScenario.projectId : this.projectId,
|
||||||
|
};
|
||||||
|
this.$post("/api/automation/setDomain", {definition: JSON.stringify(scenario)}, res => {
|
||||||
|
if (res.data) {
|
||||||
|
let data = JSON.parse(res.data);
|
||||||
|
this.scenarioDefinition = data.hashTree;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
initPlugins() {
|
initPlugins() {
|
||||||
|
if (this.plugins) {
|
||||||
|
this.plugins.forEach(item => {
|
||||||
|
let plugin = {
|
||||||
|
title: item.name,
|
||||||
|
show: this.showButton(item.jmeterClazz),
|
||||||
|
titleColor: "#555855",
|
||||||
|
titleBgColor: "#F4F4FF",
|
||||||
|
icon: "colorize",
|
||||||
|
click: () => {
|
||||||
|
this.addComponent(item.name, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.operatingElements && this.operatingElements.includes(item.jmeterClazz)) {
|
||||||
|
this.buttonData.push(plugin);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getPlugins() {
|
||||||
let url = "/plugin/list";
|
let url = "/plugin/list";
|
||||||
this.$get(url, response => {
|
this.$get(url, response => {
|
||||||
let data = response.data;
|
this.plugins = response.data;
|
||||||
if (data) {
|
|
||||||
data.forEach(item => {
|
|
||||||
let plugin = {
|
|
||||||
title: item.name,
|
|
||||||
show: this.showButton(item.jmeterClazz),
|
|
||||||
titleColor: "#555855",
|
|
||||||
titleBgColor: "#F4F4FF",
|
|
||||||
icon: "colorize",
|
|
||||||
click: () => {
|
|
||||||
this.addComponent(item.name, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.operatingElements && this.operatingElements.includes(item.jmeterClazz)) {
|
|
||||||
this.buttonData.push(plugin);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
stop() {
|
stop() {
|
||||||
|
@ -1279,6 +1307,7 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
this.setDomain();
|
||||||
this.sort();
|
this.sort();
|
||||||
// 初始化resourceId
|
// 初始化resourceId
|
||||||
if (this.scenarioDefinition) {
|
if (this.scenarioDefinition) {
|
||||||
|
@ -1352,6 +1381,7 @@ export default {
|
||||||
},
|
},
|
||||||
setProjectEnvMap(projectEnvMap) {
|
setProjectEnvMap(projectEnvMap) {
|
||||||
this.projectEnvMap = projectEnvMap;
|
this.projectEnvMap = projectEnvMap;
|
||||||
|
this.setDomain();
|
||||||
},
|
},
|
||||||
getWsProjects() {
|
getWsProjects() {
|
||||||
this.$get("/project/listAll", res => {
|
this.$get("/project/listAll", res => {
|
||||||
|
|
|
@ -1,19 +1,26 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="request.protocol === 'HTTP'">
|
<div v-if="request.protocol === 'HTTP'">
|
||||||
<el-input :placeholder="$t('api_test.definition.request.path_all_info')" v-if="request.url || isCustomizeReq" v-model="request.url"
|
<div v-if="request.url || isCustomizeReq">
|
||||||
style="width: 85%;margin-top: 10px" size="small" @blur="urlChange">
|
<el-select v-model="request.method" style="width: 100px" size="small">
|
||||||
<el-select v-model="request.method" slot="prepend" style="width: 100px" size="small">
|
|
||||||
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-input>
|
<el-input v-model="request.domain" v-if="request.isRefEnvironment && request.domain" size="small" readonly style="width: 150px"/>
|
||||||
<el-input :placeholder="$t('api_test.definition.request.path_all_info')" v-else v-model="request.path"
|
<el-input :placeholder="$t('api_test.definition.request.path_all_info')" v-model="request.url"
|
||||||
style="width: 85%;margin-top: 10px" size="small" @blur="pathChange">
|
style="width: 50%" size="small" @blur="urlChange">
|
||||||
<el-select v-model="request.method" slot="prepend" style="width: 100px" size="small">
|
</el-input>
|
||||||
|
<el-checkbox v-if="isCustomizeReq" class="is-ref-environment" v-model="request.isRefEnvironment">
|
||||||
|
{{ $t('api_test.request.refer_to_environment') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<el-select v-model="request.method" style="width: 100px" size="small">
|
||||||
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-input>
|
<el-input v-model="request.domain" v-if="request.domain" size="small" readonly style="width: 150px"/>
|
||||||
<el-checkbox v-if="isCustomizeReq" class="is-ref-environment" v-model="request.isRefEnvironment">{{ $t('api_test.request.refer_to_environment') }}</el-checkbox>
|
<el-input :placeholder="$t('api_test.definition.request.path_all_info')" style="width: 50%"
|
||||||
|
v-model="request.path" size="small" @blur="pathChange"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="request.protocol === 'TCP' && isCustomizeReq">
|
<div v-if="request.protocol === 'TCP' && isCustomizeReq">
|
||||||
|
@ -122,6 +129,16 @@ export default {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scenario-step-request-name {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 5px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
padding-bottom: 0;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: middle;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
.is-ref-environment {
|
.is-ref-environment {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue