diff --git a/backend/src/main/java/io/metersphere/api/controller/APITestController.java b/backend/src/main/java/io/metersphere/api/controller/APITestController.java index 78b90cec9f..82e2ec81e8 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APITestController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APITestController.java @@ -314,11 +314,7 @@ public class APITestController { apiCountResult.setThisWeekExecutedCount(executedInThisWeekCountNumber); //统计 失败 成功 以及总数 -// List api_allExecuteResult = apiReportService.countByProjectIdGroupByExecuteResult(projectId); List allExecuteResult = apiScenarioReportService.countByProjectIdGroupByExecuteResult(projectId); -// List allExecuteResult = new ArrayList<>(); -// allExecuteResult.addAll(api_allExecuteResult); -// allExecuteResult.addAll(scene_allExecuteResult); apiCountResult.countScheduleExecute(allExecuteResult); long allCount = apiCountResult.getExecutedCount(); diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java index 2ce942c37f..d5de0424a9 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiDefinitionController.java @@ -216,4 +216,6 @@ public class ApiDefinitionController { public String preview(@RequestBody String jsonSchema) { return JSONSchemaGenerator.getJson(jsonSchema); } + + } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java b/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java index 8c28f72bbc..7566659b14 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/ApiBatchRequest.java @@ -33,4 +33,6 @@ public class ApiBatchRequest extends ApiDefinitionWithBLOBs { private List unSelectIds; + private String moduleId; + } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java index b328123763..deac3e8a7f 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsTestElement.java @@ -98,6 +98,8 @@ public abstract class MsTestElement { private String refType; @JSONField(ordinal = 10) private LinkedList hashTree; + @JSONField(ordinal = 11) + private boolean customizeReq; private MsTestElement parent; @@ -188,15 +190,14 @@ public abstract class MsTestElement { csvDataSet.setEnabled(true); csvDataSet.setProperty(TestElement.TEST_CLASS, CSVDataSet.class.getName()); csvDataSet.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); - csvDataSet.setName(item.getName()); - csvDataSet.setProperty("fileEncoding", item.getEncoding()); - csvDataSet.setProperty("variableNames", item.getName()); + csvDataSet.setName(StringUtils.isEmpty(item.getName()) ? "CSVDataSet" : item.getName()); + csvDataSet.setProperty("fileEncoding", StringUtils.isEmpty(item.getEncoding()) ? "UTF-8" : item.getEncoding()); if (CollectionUtils.isNotEmpty(item.getFiles())) { csvDataSet.setProperty("filename", BODY_FILE_DIR + "/" + item.getFiles().get(0).getId() + "_" + item.getFiles().get(0).getName()); } csvDataSet.setIgnoreFirstLine(false); csvDataSet.setProperty("delimiter", item.getDelimiter()); - csvDataSet.setComment(item.getDescription()); + csvDataSet.setComment(StringUtils.isEmpty(item.getDescription()) ? "" : item.getDescription()); tree.add(csvDataSet); }); } @@ -218,7 +219,7 @@ public abstract class MsTestElement { counterConfig.setVarName(item.getName()); counterConfig.setIncrement(item.getIncrement()); counterConfig.setFormat(item.getValue()); - counterConfig.setComment(item.getDescription()); + counterConfig.setComment(StringUtils.isEmpty(item.getDescription()) ? "" : item.getDescription()); tree.add(counterConfig); }); } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java index 842e0acab8..2bb35dab13 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/assertions/MsAssertions.java @@ -6,6 +6,7 @@ import io.metersphere.api.dto.definition.request.ParameterConfig; import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.jmeter.assertions.*; import org.apache.jmeter.save.SaveService; import org.apache.jmeter.testelement.TestElement; @@ -89,7 +90,7 @@ public class MsAssertions extends MsTestElement { private JSONPathAssertion jsonPathAssertion(MsAssertionJsonPath assertionJsonPath) { JSONPathAssertion assertion = new JSONPathAssertion(); assertion.setEnabled(true); - assertion.setName(assertionJsonPath.getDescription()); + assertion.setName(StringUtils.isEmpty(assertionJsonPath.getDescription()) ? "JSONPathAssertion" : assertionJsonPath.getDescription()); assertion.setProperty(TestElement.TEST_CLASS, JSONPathAssertion.class.getName()); assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("JSONPathAssertionGui")); assertion.setJsonPath(assertionJsonPath.getExpression()); @@ -104,7 +105,7 @@ public class MsAssertions extends MsTestElement { private XPath2Assertion xPath2Assertion(MsAssertionXPath2 assertionXPath2) { XPath2Assertion assertion = new XPath2Assertion(); assertion.setEnabled(true); - assertion.setName(assertionXPath2.getExpression()); + assertion.setName(StringUtils.isEmpty(assertionXPath2.getExpression()) ? "XPath2Assertion" : assertionXPath2.getExpression()); assertion.setProperty(TestElement.TEST_CLASS, XPath2Assertion.class.getName()); assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("XPath2AssertionGui")); assertion.setXPathString(assertionXPath2.getExpression()); @@ -125,7 +126,7 @@ public class MsAssertions extends MsTestElement { private JSR223Assertion jsr223Assertion(MsAssertionJSR223 assertionJSR223) { JSR223Assertion assertion = new JSR223Assertion(); assertion.setEnabled(true); - assertion.setName(assertionJSR223.getDesc()); + assertion.setName(StringUtils.isEmpty(assertionJSR223.getDesc()) ? "JSR223Assertion" : assertionJSR223.getDesc()); assertion.setProperty(TestElement.TEST_CLASS, JSR223Assertion.class.getName()); assertion.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); assertion.setProperty("cacheKey", "true"); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java index 61a22081cf..acbfa04709 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsIfController.java @@ -42,10 +42,10 @@ public class MsIfController extends MsTestElement { private IfController ifController() { IfController ifController = new IfController(); ifController.setEnabled(true); - ifController.setName(this.getLabelName()); - ifController.setCondition(this.getCondition()); + ifController.setName(StringUtils.isEmpty(this.getName()) ? "IfController" : this.getName()); ifController.setProperty(TestElement.TEST_CLASS, IfController.class.getName()); ifController.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("IfControllerPanel")); + ifController.setCondition(this.getCondition()); ifController.setEvaluateAll(false); ifController.setUseExpression(true); return ifController; @@ -79,13 +79,13 @@ public class MsIfController extends MsTestElement { } if (StringUtils.equals(operator, "is empty")) { - variable = "empty(" + variable + ")"; + variable = "!empty(" + variable + ")"; operator = ""; value = ""; } if (StringUtils.equals(operator, "is not empty")) { - variable = "!empty(" + variable + ")"; + variable = "empty(" + variable + ")"; operator = ""; value = ""; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java index e82c9b07bb..3d05319d2b 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/controller/MsLoopController.java @@ -123,13 +123,13 @@ public class MsLoopController extends MsTestElement { } if (StringUtils.equals(operator, "is empty")) { - variable = "empty(" + variable + ")"; + variable = "!empty(" + variable + ")"; operator = ""; value = ""; } if (StringUtils.equals(operator, "is not empty")) { - variable = "!empty(" + variable + ")"; + variable = "empty(" + variable + ")"; operator = ""; value = ""; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java index 295890e786..28a78a6e4c 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/extract/MsExtract.java @@ -57,7 +57,7 @@ public class MsExtract extends MsTestElement { if (Optional.ofNullable(extract).orElse(extract).length() > 0) { JSR223PostProcessor shell = new JSR223PostProcessor(); shell.setEnabled(true); - shell.setName(this.getName()); + shell.setName(StringUtils.isEmpty(this.getName()) ? "JSR223PostProcessor" : this.getName()); shell.setProperty(TestElement.TEST_CLASS, JSR223PostProcessor.class.getName()); shell.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI")); shell.setProperty("script", "io.metersphere.api.jmeter.JMeterVars.addVars(prev.hashCode(),vars," + "\"" + extract.toString() + "\"" + ");"); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java index 702d3326a4..676fa3a8a4 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsHTTPSamplerProxy.java @@ -207,14 +207,17 @@ public class MsHTTPSamplerProxy extends MsTestElement { } final HashTree httpSamplerTree = tree.add(sampler); + + // 注意顺序,放在config前面,会优先于环境的请求头生效 + if (CollectionUtils.isNotEmpty(this.headers)) { + setHeader(httpSamplerTree, this.headers); + } + // 通用请求Headers if (config != null && config.getConfig() != null && config.getConfig().getHttpConfig() != null && CollectionUtils.isNotEmpty(config.getConfig().getHttpConfig().getHeaders())) { setHeader(httpSamplerTree, config.getConfig().getHttpConfig().getHeaders()); } - if (CollectionUtils.isNotEmpty(this.headers)) { - setHeader(httpSamplerTree, this.headers); - } //判断是否要开启DNS if (config != null && config.getConfig() != null && config.getConfig().getCommonConfig() != null diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java index 3eb20a8b99..dcd0bb5f19 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsJDBCSampler.java @@ -96,7 +96,7 @@ public class MsJDBCSampler extends MsTestElement { private Arguments arguments(String name, List variables) { Arguments arguments = new Arguments(); - if (!variables.isEmpty()) { + if (CollectionUtils.isNotEmpty(variables)) { arguments.setEnabled(true); arguments.setName(name); arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName()); diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java index 50c790534b..0e0031ace9 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/sampler/MsTCPSampler.java @@ -12,6 +12,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.jmeter.config.Arguments; import org.apache.jmeter.config.ConfigTestElement; import org.apache.jmeter.modifiers.UserParameters; import org.apache.jmeter.protocol.tcp.sampler.TCPSampler; @@ -79,6 +80,13 @@ public class MsTCPSampler extends MsTestElement { } config.setConfig(getEnvironmentConfig(useEnvironment)); parseEnvironment(config.getConfig()); + + // 添加环境中的公共变量 + Arguments arguments = this.addArguments(config); + if (arguments != null) { + tree.add(this.addArguments(config)); + } + final HashTree samplerHashTree = new ListedHashTree(); samplerHashTree.add(tcpConfig()); tree.set(tcpSampler(config), samplerHashTree); @@ -94,7 +102,7 @@ public class MsTCPSampler extends MsTestElement { } private void parseEnvironment(EnvironmentConfig config) { - if (config != null && config.getTcpConfig() != null) { + if (!isCustomizeReq() && config != null && config.getTcpConfig() != null) { this.server = config.getTcpConfig().getServer(); this.port = config.getTcpConfig().getPort(); } diff --git a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java index 262036e359..3923ea49e6 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -2,6 +2,7 @@ package io.metersphere.api.jmeter; import io.metersphere.api.dto.scenario.request.RequestType; import io.metersphere.api.service.*; +import io.metersphere.base.domain.ApiDefinitionExecResult; import io.metersphere.base.domain.ApiScenarioReport; import io.metersphere.base.domain.ApiTestReport; import io.metersphere.commons.constants.*; @@ -177,10 +178,17 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl } else if (StringUtils.equals(this.runMode, ApiRunMode.JENKINS.name())) { apiDefinitionService.addResult(testResult); apiDefinitionExecResultService.saveApiResult(testResult, ApiRunMode.DEFINITION.name()); - apiTestService.changeStatus(testId, APITestStatus.Completed); - report = apiReportService.getRunningReport(testResult.getTestId()); - apiReportService.complete(testResult, report); + + } else if (StringUtils.equals(this.runMode, ApiRunMode.JENKINS_API_PLAN.name())) { + apiDefinitionService.addResult(testResult); apiDefinitionExecResultService.saveApiResult(testResult, ApiRunMode.API_PLAN.name()); + ApiDefinitionExecResult result = new ApiDefinitionExecResult(); + result = apiDefinitionService.getResultByJenkins(debugReportId, ApiRunMode.API_PLAN.name()); + report = new ApiTestReport(); + report.setStatus(result.getStatus()); + report.setId(result.getId()); + report.setTriggerMode(ApiRunMode.API.name()); + report.setName(apiDefinitionService.getApiCaseInfo(testId).getName()); } else if (StringUtils.equalsAny(this.runMode, ApiRunMode.API_PLAN.name(), ApiRunMode.SCHEDULE_API_PLAN.name())) { apiDefinitionService.addResult(testResult); @@ -264,9 +272,15 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl if (StringUtils.equals("Success", report.getStatus())) { event = NoticeConstants.Event.EXECUTE_SUCCESSFUL; } + if (StringUtils.equals("success", report.getStatus())) { + event = NoticeConstants.Event.EXECUTE_SUCCESSFUL; + } if (StringUtils.equals("Error", report.getStatus())) { event = NoticeConstants.Event.EXECUTE_FAILED; } + if (StringUtils.equals("error", report.getStatus())) { + event = NoticeConstants.Event.EXECUTE_FAILED; + } Map paramMap = new HashMap<>(); paramMap.put("testName", report.getName()); paramMap.put("id", report.getId()); diff --git a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java index c8914871e7..77cdebca8b 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/TestResult.java @@ -60,6 +60,18 @@ public class TestResult { item.getSubRequestResults().forEach(subItem -> { subItem.setName(item.getName()); }); + } else { + if (requestResultMap.containsKey(result.getName())) { + requestResultMap.get(result.getName()).add(item); + } else { + List requestResults = new LinkedList<>(); + requestResults.add(item); + requestResultMap.put(result.getName(), requestResults); + } + item.getSubRequestResults().forEach(subItem -> { + subItem.setName(item.getName()); + }); + } }); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java index 7f15aff6e6..4964958aef 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -86,23 +86,33 @@ public class ApiAutomationService { private TestPlanScenarioCaseService testPlanScenarioCaseService; public List list(ApiScenarioRequest request) { - request = this.initRequest(request,true,true); + request = this.initRequest(request, true, true); List list = extApiScenarioMapper.list(request); return list; } /** * 初始化部分参数 + * * @param request * @param setDefultOrders * @param checkThisWeekData * @return */ - private ApiScenarioRequest initRequest(ApiScenarioRequest request,boolean setDefultOrders, boolean checkThisWeekData) { - if(setDefultOrders){ + private ApiScenarioRequest initRequest(ApiScenarioRequest request, boolean setDefultOrders, boolean checkThisWeekData) { + if (setDefultOrders) { request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); } - if(checkThisWeekData){ + if(StringUtils.isNotEmpty(request.getExecuteStatus())){ + Map> statusFilter = new HashMap<>(); + List list = new ArrayList<>(); + list.add("Prepare"); + list.add("Underway"); + list.add("Completed"); + statusFilter.put("status",list); + request.setFilters(statusFilter); + } + if (checkThisWeekData) { if (request.isSelectThisWeedData()) { Map weekFirstTimeAndLastTime = DateUtils.getWeedFirstTimeAndLastTime(new Date()); Date weekFirstTime = weekFirstTimeAndLastTime.get("firstTime"); @@ -217,7 +227,7 @@ public class ApiAutomationService { ids.add(scenarioId); deleteApiScenarioReport(ids); - scheduleService.deleteScheduleAndJobByResourceId(scenarioId,ScheduleGroup.API_SCENARIO_TEST.name()); + scheduleService.deleteScheduleAndJobByResourceId(scenarioId, ScheduleGroup.API_SCENARIO_TEST.name()); TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); example.createCriteria().andApiScenarioIdEqualTo(scenarioId); List testPlanApiScenarioList = testPlanApiScenarioMapper.selectByExample(example); @@ -284,7 +294,7 @@ public class ApiAutomationService { extApiScenarioMapper.removeToGc(apiIds); //将这些场景的定时任务删除掉 for (String id : apiIds) { - scheduleService.deleteScheduleAndJobByResourceId(id,ScheduleGroup.API_SCENARIO_TEST.name()); + scheduleService.deleteScheduleAndJobByResourceId(id, ScheduleGroup.API_SCENARIO_TEST.name()); } } @@ -372,7 +382,7 @@ public class ApiAutomationService { try { boolean isFirst = true; for (ApiScenarioWithBLOBs item : apiScenarios) { - if (item.getStepTotal() == 0) { + if (item.getStepTotal() == null || item.getStepTotal() == 0) { // 只有一个场景且没有测试步骤,则提示 if (apiScenarios.size() == 1) { MSException.throwException((item.getName() + "," + Translator.get("automation_exec_info"))); @@ -412,14 +422,14 @@ public class ApiAutomationService { // 创建场景报告 if (reportIds != null) { //如果是测试计划页面触发的执行方式,生成报告时createScenarioReport第二个参数需要特殊处理 - if(StringUtils.equals(request.getRunMode(),ApiRunMode.SCENARIO_PLAN.name())){ + if (StringUtils.equals(request.getRunMode(), ApiRunMode.SCENARIO_PLAN.name())) { String testPlanScenarioId = item.getId(); - if(request.getScenarioTestPlanIdMap()!=null&&request.getScenarioTestPlanIdMap().containsKey(item.getId())){ + if (request.getScenarioTestPlanIdMap() != null && request.getScenarioTestPlanIdMap().containsKey(item.getId())) { testPlanScenarioId = request.getScenarioTestPlanIdMap().get(item.getId()); } createScenarioReport(group.getName(), testPlanScenarioId, item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), request.getExecuteType(), item.getProjectId(), request.getReportUserID()); - }else{ + } else { createScenarioReport(group.getName(), item.getId(), item.getName(), request.getTriggerMode() == null ? ReportTriggerMode.MANUAL.name() : request.getTriggerMode(), request.getExecuteType(), item.getProjectId(), request.getReportUserID()); } @@ -449,6 +459,8 @@ public class ApiAutomationService { ids = this.getAllScenarioIdsByFontedSelect( request.getModuleIds(), request.getName(), request.getProjectId(), request.getFilters(), request.getUnSelectIds()); } + //检查是否有正在执行中的情景 + this.checkScenarioIsRunnng(ids); List apiScenarios = extApiScenarioMapper.selectIds(ids); String runMode = ApiRunMode.SCENARIO.name(); @@ -465,6 +477,15 @@ public class ApiAutomationService { return request.getId(); } + public void checkScenarioIsRunnng(List ids) { + List lastReportStatusByIds = apiReportService.selectLastReportByIds(ids); + for (ApiScenarioReport report : lastReportStatusByIds) { + if(StringUtils.equals(report.getStatus(),APITestStatus.Running.name())){ + MSException.throwException(report.getName()+" Is Running!"); + } + } + } + /** * 获取前台查询条件查询的所有(未经分页筛选)数据ID * @@ -506,7 +527,6 @@ public class ApiAutomationService { ParameterConfig config = new ParameterConfig(); config.setConfig(envConfig); HashTree hashTree = request.getTestElement().generateHashTree(config); - // 调用执行方法 createScenarioReport(request.getId(), request.getScenarioId(), request.getScenarioName(), ReportTriggerMode.MANUAL.name(), request.getExecuteType(), request.getProjectId(), SessionUtils.getUserId()); @@ -635,10 +655,10 @@ public class ApiAutomationService { } private void addOrUpdateApiScenarioCronJob(Schedule request) { - if(StringUtils.equals(request.getGroup(),ScheduleGroup.TEST_PLAN_TEST.name())){ + if (StringUtils.equals(request.getGroup(), ScheduleGroup.TEST_PLAN_TEST.name())) { scheduleService.addOrUpdateCronJob( request, TestPlanTestJob.getJobKey(request.getResourceId()), TestPlanTestJob.getTriggerKey(request.getResourceId()), TestPlanTestJob.class); - }else{ + } else { scheduleService.addOrUpdateCronJob( request, ApiScenarioTestJob.getJobKey(request.getResourceId()), ApiScenarioTestJob.getTriggerKey(request.getResourceId()), ApiScenarioTestJob.class); } @@ -707,7 +727,9 @@ public class ApiAutomationService { apiScenarios.forEach(item -> { JSONObject object = JSONObject.parseObject(item.getScenarioDefinition()); object.put("environmentId", request.getEnvironmentId()); - item.setScenarioDefinition(JSONObject.toJSONString(object)); + if (object != null) { + item.setScenarioDefinition(JSONObject.toJSONString(object)); + } apiScenarioMapper.updateByPrimaryKeySelective(item); }); } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java index 390043a1ff..66143cb04d 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiDefinitionService.java @@ -82,6 +82,8 @@ public class ApiDefinitionService { private ExtSwaggerUrlScheduleMapper extSwaggerUrlScheduleMapper; @Resource private ScheduleMapper scheduleMapper; + @Resource + private ApiTestCaseMapper apiTestCaseMapper; private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24); @@ -348,7 +350,8 @@ public class ApiDefinitionService { private String setImportHashTree(ApiDefinitionWithBLOBs apiDefinition) { String request = apiDefinition.getRequest(); MsHTTPSamplerProxy msHTTPSamplerProxy = JSONObject.parseObject(request, MsHTTPSamplerProxy.class); - msHTTPSamplerProxy.setHashTree(null); + msHTTPSamplerProxy.setId(apiDefinition.getId()); + msHTTPSamplerProxy.setHashTree(new LinkedList<>()); apiDefinition.setRequest(JSONObject.toJSONString(msHTTPSamplerProxy)); return request; } @@ -468,6 +471,14 @@ public class ApiDefinitionService { return buildAPIReportResult(result); } + public ApiDefinitionExecResult getResultByJenkins(String testId, String type) { + return extApiDefinitionExecResultMapper.selectMaxResultByResourceIdAndType(testId, type); + } + + public ApiTestCaseWithBLOBs getApiCaseInfo(String apiCaseId) { + return apiTestCaseMapper.selectByPrimaryKey(apiCaseId); + } + public ApiDefinitionImport apiTestImport(MultipartFile file, ApiTestImportRequest request) { ApiImportParser apiImportParser = ApiImportParserFactory.getApiImportParser(request.getPlatform()); diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java index 6c945f5d2e..7469f8a987 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -415,4 +415,12 @@ public class ApiScenarioReportService { public List countByProjectIdGroupByExecuteResult(String projectId) { return extApiScenarioReportMapper.countByProjectIdGroupByExecuteResult(projectId); } + + public List selectLastReportByIds(List ids) { + if(!ids.isEmpty()){ + return extApiScenarioReportMapper.selectLastReportByIds(ids); + }else { + return new ArrayList<>(0); + } + } } diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index f612b84f64..6ccaf75c36 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -473,7 +473,7 @@ public class ApiTestCaseService { String runMode = ApiRunMode.JENKINS.name(); */ // 调用执行方法 - jMeterService.runDefinition(request.getReportId(), jmeterHashTree, request.getReportId(), request.getRunMode()); + jMeterService.runDefinition(request.getCaseId(), jmeterHashTree, request.getReportId(), request.getRunMode()); } catch (Exception ex) { LogUtil.error(ex.getMessage()); diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml index 415d22029b..7dce263d4f 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml @@ -304,7 +304,7 @@ diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.java index 425ec646de..8fd7e161be 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.java +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.java @@ -3,6 +3,7 @@ package io.metersphere.base.mapper.ext; import io.metersphere.api.dto.QueryAPIReportRequest; import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.dto.datacount.ApiDataCountResult; +import io.metersphere.base.domain.ApiScenarioReport; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; @@ -20,4 +21,6 @@ public interface ExtApiScenarioReportMapper { long countByProjectIdAndCreateAndByScheduleInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp); List countByProjectIdGroupByExecuteResult(String projectId); + + List selectLastReportByIds(@Param("scenarioIdList") List ids); } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml index 8acd2c9948..5a552d03e3 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml @@ -194,4 +194,26 @@ WHERE acr.project_id = #{projectId} AND ar.trigger_mode = 'SCHEDULE' GROUP BY groupField; + + \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtFileContentMapper.java b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtFileContentMapper.java new file mode 100644 index 0000000000..badbe41a23 --- /dev/null +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtFileContentMapper.java @@ -0,0 +1,15 @@ +package io.metersphere.base.mapper.ext; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.io.InputStream; + +public interface ExtFileContentMapper { + @Select(value = { + "SELECT file ", + "FROM file_content ", + "WHERE file_id = #{id, jdbcType=VARCHAR}" + }) + InputStream selectZipBytes(@Param("id") String id); +} diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml index fb5e0b81ba..c1676447e5 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportMapper.xml @@ -4,10 +4,12 @@ @@ -393,4 +393,8 @@ border-left: 4px solid #783887; margin: 0px 0px 10px; } + .ms-transform { + transform: rotate(-180deg); + transition: 0ms; + } diff --git a/frontend/src/business/components/performance/report/PerformanceReportView.vue b/frontend/src/business/components/performance/report/PerformanceReportView.vue index 1257af30cd..13a512d91e 100644 --- a/frontend/src/business/components/performance/report/PerformanceReportView.vue +++ b/frontend/src/business/components/performance/report/PerformanceReportView.vue @@ -293,12 +293,12 @@ export default { }; this.result = this.$request(config).then(response => { const content = response.data; - const blob = new Blob([content]); + const blob = new Blob([content], {type: "application/octet-stream"}); if ("download" in document.createElement("a")) { // 非IE下载 // chrome/firefox let aTag = document.createElement('a'); - aTag.download = this.reportId + ".jtl"; + aTag.download = this.reportId + ".zip"; aTag.href = URL.createObjectURL(blob); aTag.click(); URL.revokeObjectURL(aTag.href) diff --git a/frontend/src/business/components/settings/organization/OrganizationWorkspace.vue b/frontend/src/business/components/settings/organization/OrganizationWorkspace.vue index 44dfbfb158..f26c83f681 100644 --- a/frontend/src/business/components/settings/organization/OrganizationWorkspace.vue +++ b/frontend/src/business/components/settings/organization/OrganizationWorkspace.vue @@ -10,8 +10,9 @@ @@ -506,7 +507,6 @@ .member-size { text-decoration: underline; - cursor: pointer; } .select-width { diff --git a/frontend/src/business/components/settings/personal/PersonSetting.vue b/frontend/src/business/components/settings/personal/PersonSetting.vue index 79ce46bc13..6bbf92a0f3 100644 --- a/frontend/src/business/components/settings/personal/PersonSetting.vue +++ b/frontend/src/business/components/settings/personal/PersonSetting.vue @@ -114,9 +114,7 @@ export default { } ], phone: [ - {required: true, message: this.$t('user.input_phone'), trigger: 'blur'}, { - required: false, pattern: PHONE_REGEX, message: this.$t('member.mobile_number_format_is_incorrect'), trigger: 'blur' diff --git a/frontend/src/business/components/settings/system/User.vue b/frontend/src/business/components/settings/system/User.vue index cbe63d7ee1..adf3841cb6 100644 --- a/frontend/src/business/components/settings/system/User.vue +++ b/frontend/src/business/components/settings/system/User.vue @@ -399,9 +399,7 @@ export default { } ], phone: [ - {required: true, message: this.$t('user.input_phone'), trigger: 'blur'}, { - required: true, pattern: PHONE_REGEX, message: this.$t('user.mobile_number_format_is_incorrect'), trigger: 'blur' diff --git a/frontend/src/business/components/track/case/components/TestCaseList.vue b/frontend/src/business/components/track/case/components/TestCaseList.vue index f63ddc8a7d..d468eda3c0 100644 --- a/frontend/src/business/components/track/case/components/TestCaseList.vue +++ b/frontend/src/business/components/track/case/components/TestCaseList.vue @@ -29,6 +29,7 @@ @filter-change="filter" @select-all="handleSelectAll" @select="handleSelect" + @header-dragend="headerDragend" @cell-mouse-enter="showPopover" row-key="id" class="test-content adjust-table ms-select-all-fixed" @@ -562,6 +563,14 @@ export default { this.selectDataCounts = this.selectRows.size; } }, + headerDragend(newWidth,oldWidth,column,event){ + let finalWidth = newWidth; + if(column.minWidth>finalWidth){ + finalWidth = column.minWidth; + } + column.width = finalWidth; + column.realWidth = finalWidth; + }, moveSave(param) { param.condition = this.condition; this.result = this.$post('/test/case/batch/edit', param, () => { diff --git a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue index 65ab346889..e499ab646e 100644 --- a/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue +++ b/frontend/src/business/components/track/plan/view/comonents/functional/FunctionalTestCaseList.vue @@ -35,6 +35,7 @@ @select="handleSelectionChange" row-key="id" @row-click="showDetail" + @header-dragend="headerDragend" :data="tableData">