Merge branch 'master' of https://github.com/metersphere/metersphere
This commit is contained in:
commit
7e51a7eb61
|
@ -10,16 +10,11 @@ import io.metersphere.api.dto.datacount.response.ApiDataCountDTO;
|
|||
import io.metersphere.api.dto.datacount.response.ExecutedCaseInfoDTO;
|
||||
import io.metersphere.api.dto.datacount.response.TaskInfoResult;
|
||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||
import io.metersphere.api.dto.scenario.request.dubbo.RegistryCenter;
|
||||
import io.metersphere.api.service.*;
|
||||
import io.metersphere.base.domain.ApiDefinition;
|
||||
import io.metersphere.base.domain.ApiTest;
|
||||
import io.metersphere.base.domain.LoadTest;
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.commons.constants.PerformanceTestStatus;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.commons.constants.ScheduleGroup;
|
||||
import io.metersphere.commons.utils.CronUtils;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
|
@ -28,24 +23,14 @@ import io.metersphere.controller.request.QueryScheduleRequest;
|
|||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.performance.service.PerformanceTestService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.service.FileService;
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import io.metersphere.track.request.testplan.SaveTestPlanRequest;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.Element;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
@ -393,7 +378,7 @@ public class APITestController {
|
|||
String testName = runRequest.getName();
|
||||
|
||||
//将jmx处理封装为通用方法
|
||||
jmxString = apiTestService.updateJmxString(jmxString,testName,true);
|
||||
jmxString = apiTestService.updateJmxString(jmxString,testName,false);
|
||||
|
||||
JmxInfoDTO dto = new JmxInfoDTO();
|
||||
dto.setName(runRequest.getName() + ".jmx");
|
||||
|
|
|
@ -44,13 +44,6 @@ public class ApiAutomationController {
|
|||
return PageUtils.setPageInfo(page, apiAutomationService.list(request));
|
||||
}
|
||||
|
||||
@PostMapping("/list/all")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||
public List<ApiScenarioWithBLOBs> list(@RequestBody ApiScenarioRequest request) {
|
||||
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
return apiAutomationService.get(request);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/create")
|
||||
public ApiScenario create(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
||||
return apiAutomationService.create(request, bodyFiles);
|
||||
|
@ -167,5 +160,11 @@ public class ApiAutomationController {
|
|||
return apiAutomationService.export(request);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/export/jmx")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public List<ApiScenrioExportJmx> exportJmx(@RequestBody ApiScenarioBatchRequest request) {
|
||||
return apiAutomationService.exportJmx(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ public class ApiTestImportRequest {
|
|||
private String platform;
|
||||
private Boolean useEnvironment;
|
||||
private String swaggerUrl;
|
||||
private String fileName;
|
||||
//导入策略
|
||||
private String modeId;
|
||||
private String userId;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.api.dto.automation;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ApiScenrioExportJmx {
|
||||
private String name;
|
||||
private String jmx;
|
||||
|
||||
public ApiScenrioExportJmx(String name, String jmx) {
|
||||
this.name = name;
|
||||
this.jmx = jmx;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package io.metersphere.api.dto.automation.parse;
|
||||
|
||||
import io.metersphere.api.dto.automation.ApiScenarioModuleDTO;
|
||||
import io.metersphere.api.service.ApiScenarioModuleService;
|
||||
import io.metersphere.base.domain.ApiScenarioModule;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ApiScenarioImportUtil {
|
||||
|
||||
public static ApiScenarioModule getSelectModule(String moduleId) {
|
||||
ApiScenarioModuleService apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class);
|
||||
if (StringUtils.isNotBlank(moduleId) && !StringUtils.equals("root", moduleId)) {
|
||||
ApiScenarioModule module = new ApiScenarioModule();
|
||||
ApiScenarioModuleDTO moduleDTO = apiModuleService.getNode(moduleId);
|
||||
if (moduleDTO != null) {
|
||||
BeanUtils.copyBean(module, moduleDTO);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ApiScenarioModule buildModule(ApiScenarioModule parentModule, String name, String projectId) {
|
||||
ApiScenarioModuleService apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class);
|
||||
ApiScenarioModule module;
|
||||
if (parentModule != null) {
|
||||
module = apiModuleService.getNewModule(name, projectId, parentModule.getLevel() + 1);
|
||||
module.setParentId(parentModule.getId());
|
||||
} else {
|
||||
module = apiModuleService.getNewModule(name, projectId, 1);
|
||||
}
|
||||
createModule(module);
|
||||
return module;
|
||||
}
|
||||
|
||||
public static void createModule(ApiScenarioModule module) {
|
||||
ApiScenarioModuleService apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class);
|
||||
List<ApiScenarioModule> apiModules = apiModuleService.selectSameModule(module);
|
||||
if (CollectionUtils.isEmpty(apiModules)) {
|
||||
apiModuleService.addNode(module);
|
||||
} else {
|
||||
module.setId(apiModules.get(0).getId());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ import io.metersphere.api.dto.automation.ImportPoolsDTO;
|
|||
import io.metersphere.api.dto.definition.request.MsScenario;
|
||||
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||
import io.metersphere.api.dto.definition.request.assertions.*;
|
||||
import io.metersphere.api.dto.definition.request.controller.MsIfController;
|
||||
import io.metersphere.api.dto.definition.request.controller.MsLoopController;
|
||||
import io.metersphere.api.dto.definition.request.controller.loop.CountController;
|
||||
import io.metersphere.api.dto.definition.request.controller.loop.MsForEachController;
|
||||
|
@ -37,6 +36,7 @@ import io.metersphere.api.dto.scenario.KeyValue;
|
|||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||
import io.metersphere.api.dto.scenario.request.BodyFile;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
import io.metersphere.api.parse.ApiImportAbstractParser;
|
||||
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||
import io.metersphere.base.domain.ApiScenarioModule;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
|
@ -51,7 +51,6 @@ import org.apache.commons.collections.CollectionUtils;
|
|||
import org.apache.jmeter.assertions.*;
|
||||
import org.apache.jmeter.config.ConfigTestElement;
|
||||
import org.apache.jmeter.control.ForeachController;
|
||||
import org.apache.jmeter.control.IfController;
|
||||
import org.apache.jmeter.control.LoopController;
|
||||
import org.apache.jmeter.control.WhileController;
|
||||
import org.apache.jmeter.extractor.JSR223PostProcessor;
|
||||
|
@ -76,7 +75,7 @@ import java.io.InputStream;
|
|||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
public class MsJmeterParser extends ScenarioImportAbstractParser {
|
||||
public class MsJmeterParser extends ApiImportAbstractParser<ScenarioImport> {
|
||||
private final String ENV_NAME = "导入数据环境";
|
||||
|
||||
@Override
|
||||
|
@ -88,12 +87,12 @@ public class MsJmeterParser extends ScenarioImportAbstractParser {
|
|||
preInitPool(request.getProjectId(), testPlan);
|
||||
|
||||
MsScenario scenario = new MsScenario();
|
||||
scenario.setReferenced("REF");
|
||||
scenario.setReferenced("IMPORT");
|
||||
jmterHashTree(testPlan, scenario);
|
||||
this.projectId = request.getProjectId();
|
||||
ScenarioImport scenarioImport = new ScenarioImport();
|
||||
scenarioImport.setData(paseObj(scenario, request));
|
||||
scenarioImport.setProjectid(request.getProjectId());
|
||||
scenarioImport.setProjectId(request.getProjectId());
|
||||
return scenarioImport;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -105,7 +104,7 @@ public class MsJmeterParser extends ScenarioImportAbstractParser {
|
|||
private List<ApiScenarioWithBLOBs> paseObj(MsScenario msScenario, ApiTestImportRequest request) {
|
||||
List<ApiScenarioWithBLOBs> scenarioWithBLOBsList = new ArrayList<>();
|
||||
ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs();
|
||||
ApiScenarioModule module = buildModule(getSelectModule(request.getModuleId()), msScenario.getName());
|
||||
ApiScenarioModule module = ApiScenarioImportUtil.buildModule(ApiScenarioImportUtil.getSelectModule(request.getModuleId()), msScenario.getName(), this.projectId);
|
||||
scenarioWithBLOBs.setName(msScenario.getName());
|
||||
scenarioWithBLOBs.setProjectId(request.getProjectId());
|
||||
if (msScenario != null && CollectionUtils.isNotEmpty(msScenario.getHashTree())) {
|
||||
|
@ -199,7 +198,6 @@ public class MsJmeterParser extends ScenarioImportAbstractParser {
|
|||
private void convertDubboSample(MsDubboSampler elementNode, DubboSample sampler) {
|
||||
elementNode.setName(sampler.getName());
|
||||
elementNode.setType("DubboSampler");
|
||||
elementNode.setProtocol("dubbo://");
|
||||
elementNode.set_interface(sampler.getPropertyAsString("FIELD_DUBBO_INTERFACE"));
|
||||
elementNode.setMethod(sampler.getPropertyAsString("FIELD_DUBBO_METHOD"));
|
||||
|
||||
|
@ -233,24 +231,24 @@ public class MsJmeterParser extends ScenarioImportAbstractParser {
|
|||
elementNode.setConsumerAndService(consumerAndService);
|
||||
|
||||
List<MethodArgument> methodArguments = Constants.getMethodArgs(sampler);
|
||||
List<KeyValue> methodArgs = new LinkedList<>();
|
||||
if (CollectionUtils.isNotEmpty(methodArguments)) {
|
||||
List<KeyValue> methodArgs = new LinkedList<>();
|
||||
methodArguments.forEach(item -> {
|
||||
KeyValue keyValue = new KeyValue(item.getParamType(), item.getParamValue());
|
||||
methodArgs.add(keyValue);
|
||||
});
|
||||
elementNode.setArgs(methodArgs);
|
||||
}
|
||||
elementNode.setArgs(methodArgs);
|
||||
|
||||
List<MethodArgument> arguments = Constants.getAttachmentArgs(sampler);
|
||||
List<KeyValue> attachmentArgs = new LinkedList<>();
|
||||
if (CollectionUtils.isNotEmpty(arguments)) {
|
||||
List<KeyValue> methodArgs = new LinkedList<>();
|
||||
arguments.forEach(item -> {
|
||||
KeyValue keyValue = new KeyValue(item.getParamType(), item.getParamValue());
|
||||
methodArgs.add(keyValue);
|
||||
attachmentArgs.add(keyValue);
|
||||
});
|
||||
elementNode.setAttachmentArgs(methodArgs);
|
||||
}
|
||||
elementNode.setAttachmentArgs(attachmentArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -568,12 +566,12 @@ public class MsJmeterParser extends ScenarioImportAbstractParser {
|
|||
BeanUtils.copyBean(elementNode, key);
|
||||
elementNode.setType("ConstantTimer");
|
||||
}
|
||||
// IF条件控制器
|
||||
else if (key instanceof IfController) {
|
||||
elementNode = new MsIfController();
|
||||
BeanUtils.copyBean(elementNode, key);
|
||||
elementNode.setType("IfController");
|
||||
}
|
||||
// IF条件控制器,这里平台方式和jmeter 不同,暂时不处理
|
||||
// else if (key instanceof IfController) {
|
||||
// elementNode = new MsIfController();
|
||||
// BeanUtils.copyBean(elementNode, key);
|
||||
// elementNode.setType("IfController");
|
||||
// }
|
||||
// 次数循环控制器
|
||||
else if (key instanceof LoopController) {
|
||||
elementNode = new MsLoopController();
|
||||
|
|
|
@ -1,205 +0,0 @@
|
|||
package io.metersphere.api.dto.automation.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.request.MsScenario;
|
||||
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||
import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
|
||||
import io.metersphere.api.dto.parse.postman.*;
|
||||
import io.metersphere.api.dto.scenario.Body;
|
||||
import io.metersphere.api.dto.scenario.KeyValue;
|
||||
import io.metersphere.base.domain.ApiScenarioModule;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.commons.constants.MsRequestBodyType;
|
||||
import io.metersphere.commons.constants.PostmanRequestBodyMode;
|
||||
import io.metersphere.commons.constants.VariableTypeConstants;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MsPostmanParser extends ScenarioImportAbstractParser {
|
||||
|
||||
@Override
|
||||
public ScenarioImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
String testStr = getApiTestStr(source);
|
||||
PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class);
|
||||
List<PostmanKeyValue> variables = postmanCollection.getVariable();
|
||||
ScenarioImport scenarioImport = new ScenarioImport();
|
||||
// 场景步骤
|
||||
LinkedList<MsTestElement> apiScenarioWithBLOBs = new LinkedList<>();
|
||||
PostmanCollectionInfo info = postmanCollection.getInfo();
|
||||
ApiScenarioWithBLOBs scenario = new ApiScenarioWithBLOBs();
|
||||
scenario.setName(info.getName());
|
||||
|
||||
MsScenario msScenario = new MsScenario();
|
||||
msScenario.setName(info.getName());
|
||||
this.projectId = request.getProjectId();
|
||||
parseItem(postmanCollection.getItem(), variables, msScenario, apiScenarioWithBLOBs);
|
||||
// 生成场景对象
|
||||
List<ApiScenarioWithBLOBs> scenarioWithBLOBs = new LinkedList<>();
|
||||
paseScenario(scenarioWithBLOBs, msScenario, request);
|
||||
scenarioImport.setData(scenarioWithBLOBs);
|
||||
return scenarioImport;
|
||||
}
|
||||
|
||||
private void paseScenario(List<ApiScenarioWithBLOBs> scenarioWithBLOBsList, MsScenario msScenario, ApiTestImportRequest request) {
|
||||
ApiScenarioModule module = buildModule(getSelectModule(request.getModuleId()), msScenario.getName());
|
||||
ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs();
|
||||
scenarioWithBLOBs.setName(msScenario.getName());
|
||||
scenarioWithBLOBs.setProjectId(request.getProjectId());
|
||||
if (msScenario != null && CollectionUtils.isNotEmpty(msScenario.getHashTree())) {
|
||||
scenarioWithBLOBs.setStepTotal(msScenario.getHashTree().size());
|
||||
}
|
||||
if (module != null) {
|
||||
scenarioWithBLOBs.setApiScenarioModuleId(module.getId());
|
||||
scenarioWithBLOBs.setModulePath("/" + module.getName());
|
||||
}
|
||||
scenarioWithBLOBs.setId(UUID.randomUUID().toString());
|
||||
scenarioWithBLOBs.setScenarioDefinition(JSON.toJSONString(msScenario));
|
||||
scenarioWithBLOBsList.add(scenarioWithBLOBs);
|
||||
}
|
||||
|
||||
private void parseItem(List<PostmanItem> items, List<PostmanKeyValue> variables, MsScenario scenario, LinkedList<MsTestElement> results) {
|
||||
for (PostmanItem item : items) {
|
||||
List<PostmanItem> childItems = item.getItem();
|
||||
if (childItems != null) {
|
||||
parseItem(childItems, variables, scenario, results);
|
||||
} else {
|
||||
MsHTTPSamplerProxy request = parsePostman(item);
|
||||
if (request != null) {
|
||||
results.add(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
scenario.setVariables(parseScenarioVariable(variables));
|
||||
scenario.setHashTree(results);
|
||||
}
|
||||
|
||||
private MsHTTPSamplerProxy parsePostman(PostmanItem requestItem) {
|
||||
PostmanRequest requestDesc = requestItem.getRequest();
|
||||
if (requestDesc == null) {
|
||||
return null;
|
||||
}
|
||||
requestDesc.getAuth(); // todo 认证方式等待优化
|
||||
PostmanUrl url = requestDesc.getUrl();
|
||||
MsHTTPSamplerProxy request = buildRequest(requestItem.getName(), url.getRaw(), requestDesc.getMethod());
|
||||
if (StringUtils.isNotBlank(request.getPath())) {
|
||||
String path = request.getPath().split("\\?")[0];
|
||||
path = path.replace("{{", "${");
|
||||
path = path.replace("}}", "}");
|
||||
request.setPath(path);
|
||||
} else {
|
||||
request.setPath("/");
|
||||
}
|
||||
parseBody(request.getBody(), requestDesc);
|
||||
request.setArguments(parseKeyValue(url.getQuery()));
|
||||
request.setHeaders(parseKeyValue(requestDesc.getHeader()));
|
||||
addBodyHeader(request);
|
||||
addPreScript(request, requestItem.getEvent());
|
||||
return request;
|
||||
}
|
||||
|
||||
private void addPreScript(MsHTTPSamplerProxy request, List<PostmanEvent> event) {
|
||||
if (request != null && CollectionUtils.isNotEmpty(event)) {
|
||||
StringBuilder scriptStr = new StringBuilder();
|
||||
event = event.stream()
|
||||
.filter(item -> item.getScript() != null)
|
||||
.collect(Collectors.toList());
|
||||
event.forEach(item -> {
|
||||
PostmanScript script = item.getScript();
|
||||
if (script != null) {
|
||||
List<String> exec = script.getExec();
|
||||
if (CollectionUtils.isNotEmpty(exec)) {
|
||||
exec.forEach(col -> {
|
||||
if (StringUtils.isNotEmpty(col)) {
|
||||
scriptStr.append(col + "/n");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
if (StringUtils.isNotBlank(scriptStr)) {
|
||||
MsJSR223PreProcessor jsr223PreProcessor = new MsJSR223PreProcessor();
|
||||
jsr223PreProcessor.setName("JSR223PreProcessor");
|
||||
jsr223PreProcessor.setScriptLanguage("javascript");
|
||||
jsr223PreProcessor.setScript(scriptStr.toString());
|
||||
LinkedList<MsTestElement> hashTree = new LinkedList<>();
|
||||
hashTree.add(jsr223PreProcessor);
|
||||
request.setHashTree(hashTree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<KeyValue> parseKeyValue(List<PostmanKeyValue> postmanKeyValues) {
|
||||
if (postmanKeyValues == null) {
|
||||
return null;
|
||||
}
|
||||
List<KeyValue> keyValues = new ArrayList<>();
|
||||
postmanKeyValues.forEach(item -> keyValues.add(new KeyValue(item.getKey(), item.getValue(), item.getDescription(), item.getContentType())));
|
||||
return keyValues;
|
||||
}
|
||||
|
||||
private List<ScenarioVariable> parseScenarioVariable(List<PostmanKeyValue> postmanKeyValues) {
|
||||
if (postmanKeyValues == null) {
|
||||
return null;
|
||||
}
|
||||
List<ScenarioVariable> keyValues = new ArrayList<>();
|
||||
postmanKeyValues.forEach(item -> keyValues.add(new ScenarioVariable(item.getKey(), item.getValue(), item.getDescription(), VariableTypeConstants.CONSTANT.name())));
|
||||
return keyValues;
|
||||
}
|
||||
|
||||
private void parseBody(Body body, PostmanRequest requestDesc) {
|
||||
JSONObject postmanBody = requestDesc.getBody();
|
||||
if (postmanBody == null) {
|
||||
return;
|
||||
}
|
||||
String bodyMode = postmanBody.getString("mode");
|
||||
if (StringUtils.isNotEmpty(bodyMode) && StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) {
|
||||
parseRawBody(body, postmanBody, bodyMode);
|
||||
} else if (StringUtils.isNotEmpty(bodyMode) && StringUtils.equalsAny(bodyMode, PostmanRequestBodyMode.FORM_DATA.value(), PostmanRequestBodyMode.URLENCODED.value())) {
|
||||
List<PostmanKeyValue> postmanKeyValues = JSON.parseArray(postmanBody.getString(bodyMode), PostmanKeyValue.class);
|
||||
body.setKvs(parseKeyValue(postmanKeyValues));
|
||||
if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FORM_DATA.value())) {
|
||||
body.setType(Body.FORM_DATA);
|
||||
} else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.URLENCODED.value())) {
|
||||
body.setType(Body.WWW_FROM);
|
||||
}
|
||||
} else if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.FILE.value())) {
|
||||
body.setType(Body.BINARY);
|
||||
body.setKvs(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRawBody(Body body, JSONObject postmanBody, String bodyMode) {
|
||||
body.setRaw(postmanBody.getString(bodyMode));
|
||||
body.setType(MsRequestBodyType.RAW.value());
|
||||
JSONObject options = postmanBody.getJSONObject("options");
|
||||
if (options != null) {
|
||||
JSONObject raw = options.getJSONObject(PostmanRequestBodyMode.RAW.value());
|
||||
if (raw != null && raw.getString("language") != null) {
|
||||
String bodyType = "";
|
||||
switch (raw.getString("language")) {
|
||||
case "json":
|
||||
bodyType = Body.JSON;
|
||||
break;
|
||||
case "xml":
|
||||
bodyType = Body.XML;
|
||||
break;
|
||||
default:
|
||||
bodyType = Body.RAW;
|
||||
}
|
||||
body.setType(bodyType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +1,49 @@
|
|||
package io.metersphere.api.dto.automation.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.request.MsScenario;
|
||||
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||
import io.metersphere.api.parse.MsAbstractParser;
|
||||
import io.metersphere.base.domain.ApiScenarioModule;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
public class MsScenarioParser extends ScenarioImportAbstractParser {
|
||||
public class MsScenarioParser extends MsAbstractParser<ScenarioImport> {
|
||||
|
||||
@Override
|
||||
public ScenarioImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
String testStr = getApiTestStr(source);
|
||||
this.projectId = request.getProjectId();
|
||||
ScenarioImport scenarioImport = parseMsFormat(testStr, request);
|
||||
return scenarioImport;
|
||||
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
|
||||
if (testObject.get("projectName") != null || testObject.get("projectId") != null ) {
|
||||
return parseMsFormat(testStr, request);
|
||||
} else {
|
||||
ScenarioImport apiImport = new ScenarioImport();
|
||||
ArrayList<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = new ArrayList<>();
|
||||
apiScenarioWithBLOBs.add(parsePluginFormat(testObject, request));
|
||||
apiImport.setData(apiScenarioWithBLOBs);
|
||||
return apiImport;
|
||||
}
|
||||
}
|
||||
|
||||
protected ApiScenarioWithBLOBs parsePluginFormat(JSONObject testObject, ApiTestImportRequest importRequest) {
|
||||
LinkedList<MsTestElement> results = new LinkedList<>();
|
||||
testObject.keySet().forEach(tag -> {
|
||||
results.addAll(parseMsHTTPSamplerProxy(testObject, tag));
|
||||
});
|
||||
MsScenario msScenario = new MsScenario();
|
||||
msScenario.setName(importRequest.getFileName());
|
||||
msScenario.setHashTree(results);
|
||||
ApiScenarioWithBLOBs scenarioWithBLOBs = parseScenario(msScenario);
|
||||
scenarioWithBLOBs.setApiScenarioModuleId(importRequest.getModuleId());
|
||||
return scenarioWithBLOBs;
|
||||
}
|
||||
|
||||
private ScenarioImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) {
|
||||
|
@ -31,7 +54,7 @@ public class MsScenarioParser extends ScenarioImportAbstractParser {
|
|||
if (StringUtils.isBlank(item.getModulePath())) {
|
||||
item.setApiScenarioModuleId(null);
|
||||
}
|
||||
parseModule(item, importRequest);
|
||||
parseModule(item.getModulePath(), importRequest, item);
|
||||
item.setId(UUID.randomUUID().toString());
|
||||
item.setProjectId(this.projectId);
|
||||
});
|
||||
|
@ -39,8 +62,7 @@ public class MsScenarioParser extends ScenarioImportAbstractParser {
|
|||
return apiDefinitionImport;
|
||||
}
|
||||
|
||||
private void parseModule(ApiScenarioWithBLOBs apiDefinition, ApiTestImportRequest importRequest) {
|
||||
String modulePath = apiDefinition.getModulePath();
|
||||
protected void parseModule(String modulePath, ApiTestImportRequest importRequest, ApiScenarioWithBLOBs apiScenarioWithBLOBs) {
|
||||
if (StringUtils.isEmpty(modulePath)) {
|
||||
return;
|
||||
}
|
||||
|
@ -51,15 +73,14 @@ public class MsScenarioParser extends ScenarioImportAbstractParser {
|
|||
modulePath = modulePath.substring(0, modulePath.length() - 1);
|
||||
}
|
||||
List<String> modules = Arrays.asList(modulePath.split("/"));
|
||||
ApiScenarioModule parent = getSelectModule(importRequest.getModuleId());
|
||||
ApiScenarioModule parent = ApiScenarioImportUtil.getSelectModule(importRequest.getModuleId());
|
||||
Iterator<String> iterator = modules.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String item = iterator.next();
|
||||
parent = buildModule(parent, item);
|
||||
parent = ApiScenarioImportUtil.buildModule(parent, item, this.projectId);
|
||||
if (!iterator.hasNext()) {
|
||||
apiDefinition.setApiScenarioModuleId(parent.getId());
|
||||
apiScenarioWithBLOBs.setApiScenarioModuleId(parent.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package io.metersphere.api.dto.automation.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.request.MsScenario;
|
||||
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanCollection;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanCollectionInfo;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanItem;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanKeyValue;
|
||||
import io.metersphere.api.parse.PostmanAbstractParserParser;
|
||||
import io.metersphere.base.domain.ApiScenarioModule;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.commons.constants.VariableTypeConstants;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class PostmanScenarioParser extends PostmanAbstractParserParser<ScenarioImport> {
|
||||
|
||||
@Override
|
||||
public ScenarioImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
String testStr = getApiTestStr(source);
|
||||
PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class);
|
||||
List<PostmanKeyValue> variables = postmanCollection.getVariable();
|
||||
ScenarioImport scenarioImport = new ScenarioImport();
|
||||
// 场景步骤
|
||||
LinkedList<MsTestElement> apiScenarioWithBLOBs = new LinkedList<>();
|
||||
PostmanCollectionInfo info = postmanCollection.getInfo();
|
||||
ApiScenarioWithBLOBs scenario = new ApiScenarioWithBLOBs();
|
||||
scenario.setName(info.getName());
|
||||
|
||||
MsScenario msScenario = new MsScenario();
|
||||
msScenario.setName(info.getName());
|
||||
this.projectId = request.getProjectId();
|
||||
parseItem(postmanCollection.getItem(), variables, msScenario, apiScenarioWithBLOBs);
|
||||
// 生成场景对象
|
||||
List<ApiScenarioWithBLOBs> scenarioWithBLOBs = new LinkedList<>();
|
||||
parseScenarioWithBLOBs(scenarioWithBLOBs, msScenario, request);
|
||||
scenarioImport.setData(scenarioWithBLOBs);
|
||||
return scenarioImport;
|
||||
}
|
||||
|
||||
private void parseScenarioWithBLOBs(List<ApiScenarioWithBLOBs> scenarioWithBLOBsList, MsScenario msScenario, ApiTestImportRequest request) {
|
||||
ApiScenarioModule module = ApiScenarioImportUtil.buildModule(ApiScenarioImportUtil.getSelectModule(request.getModuleId()), msScenario.getName(), this.projectId);
|
||||
ApiScenarioWithBLOBs scenarioWithBLOBs = parseScenario(msScenario);
|
||||
if (module != null) {
|
||||
scenarioWithBLOBs.setApiScenarioModuleId(module.getId());
|
||||
scenarioWithBLOBs.setModulePath("/" + module.getName());
|
||||
}
|
||||
scenarioWithBLOBsList.add(scenarioWithBLOBs);
|
||||
}
|
||||
|
||||
private void parseItem(List<PostmanItem> items, List<PostmanKeyValue> variables, MsScenario scenario, LinkedList<MsTestElement> results) {
|
||||
for (PostmanItem item : items) {
|
||||
List<PostmanItem> childItems = item.getItem();
|
||||
if (childItems != null) {
|
||||
parseItem(childItems, variables, scenario, results);
|
||||
} else {
|
||||
MsHTTPSamplerProxy request = parsePostman(item);
|
||||
if (request != null) {
|
||||
results.add(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
scenario.setVariables(parseScenarioVariable(variables));
|
||||
scenario.setHashTree(results);
|
||||
}
|
||||
|
||||
private List<ScenarioVariable> parseScenarioVariable(List<PostmanKeyValue> postmanKeyValues) {
|
||||
if (postmanKeyValues == null) {
|
||||
return null;
|
||||
}
|
||||
List<ScenarioVariable> keyValues = new ArrayList<>();
|
||||
postmanKeyValues.forEach(item -> keyValues.add(new ScenarioVariable(item.getKey(), item.getValue(), item.getDescription(), VariableTypeConstants.CONSTANT.name())));
|
||||
return keyValues;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,6 @@ import java.util.List;
|
|||
|
||||
@Data
|
||||
public class ScenarioImport {
|
||||
private String projectid;
|
||||
private String projectId;
|
||||
private List<ApiScenarioWithBLOBs> data;
|
||||
}
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
package io.metersphere.api.dto.automation.parse;
|
||||
|
||||
import io.metersphere.api.dto.automation.ApiScenarioModuleDTO;
|
||||
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.api.service.ApiScenarioModuleService;
|
||||
import io.metersphere.base.domain.ApiScenarioModule;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class ScenarioImportAbstractParser implements ScenarioImportParser {
|
||||
protected ApiScenarioModuleService apiModuleService;
|
||||
protected String projectId;
|
||||
|
||||
protected ApiScenarioModule getSelectModule(String moduleId) {
|
||||
apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class);
|
||||
if (StringUtils.isNotBlank(moduleId) && !StringUtils.equals("root", moduleId)) {
|
||||
ApiScenarioModule module = new ApiScenarioModule();
|
||||
ApiScenarioModuleDTO moduleDTO = apiModuleService.getNode(moduleId);
|
||||
if (moduleDTO != null) {
|
||||
BeanUtils.copyBean(module, moduleDTO);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ApiScenarioModule buildModule(ApiScenarioModule parentModule, String name) {
|
||||
apiModuleService = CommonBeanFactory.getBean(ApiScenarioModuleService.class);
|
||||
ApiScenarioModule module;
|
||||
if (parentModule != null) {
|
||||
module = apiModuleService.getNewModule(name, this.projectId, parentModule.getLevel() + 1);
|
||||
module.setParentId(parentModule.getId());
|
||||
} else {
|
||||
module = apiModuleService.getNewModule(name, this.projectId, 1);
|
||||
}
|
||||
createModule(module);
|
||||
return module;
|
||||
}
|
||||
|
||||
protected void createModule(ApiScenarioModule module) {
|
||||
List<ApiScenarioModule> apiModules = apiModuleService.selectSameModule(module);
|
||||
if (CollectionUtils.isEmpty(apiModules)) {
|
||||
apiModuleService.addNode(module);
|
||||
} else {
|
||||
module.setId(apiModules.get(0).getId());
|
||||
}
|
||||
}
|
||||
|
||||
protected String getApiTestStr(InputStream source) {
|
||||
StringBuilder testStr = null;
|
||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(source, StandardCharsets.UTF_8))) {
|
||||
testStr = new StringBuilder();
|
||||
String inputStr;
|
||||
while ((inputStr = bufferedReader.readLine()) != null) {
|
||||
testStr.append(inputStr);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
MSException.throwException(e.getMessage());
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
if (source != null) {
|
||||
source.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
MSException.throwException(e.getMessage());
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return testStr.toString();
|
||||
}
|
||||
|
||||
private String formatPath(String url) {
|
||||
try {
|
||||
URL urlObject = new URL(url);
|
||||
StringBuilder pathBuffer = new StringBuilder(urlObject.getPath());
|
||||
if (StringUtils.isNotEmpty(urlObject.getQuery())) {
|
||||
pathBuffer.append("?").append(urlObject.getQuery());
|
||||
}
|
||||
return pathBuffer.toString();
|
||||
} catch (Exception ex) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
protected MsHTTPSamplerProxy buildRequest(String name, String path, String method) {
|
||||
MsHTTPSamplerProxy request = new MsHTTPSamplerProxy();
|
||||
request.setName(name);
|
||||
// 路径去掉域名/IP 地址,保留方法名称及参数
|
||||
request.setPath(formatPath(path));
|
||||
request.setMethod(method);
|
||||
request.setProtocol(RequestType.HTTP);
|
||||
request.setId(UUID.randomUUID().toString());
|
||||
request.setHeaders(new ArrayList<>());
|
||||
request.setArguments(new ArrayList<>());
|
||||
request.setRest(new ArrayList<>());
|
||||
request.setAuthManager(null);
|
||||
Body body = new Body();
|
||||
body.initKvs();
|
||||
body.initBinary();
|
||||
request.setBody(body);
|
||||
return request;
|
||||
}
|
||||
|
||||
protected void addHeader(List<KeyValue> headers, String key, String value, String description, String contentType, boolean required) {
|
||||
boolean hasContentType = false;
|
||||
for (KeyValue header : headers) {
|
||||
if (StringUtils.equalsIgnoreCase(header.getName(), key)) {
|
||||
hasContentType = true;
|
||||
}
|
||||
}
|
||||
if (!hasContentType) {
|
||||
headers.add(new KeyValue(key, value, description, contentType, required));
|
||||
}
|
||||
}
|
||||
|
||||
protected void addHeader(List<KeyValue> headers, String key, String value) {
|
||||
addHeader(headers, key, value, "", "", true);
|
||||
}
|
||||
|
||||
protected void addContentType(List<KeyValue> headers, String contentType) {
|
||||
addHeader(headers, "Content-Type", contentType);
|
||||
}
|
||||
|
||||
protected void addBodyHeader(MsHTTPSamplerProxy request) {
|
||||
String contentType = "";
|
||||
if (request.getBody() != null && StringUtils.isNotBlank(request.getBody().getType())) {
|
||||
switch (request.getBody().getType()) {
|
||||
case Body.JSON:
|
||||
contentType = "application/json";
|
||||
break;
|
||||
case Body.WWW_FROM:
|
||||
contentType = "application/x-www-form-urlencoded";
|
||||
break;
|
||||
case Body.XML:
|
||||
contentType = "application/xml";
|
||||
break;
|
||||
case Body.BINARY:
|
||||
contentType = "application/octet-stream";
|
||||
break;
|
||||
}
|
||||
List<KeyValue> headers = request.getHeaders();
|
||||
if (headers == null) {
|
||||
headers = new ArrayList<>();
|
||||
request.setHeaders(headers);
|
||||
}
|
||||
addContentType(request.getHeaders(), contentType);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package io.metersphere.api.dto.automation.parse;
|
||||
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface ScenarioImportParser {
|
||||
ScenarioImport parse(InputStream source, ApiTestImportRequest request);
|
||||
}
|
|
@ -1,14 +1,15 @@
|
|||
package io.metersphere.api.dto.automation.parse;
|
||||
|
||||
import io.metersphere.api.parse.ApiImportParser;
|
||||
import io.metersphere.commons.constants.ApiImportPlatform;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ScenarioImportParserFactory {
|
||||
public static ScenarioImportParser getImportParser(String platform) {
|
||||
public static ApiImportParser getImportParser(String platform) {
|
||||
if (StringUtils.equals(ApiImportPlatform.Metersphere.name(), platform)) {
|
||||
return new MsScenarioParser();
|
||||
} else if (StringUtils.equals(ApiImportPlatform.Postman.name(), platform)) {
|
||||
return new MsPostmanParser();
|
||||
return new PostmanScenarioParser();
|
||||
} else if (StringUtils.equals(ApiImportPlatform.Jmeter.name(), platform)) {
|
||||
return new MsJmeterParser();
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import java.util.List;
|
|||
public class ApiExportResult {
|
||||
private String projectName;
|
||||
private String protocol;
|
||||
private String projectId;
|
||||
private String version;
|
||||
private List<ApiDefinitionWithBLOBs> data;
|
||||
private List<ApiTestCaseWithBLOBs> cases;
|
||||
}
|
||||
|
|
|
@ -14,10 +14,6 @@ public class ApiDefinitionImport {
|
|||
private String protocol;
|
||||
private List<ApiDefinitionWithBLOBs> data;
|
||||
|
||||
//导入场景
|
||||
private MsScenario scenarioDefinition;
|
||||
private List<ApiScenarioWithBLOBs> scenarioDefinitionData;
|
||||
|
||||
// 新版本带用例导出
|
||||
private List<ApiTestCaseWithBLOBs> cases;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package io.metersphere.api.parse;
|
||||
package io.metersphere.api.dto.definition.parse;
|
||||
|
||||
import io.metersphere.api.parse.ApiImportParser;
|
||||
import io.metersphere.commons.constants.ApiImportPlatform;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ApiImportParserFactory {
|
||||
public class ApiDefinitionImportParserFactory {
|
||||
public static ApiImportParser getApiImportParser(String platform) {
|
||||
if (StringUtils.equals(ApiImportPlatform.Metersphere.name(), platform)) {
|
||||
return new MsParser();
|
||||
return new MsDefinitionParser();
|
||||
} else if (StringUtils.equals(ApiImportPlatform.Postman.name(), platform)) {
|
||||
return new PostmanParser();
|
||||
return new PostmanDefinitionParser();
|
||||
} else if (StringUtils.equals(ApiImportPlatform.Swagger2.name(), platform)) {
|
||||
return new Swagger2Parser();
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package io.metersphere.api.dto.definition.parse;
|
||||
|
||||
import io.metersphere.api.dto.definition.ApiModuleDTO;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
import io.metersphere.api.service.ApiModuleService;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ApiDefinitionImportUtil {
|
||||
|
||||
public static ApiModule getSelectModule(String moduleId) {
|
||||
ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
if (StringUtils.isNotBlank(moduleId) && !StringUtils.equals("root", moduleId)) {
|
||||
ApiModule module = new ApiModule();
|
||||
ApiModuleDTO moduleDTO = apiModuleService.getNode(moduleId);
|
||||
if (moduleDTO != null) {
|
||||
BeanUtils.copyBean(module, moduleDTO);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ApiModule buildModule(ApiModule parentModule, String name, String projectId) {
|
||||
ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
ApiModule module;
|
||||
if (parentModule != null) {
|
||||
module = apiModuleService.getNewModule(name, projectId, parentModule.getLevel() + 1);
|
||||
module.setParentId(parentModule.getId());
|
||||
} else {
|
||||
module = apiModuleService.getNewModule(name, projectId, 1);
|
||||
}
|
||||
createModule(module);
|
||||
return module;
|
||||
}
|
||||
|
||||
public static void createModule(ApiModule module) {
|
||||
ApiModuleService apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
module.setProtocol(RequestType.HTTP);
|
||||
List<ApiModule> apiModules = apiModuleService.selectSameModule(module);
|
||||
if (CollectionUtils.isEmpty(apiModules)) {
|
||||
apiModuleService.addNode(module);
|
||||
} else {
|
||||
module.setId(apiModules.get(0).getId());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package io.metersphere.api.dto.definition.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
import io.metersphere.api.parse.MsAbstractParser;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
import io.metersphere.commons.constants.ApiImportPlatform;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
public class MsDefinitionParser extends MsAbstractParser<ApiDefinitionImport> {
|
||||
|
||||
@Override
|
||||
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
String testStr = getApiTestStr(source);
|
||||
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
|
||||
this.projectId = request.getProjectId();
|
||||
if (testObject.get("projectName") != null || testObject.get("projectId") != null ) {
|
||||
return parseMsFormat(testStr, request);
|
||||
} else {
|
||||
request.setPlatform(ApiImportPlatform.Plugin.name());
|
||||
ApiDefinitionImport apiImport = new ApiDefinitionImport();
|
||||
apiImport.setProtocol(RequestType.HTTP);
|
||||
apiImport.setData(parsePluginFormat(testObject, request, true));
|
||||
return apiImport;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<ApiDefinitionWithBLOBs> parsePluginFormat(JSONObject testObject, ApiTestImportRequest importRequest, Boolean isCreateModule) {
|
||||
List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
|
||||
testObject.keySet().forEach(tag -> {
|
||||
String moduleId = null;
|
||||
if (isCreateModule) {
|
||||
moduleId = ApiDefinitionImportUtil.buildModule(ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId()), tag, this.projectId).getId();
|
||||
}
|
||||
List<MsHTTPSamplerProxy> msHTTPSamplerProxies = parseMsHTTPSamplerProxy(testObject, tag);
|
||||
for (MsHTTPSamplerProxy msHTTPSamplerProxy : msHTTPSamplerProxies) {
|
||||
ApiDefinitionWithBLOBs apiDefinition = buildApiDefinition(msHTTPSamplerProxy.getId(), msHTTPSamplerProxy.getName(), msHTTPSamplerProxy.getPath(), msHTTPSamplerProxy.getMethod(), importRequest);
|
||||
apiDefinition.setModuleId(moduleId);
|
||||
apiDefinition.setProjectId(this.projectId);
|
||||
apiDefinition.setRequest(JSONObject.toJSONString(msHTTPSamplerProxy));
|
||||
apiDefinition.setName(apiDefinition.getPath() + " [" + apiDefinition.getMethod() + "]");
|
||||
results.add(apiDefinition);
|
||||
}
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
||||
private ApiDefinitionImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) {
|
||||
ApiDefinitionImport apiDefinitionImport = JSON.parseObject(testStr, ApiDefinitionImport.class);
|
||||
apiDefinitionImport.getData().forEach(apiDefinition -> {
|
||||
parseApiDefinition(apiDefinition, importRequest);
|
||||
});
|
||||
return apiDefinitionImport;
|
||||
}
|
||||
|
||||
private void parseApiDefinition(ApiDefinitionWithBLOBs apiDefinition, ApiTestImportRequest importRequest) {
|
||||
String id = UUID.randomUUID().toString();
|
||||
if (StringUtils.isBlank(apiDefinition.getModulePath())) {
|
||||
apiDefinition.setModuleId(null);
|
||||
}
|
||||
parseModule(apiDefinition.getModulePath(), importRequest, apiDefinition);
|
||||
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));
|
||||
}
|
||||
|
||||
private void parseModule(String modulePath, ApiTestImportRequest importRequest, ApiDefinitionWithBLOBs apiDefinition) {
|
||||
if (StringUtils.isEmpty(modulePath)) {
|
||||
return;
|
||||
}
|
||||
if (modulePath.startsWith("/")) {
|
||||
modulePath = modulePath.substring(1, modulePath.length());
|
||||
}
|
||||
if (modulePath.endsWith("/")) {
|
||||
modulePath = modulePath.substring(0, modulePath.length() - 1);
|
||||
}
|
||||
List<String> modules = Arrays.asList(modulePath.split("/"));
|
||||
ApiModule parent = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId());
|
||||
Iterator<String> iterator = modules.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String item = iterator.next();
|
||||
parent = ApiDefinitionImportUtil.buildModule(parent, item, this.projectId);
|
||||
if (!iterator.hasNext()) {
|
||||
apiDefinition.setModuleId(parent.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package io.metersphere.api.dto.definition.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanCollection;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanItem;
|
||||
import io.metersphere.api.dto.parse.postman.PostmanKeyValue;
|
||||
import io.metersphere.api.parse.PostmanAbstractParserParser;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PostmanDefinitionParser extends PostmanAbstractParserParser<ApiDefinitionImport> {
|
||||
|
||||
@Override
|
||||
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
String testStr = getApiTestStr(source);
|
||||
this.projectId = request.getProjectId();
|
||||
PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class);
|
||||
List<PostmanKeyValue> variables = postmanCollection.getVariable();
|
||||
ApiDefinitionImport apiImport = new ApiDefinitionImport();
|
||||
List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
|
||||
parseItem(postmanCollection.getItem(), variables, results,
|
||||
ApiDefinitionImportUtil.buildModule(ApiDefinitionImportUtil.getSelectModule(request.getModuleId()), postmanCollection.getInfo().getName(), this.projectId), true);
|
||||
apiImport.setData(results);
|
||||
return apiImport;
|
||||
}
|
||||
|
||||
protected void parseItem(List<PostmanItem> items, List<PostmanKeyValue> variables, List<ApiDefinitionWithBLOBs> results, ApiModule parentModule, Boolean isCreateModule) {
|
||||
for (PostmanItem item : items) {
|
||||
List<PostmanItem> childItems = item.getItem();
|
||||
if (childItems != null) {
|
||||
ApiModule module = null;
|
||||
if (isCreateModule) {
|
||||
module = ApiDefinitionImportUtil.buildModule(parentModule, item.getName(), this.projectId);
|
||||
}
|
||||
parseItem(childItems, variables, results, module, isCreateModule);
|
||||
} else {
|
||||
MsHTTPSamplerProxy msHTTPSamplerProxy = parsePostman(item);
|
||||
ApiDefinitionWithBLOBs request = buildApiDefinition(msHTTPSamplerProxy.getId(), msHTTPSamplerProxy.getName(),
|
||||
msHTTPSamplerProxy.getPath(), msHTTPSamplerProxy.getMethod(), new ApiTestImportRequest());
|
||||
request.setPath(msHTTPSamplerProxy.getPath());
|
||||
request.setRequest(JSON.toJSONString(msHTTPSamplerProxy));
|
||||
|
||||
if (request != null) {
|
||||
results.add(request);
|
||||
}
|
||||
if (parentModule != null) {
|
||||
request.setModuleId(parentModule.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
package io.metersphere.api.parse;
|
||||
package io.metersphere.api.dto.definition.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.definition.response.HttpResponse;
|
||||
import io.metersphere.api.dto.scenario.Body;
|
||||
|
@ -57,7 +56,7 @@ public class Swagger2Parser extends SwaggerAbstractParser {
|
|||
|
||||
List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
|
||||
|
||||
ApiModule parentNode = getSelectModule(importRequest.getModuleId());
|
||||
ApiModule parentNode = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId());
|
||||
|
||||
for (String pathName : pathNames) {
|
||||
Path path = paths.get(pathName);
|
|
@ -1,10 +1,9 @@
|
|||
package io.metersphere.api.parse;
|
||||
package io.metersphere.api.dto.definition.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.definition.response.HttpResponse;
|
||||
import io.metersphere.api.dto.scenario.Body;
|
||||
|
@ -78,7 +77,7 @@ public class Swagger3Parser extends SwaggerAbstractParser {
|
|||
|
||||
List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
|
||||
|
||||
ApiModule parentNode = getSelectModule(importRequest.getModuleId());
|
||||
ApiModule parentNode = ApiDefinitionImportUtil.getSelectModule(importRequest.getModuleId());
|
||||
|
||||
for (String pathName : pathNames) {
|
||||
PathItem pathItem = paths.get(pathName);
|
|
@ -1,16 +1,17 @@
|
|||
package io.metersphere.api.parse;
|
||||
package io.metersphere.api.dto.definition.parse;
|
||||
|
||||
import io.metersphere.api.parse.ApiImportAbstractParser;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class SwaggerAbstractParser extends ApiImportAbstractParser {
|
||||
public abstract class SwaggerAbstractParser extends ApiImportAbstractParser<ApiDefinitionImport> {
|
||||
|
||||
protected void buildModule(ApiModule parentModule, ApiDefinitionWithBLOBs apiDefinition, List<String> tags) {
|
||||
if (tags != null) {
|
||||
tags.forEach(tag -> {
|
||||
ApiModule module = buildModule(parentModule, tag);
|
||||
ApiModule module = ApiDefinitionImportUtil.buildModule(parentModule, tag, this.projectId);
|
||||
apiDefinition.setModuleId(module.getId());
|
||||
});
|
||||
}
|
|
@ -66,9 +66,6 @@ public class MsScenario extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
if (this.getReferenced() != null && this.getReferenced().equals("Deleted")) {
|
||||
return;
|
||||
} else if (this.getReferenced() != null && this.getReferenced().equals("REF")) {
|
||||
|
@ -77,16 +74,15 @@ public class MsScenario extends MsTestElement {
|
|||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
ApiScenarioWithBLOBs scenario = apiAutomationService.getApiScenario(this.getId());
|
||||
JSONObject element = JSON.parseObject(scenario.getScenarioDefinition());
|
||||
hashTree = mapper.readValue(element.getString("hashTree"), new TypeReference<LinkedList<MsTestElement>>() {
|
||||
});
|
||||
if (scenario != null && StringUtils.isNotEmpty(scenario.getScenarioDefinition())) {
|
||||
JSONObject element = JSON.parseObject(scenario.getScenarioDefinition());
|
||||
hashTree = mapper.readValue(element.getString("hashTree"), new TypeReference<LinkedList<MsTestElement>>() {
|
||||
});
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
config.setStep(this.getName());
|
||||
config.setStepType("SCENARIO");
|
||||
config.setEnableCookieShare(enableCookieShare);
|
||||
if (StringUtils.isNotEmpty(environmentId)) {
|
||||
ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
|
||||
|
@ -103,6 +99,9 @@ public class MsScenario extends MsTestElement {
|
|||
this.addCsvDataSet(tree, variables);
|
||||
this.addCounter(tree, variables);
|
||||
this.addRandom(tree, variables);
|
||||
if (CollectionUtils.isNotEmpty(this.headers)) {
|
||||
setHeader(tree, this.headers);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||
for (MsTestElement el : hashTree) {
|
||||
// 给所有孩子加一个父亲标志
|
||||
|
@ -110,9 +109,6 @@ public class MsScenario extends MsTestElement {
|
|||
el.toHashTree(tree, el.getHashTree(), config);
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(this.headers)) {
|
||||
setHeader(tree, this.headers);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOldVariables(List<KeyValue> oldVariables) {
|
||||
|
|
|
@ -164,9 +164,9 @@ public abstract class MsTestElement {
|
|||
}
|
||||
|
||||
public Arguments addArguments(ParameterConfig config) {
|
||||
Arguments arguments = new Arguments();
|
||||
if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null
|
||||
&& CollectionUtils.isNotEmpty(config.getConfig().getCommonConfig().getVariables())) {
|
||||
Arguments arguments = new Arguments();
|
||||
arguments.setEnabled(true);
|
||||
arguments.setName(name + "Variables");
|
||||
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
|
||||
|
@ -174,8 +174,9 @@ public abstract class MsTestElement {
|
|||
config.getConfig().getCommonConfig().getVariables().stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue ->
|
||||
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
|
||||
);
|
||||
return arguments;
|
||||
}
|
||||
return arguments;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected EnvironmentConfig getEnvironmentConfig(String environmentId) {
|
||||
|
@ -255,14 +256,15 @@ public abstract class MsTestElement {
|
|||
}
|
||||
}
|
||||
|
||||
public MsTestElement getRootParent(MsTestElement element) {
|
||||
public void getFullPath(MsTestElement element, StringBuilder path) {
|
||||
if (element.getParent() == null) {
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
if (MsTestElementConstants.LoopController.name().equals(element.getType())) {
|
||||
return element;
|
||||
return;
|
||||
}
|
||||
return getRootParent(element.getParent());
|
||||
path.append(element.getResourceId()).append("/");
|
||||
getFullPath(element.getParent(), path);
|
||||
}
|
||||
|
||||
protected String getParentName(MsTestElement parent, ParameterConfig config) {
|
||||
|
@ -279,13 +281,11 @@ public abstract class MsTestElement {
|
|||
return "次数循环-" + "${LoopCounterConfigXXX}";
|
||||
}
|
||||
}
|
||||
return parent.getName();
|
||||
} else if (config != null && StringUtils.isNotEmpty(config.getStep())) {
|
||||
if (MsTestElementConstants.SCENARIO.name().equals(config.getStepType())) {
|
||||
return config.getStep();
|
||||
} else {
|
||||
return config.getStep() + "-" + "${LoopCounterConfigXXX}";
|
||||
}
|
||||
// 获取全路径以备后面使用
|
||||
StringBuilder fullPath = new StringBuilder();
|
||||
getFullPath(parent, fullPath);
|
||||
|
||||
return fullPath + "<->" + parent.getName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -45,11 +45,11 @@ public class MsThreadGroup extends MsTestElement {
|
|||
loopController.setName("LoopController");
|
||||
loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
|
||||
loopController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("LoopControlPanel"));
|
||||
loopController.setEnabled(true);
|
||||
loopController.setEnabled(this.isEnable());
|
||||
loopController.setLoops(1);
|
||||
|
||||
ThreadGroup threadGroup = new ThreadGroup();
|
||||
threadGroup.setEnabled(true);
|
||||
threadGroup.setEnabled(this.isEnable());
|
||||
threadGroup.setName(this.getName());
|
||||
threadGroup.setProperty(TestElement.TEST_CLASS, ThreadGroup.class.getName());
|
||||
threadGroup.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ThreadGroupGui"));
|
||||
|
|
|
@ -8,15 +8,21 @@ import java.util.List;
|
|||
|
||||
@Data
|
||||
public class ParameterConfig {
|
||||
// 环境配置
|
||||
/**
|
||||
* 环境配置
|
||||
*/
|
||||
private EnvironmentConfig config;
|
||||
// 公共场景参数
|
||||
/**
|
||||
* 公共场景参数
|
||||
*/
|
||||
private List<ScenarioVariable> variables;
|
||||
// 公共Cookie
|
||||
/**
|
||||
* 公共Cookie
|
||||
*/
|
||||
private boolean enableCookieShare;
|
||||
// 步骤
|
||||
private String step;
|
||||
|
||||
private String stepType;
|
||||
|
||||
/**
|
||||
* 是否是导入/导出操作
|
||||
*/
|
||||
private boolean isOperating;
|
||||
}
|
||||
|
|
|
@ -27,9 +27,7 @@ public class MsAssertions extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (this.isEnable()) {
|
||||
addAssertions(tree);
|
||||
}
|
||||
addAssertions(tree);
|
||||
}
|
||||
|
||||
private void addAssertions(HashTree hashTree) {
|
||||
|
@ -64,7 +62,7 @@ public class MsAssertions extends MsTestElement {
|
|||
|
||||
private ResponseAssertion responseAssertion(MsAssertionRegex assertionRegex) {
|
||||
ResponseAssertion assertion = new ResponseAssertion();
|
||||
assertion.setEnabled(true);
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName(assertionRegex.getDescription());
|
||||
assertion.setProperty(TestElement.TEST_CLASS, ResponseAssertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("AssertionGui"));
|
||||
|
@ -89,7 +87,7 @@ public class MsAssertions extends MsTestElement {
|
|||
|
||||
private JSONPathAssertion jsonPathAssertion(MsAssertionJsonPath assertionJsonPath) {
|
||||
JSONPathAssertion assertion = new JSONPathAssertion();
|
||||
assertion.setEnabled(true);
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName(StringUtils.isEmpty(assertionJsonPath.getDescription()) ? "JSONPathAssertion" : assertionJsonPath.getDescription());
|
||||
assertion.setProperty(TestElement.TEST_CLASS, JSONPathAssertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("JSONPathAssertionGui"));
|
||||
|
@ -104,7 +102,7 @@ public class MsAssertions extends MsTestElement {
|
|||
|
||||
private XPath2Assertion xPath2Assertion(MsAssertionXPath2 assertionXPath2) {
|
||||
XPath2Assertion assertion = new XPath2Assertion();
|
||||
assertion.setEnabled(true);
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName(StringUtils.isEmpty(assertionXPath2.getExpression()) ? "XPath2Assertion" : assertionXPath2.getExpression());
|
||||
assertion.setProperty(TestElement.TEST_CLASS, XPath2Assertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("XPath2AssertionGui"));
|
||||
|
@ -115,7 +113,7 @@ public class MsAssertions extends MsTestElement {
|
|||
|
||||
private DurationAssertion durationAssertion(MsAssertionDuration assertionDuration) {
|
||||
DurationAssertion assertion = new DurationAssertion();
|
||||
assertion.setEnabled(true);
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName("Response In Time: " + assertionDuration.getValue());
|
||||
assertion.setProperty(TestElement.TEST_CLASS, DurationAssertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("DurationAssertionGui"));
|
||||
|
@ -125,7 +123,7 @@ public class MsAssertions extends MsTestElement {
|
|||
|
||||
private JSR223Assertion jsr223Assertion(MsAssertionJSR223 assertionJSR223) {
|
||||
JSR223Assertion assertion = new JSR223Assertion();
|
||||
assertion.setEnabled(true);
|
||||
assertion.setEnabled(this.isEnable());
|
||||
assertion.setName(StringUtils.isEmpty(assertionJSR223.getDesc()) ? "JSR223Assertion" : assertionJSR223.getDesc());
|
||||
assertion.setProperty(TestElement.TEST_CLASS, JSR223Assertion.class.getName());
|
||||
assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI"));
|
||||
|
|
|
@ -27,11 +27,8 @@ public class MsHeaderManager extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
HeaderManager headerManager = new HeaderManager();
|
||||
headerManager.setEnabled(true);
|
||||
headerManager.setEnabled(this.isEnable());
|
||||
headerManager.setName(this.getName() + "Headers");
|
||||
headerManager.setProperty(TestElement.TEST_CLASS, HeaderManager.class.getName());
|
||||
headerManager.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("HeaderPanel"));
|
||||
|
|
|
@ -26,9 +26,6 @@ public class MsIfController extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
final HashTree groupTree = tree.add(ifController());
|
||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||
hashTree.forEach(el -> {
|
||||
|
@ -41,7 +38,7 @@ public class MsIfController extends MsTestElement {
|
|||
|
||||
private IfController ifController() {
|
||||
IfController ifController = new IfController();
|
||||
ifController.setEnabled(true);
|
||||
ifController.setEnabled(this.isEnable());
|
||||
ifController.setName(StringUtils.isEmpty(this.getName()) ? "IfController" : this.getName());
|
||||
ifController.setProperty(TestElement.TEST_CLASS, IfController.class.getName());
|
||||
ifController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("IfControllerPanel"));
|
||||
|
|
|
@ -44,21 +44,6 @@ public class MsLoopController extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.equals(this.loopType, LoopConstants.WHILE.name()) && this.whileController != null) {
|
||||
config.setStep("While 循环");
|
||||
}
|
||||
if (StringUtils.equals(this.loopType, LoopConstants.FOREACH.name()) && this.forEachController != null) {
|
||||
config.setStep("ForEach 循环");
|
||||
}
|
||||
if (StringUtils.equals(this.loopType, LoopConstants.LOOP_COUNT.name()) && this.countController != null) {
|
||||
config.setStep("次数循环");
|
||||
}
|
||||
|
||||
config.setStepType("LOOP");
|
||||
|
||||
final HashTree groupTree = controller(tree);
|
||||
if (CollectionUtils.isNotEmpty(config.getVariables())) {
|
||||
this.addCsvDataSet(groupTree, config.getVariables());
|
||||
|
@ -104,7 +89,7 @@ public class MsLoopController extends MsTestElement {
|
|||
|
||||
private LoopController initLoopController() {
|
||||
LoopController loopController = new LoopController();
|
||||
loopController.setEnabled(true);
|
||||
loopController.setEnabled(this.isEnable());
|
||||
loopController.setName("LoopController");
|
||||
loopController.setProperty(TestElement.TEST_CLASS, LoopController.class.getName());
|
||||
loopController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("LoopControlPanel"));
|
||||
|
@ -142,7 +127,7 @@ public class MsLoopController extends MsTestElement {
|
|||
return null;
|
||||
}
|
||||
WhileController controller = new WhileController();
|
||||
controller.setEnabled(true);
|
||||
controller.setEnabled(this.isEnable());
|
||||
controller.setName("WhileController");
|
||||
controller.setProperty(TestElement.TEST_CLASS, WhileController.class.getName());
|
||||
controller.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("WhileControllerGui"));
|
||||
|
@ -152,7 +137,7 @@ public class MsLoopController extends MsTestElement {
|
|||
|
||||
private ForeachController initForeachController() {
|
||||
ForeachController controller = new ForeachController();
|
||||
controller.setEnabled(true);
|
||||
controller.setEnabled(this.isEnable());
|
||||
controller.setName("ForeachController");
|
||||
controller.setProperty(TestElement.TEST_CLASS, ForeachController.class.getName());
|
||||
controller.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ForeachControlPanel"));
|
||||
|
@ -188,7 +173,7 @@ public class MsLoopController extends MsTestElement {
|
|||
|
||||
private ConstantTimer getCnstantTimer() {
|
||||
ConstantTimer constantTimer = new ConstantTimer();
|
||||
constantTimer.setEnabled(true);
|
||||
constantTimer.setEnabled(this.isEnable());
|
||||
constantTimer.setProperty(TestElement.TEST_CLASS, ConstantTimer.class.getName());
|
||||
constantTimer.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ConstantTimerGui"));
|
||||
if (StringUtils.equals(this.loopType, LoopConstants.WHILE.name()) && this.whileController != null) {
|
||||
|
|
|
@ -30,9 +30,6 @@ public class MsExtract extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
addRequestExtractors(tree);
|
||||
}
|
||||
|
||||
|
@ -68,7 +65,7 @@ public class MsExtract extends MsTestElement {
|
|||
private RegexExtractor regexExtractor(MsExtractRegex extractRegex, StringJoiner extract) {
|
||||
|
||||
RegexExtractor extractor = new RegexExtractor();
|
||||
extractor.setEnabled(true);
|
||||
extractor.setEnabled(this.isEnable());
|
||||
extractor.setName(extractRegex.getVariable() + " RegexExtractor");
|
||||
extractor.setProperty(TestElement.TEST_CLASS, RegexExtractor.class.getName());
|
||||
extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("RegexExtractorGui"));
|
||||
|
@ -86,7 +83,7 @@ public class MsExtract extends MsTestElement {
|
|||
|
||||
private XPath2Extractor xPath2Extractor(MsExtractXPath extractXPath, StringJoiner extract) {
|
||||
XPath2Extractor extractor = new XPath2Extractor();
|
||||
extractor.setEnabled(true);
|
||||
extractor.setEnabled(this.isEnable());
|
||||
extractor.setName(extractXPath.getVariable() + " XPath2Extractor");
|
||||
extractor.setProperty(TestElement.TEST_CLASS, XPath2Extractor.class.getName());
|
||||
extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("XPath2ExtractorGui"));
|
||||
|
@ -101,7 +98,7 @@ public class MsExtract extends MsTestElement {
|
|||
|
||||
private JSONPostProcessor jsonPostProcessor(MsExtractJSONPath extractJSONPath, StringJoiner extract) {
|
||||
JSONPostProcessor extractor = new JSONPostProcessor();
|
||||
extractor.setEnabled(true);
|
||||
extractor.setEnabled(this.isEnable());
|
||||
extractor.setName(extractJSONPath.getVariable() + " JSONExtractor");
|
||||
extractor.setProperty(TestElement.TEST_CLASS, JSONPostProcessor.class.getName());
|
||||
extractor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("JSONPostProcessorGui"));
|
||||
|
|
|
@ -29,18 +29,15 @@ public class MsJSR223Processor extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
JSR223Sampler processor = new JSR223Sampler();
|
||||
processor.setEnabled(true);
|
||||
processor.setEnabled(this.isEnable());
|
||||
if (StringUtils.isNotEmpty(this.getName())) {
|
||||
processor.setName(this.getName());
|
||||
} else {
|
||||
processor.setName("JSR223Processor");
|
||||
}
|
||||
String name = this.getParentName(this.getParent(), config);
|
||||
if (StringUtils.isNotEmpty(name)) {
|
||||
if (StringUtils.isNotEmpty(name) && !config.isOperating()) {
|
||||
processor.setName(this.getName() + "<->" + name);
|
||||
}
|
||||
processor.setProperty(TestElement.TEST_CLASS, JSR223Sampler.class.getName());
|
||||
|
|
|
@ -29,11 +29,8 @@ public class MsJSR223PostProcessor extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
JSR223PostProcessor processor = new JSR223PostProcessor();
|
||||
processor.setEnabled(true);
|
||||
processor.setEnabled(this.isEnable());
|
||||
if (StringUtils.isNotEmpty(this.getName())) {
|
||||
processor.setName(this.getName());
|
||||
} else {
|
||||
|
|
|
@ -29,9 +29,6 @@ public class MsJSR223PreProcessor extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
final HashTree jsr223PreTree = tree.add(getJSR223PreProcessor());
|
||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||
hashTree.forEach(el -> {
|
||||
|
@ -42,7 +39,7 @@ public class MsJSR223PreProcessor extends MsTestElement {
|
|||
|
||||
public JSR223PreProcessor getJSR223PreProcessor() {
|
||||
JSR223PreProcessor processor = new JSR223PreProcessor();
|
||||
processor.setEnabled(true);
|
||||
processor.setEnabled(this.isEnable());
|
||||
if (StringUtils.isNotEmpty(this.getName())) {
|
||||
processor.setName(this.getName());
|
||||
} else {
|
||||
|
|
|
@ -33,7 +33,7 @@ public class MsDubboSampler extends MsTestElement {
|
|||
private String type = "DubboSampler";
|
||||
|
||||
@JSONField(ordinal = 52)
|
||||
private String protocol = "DUBBO";
|
||||
private final String protocol = "dubbo://";
|
||||
@JsonProperty(value = "interface")
|
||||
@JSONField(ordinal = 53, name = "interface")
|
||||
private String _interface;
|
||||
|
@ -52,14 +52,11 @@ public class MsDubboSampler extends MsTestElement {
|
|||
@JSONField(ordinal = 59)
|
||||
private List<KeyValue> attachmentArgs;
|
||||
|
||||
@JSONField(ordinal = 60)
|
||||
private Object requestResult;
|
||||
// @JSONField(ordinal = 60)
|
||||
// private Object requestResult;
|
||||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
if (this.getReferenced() != null && "Deleted".equals(this.getReferenced())) {
|
||||
return;
|
||||
}
|
||||
|
@ -77,9 +74,10 @@ public class MsDubboSampler extends MsTestElement {
|
|||
|
||||
private DubboSample dubboSample(ParameterConfig config) {
|
||||
DubboSample sampler = new DubboSample();
|
||||
sampler.setEnabled(this.isEnable());
|
||||
sampler.setName(this.getName());
|
||||
String name = this.getParentName(this.getParent(), config);
|
||||
if (StringUtils.isNotEmpty(name)) {
|
||||
if (StringUtils.isNotEmpty(name) && !config.isOperating()) {
|
||||
sampler.setName(this.getName() + "<->" + name);
|
||||
}
|
||||
sampler.setProperty(TestElement.TEST_CLASS, DubboSample.class.getName());
|
||||
|
|
|
@ -85,25 +85,23 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
@JSONField(ordinal = 34)
|
||||
private List<KeyValue> arguments;
|
||||
|
||||
@JSONField(ordinal = 35)
|
||||
private Object requestResult;
|
||||
// @JSONField(ordinal = 35)
|
||||
// private Object requestResult;
|
||||
|
||||
@JSONField(ordinal = 36)
|
||||
private MsAuthManager authManager;
|
||||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
|
||||
this.getRefElement(this);
|
||||
}
|
||||
HTTPSamplerProxy sampler = new HTTPSamplerProxy();
|
||||
sampler.setEnabled(true);
|
||||
sampler.setEnabled(this.isEnable());
|
||||
sampler.setName(this.getName());
|
||||
String name = this.getParentName(this.getParent(), config);
|
||||
if (StringUtils.isNotEmpty(name)) {
|
||||
if (StringUtils.isNotEmpty(name) && !config.isOperating()) {
|
||||
sampler.setName(this.getName() + "<->" + name);
|
||||
}
|
||||
sampler.setProperty(TestElement.TEST_CLASS, HTTPSamplerProxy.class.getName());
|
||||
|
@ -124,7 +122,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
// 添加环境中的公共变量
|
||||
Arguments arguments = this.addArguments(config);
|
||||
if (arguments != null) {
|
||||
tree.add(this.addArguments(config));
|
||||
tree.add(arguments);
|
||||
}
|
||||
try {
|
||||
if (config != null && config.getConfig() != null) {
|
||||
|
|
|
@ -46,8 +46,8 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
private List<KeyValue> variables;
|
||||
@JSONField(ordinal = 26)
|
||||
private String environmentId;
|
||||
@JSONField(ordinal = 27)
|
||||
private Object requestResult;
|
||||
// @JSONField(ordinal = 27)
|
||||
// private Object requestResult;
|
||||
@JSONField(ordinal = 28)
|
||||
private String dataSourceId;
|
||||
@JSONField(ordinal = 29)
|
||||
|
@ -55,9 +55,6 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
|
||||
this.getRefElement(this);
|
||||
}
|
||||
|
@ -70,7 +67,10 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
}
|
||||
final HashTree samplerHashTree = tree.add(jdbcSampler(config));
|
||||
tree.add(jdbcDataSource());
|
||||
tree.add(arguments(this.getName() + " Variables", this.getVariables()));
|
||||
Arguments arguments = arguments(this.getName() + " Variables", this.getVariables());
|
||||
if (arguments != null) {
|
||||
tree.add(arguments);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||
hashTree.forEach(el -> {
|
||||
el.toHashTree(samplerHashTree, el.getHashTree(), config);
|
||||
|
@ -95,24 +95,26 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
}
|
||||
|
||||
private Arguments arguments(String name, List<KeyValue> variables) {
|
||||
Arguments arguments = new Arguments();
|
||||
if (CollectionUtils.isNotEmpty(variables)) {
|
||||
Arguments arguments = new Arguments();
|
||||
arguments.setEnabled(true);
|
||||
arguments.setName(name);
|
||||
arguments.setName(name + "JDBC_Argument");
|
||||
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
|
||||
arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ArgumentsPanel"));
|
||||
variables.stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue ->
|
||||
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
|
||||
);
|
||||
return arguments;
|
||||
}
|
||||
return arguments;
|
||||
return null;
|
||||
}
|
||||
|
||||
private JDBCSampler jdbcSampler(ParameterConfig config) {
|
||||
JDBCSampler sampler = new JDBCSampler();
|
||||
sampler.setEnabled(this.isEnable());
|
||||
sampler.setName(this.getName());
|
||||
String name = this.getParentName(this.getParent(), config);
|
||||
if (StringUtils.isNotEmpty(name)) {
|
||||
if (StringUtils.isNotEmpty(name) && !config.isOperating()) {
|
||||
sampler.setName(this.getName() + "<->" + name);
|
||||
}
|
||||
sampler.setProperty(TestElement.TEST_CLASS, JDBCSampler.class.getName());
|
||||
|
|
|
@ -59,8 +59,8 @@ public class MsTCPSampler extends MsTestElement {
|
|||
private String password = "";
|
||||
@JSONField(ordinal = 33)
|
||||
private String request;
|
||||
@JSONField(ordinal = 34)
|
||||
private Object requestResult;
|
||||
// @JSONField(ordinal = 34)
|
||||
// private Object requestResult;
|
||||
@JSONField(ordinal = 35)
|
||||
private List<KeyValue> parameters;
|
||||
@JSONField(ordinal = 36)
|
||||
|
@ -72,9 +72,6 @@ public class MsTCPSampler extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
if (this.getReferenced() != null && MsTestElementConstants.REF.name().equals(this.getReferenced())) {
|
||||
this.getRefElement(this);
|
||||
}
|
||||
|
@ -84,7 +81,7 @@ public class MsTCPSampler extends MsTestElement {
|
|||
// 添加环境中的公共变量
|
||||
Arguments arguments = this.addArguments(config);
|
||||
if (arguments != null) {
|
||||
tree.add(this.addArguments(config));
|
||||
tree.add(arguments);
|
||||
}
|
||||
|
||||
final HashTree samplerHashTree = new ListedHashTree();
|
||||
|
@ -110,9 +107,10 @@ public class MsTCPSampler extends MsTestElement {
|
|||
|
||||
private TCPSampler tcpSampler(ParameterConfig config) {
|
||||
TCPSampler tcpSampler = new TCPSampler();
|
||||
tcpSampler.setEnabled(this.isEnable());
|
||||
tcpSampler.setName(this.getName());
|
||||
String name = this.getParentName(this.getParent(), config);
|
||||
if (StringUtils.isNotEmpty(name)) {
|
||||
if (StringUtils.isNotEmpty(name) && !config.isOperating()) {
|
||||
tcpSampler.setName(this.getName() + "<->" + name);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,7 @@ public class MsConstantTimer extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final HashTree groupTree = tree.add(constantTimer());
|
||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||
hashTree.forEach(el -> {
|
||||
|
@ -39,7 +37,7 @@ public class MsConstantTimer extends MsTestElement {
|
|||
|
||||
private ConstantTimer constantTimer() {
|
||||
ConstantTimer constantTimer = new ConstantTimer();
|
||||
constantTimer.setEnabled(true);
|
||||
constantTimer.setEnabled(this.isEnable());
|
||||
constantTimer.setName(this.getDelay() + " ms");
|
||||
constantTimer.setProperty(TestElement.TEST_CLASS, ConstantTimer.class.getName());
|
||||
constantTimer.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("ConstantTimerGui"));
|
||||
|
|
|
@ -29,17 +29,17 @@ public class MsJmeterElement extends MsTestElement {
|
|||
|
||||
@Override
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree, ParameterConfig config) {
|
||||
if (!this.isEnable()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
InputStream inputSource = getStrToStream(jmeterElement);
|
||||
if (inputSource != null) {
|
||||
Object scriptWrapper = SaveService.loadElement(inputSource);
|
||||
HashTree elementTree = tree;
|
||||
if (!(scriptWrapper instanceof TestPlan) && !(scriptWrapper instanceof ThreadGroup)) {
|
||||
if (config.isOperating()) {
|
||||
elementTree = tree.add(scriptWrapper);
|
||||
} else if (!(scriptWrapper instanceof TestPlan) && !(scriptWrapper instanceof ThreadGroup)) {
|
||||
elementTree = tree.add(scriptWrapper);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||
for (MsTestElement el : hashTree) {
|
||||
el.toHashTree(elementTree, el.getHashTree(), config);
|
||||
|
|
|
@ -40,6 +40,10 @@ public class ScenarioVariable {
|
|||
private String minNumber;
|
||||
private String maxNumber;
|
||||
|
||||
public ScenarioVariable() {
|
||||
|
||||
}
|
||||
|
||||
public ScenarioVariable(String key, String value, String description, String type) {
|
||||
this.name = key;
|
||||
this.value = value;
|
||||
|
|
|
@ -48,8 +48,8 @@ public class TestResult {
|
|||
result.getRequestResults().forEach(item -> {
|
||||
if (StringUtils.isNotEmpty(item.getName()) && item.getName().indexOf(SEPARATOR) != -1) {
|
||||
String array[] = item.getName().split(SEPARATOR);
|
||||
String scenarioName = array[array.length - 1];
|
||||
item.setName(item.getName().replace(SEPARATOR + scenarioName, ""));
|
||||
String scenarioName = item.getName().replace(array[0] + SEPARATOR, "");
|
||||
item.setName(array[0]);
|
||||
if (requestResultMap.containsKey(scenarioName)) {
|
||||
requestResultMap.get(scenarioName).add(item);
|
||||
} else {
|
||||
|
@ -80,6 +80,9 @@ public class TestResult {
|
|||
ScenarioResult scenarioResult = new ScenarioResult();
|
||||
BeanUtils.copyBean(scenarioResult, result);
|
||||
scenarioResult.setName(k);
|
||||
if (k.indexOf(SEPARATOR) != -1) {
|
||||
scenarioResult.setName(k.split(SEPARATOR)[1]);
|
||||
}
|
||||
scenarioResult.setRequestResults(v);
|
||||
scenarios.add(scenarioResult);
|
||||
});
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.ApiModuleDTO;
|
||||
import io.metersphere.api.dto.definition.request.MsScenario;
|
||||
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.Scenario;
|
||||
import io.metersphere.api.dto.scenario.request.RequestType;
|
||||
import io.metersphere.api.service.ApiModuleService;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
@ -29,10 +27,9 @@ import java.util.List;
|
|||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class ApiImportAbstractParser implements ApiImportParser {
|
||||
public abstract class ApiImportAbstractParser<T> implements ApiImportParser<T> {
|
||||
|
||||
protected String projectId;
|
||||
protected ApiModuleService apiModuleService;
|
||||
|
||||
protected String getApiTestStr(InputStream source) {
|
||||
StringBuilder testStr = null;
|
||||
|
@ -47,7 +44,9 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
|||
LogUtil.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
source.close();
|
||||
if (source != null) {
|
||||
source.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
MSException.throwException(e.getMessage());
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
|
@ -62,42 +61,6 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
|||
}
|
||||
}
|
||||
|
||||
protected ApiModule getSelectModule(String moduleId) {
|
||||
apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
if (StringUtils.isNotBlank(moduleId) && !StringUtils.equals("root", moduleId)) {
|
||||
ApiModule module = new ApiModule();
|
||||
ApiModuleDTO moduleDTO = apiModuleService.getNode(moduleId);
|
||||
if (moduleDTO != null) {
|
||||
BeanUtils.copyBean(module, moduleDTO);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected ApiModule buildModule(ApiModule parentModule, String name) {
|
||||
apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
ApiModule module;
|
||||
if (parentModule != null) {
|
||||
module = apiModuleService.getNewModule(name, this.projectId, parentModule.getLevel() + 1);
|
||||
module.setParentId(parentModule.getId());
|
||||
} else {
|
||||
module = apiModuleService.getNewModule(name, this.projectId, 1);
|
||||
}
|
||||
createModule(module);
|
||||
return module;
|
||||
}
|
||||
|
||||
protected void createModule(ApiModule module) {
|
||||
module.setProtocol(RequestType.HTTP);
|
||||
List<ApiModule> apiModules = apiModuleService.selectSameModule(module);
|
||||
if (CollectionUtils.isEmpty(apiModules)) {
|
||||
apiModuleService.addNode(module);
|
||||
} else {
|
||||
module.setId(apiModules.get(0).getId());
|
||||
}
|
||||
}
|
||||
|
||||
protected String getBodyType(String contentType) {
|
||||
String bodyType = "";
|
||||
switch (contentType) {
|
||||
|
@ -233,4 +196,22 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
|||
headers.add(new KeyValue(key, value, description, contentType, required));
|
||||
}
|
||||
}
|
||||
|
||||
protected ApiScenarioWithBLOBs parseScenario(MsScenario msScenario) {
|
||||
// ApiScenarioModule module = ApiScenarioImportUtil.buildModule(ApiScenarioImportUtil.getSelectModule(request.getModuleId()), msScenario.getName(), this.projectId);
|
||||
ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs();
|
||||
scenarioWithBLOBs.setName(msScenario.getName());
|
||||
scenarioWithBLOBs.setProjectId(this.projectId);
|
||||
if (msScenario != null && CollectionUtils.isNotEmpty(msScenario.getHashTree())) {
|
||||
scenarioWithBLOBs.setStepTotal(msScenario.getHashTree().size());
|
||||
}
|
||||
// if (module != null) {
|
||||
// scenarioWithBLOBs.setApiScenarioModuleId(module.getId());
|
||||
// scenarioWithBLOBs.setModulePath("/" + module.getName());
|
||||
// }
|
||||
scenarioWithBLOBs.setId(UUID.randomUUID().toString());
|
||||
scenarioWithBLOBs.setScenarioDefinition(JSON.toJSONString(msScenario));
|
||||
return scenarioWithBLOBs;
|
||||
// scenarioWithBLOBsList.add(scenarioWithBLOBs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface ApiImportParser {
|
||||
ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request);
|
||||
public interface ApiImportParser<T> {
|
||||
T parse(InputStream source, ApiTestImportRequest request);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
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.commons.utils.LogUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class MsAbstractParser<T> extends ApiImportAbstractParser<T> {
|
||||
|
||||
protected List<MsHTTPSamplerProxy> parseMsHTTPSamplerProxy(JSONObject testObject, String tag) {
|
||||
JSONObject requests = testObject.getJSONObject(tag);
|
||||
List<MsHTTPSamplerProxy> msHTTPSamplerProxies = new ArrayList<>();
|
||||
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);
|
||||
parseBody(requestObject, request.getBody());
|
||||
parseHeader(requestObject, request.getHeaders());
|
||||
parsePath(request);
|
||||
msHTTPSamplerProxies.add(request);
|
||||
});
|
||||
return msHTTPSamplerProxies;
|
||||
}
|
||||
|
||||
private void parsePath(MsHTTPSamplerProxy request) {
|
||||
if (StringUtils.isNotBlank(request.getPath())) {
|
||||
String[] split = request.getPath().split("\\?");
|
||||
String path = split[0];
|
||||
parseQueryParameters(split, request.getArguments());
|
||||
request.setPath(path);
|
||||
} else {
|
||||
request.setPath("/");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseQueryParameters(String[] split, List<KeyValue> arguments) {
|
||||
if (split.length > 1) {
|
||||
try {
|
||||
String queryParams = split[1];
|
||||
queryParams = URLDecoder.decode(queryParams, "UTF-8");
|
||||
String[] params = queryParams.split("&");
|
||||
for (String param : params) {
|
||||
String[] kv = param.split("=");
|
||||
arguments.add(new KeyValue(kv[0], kv.length < 2 ? null : kv[1]));
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LogUtil.info(e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
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, Body msBody) {
|
||||
if (requestObject.containsKey("body")) {
|
||||
Object body = requestObject.get("body");
|
||||
if (body instanceof JSONArray) {
|
||||
JSONArray bodies = requestObject.getJSONArray("body");
|
||||
if (bodies != null) {
|
||||
StringBuilder bodyStr = new StringBuilder();
|
||||
for (int i = 0; i < bodies.size(); i++) {
|
||||
String tmp = bodies.getString(i);
|
||||
bodyStr.append(tmp);
|
||||
}
|
||||
msBody.setType(Body.RAW);
|
||||
msBody.setRaw(bodyStr.toString());
|
||||
}
|
||||
} else if (body instanceof JSONObject) {
|
||||
JSONObject bodyObj = requestObject.getJSONObject("body");
|
||||
if (bodyObj != null) {
|
||||
ArrayList<KeyValue> kvs = new ArrayList<>();
|
||||
bodyObj.keySet().forEach(key -> {
|
||||
kvs.add(new KeyValue(key, bodyObj.getString(key)));
|
||||
});
|
||||
msBody.setKvs(kvs);
|
||||
msBody.setType(Body.WWW_FROM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
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.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.api.service.ApiModuleService;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
import io.metersphere.base.domain.ApiTestCaseWithBLOBs;
|
||||
import io.metersphere.commons.constants.ApiImportPlatform;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MsParser extends ApiImportAbstractParser {
|
||||
|
||||
@Override
|
||||
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
String testStr = getApiTestStr(source);
|
||||
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
|
||||
apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
this.projectId = request.getProjectId();
|
||||
if (testObject.get("projectName") != null) {
|
||||
return parseMsFormat(testStr, request);
|
||||
} else {
|
||||
request.setPlatform(ApiImportPlatform.Plugin.name());
|
||||
return parsePluginFormat(testObject, request, true);
|
||||
}
|
||||
}
|
||||
|
||||
private ApiDefinitionImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) {
|
||||
ApiDefinitionImport apiDefinitionImport = JSON.parseObject(testStr, ApiDefinitionImport.class);
|
||||
apiDefinitionImport.getData().forEach(apiDefinition -> {
|
||||
parseApiDefinition(apiDefinition, importRequest);
|
||||
});
|
||||
return apiDefinitionImport;
|
||||
}
|
||||
|
||||
private void parseApiDefinition(ApiDefinitionWithBLOBs apiDefinition, ApiTestImportRequest importRequest) {
|
||||
String id = UUID.randomUUID().toString();
|
||||
if (StringUtils.isBlank(apiDefinition.getModulePath())) {
|
||||
apiDefinition.setModuleId(null);
|
||||
}
|
||||
parseModule(apiDefinition.getModulePath(), importRequest, apiDefinition::setModuleId);
|
||||
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));
|
||||
}
|
||||
|
||||
protected ApiDefinitionImport parsePluginFormat(JSONObject testObject, ApiTestImportRequest importRequest, Boolean isCreateModule) {
|
||||
List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
|
||||
ApiDefinitionImport apiImport = new ApiDefinitionImport();
|
||||
apiImport.setProtocol(RequestType.HTTP);
|
||||
apiImport.setData(results);
|
||||
testObject.keySet().forEach(tag -> {
|
||||
|
||||
String moduleId = "";
|
||||
if (isCreateModule) {
|
||||
moduleId = buildModule(getSelectModule(importRequest.getModuleId()), tag).getId();
|
||||
}
|
||||
JSONObject requests = testObject.getJSONObject(tag);
|
||||
|
||||
String finalModuleId = moduleId;
|
||||
|
||||
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);
|
||||
ApiDefinitionWithBLOBs apiDefinition = buildApiDefinition(request.getId(), requestName, path, method,importRequest);
|
||||
|
||||
apiDefinition.setModuleId(finalModuleId);
|
||||
apiDefinition.setProjectId(this.projectId);
|
||||
parseBody(requestObject, request.getBody());
|
||||
parseHeader(requestObject, request.getHeaders());
|
||||
parsePath(request, apiDefinition);
|
||||
apiDefinition.setRequest(JSONObject.toJSONString(request));
|
||||
results.add(apiDefinition);
|
||||
});
|
||||
});
|
||||
return apiImport;
|
||||
}
|
||||
|
||||
private void parsePath(MsHTTPSamplerProxy request, ApiDefinitionWithBLOBs apiDefinition) {
|
||||
if (StringUtils.isNotBlank(request.getPath())) {
|
||||
String[] split = request.getPath().split("\\?");
|
||||
String path = split[0];
|
||||
parseQueryParameters(split, request.getArguments());
|
||||
request.setPath(path);
|
||||
apiDefinition.setPath(path);
|
||||
} else {
|
||||
request.setPath("/");
|
||||
apiDefinition.setPath("/");
|
||||
}
|
||||
apiDefinition.setName(apiDefinition.getPath() + " [" + apiDefinition.getMethod() + "]");
|
||||
}
|
||||
|
||||
private void parseQueryParameters(String[] split, List<KeyValue> arguments) {
|
||||
if (split.length > 1) {
|
||||
try {
|
||||
String queryParams = split[1];
|
||||
queryParams = URLDecoder.decode(queryParams, "UTF-8");
|
||||
String[] params = queryParams.split("&");
|
||||
for (String param : params) {
|
||||
String[] kv = param.split("=");
|
||||
arguments.add(new KeyValue(kv[0], kv[1]));
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
LogUtil.info(e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
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, Body msBody) {
|
||||
if (requestObject.containsKey("body")) {
|
||||
Object body = requestObject.get("body");
|
||||
if (body instanceof JSONArray) {
|
||||
JSONArray bodies = requestObject.getJSONArray("body");
|
||||
if (bodies != null) {
|
||||
StringBuilder bodyStr = new StringBuilder();
|
||||
for (int i = 0; i < bodies.size(); i++) {
|
||||
String tmp = bodies.getString(i);
|
||||
bodyStr.append(tmp);
|
||||
}
|
||||
msBody.setType(Body.RAW);
|
||||
msBody.setRaw(bodyStr.toString());
|
||||
}
|
||||
} else if (body instanceof JSONObject) {
|
||||
JSONObject bodyObj = requestObject.getJSONObject("body");
|
||||
if (bodyObj != null) {
|
||||
ArrayList<KeyValue> kvs = new ArrayList<>();
|
||||
bodyObj.keySet().forEach(key -> {
|
||||
kvs.add(new KeyValue(key, bodyObj.getString(key)));
|
||||
});
|
||||
msBody.setKvs(kvs);
|
||||
msBody.setType(Body.WWW_FROM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseModule(String modulePath, ApiTestImportRequest importRequest, Consumer<String> consumer) {
|
||||
if (StringUtils.isBlank(modulePath)) {
|
||||
return;
|
||||
}
|
||||
if (modulePath.startsWith("/")) {
|
||||
modulePath = modulePath.substring(1, modulePath.length());
|
||||
}
|
||||
if (modulePath.endsWith("/")) {
|
||||
modulePath = modulePath.substring(0, modulePath.length() - 1);
|
||||
}
|
||||
List<String> modules = Arrays.asList(modulePath.split("/"));
|
||||
ApiModule parent = getSelectModule(importRequest.getModuleId());
|
||||
Iterator<String> iterator = modules.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String item = iterator.next();
|
||||
parent = buildModule(parent, item);
|
||||
if (!iterator.hasNext()) {
|
||||
consumer.accept(parent.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,64 +2,25 @@ package io.metersphere.api.parse;
|
|||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||
import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.parse.postman.*;
|
||||
import io.metersphere.api.dto.scenario.Body;
|
||||
import io.metersphere.api.dto.scenario.KeyValue;
|
||||
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
import io.metersphere.commons.constants.MsRequestBodyType;
|
||||
import io.metersphere.commons.constants.PostmanRequestBodyMode;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PostmanParser extends ApiImportAbstractParser {
|
||||
public abstract class PostmanAbstractParserParser<T> extends ApiImportAbstractParser<T> {
|
||||
|
||||
@Override
|
||||
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
String testStr = getApiTestStr(source);
|
||||
this.projectId = request.getProjectId();
|
||||
PostmanCollection postmanCollection = JSON.parseObject(testStr, PostmanCollection.class);
|
||||
List<PostmanKeyValue> variables = postmanCollection.getVariable();
|
||||
ApiDefinitionImport apiImport = new ApiDefinitionImport();
|
||||
List<ApiDefinitionWithBLOBs> results = new ArrayList<>();
|
||||
parseItem(postmanCollection.getItem(), variables, results, buildModule(getSelectModule(request.getModuleId()), postmanCollection.getInfo().getName()), true);
|
||||
apiImport.setData(results);
|
||||
return apiImport;
|
||||
}
|
||||
|
||||
protected void parseItem(List<PostmanItem> items, List<PostmanKeyValue> variables, List<ApiDefinitionWithBLOBs> results, ApiModule parentModule, Boolean isCreateModule) {
|
||||
for (PostmanItem item : items) {
|
||||
List<PostmanItem> childItems = item.getItem();
|
||||
if (childItems != null) {
|
||||
ApiModule module = null;
|
||||
if (isCreateModule) {
|
||||
module = buildModule(parentModule, item.getName());
|
||||
}
|
||||
parseItem(childItems, variables, results, module, isCreateModule);
|
||||
} else {
|
||||
ApiDefinitionWithBLOBs request = parsePostman(item);
|
||||
if (request != null) {
|
||||
results.add(request);
|
||||
}
|
||||
if (parentModule != null) {
|
||||
request.setModuleId(parentModule.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ApiDefinitionWithBLOBs parsePostman(PostmanItem requestItem) {
|
||||
protected MsHTTPSamplerProxy parsePostman(PostmanItem requestItem) {
|
||||
PostmanRequest requestDesc = requestItem.getRequest();
|
||||
if (requestDesc == null) {
|
||||
return null;
|
||||
|
@ -67,44 +28,45 @@ public class PostmanParser extends ApiImportAbstractParser {
|
|||
requestDesc.getAuth(); // todo 认证方式等待优化
|
||||
PostmanUrl url = requestDesc.getUrl();
|
||||
MsHTTPSamplerProxy request = buildRequest(requestItem.getName(), url.getRaw(), requestDesc.getMethod());
|
||||
ApiDefinitionWithBLOBs apiDefinition =
|
||||
buildApiDefinition(request.getId(), requestItem.getName(), url.getRaw(), requestDesc.getMethod(),new ApiTestImportRequest());
|
||||
if (StringUtils.isNotBlank(request.getPath())) {
|
||||
String path = request.getPath().split("\\?")[0];
|
||||
path = path.replace("{{", "${");
|
||||
path = path.replace("}}", "}");
|
||||
request.setPath(path);
|
||||
apiDefinition.setPath(path);
|
||||
} else {
|
||||
request.setPath("/");
|
||||
apiDefinition.setPath("/");
|
||||
}
|
||||
parseBody(request.getBody(), requestDesc);
|
||||
request.setArguments(parseKeyValue(url.getQuery()));
|
||||
request.setHeaders(parseKeyValue(requestDesc.getHeader()));
|
||||
addBodyHeader(request);
|
||||
addPreScript(request, requestItem.getEvent());
|
||||
apiDefinition.setRequest(JSON.toJSONString(request));
|
||||
return apiDefinition;
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
private void addPreScript(MsHTTPSamplerProxy request, List<PostmanEvent> event) {
|
||||
if (CollectionUtils.isNotEmpty(event)) {
|
||||
if (request != null && CollectionUtils.isNotEmpty(event)) {
|
||||
StringBuilder scriptStr = new StringBuilder();
|
||||
event = event.stream()
|
||||
.filter(item -> item.getScript() != null)
|
||||
.collect(Collectors.toList());
|
||||
event.forEach(item -> {
|
||||
PostmanScript script = item.getScript();
|
||||
List<String> exec = script.getExec();
|
||||
if (CollectionUtils.isNotEmpty(exec)) {
|
||||
exec.forEach(col -> {
|
||||
scriptStr.append(col + "/n");
|
||||
});
|
||||
if (script != null && item.getListen().contains("prerequest")) {
|
||||
List<String> exec = script.getExec();
|
||||
if (CollectionUtils.isNotEmpty(exec)) {
|
||||
exec.forEach(col -> {
|
||||
if (StringUtils.isNotEmpty(col)) {
|
||||
scriptStr.append(col + "\n");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
if (StringUtils.isNotBlank(scriptStr)) {
|
||||
MsJSR223PreProcessor jsr223PreProcessor = new MsJSR223PreProcessor();
|
||||
jsr223PreProcessor.setName("JSR223PreProcessor");
|
||||
jsr223PreProcessor.setScriptLanguage("javascript");
|
||||
jsr223PreProcessor.setScript(scriptStr.toString());
|
||||
LinkedList<MsTestElement> hashTree = new LinkedList<>();
|
||||
|
@ -129,6 +91,9 @@ public class PostmanParser extends ApiImportAbstractParser {
|
|||
return;
|
||||
}
|
||||
String bodyMode = postmanBody.getString("mode");
|
||||
if (StringUtils.isBlank(bodyMode)) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.equals(bodyMode, PostmanRequestBodyMode.RAW.value())) {
|
||||
parseRawBody(body, postmanBody, bodyMode);
|
||||
} else if (StringUtils.equalsAny(bodyMode, PostmanRequestBodyMode.FORM_DATA.value(), PostmanRequestBodyMode.URLENCODED.value())) {
|
|
@ -1,71 +0,0 @@
|
|||
package io.metersphere.api.parse;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||
import io.metersphere.api.dto.automation.ApiScenrioExportResult;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImport;
|
||||
import io.metersphere.api.dto.definition.request.MsScenario;
|
||||
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.service.ApiModuleService;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.commons.constants.ApiImportPlatform;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.LinkedList;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ScenarioMsParser extends MsParser {
|
||||
|
||||
@Override
|
||||
public ApiDefinitionImport parse(InputStream source, ApiTestImportRequest request) {
|
||||
String testStr = getApiTestStr(source);
|
||||
JSONObject testObject = JSONObject.parseObject(testStr, Feature.OrderedField);
|
||||
apiModuleService = CommonBeanFactory.getBean(ApiModuleService.class);
|
||||
this.projectId = request.getProjectId();
|
||||
if (testObject.get("projectId") != null) {
|
||||
return parseMsFormat(testStr, request);
|
||||
} else {
|
||||
request.setPlatform(ApiImportPlatform.Plugin.name());
|
||||
ApiDefinitionImport apiDefinitionImport = parsePluginFormat(testObject, request, false);
|
||||
MsScenario msScenario = new MsScenario();
|
||||
LinkedList<MsTestElement> msHTTPSamplerProxies = new LinkedList<>();
|
||||
apiDefinitionImport.getData().forEach(res -> {
|
||||
msHTTPSamplerProxies.add(JSONObject.parseObject(res.getRequest(), MsHTTPSamplerProxy.class));
|
||||
});
|
||||
msScenario.setHashTree(msHTTPSamplerProxies);
|
||||
msScenario.setType("scenario");
|
||||
apiDefinitionImport.setScenarioDefinition(msScenario);
|
||||
return apiDefinitionImport;
|
||||
}
|
||||
}
|
||||
|
||||
private ApiDefinitionImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) {
|
||||
ApiScenrioExportResult apiScenrioExportResult = JSON.parseObject(testStr, ApiScenrioExportResult.class);
|
||||
apiScenrioExportResult.getData().forEach(scenario -> {
|
||||
parseApiDefinition(scenario, importRequest);
|
||||
});
|
||||
ApiDefinitionImport apiDefinitionImport = new ApiDefinitionImport();
|
||||
apiDefinitionImport.setScenarioDefinitionData(apiScenrioExportResult.getData());
|
||||
return apiDefinitionImport;
|
||||
}
|
||||
|
||||
private void parseApiDefinition(ApiScenarioWithBLOBs scenario, ApiTestImportRequest importRequest) {
|
||||
String id = UUID.randomUUID().toString();
|
||||
if (StringUtils.isBlank(scenario.getModulePath())) {
|
||||
scenario.setApiScenarioModuleId(null);
|
||||
}
|
||||
// parseModule(scenario.getModulePath(), importRequest, scenario::setApiScenarioModuleId);
|
||||
scenario.setId(id);
|
||||
scenario.setProjectId(this.projectId);
|
||||
String scenarioDefinition = scenario.getScenarioDefinition();
|
||||
JSONObject scenarioDefinitionObj = JSONObject.parseObject(scenarioDefinition);
|
||||
scenarioDefinitionObj.put("id", id);
|
||||
scenarioDefinitionObj.put("name", scenario.getName());
|
||||
scenario.setScenarioDefinition(JSONObject.toJSONString(scenarioDefinitionObj));
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ import org.aspectj.util.FileUtil;
|
|||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.QName;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
@ -461,55 +462,55 @@ public class APITestService {
|
|||
});
|
||||
}
|
||||
|
||||
public String updateJmxString(String jmxString,String testName,boolean updateHTTPSamplerProxyName) {
|
||||
/**
|
||||
* 更新jmx数据,处理jmx里的各种参数
|
||||
* <p>
|
||||
* 注: 与1.7分支合并时,如果该方法产生冲突,请以master为准
|
||||
*
|
||||
* @param jmxString 原JMX文件
|
||||
* @param testNameParam 某些节点要替换的testName
|
||||
* @param isFromScenario 是否来源于场景 (来源于场景的话,testName要进行处理)
|
||||
* @return
|
||||
* @author song tianyang
|
||||
*/
|
||||
public String updateJmxString(String jmxString, String testNameParam, boolean isFromScenario) {
|
||||
//注: 与1.7分支合并时,如果该方法产生冲突,请以master为准
|
||||
String attribute_testName = "testname";
|
||||
String[] requestElementNameArr = new String[]{"HTTPSamplerProxy", "TCPSampler", "JDBCSampler", "DubboSample"};
|
||||
|
||||
try {
|
||||
//将ThreadGroup的testname改为接口名称
|
||||
Document doc = DocumentHelper.parseText(jmxString);// 获取可续保保单列表报文模板
|
||||
Element root = doc.getRootElement();
|
||||
Element rootHashTreeElement = root.element("hashTree");
|
||||
Element innerHashTreeElement = rootHashTreeElement.elements("hashTree").get(0);
|
||||
Element theadGroupElement = innerHashTreeElement.elements("ThreadGroup").get(0);
|
||||
theadGroupElement.attribute("testname").setText(testName);
|
||||
|
||||
List<Element> thirdHashTreeElementList = innerHashTreeElement.elements("hashTree");
|
||||
for (Element element : thirdHashTreeElementList) {
|
||||
if(updateHTTPSamplerProxyName){
|
||||
List<Element> sampleProxyElementList = element.elements("HTTPSamplerProxy");
|
||||
for (Element itemElement : sampleProxyElementList) {
|
||||
itemElement.attribute("testname").setText(testName);
|
||||
List<Element> innerHashTreeElementList = rootHashTreeElement.elements("hashTree");
|
||||
for (Element innerHashTreeElement : innerHashTreeElementList) {
|
||||
//转换DubboDefaultConfigGui
|
||||
List<Element> configTestElementList = innerHashTreeElement.elements("ConfigTestElement");
|
||||
for (Element configTestElement : configTestElementList) {
|
||||
this.updateDubboDefaultConfigGuiElement(configTestElement);
|
||||
}
|
||||
|
||||
List<Element> theadGroupElementList = innerHashTreeElement.elements("ThreadGroup");
|
||||
for (Element theadGroupElement : theadGroupElementList) {
|
||||
if (StringUtils.isNotEmpty(testNameParam)) {
|
||||
theadGroupElement.attribute(attribute_testName).setText(testNameParam);
|
||||
}
|
||||
}
|
||||
//检查有没有自定义参数
|
||||
List<Element> scriptHashTreeElementList = element.elements("hashTree");
|
||||
for (Element scriptHashTreeElement : scriptHashTreeElementList) {
|
||||
boolean isRemove = false;
|
||||
List<Element> removeElement = new ArrayList<>();
|
||||
List<Element> scriptElementItemList = scriptHashTreeElement.elements();
|
||||
for (Element hashTreeItemElement : scriptElementItemList) {
|
||||
String className = hashTreeItemElement.attributeValue("testclass");
|
||||
String qname = hashTreeItemElement.getQName().getName();
|
||||
List<Element> thirdHashTreeElementList = innerHashTreeElement.elements("hashTree");
|
||||
for (Element element : thirdHashTreeElementList) {
|
||||
String testName = testNameParam;
|
||||
|
||||
if (isRemove) {
|
||||
if (org.apache.commons.lang3.StringUtils.equals("hashTree", qname)) {
|
||||
removeElement.add(hashTreeItemElement);
|
||||
}
|
||||
}
|
||||
isRemove = false;
|
||||
if (org.apache.commons.lang3.StringUtils.equals(className, "JSR223PostProcessor")) {
|
||||
List<Element> scriptElements = hashTreeItemElement.elements("stringProp");
|
||||
for (Element scriptElement : scriptElements) {
|
||||
String scriptName = scriptElement.attributeValue("name");
|
||||
String contentValue = scriptElement.getStringValue();
|
||||
//更新请求类节点的部份属性
|
||||
this.updateRequestElementInfo(element, testNameParam, requestElementNameArr, isFromScenario);
|
||||
//检查有无jmeter不是别的自定义参数
|
||||
this.checkPrivateFunctionNode(element);
|
||||
|
||||
if ("script".equals(scriptName) && contentValue.startsWith("io.metersphere.api.jmeter.JMeterVars.addVars")) {
|
||||
isRemove = true;
|
||||
removeElement.add(hashTreeItemElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Element itemElement : removeElement) {
|
||||
scriptHashTreeElement.remove(itemElement);
|
||||
//转换DubboDefaultConfigGui
|
||||
List<Element> hashTreeConfigTestElementList = element.elements("ConfigTestElement");
|
||||
for (Element configTestElement : hashTreeConfigTestElementList) {
|
||||
this.updateDubboDefaultConfigGuiElement(configTestElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -517,6 +518,86 @@ public class APITestService {
|
|||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!jmxString.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")) {
|
||||
jmxString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + jmxString;
|
||||
}
|
||||
return jmxString;
|
||||
}
|
||||
|
||||
private void updateDubboDefaultConfigGuiElement(Element configTestElement) {
|
||||
String dubboDefaultConfigGuiClassName = "io.github.ningyu.jmeter.plugin.dubbo.gui.DubboDefaultConfigGui";
|
||||
if (configTestElement == null) {
|
||||
return;
|
||||
}
|
||||
String guiClassValue = configTestElement.attributeValue("guiclass");
|
||||
if (StringUtils.equals(guiClassValue, "DubboDefaultConfigGui")) {
|
||||
configTestElement.attribute("guiclass").setText(dubboDefaultConfigGuiClassName);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkPrivateFunctionNode(Element element) {
|
||||
List<Element> scriptHashTreeElementList = element.elements("hashTree");
|
||||
for (Element scriptHashTreeElement : scriptHashTreeElementList) {
|
||||
boolean isRemove = false;
|
||||
List<Element> removeElement = new ArrayList<>();
|
||||
List<Element> scriptElementItemList = scriptHashTreeElement.elements();
|
||||
for (Element hashTreeItemElement : scriptElementItemList) {
|
||||
String className = hashTreeItemElement.attributeValue("testclass");
|
||||
String qname = hashTreeItemElement.getQName().getName();
|
||||
|
||||
if (isRemove) {
|
||||
if (org.apache.commons.lang3.StringUtils.equals("hashTree", qname)) {
|
||||
removeElement.add(hashTreeItemElement);
|
||||
}
|
||||
}
|
||||
|
||||
isRemove = false;
|
||||
if (org.apache.commons.lang3.StringUtils.equals(className, "JSR223PostProcessor")) {
|
||||
List<Element> scriptElements = hashTreeItemElement.elements("stringProp");
|
||||
for (Element scriptElement : scriptElements) {
|
||||
String scriptName = scriptElement.attributeValue("name");
|
||||
String contentValue = scriptElement.getStringValue();
|
||||
|
||||
if ("script".equals(scriptName) && contentValue.startsWith("io.metersphere.api.jmeter.JMeterVars.addVars")) {
|
||||
isRemove = true;
|
||||
removeElement.add(hashTreeItemElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Element itemElement : removeElement) {
|
||||
scriptHashTreeElement.remove(itemElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRequestElementInfo(Element element, String testNameParam, String[] requestElementNameArr, boolean isFromScenario) {
|
||||
String attribute_testName = "testname";
|
||||
String scenarioCaseNameSplit = "<->";
|
||||
String testName = testNameParam;
|
||||
|
||||
for (String requestElementName : requestElementNameArr) {
|
||||
List<Element> sampleProxyElementList = element.elements(requestElementName);
|
||||
for (Element itemElement : sampleProxyElementList) {
|
||||
if (isFromScenario) {
|
||||
testName = itemElement.attributeValue(attribute_testName);
|
||||
String[] testNameArr = testName.split(scenarioCaseNameSplit);
|
||||
if (testNameArr.length > 0) {
|
||||
testName = testNameArr[0];
|
||||
}
|
||||
}
|
||||
itemElement.attribute(attribute_testName).setText(testName);
|
||||
|
||||
//double的话有额外处理方式
|
||||
if (StringUtils.equals(requestElementName, "DubboSample")) {
|
||||
//dubbo节点要更新 标签、guiClass 和 testClass
|
||||
itemElement.setName("io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample");
|
||||
itemElement.attribute("testclass").setText("io.github.ningyu.jmeter.plugin.dubbo.sample.DubboSample");
|
||||
itemElement.attribute("guiclass").setText("io.github.ningyu.jmeter.plugin.dubbo.gui.DubboSampleGui");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,15 @@ import io.metersphere.api.dto.DeleteAPIReportRequest;
|
|||
import io.metersphere.api.dto.JmxInfoDTO;
|
||||
import io.metersphere.api.dto.automation.*;
|
||||
import io.metersphere.api.dto.automation.parse.ScenarioImport;
|
||||
import io.metersphere.api.dto.automation.parse.ScenarioImportParser;
|
||||
import io.metersphere.api.dto.automation.parse.ScenarioImportParserFactory;
|
||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||
import io.metersphere.api.dto.definition.request.*;
|
||||
import io.metersphere.api.dto.definition.request.unknown.MsJmeterElement;
|
||||
import io.metersphere.api.dto.definition.request.variable.ScenarioVariable;
|
||||
import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
||||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.api.parse.ApiImportParser;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ApiScenarioReportMapper;
|
||||
|
@ -435,6 +436,56 @@ public class ApiAutomationService {
|
|||
return jmeterHashTree;
|
||||
}
|
||||
|
||||
private String generateJmx(ApiScenarioWithBLOBs apiScenario) {
|
||||
HashTree jmeterHashTree = new ListedHashTree();
|
||||
MsTestPlan testPlan = new MsTestPlan();
|
||||
testPlan.setName(apiScenario.getName());
|
||||
testPlan.setHashTree(new LinkedList<>());
|
||||
ParameterConfig config = new ParameterConfig();
|
||||
config.setOperating(true);
|
||||
try {
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
JSONObject element = JSON.parseObject(apiScenario.getScenarioDefinition());
|
||||
MsScenario scenario = JSONObject.parseObject(apiScenario.getScenarioDefinition(), MsScenario.class);
|
||||
|
||||
// 多态JSON普通转换会丢失内容,需要通过 ObjectMapper 获取
|
||||
if (element != null && StringUtils.isNotEmpty(element.getString("hashTree"))) {
|
||||
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"),
|
||||
new TypeReference<LinkedList<MsTestElement>>() {
|
||||
});
|
||||
scenario.setHashTree(elements);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(element.getString("variables"))) {
|
||||
LinkedList<ScenarioVariable> variables = mapper.readValue(element.getString("variables"),
|
||||
new TypeReference<LinkedList<ScenarioVariable>>() {
|
||||
});
|
||||
scenario.setVariables(variables);
|
||||
}
|
||||
// 针对导入的jmx 处理
|
||||
if (CollectionUtils.isNotEmpty(scenario.getHashTree()) && (scenario.getHashTree().get(0) instanceof MsJmeterElement)) {
|
||||
scenario.toHashTree(jmeterHashTree, scenario.getHashTree(), config);
|
||||
return scenario.getJmx(jmeterHashTree);
|
||||
} else {
|
||||
MsThreadGroup group = new MsThreadGroup();
|
||||
group.setLabel(apiScenario.getName());
|
||||
group.setName(apiScenario.getName());
|
||||
group.setEnableCookieShare(scenario.isEnableCookieShare());
|
||||
group.setHashTree(new LinkedList<MsTestElement>() {{
|
||||
this.add(scenario);
|
||||
}});
|
||||
testPlan.getHashTree().add(group);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
MSException.throwException(ex.getMessage());
|
||||
}
|
||||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), config);
|
||||
return testPlan.getJmx(jmeterHashTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 场景测试执行
|
||||
*
|
||||
|
@ -515,7 +566,6 @@ public class ApiAutomationService {
|
|||
ParameterConfig config = new ParameterConfig();
|
||||
config.setConfig(envConfig);
|
||||
HashTree hashTree = request.getTestElement().generateHashTree(config);
|
||||
System.out.println(request.getTestElement().getJmx(hashTree));
|
||||
// 调用执行方法
|
||||
createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
|
||||
SessionUtils.getUserId());
|
||||
|
@ -668,7 +718,7 @@ public class ApiAutomationService {
|
|||
HashTree jmeterHashTree = generateHashTree(apiScenarios, request, null);
|
||||
String jmx = testPlan.getJmx(jmeterHashTree);
|
||||
|
||||
jmx = apiTestService.updateJmxString(jmx,testName,false);
|
||||
jmx = apiTestService.updateJmxString(jmx, testName, true);
|
||||
|
||||
//将ThreadGroup的testname改为接口名称
|
||||
// Document doc = DocumentHelper.parseText(jmx);// 获取可续保保单列表报文模板
|
||||
|
@ -720,16 +770,6 @@ public class ApiAutomationService {
|
|||
}
|
||||
}
|
||||
|
||||
public List<ApiScenarioWithBLOBs> get(ApiScenarioRequest request) {
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
if (CollectionUtils.isNotEmpty(request.getIds())) {
|
||||
example.createCriteria().andIdIn(request.getIds());
|
||||
} else {
|
||||
example.createCriteria().andProjectIdEqualTo(request.getProjectId());
|
||||
}
|
||||
return apiScenarioMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
|
||||
public List<ApiScenarioWithBLOBs> getWithBLOBs(ApiScenarioWithBLOBs request) {
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId()).andStatusNotEqualTo("Trash").andIdNotEqualTo(request.getId());
|
||||
|
@ -801,10 +841,12 @@ public class ApiAutomationService {
|
|||
}
|
||||
|
||||
public ScenarioImport scenarioImport(MultipartFile file, ApiTestImportRequest request) {
|
||||
ScenarioImportParser apiImportParser = ScenarioImportParserFactory.getImportParser(request.getPlatform());
|
||||
ApiImportParser apiImportParser = ScenarioImportParserFactory.getImportParser(request.getPlatform());
|
||||
ScenarioImport apiImport = null;
|
||||
Optional.ofNullable(file)
|
||||
.ifPresent(item -> request.setFileName(file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."))));
|
||||
try {
|
||||
apiImport = Objects.requireNonNull(apiImportParser).parse(file == null ? null : file.getInputStream(), request);
|
||||
apiImport = (ScenarioImport) Objects.requireNonNull(apiImportParser).parse(file == null ? null : file.getInputStream(), request);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("parse_data_error"));
|
||||
|
@ -815,16 +857,33 @@ public class ApiAutomationService {
|
|||
return apiImport;
|
||||
}
|
||||
|
||||
public ApiScenrioExportResult export(ApiScenarioBatchRequest request) {
|
||||
private List<ApiScenarioWithBLOBs> getExportResult(ApiScenarioBatchRequest request) {
|
||||
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
||||
(query) -> extApiScenarioMapper.selectIdsByQuery((ApiScenarioRequest) query));
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
example.createCriteria().andIdIn(request.getIds());
|
||||
List<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = apiScenarioMapper.selectByExampleWithBLOBs(example);
|
||||
ApiScenrioExportResult result = new ApiScenrioExportResult();
|
||||
result.setData(apiScenarioWithBLOBs);
|
||||
return apiScenarioWithBLOBs;
|
||||
}
|
||||
|
||||
public ApiScenrioExportResult export(ApiScenarioBatchRequest request) {
|
||||
ApiScenrioExportResult result = new ApiScenrioExportResult();
|
||||
result.setData(getExportResult(request));
|
||||
result.setProjectId(request.getProjectId());
|
||||
result.setVersion(System.getenv("MS_VERSION"));
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<ApiScenrioExportJmx> exportJmx(ApiScenarioBatchRequest request) {
|
||||
List<ApiScenarioWithBLOBs> apiScenarioWithBLOBs = getExportResult(request);
|
||||
// 生成jmx
|
||||
List<ApiScenrioExportJmx> resList = new ArrayList<>();
|
||||
apiScenarioWithBLOBs.forEach(item -> {
|
||||
String jmx = generateJmx(item);
|
||||
ApiScenrioExportJmx scenrioExportJmx = new ApiScenrioExportJmx(item.getName(), apiTestService.updateJmxString(jmx, null, true));
|
||||
resList.add(scenrioExportJmx);
|
||||
});
|
||||
return resList;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import io.metersphere.api.jmeter.JMeterService;
|
|||
import io.metersphere.api.jmeter.RequestResult;
|
||||
import io.metersphere.api.jmeter.TestResult;
|
||||
import io.metersphere.api.parse.ApiImportParser;
|
||||
import io.metersphere.api.parse.ApiImportParserFactory;
|
||||
import io.metersphere.api.dto.definition.parse.ApiDefinitionImportParserFactory;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.*;
|
||||
|
@ -130,6 +130,9 @@ public class ApiDefinitionService {
|
|||
|
||||
public void create(SaveApiDefinitionRequest request, List<MultipartFile> bodyFiles) {
|
||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||
if (StringUtils.equals(request.getProtocol(), "DUBBO")) {
|
||||
request.setMethod("dubbo://");
|
||||
}
|
||||
createTest(request);
|
||||
FileUtils.createBodyFiles(bodyUploadIds, bodyFiles);
|
||||
}
|
||||
|
@ -140,6 +143,9 @@ public class ApiDefinitionService {
|
|||
}
|
||||
List<String> bodyUploadIds = request.getBodyUploadIds();
|
||||
request.setBodyUploadIds(null);
|
||||
if (StringUtils.equals(request.getProtocol(), "DUBBO")) {
|
||||
request.setMethod("dubbo://");
|
||||
}
|
||||
updateTest(request);
|
||||
FileUtils.createBodyFiles(bodyUploadIds, bodyFiles);
|
||||
}
|
||||
|
@ -382,6 +388,9 @@ public class ApiDefinitionService {
|
|||
apiTestCase.setUpdateUserId(SessionUtils.getUserId());
|
||||
apiTestCase.setNum(getNextNum(apiTestCase.getApiDefinitionId()));
|
||||
apiTestCase.setPriority("P0");
|
||||
if (apiTestCase.getName().length() > 255) {
|
||||
apiTestCase.setName(apiTestCase.getName().substring(0, 255));
|
||||
}
|
||||
if (!isInsert) {
|
||||
apiTestCase.setName(apiTestCase.getName() + "_" + apiTestCase.getId().substring(0, 5));
|
||||
}
|
||||
|
@ -490,10 +499,10 @@ public class ApiDefinitionService {
|
|||
|
||||
|
||||
public ApiDefinitionImport apiTestImport(MultipartFile file, ApiTestImportRequest request) {
|
||||
ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(request.getPlatform());
|
||||
ApiImportParser apiImportParser = ApiDefinitionImportParserFactory.getApiImportParser(request.getPlatform());
|
||||
ApiDefinitionImport apiImport = null;
|
||||
try {
|
||||
apiImport = Objects.requireNonNull(apiImportParser).parse(file == null ? null : file.getInputStream(), request);
|
||||
apiImport = (ApiDefinitionImport) Objects.requireNonNull(apiImportParser).parse(file == null ? null : file.getInputStream(), request);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("parse_data_error"));
|
||||
|
@ -615,7 +624,7 @@ public class ApiDefinitionService {
|
|||
return example;
|
||||
}
|
||||
|
||||
private List<String> getAllApiIdsByFontedSelect(Map<String, List<String>> filters, String name, List<String> moduleIds, String projectId, List<String> unSelectIds,String protocol) {
|
||||
private List<String> getAllApiIdsByFontedSelect(Map<String, List<String>> filters, String name, List<String> moduleIds, String projectId, List<String> unSelectIds, String protocol) {
|
||||
ApiDefinitionRequest request = new ApiDefinitionRequest();
|
||||
request.setFilters(filters);
|
||||
request.setName(name);
|
||||
|
@ -744,6 +753,8 @@ public class ApiDefinitionService {
|
|||
apiExportResult.setCases(apiTestCaseService.selectCasesBydApiIds(request.getIds()));
|
||||
apiExportResult.setProjectName(request.getProjectId());
|
||||
apiExportResult.setProtocol(request.getProtocol());
|
||||
apiExportResult.setProjectId(request.getProjectId());
|
||||
apiExportResult.setVersion(System.getenv("MS_VERSION"));
|
||||
return apiExportResult;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
SELECT api.id,api.name FROM Api_definition api
|
||||
<where>
|
||||
<if test="request.projectId != null">
|
||||
api.project_Id = #{request.projectId}
|
||||
AND api.project_Id = #{request.projectId}
|
||||
</if>
|
||||
<if test="request.name != null">
|
||||
api.project_Id like CONCAT('%', #{request.name},'%')
|
||||
<if test="request.name != null and request.name != '' ">
|
||||
AND api.name like CONCAT('%', #{request.name},'%')
|
||||
</if>
|
||||
<if test="request.type != null">
|
||||
api.method = #{request.type}
|
||||
<if test="request.type != null and request.type != '' and request.type != 'ALL' ">
|
||||
AND api.method = #{request.type}
|
||||
</if>
|
||||
|
||||
<if test="request.moduleIds != null and request.moduleIds.size() > 0">
|
||||
|
|
|
@ -4,7 +4,6 @@ import io.metersphere.commons.exception.MSException;
|
|||
import io.metersphere.controller.request.BaseQueryRequest;
|
||||
import io.metersphere.controller.request.OrderRequest;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -26,13 +25,14 @@ public class ServiceUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* 获取前端全选的id列表
|
||||
* 获取前端全选的id列表
|
||||
*
|
||||
* @param queryRequest 查询条件
|
||||
* @param func 查询id列表的数据库查询
|
||||
* @param func 查询id列表的数据库查询
|
||||
* @return
|
||||
*/
|
||||
public static<T> void getSelectAllIds( T batchRequest, BaseQueryRequest queryRequest, Function<BaseQueryRequest, List<String>> func) {
|
||||
if (queryRequest.isSelectAll()) {
|
||||
public static <T> void getSelectAllIds(T batchRequest, BaseQueryRequest queryRequest, Function<BaseQueryRequest, List<String>> func) {
|
||||
if (queryRequest != null && queryRequest.isSelectAll()) {
|
||||
List<String> ids = func.apply(queryRequest);
|
||||
if (!ids.isEmpty()) {
|
||||
ids = ids.stream()
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 5e0b365f1080197e84055e80071165787e2e79c5
|
||||
Subproject commit b9042074b780205e275c674f64417799110519fd
|
|
@ -9,6 +9,7 @@
|
|||
@setNodeTree="setNodeTree"
|
||||
@enableTrash="enableTrash"
|
||||
@exportAPI="exportAPI"
|
||||
@exportJmx="exportJmx"
|
||||
@refreshAll="refreshAll"
|
||||
:type="'edit'"
|
||||
ref="nodeTree"/>
|
||||
|
@ -69,7 +70,6 @@
|
|||
import MsApiScenarioModule from "@/business/components/api/automation/scenario/ApiScenarioModule";
|
||||
import MsEditApiScenario from "./scenario/EditApiScenario";
|
||||
import {getCurrentProjectID} from "../../../../common/js/utils";
|
||||
import {PROJECT_NAME} from "../../../../common/js/constants";
|
||||
|
||||
export default {
|
||||
name: "ApiAutomation",
|
||||
|
@ -131,25 +131,10 @@
|
|||
},
|
||||
methods: {
|
||||
exportAPI() {
|
||||
let obj = {projectName: localStorage.getItem(PROJECT_NAME)}
|
||||
let condition = {projectId: getCurrentProjectID(), ids: this.$refs.apiScenarioList.selection};
|
||||
let url = "/api/automation/list/all";
|
||||
this.loading = true;
|
||||
this.$post(url, condition, response => {
|
||||
obj.data = response.data;
|
||||
this.buildApiPath(obj.data);
|
||||
this.loading = false;
|
||||
downloadFile("Metersphere_Scenario_" + localStorage.getItem(PROJECT_NAME) + ".json", JSON.stringify(obj));
|
||||
});
|
||||
this.$refs.apiScenarioList.exportApi();
|
||||
},
|
||||
buildApiPath(apis) {
|
||||
apis.forEach((api) => {
|
||||
this.moduleOptions.forEach(item => {
|
||||
if (api.moduleId === item.id) {
|
||||
api.modulePath = item.path;
|
||||
}
|
||||
});
|
||||
});
|
||||
exportJmx(){
|
||||
this.$refs.apiScenarioList.exportJmx();
|
||||
},
|
||||
checkRedirectEditPage(redirectParam) {
|
||||
if (redirectParam != null) {
|
||||
|
|
|
@ -167,50 +167,50 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import MsTableHeader from "@/business/components/common/components/MsTableHeader";
|
||||
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import ShowMoreBtn from "@/business/components/track/case/components/ShowMoreBtn";
|
||||
import MsTag from "../../../common/components/MsTag";
|
||||
import {downloadFile, getCurrentProjectID, getCurrentUser, getUUID} from "@/common/js/utils";
|
||||
import MsApiReportDetail from "../report/ApiReportDetail";
|
||||
import MsTableMoreBtn from "./TableMoreBtn";
|
||||
import MsScenarioExtendButtons from "@/business/components/api/automation/scenario/ScenarioExtendBtns";
|
||||
import MsTestPlanList from "./testplan/TestPlanList";
|
||||
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
|
||||
import {API_SCENARIO_CONFIGS} from "@/business/components/common/components/search/search-components";
|
||||
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
|
||||
import PriorityTableItem from "../../../track/common/tableItems/planview/PriorityTableItem";
|
||||
import PlanStatusTableItem from "../../../track/common/tableItems/plan/PlanStatusTableItem";
|
||||
import BatchEdit from "../../../track/case/components/BatchEdit";
|
||||
import {API_SCENARIO_LIST, TEST_CASE_LIST, TEST_PLAN_LIST, WORKSPACE_ID} from "../../../../../common/js/constants";
|
||||
import {PROJECT_NAME} from "../../../../../common/js/constants";
|
||||
import EnvironmentSelect from "../../definition/components/environment/EnvironmentSelect";
|
||||
import BatchMove from "../../../track/case/components/BatchMove";
|
||||
import {_sort} from "@/common/js/tableUtils";
|
||||
import {Api_Scenario_List, Track_Test_Case} from "@/business/components/common/model/JsonData";
|
||||
import HeaderCustom from "@/business/components/common/head/HeaderCustom";
|
||||
import {
|
||||
_filter,
|
||||
_handleSelect,
|
||||
_handleSelectAll,
|
||||
getSelectDataCounts,
|
||||
setUnSelectIds, toggleAllSelection
|
||||
} from "@/common/js/tableUtils";
|
||||
import MsTableHeader from "@/business/components/common/components/MsTableHeader";
|
||||
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import ShowMoreBtn from "@/business/components/track/case/components/ShowMoreBtn";
|
||||
import MsTag from "../../../common/components/MsTag";
|
||||
import {downloadFile, getCurrentProjectID, getCurrentUser, getUUID} from "@/common/js/utils";
|
||||
import MsApiReportDetail from "../report/ApiReportDetail";
|
||||
import MsTableMoreBtn from "./TableMoreBtn";
|
||||
import MsScenarioExtendButtons from "@/business/components/api/automation/scenario/ScenarioExtendBtns";
|
||||
import MsTestPlanList from "./testplan/TestPlanList";
|
||||
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
|
||||
import {API_SCENARIO_CONFIGS} from "@/business/components/common/components/search/search-components";
|
||||
import MsTableOperatorButton from "@/business/components/common/components/MsTableOperatorButton";
|
||||
import PriorityTableItem from "../../../track/common/tableItems/planview/PriorityTableItem";
|
||||
import PlanStatusTableItem from "../../../track/common/tableItems/plan/PlanStatusTableItem";
|
||||
import BatchEdit from "../../../track/case/components/BatchEdit";
|
||||
import {API_SCENARIO_LIST, TEST_CASE_LIST, TEST_PLAN_LIST, WORKSPACE_ID} from "../../../../../common/js/constants";
|
||||
import {PROJECT_NAME} from "../../../../../common/js/constants";
|
||||
import EnvironmentSelect from "../../definition/components/environment/EnvironmentSelect";
|
||||
import BatchMove from "../../../track/case/components/BatchMove";
|
||||
import {_sort} from "@/common/js/tableUtils";
|
||||
import {Api_Scenario_List} from "@/business/components/common/model/JsonData";
|
||||
import HeaderCustom from "@/business/components/common/head/HeaderCustom";
|
||||
import {
|
||||
_filter,
|
||||
_handleSelect,
|
||||
_handleSelectAll,
|
||||
getSelectDataCounts,
|
||||
setUnSelectIds, toggleAllSelection
|
||||
} from "@/common/js/tableUtils";
|
||||
|
||||
export default {
|
||||
name: "MsApiScenarioList",
|
||||
components: {
|
||||
HeaderCustom,
|
||||
BatchMove,
|
||||
EnvironmentSelect,
|
||||
BatchEdit,
|
||||
PlanStatusTableItem,
|
||||
PriorityTableItem,
|
||||
MsTableHeaderSelectPopover,
|
||||
MsTablePagination,
|
||||
MsTableMoreBtn,
|
||||
ShowMoreBtn,
|
||||
MsTableHeader,
|
||||
export default {
|
||||
name: "MsApiScenarioList",
|
||||
components: {
|
||||
HeaderCustom,
|
||||
BatchMove,
|
||||
EnvironmentSelect,
|
||||
BatchEdit,
|
||||
PlanStatusTableItem,
|
||||
PriorityTableItem,
|
||||
MsTableHeaderSelectPopover,
|
||||
MsTablePagination,
|
||||
MsTableMoreBtn,
|
||||
ShowMoreBtn,
|
||||
MsTableHeader,
|
||||
MsTag,
|
||||
MsApiReportDetail,
|
||||
MsScenarioExtendButtons,
|
||||
|
@ -554,12 +554,15 @@ export default {
|
|||
_handleSelectAll(this, selection, this.tableData, this.selectRows);
|
||||
setUnSelectIds(this.tableData, this.condition, this.selectRows);
|
||||
this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows);
|
||||
this.$emit('selection', selection);
|
||||
},
|
||||
handleSelect(selection, row) {
|
||||
_handleSelect(this, selection, row, this.selectRows);
|
||||
setUnSelectIds(this.tableData, this.condition, this.selectRows);
|
||||
this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows);
|
||||
this.$emit('selection', selection);
|
||||
},
|
||||
|
||||
isSelectDataAll(data) {
|
||||
this.condition.selectAll = data;
|
||||
setUnSelectIds(this.tableData, this.condition, this.selectRows);
|
||||
|
@ -587,7 +590,7 @@ export default {
|
|||
scenarioIds.push(row.id);
|
||||
run.id = getUUID();
|
||||
run.projectId = getCurrentProjectID();
|
||||
run.scenarioIds = scenarioIds;
|
||||
run.ids = scenarioIds;
|
||||
this.$post(url, run, response => {
|
||||
let data = response.data;
|
||||
this.runVisible = true;
|
||||
|
@ -672,6 +675,24 @@ export default {
|
|||
downloadFile("Metersphere_Scenario_" + localStorage.getItem(PROJECT_NAME) + ".json", JSON.stringify(obj));
|
||||
});
|
||||
},
|
||||
exportJmx() {
|
||||
let param = {};
|
||||
this.buildBatchParam(param);
|
||||
if (param.ids === undefined || param.ids.length < 1) {
|
||||
this.$warning(this.$t("api_test.automation.scenario.check_case"));
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
this.result = this.$post("/api/automation/export/jmx", param, response => {
|
||||
this.loading = false;
|
||||
let obj = response.data;
|
||||
if (obj && obj.length > 0) {
|
||||
obj.forEach(item => {
|
||||
downloadFile(item.name + ".jmx", item.jmx);
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
buildApiPath(scenarios) {
|
||||
scenarios.forEach((scenario) => {
|
||||
this.moduleOptions.forEach(item => {
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="add-scenario">{{ $t('api_test.automation.add_scenario') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="import">{{ $t('api_test.api_import.label') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="export">{{ $t('report.export') }}</el-dropdown-item>
|
||||
<el-dropdown-item command="export">{{ $t('report.export') }}MS</el-dropdown-item>
|
||||
<el-dropdown-item command="exportJmx">{{ $t('report.export') }}JMX</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
@ -33,14 +34,14 @@
|
|||
<module-trash-button v-if="!isReadOnly" :condition="condition" :exe="enableTrash"/>
|
||||
<!-- 是否保留这个 -->
|
||||
<!--<api-scenario-module-header-->
|
||||
<!--:condition="condition"-->
|
||||
<!--:current-module="currentModule"-->
|
||||
<!--:is-read-only="isReadOnly"-->
|
||||
<!--:project-id="projectId"-->
|
||||
<!--@exportAPI="exportAPI"-->
|
||||
<!--@addScenario="addScenario"-->
|
||||
<!--@refreshTable="$emit('refreshTable')"-->
|
||||
<!--@refresh="refresh"/>-->
|
||||
<!--:condition="condition"-->
|
||||
<!--:current-module="currentModule"-->
|
||||
<!--:is-read-only="isReadOnly"-->
|
||||
<!--:project-id="projectId"-->
|
||||
<!--@exportAPI="exportAPI"-->
|
||||
<!--@addScenario="addScenario"-->
|
||||
<!--@refreshTable="$emit('refreshTable')"-->
|
||||
<!--@refresh="refresh"/>-->
|
||||
</template>
|
||||
|
||||
</ms-node-tree>
|
||||
|
@ -56,27 +57,26 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import SelectMenu from "../../../track/common/SelectMenu";
|
||||
import MsAddBasisScenario from "@/business/components/api/automation/scenario/AddBasisScenario";
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
import MsNodeTree from "../../../track/common/NodeTree";
|
||||
import {buildNodePath} from "../../definition/model/NodeTree";
|
||||
import ModuleTrashButton from "../../definition/components/module/ModuleTrashButton";
|
||||
import ApiScenarioModuleHeader from "@/business/components/api/automation/scenario/module/ApiScenarioModuleHeader";
|
||||
import ApiImport from "./common/ScenarioImport";
|
||||
import SelectMenu from "../../../track/common/SelectMenu";
|
||||
import MsAddBasisScenario from "@/business/components/api/automation/scenario/AddBasisScenario";
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
import MsNodeTree from "../../../track/common/NodeTree";
|
||||
import {buildNodePath} from "../../definition/model/NodeTree";
|
||||
import ModuleTrashButton from "../../definition/components/module/ModuleTrashButton";
|
||||
import ApiImport from "./common/ScenarioImport";
|
||||
|
||||
export default {
|
||||
name: 'MsApiScenarioModule',
|
||||
components: {
|
||||
ApiImport,
|
||||
ModuleTrashButton,
|
||||
MsNodeTree,
|
||||
MsAddBasisScenario,
|
||||
SelectMenu,
|
||||
},
|
||||
props: {
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
export default {
|
||||
name: 'MsApiScenarioModule',
|
||||
components: {
|
||||
ApiImport,
|
||||
ModuleTrashButton,
|
||||
MsNodeTree,
|
||||
MsAddBasisScenario,
|
||||
SelectMenu,
|
||||
},
|
||||
props: {
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false
|
||||
}
|
||||
|
@ -145,6 +145,9 @@ export default {
|
|||
case "export":
|
||||
this.$emit('exportAPI');
|
||||
break;
|
||||
case "exportJmx":
|
||||
this.$emit('exportJmx');
|
||||
break;
|
||||
}
|
||||
},
|
||||
list() {
|
||||
|
|
|
@ -204,44 +204,44 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {API_STATUS, PRIORITY} from "../../definition/model/JsonData";
|
||||
import {WORKSPACE_ID} from '@/common/js/constants';
|
||||
import {
|
||||
Assertions,
|
||||
ConstantTimer,
|
||||
Extract,
|
||||
IfController,
|
||||
JSR223Processor,
|
||||
LoopController
|
||||
} from "../../definition/model/ApiTestModel";
|
||||
import {parseEnvironment} from "../../definition/model/EnvironmentModel";
|
||||
import {ELEMENT_TYPE, ELEMENTS} from "./Setting";
|
||||
import MsApiCustomize from "./ApiCustomize";
|
||||
import {getCurrentProjectID, getUUID} from "@/common/js/utils";
|
||||
import ApiEnvironmentConfig from "../../definition/components/environment/ApiEnvironmentConfig";
|
||||
import MsInputTag from "./MsInputTag";
|
||||
import MsRun from "./DebugRun";
|
||||
import MsApiReportDetail from "../report/ApiReportDetail";
|
||||
import MsVariableList from "./variable/VariableList";
|
||||
import ApiImport from "../../definition/components/import/ApiImport";
|
||||
import "@/common/css/material-icons.css"
|
||||
import OutsideClick from "@/common/js/outside-click";
|
||||
import ScenarioApiRelevance from "./api/ApiRelevance";
|
||||
import ScenarioRelevance from "./api/ScenarioRelevance";
|
||||
import MsComponentConfig from "./component/ComponentConfig";
|
||||
import {handleCtrlSEvent} from "../../../../../common/js/utils";
|
||||
import {API_STATUS, PRIORITY} from "../../definition/model/JsonData";
|
||||
import {WORKSPACE_ID} from '@/common/js/constants';
|
||||
import {
|
||||
Assertions,
|
||||
ConstantTimer,
|
||||
Extract,
|
||||
IfController,
|
||||
JSR223Processor,
|
||||
LoopController
|
||||
} from "../../definition/model/ApiTestModel";
|
||||
import {parseEnvironment} from "../../definition/model/EnvironmentModel";
|
||||
import {ELEMENT_TYPE, ELEMENTS} from "./Setting";
|
||||
import MsApiCustomize from "./ApiCustomize";
|
||||
import {getCurrentProjectID, getUUID} from "@/common/js/utils";
|
||||
import ApiEnvironmentConfig from "../../definition/components/environment/ApiEnvironmentConfig";
|
||||
import MsInputTag from "./MsInputTag";
|
||||
import MsRun from "./DebugRun";
|
||||
import MsApiReportDetail from "../report/ApiReportDetail";
|
||||
import MsVariableList from "./variable/VariableList";
|
||||
import ApiImport from "../../definition/components/import/ApiImport";
|
||||
import "@/common/css/material-icons.css"
|
||||
import OutsideClick from "@/common/js/outside-click";
|
||||
import ScenarioApiRelevance from "./api/ApiRelevance";
|
||||
import ScenarioRelevance from "./api/ScenarioRelevance";
|
||||
import MsComponentConfig from "./component/ComponentConfig";
|
||||
import {handleCtrlSEvent} from "../../../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "EditApiScenario",
|
||||
props: {
|
||||
moduleOptions: Array,
|
||||
currentScenario: {},
|
||||
},
|
||||
components: {
|
||||
MsVariableList,
|
||||
ScenarioRelevance,
|
||||
ScenarioApiRelevance,
|
||||
ApiEnvironmentConfig,
|
||||
export default {
|
||||
name: "EditApiScenario",
|
||||
props: {
|
||||
moduleOptions: Array,
|
||||
currentScenario: {},
|
||||
},
|
||||
components: {
|
||||
MsVariableList,
|
||||
ScenarioRelevance,
|
||||
ScenarioApiRelevance,
|
||||
ApiEnvironmentConfig,
|
||||
MsApiReportDetail,
|
||||
MsInputTag, MsRun,
|
||||
MsApiCustomize,
|
||||
|
@ -596,6 +596,9 @@ export default {
|
|||
if (item.protocol) {
|
||||
request.protocol = item.protocol;
|
||||
}
|
||||
if (request.protocol === "DUBBO") {
|
||||
request.protocol = "dubbo://";
|
||||
}
|
||||
request.id = item.id;
|
||||
request.name = item.name;
|
||||
request.refType = refType;
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
<relevance-dialog :title="$t('api_test.automation.scenario_import')" ref="relevanceDialog">
|
||||
|
||||
<template v-slot:aside>
|
||||
<ms-api-scenario-module
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@refreshTable="refresh"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
@enableTrash="false"
|
||||
:is-read-only="true"
|
||||
ref="nodeTree"/>
|
||||
<ms-api-scenario-module
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@refreshTable="refresh"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
@enableTrash="false"
|
||||
:is-read-only="true"
|
||||
ref="nodeTree"/>
|
||||
</template>
|
||||
|
||||
<ms-api-scenario-list
|
||||
|
@ -27,94 +27,98 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import ScenarioRelevanceCaseList from "./RelevanceCaseList";
|
||||
import MsApiModule from "../../../definition/components/module/ApiModule";
|
||||
import MsContainer from "../../../../common/components/MsContainer";
|
||||
import MsAsideContainer from "../../../../common/components/MsAsideContainer";
|
||||
import MsMainContainer from "../../../../common/components/MsMainContainer";
|
||||
import ScenarioRelevanceApiList from "./RelevanceApiList";
|
||||
import MsApiScenarioModule from "../ApiScenarioModule";
|
||||
import MsApiScenarioList from "../ApiScenarioList";
|
||||
import {getUUID} from "../../../../../../common/js/utils";
|
||||
import RelevanceDialog from "../../../../track/plan/view/comonents/base/RelevanceDialog";
|
||||
export default {
|
||||
name: "ScenarioRelevance",
|
||||
components: {
|
||||
RelevanceDialog,
|
||||
MsApiScenarioList,
|
||||
MsApiScenarioModule,
|
||||
MsMainContainer, MsAsideContainer, MsContainer},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
currentProtocol: null,
|
||||
selectNodeIds: [],
|
||||
moduleOptions: {},
|
||||
isApiListEnable: true,
|
||||
currentScenario: [],
|
||||
currentScenarioIds: [],
|
||||
}
|
||||
import ScenarioRelevanceCaseList from "./RelevanceCaseList";
|
||||
import MsApiModule from "../../../definition/components/module/ApiModule";
|
||||
import MsContainer from "../../../../common/components/MsContainer";
|
||||
import MsAsideContainer from "../../../../common/components/MsAsideContainer";
|
||||
import MsMainContainer from "../../../../common/components/MsMainContainer";
|
||||
import ScenarioRelevanceApiList from "./RelevanceApiList";
|
||||
import MsApiScenarioModule from "../ApiScenarioModule";
|
||||
import MsApiScenarioList from "../ApiScenarioList";
|
||||
import {getUUID} from "../../../../../../common/js/utils";
|
||||
import RelevanceDialog from "../../../../track/plan/view/comonents/base/RelevanceDialog";
|
||||
|
||||
export default {
|
||||
name: "ScenarioRelevance",
|
||||
components: {
|
||||
RelevanceDialog,
|
||||
MsApiScenarioList,
|
||||
MsApiScenarioModule,
|
||||
MsMainContainer, MsAsideContainer, MsContainer
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
currentProtocol: null,
|
||||
selectNodeIds: [],
|
||||
moduleOptions: {},
|
||||
isApiListEnable: true,
|
||||
currentScenario: [],
|
||||
currentScenarioIds: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reference() {
|
||||
let scenarios = [];
|
||||
if (!this.currentScenario || this.currentScenario.length < 1) {
|
||||
this.$emit('请选择场景');
|
||||
return;
|
||||
}
|
||||
this.currentScenario.forEach(item => {
|
||||
let obj = {id: item.id, name: item.name, type: "scenario", referenced: 'REF', resourceId: getUUID()};
|
||||
scenarios.push(obj);
|
||||
});
|
||||
this.$emit('save', scenarios);
|
||||
this.close();
|
||||
},
|
||||
methods: {
|
||||
reference() {
|
||||
let scenarios = [];
|
||||
if (!this.currentScenario || this.currentScenario.length < 1) {
|
||||
this.$emit('请选择场景');
|
||||
return;
|
||||
}
|
||||
this.currentScenario.forEach(item => {
|
||||
let obj = {id: item.id, name: item.name, type: "scenario", referenced: 'REF', resourceId: getUUID()};
|
||||
scenarios.push(obj);
|
||||
});
|
||||
this.$emit('save', scenarios);
|
||||
this.close();
|
||||
},
|
||||
copy() {
|
||||
let scenarios = [];
|
||||
if (!this.currentScenarioIds || this.currentScenarioIds.length < 1) {
|
||||
this.$emit('请选择场景');
|
||||
return;
|
||||
}
|
||||
this.result = this.$post("/api/automation/getApiScenarios/", this.currentScenarioIds, response => {
|
||||
if (response.data) {
|
||||
response.data.forEach(item => {
|
||||
let scenarioDefinition = JSON.parse(item.scenarioDefinition);
|
||||
copy() {
|
||||
let scenarios = [];
|
||||
if (!this.currentScenarioIds || this.currentScenarioIds.length < 1) {
|
||||
this.$warning('请选择场景');
|
||||
return;
|
||||
}
|
||||
this.result = this.$post("/api/automation/getApiScenarios/", this.currentScenarioIds, response => {
|
||||
if (response.data) {
|
||||
response.data.forEach(item => {
|
||||
let scenarioDefinition = JSON.parse(item.scenarioDefinition);
|
||||
if (scenarioDefinition && scenarioDefinition.hashTree) {
|
||||
let obj = {id: item.id, name: item.name, type: "scenario", referenced: 'Copy', resourceId: getUUID(), hashTree: scenarioDefinition.hashTree};
|
||||
scenarios.push(obj);
|
||||
});
|
||||
this.$emit('save', scenarios);
|
||||
this.close();
|
||||
}
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.refresh();
|
||||
this.$refs.relevanceDialog.close();
|
||||
},
|
||||
open() {
|
||||
this.$refs.relevanceDialog.open();
|
||||
if (this.$refs.apiScenarioList) {
|
||||
this.$refs.apiScenarioList.search();
|
||||
}
|
||||
});
|
||||
this.$emit('save', scenarios);
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
nodeChange(node, nodeIds, pNodes) {
|
||||
this.selectNodeIds = nodeIds;
|
||||
},
|
||||
handleProtocolChange(protocol) {
|
||||
this.currentProtocol = protocol;
|
||||
},
|
||||
setModuleOptions(data) {
|
||||
this.moduleOptions = data;
|
||||
},
|
||||
refresh() {
|
||||
this.$refs.apiScenarioList.search();
|
||||
},
|
||||
setData(data) {
|
||||
this.currentScenario = Array.from(data).map(row => row);
|
||||
this.currentScenarioIds = Array.from(data).map(row => row.id);
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.refresh();
|
||||
this.$refs.relevanceDialog.close();
|
||||
},
|
||||
open() {
|
||||
this.$refs.relevanceDialog.open();
|
||||
if (this.$refs.apiScenarioList) {
|
||||
this.$refs.apiScenarioList.search();
|
||||
}
|
||||
},
|
||||
nodeChange(node, nodeIds, pNodes) {
|
||||
this.selectNodeIds = nodeIds;
|
||||
},
|
||||
handleProtocolChange(protocol) {
|
||||
this.currentProtocol = protocol;
|
||||
},
|
||||
setModuleOptions(data) {
|
||||
this.moduleOptions = data;
|
||||
},
|
||||
refresh() {
|
||||
this.$refs.apiScenarioList.search();
|
||||
},
|
||||
setData(data) {
|
||||
this.currentScenario = Array.from(data).map(row => row);
|
||||
this.currentScenarioIds = Array.from(data).map(row => row.id);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-dialog :close-on-click-modal="false" :title="$t('api_test.api_import.title')" width="30%"
|
||||
<el-dialog :close-on-click-modal="false" :title="$t('api_test.automation.scenario_import')" width="30%"
|
||||
:visible.sync="visible" class="api-import" v-loading="result.loading" @close="close">
|
||||
|
||||
<div class="header-bar">
|
||||
|
|
|
@ -22,23 +22,23 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters";
|
||||
import MsTcpBasisParameters from "../../../definition/components/request/tcp/TcpBasisParameters";
|
||||
import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters";
|
||||
import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm";
|
||||
import ApiBaseComponent from "../common/ApiBaseComponent";
|
||||
import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters";
|
||||
import MsTcpBasisParameters from "../../../definition/components/request/tcp/TcpBasisParameters";
|
||||
import MsDubboBasisParameters from "../../../definition/components/request/dubbo/BasisParameters";
|
||||
import MsApiRequestForm from "../../../definition/components/request/http/ApiHttpRequestForm";
|
||||
import ApiBaseComponent from "../common/ApiBaseComponent";
|
||||
|
||||
export default {
|
||||
name: "ApiScenarioComponent",
|
||||
props: {
|
||||
scenario: {},
|
||||
node: {},
|
||||
draggable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
export default {
|
||||
name: "ApiScenarioComponent",
|
||||
props: {
|
||||
scenario: {},
|
||||
node: {},
|
||||
draggable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {},
|
||||
watch: {},
|
||||
created() {
|
||||
if (this.scenario.id && this.scenario.referenced === 'REF' && !this.scenario.loaded) {
|
||||
this.result = this.$get("/api/automation/getApiScenario/" + this.scenario.id, response => {
|
||||
|
@ -79,8 +79,10 @@ export default {
|
|||
this.$emit('remove', this.scenario, this.node);
|
||||
},
|
||||
active(item) {
|
||||
item.active = !item.active;
|
||||
this.reload();
|
||||
if (item && item.active) {
|
||||
item.active = !item.active;
|
||||
this.reload();
|
||||
}
|
||||
},
|
||||
copyRow() {
|
||||
this.$emit('copyRow', this.scenario, this.node);
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
</el-link>
|
||||
</el-row>
|
||||
<div style="min-height: 400px">
|
||||
<ms-api-key-value :items="headers"/>
|
||||
<ms-api-key-value :items="headers" :suggestions="headerSuggestions"/>
|
||||
<batch-add-parameter @batchSave="batchSave" ref="batchAddParameter"/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
@ -95,33 +95,34 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import MsEditConstant from "./EditConstant";
|
||||
import MsDialogFooter from "../../../../common/components/MsDialogFooter";
|
||||
import MsTableHeader from "@/business/components/common/components/MsTableHeader";
|
||||
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import MsEditCounter from "./EditCounter";
|
||||
import MsEditRandom from "./EditRandom";
|
||||
import MsEditListValue from "./EditListValue";
|
||||
import MsEditCsv from "./EditCsv";
|
||||
import {getUUID} from "@/common/js/utils";
|
||||
import MsApiKeyValue from "../../../definition/components/ApiKeyValue";
|
||||
import BatchAddParameter from "../../../definition/components/basis/BatchAddParameter";
|
||||
import {KeyValue} from "../../../definition/model/ApiTestModel";
|
||||
import MsEditConstant from "./EditConstant";
|
||||
import MsDialogFooter from "../../../../common/components/MsDialogFooter";
|
||||
import MsTableHeader from "@/business/components/common/components/MsTableHeader";
|
||||
import MsTablePagination from "@/business/components/common/pagination/TablePagination";
|
||||
import MsEditCounter from "./EditCounter";
|
||||
import MsEditRandom from "./EditRandom";
|
||||
import MsEditListValue from "./EditListValue";
|
||||
import MsEditCsv from "./EditCsv";
|
||||
import {getUUID} from "@/common/js/utils";
|
||||
import MsApiKeyValue from "../../../definition/components/ApiKeyValue";
|
||||
import BatchAddParameter from "../../../definition/components/basis/BatchAddParameter";
|
||||
import {KeyValue} from "../../../definition/model/ApiTestModel";
|
||||
import {REQUEST_HEADERS} from "@/common/js/constants";
|
||||
|
||||
export default {
|
||||
name: "MsVariableList",
|
||||
components: {
|
||||
MsEditConstant,
|
||||
MsDialogFooter,
|
||||
MsTableHeader,
|
||||
MsTablePagination,
|
||||
MsEditCounter,
|
||||
MsEditRandom,
|
||||
MsEditListValue,
|
||||
MsEditCsv,
|
||||
MsApiKeyValue,
|
||||
BatchAddParameter
|
||||
},
|
||||
export default {
|
||||
name: "MsVariableList",
|
||||
components: {
|
||||
MsEditConstant,
|
||||
MsDialogFooter,
|
||||
MsTableHeader,
|
||||
MsTablePagination,
|
||||
MsEditCounter,
|
||||
MsEditRandom,
|
||||
MsEditListValue,
|
||||
MsEditCsv,
|
||||
MsApiKeyValue,
|
||||
BatchAddParameter
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
variables: [],
|
||||
|
@ -144,6 +145,7 @@ export default {
|
|||
editData: {},
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
headerSuggestions: REQUEST_HEADERS,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -285,19 +287,19 @@ export default {
|
|||
</script>
|
||||
|
||||
<style>
|
||||
.ms-variable-hidden-row {
|
||||
display: none;
|
||||
}
|
||||
.ms-variable-hidden-row {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ms-variable-header {
|
||||
background: #783887;
|
||||
color: white;
|
||||
height: 18px;
|
||||
border-radius: 42%;
|
||||
}
|
||||
.ms-variable-header {
|
||||
background: #783887;
|
||||
color: white;
|
||||
height: 18px;
|
||||
border-radius: 42%;
|
||||
}
|
||||
|
||||
.ms-variable-link {
|
||||
float: right;
|
||||
margin-right: 45px;
|
||||
}
|
||||
.ms-variable-link {
|
||||
float: right;
|
||||
margin-right: 45px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -384,6 +384,7 @@ export default {
|
|||
}
|
||||
|
||||
let simpleInfoUrl = "/api/document/selectApiSimpleInfo";
|
||||
this.apiSimpleInfoArray = [];
|
||||
this.$post(simpleInfoUrl, simpleRequest, response => {
|
||||
this.apiSimpleInfoArray = response.data;
|
||||
this.apiStepIndex = 0;
|
||||
|
|
|
@ -699,6 +699,10 @@ export default {
|
|||
exportApi() {
|
||||
let param = this.buildBatchParam();
|
||||
param.protocol = this.currentProtocol;
|
||||
if (param.ids === undefined || param.ids.length < 1) {
|
||||
this.$warning(this.$t("api_test.definition.check_select"));
|
||||
return;
|
||||
}
|
||||
this.result = this.$post("/api/definition/export", param, response => {
|
||||
let obj = response.data;
|
||||
obj.protocol = this.currentProtocol;
|
||||
|
|
|
@ -1,83 +1,86 @@
|
|||
<template>
|
||||
<el-form :model="config" :rules="rules" ref="config" label-width="100px" size="small" :disabled="isReadOnly">
|
||||
<div class="dubbo-form-description" v-if="description">
|
||||
{{ description }}
|
||||
</div>
|
||||
<el-form-item label="Protocol" prop="protocol" class="dubbo-form-item">
|
||||
<el-select v-model="config.protocol" class="select-100" clearable>
|
||||
<el-option v-for="p in protocols" :key="p" :label="p" :value="p"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<div class="dubbo-form-description" v-if="description">
|
||||
{{ description }}
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="Group" prop="group" class="dubbo-form-item">
|
||||
<el-input v-model="config.group" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-form-item label="Protocol" prop="protocol" class="dubbo-form-item">
|
||||
<el-select v-model="config.protocol" class="select-100" clearable>
|
||||
<el-option v-for="p in protocols" :key="p" :label="p" :value="p"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="Group" prop="group" class="dubbo-form-item">
|
||||
<el-input v-model="config.group" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Namespace" prop="namespace" class="dubbo-form-item">
|
||||
<el-input v-model="config.namespace" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="config.timeout" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="Address" prop="address" class="dubbo-form-item-long">
|
||||
<el-input v-model="config.address" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Namespace" prop="namespace" class="dubbo-form-item">
|
||||
<el-input v-model="config.namespace" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="config.timeout" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Address" prop="address" class="dubbo-form-item-long">
|
||||
<el-input v-model="config.address" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="UserName" prop="username" class="dubbo-form-item">
|
||||
<el-input v-model="config.username" maxlength="100" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Password" prop="password" class="dubbo-form-item">
|
||||
<el-input v-model="config.password" maxlength="30" show-word-limit show-password autocomplete="new-password"
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="UserName" prop="username" class="dubbo-form-item">
|
||||
<el-input v-model="config.username" maxlength="100" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Password" prop="password" class="dubbo-form-item">
|
||||
<el-input v-model="config.password" maxlength="30" show-word-limit show-password autocomplete="new-password"
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import './dubbo.css'
|
||||
import {ConfigCenter} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
import './dubbo.css'
|
||||
import {ConfigCenter} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
|
||||
export default {
|
||||
name: "MsDubboConfigCenter",
|
||||
props: {
|
||||
description: String,
|
||||
config: {},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
protocols: ConfigCenter.PROTOCOLS,
|
||||
methods: [],
|
||||
rules: {
|
||||
group: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
namespace: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
username: [
|
||||
{max: 100, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
password: [
|
||||
{max: 30, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
address: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
]
|
||||
export default {
|
||||
name: "MsDubboConfigCenter",
|
||||
props: {
|
||||
description: String,
|
||||
config: {},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
protocols: ConfigCenter.PROTOCOLS,
|
||||
methods: [],
|
||||
rules: {
|
||||
group: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
namespace: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
username: [
|
||||
{max: 100, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
password: [
|
||||
{max: 30, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
address: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,82 +1,86 @@
|
|||
<template>
|
||||
|
||||
<el-form :model="consumer" :rules="rules" ref="consumer" label-width="100px" size="small" :disabled="isReadOnly">
|
||||
<div class="dubbo-form-description" v-if="description">
|
||||
{{ description }}
|
||||
</div>
|
||||
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="consumer.timeout" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<div class="dubbo-form-description" v-if="description">
|
||||
{{ description }}
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="consumer.timeout" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Version" prop="version" class="dubbo-form-item">
|
||||
<el-input v-model="consumer.version" maxlength="30" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Version" prop="version" class="dubbo-form-item">
|
||||
<el-input v-model="consumer.version" maxlength="30" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Retries" prop="retries" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="consumer.retries" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Retries" prop="retries" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="consumer.retries" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Cluster" prop="cluster" class="dubbo-form-item">
|
||||
<el-input v-model="consumer.cluster" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="Group" prop="group" class="dubbo-form-item">
|
||||
<el-input v-model="consumer.group" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Cluster" prop="cluster" class="dubbo-form-item">
|
||||
<el-input v-model="consumer.cluster" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Connections" prop="connections" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="consumer.connections" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Group" prop="group" class="dubbo-form-item">
|
||||
<el-input v-model="consumer.group" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Async" prop="async" class="dubbo-form-item">
|
||||
<el-select v-model="consumer.async" class="select-100" clearable>
|
||||
<el-option v-for="option in asyncOptions" :key="option" :label="option" :value="option"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Connections" prop="connections" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="consumer.connections" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Async" prop="async" class="dubbo-form-item">
|
||||
<el-select v-model="consumer.async" class="select-100" clearable>
|
||||
<el-option v-for="option in asyncOptions" :key="option" :label="option" :value="option"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="LoadBalance" prop="loadBalance" class="dubbo-form-item">
|
||||
<el-select v-model="consumer.loadBalance" class="select-100" clearable>
|
||||
<el-option v-for="option in loadBalances" :key="option" :label="option" :value="option"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="LoadBalance" prop="loadBalance" class="dubbo-form-item">
|
||||
<el-select v-model="consumer.loadBalance" class="select-100" clearable>
|
||||
<el-option v-for="option in loadBalances" :key="option" :label="option" :value="option"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import './dubbo.css'
|
||||
import {ConsumerAndService, RegistryCenter} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
import './dubbo.css'
|
||||
import {ConsumerAndService, RegistryCenter} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
|
||||
export default {
|
||||
name: "MsDubboConsumerService",
|
||||
props: {
|
||||
description: String,
|
||||
consumer: {},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
asyncOptions: ConsumerAndService.ASYNC_OPTIONS,
|
||||
loadBalances: ConsumerAndService.LOAD_BALANCE_OPTIONS,
|
||||
methods: [],
|
||||
rules: {
|
||||
version: [
|
||||
{max: 30, message: this.$t('commons.input_limit', [0, 30]), trigger: 'blur'}
|
||||
],
|
||||
cluster: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
group: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
]
|
||||
export default {
|
||||
name: "MsDubboConsumerService",
|
||||
props: {
|
||||
description: String,
|
||||
consumer: {},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
asyncOptions: ConsumerAndService.ASYNC_OPTIONS,
|
||||
loadBalances: ConsumerAndService.LOAD_BALANCE_OPTIONS,
|
||||
methods: [],
|
||||
rules: {
|
||||
version: [
|
||||
{max: 30, message: this.$t('commons.input_limit', [0, 30]), trigger: 'blur'}
|
||||
],
|
||||
cluster: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
group: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
|
||||
<style scoped>
|
||||
.get-provider {
|
||||
margin-bottom: 22px;
|
||||
margin: 5px 5px 10px;
|
||||
}
|
||||
|
||||
.select-100 {
|
||||
|
|
|
@ -1,73 +1,78 @@
|
|||
<template>
|
||||
<el-form :model="registry" :rules="rules" ref="registry" label-width="100px" size="small" :disabled="isReadOnly">
|
||||
<div class="dubbo-form-description" v-if="description">
|
||||
{{ description }}
|
||||
</div>
|
||||
<el-form-item label="Protocol" prop="protocol" class="dubbo-form-item">
|
||||
<el-select v-model="registry.protocol" class="select-100" clearable>
|
||||
<el-option v-for="p in protocols" :key="p" :label="p" :value="p"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<div class="dubbo-form-description" v-if="description">
|
||||
{{ description }}
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="Protocol" prop="protocol" class="dubbo-form-item">
|
||||
<el-select v-model="registry.protocol" class="select-100" clearable>
|
||||
<el-option v-for="p in protocols" :key="p" :label="p" :value="p"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Group" prop="group" class="dubbo-form-item">
|
||||
<el-input v-model="registry.group" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Group" prop="group" class="dubbo-form-item">
|
||||
<el-input v-model="registry.group" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="UserName" prop="username" class="dubbo-form-item">
|
||||
<el-input v-model="registry.username" maxlength="100" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="UserName" prop="username" class="dubbo-form-item">
|
||||
<el-input v-model="registry.username" maxlength="100" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Password" prop="password" class="dubbo-form-item">
|
||||
<el-input v-model="registry.password" maxlength="30" show-word-limit show-password autocomplete="new-password"
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Password" prop="password" class="dubbo-form-item">
|
||||
<el-input v-model="registry.password" maxlength="30" show-word-limit show-password autocomplete="new-password"
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="Address" prop="address" class="dubbo-form-item-long">
|
||||
<el-input v-model="registry.address" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Address" prop="address" class="dubbo-form-item-long">
|
||||
<el-input v-model="registry.address" maxlength="300" show-word-limit
|
||||
:placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="registry.timeout" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="Timeout" prop="timeout" class="dubbo-form-item">
|
||||
<el-input type="number" v-model="registry.timeout" :placeholder="$t('commons.input_content')"/>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import './dubbo.css'
|
||||
import {RegistryCenter} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
import './dubbo.css'
|
||||
import {RegistryCenter} from "@/business/components/api/definition/model/ApiTestModel";
|
||||
|
||||
export default {
|
||||
name: "MsDubboRegistryCenter",
|
||||
props: {
|
||||
description: String,
|
||||
registry: {},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
protocols: RegistryCenter.PROTOCOLS,
|
||||
methods: [],
|
||||
rules: {
|
||||
group: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
username: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
password: [
|
||||
{max: 30, message: this.$t('commons.input_limit', [0, 30]), trigger: 'blur'}
|
||||
],
|
||||
address: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
]
|
||||
export default {
|
||||
name: "MsDubboRegistryCenter",
|
||||
props: {
|
||||
description: String,
|
||||
registry: {},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
protocols: RegistryCenter.PROTOCOLS,
|
||||
methods: [],
|
||||
rules: {
|
||||
group: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
username: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
],
|
||||
password: [
|
||||
{max: 30, message: this.$t('commons.input_limit', [0, 30]), trigger: 'blur'}
|
||||
],
|
||||
address: [
|
||||
{max: 300, message: this.$t('commons.input_limit', [0, 300]), trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -8,18 +8,21 @@
|
|||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('api_test.definition.request.response_header')" name="headers" class="pane">
|
||||
<div style="width: 400px">
|
||||
<pre>{{ response.responseResult.headers }}</pre>
|
||||
</div>
|
||||
<!--<div style="width: 400px">-->
|
||||
<!--<pre>{{ response.responseResult.headers }}</pre>-->
|
||||
<!--</div>-->
|
||||
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="response.responseResult.headers"/>
|
||||
|
||||
</el-tab-pane>
|
||||
<!--<el-tab-pane label="Cookie" name="cookie" class="pane cookie">-->
|
||||
<!--<pre>{{response.cookies}}</pre>-->
|
||||
<!--</el-tab-pane>-->
|
||||
|
||||
<el-tab-pane :label="$t('api_test.definition.request.console')" name="console" class="pane">
|
||||
<div style="width: 400px">
|
||||
<pre>{{response.responseResult.console}}</pre>
|
||||
</div>
|
||||
<!--<div style="width: 400px">-->
|
||||
<!--<pre>{{response.responseResult.console}}</pre>-->
|
||||
<!--</div>-->
|
||||
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="response.responseResult.console"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('api_report.assertions')" name="assertions" class="pane assertions">
|
||||
|
@ -27,29 +30,30 @@
|
|||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('api_test.request.extract.label')" name="label" class="pane">
|
||||
<div style="width: 400px">
|
||||
<pre>{{response.responseResult.vars}}</pre>
|
||||
</div>
|
||||
<!--<div style="width: 400px">-->
|
||||
<!--<pre>{{response.responseResult.vars}}</pre>-->
|
||||
<!--</div>-->
|
||||
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="response.responseResult.vars"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('api_report.request_body')" name="request_body" class="pane">
|
||||
<div class="ms-div">
|
||||
{{$t('api_test.request.address')}} :
|
||||
<pre>{{ response.url }}</pre>
|
||||
</div>
|
||||
<div class="ms-div">
|
||||
{{$t('api_test.scenario.headers')}} :
|
||||
<pre>{{ response.headers }}</pre>
|
||||
</div>
|
||||
<div class="ms-div">
|
||||
Cookies :
|
||||
<pre>{{response.cookies}}</pre>
|
||||
</div>
|
||||
<div class="ms-div">
|
||||
Body :
|
||||
<pre>{{response.body ? response.body:""}}</pre>
|
||||
</div>
|
||||
|
||||
<!--<div class="ms-div">-->
|
||||
<!--{{$t('api_test.request.address')}} :-->
|
||||
<!--<pre>{{ response.url }}</pre>-->
|
||||
<!--</div>-->
|
||||
<!--<div class="ms-div">-->
|
||||
<!--{{$t('api_test.scenario.headers')}} :-->
|
||||
<!--<pre>{{ response.headers }}</pre>-->
|
||||
<!--</div>-->
|
||||
<!--<div class="ms-div">-->
|
||||
<!--Cookies :-->
|
||||
<!--<pre>{{response.cookies}}</pre>-->
|
||||
<!--</div>-->
|
||||
<!--<div class="ms-div">-->
|
||||
<!--Body :-->
|
||||
<!--<pre>{{response.body ? response.body:""}}</pre>-->
|
||||
<!--</div>-->
|
||||
<ms-code-edit :mode="'text'" :read-only="true" :data.sync="reqMessages"/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane v-if="activeName == 'body'" :disabled="true" name="mode" class="pane cookie">
|
||||
|
@ -63,23 +67,23 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import MsAssertionResults from "./AssertionResults";
|
||||
import MsCodeEdit from "../MsCodeEdit";
|
||||
import MsDropdown from "../../../../common/components/MsDropdown";
|
||||
import {BODY_FORMAT} from "../../model/ApiTestModel";
|
||||
import MsSqlResultTable from "./SqlResultTable";
|
||||
import MsAssertionResults from "./AssertionResults";
|
||||
import MsCodeEdit from "../MsCodeEdit";
|
||||
import MsDropdown from "../../../../common/components/MsDropdown";
|
||||
import {BODY_FORMAT} from "../../model/ApiTestModel";
|
||||
import MsSqlResultTable from "./SqlResultTable";
|
||||
|
||||
export default {
|
||||
name: "MsResponseResult",
|
||||
export default {
|
||||
name: "MsResponseResult",
|
||||
|
||||
components: {
|
||||
MsDropdown,
|
||||
MsCodeEdit,
|
||||
MsAssertionResults,
|
||||
MsSqlResultTable
|
||||
},
|
||||
components: {
|
||||
MsDropdown,
|
||||
MsCodeEdit,
|
||||
MsAssertionResults,
|
||||
MsSqlResultTable
|
||||
},
|
||||
|
||||
props: {
|
||||
props: {
|
||||
response: Object,
|
||||
currentProtocol: String,
|
||||
},
|
||||
|
@ -91,12 +95,14 @@ export default {
|
|||
modes: ['text', 'json', 'xml', 'html'],
|
||||
sqlModes: ['text', 'table'],
|
||||
mode: BODY_FORMAT.TEXT,
|
||||
isMsCodeEditShow: true
|
||||
isMsCodeEditShow: true,
|
||||
reqMessages: "",
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
response() {
|
||||
this.setBodyType();
|
||||
this.setReqMessage();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -126,9 +132,29 @@ export default {
|
|||
this.isMsCodeEditShow = true;
|
||||
});
|
||||
},
|
||||
setReqMessage() {
|
||||
if (this.response) {
|
||||
if (!this.response.url) {
|
||||
this.response.url = "";
|
||||
}
|
||||
if (!this.response.headers) {
|
||||
this.response.headers = "";
|
||||
}
|
||||
if (!this.response.cookies) {
|
||||
this.response.cookies = "";
|
||||
}
|
||||
if (!this.response.body) {
|
||||
this.response.body = "";
|
||||
}
|
||||
this.reqMessages = this.$t('api_test.request.address') + ":\n" + this.response.url + "\n" +
|
||||
this.$t('api_test.scenario.headers') + ":\n" + this.response.headers + "\n" + "Cookies :\n" +
|
||||
this.response.cookies + "\n" + "Bpdy:" + "\n" + this.response.body;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setBodyType();
|
||||
this.setReqMessage();
|
||||
},
|
||||
computed: {
|
||||
isSqlType() {
|
||||
|
|
|
@ -254,8 +254,12 @@ export default {
|
|||
let resultValidate = {validate: true, msg: this.$t('test_resource_pool.fill_the_data')};
|
||||
this.infoList.forEach(info => {
|
||||
for (let key in info) {
|
||||
// 排除非必填项
|
||||
if (key === 'nodeSelector') {
|
||||
continue;
|
||||
}
|
||||
if (info[key] != '0' && !info[key]) {
|
||||
resultValidate.validate = false
|
||||
resultValidate.validate = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -533,6 +533,7 @@ export default {
|
|||
api_case_passing_rate: "Use case pass rate",
|
||||
create_tip: "Note: Detailed interface information can be filled out on the edit page",
|
||||
api_import: "Api Import",
|
||||
check_select: "Please check the API",
|
||||
select_comp: {
|
||||
no_data: "No Data",
|
||||
add_data: "Add Data"
|
||||
|
|
|
@ -533,6 +533,7 @@ export default {
|
|||
api_case_passing_rate: "用例通过率",
|
||||
create_tip: "注: 详细的接口信息可以在编辑页面填写",
|
||||
api_import: "接口导入",
|
||||
check_select: "请勾选接口",
|
||||
select_comp: {
|
||||
no_data: "无数据",
|
||||
add_data: "去添加"
|
||||
|
|
|
@ -532,6 +532,7 @@ export default {
|
|||
api_case_passing_rate: "用例通過率",
|
||||
create_tip: "註: 詳細的接口信息可以在編輯頁面填寫",
|
||||
api_import: "接口導入",
|
||||
check_select: "請勾選接口",
|
||||
select_comp: {
|
||||
no_data: "無數據",
|
||||
add_data: "去添加"
|
||||
|
|
Loading…
Reference in New Issue