Merge remote-tracking branch 'origin/master'
# Conflicts: # backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java
This commit is contained in:
commit
7e7433f801
|
@ -11,6 +11,7 @@ import io.metersphere.api.service.ApiAutomationService;
|
|||
import io.metersphere.base.domain.ApiScenario;
|
||||
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
|
@ -102,12 +103,16 @@ public class ApiAutomationController {
|
|||
@PostMapping(value = "/run")
|
||||
public String run(@RequestBody RunScenarioRequest request) {
|
||||
request.setExecuteType(ExecuteType.Completed.name());
|
||||
request.setTriggerMode(ApiRunMode.SCENARIO.name());
|
||||
request.setRunMode(ApiRunMode.SCENARIO.name());
|
||||
return apiAutomationService.run(request);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/run/batch")
|
||||
public String runBatch(@RequestBody RunScenarioRequest request) {
|
||||
request.setExecuteType(ExecuteType.Saved.name());
|
||||
request.setTriggerMode(ApiRunMode.SCENARIO.name());
|
||||
request.setRunMode(ApiRunMode.SCENARIO.name());
|
||||
return apiAutomationService.run(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ public class MsScenario extends MsTestElement {
|
|||
JSONObject element = JSON.parseObject(scenario.getScenarioDefinition());
|
||||
hashTree = mapper.readValue(element.getString("hashTree"), new TypeReference<LinkedList<MsTestElement>>() {
|
||||
});
|
||||
OldVersionUtil.transferHashTree(hashTree);
|
||||
// 场景变量
|
||||
if (StringUtils.isNotEmpty(element.getString("variables"))) {
|
||||
LinkedList<ScenarioVariable> variables = mapper.readValue(element.getString("variables"),
|
||||
|
|
|
@ -161,6 +161,7 @@ public abstract class MsTestElement {
|
|||
element = mapper.readValue(apiDefinition.getRequest(), new TypeReference<MsTestElement>() {
|
||||
});
|
||||
hashTree.add(element);
|
||||
OldVersionUtil.transferHashTree(hashTree);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package io.metersphere.api.dto.definition.request;
|
||||
|
||||
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OldVersionUtil {
|
||||
|
||||
public static void transferHashTree(List<MsTestElement> hashTree) {
|
||||
for (int i = 0; i < hashTree.size(); i++) {
|
||||
MsTestElement element = hashTree.get(i);
|
||||
if (StringUtils.isBlank(element.getProjectId())) {
|
||||
element.setProjectId(SessionUtils.getCurrentProjectId());
|
||||
}
|
||||
if (element.getHashTree() != null && element.getHashTree().size() > 0) {
|
||||
transferHashTree(element.getHashTree());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -96,7 +96,7 @@ public class MsAssertions extends MsTestElement {
|
|||
assertion.setJsonValidationBool(true);
|
||||
assertion.setExpectNull(false);
|
||||
assertion.setInvert(false);
|
||||
assertion.setIsRegex(false);
|
||||
assertion.setIsRegex(true);
|
||||
return assertion;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,17 +157,6 @@ public class ApiAutomationService {
|
|||
return request;
|
||||
}
|
||||
|
||||
|
||||
public List<String> selectIdsNotExistsInPlan(String projectId, String planId) {
|
||||
return extApiScenarioMapper.selectIdsNotExistsInPlan(projectId, planId);
|
||||
}
|
||||
|
||||
public void deleteByIds(List<String> nodeIds) {
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
example.createCriteria().andApiScenarioModuleIdIn(nodeIds);
|
||||
apiScenarioMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
public void removeToGcByIds(List<String> nodeIds) {
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
example.createCriteria().andApiScenarioModuleIdIn(nodeIds);
|
||||
|
@ -347,7 +336,7 @@ public class ApiAutomationService {
|
|||
}
|
||||
|
||||
public byte[] loadFileAsBytes(FileOperationRequest fileOperationRequest) {
|
||||
File file = new File("/opt/metersphere/data/body/" + fileOperationRequest.getId() + "_" + fileOperationRequest.getName());
|
||||
File file = new File(FileUtils.BODY_FILE_DIR + fileOperationRequest.getId() + "_" + fileOperationRequest.getName());
|
||||
try (FileInputStream fis = new FileInputStream(file);
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);) {
|
||||
byte[] b = new byte[1000];
|
||||
|
@ -362,7 +351,7 @@ public class ApiAutomationService {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void createScenarioReport(String id, String scenarioId, String scenarioName, String triggerMode, String execType, String projectId, String userID) {
|
||||
public APIScenarioReportResult createScenarioReport(String id, String scenarioId, String scenarioName, String triggerMode, String execType, String projectId, String userID) {
|
||||
APIScenarioReportResult report = new APIScenarioReportResult();
|
||||
report.setId(id);
|
||||
report.setTestId(id);
|
||||
|
@ -384,87 +373,55 @@ public class ApiAutomationService {
|
|||
report.setProjectId(projectId);
|
||||
report.setScenarioName(scenarioName);
|
||||
report.setScenarioId(scenarioId);
|
||||
apiScenarioReportMapper.insert(report);
|
||||
return report;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成HashTree
|
||||
*
|
||||
* @param apiScenarios 场景
|
||||
* @param request 请求参数
|
||||
* @param reportIds 报告ID
|
||||
* @return hashTree
|
||||
*/
|
||||
private HashTree generateHashTree(List<ApiScenarioWithBLOBs> apiScenarios, RunScenarioRequest request, List<String> reportIds) {
|
||||
HashTree jmeterHashTree = new ListedHashTree();
|
||||
|
||||
private void parse(String scenarioDefinition, MsScenario scenario) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
try {
|
||||
JSONObject element = JSON.parseObject(scenarioDefinition);
|
||||
// 多态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 (element != null && StringUtils.isNotEmpty(element.getString("variables"))) {
|
||||
LinkedList<ScenarioVariable> variables = mapper.readValue(element.getString("variables"),
|
||||
new TypeReference<LinkedList<ScenarioVariable>>() {
|
||||
});
|
||||
scenario.setVariables(variables);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
LogUtil.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private HashTree generateHashTree(ApiScenarioWithBLOBs item, String reportId, Map<String, String> planEnvMap) {
|
||||
HashTree jmeterHashTree = new HashTree();
|
||||
MsTestPlan testPlan = new MsTestPlan();
|
||||
testPlan.setHashTree(new LinkedList<>());
|
||||
try {
|
||||
boolean isFirst = true;
|
||||
for (ApiScenarioWithBLOBs item : apiScenarios) {
|
||||
if (item.getStepTotal() == null || item.getStepTotal() == 0) {
|
||||
// 只有一个场景且没有测试步骤,则提示
|
||||
if (apiScenarios.size() == 1) {
|
||||
MSException.throwException((item.getName() + "," + Translator.get("automation_exec_info")));
|
||||
}
|
||||
LogUtil.warn(item.getName() + "," + Translator.get("automation_exec_info"));
|
||||
continue;
|
||||
}
|
||||
MsThreadGroup group = new MsThreadGroup();
|
||||
group.setLabel(item.getName());
|
||||
group.setName(UUID.randomUUID().toString());
|
||||
// 批量执行的结果直接存储为报告
|
||||
if (isFirst) {
|
||||
group.setName(request.getId());
|
||||
isFirst = false;
|
||||
}
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
JSONObject element = JSON.parseObject(item.getScenarioDefinition());
|
||||
MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class);
|
||||
MsThreadGroup group = new MsThreadGroup();
|
||||
group.setLabel(item.getName());
|
||||
group.setName(reportId);
|
||||
|
||||
// 多态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);
|
||||
}
|
||||
group.setEnableCookieShare(scenario.isEnableCookieShare());
|
||||
LinkedList<MsTestElement> scenarios = new LinkedList<>();
|
||||
scenarios.add(scenario);
|
||||
// 创建场景报告
|
||||
if (reportIds != null) {
|
||||
//如果是测试计划页面触发的执行方式,生成报告时createScenarioReport第二个参数需要特殊处理
|
||||
if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
||||
String testPlanScenarioId = item.getId();
|
||||
if (request.getScenarioTestPlanIdMap() != null && request.getScenarioTestPlanIdMap().containsKey(item.getId())) {
|
||||
testPlanScenarioId = request.getScenarioTestPlanIdMap().get(item.getId());
|
||||
// 获取场景用例单独的执行环境
|
||||
TestPlanApiScenario planApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(testPlanScenarioId);
|
||||
String environment = planApiScenario.getEnvironment();
|
||||
if (StringUtils.isNotBlank(environment)) {
|
||||
scenario.setEnvironmentMap(JSON.parseObject(environment, Map.class));
|
||||
}
|
||||
}
|
||||
createScenarioReport(group.getName(), testPlanScenarioId, item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
|
||||
request.getExecuteType(), item.getProjectId(), request.getReportUserID());
|
||||
} else {
|
||||
createScenarioReport(group.getName(), item.getId(), item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(),
|
||||
request.getExecuteType(), item.getProjectId(), request.getReportUserID());
|
||||
}
|
||||
|
||||
reportIds.add(group.getName());
|
||||
}
|
||||
group.setHashTree(scenarios);
|
||||
testPlan.getHashTree().add(group);
|
||||
MsScenario scenario = JSONObject.parseObject(item.getScenarioDefinition(), MsScenario.class);
|
||||
if (planEnvMap.size() > 0) {
|
||||
scenario.setEnvironmentMap(planEnvMap);
|
||||
}
|
||||
parse(item.getScenarioDefinition(), scenario);
|
||||
|
||||
group.setEnableCookieShare(scenario.isEnableCookieShare());
|
||||
LinkedList<MsTestElement> scenarios = new LinkedList<>();
|
||||
scenarios.add(scenario);
|
||||
|
||||
group.setHashTree(scenarios);
|
||||
testPlan.getHashTree().add(group);
|
||||
} catch (Exception ex) {
|
||||
MSException.throwException(ex.getMessage());
|
||||
}
|
||||
|
@ -482,27 +439,11 @@ public class ApiAutomationService {
|
|||
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 (element != null && StringUtils.isNotEmpty(element.getString("variables"))) {
|
||||
LinkedList<ScenarioVariable> variables = mapper.readValue(element.getString("variables"),
|
||||
new TypeReference<LinkedList<ScenarioVariable>>() {
|
||||
});
|
||||
scenario.setVariables(variables);
|
||||
}
|
||||
if (scenario == null) {
|
||||
return null;
|
||||
}
|
||||
parse(apiScenario.getScenarioDefinition(), scenario);
|
||||
// 针对导入的jmx 处理
|
||||
if (CollectionUtils.isNotEmpty(scenario.getHashTree()) && (scenario.getHashTree().get(0) instanceof MsJmeterElement)) {
|
||||
scenario.toHashTree(jmeterHashTree, scenario.getHashTree(), config);
|
||||
|
@ -533,26 +474,62 @@ public class ApiAutomationService {
|
|||
* @return
|
||||
*/
|
||||
public String run(RunScenarioRequest request) {
|
||||
|
||||
ServiceUtils.getSelectAllIds(request, request.getCondition(),
|
||||
(query) -> extApiScenarioMapper.selectIdsByQuery((ApiScenarioRequest) query));
|
||||
|
||||
List<String> ids = request.getIds();
|
||||
//检查是否有正在执行中的情景
|
||||
this.checkScenarioIsRunning(ids);
|
||||
List<ApiScenarioWithBLOBs> apiScenarios = extApiScenarioMapper.selectIds(ids);
|
||||
|
||||
String runMode = ApiRunMode.SCENARIO.name();
|
||||
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
||||
runMode = ApiRunMode.SCENARIO_PLAN.name();
|
||||
List<ApiScenarioWithBLOBs> apiScenarios = extApiScenarioMapper.selectIds(ids);
|
||||
// 只有一个场景且没有测试步骤,则提示
|
||||
if (apiScenarios != null && apiScenarios.size() == 1 && (apiScenarios.get(0).getStepTotal() == null || apiScenarios.get(0).getStepTotal() == 0)) {
|
||||
MSException.throwException((apiScenarios.get(0).getName() + "," + Translator.get("automation_exec_info")));
|
||||
}
|
||||
if (StringUtils.isNotBlank(request.getRunMode()) && StringUtils.equals(request.getRunMode(), ApiRunMode.DEFINITION.name())) {
|
||||
runMode = ApiRunMode.DEFINITION.name();
|
||||
if (StringUtils.isEmpty(request.getTriggerMode())) {
|
||||
request.setTriggerMode(ReportTriggerMode.MANUAL.name());
|
||||
}
|
||||
// 调用执行方法
|
||||
List<String> reportIds = new LinkedList<>();
|
||||
HashTree hashTree = generateHashTree(apiScenarios, request, reportIds);
|
||||
jMeterService.runDefinition(JSON.toJSONString(reportIds), hashTree, request.getReportId(), runMode);
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiScenarioReportMapper batchMapper = sqlSession.getMapper(ApiScenarioReportMapper.class);
|
||||
String reportId = request.getId();
|
||||
// 按照场景执行
|
||||
for (ApiScenarioWithBLOBs item : apiScenarios) {
|
||||
if (item.getStepTotal() == null || item.getStepTotal() == 0) {
|
||||
continue;
|
||||
}
|
||||
APIScenarioReportResult report;
|
||||
Map<String, String> planEnvMap = new HashMap<>();
|
||||
//如果是测试计划页面触发的执行方式,生成报告时createScenarioReport第二个参数需要特殊处理
|
||||
if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) {
|
||||
String testPlanScenarioId = item.getId();
|
||||
if (request.getScenarioTestPlanIdMap() != null && request.getScenarioTestPlanIdMap().containsKey(item.getId())) {
|
||||
testPlanScenarioId = request.getScenarioTestPlanIdMap().get(item.getId());
|
||||
// 获取场景用例单独的执行环境
|
||||
TestPlanApiScenario planApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(testPlanScenarioId);
|
||||
String environment = planApiScenario.getEnvironment();
|
||||
if (StringUtils.isNotBlank(environment)) {
|
||||
planEnvMap = JSON.parseObject(environment, Map.class);
|
||||
}
|
||||
}
|
||||
report = createScenarioReport(reportId, testPlanScenarioId, item.getName(), request.getTriggerMode(),
|
||||
request.getExecuteType(), item.getProjectId(), request.getReportUserID());
|
||||
} else {
|
||||
report = createScenarioReport(reportId, item.getId(), item.getName(), request.getTriggerMode(),
|
||||
request.getExecuteType(), item.getProjectId(), request.getReportUserID());
|
||||
}
|
||||
|
||||
// 生成报告和HashTree
|
||||
HashTree hashTree = generateHashTree(item, reportId, planEnvMap);
|
||||
|
||||
//存储报告
|
||||
batchMapper.insert(report);
|
||||
|
||||
// 调用执行方法
|
||||
jMeterService.runDefinition(report.getId(), hashTree, request.getReportId(), request.getRunMode());
|
||||
// 重置报告ID
|
||||
reportId = UUID.randomUUID().toString();
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
return request.getId();
|
||||
}
|
||||
|
||||
|
@ -598,7 +575,7 @@ public class ApiAutomationService {
|
|||
public String debugRun(RunDefinitionRequest request, List<MultipartFile> bodyFiles) {
|
||||
List<String> bodyUploadIds = new ArrayList<>(request.getBodyUploadIds());
|
||||
FileUtils.createBodyFiles(bodyUploadIds, bodyFiles);
|
||||
Map<String,EnvironmentConfig> envConfig = new HashMap<>();
|
||||
Map<String, EnvironmentConfig> envConfig = new HashMap<>();
|
||||
Map<String, String> map = request.getEnvironmentMap();
|
||||
if (map != null) {
|
||||
map.keySet().forEach(id -> {
|
||||
|
@ -611,8 +588,9 @@ public class ApiAutomationService {
|
|||
config.setConfig(envConfig);
|
||||
HashTree hashTree = request.getTestElement().generateHashTree(config);
|
||||
// 调用执行方法
|
||||
createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
|
||||
APIScenarioReportResult reportResult = createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(),
|
||||
SessionUtils.getUserId());
|
||||
apiScenarioReportMapper.insert(reportResult);
|
||||
// 调用执行方法
|
||||
jMeterService.runDefinition(request.getId(), hashTree, request.getReportId(), ApiRunMode.SCENARIO.name());
|
||||
return request.getId();
|
||||
|
@ -761,13 +739,12 @@ public class ApiAutomationService {
|
|||
if (!apiScenarios.isEmpty()) {
|
||||
testName = apiScenarios.get(0).getName();
|
||||
}
|
||||
if (CollectionUtils.isEmpty(apiScenarios)) {
|
||||
return null;
|
||||
}
|
||||
MsTestPlan testPlan = new MsTestPlan();
|
||||
testPlan.setHashTree(new LinkedList<>());
|
||||
|
||||
HashTree jmeterHashTree = generateHashTree(apiScenarios, request, null);
|
||||
String jmx = testPlan.getJmx(jmeterHashTree);
|
||||
|
||||
JmxInfoDTO dto = apiTestService.updateJmxString(jmx, testName, true);
|
||||
JmxInfoDTO dto = apiTestService.updateJmxString(generateJmx(apiScenarios.get(0)), testName, true);
|
||||
|
||||
String name = request.getName() + ".jmx";
|
||||
dto.setName(name);
|
||||
|
@ -931,7 +908,9 @@ public class ApiAutomationService {
|
|||
Map<String, String> envMap = request.getEnvMap();
|
||||
Map<String, List<String>> mapping = request.getMapping();
|
||||
Set<String> set = mapping.keySet();
|
||||
if (set.isEmpty()) { return; }
|
||||
if (set.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
set.forEach(id -> {
|
||||
Map<String, String> newEnvMap = new HashMap<>(16);
|
||||
if (envMap != null && !envMap.isEmpty()) {
|
||||
|
|
|
@ -152,7 +152,7 @@ public class ApiScenarioReportService {
|
|||
apiScenarioReportDetailMapper.insert(detail);
|
||||
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(report.getScenarioId());
|
||||
if(testPlanApiScenario!=null){
|
||||
if (testPlanApiScenario != null) {
|
||||
report.setScenarioId(testPlanApiScenario.getApiScenarioId());
|
||||
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
||||
if (scenarioResult.getError() > 0) {
|
||||
|
@ -236,17 +236,12 @@ public class ApiScenarioReportService {
|
|||
/**
|
||||
* 批量更新状态,防止重复刷新报告
|
||||
*
|
||||
* @param reportIds
|
||||
* @param reportId
|
||||
*/
|
||||
private void updateScenarioStatus(String reportIds) {
|
||||
|
||||
if (StringUtils.isNotEmpty(reportIds)) {
|
||||
private void updateScenarioStatus(String reportId) {
|
||||
if (StringUtils.isNotEmpty(reportId)) {
|
||||
List<String> list = new ArrayList<>();
|
||||
try {
|
||||
list = JSON.parseArray(reportIds, String.class);
|
||||
} catch (Exception e) {
|
||||
list.add(reportIds);
|
||||
}
|
||||
list.add(reportId);
|
||||
ApiScenarioReportExample scenarioReportExample = new ApiScenarioReportExample();
|
||||
scenarioReportExample.createCriteria().andIdIn(list);
|
||||
List<ApiScenarioReport> reportList = apiScenarioReportMapper.selectByExample(scenarioReportExample);
|
||||
|
@ -350,13 +345,13 @@ public class ApiScenarioReportService {
|
|||
int handleCount = 7000;
|
||||
//每次处理的集合
|
||||
List<String> handleIdList = new ArrayList<>(handleCount);
|
||||
while (ids.size() > handleCount){
|
||||
while (ids.size() > handleCount) {
|
||||
handleIdList = new ArrayList<>(handleCount);
|
||||
List<String> otherIdList = new ArrayList<>();
|
||||
for (int index = 0;index < ids.size();index++){
|
||||
if(index<handleCount){
|
||||
for (int index = 0; index < ids.size(); index++) {
|
||||
if (index < handleCount) {
|
||||
handleIdList.add(ids.get(index));
|
||||
}else{
|
||||
} else {
|
||||
otherIdList.add(ids.get(index));
|
||||
}
|
||||
}
|
||||
|
@ -372,7 +367,7 @@ public class ApiScenarioReportService {
|
|||
}
|
||||
|
||||
//处理最后剩余的数据
|
||||
if(!ids.isEmpty()){
|
||||
if (!ids.isEmpty()) {
|
||||
ApiScenarioReportDetailExample detailExample = new ApiScenarioReportDetailExample();
|
||||
detailExample.createCriteria().andReportIdIn(ids);
|
||||
apiScenarioReportDetailMapper.deleteByExample(detailExample);
|
||||
|
@ -417,9 +412,9 @@ public class ApiScenarioReportService {
|
|||
}
|
||||
|
||||
public List<ApiScenarioReport> selectLastReportByIds(List<String> ids) {
|
||||
if(!ids.isEmpty()){
|
||||
if (!ids.isEmpty()) {
|
||||
return extApiScenarioReportMapper.selectLastReportByIds(ids);
|
||||
}else {
|
||||
} else {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
select test_case_review_test_case.id as id, test_case.id as caseId, test_case.name, test_case.priority,
|
||||
test_case.type, test_case.node_path, test_case.method, test_case.num, test_case_review_test_case.reviewer,
|
||||
test_case.review_status, test_case_review_test_case.update_time, test_case_node.name as model,
|
||||
project.name as projectName, test_case_review_test_case.review_id as reviewId
|
||||
project.name as projectName, test_case_review_test_case.review_id as reviewId,test_case.test_id as testId
|
||||
from test_case_review_test_case
|
||||
inner join test_case on test_case_review_test_case.case_id = test_case.id
|
||||
left join test_case_node on test_case_node.id=test_case.node_id
|
||||
|
|
|
@ -68,8 +68,8 @@ public class TestCaseReviewController {
|
|||
|
||||
@PostMapping("/edit")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public void editCaseReview(@RequestBody SaveTestCaseReviewRequest testCaseReview) {
|
||||
testCaseReviewService.editCaseReview(testCaseReview);
|
||||
public String editCaseReview(@RequestBody SaveTestCaseReviewRequest testCaseReview) {
|
||||
return testCaseReviewService.editCaseReview(testCaseReview);
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{reviewId}")
|
||||
|
|
|
@ -8,6 +8,7 @@ import io.metersphere.commons.exception.MSException;
|
|||
import io.metersphere.commons.user.SessionUser;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.EncryptUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.IntegrationRequest;
|
||||
import io.metersphere.service.IntegrationService;
|
||||
|
@ -15,10 +16,21 @@ import io.metersphere.service.ProjectService;
|
|||
import io.metersphere.track.request.testcase.IssuesRequest;
|
||||
import io.metersphere.track.service.TestCaseService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustStrategy;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
||||
|
||||
private static RestTemplate restTemplate;
|
||||
|
||||
protected IntegrationService integrationService;
|
||||
protected TestCaseIssuesMapper testCaseIssuesMapper;
|
||||
protected ProjectService projectService;
|
||||
|
@ -26,8 +38,29 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
|||
protected IssuesMapper issuesMapper;
|
||||
protected ExtIssuesMapper extIssuesMapper;
|
||||
|
||||
protected RestTemplate restTemplateIgnoreSSL;
|
||||
|
||||
protected String testCaseId;
|
||||
|
||||
static {
|
||||
try {
|
||||
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
|
||||
SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
|
||||
.loadTrustMaterial(null, acceptingTrustStrategy)
|
||||
.build();
|
||||
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
|
||||
CloseableHttpClient httpClient = HttpClients.custom()
|
||||
.setSSLSocketFactory(csf)
|
||||
.build();
|
||||
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
|
||||
requestFactory.setHttpClient(httpClient);
|
||||
|
||||
restTemplate = new RestTemplate(requestFactory);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractIssuePlatform(IssuesRequest issuesRequest) {
|
||||
this.integrationService = CommonBeanFactory.getBean(IntegrationService.class);
|
||||
this.testCaseIssuesMapper = CommonBeanFactory.getBean(TestCaseIssuesMapper.class);
|
||||
|
@ -36,6 +69,8 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
|||
this.issuesMapper = CommonBeanFactory.getBean(IssuesMapper.class);
|
||||
this.extIssuesMapper = CommonBeanFactory.getBean(ExtIssuesMapper.class);
|
||||
this.testCaseId = issuesRequest.getTestCaseId();
|
||||
//
|
||||
this.restTemplateIgnoreSSL = restTemplate;
|
||||
}
|
||||
|
||||
protected String getPlatformConfig(String platform) {
|
||||
|
@ -64,6 +99,7 @@ public abstract class AbstractIssuePlatform implements IssuesPlatform {
|
|||
|
||||
/**
|
||||
* 获取平台与项目相关的属性
|
||||
*
|
||||
* @return 其他平台和本地项目绑定的属性值
|
||||
*/
|
||||
abstract String getProjectId();
|
||||
|
|
|
@ -186,8 +186,8 @@ public class JiraPlatform extends AbstractIssuePlatform {
|
|||
String url = object.getString("url");
|
||||
HttpHeaders headers = auth(account, password);
|
||||
HttpEntity<MultiValueMap> requestEntity = new HttpEntity<>(headers);
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
restTemplate.exchange(url + "rest/api/2/issue/createmeta", HttpMethod.GET, requestEntity, String.class);
|
||||
// 忽略ssl
|
||||
restTemplateIgnoreSSL.exchange(url + "rest/api/2/issue/createmeta", HttpMethod.GET, requestEntity, String.class);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException("验证失败!");
|
||||
|
|
|
@ -203,7 +203,7 @@ public class TestCaseReviewService {
|
|||
return extTestCaseReviewMapper.listByWorkspaceId(currentWorkspaceId, SessionUtils.getUserId(), SessionUtils.getCurrentProjectId());
|
||||
}
|
||||
|
||||
public void editCaseReview(SaveTestCaseReviewRequest testCaseReview) {
|
||||
public String editCaseReview(SaveTestCaseReviewRequest testCaseReview) {
|
||||
editCaseReviewer(testCaseReview);
|
||||
testCaseReview.setUpdateTime(System.currentTimeMillis());
|
||||
checkCaseReviewExist(testCaseReview);
|
||||
|
@ -221,6 +221,7 @@ public class TestCaseReviewService {
|
|||
.event(NoticeConstants.Event.UPDATE)
|
||||
.build();
|
||||
noticeSendService.send(NoticeConstants.TaskType.REVIEW_TASK, noticeModel);
|
||||
return testCaseReview.getId();
|
||||
}
|
||||
|
||||
private void editCaseReviewer(SaveTestCaseReviewRequest testCaseReview) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3f497f88ebbd312a3b7637c1b694a8e28c68c287
|
||||
Subproject commit d2fc4b42117be97c679b4d15d6f979923e598f7f
|
|
@ -33,7 +33,7 @@ alter table swagger_url_project
|
|||
|
||||
-- add_test_case
|
||||
alter table test_case
|
||||
add demand_id varchar(50) null;
|
||||
add demand_id varchar(120) null;
|
||||
|
||||
alter table test_case
|
||||
add demand_name varchar(999) null;
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<div class="card-content">
|
||||
<div class="ms-main-div" @click="showAll">
|
||||
<div class="ms-main-div" @click="showAll" v-if="type!=='detail'">
|
||||
|
||||
<!--操作按钮-->
|
||||
<div class="ms-opt-btn">
|
||||
<el-button id="inputDelay" type="primary" size="small" @click="editScenario" title="ctrl + s">{{$t('commons.save')}}</el-button>
|
||||
<el-button id="inputDelay" type="primary" size="small" @click="editScenario" title="ctrl + s">
|
||||
{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div class="tip">{{$t('test_track.plan_view.base_info')}}</div>
|
||||
<el-form :model="currentScenario" label-position="right" label-width="80px" size="small" :rules="rules" ref="currentScenario" style="margin-right: 20px">
|
||||
<div class="tip">{{ $t('test_track.plan_view.base_info') }}</div>
|
||||
<el-form :model="currentScenario" label-position="right" label-width="80px" size="small" :rules="rules"
|
||||
ref="currentScenario" style="margin-right: 20px">
|
||||
<!-- 基础信息 -->
|
||||
<el-row>
|
||||
<el-col :span="7">
|
||||
|
@ -99,7 +102,7 @@
|
|||
<div class="ms-debug-div" @click="showAll">
|
||||
<el-row style="margin: 5px">
|
||||
<el-col :span="6" class="ms-col-one ms-font">
|
||||
{{currentScenario.name ===undefined || ''? $t('api_test.scenario.name') : currentScenario.name}}
|
||||
{{ currentScenario.name === undefined || '' ? $t('api_test.scenario.name') : currentScenario.name }}
|
||||
</el-col>
|
||||
<el-col :span="3" class="ms-col-one ms-font">
|
||||
{{$t('api_test.automation.step_total')}}:{{scenarioDefinition.length}}
|
||||
|
@ -160,30 +163,35 @@
|
|||
</div>
|
||||
|
||||
<!--接口列表-->
|
||||
<scenario-api-relevance @save="pushApiOrCase" ref="scenarioApiRelevance"/>
|
||||
<scenario-api-relevance @save="pushApiOrCase" ref="scenarioApiRelevance" v-if="type!=='detail'"/>
|
||||
|
||||
<!--自定义接口-->
|
||||
<el-drawer :visible.sync="customizeVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :title="$t('api_test.automation.customize_req')" style="overflow: auto" :modal="false" size="90%">
|
||||
<el-drawer v-if="type!=='detail'" :visible.sync="customizeVisible" :destroy-on-close="true" direction="ltr"
|
||||
:withHeader="false" :title="$t('api_test.automation.customize_req')" style="overflow: auto"
|
||||
:modal="false" size="90%">
|
||||
<ms-api-customize :request="customizeRequest" @addCustomizeApi="addCustomizeApi"/>
|
||||
</el-drawer>
|
||||
<!--场景导入 -->
|
||||
<scenario-relevance @save="addScenario" ref="scenarioRelevance"/>
|
||||
<scenario-relevance v-if="type!=='detail'" @save="addScenario" ref="scenarioRelevance"/>
|
||||
|
||||
<!-- 环境 -->
|
||||
<api-environment-config ref="environmentConfig" @close="environmentConfigClose"/>
|
||||
<api-environment-config v-if="type!=='detail'" ref="environmentConfig" @close="environmentConfigClose"/>
|
||||
|
||||
<!--执行组件-->
|
||||
<ms-run :debug="true" :environment="projectEnvMap" :reportId="reportId" :run-data="debugData"
|
||||
<ms-run :debug="true" v-if="type!=='detail'" :environment="projectEnvMap" :reportId="reportId"
|
||||
:run-data="debugData"
|
||||
@runRefresh="runRefresh" ref="runTest"/>
|
||||
<!-- 调试结果 -->
|
||||
<el-drawer :visible.sync="debugVisible" :destroy-on-close="true" direction="ltr" :withHeader="true" :modal="false" size="90%">
|
||||
<el-drawer v-if="type!=='detail'" :visible.sync="debugVisible" :destroy-on-close="true" direction="ltr"
|
||||
:withHeader="true" :modal="false" size="90%">
|
||||
<ms-api-report-detail :report-id="reportId" :debug="true" :currentProjectId="projectId"/>
|
||||
</el-drawer>
|
||||
|
||||
<!--场景公共参数-->
|
||||
<ms-variable-list @setVariables="setVariables" ref="scenarioParameters" class="ms-sc-variable-header"/>
|
||||
<ms-variable-list v-if="type!=='detail'" @setVariables="setVariables" ref="scenarioParameters"
|
||||
class="ms-sc-variable-header"/>
|
||||
<!--外部导入-->
|
||||
<api-import ref="apiImport" :saved="false" @refresh="apiImport"/>
|
||||
<api-import v-if="type!=='detail'" ref="apiImport" :saved="false" @refresh="apiImport"/>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
@ -222,6 +230,7 @@
|
|||
props: {
|
||||
moduleOptions: Array,
|
||||
currentScenario: {},
|
||||
type: String
|
||||
},
|
||||
components: {
|
||||
MsVariableList,
|
||||
|
@ -532,6 +541,9 @@
|
|||
if (arr[i].type === ELEMENT_TYPE.LoopController && arr[i].hashTree && arr[i].hashTree.length > 1) {
|
||||
arr[i].countController.proceed = true;
|
||||
}
|
||||
if (!arr[i].projectId) {
|
||||
arr[i].projectId = getCurrentProjectID();
|
||||
}
|
||||
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
|
||||
this.recursiveSorting(arr[i].hashTree);
|
||||
}
|
||||
|
@ -544,6 +556,9 @@
|
|||
&& this.scenarioDefinition[i].hashTree.length > 1) {
|
||||
this.scenarioDefinition[i].countController.proceed = true;
|
||||
}
|
||||
if (!this.scenarioDefinition[i].projectId) {
|
||||
this.scenarioDefinition.projectId = getCurrentProjectID();
|
||||
}
|
||||
if (this.scenarioDefinition[i].hashTree != undefined && this.scenarioDefinition[i].hashTree.length > 0) {
|
||||
this.recursiveSorting(this.scenarioDefinition[i].hashTree);
|
||||
}
|
||||
|
@ -919,14 +934,15 @@
|
|||
}
|
||||
this.enableCookieShare = obj.enableCookieShare;
|
||||
this.scenarioDefinition = obj.hashTree;
|
||||
this.initProjectIds();
|
||||
}
|
||||
}
|
||||
if (this.currentScenario.copy) {
|
||||
this.path = "/api/automation/create";
|
||||
}
|
||||
}
|
||||
this.getEnvironments();
|
||||
this.sort();
|
||||
this.initProjectIds();
|
||||
// this.getEnvironments();
|
||||
})
|
||||
}
|
||||
},
|
||||
|
|
|
@ -251,16 +251,19 @@
|
|||
this.reload();
|
||||
},
|
||||
run() {
|
||||
if (!this.envMap || this.envMap.size === 0) {
|
||||
this.$warning("请在环境配置中为该步骤所属项目选择运行环境!");
|
||||
return false;
|
||||
} else if (this.envMap && this.envMap.size > 0) {
|
||||
const env = this.envMap.get(this.request.projectId);
|
||||
if (!env) {
|
||||
if (this.isApiImport) {
|
||||
if (!this.envMap || this.envMap.size === 0) {
|
||||
this.$warning("请在环境配置中为该步骤所属项目选择运行环境!");
|
||||
return false;
|
||||
} else if (this.envMap && this.envMap.size > 0) {
|
||||
const env = this.envMap.get(this.request.projectId);
|
||||
if (!env) {
|
||||
this.$warning("请在环境配置中为该步骤所属项目选择运行环境!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.request.active = true;
|
||||
this.loading = true;
|
||||
this.runData = [];
|
||||
|
|
|
@ -108,6 +108,9 @@
|
|||
recursive(arr) {
|
||||
for (let i in arr) {
|
||||
arr[i].disabled = true;
|
||||
if (!arr[i].projectId) {
|
||||
arr[i].projectId = getCurrentProjectID();
|
||||
}
|
||||
if (arr[i].hashTree != undefined && arr[i].hashTree.length > 0) {
|
||||
this.recursive(arr[i].hashTree);
|
||||
}
|
||||
|
@ -116,6 +119,9 @@
|
|||
setDisabled(scenarioDefinition) {
|
||||
for (let i in scenarioDefinition) {
|
||||
scenarioDefinition[i].disabled = true;
|
||||
if (!scenarioDefinition[i].projectId) {
|
||||
scenarioDefinition[i].projectId = getCurrentProjectID();
|
||||
}
|
||||
if (scenarioDefinition[i].hashTree != undefined && scenarioDefinition[i].hashTree.length > 0) {
|
||||
this.recursive(scenarioDefinition[i].hashTree);
|
||||
}
|
||||
|
|
|
@ -231,14 +231,6 @@ export default {
|
|||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
for (let i = 0; i < this.tableData.length; i++) {
|
||||
let path = "/test/plan/project";
|
||||
this.$post(path, {planId: this.tableData[i].id}, res => {
|
||||
let arr = res.data;
|
||||
let projectIds = arr.map(data => data.id);
|
||||
this.$set(this.tableData[i], "projectIds", projectIds);
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
buildPagePath(path) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<el-card style="margin-top: 5px" @click.native="selectTestCase(apiCase,$event)">
|
||||
<div @click="active(apiCase)">
|
||||
<div @click="active(apiCase)" v-if="type!=='detail'">
|
||||
<el-row>
|
||||
<el-col :span="5">
|
||||
<el-row>
|
||||
|
@ -79,16 +79,14 @@
|
|||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-divider ></el-divider>
|
||||
</div>
|
||||
|
||||
<!-- 请求参数-->
|
||||
<el-collapse-transition>
|
||||
<div v-if="apiCase.active">
|
||||
<el-divider></el-divider>
|
||||
|
||||
<div v-if="apiCase.active||type==='detail'">
|
||||
<p class="tip">{{ $t('api_test.definition.request.req_param') }} </p>
|
||||
|
||||
<ms-api-request-form :isShowEnable="true" :showScript="true" :is-read-only="isReadOnly" :headers="apiCase.request.headers " :request="apiCase.request" v-if="api.protocol==='HTTP'"/>
|
||||
<ms-api-request-form :isShowEnable="true" :showScript="true" :is-read-only="isReadOnly" :headers="apiCase.request.headers " :request="apiCase.request" v-if="api.protocol==='HTTP'"/>
|
||||
<ms-tcp-basis-parameters :showScript="true" :request="apiCase.request" v-if="api.protocol==='TCP'"/>
|
||||
<ms-sql-basis-parameters :showScript="true" :request="apiCase.request" v-if="api.protocol==='SQL'"/>
|
||||
<ms-dubbo-basis-parameters :showScript="true" :request="apiCase.request" v-if="api.protocol==='DUBBO'"/>
|
||||
|
@ -99,12 +97,13 @@
|
|||
|
||||
<ms-jmx-step :request="apiCase.request" :response="apiCase.responseData"/>
|
||||
<!-- 保存操作 -->
|
||||
<el-button type="primary" size="small" style="margin: 20px; float: right" @click="saveTestCase(apiCase)" v-tester>
|
||||
<el-button type="primary" size="small" style="margin: 20px; float: right" @click="saveTestCase(apiCase)" v-tester v-if="type!=='detail'">
|
||||
{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</el-card>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -183,6 +182,7 @@
|
|||
return {}
|
||||
}
|
||||
},
|
||||
type:String,
|
||||
isCaseEdit: Boolean,
|
||||
},
|
||||
watch: {},
|
||||
|
|
|
@ -132,7 +132,8 @@
|
|||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
type: String,
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
|
@ -63,11 +63,16 @@ export const Api_Case_List = [
|
|||
export const Api_Scenario_List = [
|
||||
{id: 'num', label: "ID"},
|
||||
{id: 'name', label: i18n.t('test_track.case.name')},
|
||||
{id: 'priority', label: i18n.t('test_track.case.priority')},
|
||||
{id: 'path', label: i18n.t('api_test.definition.api_path')},
|
||||
{id: 'level', label: i18n.t('api_test.automation.case_level')},
|
||||
{id: 'status', label: i18n.t('test_track.plan.plan_status')},
|
||||
{id: 'tags', label: i18n.t('commons.tag')},
|
||||
{id: 'createUser', label: '创建人'},
|
||||
{id: 'userId', label: i18n.t('api_test.automation.creator')},
|
||||
{id: 'updateTime', label: i18n.t('api_test.definition.api_last_time')},
|
||||
{id: 'stepTotal', label: i18n.t('api_test.automation.step')},
|
||||
{id: 'lastResult', label: i18n.t('api_test.automation.last_result')},
|
||||
{id: 'passRate', label: i18n.t('api_test.automation.passing_rate')},
|
||||
|
||||
|
||||
]
|
||||
//测试评审-测试用例
|
||||
export const Test_Case_Review_Case_List = [
|
||||
|
|
|
@ -134,7 +134,6 @@ export default {
|
|||
plannedStartTime: '',
|
||||
plannedEndTime: ''
|
||||
},
|
||||
dbProjectIds: [],
|
||||
rules: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_track.plan.input_plan_name'), trigger: 'blur'},
|
||||
|
@ -160,7 +159,6 @@ export default {
|
|||
let tmp = {};
|
||||
Object.assign(tmp, testPlan);
|
||||
Object.assign(this.form, tmp);
|
||||
this.dbProjectIds = JSON.parse(JSON.stringify(this.form.projectIds));
|
||||
}
|
||||
listenGoBack(this.close);
|
||||
this.dialogFormVisible = true;
|
||||
|
|
|
@ -279,14 +279,6 @@ export default {
|
|||
let data = response.data;
|
||||
this.total = data.itemCount;
|
||||
this.tableData = data.listObject;
|
||||
for (let i = 0; i < this.tableData.length; i++) {
|
||||
let path = "/test/plan/project";
|
||||
this.$post(path, {planId: this.tableData[i].id}, res => {
|
||||
let arr = res.data;
|
||||
let projectIds = arr.filter(d => d.id !== this.tableData[i].projectId).map(data => data.id);
|
||||
this.$set(this.tableData[i], "projectIds", projectIds);
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
buildPagePath(path) {
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
<el-button type="primary" @click="saveReview">
|
||||
{{ $t('test_track.confirm') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="reviewInfo('form')">
|
||||
<el-button type="primary" @click="reviewInfo">
|
||||
{{ $t('test_track.planning_execution') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
@ -137,7 +137,23 @@ export default {
|
|||
};
|
||||
},
|
||||
methods: {
|
||||
reviewInfo(form) {
|
||||
openCaseReviewEditDialog(caseReview) {
|
||||
this.resetForm();
|
||||
this.setReviewerOptions();
|
||||
this.operationType = 'save';
|
||||
if (caseReview) {
|
||||
//修改
|
||||
this.operationType = 'edit';
|
||||
let tmp = {};
|
||||
Object.assign(tmp, caseReview);
|
||||
Object.assign(this.form, tmp);
|
||||
this.dbProjectIds = JSON.parse(JSON.stringify(this.form.projectIds));
|
||||
}
|
||||
listenGoBack(this.close);
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
reviewInfo() {
|
||||
|
||||
this.$refs['reviewForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
let param = {};
|
||||
|
@ -155,7 +171,6 @@ export default {
|
|||
if (!this.compareTime(new Date().getTime(), this.form.endTime)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.result = this.$post('/test/case/review/' + this.operationType, param, response => {
|
||||
this.dialogFormVisible = false;
|
||||
this.$router.push('/track/review/view/' + response.data);
|
||||
|
@ -165,21 +180,7 @@ export default {
|
|||
}
|
||||
});
|
||||
},
|
||||
openCaseReviewEditDialog(caseReview) {
|
||||
this.resetForm();
|
||||
this.setReviewerOptions();
|
||||
this.operationType = 'save';
|
||||
if (caseReview) {
|
||||
//修改
|
||||
this.operationType = 'edit';
|
||||
let tmp = {};
|
||||
Object.assign(tmp, caseReview);
|
||||
Object.assign(this.form, tmp);
|
||||
this.dbProjectIds = JSON.parse(JSON.stringify(this.form.projectIds));
|
||||
}
|
||||
listenGoBack(this.close);
|
||||
this.dialogFormVisible = true;
|
||||
},
|
||||
|
||||
saveReview() {
|
||||
this.$refs['reviewForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<el-menu-item index="functional">功能测试用例</el-menu-item>
|
||||
<el-menu-item index="api">接口测试用例</el-menu-item>
|
||||
<el-menu-item index="load">性能测试用例</el-menu-item>
|
||||
<el-menu-item index="report">报告统计</el-menu-item>
|
||||
<!-- <el-menu-item index="report">报告统计</el-menu-item>-->
|
||||
</el-menu>
|
||||
</template>
|
||||
</ms-test-plan-header-bar>
|
||||
|
@ -24,6 +24,7 @@
|
|||
:review-id="reviewId"></test-review-api>
|
||||
<test-review-load v-if="activeIndex === 'load'" :redirectCharType="redirectCharType" :clickType="clickType"
|
||||
:review-id="reviewId"></test-review-load>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
|
|
@ -1,55 +1,116 @@
|
|||
<template>
|
||||
<ms-test-plan-common-component>
|
||||
<template v-slot:aside>
|
||||
<ms-node-tree
|
||||
class="node-tree"
|
||||
:all-label="$t('commons.all_label.review')"
|
||||
v-loading="result.loading"
|
||||
<ms-api-module
|
||||
v-if="model === 'api'"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
:tree-nodes="treeNodes"
|
||||
ref="nodeTree"/>
|
||||
@protocolChange="handleProtocolChange"
|
||||
@refreshTable="refreshTable"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
:review-id="reviewId"
|
||||
:is-read-only="true"
|
||||
:redirectCharType="redirectCharType"
|
||||
ref="apiNodeTree"
|
||||
>
|
||||
<template v-slot:header>
|
||||
<div class="model-change-radio">
|
||||
<el-radio v-model="model" label="api">接口用例</el-radio>
|
||||
<el-radio v-model="model" label="scenario">场景用例</el-radio>
|
||||
</div>
|
||||
</template>
|
||||
</ms-api-module>
|
||||
|
||||
<ms-api-scenario-module
|
||||
v-if="model === 'scenario'"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
@refreshTable="refreshTable"
|
||||
@setModuleOptions="setModuleOptions"
|
||||
:is-read-only="true"
|
||||
:review-id="reviewId"
|
||||
ref="scenarioNodeTree">
|
||||
<template v-slot:header>
|
||||
<div class="model-change-radio">
|
||||
<el-radio v-model="model" label="api">接口用例</el-radio>
|
||||
<el-radio v-model="model" label="scenario">场景用例</el-radio>
|
||||
</div>
|
||||
</template>
|
||||
</ms-api-scenario-module>
|
||||
</template>
|
||||
<template v-slot:main>
|
||||
<test-review-test-case-list
|
||||
class="table-list"
|
||||
@openTestReviewRelevanceDialog="openTestReviewRelevanceDialog"
|
||||
@refresh="refresh"
|
||||
:review-id="reviewId"
|
||||
<test-plan-api-case-list
|
||||
v-if="model === 'api'"
|
||||
:current-protocol="currentProtocol"
|
||||
:currentRow="currentRow"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:trash-enable="trashEnable"
|
||||
:is-case-relevance="true"
|
||||
:model="'plan'"
|
||||
:review-id="reviewId"
|
||||
:clickType="clickType"
|
||||
@refresh="refreshTree"
|
||||
@relevanceCase="openTestCaseRelevanceDialog"
|
||||
ref="apiCaseList"/>
|
||||
|
||||
<ms-test-plan-api-scenario-list
|
||||
v-if="model === 'scenario'"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:select-parent-nodes="selectParentNodes"
|
||||
:trash-enable="trashEnable"
|
||||
:review-id="reviewId"
|
||||
:clickType="clickType"
|
||||
ref="testPlanTestCaseList"/>
|
||||
@refresh="refreshTree"
|
||||
@relevanceCase="openTestCaseRelevanceDialog"
|
||||
ref="apiScenarioList"/>
|
||||
</template>
|
||||
<test-review-relevance
|
||||
<test-case-api-relevance
|
||||
@refresh="refresh"
|
||||
:review-id="reviewId"
|
||||
ref="testReviewRelevance"/>
|
||||
:model="model"
|
||||
ref="apiCaseRelevance"/>
|
||||
<test-case-scenario-relevance
|
||||
@refresh="refresh"
|
||||
:review-id="reviewId"
|
||||
:model="model"
|
||||
ref="scenarioCaseRelevance"/>
|
||||
</ms-test-plan-common-component>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsTestPlanCommonComponent from "@/business/components/track/plan/view/comonents/base/TestPlanCommonComponent";
|
||||
import FunctionalTestCaseList from "@/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList";
|
||||
import MsNodeTree from "@/business/components/track/common/NodeTree";
|
||||
import TestReviewRelevance from "@/business/components/track/review/view/components/TestReviewRelevance";
|
||||
import TestReviewTestCaseList from "@/business/components/track/review/view/components/TestReviewTestCaseList";
|
||||
import TestCaseScenarioRelevance from "@/business/components/track/plan/view/comonents/api/TestCaseScenarioRelevance";
|
||||
import MsTestPlanApiScenarioList from "@/business/components/track/plan/view/comonents/api/TestPlanApiScenarioList";
|
||||
import MsApiScenarioModule from "@/business/components/api/automation/scenario/ApiScenarioModule";
|
||||
import ApiCaseSimpleList from "@/business/components/api/definition/components/list/ApiCaseSimpleList";
|
||||
import TestCaseApiRelevance from "@/business/components/track/plan/view/comonents/api/TestCaseApiRelevance";
|
||||
import TestPlanApiCaseList from "@/business/components/track/plan/view/comonents/api/TestPlanApiCaseList";
|
||||
import TestCaseRelevance from "@/business/components/track/plan/view/comonents/functional/TestCaseFunctionalRelevance";
|
||||
import NodeTree from "@/business/components/track/common/NodeTree";
|
||||
import MsApiModule from "../../../../api/definition/components/module/ApiModule"
|
||||
|
||||
export default {
|
||||
name: "TestReviewApi",
|
||||
components: {
|
||||
TestReviewTestCaseList,
|
||||
TestReviewRelevance, MsNodeTree, FunctionalTestCaseList, MsTestPlanCommonComponent
|
||||
TestCaseScenarioRelevance,
|
||||
MsTestPlanApiScenarioList,
|
||||
MsApiScenarioModule,
|
||||
ApiCaseSimpleList,
|
||||
TestCaseApiRelevance,
|
||||
TestPlanApiCaseList,
|
||||
MsTestPlanCommonComponent,
|
||||
TestCaseRelevance,
|
||||
NodeTree,
|
||||
MsApiModule,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
testReviews: [],
|
||||
currentReview: {},
|
||||
selectNodeIds: [],
|
||||
selectParentNodes: [],
|
||||
treeNodes: [],
|
||||
isMenuShow: true,
|
||||
currentRow: "",
|
||||
trashEnable: false,
|
||||
currentProtocol: null,
|
||||
currentModule: null,
|
||||
selectNodeIds: [],
|
||||
moduleOptions: {},
|
||||
model: 'api'
|
||||
}
|
||||
},
|
||||
props: [
|
||||
|
@ -58,32 +119,66 @@ export default {
|
|||
'clickType'
|
||||
],
|
||||
mounted() {
|
||||
this.getNodeTreeByReviewId()
|
||||
this.checkRedirectCharType();
|
||||
},
|
||||
activated() {
|
||||
this.getNodeTreeByReviewId()
|
||||
|
||||
watch: {
|
||||
model() {
|
||||
this.selectNodeIds = [];
|
||||
this.moduleOptions = {};
|
||||
},
|
||||
redirectCharType(){
|
||||
if(this.redirectCharType=='scenario'){
|
||||
this.model = 'scenario';
|
||||
}else{
|
||||
this.model = 'api';
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
refresh() {
|
||||
this.selectNodeIds = [];
|
||||
this.selectParentNodes = [];
|
||||
this.$refs.testReviewRelevance.search();
|
||||
this.getNodeTreeByReviewId();
|
||||
},
|
||||
nodeChange(node, nodeIds, pNodes) {
|
||||
this.selectNodeIds = nodeIds;
|
||||
this.selectParentNodes = pNodes;
|
||||
},
|
||||
getNodeTreeByReviewId() {
|
||||
if (this.reviewId) {
|
||||
this.result = this.$get("/case/node/list/review/" + this.reviewId, response => {
|
||||
this.treeNodes = response.data;
|
||||
});
|
||||
checkRedirectCharType(){
|
||||
if(this.redirectCharType=='scenario'){
|
||||
this.model = 'scenario';
|
||||
}else{
|
||||
this.model = 'api';
|
||||
}
|
||||
},
|
||||
openTestReviewRelevanceDialog() {
|
||||
this.$refs.testReviewRelevance.openTestReviewRelevanceDialog();
|
||||
refresh() {
|
||||
this.refreshTree();
|
||||
this.refreshTable();
|
||||
},
|
||||
refreshTable() {
|
||||
if (this.$refs.apiCaseList) {
|
||||
this.$refs.apiCaseList.initTable();
|
||||
}
|
||||
if (this.$refs.apiScenarioList) {
|
||||
this.$refs.apiScenarioList.search();
|
||||
}
|
||||
},
|
||||
refreshTree() {
|
||||
if (this.$refs.apiNodeTree) {
|
||||
this.$refs.apiNodeTree.list();
|
||||
}
|
||||
if (this.$refs.scenarioNodeTree) {
|
||||
this.$refs.scenarioNodeTree.list();
|
||||
}
|
||||
},
|
||||
|
||||
nodeChange(node, nodeIds, pNodes) {
|
||||
this.selectNodeIds = nodeIds;
|
||||
},
|
||||
handleProtocolChange(protocol) {
|
||||
this.currentProtocol = protocol;
|
||||
},
|
||||
setModuleOptions(data) {
|
||||
this.moduleOptions = data;
|
||||
},
|
||||
|
||||
openTestCaseRelevanceDialog(model) {
|
||||
if (model === 'scenario') {
|
||||
this.$refs.scenarioCaseRelevance.open();
|
||||
} else {
|
||||
this.$refs.apiCaseRelevance.open();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,55 +1,52 @@
|
|||
<template>
|
||||
<ms-test-plan-common-component>
|
||||
<template v-slot:aside>
|
||||
<ms-node-tree
|
||||
<node-tree
|
||||
class="node-tree"
|
||||
:all-label="$t('commons.all_label.review')"
|
||||
v-loading="result.loading"
|
||||
@nodeSelectEvent="nodeChange"
|
||||
:tree-nodes="treeNodes"
|
||||
ref="nodeTree"/>
|
||||
</template>
|
||||
<template v-slot:main>
|
||||
<test-review-test-case-list
|
||||
<test-plan-load-case-list
|
||||
class="table-list"
|
||||
@openTestReviewRelevanceDialog="openTestReviewRelevanceDialog"
|
||||
@refresh="refresh"
|
||||
:review-id="reviewId"
|
||||
:select-node-ids="selectNodeIds"
|
||||
:select-parent-nodes="selectParentNodes"
|
||||
:clickType="clickType"
|
||||
ref="testPlanTestCaseList"/>
|
||||
:select-project-id="selectProjectId"
|
||||
:select-parent-nodes="selectParentNodes"
|
||||
@relevanceCase="openTestCaseRelevanceDialog"
|
||||
ref="testPlanLoadCaseList"/>
|
||||
</template>
|
||||
<test-review-relevance
|
||||
<test-case-load-relevance
|
||||
@refresh="refresh"
|
||||
:review-id="reviewId"
|
||||
ref="testReviewRelevance"/>
|
||||
ref="testCaseLoadRelevance"/>
|
||||
</ms-test-plan-common-component>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsTestPlanCommonComponent from "@/business/components/track/plan/view/comonents/base/TestPlanCommonComponent";
|
||||
import FunctionalTestCaseList from "@/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList";
|
||||
import MsNodeTree from "@/business/components/track/common/NodeTree";
|
||||
import TestReviewRelevance from "@/business/components/track/review/view/components/TestReviewRelevance";
|
||||
import TestReviewTestCaseList from "@/business/components/track/review/view/components/TestReviewTestCaseList";
|
||||
|
||||
import NodeTree from "@/business/components/track/common/NodeTree";
|
||||
import TestPlanLoadCaseList from "@/business/components/track/plan/view/comonents/load/TestPlanLoadCaseList";
|
||||
import TestCaseLoadRelevance from "@/business/components/track/plan/view/comonents/load/TestCaseLoadRelevance";
|
||||
export default {
|
||||
name: "TestReviewLoad",
|
||||
components: {
|
||||
TestReviewTestCaseList,
|
||||
TestReviewRelevance, MsNodeTree, FunctionalTestCaseList, MsTestPlanCommonComponent
|
||||
MsTestPlanCommonComponent,
|
||||
NodeTree,
|
||||
TestPlanLoadCaseList,
|
||||
TestCaseLoadRelevance,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
testReviews: [],
|
||||
currentReview: {},
|
||||
selectNodeIds: [],
|
||||
selectParentNodes: [],
|
||||
selectProjectId: "",
|
||||
treeNodes: [],
|
||||
isMenuShow: true,
|
||||
}
|
||||
},
|
||||
props: [
|
||||
|
@ -57,34 +54,42 @@ export default {
|
|||
'redirectCharType',
|
||||
'clickType'
|
||||
],
|
||||
mounted() {
|
||||
this.getNodeTreeByReviewId()
|
||||
watch: {
|
||||
planId() {
|
||||
this.initData();
|
||||
}
|
||||
},
|
||||
activated() {
|
||||
this.getNodeTreeByReviewId()
|
||||
|
||||
mounted() {
|
||||
this.initData();
|
||||
},
|
||||
methods: {
|
||||
refresh() {
|
||||
this.selectNodeIds = [];
|
||||
this.selectProjectId = '';
|
||||
this.selectParentNodes = [];
|
||||
this.$refs.testReviewRelevance.search();
|
||||
this.getNodeTreeByReviewId();
|
||||
this.$refs.testPlanLoadCaseList.initTable();
|
||||
this.getNodeTreeByPlanId();
|
||||
},
|
||||
initData() {
|
||||
this.getNodeTreeByPlanId();
|
||||
},
|
||||
openTestCaseRelevanceDialog() {
|
||||
this.$refs.testCaseLoadRelevance.open();
|
||||
},
|
||||
nodeChange(node, nodeIds, pNodes) {
|
||||
this.selectNodeIds = nodeIds;
|
||||
this.selectParentNodes = pNodes;
|
||||
this.selectProjectId = node.key;
|
||||
// 切换node后,重置分页数
|
||||
this.$refs.testPlanLoadCaseList.currentPage = 1;
|
||||
this.$refs.testPlanLoadCaseList.pageSize = 10;
|
||||
},
|
||||
getNodeTreeByReviewId() {
|
||||
if (this.reviewId) {
|
||||
this.result = this.$get("/case/node/list/review/" + this.reviewId, response => {
|
||||
getNodeTreeByPlanId() {
|
||||
if (this.planId) {
|
||||
this.result = this.$get("/case/node/list/plan/" + this.planId, response => {
|
||||
this.treeNodes = response.data;
|
||||
// 性能测试与模块无关,过滤项目下模块
|
||||
this.treeNodes.map(node => node.children = null);
|
||||
});
|
||||
}
|
||||
},
|
||||
openTestReviewRelevanceDialog() {
|
||||
this.$refs.testReviewRelevance.openTestReviewRelevanceDialog();
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -39,11 +39,14 @@
|
|||
<el-divider direction="vertical"></el-divider>
|
||||
|
||||
<el-button type="success" size="mini"
|
||||
:disabled="isReadOnly" :icon="testCase.reviewStatus === 'Pass' ? 'el-icon-check' : ''" @click="saveCase('Pass')">
|
||||
:disabled="isReadOnly" :icon="testCase.reviewStatus === 'Pass' ? 'el-icon-check' : ''"
|
||||
@click="saveCase('Pass')">
|
||||
{{ $t('test_track.review.pass') }}
|
||||
</el-button>
|
||||
<el-button type="danger" size="mini"
|
||||
:disabled="isReadOnly" :icon="testCase.reviewStatus === 'UnPass' ? 'el-icon-check' : ''" @click="saveCase('UnPass')">
|
||||
:disabled="isReadOnly"
|
||||
:icon="testCase.reviewStatus === 'UnPass' ? 'el-icon-check' : ''"
|
||||
@click="saveCase('UnPass')">
|
||||
{{ $t('test_track.review.un_pass') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
@ -66,29 +69,22 @@
|
|||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="cast_label">{{ $t('test_track.case.case_type') }}:</span>
|
||||
<span class="cast_item" v-if="testCase.type === 'functional'">{{
|
||||
$t('commons.functional')
|
||||
}}</span>
|
||||
<span class="cast_item" v-if="testCase.type === 'automation'">
|
||||
场景用例
|
||||
</span>
|
||||
<span class="cast_item"
|
||||
v-if="testCase.type === 'performance'">{{ $t('commons.performance') }}</span>
|
||||
<span class="cast_item" v-if="testCase.type === 'api'">{{ $t('commons.api') }}</span>
|
||||
<span class="cast_item" v-if="testCase.type === 'testcase'">接口用例</span>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="4" :offset="1">
|
||||
<span class="cast_label">{{ $t('test_track.case.method') }}:</span>
|
||||
<span v-if="testCase.method === 'manual'">{{ $t('test_track.case.manual') }}</span>
|
||||
<span v-if="testCase.method === 'auto'">{{ $t('test_track.case.auto') }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-col :offset="1">
|
||||
<span class="cast_label">{{ $t('test_track.case.module') }}:</span>
|
||||
<span class="cast_item">{{ testCase.nodePath }}</span>
|
||||
</el-col>
|
||||
<el-col :span="4" :offset="1">
|
||||
<span class="cast_label">{{ $t('test_track.plan.plan_project') }}:</span>
|
||||
<span class="cast_item">{{ testCase.projectName }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
|
@ -98,7 +94,7 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row v-if="testCase.method === 'auto' && testCase.testId">
|
||||
<el-row>
|
||||
<el-col class="test-detail" :span="20" :offset="1">
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<el-tab-pane name="detail" :label="$t('test_track.plan_view.test_detail')">
|
||||
|
@ -108,12 +104,17 @@
|
|||
:is-read-only="true"
|
||||
:id="testCase.testId"
|
||||
ref="performanceTestDetail"/>
|
||||
<api-case-item :type="mark" :api="api" :api-case="apiCase" v-if="testCase.type==='testcase'"
|
||||
ref="apiCaseConfig"/>
|
||||
<ms-edit-api-scenario :type="mark" v-if="testCase.type==='automation'" :currentScenario="currentScenario"
|
||||
ref="autoScenarioConfig"></ms-edit-api-scenario>
|
||||
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row v-if="testCase.method && testCase.method !== 'auto'">
|
||||
<el-row v-if="testCase.type === 'function'">
|
||||
<el-col :span="20" :offset="1">
|
||||
<div>
|
||||
<span class="cast_label">{{ $t('test_track.case.steps') }}:</span>
|
||||
|
@ -229,7 +230,8 @@
|
|||
<i class="el-icon-refresh" @click="getComments(testCase)"
|
||||
style="margin-left:10px;font-size: 14px; cursor: pointer"/>
|
||||
</template>
|
||||
<review-comment :comments="comments" :case-id="testCase.caseId" :review-id="testCase.reviewId" @getComments="getComments"/>
|
||||
<review-comment :comments="comments" :case-id="testCase.caseId" :review-id="testCase.reviewId"
|
||||
@getComments="getComments"/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</div>
|
||||
|
@ -248,9 +250,11 @@ import PerformanceTestDetail from "../../../plan/view/comonents/test/Performance
|
|||
import ApiTestResult from "../../../plan/view/comonents/test/ApiTestResult";
|
||||
import ApiTestDetail from "../../../plan/view/comonents/test/ApiTestDetail";
|
||||
import TestPlanTestCaseStatusButton from "../../../plan/common/TestPlanTestCaseStatusButton";
|
||||
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||
import {getCurrentProjectID, listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||
import ReviewComment from "../../commom/ReviewComment";
|
||||
import TestCaseAttachment from "@/business/components/track/case/components/TestCaseAttachment";
|
||||
import ApiCaseItem from "@/business/components/api/definition/components/case/ApiCaseItem";
|
||||
import MsEditApiScenario from "@/business/components/api/automation/scenario/EditApiScenario"
|
||||
|
||||
export default {
|
||||
name: "TestReviewTestCaseEdit",
|
||||
|
@ -261,7 +265,10 @@ export default {
|
|||
ApiTestDetail,
|
||||
TestPlanTestCaseStatusButton,
|
||||
ReviewComment,
|
||||
TestCaseAttachment
|
||||
TestCaseAttachment,
|
||||
ApiCaseItem,
|
||||
MsEditApiScenario
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -277,7 +284,11 @@ export default {
|
|||
users: [],
|
||||
activeName: 'comment',
|
||||
comments: [],
|
||||
tableData: []
|
||||
tableData: [],
|
||||
currentScenario: {},
|
||||
mark: 'detail',
|
||||
api: {},
|
||||
apiCase: {},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
|
@ -378,16 +389,55 @@ export default {
|
|||
listenGoBack(this.handleClose);
|
||||
this.initData(testCase);
|
||||
this.getComments(testCase);
|
||||
this.getApiTestCase(testCase);
|
||||
this.getCurrentScenario(testCase)
|
||||
},
|
||||
getApiTestCase(testCase) {
|
||||
let param = {}
|
||||
param.projectId = getCurrentProjectID();
|
||||
param.id = testCase.testId;
|
||||
this.result = this.$post("/api/testcase/list", param, response => {
|
||||
let apiCaseList = []
|
||||
this.apiCaseList = response.data;
|
||||
this.apiCaseList.forEach(apiCase => {
|
||||
if (apiCase.tags && apiCase.tags.length > 0) {
|
||||
apiCase.tags = JSON.parse(apiCase.tags);
|
||||
this.$set(apiCase, 'selected', false);
|
||||
}
|
||||
if (Object.prototype.toString.call(apiCase.request).match(/\[object (\w+)\]/)[1].toLowerCase() != 'object') {
|
||||
apiCase.request = JSON.parse(apiCase.request);
|
||||
}
|
||||
if (!apiCase.request.hashTree) {
|
||||
apiCase.request.hashTree = [];
|
||||
}
|
||||
this.apiCase = apiCase
|
||||
this.handleTestCase(apiCase)
|
||||
})
|
||||
|
||||
});
|
||||
},
|
||||
getCurrentScenario(testCase) {
|
||||
this.result = this.$get("/api/automation/getApiScenario/" + testCase.testId, response => {
|
||||
this.currentScenario=response.data
|
||||
});
|
||||
},
|
||||
|
||||
handleTestCase(testCase) {
|
||||
this.$get('/api/definition/get/' + testCase.apiDefinitionId, (response) => {
|
||||
this.api = response.data;
|
||||
});
|
||||
},
|
||||
initTest() {
|
||||
this.$nextTick(() => {
|
||||
if (this.testCase.testId && this.testCase.testId !== 'other') {
|
||||
if (this.testCase.method === 'auto') {
|
||||
if (this.$refs.apiTestDetail && this.testCase.type === 'api') {
|
||||
this.$refs.apiTestDetail.init();
|
||||
} else if (this.testCase.type === 'performance') {
|
||||
this.$refs.performanceTestDetail.init();
|
||||
}
|
||||
if (this.$refs.apiTestDetail && this.testCase.type === 'api') {
|
||||
this.$refs.apiTestDetail.init();
|
||||
} else if (this.testCase.type === 'performance') {
|
||||
this.$refs.performanceTestDetail.init();
|
||||
} else if (this.testCase.type === 'testcase') {
|
||||
this.$refs.apiCaseConfig.active(this.api);
|
||||
} else if (this.testCase.type === 'automation') {
|
||||
this.$refs.autoScenarioConfig.showAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
<!-- <el-table-column
|
||||
v-if="item.id=='method'"
|
||||
prop="method"
|
||||
:filters="methodFilters"
|
||||
|
@ -95,7 +95,7 @@
|
|||
<template v-slot:default="scope">
|
||||
<method-table-item :value="scope.row.method"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>-->
|
||||
|
||||
<el-table-column
|
||||
v-if="item.id=='nodePath'"
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e4422e1dc640704febfbf469185cd85b78d2147a
|
||||
Subproject commit 360d7214d15951ae11b3973add795305a5c3d035
|
|
@ -187,7 +187,7 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: 1440px;
|
||||
width: 1200px;
|
||||
height: 810px;
|
||||
margin: calc((100vh - 810px) / 2) auto 0;
|
||||
background-color: #FFFFFF;
|
||||
|
@ -294,6 +294,7 @@ body {
|
|||
color: #2B415C;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
margin: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.form .el-input > .el-input__inner {
|
||||
|
|
Loading…
Reference in New Issue