Merge branch 'v1.8'

This commit is contained in:
chenjianxing 2021-03-30 16:09:27 +08:00
commit 89e28ea3df
27 changed files with 242 additions and 111 deletions

3
.gitignore vendored
View File

@ -14,7 +14,8 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
# Editor directories and files # Editor directories and files
.idea .idea/*
!.idea/icon.png
**/*.iml **/*.iml
.vscode .vscode
*.suo *.suo

BIN
.idea/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

View File

@ -283,6 +283,13 @@
<version>2.0.22</version> <version>2.0.22</version>
</dependency> </dependency>
<!-- ApacheJMeter_core scope 是 runtime这里去掉scope -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-jsr223</artifactId>
<version>2.5.10</version>
</dependency>
<!-- 执行 js 代码依赖 --> <!-- 执行 js 代码依赖 -->
<dependency> <dependency>
<groupId>org.graalvm.sdk</groupId> <groupId>org.graalvm.sdk</groupId>

View File

@ -130,7 +130,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
} }
// 1.8 之前历史数据 // 1.8 之前历史数据
if(StringUtils.isEmpty(this.getProjectId()) && config.getConfig()!= null && !config.getConfig().isEmpty()){ if (StringUtils.isEmpty(this.getProjectId()) && config.getConfig() != null && !config.getConfig().isEmpty()) {
this.setProjectId("historyProjectID"); this.setProjectId("historyProjectID");
} }
@ -154,10 +154,11 @@ public class MsHTTPSamplerProxy extends MsTestElement {
} }
URL urlObject = new URL(url); URL urlObject = new URL(url);
sampler.setDomain(URLDecoder.decode(urlObject.getHost(), "UTF-8")); sampler.setDomain(URLDecoder.decode(urlObject.getHost(), "UTF-8"));
if (urlObject.getPort() > 0 && urlObject.getPort() != 10990 && StringUtils.isNotEmpty(this.getPort()) && this.getPort().startsWith("${")) {
sampler.setPort(urlObject.getPort()); if (urlObject.getPort() > 0 && urlObject.getPort() == 10990 && StringUtils.isNotEmpty(this.getPort()) && this.getPort().startsWith("${")) {
} else {
sampler.setProperty("HTTPSampler.port", this.getPort()); sampler.setProperty("HTTPSampler.port", this.getPort());
} else {
sampler.setPort(urlObject.getPort());
} }
sampler.setProtocol(urlObject.getProtocol()); sampler.setProtocol(urlObject.getProtocol());
sampler.setPath(urlObject.getPath()); sampler.setPath(urlObject.getPath());

View File

@ -21,10 +21,7 @@ import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.jmeter.JMeterService;
import io.metersphere.api.parse.ApiImportParser; import io.metersphere.api.parse.ApiImportParser;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.ApiScenarioMapper; import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ApiScenarioReportMapper;
import io.metersphere.base.mapper.TestCaseReviewScenarioMapper;
import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
import io.metersphere.base.mapper.ext.*; import io.metersphere.base.mapper.ext.*;
import io.metersphere.commons.constants.*; import io.metersphere.commons.constants.*;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
@ -61,6 +58,8 @@ import java.util.stream.Collectors;
@Service @Service
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public class ApiAutomationService { public class ApiAutomationService {
@Resource
ApiScenarioModuleMapper apiScenarioModuleMapper;
@Resource @Resource
private ExtScheduleMapper extScheduleMapper; private ExtScheduleMapper extScheduleMapper;
@Resource @Resource
@ -242,9 +241,14 @@ public class ApiAutomationService {
} else { } else {
scenario.setUserId(request.getUserId()); scenario.setUserId(request.getUserId());
} }
if (StringUtils.isEmpty(request.getApiScenarioModuleId()) || StringUtils.isEmpty(request.getModulePath())) { if (StringUtils.isEmpty(request.getApiScenarioModuleId()) || StringUtils.isEmpty(request.getModulePath()) || "default-module".equals(request.getApiScenarioModuleId())) {
scenario.setApiScenarioModuleId("default-module"); ApiScenarioModuleExample example = new ApiScenarioModuleExample();
scenario.setModulePath("/默认模块"); example.createCriteria().andProjectIdEqualTo(request.getProjectId()).andNameEqualTo("默认模块");
List<ApiScenarioModule> modules = apiScenarioModuleMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(modules)) {
scenario.setApiScenarioModuleId(modules.get(0).getId());
scenario.setModulePath(modules.get(0).getName());
}
} }
return scenario; return scenario;
} }

View File

@ -94,6 +94,8 @@ public class ApiDefinitionService {
private ApiTestEnvironmentService environmentService; private ApiTestEnvironmentService environmentService;
@Resource @Resource
private EsbApiParamService esbApiParamService; private EsbApiParamService esbApiParamService;
@Resource
ApiModuleMapper apiModuleMapper;
private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24); private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24);
@ -262,9 +264,14 @@ public class ApiDefinitionService {
test.setEnvironmentId(request.getEnvironmentId()); test.setEnvironmentId(request.getEnvironmentId());
test.setUserId(request.getUserId()); test.setUserId(request.getUserId());
test.setTags(request.getTags()); test.setTags(request.getTags());
if (StringUtils.isEmpty(request.getModulePath()) || StringUtils.isEmpty(request.getModuleId())) { if (StringUtils.isEmpty(request.getModulePath()) || StringUtils.isEmpty(request.getModuleId()) || "default-module".equals(request.getModuleId())) {
test.setModulePath("/默认模块"); ApiModuleExample example = new ApiModuleExample();
test.setModuleId("default-module"); example.createCriteria().andProjectIdEqualTo(test.getProjectId()).andProtocolEqualTo(test.getProtocol()).andNameEqualTo("默认模块");
List<ApiModule> modules = apiModuleMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(modules)) {
test.setModuleId(modules.get(0).getId());
test.setModulePath(modules.get(0).getName());
}
} }
apiDefinitionMapper.updateByPrimaryKeySelective(test); apiDefinitionMapper.updateByPrimaryKeySelective(test);
return test; return test;
@ -290,9 +297,14 @@ public class ApiDefinitionService {
test.setStatus(APITestStatus.Underway.name()); test.setStatus(APITestStatus.Underway.name());
test.setModulePath(request.getModulePath()); test.setModulePath(request.getModulePath());
test.setModuleId(request.getModuleId()); test.setModuleId(request.getModuleId());
if (StringUtils.isEmpty(request.getModulePath()) || StringUtils.isEmpty(request.getModuleId())) { if (StringUtils.isEmpty(request.getModulePath()) || StringUtils.isEmpty(request.getModuleId()) || "default-module".equals(request.getModuleId())) {
test.setModulePath("/默认模块"); ApiModuleExample example = new ApiModuleExample();
test.setModuleId("default-module"); example.createCriteria().andProjectIdEqualTo(test.getProjectId()).andProtocolEqualTo(test.getProtocol()).andNameEqualTo("默认模块");
List<ApiModule> modules = apiModuleMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(modules)) {
test.setModuleId(modules.get(0).getId());
test.setModulePath("/默认模块");
}
} }
test.setResponse(JSONObject.toJSONString(request.getResponse())); test.setResponse(JSONObject.toJSONString(request.getResponse()));
test.setEnvironmentId(request.getEnvironmentId()); test.setEnvironmentId(request.getEnvironmentId());
@ -604,9 +616,14 @@ public class ApiDefinitionService {
} }
for (int i = 0; i < data.size(); i++) { for (int i = 0; i < data.size(); i++) {
ApiDefinitionWithBLOBs item = data.get(i); ApiDefinitionWithBLOBs item = data.get(i);
if (StringUtils.isEmpty(item.getModuleId()) || StringUtils.isEmpty(item.getModulePath())) { if (StringUtils.isEmpty(item.getModuleId()) || StringUtils.isEmpty(item.getModulePath()) || "default-module".equals(item.getModuleId())) {
item.setModuleId("default-module"); ApiModuleExample example = new ApiModuleExample();
item.setModulePath("/默认模块"); example.createCriteria().andProjectIdEqualTo(item.getProjectId()).andProtocolEqualTo(item.getProtocol()).andNameEqualTo("默认模块");
List<ApiModule> modules = apiModuleMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(modules)) {
item.setModuleId(modules.get(0).getId());
item.setModulePath(modules.get(0).getName());
}
} }
if (item.getName().length() > 255) { if (item.getName().length() > 255) {
item.setName(item.getName().substring(0, 255)); item.setName(item.getName().substring(0, 255));

View File

@ -39,8 +39,6 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
@Resource @Resource
ExtApiModuleMapper extApiModuleMapper; ExtApiModuleMapper extApiModuleMapper;
@Resource @Resource
private ApiDefinitionMapper apiDefinitionMapper;
@Resource
private ExtApiDefinitionMapper extApiDefinitionMapper; private ExtApiDefinitionMapper extApiDefinitionMapper;
@Resource @Resource
private TestPlanProjectService testPlanProjectService; private TestPlanProjectService testPlanProjectService;
@ -61,6 +59,22 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
} }
public List<ApiModuleDTO> getNodeTreeByProjectId(String projectId, String protocol) { public List<ApiModuleDTO> getNodeTreeByProjectId(String projectId, String protocol) {
// 判断当前项目下是否有默认模块没有添加默认模块
ApiModuleExample example = new ApiModuleExample();
example.createCriteria().andProjectIdEqualTo(projectId).andProtocolEqualTo(protocol).andNameEqualTo("默认模块");
long count = apiModuleMapper.countByExample(example);
if (count <= 0) {
ApiModule record = new ApiModule();
record.setId(UUID.randomUUID().toString());
record.setName("默认模块");
record.setProtocol(protocol);
record.setPos(1.0);
record.setLevel(1);
record.setCreateTime(System.currentTimeMillis());
record.setUpdateTime(System.currentTimeMillis());
record.setProjectId(projectId);
apiModuleMapper.insert(record);
}
List<ApiModuleDTO> apiModules = extApiModuleMapper.getNodeTreeByProjectId(projectId, protocol); List<ApiModuleDTO> apiModules = extApiModuleMapper.getNodeTreeByProjectId(projectId, protocol);
return getNodeTrees(apiModules); return getNodeTrees(apiModules);
} }

View File

@ -53,6 +53,22 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
} }
public List<ApiScenarioModuleDTO> getNodeTreeByProjectId(String projectId) { public List<ApiScenarioModuleDTO> getNodeTreeByProjectId(String projectId) {
// 判断当前项目下是否有默认模块没有添加默认模块
ApiScenarioModuleExample example = new ApiScenarioModuleExample();
example.createCriteria().andProjectIdEqualTo(projectId).andNameEqualTo("默认模块");
long count = apiScenarioModuleMapper.countByExample(example);
if (count <= 0) {
ApiScenarioModule record = new ApiScenarioModule();
record.setId(UUID.randomUUID().toString());
record.setName("默认模块");
record.setPos(1.0);
record.setLevel(1);
record.setCreateTime(System.currentTimeMillis());
record.setUpdateTime(System.currentTimeMillis());
record.setProjectId(projectId);
apiScenarioModuleMapper.insert(record);
}
List<ApiScenarioModuleDTO> nodes = extApiScenarioModuleMapper.getNodeTreeByProjectId(projectId); List<ApiScenarioModuleDTO> nodes = extApiScenarioModuleMapper.getNodeTreeByProjectId(projectId);
return getNodeTrees(nodes); return getNodeTrees(nodes);
} }

View File

@ -701,9 +701,11 @@ public class JmeterDocumentParser implements DocumentParser {
switch (unit) { switch (unit) {
case "M": case "M":
duration = String.valueOf(Long.parseLong(duration) * 60); duration = String.valueOf(Long.parseLong(duration) * 60);
rampUp = String.valueOf(Long.parseLong(rampUp) * 60);
break; break;
case "H": case "H":
duration = String.valueOf(Long.parseLong(duration) * 60 * 60); duration = String.valueOf(Long.parseLong(duration) * 60 * 60);
rampUp = String.valueOf(Long.parseLong(rampUp) * 60 * 60);
break; break;
default: default:
break; break;
@ -804,9 +806,11 @@ public class JmeterDocumentParser implements DocumentParser {
switch (unit) { switch (unit) {
case "M": case "M":
hold = String.valueOf(Long.parseLong(hold) * 60); hold = String.valueOf(Long.parseLong(hold) * 60);
rampUp = String.valueOf(Long.parseLong(rampUp) * 60);
break; break;
case "H": case "H":
hold = String.valueOf(Long.parseLong(hold) * 60 * 60); hold = String.valueOf(Long.parseLong(hold) * 60 * 60);
rampUp = String.valueOf(Long.parseLong(rampUp) * 60 * 60);
break; break;
default: default:
break; break;

View File

@ -107,6 +107,21 @@ public class TestCaseNodeService extends NodeTreeService<TestCaseNodeDTO> {
} }
public List<TestCaseNodeDTO> getNodeTreeByProjectId(String projectId) { public List<TestCaseNodeDTO> getNodeTreeByProjectId(String projectId) {
// 判断当前项目下是否有默认模块没有添加默认模块
TestCaseNodeExample example = new TestCaseNodeExample();
example.createCriteria().andProjectIdEqualTo(projectId).andNameEqualTo("默认模块");
long count = testCaseNodeMapper.countByExample(example);
if (count <= 0) {
TestCaseNode record = new TestCaseNode();
record.setId(UUID.randomUUID().toString());
record.setName("默认模块");
record.setPos(1.0);
record.setLevel(1);
record.setCreateTime(System.currentTimeMillis());
record.setUpdateTime(System.currentTimeMillis());
record.setProjectId(projectId);
testCaseNodeMapper.insert(record);
}
List<TestCaseNodeDTO> testCaseNodes = extTestCaseNodeMapper.getNodeTreeByProjectId(projectId); List<TestCaseNodeDTO> testCaseNodes = extTestCaseNodeMapper.getNodeTreeByProjectId(projectId);
return getNodeTrees(testCaseNodes); return getNodeTrees(testCaseNodes);
} }

View File

@ -52,6 +52,8 @@ import java.util.stream.Collectors;
@Service @Service
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public class TestCaseService { public class TestCaseService {
@Resource
TestCaseNodeMapper testCaseNodeMapper;
@Resource @Resource
TestCaseMapper testCaseMapper; TestCaseMapper testCaseMapper;
@ -90,6 +92,18 @@ public class TestCaseService {
@Resource @Resource
TestCaseTestMapper testCaseTestMapper; TestCaseTestMapper testCaseTestMapper;
private void setNode(TestCaseWithBLOBs testCase){
if (StringUtils.isEmpty(testCase.getNodeId()) || StringUtils.isEmpty(testCase.getNodePath()) || "default-module".equals(testCase.getNodeId())) {
TestCaseNodeExample example = new TestCaseNodeExample();
example.createCriteria().andProjectIdEqualTo(testCase.getProjectId()).andNameEqualTo("默认模块");
List<TestCaseNode> nodes = testCaseNodeMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(nodes)) {
testCase.setNodeId(nodes.get(0).getId());
testCase.setNodePath("/" + nodes.get(0).getName());
}
}
}
public TestCaseWithBLOBs addTestCase(TestCaseWithBLOBs testCase) { public TestCaseWithBLOBs addTestCase(TestCaseWithBLOBs testCase) {
testCase.setName(testCase.getName()); testCase.setName(testCase.getName());
checkTestCaseExist(testCase); checkTestCaseExist(testCase);
@ -100,7 +114,7 @@ public class TestCaseService {
testCase.setReviewStatus(TestCaseReviewStatus.Prepare.name()); testCase.setReviewStatus(TestCaseReviewStatus.Prepare.name());
testCase.setDemandId(testCase.getDemandId()); testCase.setDemandId(testCase.getDemandId());
testCase.setDemandName(testCase.getDemandName()); testCase.setDemandName(testCase.getDemandName());
this.setNode(testCase);
testCaseMapper.insert(testCase); testCaseMapper.insert(testCase);
return testCase; return testCase;
} }
@ -179,7 +193,7 @@ public class TestCaseService {
String steps = tc.getSteps(); String steps = tc.getSteps();
String remark = tc.getRemark(); String remark = tc.getRemark();
if (StringUtils.equals(steps, testCase.getSteps()) && StringUtils.equals(remark, caseRemark)) { if (StringUtils.equals(steps, testCase.getSteps()) && StringUtils.equals(remark, caseRemark)) {
//MSException.throwException(Translator.get("test_case_already_exists")); //MSException.throwException(Translator.get("test_case_already_exists"));
isExt = true; isExt = true;
} }
} }
@ -195,16 +209,16 @@ public class TestCaseService {
* 根据id和pojectId查询id是否在数据库中存在 * 根据id和pojectId查询id是否在数据库中存在
* 在数据库中单id的话是可重复的,id与projectId的组合是唯一的 * 在数据库中单id的话是可重复的,id与projectId的组合是唯一的
*/ */
public Integer checkIdExist(Integer id, String projectId){ public Integer checkIdExist(Integer id, String projectId) {
TestCaseExample example = new TestCaseExample(); TestCaseExample example = new TestCaseExample();
TestCaseExample.Criteria criteria = example.createCriteria(); TestCaseExample.Criteria criteria = example.createCriteria();
if (null != id) { if (null != id) {
criteria.andNumEqualTo(id); criteria.andNumEqualTo(id);
criteria.andProjectIdEqualTo(projectId); criteria.andProjectIdEqualTo(projectId);
long count = testCaseMapper.countByExample(example); //查询是否有包含此ID的数据 long count = testCaseMapper.countByExample(example); //查询是否有包含此ID的数据
if(count == 0){ //如果ID不存在 if (count == 0) { //如果ID不存在
return null; return null;
}else { //有对应ID的数据 } else { //有对应ID的数据
return id; return id;
} }
} }
@ -415,7 +429,7 @@ public class TestCaseService {
testcase.setSort(sort.getAndIncrement()); testcase.setSort(sort.getAndIncrement());
testcase.setNum(num.decrementAndGet()); testcase.setNum(num.decrementAndGet());
testcase.setReviewStatus(TestCaseReviewStatus.Prepare.name()); testcase.setReviewStatus(TestCaseReviewStatus.Prepare.name());
mapper.insert(testcase); mapper.insert(testcase);
}); });
} }
sqlSession.flushStatements(); sqlSession.flushStatements();
@ -443,6 +457,7 @@ public class TestCaseService {
/** /**
* 把Excel中带ID的数据更新到数据库 * 把Excel中带ID的数据更新到数据库
*
* @param testCases * @param testCases
* @param projectId * @param projectId
*/ */
@ -821,14 +836,14 @@ public class TestCaseService {
if (files != null) { if (files != null) {
files.forEach(file -> { files.forEach(file -> {
final FileMetadata fileMetadata = fileService.saveFile(file,testCaseWithBLOBs.getProjectId()); final FileMetadata fileMetadata = fileService.saveFile(file, testCaseWithBLOBs.getProjectId());
TestCaseFile testCaseFile = new TestCaseFile(); TestCaseFile testCaseFile = new TestCaseFile();
testCaseFile.setFileId(fileMetadata.getId()); testCaseFile.setFileId(fileMetadata.getId());
testCaseFile.setCaseId(request.getId()); testCaseFile.setCaseId(request.getId());
testCaseFileMapper.insert(testCaseFile); testCaseFileMapper.insert(testCaseFile);
}); });
} }
this.setNode(request);
editTestCase(request); editTestCase(request);
return request.getId(); return request.getId();
} }

View File

@ -24,6 +24,7 @@ import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -34,6 +35,10 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager; import javax.script.ScriptEngineManager;
import javax.script.ScriptException; import javax.script.ScriptException;
import io.metersphere.base.domain.JarConfig;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.service.JarConfigService;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.map.LRUMap; import org.apache.commons.collections.map.LRUMap;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -45,9 +50,11 @@ import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterContextService; import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterVariables; import org.apache.jmeter.threads.JMeterVariables;
import org.apache.jorphan.util.JOrphanUtils; import org.apache.jorphan.util.JOrphanUtils;
import org.codehaus.groovy.jsr223.GroovyScriptEngineImpl;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* Base class for JSR223 Test elements * Base class for JSR223 Test elements
* *
@ -166,6 +173,9 @@ public abstract class JSR223TestElement extends ScriptingTestElement
*/ */
protected Object processFileOrScript(ScriptEngine scriptEngine, final Bindings pBindings) protected Object processFileOrScript(ScriptEngine scriptEngine, final Bindings pBindings)
throws IOException, ScriptException { throws IOException, ScriptException {
this.loadGroovyJar(scriptEngine);
Bindings bindings = pBindings; Bindings bindings = pBindings;
if (bindings == null) { if (bindings == null) {
bindings = scriptEngine.createBindings(); bindings = scriptEngine.createBindings();
@ -250,6 +260,37 @@ public abstract class JSR223TestElement extends ScriptingTestElement
} }
} }
/**
* groovy 使用的是自己的类加载器
* 这里再执行脚本前使用 groovy的加载器加载jar包
* 解决groovy脚本无法使用jar包的问题
* @Auth jianxing
* @param scriptEngine
*/
public static void loadGroovyJar(ScriptEngine scriptEngine) {
if (scriptEngine instanceof GroovyScriptEngineImpl) {
GroovyScriptEngineImpl groovyScriptEngine = (GroovyScriptEngineImpl) scriptEngine;
JarConfigService jarConfigService = CommonBeanFactory.getBean(JarConfigService.class);
List<JarConfig> jars = jarConfigService.list();
jars.forEach(jarConfig -> {
try {
String path = jarConfig.getPath();
File file = new File(path);
if (file.isDirectory() && !path.endsWith("/")) {
file = new File(path + "/");
}
groovyScriptEngine.getClassLoader().addURL(file.toURI().toURL());
} catch (Exception e) {
e.printStackTrace();
LogUtil.error(e.getMessage(), e);
}
});
}
}
/** /**
* @return boolean true if element is not compilable or if compilation succeeds * @return boolean true if element is not compilable or if compilation succeeds
* @throws IOException if script is missing * @throws IOException if script is missing
@ -351,4 +392,4 @@ public abstract class JSR223TestElement extends ScriptingTestElement
public void setScriptLanguage(String s) { public void setScriptLanguage(String s) {
scriptLanguage = s; scriptLanguage = s;
} }
} }

View File

@ -0,0 +1,5 @@
-- file name length change
ALTER TABLE file_metadata
MODIFY name VARCHAR(250) NOT NULL COMMENT 'File name';
-- api_scenario_report modify column length
ALTER TABLE api_scenario_report MODIFY COLUMN name VARCHAR(300);

View File

@ -190,13 +190,17 @@
this.activeName = name; this.activeName = name;
let currentScenario = { let currentScenario = {
status: "Underway", principal: getCurrentUser().id, status: "Underway", principal: getCurrentUser().id,
apiScenarioModuleId: "root", id: getUUID(), apiScenarioModuleId: "default-module", id: getUUID(),
modulePath: "/" + this.$t("commons.module_title") modulePath: "/" + this.$t("commons.module_title")
}; };
if (this.nodeTree && this.nodeTree.length > 0) { if (this.nodeTree && this.nodeTree.length > 0) {
currentScenario.apiScenarioModuleId = this.nodeTree[0].id; currentScenario.apiScenarioModuleId = this.nodeTree[0].id;
currentScenario.modulePath = this.nodeTree[0].path; currentScenario.modulePath = this.nodeTree[0].path;
} }
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
currentScenario.apiScenarioModuleId = this.selectNodeIds[0];
}
this.tabs.push({label: label, name: name, currentScenario: currentScenario}); this.tabs.push({label: label, name: name, currentScenario: currentScenario});
} }
if (tab.name === 'edit') { if (tab.name === 'edit') {

View File

@ -117,6 +117,9 @@
if (this.currentModule && this.currentModule.id != "root") { if (this.currentModule && this.currentModule.id != "root") {
this.scenarioForm.modulePath = this.currentModule.method !== undefined ? this.currentModule.method : null; this.scenarioForm.modulePath = this.currentModule.method !== undefined ? this.currentModule.method : null;
this.scenarioForm.apiScenarioModuleId = this.currentModule.id; this.scenarioForm.apiScenarioModuleId = this.currentModule.id;
}else{
this.scenarioForm.modulePath = this.$t("commons.module_title");
this.scenarioForm.apiScenarioModuleId = "default-module";
} }
}, },
getMaintainerOptions() { getMaintainerOptions() {

View File

@ -29,7 +29,7 @@
@refresh="refresh" @refresh="refresh"
ref="basisScenario"/> ref="basisScenario"/>
<api-import ref="apiImport" :moduleOptions="extendTreeNodes" @refreshAll="$emit('refreshAll')"/> <api-import ref="apiImport" :moduleOptions="data" @refreshAll="$emit('refreshAll')"/>
</div> </div>
</template> </template>
@ -82,9 +82,7 @@
trashEnable: false trashEnable: false
}, },
data: [], data: [],
extendTreeNodes: [],
currentModule: undefined, currentModule: undefined,
moduleOptions: [],
operators: [ operators: [
{ {
label: this.$t('api_test.automation.add_scenario'), label: this.$t('api_test.automation.add_scenario'),
@ -141,11 +139,9 @@
this.result = this.$get("/api/automation/module/list/" + this.projectId, response => { this.result = this.$get("/api/automation/module/list/" + this.projectId, response => {
if (response.data != undefined && response.data != null) { if (response.data != undefined && response.data != null) {
this.data = response.data; this.data = response.data;
let moduleOptions = [];
this.data.forEach(node => { this.data.forEach(node => {
buildNodePath(node, {path: ''}, moduleOptions); buildTree(node, {path: ''});
}); });
this.moduleOptions = moduleOptions
} }
}); });
this.$refs.apiImport.open(this.currentModule); this.$refs.apiImport.open(this.currentModule);
@ -163,11 +159,9 @@
this.result = this.$get("/api/automation/module/list/" + this.projectId, response => { this.result = this.$get("/api/automation/module/list/" + this.projectId, response => {
if (response.data != undefined && response.data != null) { if (response.data != undefined && response.data != null) {
this.data = response.data; this.data = response.data;
let moduleOptions = [];
this.data.forEach(node => { this.data.forEach(node => {
buildNodePath(node, {path: ''}, moduleOptions); buildTree(node, {path: ''});
}); });
this.moduleOptions = moduleOptions
} }
}); });
this.$refs.apiImport.open(this.currentModule); this.$refs.apiImport.open(this.currentModule);
@ -188,17 +182,10 @@
this.result = this.$get(url, response => { this.result = this.$get(url, response => {
if (response.data != undefined && response.data != null) { if (response.data != undefined && response.data != null) {
this.data = response.data; this.data = response.data;
this.extendTreeNodes = []; this.data.forEach(node => {
this.extendTreeNodes.unshift({
"id": "root",
"name": this.$t('commons.module_title'),
"level": 0,
"children": this.data,
});
this.extendTreeNodes.forEach(node => {
buildTree(node, {path: ''}); buildTree(node, {path: ''});
}); });
this.$emit('setModuleOptions', this.extendTreeNodes); this.$emit('setModuleOptions', this.data);
this.$emit('setNodeTree', this.data); this.$emit('setNodeTree', this.data);
if (this.$refs.nodeTree) { if (this.$refs.nodeTree) {
this.$refs.nodeTree.filter(this.condition.filterText); this.$refs.nodeTree.filter(this.condition.filterText);

View File

@ -84,7 +84,7 @@
callback(); callback();
}; };
return { return {
httpForm: {environmentId: "", moduleId: "root"}, httpForm: {environmentId: "", moduleId: "default-module"},
moduleOptions: [], moduleOptions: [],
httpVisible: false, httpVisible: false,
currentModule: {}, currentModule: {},
@ -251,14 +251,7 @@
let url = "/api/module/list/" + getCurrentProjectID() + "/" + data.protocol; let url = "/api/module/list/" + getCurrentProjectID() + "/" + data.protocol;
this.result = this.$get(url, response => { this.result = this.$get(url, response => {
if (response.data != undefined && response.data != null) { if (response.data != undefined && response.data != null) {
let data = response.data; this.moduleOptions = response.data;
this.moduleOptions = [];
this.moduleOptions.unshift({
"id": "root",
"name": this.$t('commons.module_title'),
"level": 0,
"children": data,
});
this.moduleOptions.forEach(node => { this.moduleOptions.forEach(node => {
buildTree(node, {path: ''}); buildTree(node, {path: ''});
}); });
@ -282,7 +275,7 @@
data.protocol = "DUBBO"; data.protocol = "DUBBO";
} }
data.id = getUUID(); data.id = getUUID();
this.httpForm = {id: data.id, name: data.name, protocol: data.protocol, path: data.path, method: api.method, userId: getCurrentUser().id, request: data, moduleId: "root"}; this.httpForm = {id: data.id, name: data.name, protocol: data.protocol, path: data.path, method: api.method, userId: getCurrentUser().id, request: data, moduleId: "default-module"};
this.getMaintainerOptions(); this.getMaintainerOptions();
this.list(data); this.list(data);
this.httpVisible = true; this.httpVisible = true;

View File

@ -32,7 +32,7 @@
</el-tooltip> </el-tooltip>
<slot name="button"></slot> <slot name="button"></slot>
<el-tooltip content="Copy" placement="top"> <el-tooltip content="Copy" placement="top">
<el-button size="mini" icon="el-icon-copy-document" circle @click="copyRow" style="padding: 5px"/> <el-button size="mini" icon="el-icon-copy-document" circle @click="copyRow" style="padding: 5px" :disabled="data.disabled && !data.root"/>
</el-tooltip> </el-tooltip>
<step-extend-btns style="display: contents" :data="data" @copy="copyRow" @remove="remove" @openScenario="openScenario" v-if="showBtn && (!data.disabled || data.root)"/> <step-extend-btns style="display: contents" :data="data" @copy="copyRow" @remove="remove" @openScenario="openScenario" v-if="showBtn && (!data.disabled || data.root)"/>
</div> </div>

View File

@ -302,6 +302,9 @@
api.moduleId = this.nodeTree[0].id; api.moduleId = this.nodeTree[0].id;
api.modulePath = this.nodeTree[0].path; api.modulePath = this.nodeTree[0].path;
} }
if (this.selectNodeIds && this.selectNodeIds.length > 0) {
api.moduleId = this.selectNodeIds[0];
}
this.handleTabsEdit(this.$t('api_test.definition.request.title'), e, api); this.handleTabsEdit(this.$t('api_test.definition.request.title'), e, api);
}, },
handleTabClose() { handleTabClose() {

View File

@ -154,6 +154,9 @@
if (this.currentModule != null) { if (this.currentModule != null) {
this.httpForm.modulePath = this.currentModule.method != undefined ? this.currentModule.method : null; this.httpForm.modulePath = this.currentModule.method != undefined ? this.currentModule.method : null;
this.httpForm.moduleId = this.currentModule.id; this.httpForm.moduleId = this.currentModule.id;
} else {
this.httpForm.modulePath = this.$t("commons.module_title");
this.httpForm.moduleId = "default-module";
} }
}, },

View File

@ -130,13 +130,6 @@
this.result = this.$get(url, response => { this.result = this.$get(url, response => {
if (response.data != undefined && response.data != null) { if (response.data != undefined && response.data != null) {
this.data = response.data; this.data = response.data;
this.data.unshift({
"id": "default-module",
"name": this.$t('commons.module_title'),
"level": 0,
"path": "/" + this.$t('commons.module_title'),
"children": [],
});
this.data.forEach(node => { this.data.forEach(node => {
buildTree(node, {path: ''}); buildTree(node, {path: ''});
}); });

View File

@ -154,35 +154,39 @@ export default {
} }
let rows = this.existFiles.filter(f => this.selectIds.has(f.id)); let rows = this.existFiles.filter(f => this.selectIds.has(f.id));
let jmxIds = [];
for (let i = 0; i < rows.length; i++) { for (let i = 0; i < rows.length; i++) {
let row = rows[i]; let row = rows[i];
if (this.tableData.filter(f => f.name === row.name).length > 0) { if (this.tableData.filter(f => f.name === row.name).length > 0) {
this.$error(this.$t('load_test.delete_file') + ', name: ' + row.name); setTimeout(() => {
this.selectIds.clear(); this.$warning(this.$t('load_test.delete_file') + 'name: ' + row.name);
return; }, 100);
continue;
} }
if (row.type.toUpperCase() === 'JMX') {
jmxIds.push(row.id);
}
this.tableData.push({
name: row.name,
size: (row.size / 1024).toFixed(2) + ' KB',
type: row.type.toUpperCase(),
updateTime: row.lastModified,
});
} }
if (this.loadType === 'resource') { if (this.loadType === 'resource') {
rows.forEach(row => { rows.forEach(row => {
this.fileList.push(row); this.fileList.push(row);
this.tableData.push({
name: row.name,
size: (row.size / 1024).toFixed(2) + ' KB',
type: row.type.toUpperCase(),
updateTime: row.lastModified,
});
}) })
this.$success(this.$t('test_track.case.import.success')); this.$success(this.$t('test_track.case.import.success'));
this.loadFileVisible = false; this.close();
this.selectIds.clear();
return; return;
} }
this.getJmxContents(); this.getJmxContents(jmxIds);
}, },
getJmxContents() { getJmxContents(jmxIds) {
this.projectLoadingResult = this.$post('/performance/export/jmx', [...this.selectIds], (response) => { this.projectLoadingResult = this.$post('/performance/export/jmx', jmxIds, (response) => {
let data = response.data; let data = response.data;
if (!data) { if (!data) {
return; return;
@ -195,18 +199,11 @@ export default {
}); });
let file = new File([d.jmx], d.name); let file = new File([d.jmx], d.name);
this.uploadList.push(file); this.uploadList.push(file);
this.tableData.push({
name: file.name,
size: (file.size / 1024).toFixed(2) + ' KB',
type: 'JMX',
updateTime: file.lastModified,
});
}); });
this.$emit('fileChange', this.scenarios); this.$emit('fileChange', this.scenarios);
this.$success(this.$t('test_track.case.import.success')); this.$success(this.$t('test_track.case.import.success'));
this.loadFileVisible = false; this.close();
this.selectIds.clear();
}); });
}, },
beforeUploadFile(file) { beforeUploadFile(file) {

View File

@ -114,8 +114,8 @@ export default {
this.testCaseForm.nodePath = this.currentModule.path; this.testCaseForm.nodePath = this.currentModule.path;
this.testCaseForm.nodeId = this.currentModule.id; this.testCaseForm.nodeId = this.currentModule.id;
} else { } else {
this.testCaseForm.nodePath = "/全部用例" this.testCaseForm.nodePath = "/默认模块"
this.testCaseForm.nodeId = "root" this.testCaseForm.nodeId = "default-module"
} }
this.result = this.$post(path, this.testCaseForm, response => { this.result = this.$post(path, this.testCaseForm, response => {
this.testCaseForm.id = response.data.id this.testCaseForm.id = response.data.id

View File

@ -35,7 +35,7 @@
<el-col :span="7"> <el-col :span="7">
<el-form-item :label="$t('test_track.case.module')" :label-width="formLabelWidth" prop="module"> <el-form-item :label="$t('test_track.case.module')" :label-width="formLabelWidth" prop="module">
<ms-select-tree :disabled="readOnly" :data="moduleOptions" :defaultKey="form.module" :obj="moduleObj" <ms-select-tree :disabled="readOnly" :data="treeNodes" :defaultKey="form.module" :obj="moduleObj"
@getValue="setModule" clearable checkStrictly size="small" /> @getValue="setModule" clearable checkStrictly size="small" />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -314,8 +314,8 @@ export default {
dialogFormVisible: false, dialogFormVisible: false,
form: { form: {
name: '', name: '',
module: 'root', module: 'default-module',
nodePath:'', nodePath:'/默认模块',
maintainer: getCurrentUser().id, maintainer: getCurrentUser().id,
priority: 'P0', priority: 'P0',
type: '', type: '',
@ -416,7 +416,7 @@ export default {
}; };
}); });
}, 1000); }, 1000);
if(this.selectNode && this.selectNode.data){ if(this.selectNode && this.selectNode.data && !this.form.id){
this.form.module = this.selectNode.data.id; this.form.module = this.selectNode.data.id;
this.form.nodePath = this.selectNode.data.path; this.form.nodePath = this.selectNode.data.path;
} }
@ -432,7 +432,16 @@ export default {
created() { created() {
this.loadOptions(); this.loadOptions();
this.addListener(); // ctrl s this.addListener(); // ctrl s
if(this.selectNode && this.selectNode.data && !this.form.id){
this.form.module = this.selectNode.data.id;
this.form.nodePath = this.selectNode.data.path;
}else{
this.form.module =this.treeNodes && this.length>0? this.treeNodes[0].id:"";
}
if (this.type === 'edit' || this.type === 'copy') {
this.form.module = this.currentTestCaseInfo.nodeId;
this.form.nodePath = this.currentTestCaseInfo.nodePath;
}
}, },
methods: { methods: {
setModule(id,data) { setModule(id,data) {
@ -836,16 +845,11 @@ export default {
this.getTestOptions() this.getTestOptions()
}, },
getModuleOptions() { getModuleOptions() {
this.moduleOptions = []; let moduleOptions = [];
this.moduleOptions.unshift({ this.treeNodes.forEach(node => {
"id": "root", buildNodePath(node, {path: ''}, moduleOptions);
"name": this.$t('commons.module_title'),
"level": 0,
"children": this.treeNodes,
});
this.moduleOptions.forEach(node => {
buildTree(node, {path: ''});
}); });
this.moduleOptions = moduleOptions;
}, },
getMaintainerOptions() { getMaintainerOptions() {
let workspaceId = localStorage.getItem(WORKSPACE_ID); let workspaceId = localStorage.getItem(WORKSPACE_ID);

View File

@ -32,7 +32,7 @@
<span v-if="!disabled" class="node-operate child"> <span v-if="!disabled" class="node-operate child">
<el-tooltip <el-tooltip
v-if="data.id != 'root'" v-if="data.id != 'root' && data.name !='默认模块'"
class="item" class="item"
effect="dark" effect="dark"
:open-delay="200" :open-delay="200"
@ -49,7 +49,7 @@
<i @click.stop="append(node, data)" class="el-icon-circle-plus-outline"></i> <i @click.stop="append(node, data)" class="el-icon-circle-plus-outline"></i>
</el-tooltip> </el-tooltip>
<el-tooltip <el-tooltip
v-if="data.id != 'root'" v-if="data.id != 'root' && data.name !='默认模块'"
class="item" effect="dark" class="item" effect="dark"
:open-delay="200" :open-delay="200"
:content="$t('commons.delete')" :content="$t('commons.delete')"
@ -230,7 +230,7 @@ export default {
if (dropType === "none" || dropType === undefined) { if (dropType === "none" || dropType === undefined) {
return; return;
} }
if (dropNode.data.id === 'root' && dropType === 'before') { if (dropNode.data.id === 'root' && dropType === 'before' || draggingNode.data.name==='默认模块') {
this.$emit('refresh'); this.$emit('refresh');
return false; return false;
} }

View File

@ -37,6 +37,7 @@ import MsNodeTree from "./NodeTree";
import TestCaseCreate from "@/business/components/track/case/components/TestCaseCreate"; import TestCaseCreate from "@/business/components/track/case/components/TestCaseCreate";
import TestCaseImport from "@/business/components/track/case/components/TestCaseImport"; import TestCaseImport from "@/business/components/track/case/components/TestCaseImport";
import MsSearchBar from "@/business/components/common/components/search/MsSearchBar"; import MsSearchBar from "@/business/components/common/components/search/MsSearchBar";
import {buildTree} from "../../api/definition/model/NodeTree";
export default { export default {
name: "TestCaseNodeTree", name: "TestCaseNodeTree",
@ -115,6 +116,9 @@ export default {
if (this.projectId) { if (this.projectId) {
this.result = this.$get("/case/node/list/" + this.projectId, response => { this.result = this.$get("/case/node/list/" + this.projectId, response => {
this.treeNodes = response.data; this.treeNodes = response.data;
this.treeNodes.forEach(node => {
buildTree(node, {path: ''});
});
if (this.$refs.nodeTree) { if (this.$refs.nodeTree) {
this.$refs.nodeTree.filter(); this.$refs.nodeTree.filter();
} }

@ -1 +1 @@
Subproject commit 2115bd28a90854d2b6276a90878934715498c584 Subproject commit 07951ba17aef6f29e50cfd68e40de3266f9a60cd