refactor(接口自动化): 场景导入 ms,postman 基本完成
This commit is contained in:
parent
c94aab0219
commit
c74e88c3f3
|
@ -2,14 +2,15 @@ package io.metersphere.api.controller;
|
||||||
|
|
||||||
import com.github.pagehelper.Page;
|
import com.github.pagehelper.Page;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||||
import io.metersphere.api.dto.JmxInfoDTO;
|
import io.metersphere.api.dto.JmxInfoDTO;
|
||||||
import io.metersphere.api.dto.automation.*;
|
import io.metersphere.api.dto.automation.*;
|
||||||
|
import io.metersphere.api.dto.automation.parse.ScenarioImport;
|
||||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||||
import io.metersphere.api.service.ApiAutomationService;
|
import io.metersphere.api.service.ApiAutomationService;
|
||||||
import io.metersphere.base.domain.ApiScenario;
|
import io.metersphere.base.domain.ApiScenario;
|
||||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||||
import io.metersphere.base.domain.Schedule;
|
import io.metersphere.base.domain.Schedule;
|
||||||
import io.metersphere.commons.constants.ApiRunMode;
|
|
||||||
import io.metersphere.commons.constants.RoleConstants;
|
import io.metersphere.commons.constants.RoleConstants;
|
||||||
import io.metersphere.commons.utils.PageUtils;
|
import io.metersphere.commons.utils.PageUtils;
|
||||||
import io.metersphere.commons.utils.Pager;
|
import io.metersphere.commons.utils.Pager;
|
||||||
|
@ -43,6 +44,13 @@ public class ApiAutomationController {
|
||||||
return PageUtils.setPageInfo(page, apiAutomationService.list(request));
|
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")
|
@PostMapping(value = "/create")
|
||||||
public ApiScenario create(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
public ApiScenario create(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
||||||
return apiAutomationService.create(request, bodyFiles);
|
return apiAutomationService.create(request, bodyFiles);
|
||||||
|
@ -146,5 +154,12 @@ public class ApiAutomationController {
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileOperationRequest.getName() + "\"")
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileOperationRequest.getName() + "\"")
|
||||||
.body(bytes);
|
.body(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/import", consumes = {"multipart/form-data"})
|
||||||
|
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||||
|
public ScenarioImport scenarioImport(@RequestPart(value = "file", required = false) MultipartFile file, @RequestPart("request") ApiTestImportRequest request) {
|
||||||
|
return apiAutomationService.scenarioImport(file, request);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package io.metersphere.api.dto.automation.parse;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class MsScenarioParser extends ScenarioImportAbstractParser {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScenarioImport parse(InputStream source, ApiTestImportRequest request) {
|
||||||
|
String testStr = getApiTestStr(source);
|
||||||
|
this.projectId = request.getProjectId();
|
||||||
|
ScenarioImport scenarioImport = parseMsFormat(testStr, request);
|
||||||
|
return scenarioImport;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScenarioImport parseMsFormat(String testStr, ApiTestImportRequest importRequest) {
|
||||||
|
ScenarioImport apiDefinitionImport = JSON.parseObject(testStr, ScenarioImport.class);
|
||||||
|
List<ApiScenarioWithBLOBs> data = apiDefinitionImport.getData();
|
||||||
|
if (CollectionUtils.isNotEmpty(data)) {
|
||||||
|
data.forEach(item -> {
|
||||||
|
if (StringUtils.isBlank(item.getModulePath())) {
|
||||||
|
item.setApiScenarioModuleId(null);
|
||||||
|
}
|
||||||
|
parseModule(item, importRequest);
|
||||||
|
item.setId(UUID.randomUUID().toString());
|
||||||
|
item.setProjectId(this.projectId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return apiDefinitionImport;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseModule(ApiScenarioWithBLOBs apiDefinition, ApiTestImportRequest importRequest) {
|
||||||
|
String modulePath = apiDefinition.getModulePath();
|
||||||
|
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("/"));
|
||||||
|
ApiScenarioModule parent = getSelectModule(importRequest.getModuleId());
|
||||||
|
Iterator<String> iterator = modules.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
String item = iterator.next();
|
||||||
|
parent = buildModule(parent, item);
|
||||||
|
if (!iterator.hasNext()) {
|
||||||
|
apiDefinition.setApiScenarioModuleId(parent.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package io.metersphere.api.dto.automation.parse;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ScenarioImport {
|
||||||
|
private String projectid;
|
||||||
|
private List<ApiScenarioWithBLOBs> data;
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
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);
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package io.metersphere.api.dto.automation.parse;
|
||||||
|
|
||||||
|
import io.metersphere.commons.constants.ApiImportPlatform;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
public class ScenarioImportParserFactory {
|
||||||
|
public static ScenarioImportParser getImportParser(String platform) {
|
||||||
|
if (StringUtils.equals(ApiImportPlatform.Metersphere.name(), platform)) {
|
||||||
|
return new MsScenarioParser();
|
||||||
|
} else if (StringUtils.equals(ApiImportPlatform.Postman.name(), platform)) {
|
||||||
|
return new MsPostmanParser();
|
||||||
|
}
|
||||||
|
// else if (StringUtils.equals(ApiImportPlatform.Swagger2.name(), platform)) {
|
||||||
|
// return new Swagger2Parser();
|
||||||
|
// }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,13 @@ public class ScenarioVariable {
|
||||||
private String minNumber;
|
private String minNumber;
|
||||||
private String maxNumber;
|
private String maxNumber;
|
||||||
|
|
||||||
|
public ScenarioVariable(String key, String value, String description, String type) {
|
||||||
|
this.name = key;
|
||||||
|
this.value = value;
|
||||||
|
this.description = description;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isConstantValid() {
|
public boolean isConstantValid() {
|
||||||
if (StringUtils.equals(this.type, VariableTypeConstants.CONSTANT.name()) && StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(value)) {
|
if (StringUtils.equals(this.type, VariableTypeConstants.CONSTANT.name()) && StringUtils.isNotEmpty(name) && StringUtils.isNotEmpty(value)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -5,9 +5,13 @@ import com.alibaba.fastjson.JSONObject;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.metersphere.api.dto.ApiTestImportRequest;
|
||||||
import io.metersphere.api.dto.DeleteAPIReportRequest;
|
import io.metersphere.api.dto.DeleteAPIReportRequest;
|
||||||
import io.metersphere.api.dto.JmxInfoDTO;
|
import io.metersphere.api.dto.JmxInfoDTO;
|
||||||
import io.metersphere.api.dto.automation.*;
|
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.datacount.ApiDataCountResult;
|
||||||
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
import io.metersphere.api.dto.definition.RunDefinitionRequest;
|
||||||
import io.metersphere.api.dto.definition.request.*;
|
import io.metersphere.api.dto.definition.request.*;
|
||||||
|
@ -91,8 +95,19 @@ public class ApiAutomationService {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化部分参数
|
* 初始化部分参数
|
||||||
|
*
|
||||||
* @param request
|
* @param request
|
||||||
* @param setDefultOrders
|
* @param setDefultOrders
|
||||||
* @param checkThisWeekData
|
* @param checkThisWeekData
|
||||||
|
@ -712,4 +727,89 @@ public class ApiAutomationService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ApiScenarioWithBLOBs> getWithBLOBs(ApiScenarioWithBLOBs request) {
|
||||||
|
ApiScenarioExample example = new ApiScenarioExample();
|
||||||
|
example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId()).andStatusNotEqualTo("Trash").andIdNotEqualTo(request.getId());
|
||||||
|
return apiScenarioMapper.selectByExampleWithBLOBs(example);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _importCreate(List<ApiScenarioWithBLOBs> sameRequest, ApiScenarioMapper batchMapper, ApiScenarioWithBLOBs scenarioWithBLOBs, ApiTestImportRequest apiTestImportRequest) {
|
||||||
|
if (CollectionUtils.isEmpty(sameRequest)) {
|
||||||
|
scenarioWithBLOBs.setId(UUID.randomUUID().toString());
|
||||||
|
batchMapper.insert(scenarioWithBLOBs);
|
||||||
|
} else {
|
||||||
|
//如果存在则修改
|
||||||
|
scenarioWithBLOBs.setId(sameRequest.get(0).getId());
|
||||||
|
batchMapper.updateByPrimaryKeyWithBLOBs(scenarioWithBLOBs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiScenarioWithBLOBs importCreate(ApiScenarioWithBLOBs request, ApiScenarioMapper batchMapper, ApiTestImportRequest apiTestImportRequest) {
|
||||||
|
final ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs();
|
||||||
|
BeanUtils.copyBean(scenarioWithBLOBs, request);
|
||||||
|
scenarioWithBLOBs.setCreateTime(System.currentTimeMillis());
|
||||||
|
scenarioWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||||
|
scenarioWithBLOBs.setStatus(APITestStatus.Underway.name());
|
||||||
|
scenarioWithBLOBs.setProjectId(apiTestImportRequest.getProjectId());
|
||||||
|
if (StringUtils.isEmpty(request.getPrincipal())) {
|
||||||
|
scenarioWithBLOBs.setPrincipal(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
||||||
|
}
|
||||||
|
if (request.getUserId() == null) {
|
||||||
|
scenarioWithBLOBs.setUserId(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
||||||
|
} else {
|
||||||
|
scenarioWithBLOBs.setUserId(request.getUserId());
|
||||||
|
}
|
||||||
|
scenarioWithBLOBs.setDescription(request.getDescription());
|
||||||
|
|
||||||
|
List<ApiScenarioWithBLOBs> sameRequest = getWithBLOBs(scenarioWithBLOBs);
|
||||||
|
if (StringUtils.equals("fullCoverage", apiTestImportRequest.getModeId())) {
|
||||||
|
_importCreate(sameRequest, batchMapper, scenarioWithBLOBs, apiTestImportRequest);
|
||||||
|
} else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) {
|
||||||
|
if (CollectionUtils.isEmpty(sameRequest)) {
|
||||||
|
batchMapper.insert(scenarioWithBLOBs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_importCreate(sameRequest, batchMapper, scenarioWithBLOBs, apiTestImportRequest);
|
||||||
|
}
|
||||||
|
return scenarioWithBLOBs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void editScenario(ApiTestImportRequest request, ScenarioImport apiImport) {
|
||||||
|
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||||
|
ApiScenarioMapper batchMapper = sqlSession.getMapper(ApiScenarioMapper.class);
|
||||||
|
List<ApiScenarioWithBLOBs> data = apiImport.getData();
|
||||||
|
int num = 0;
|
||||||
|
if (!CollectionUtils.isEmpty(data) && data.get(0) != null && data.get(0).getProjectId() != null) {
|
||||||
|
num = getNextNum(data.get(0).getProjectId());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < data.size(); i++) {
|
||||||
|
ApiScenarioWithBLOBs item = data.get(i);
|
||||||
|
if (item.getName().length() > 255) {
|
||||||
|
item.setName(item.getName().substring(0, 255));
|
||||||
|
}
|
||||||
|
item.setNum(num++);
|
||||||
|
importCreate(item, batchMapper, request);
|
||||||
|
if (i % 300 == 0) {
|
||||||
|
sqlSession.flushStatements();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sqlSession.flushStatements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScenarioImport scenarioImport(MultipartFile file, ApiTestImportRequest request) {
|
||||||
|
ScenarioImportParser apiImportParser = ScenarioImportParserFactory.getImportParser(request.getPlatform());
|
||||||
|
ScenarioImport apiImport = null;
|
||||||
|
try {
|
||||||
|
apiImport = 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"));
|
||||||
|
}
|
||||||
|
if (apiImport != null) {
|
||||||
|
editScenario(request, apiImport);
|
||||||
|
}
|
||||||
|
return apiImport;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,33 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ApiScenarioModule getNewModule(String name, String projectId, int level) {
|
||||||
|
ApiScenarioModule node = new ApiScenarioModule();
|
||||||
|
node.setCreateTime(System.currentTimeMillis());
|
||||||
|
node.setUpdateTime(System.currentTimeMillis());
|
||||||
|
node.setId(UUID.randomUUID().toString());
|
||||||
|
node.setLevel(level);
|
||||||
|
node.setName(name);
|
||||||
|
node.setProjectId(projectId);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ApiScenarioModule> selectSameModule(ApiScenarioModule node) {
|
||||||
|
ApiScenarioModuleExample example = new ApiScenarioModuleExample();
|
||||||
|
ApiScenarioModuleExample.Criteria criteria = example.createCriteria();
|
||||||
|
criteria.andNameEqualTo(node.getName())
|
||||||
|
.andProjectIdEqualTo(node.getProjectId());
|
||||||
|
if (StringUtils.isNotBlank(node.getParentId())) {
|
||||||
|
criteria.andParentIdEqualTo(node.getParentId());
|
||||||
|
} else {
|
||||||
|
criteria.andParentIdIsNull();
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(node.getId())) {
|
||||||
|
criteria.andIdNotEqualTo(node.getId());
|
||||||
|
}
|
||||||
|
return apiScenarioModuleMapper.selectByExample(example);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updatePos(String id, Double pos) {
|
public void updatePos(String id, Double pos) {
|
||||||
extApiScenarioModuleMapper.updatePos(id, pos);
|
extApiScenarioModuleMapper.updatePos(id, pos);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<ms-container v-if="renderComponent">
|
<ms-container v-if="renderComponent" v-loading="loading">
|
||||||
<ms-aside-container>
|
<ms-aside-container>
|
||||||
<ms-api-scenario-module
|
<ms-api-scenario-module
|
||||||
@nodeSelectEvent="nodeChange"
|
@nodeSelectEvent="nodeChange"
|
||||||
|
@ -8,6 +8,7 @@
|
||||||
@setModuleOptions="setModuleOptions"
|
@setModuleOptions="setModuleOptions"
|
||||||
@setNodeTree="setNodeTree"
|
@setNodeTree="setNodeTree"
|
||||||
@enableTrash="enableTrash"
|
@enableTrash="enableTrash"
|
||||||
|
@exportAPI="exportAPI"
|
||||||
:type="'edit'"
|
:type="'edit'"
|
||||||
ref="nodeTree"/>
|
ref="nodeTree"/>
|
||||||
</ms-aside-container>
|
</ms-aside-container>
|
||||||
|
@ -63,10 +64,11 @@
|
||||||
import MsAsideContainer from "@/business/components/common/components/MsAsideContainer";
|
import MsAsideContainer from "@/business/components/common/components/MsAsideContainer";
|
||||||
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
|
import MsMainContainer from "@/business/components/common/components/MsMainContainer";
|
||||||
import MsApiScenarioList from "@/business/components/api/automation/scenario/ApiScenarioList";
|
import MsApiScenarioList from "@/business/components/api/automation/scenario/ApiScenarioList";
|
||||||
import {getUUID} from "@/common/js/utils";
|
import {getUUID, downloadFile} from "@/common/js/utils";
|
||||||
import MsApiScenarioModule from "@/business/components/api/automation/scenario/ApiScenarioModule";
|
import MsApiScenarioModule from "@/business/components/api/automation/scenario/ApiScenarioModule";
|
||||||
import MsEditApiScenario from "./scenario/EditApiScenario";
|
import MsEditApiScenario from "./scenario/EditApiScenario";
|
||||||
import {getCurrentProjectID} from "../../../../common/js/utils";
|
import {getCurrentProjectID} from "../../../../common/js/utils";
|
||||||
|
import {PROJECT_NAME} from "../../../../common/js/constants";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "ApiAutomation",
|
name: "ApiAutomation",
|
||||||
|
@ -101,6 +103,7 @@
|
||||||
currentModule: null,
|
currentModule: null,
|
||||||
moduleOptions: [],
|
moduleOptions: [],
|
||||||
tabs: [],
|
tabs: [],
|
||||||
|
loading: false,
|
||||||
trashEnable: false,
|
trashEnable: false,
|
||||||
selectNodeIds: [],
|
selectNodeIds: [],
|
||||||
nodeTree: []
|
nodeTree: []
|
||||||
|
@ -126,6 +129,27 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
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));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
buildApiPath(apis) {
|
||||||
|
apis.forEach((api) => {
|
||||||
|
this.moduleOptions.forEach(item => {
|
||||||
|
if (api.moduleId === item.id) {
|
||||||
|
api.modulePath = item.path;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
checkRedirectEditPage(redirectParam) {
|
checkRedirectEditPage(redirectParam) {
|
||||||
if (redirectParam != null) {
|
if (redirectParam != null) {
|
||||||
let selectParamArr = redirectParam.split("edit:");
|
let selectParamArr = redirectParam.split("edit:");
|
||||||
|
|
|
@ -138,6 +138,7 @@
|
||||||
this.$refs.apiImport.open(this.currentModule);
|
this.$refs.apiImport.open(this.currentModule);
|
||||||
break;
|
break;
|
||||||
case "export":
|
case "export":
|
||||||
|
this.$emit('exportAPI');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -35,6 +35,23 @@
|
||||||
<el-col :span="1">
|
<el-col :span="1">
|
||||||
<el-divider direction="vertical"/>
|
<el-divider direction="vertical"/>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-upload
|
||||||
|
class="api-upload"
|
||||||
|
drag
|
||||||
|
action=""
|
||||||
|
:http-request="upload"
|
||||||
|
:limit="1"
|
||||||
|
:beforeUpload="uploadValidate"
|
||||||
|
:on-remove="handleRemove"
|
||||||
|
:file-list="fileList"
|
||||||
|
:on-exceed="handleExceed"
|
||||||
|
multiple>
|
||||||
|
<i class="el-icon-upload"></i>
|
||||||
|
<div class="el-upload__text" v-html="$t('load_test.upload_tips')"></div>
|
||||||
|
<div class="el-upload__tip" slot="tip">{{ $t('api_test.api_import.file_size_limit') }}</div>
|
||||||
|
</el-upload>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
@ -182,7 +199,7 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let param = this.buildParam();
|
let param = this.buildParam();
|
||||||
this.result = this.$fileUpload('/api/definition/import', param.file, null, this.buildParam(), response => {
|
this.result = this.$fileUpload('/api/automation/import', param.file, null, this.buildParam(), response => {
|
||||||
let res = response.data;
|
let res = response.data;
|
||||||
this.$success(this.$t('test_track.case.import.success'));
|
this.$success(this.$t('test_track.case.import.success'));
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
|
|
Loading…
Reference in New Issue