From b84883097605724a2520d71817a983207ba21cca Mon Sep 17 00:00:00 2001 From: fit2-zhao Date: Mon, 7 Dec 2020 19:03:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8E=A5=E5=8F=A3=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96):=20=E5=AE=8C=E6=88=90=E5=9C=BA=E6=99=AF=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=89=A7=E8=A1=8C=EF=BC=8C=E5=9F=BA=E7=A1=80=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../APIScenarioReportController.java | 51 +++- .../controller/ApiAutomationController.java | 17 +- .../automation/APIScenarioReportResult.java | 18 ++ .../dto/automation/RunScenarioRequest.java | 19 ++ .../automation/SaveApiScenarioRequest.java | 4 + .../dto/definition/request/MsScenario.java | 27 ++- .../dto/definition/request/MsTestElement.java | 2 +- .../dto/definition/request/MsThreadGroup.java | 1 + .../api/jmeter/APIBackendListenerClient.java | 2 +- .../api/service/ApiAutomationService.java | 96 ++++++-- .../api/service/ApiScenarioReportService.java | 117 ++++++++- .../base/domain/ApiScenarioReport.java | 5 +- .../base/domain/ApiScenarioReportDetail.java | 2 +- .../ApiScenarioReportDetailExample.java | 56 ++--- .../base/domain/ApiScenarioReportExample.java | 56 ++--- .../mapper/ApiScenarioReportDetailMapper.xml | 32 +-- .../base/mapper/ApiScenarioReportMapper.xml | 28 +-- .../ext/ExtApiScenarioReportMapper.java | 15 ++ .../mapper/ext/ExtApiScenarioReportMapper.xml | 169 +++++++++++++ .../src/main/resources/generatorConfig.xml | 6 +- .../api/automation/report/ApiReportDetail.vue | 37 ++- .../api/automation/report/ApiReportList.vue | 228 ++++++++++++++++++ .../automation/report/ApiReportViewHeader.vue | 15 +- .../report/components/ScenarioResult.vue | 22 +- .../automation/scenario/ApiScenarioList.vue | 151 +++++++----- .../api/automation/scenario/DebugRun.vue | 106 ++++++++ .../automation/scenario/EditApiScenario.vue | 69 +++++- .../api/automation/scenario/Run.vue | 118 --------- .../jmeter/components/test-plan/index.js | 5 - .../jmeter/components/thread-group/index.js | 14 -- .../components/api/head/ApiHeaderMenus.vue | 4 + .../src/business/components/api/router.js | 5 + frontend/src/i18n/en-US.js | 20 +- frontend/src/i18n/zh-CN.js | 20 +- frontend/src/i18n/zh-TW.js | 5 +- 35 files changed, 1171 insertions(+), 371 deletions(-) create mode 100644 backend/src/main/java/io/metersphere/api/dto/automation/APIScenarioReportResult.java create mode 100644 backend/src/main/java/io/metersphere/api/dto/automation/RunScenarioRequest.java create mode 100644 backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.java create mode 100644 backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioReportMapper.xml create mode 100644 frontend/src/business/components/api/automation/report/ApiReportList.vue create mode 100644 frontend/src/business/components/api/automation/scenario/DebugRun.vue delete mode 100644 frontend/src/business/components/api/automation/scenario/Run.vue diff --git a/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java b/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java index 2021a1fdc5..560ce4f1ce 100644 --- a/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java +++ b/backend/src/main/java/io/metersphere/api/controller/APIScenarioReportController.java @@ -1,16 +1,22 @@ package io.metersphere.api.controller; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; import io.metersphere.api.dto.APIReportResult; +import io.metersphere.api.dto.DeleteAPIReportRequest; +import io.metersphere.api.dto.QueryAPIReportRequest; +import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.service.ApiScenarioReportService; import io.metersphere.commons.constants.RoleConstants; +import io.metersphere.commons.utils.PageUtils; +import io.metersphere.commons.utils.Pager; +import io.metersphere.commons.utils.SessionUtils; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresRoles; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.util.List; @RestController @RequestMapping(value = "/api/scenario/report") @@ -20,8 +26,41 @@ public class APIScenarioReportController { @Resource private ApiScenarioReportService apiReportService; - @GetMapping("/get/{reportId}") - public APIReportResult get(@PathVariable String reportId) { + @GetMapping("/get/{reportId}/{infoDb}") + public APIReportResult get(@PathVariable String reportId,@PathVariable Boolean infoDb) { + if(infoDb){ + return apiReportService.get(reportId); + } return apiReportService.getCacheResult(reportId); } + + @PostMapping("/list/{goPage}/{pageSize}") + public Pager> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryAPIReportRequest request) { + Page page = PageHelper.startPage(goPage, pageSize, true); + request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId()); + return PageUtils.setPageInfo(page, apiReportService.list(request)); + } + + @PostMapping("/add") + @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) + public String add(@RequestBody APIScenarioReportResult node) { + return apiReportService.add(node); + } + + @PostMapping("/update") + @RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR) + public String update(@RequestBody APIScenarioReportResult node) { + return apiReportService.update(node); + } + + @PostMapping("/delete") + public void delete(@RequestBody DeleteAPIReportRequest request) { + apiReportService.delete(request); + } + + @PostMapping("/batch/delete") + public void deleteAPIReportBatch(@RequestBody DeleteAPIReportRequest reportRequest) { + apiReportService.deleteAPIReportBatch(reportRequest); + } + } diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java index 71adcdd5ab..d7500fdc88 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiAutomationController.java @@ -4,6 +4,7 @@ import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.metersphere.api.dto.automation.ApiScenarioDTO; import io.metersphere.api.dto.automation.ApiScenarioRequest; +import io.metersphere.api.dto.automation.RunScenarioRequest; import io.metersphere.api.dto.automation.SaveApiScenarioRequest; import io.metersphere.api.dto.definition.RunDefinitionRequest; import io.metersphere.api.service.ApiAutomationService; @@ -36,13 +37,13 @@ public class ApiAutomationController { } @PostMapping(value = "/create") - public void create(@RequestBody SaveApiScenarioRequest request) { - apiAutomationService.create(request); + public void create(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "files") List bodyFiles) { + apiAutomationService.create(request, bodyFiles); } @PostMapping(value = "/update") - public void update(@RequestBody SaveApiScenarioRequest request) { - apiAutomationService.update(request); + public void update(@RequestPart("request") SaveApiScenarioRequest request, @RequestPart(value = "files") List bodyFiles) { + apiAutomationService.update(request, bodyFiles); } @GetMapping("/delete/{id}") @@ -70,9 +71,15 @@ public class ApiAutomationController { return apiAutomationService.getApiScenarios(ids); } - @PostMapping(value = "/run") + @PostMapping(value = "/run/debug") public void runDebug(@RequestPart("request") RunDefinitionRequest request, @RequestPart(value = "files") List bodyFiles) { apiAutomationService.run(request, bodyFiles); } + + @PostMapping(value = "/run") + public void run(@RequestBody RunScenarioRequest request) { + apiAutomationService.run(request); + } + } diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/APIScenarioReportResult.java b/backend/src/main/java/io/metersphere/api/dto/automation/APIScenarioReportResult.java new file mode 100644 index 0000000000..dae152bd5a --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/automation/APIScenarioReportResult.java @@ -0,0 +1,18 @@ +package io.metersphere.api.dto.automation; + +import io.metersphere.base.domain.ApiScenarioReport; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class APIScenarioReportResult extends ApiScenarioReport { + + private String testName; + + private String projectName; + + private String userName; + + private String content; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/RunScenarioRequest.java b/backend/src/main/java/io/metersphere/api/dto/automation/RunScenarioRequest.java new file mode 100644 index 0000000000..f3d7ddc2f4 --- /dev/null +++ b/backend/src/main/java/io/metersphere/api/dto/automation/RunScenarioRequest.java @@ -0,0 +1,19 @@ +package io.metersphere.api.dto.automation; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Setter +@Getter +public class RunScenarioRequest { + + private String id; + + private String reportId; + + private String environmentId; + + private List scenarioIds; +} diff --git a/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java b/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java index 9fe0085aa0..9d25b4e257 100644 --- a/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java +++ b/backend/src/main/java/io/metersphere/api/dto/automation/SaveApiScenarioRequest.java @@ -3,6 +3,8 @@ package io.metersphere.api.dto.automation; import lombok.Getter; import lombok.Setter; +import java.util.List; + @Setter @Getter public class SaveApiScenarioRequest { @@ -35,4 +37,6 @@ public class SaveApiScenarioRequest { private String description; private String scenarioDefinition; + + List bodyUploadIds; } diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java index 5a2ff7a466..48fc7ec826 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsScenario.java @@ -4,6 +4,9 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONType; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.service.ApiAutomationService; import io.metersphere.api.service.ApiTestEnvironmentService; @@ -15,6 +18,7 @@ import lombok.EqualsAndHashCode; import org.apache.commons.collections.CollectionUtils; import org.apache.jorphan.collections.HashTree; +import java.util.LinkedList; import java.util.List; @Data @@ -41,14 +45,21 @@ public class MsScenario extends MsTestElement { if (this.getReferenced() != null && this.getReferenced().equals("Deleted")) { return; } else if (this.getReferenced() != null && this.getReferenced().equals("REF")) { - ApiAutomationService apiAutomationService = CommonBeanFactory.getBean(ApiAutomationService.class); - ApiScenario scenario = apiAutomationService.getApiScenario(this.getId()); - JSONObject element = JSON.parseObject(scenario.getScenarioDefinition()); - List dataArr = JSON.parseArray(element.getString("hashTree"), MsTestElement.class); - if (hashTree == null) { - hashTree = dataArr; - } else { - hashTree.addAll(dataArr); + try { + ApiAutomationService apiAutomationService = CommonBeanFactory.getBean(ApiAutomationService.class); + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + ApiScenario scenario = apiAutomationService.getApiScenario(this.getId()); + JSONObject element = JSON.parseObject(scenario.getScenarioDefinition()); + LinkedList elements = mapper.readValue(element.getString("hashTree"), new TypeReference>() { + }); + if (hashTree == null) { + hashTree = elements; + } else { + hashTree.addAll(elements); + } + } catch (Exception ex) { + ex.printStackTrace(); } } if (CollectionUtils.isNotEmpty(hashTree)) { 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 1f70213d34..76e6349495 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 @@ -51,7 +51,7 @@ import java.util.List; MsJSR223PreProcessor.class, MsTestPlan.class, MsThreadGroup.class, AuthManager.class, MsAssertions.class, MsExtract.class, MsTCPSampler.class, MsDubboSampler.class, MsJDBCSampler.class, MsConstantTimer.class, MsIfController.class, MsScenario.class}, typeKey = "type") @Data -public abstract class MsTestElement { +public class MsTestElement { private String type; @JSONField(ordinal = 1) private String id; diff --git a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsThreadGroup.java b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsThreadGroup.java index d8e31fbd7f..3e366cd4a7 100644 --- a/backend/src/main/java/io/metersphere/api/dto/definition/request/MsThreadGroup.java +++ b/backend/src/main/java/io/metersphere/api/dto/definition/request/MsThreadGroup.java @@ -50,4 +50,5 @@ public class MsThreadGroup extends MsTestElement { threadGroup.setSamplerController(loopController); return threadGroup; } + } 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 b65ef3acba..bccf9dccb6 100644 --- a/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java +++ b/backend/src/main/java/io/metersphere/api/jmeter/APIBackendListenerClient.java @@ -169,7 +169,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl } } else if (StringUtils.equals(this.runMode, ApiRunMode.SCENARIO.name())) { // 执行报告不需要存储,由用户确认后在存储 - testResult.setTestId(debugReportId); + testResult.setTestId(testId); apiScenarioReportService.complete(testResult); } else { apiTestService.changeStatus(testId, APITestStatus.Completed); 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 422987be8d..6b739e95ad 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiAutomationService.java @@ -2,13 +2,16 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import io.metersphere.api.dto.APIReportResult; -import io.metersphere.api.dto.automation.ApiScenarioDTO; -import io.metersphere.api.dto.automation.ApiScenarioRequest; -import io.metersphere.api.dto.automation.SaveApiScenarioRequest; -import io.metersphere.api.dto.automation.ScenarioStatus; +import io.metersphere.api.dto.automation.*; import io.metersphere.api.dto.definition.RunDefinitionRequest; +import io.metersphere.api.dto.definition.request.MsTestElement; +import io.metersphere.api.dto.definition.request.MsTestPlan; +import io.metersphere.api.dto.definition.request.MsThreadGroup; import io.metersphere.api.dto.scenario.environment.EnvironmentConfig; import io.metersphere.api.jmeter.JMeterService; import io.metersphere.base.domain.*; @@ -24,6 +27,7 @@ import io.metersphere.i18n.Translator; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.jorphan.collections.HashTree; +import org.apache.jorphan.collections.ListedHashTree; import org.aspectj.util.FileUtil; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -32,9 +36,9 @@ import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.*; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.stream.Collectors; @Service @@ -83,8 +87,9 @@ public class ApiAutomationService { apiScenarioMapper.deleteByExample(example); } - public void create(SaveApiScenarioRequest request) { + public void create(SaveApiScenarioRequest request, List bodyFiles) { checkNameExist(request); + final ApiScenario scenario = new ApiScenario(); scenario.setId(request.getId()); scenario.setName(request.getName()); @@ -111,10 +116,16 @@ public class ApiAutomationService { } scenario.setDescription(request.getDescription()); apiScenarioMapper.insert(scenario); + + List bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()); + createBodyFiles(bodyUploadIds, bodyFiles); } - public void update(SaveApiScenarioRequest request) { + public void update(SaveApiScenarioRequest request, List bodyFiles) { checkNameExist(request); + List bodyUploadIds = new ArrayList<>(request.getBodyUploadIds()); + createBodyFiles(bodyUploadIds, bodyFiles); + final ApiScenario scenario = new ApiScenario(); scenario.setId(request.getId()); scenario.setName(request.getName()); @@ -176,7 +187,7 @@ public class ApiAutomationService { } private void createBodyFiles(List bodyUploadIds, List bodyFiles) { - if (!bodyUploadIds.isEmpty()) { + if (!bodyUploadIds.isEmpty() && !bodyFiles.isEmpty()) { File testDir = new File(BODY_FILE_DIR); if (!testDir.exists()) { testDir.mkdirs(); @@ -208,6 +219,63 @@ public class ApiAutomationService { } } + private void createAPIReportResult(String id) { + APIReportResult report = new APIReportResult(); + report.setId(id); + report.setTestId(id); + report.setName(""); + report.setTriggerMode(null); + report.setCreateTime(System.currentTimeMillis()); + report.setUpdateTime(System.currentTimeMillis()); + report.setStatus(APITestStatus.Running.name()); + report.setUserId(SessionUtils.getUserId()); + apiReportService.addResult(report); + + } + + /** + * 场景测试执行 + * + * @param request + * @return + */ + public String run(RunScenarioRequest request) { + List apiScenarios = extApiScenarioMapper.selectIds(request.getScenarioIds()); + MsTestPlan testPlan = new MsTestPlan(); + testPlan.setHashTree(new LinkedList<>()); + HashTree jmeterTestPlanHashTree = new ListedHashTree(); + EnvironmentConfig config = null; + for (ApiScenario item : apiScenarios) { + MsThreadGroup group = new MsThreadGroup(); + group.setLabel(item.getName()); + group.setName(item.getName()); + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + JSONObject element = JSON.parseObject(item.getScenarioDefinition()); + String environmentId = element.getString("environmentId"); + if (environmentId != null) { + ApiTestEnvironmentWithBLOBs environment = environmentService.get(environmentId); + config = JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class); + } + + LinkedList elements = mapper.readValue(element.getString("hashTree"), new TypeReference>() { + }); + group.setHashTree(elements); + testPlan.getHashTree().add(group); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + testPlan.toHashTree(jmeterTestPlanHashTree, testPlan.getHashTree(), config); + + // 调用执行方法 + jMeterService.runDefinition(request.getId(), jmeterTestPlanHashTree, request.getReportId(), ApiRunMode.SCENARIO.name()); + createAPIReportResult(request.getId()); + return request.getId(); + } + + /** * 场景测试执行 * @@ -228,17 +296,7 @@ public class ApiAutomationService { // 调用执行方法 jMeterService.runDefinition(request.getId(), hashTree, request.getReportId(), ApiRunMode.SCENARIO.name()); - APIReportResult report = new APIReportResult(); - report.setId(UUID.randomUUID().toString()); - report.setTestId(request.getReportId()); - report.setName("RUN"); - report.setTriggerMode(null); - report.setCreateTime(System.currentTimeMillis()); - report.setUpdateTime(System.currentTimeMillis()); - report.setStatus(APITestStatus.Running.name()); - report.setUserId(SessionUtils.getUserId()); - apiReportService.addResult(report); + createAPIReportResult(request.getId()); return request.getId(); } - } 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 9879e89bb2..54401c9125 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -2,23 +2,39 @@ package io.metersphere.api.service; import com.alibaba.fastjson.JSONObject; import io.metersphere.api.dto.APIReportResult; +import io.metersphere.api.dto.DeleteAPIReportRequest; +import io.metersphere.api.dto.QueryAPIReportRequest; +import io.metersphere.api.dto.automation.APIScenarioReportResult; import io.metersphere.api.jmeter.TestResult; -import io.metersphere.base.domain.ApiTestReportDetail; +import io.metersphere.base.domain.*; +import io.metersphere.base.mapper.ApiScenarioReportDetailMapper; +import io.metersphere.base.mapper.ApiScenarioReportMapper; +import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper; import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.exception.MSException; +import io.metersphere.commons.utils.ServiceUtils; import io.metersphere.i18n.Translator; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import sun.security.util.Cache; +import javax.annotation.Resource; import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.UUID; @Service @Transactional(rollbackFor = Exception.class) public class ApiScenarioReportService { private static Cache cache = Cache.newHardMemoryCache(0, 3600 * 24); + @Resource + private ExtApiScenarioReportMapper extApiScenarioReportMapper; + @Resource + private ApiScenarioReportMapper apiScenarioReportMapper; + @Resource + private ApiScenarioReportDetailMapper apiScenarioReportDetailMapper; public void complete(TestResult result) { Object obj = cache.get(result.getTestId()); @@ -64,4 +80,103 @@ public class ApiScenarioReportService { } return null; } + + public APIReportResult get(String reportId) { + APIReportResult reportResult = extApiScenarioReportMapper.get(reportId); + ApiScenarioReportDetail detail = apiScenarioReportDetailMapper.selectByPrimaryKey(reportId); + if (detail != null) { + reportResult.setContent(new String(detail.getContent(), StandardCharsets.UTF_8)); + } + return reportResult; + } + + public List list(QueryAPIReportRequest request) { + request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); + return extApiScenarioReportMapper.list(request); + } + + private void checkNameExist(APIScenarioReportResult request) { + ApiScenarioReportExample example = new ApiScenarioReportExample(); + example.createCriteria().andNameEqualTo(request.getName()).andProjectIdEqualTo(request.getProjectId()).andIdNotEqualTo(request.getId()); + if (apiScenarioReportMapper.countByExample(example) > 0) { + MSException.throwException(Translator.get("load_test_already_exists")); + } + } + + public ApiScenarioReport createReport(APIScenarioReportResult test) { + checkNameExist(test); + ApiScenarioReport report = new ApiScenarioReport(); + report.setId(UUID.randomUUID().toString()); + report.setProjectId(test.getProjectId()); + report.setName(test.getName()); + report.setTriggerMode(test.getTriggerMode()); + report.setDescription(test.getDescription()); + report.setCreateTime(System.currentTimeMillis()); + report.setUpdateTime(System.currentTimeMillis()); + report.setStatus(test.getStatus()); + report.setUserId(test.getUserId()); + apiScenarioReportMapper.insert(report); + return report; + } + + public ApiScenarioReport updateReport(APIScenarioReportResult test) { + checkNameExist(test); + ApiScenarioReport report = new ApiScenarioReport(); + report.setId(test.getId()); + report.setProjectId(test.getProjectId()); + report.setName(test.getName()); + report.setTriggerMode(test.getTriggerMode()); + report.setDescription(test.getDescription()); + report.setCreateTime(System.currentTimeMillis()); + report.setUpdateTime(System.currentTimeMillis()); + report.setStatus(test.getStatus()); + report.setUserId(test.getUserId()); + apiScenarioReportMapper.updateByPrimaryKey(report); + return report; + } + + + public String add(APIScenarioReportResult test) { + ApiScenarioReport report = createReport(test); + ApiScenarioReportDetail detail = new ApiScenarioReportDetail(); + detail.setContent(test.getContent().getBytes(StandardCharsets.UTF_8)); + detail.setReportId(report.getId()); + detail.setProjectId(test.getProjectId()); + apiScenarioReportDetailMapper.insert(detail); + return report.getId(); + } + + public String update(APIScenarioReportResult test) { + ApiScenarioReport report = updateReport(test); + ApiScenarioReportDetail detail = apiScenarioReportDetailMapper.selectByPrimaryKey(test.getId()); + if (detail == null) { + detail = new ApiScenarioReportDetail(); + detail.setContent(test.getContent().getBytes(StandardCharsets.UTF_8)); + detail.setReportId(report.getId()); + detail.setProjectId(test.getProjectId()); + apiScenarioReportDetailMapper.insert(detail); + } else { + detail.setContent(test.getContent().getBytes(StandardCharsets.UTF_8)); + detail.setReportId(report.getId()); + detail.setProjectId(test.getProjectId()); + apiScenarioReportDetailMapper.updateByPrimaryKey(detail); + } + return report.getId(); + } + + public void delete(DeleteAPIReportRequest request) { + apiScenarioReportDetailMapper.deleteByPrimaryKey(request.getId()); + apiScenarioReportMapper.deleteByPrimaryKey(request.getId()); + } + + public void deleteAPIReportBatch(DeleteAPIReportRequest reportRequest) { + ApiScenarioReportDetailExample detailExample = new ApiScenarioReportDetailExample(); + detailExample.createCriteria().andReportIdIn(reportRequest.getIds()); + apiScenarioReportDetailMapper.deleteByExample(detailExample); + + ApiScenarioReportExample apiTestReportExample = new ApiScenarioReportExample(); + apiTestReportExample.createCriteria().andIdIn(reportRequest.getIds()); + apiScenarioReportMapper.deleteByExample(apiTestReportExample); + } + } diff --git a/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReport.java b/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReport.java index fab8fb7cb5..b6c632c40c 100644 --- a/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReport.java +++ b/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReport.java @@ -1,13 +1,14 @@ package io.metersphere.base.domain; -import java.io.Serializable; import lombok.Data; +import java.io.Serializable; + @Data public class ApiScenarioReport implements Serializable { private String id; - private String scenarioId; + private String projectId; private String name; diff --git a/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportDetail.java b/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportDetail.java index 43c4410ff0..fb774bfe7c 100644 --- a/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportDetail.java +++ b/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportDetail.java @@ -7,7 +7,7 @@ import lombok.Data; public class ApiScenarioReportDetail implements Serializable { private String reportId; - private String scenarioId; + private String projectId; private byte[] content; diff --git a/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportDetailExample.java b/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportDetailExample.java index 651e851326..07719fa61a 100644 --- a/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportDetailExample.java +++ b/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportDetailExample.java @@ -174,73 +174,73 @@ public class ApiScenarioReportDetailExample { return (Criteria) this; } - public Criteria andScenarioIdIsNull() { - addCriterion("scenario_id is null"); + public Criteria andProjectIdIsNull() { + addCriterion("project_id is null"); return (Criteria) this; } - public Criteria andScenarioIdIsNotNull() { - addCriterion("scenario_id is not null"); + public Criteria andProjectIdIsNotNull() { + addCriterion("project_id is not null"); return (Criteria) this; } - public Criteria andScenarioIdEqualTo(String value) { - addCriterion("scenario_id =", value, "scenarioId"); + public Criteria andProjectIdEqualTo(String value) { + addCriterion("project_id =", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdNotEqualTo(String value) { - addCriterion("scenario_id <>", value, "scenarioId"); + public Criteria andProjectIdNotEqualTo(String value) { + addCriterion("project_id <>", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdGreaterThan(String value) { - addCriterion("scenario_id >", value, "scenarioId"); + public Criteria andProjectIdGreaterThan(String value) { + addCriterion("project_id >", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdGreaterThanOrEqualTo(String value) { - addCriterion("scenario_id >=", value, "scenarioId"); + public Criteria andProjectIdGreaterThanOrEqualTo(String value) { + addCriterion("project_id >=", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdLessThan(String value) { - addCriterion("scenario_id <", value, "scenarioId"); + public Criteria andProjectIdLessThan(String value) { + addCriterion("project_id <", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdLessThanOrEqualTo(String value) { - addCriterion("scenario_id <=", value, "scenarioId"); + public Criteria andProjectIdLessThanOrEqualTo(String value) { + addCriterion("project_id <=", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdLike(String value) { - addCriterion("scenario_id like", value, "scenarioId"); + public Criteria andProjectIdLike(String value) { + addCriterion("project_id like", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdNotLike(String value) { - addCriterion("scenario_id not like", value, "scenarioId"); + public Criteria andProjectIdNotLike(String value) { + addCriterion("project_id not like", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdIn(List values) { - addCriterion("scenario_id in", values, "scenarioId"); + public Criteria andProjectIdIn(List values) { + addCriterion("project_id in", values, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdNotIn(List values) { - addCriterion("scenario_id not in", values, "scenarioId"); + public Criteria andProjectIdNotIn(List values) { + addCriterion("project_id not in", values, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdBetween(String value1, String value2) { - addCriterion("scenario_id between", value1, value2, "scenarioId"); + public Criteria andProjectIdBetween(String value1, String value2) { + addCriterion("project_id between", value1, value2, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdNotBetween(String value1, String value2) { - addCriterion("scenario_id not between", value1, value2, "scenarioId"); + public Criteria andProjectIdNotBetween(String value1, String value2) { + addCriterion("project_id not between", value1, value2, "projectId"); return (Criteria) this; } } diff --git a/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportExample.java b/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportExample.java index 3fa51f73fd..843e0efac1 100644 --- a/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportExample.java +++ b/backend/src/main/java/io/metersphere/base/domain/ApiScenarioReportExample.java @@ -174,73 +174,73 @@ public class ApiScenarioReportExample { return (Criteria) this; } - public Criteria andScenarioIdIsNull() { - addCriterion("scenario_id is null"); + public Criteria andProjectIdIsNull() { + addCriterion("project_id is null"); return (Criteria) this; } - public Criteria andScenarioIdIsNotNull() { - addCriterion("scenario_id is not null"); + public Criteria andProjectIdIsNotNull() { + addCriterion("project_id is not null"); return (Criteria) this; } - public Criteria andScenarioIdEqualTo(String value) { - addCriterion("scenario_id =", value, "scenarioId"); + public Criteria andProjectIdEqualTo(String value) { + addCriterion("project_id =", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdNotEqualTo(String value) { - addCriterion("scenario_id <>", value, "scenarioId"); + public Criteria andProjectIdNotEqualTo(String value) { + addCriterion("project_id <>", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdGreaterThan(String value) { - addCriterion("scenario_id >", value, "scenarioId"); + public Criteria andProjectIdGreaterThan(String value) { + addCriterion("project_id >", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdGreaterThanOrEqualTo(String value) { - addCriterion("scenario_id >=", value, "scenarioId"); + public Criteria andProjectIdGreaterThanOrEqualTo(String value) { + addCriterion("project_id >=", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdLessThan(String value) { - addCriterion("scenario_id <", value, "scenarioId"); + public Criteria andProjectIdLessThan(String value) { + addCriterion("project_id <", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdLessThanOrEqualTo(String value) { - addCriterion("scenario_id <=", value, "scenarioId"); + public Criteria andProjectIdLessThanOrEqualTo(String value) { + addCriterion("project_id <=", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdLike(String value) { - addCriterion("scenario_id like", value, "scenarioId"); + public Criteria andProjectIdLike(String value) { + addCriterion("project_id like", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdNotLike(String value) { - addCriterion("scenario_id not like", value, "scenarioId"); + public Criteria andProjectIdNotLike(String value) { + addCriterion("project_id not like", value, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdIn(List values) { - addCriterion("scenario_id in", values, "scenarioId"); + public Criteria andProjectIdIn(List values) { + addCriterion("project_id in", values, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdNotIn(List values) { - addCriterion("scenario_id not in", values, "scenarioId"); + public Criteria andProjectIdNotIn(List values) { + addCriterion("project_id not in", values, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdBetween(String value1, String value2) { - addCriterion("scenario_id between", value1, value2, "scenarioId"); + public Criteria andProjectIdBetween(String value1, String value2) { + addCriterion("project_id between", value1, value2, "projectId"); return (Criteria) this; } - public Criteria andScenarioIdNotBetween(String value1, String value2) { - addCriterion("scenario_id not between", value1, value2, "scenarioId"); + public Criteria andProjectIdNotBetween(String value1, String value2) { + addCriterion("project_id not between", value1, value2, "projectId"); return (Criteria) this; } diff --git a/backend/src/main/java/io/metersphere/base/mapper/ApiScenarioReportDetailMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ApiScenarioReportDetailMapper.xml index fe0a4d5d9b..c9357a7580 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ApiScenarioReportDetailMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ApiScenarioReportDetailMapper.xml @@ -3,7 +3,7 @@ - + @@ -67,7 +67,7 @@ - report_id, scenario_id + report_id, project_id content @@ -121,9 +121,9 @@ - insert into api_scenario_report_detail (report_id, scenario_id, content + insert into api_scenario_report_detail (report_id, project_id, content ) - values (#{reportId,jdbcType=VARCHAR}, #{scenarioId,jdbcType=VARCHAR}, #{content,jdbcType=LONGVARBINARY} + values (#{reportId,jdbcType=VARCHAR}, #{projectId,jdbcType=VARCHAR}, #{content,jdbcType=LONGVARBINARY} ) @@ -132,8 +132,8 @@ report_id, - - scenario_id, + + project_id, content, @@ -143,8 +143,8 @@ #{reportId,jdbcType=VARCHAR}, - - #{scenarioId,jdbcType=VARCHAR}, + + #{projectId,jdbcType=VARCHAR}, #{content,jdbcType=LONGVARBINARY}, @@ -163,8 +163,8 @@ report_id = #{record.reportId,jdbcType=VARCHAR}, - - scenario_id = #{record.scenarioId,jdbcType=VARCHAR}, + + project_id = #{record.projectId,jdbcType=VARCHAR}, content = #{record.content,jdbcType=LONGVARBINARY}, @@ -177,7 +177,7 @@ update api_scenario_report_detail set report_id = #{record.reportId,jdbcType=VARCHAR}, - scenario_id = #{record.scenarioId,jdbcType=VARCHAR}, + project_id = #{record.projectId,jdbcType=VARCHAR}, content = #{record.content,jdbcType=LONGVARBINARY} @@ -186,7 +186,7 @@ update api_scenario_report_detail set report_id = #{record.reportId,jdbcType=VARCHAR}, - scenario_id = #{record.scenarioId,jdbcType=VARCHAR} + project_id = #{record.projectId,jdbcType=VARCHAR} @@ -194,8 +194,8 @@ update api_scenario_report_detail - - scenario_id = #{scenarioId,jdbcType=VARCHAR}, + + project_id = #{projectId,jdbcType=VARCHAR}, content = #{content,jdbcType=LONGVARBINARY}, @@ -205,13 +205,13 @@ update api_scenario_report_detail - set scenario_id = #{scenarioId,jdbcType=VARCHAR}, + set project_id = #{projectId,jdbcType=VARCHAR}, content = #{content,jdbcType=LONGVARBINARY} where report_id = #{reportId,jdbcType=VARCHAR} update api_scenario_report_detail - set scenario_id = #{scenarioId,jdbcType=VARCHAR} + set project_id = #{projectId,jdbcType=VARCHAR} where report_id = #{reportId,jdbcType=VARCHAR} \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/ApiScenarioReportMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ApiScenarioReportMapper.xml index 25ff8666d6..c4c38aa228 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ApiScenarioReportMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ApiScenarioReportMapper.xml @@ -3,7 +3,7 @@ - + @@ -71,7 +71,7 @@ - id, scenario_id, `name`, description, create_time, update_time, `status`, user_id, + id, project_id, `name`, description, create_time, update_time, `status`, user_id, trigger_mode + SELECT r.name AS test_name, + r.name, r.description, r.id, r.project_id, r.create_time, r.update_time, r.status, r.trigger_mode, + project.name AS project_name, user.name AS user_name + FROM api_scenario_report r + LEFT JOIN project ON project.id = r.project_id + LEFT JOIN user ON user.id = r.user_id + + + + + + + + + + and r.name like CONCAT('%', #{request.name},'%') + + + AND r.user_id = #{request.userId,jdbcType=VARCHAR} + + + AND project.id = #{request.projectId} + + + AND project.workspace_id = #{request.workspaceId,jdbcType=VARCHAR} + + + + + + + and r.status in + + #{value} + + + + and r.trigger_mode in + + #{value} + + + + + + + AND r.status != 'Debug' + + + order by + + r.${order.name} ${order.type} + + + + + + + \ No newline at end of file diff --git a/backend/src/main/resources/generatorConfig.xml b/backend/src/main/resources/generatorConfig.xml index 2ca4e43942..2bbafcfd42 100644 --- a/backend/src/main/resources/generatorConfig.xml +++ b/backend/src/main/resources/generatorConfig.xml @@ -64,10 +64,8 @@ - -
-
-
+
+
\ No newline at end of file diff --git a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue index 12a6858936..fd57c5587b 100644 --- a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue +++ b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue @@ -4,12 +4,12 @@
- +
-
- +
+
@@ -64,10 +64,14 @@ requestType: undefined, } }, - props: ['reportId'], activated() { this.isRequestResult = false; }, + props: { + reportId: String, + currentProjectId: String, + infoDb: Boolean, + }, watch: { reportId() { this.getReport(); @@ -91,7 +95,7 @@ getReport() { this.init(); if (this.reportId) { - let url = "/api/scenario/report/get/" + this.reportId; + let url = "/api/scenario/report/get/" + this.reportId + "/" + this.infoDb; this.$get(url, response => { this.report = response.data || {}; if (response.data) { @@ -99,7 +103,6 @@ try { this.content = JSON.parse(this.report.content); } catch (e) { - // console.log(this.report.content) throw e; } this.getFails(); @@ -136,6 +139,7 @@ } }, requestResult(requestResult) { + this.active(); this.isRequestResult = false; this.requestType = undefined; if (requestResult.request.body.indexOf('[Callable Statement]') > -1) { @@ -155,6 +159,27 @@ reset(); }); }, + handleSave() { + if (!this.report.name) { + this.$warning(this.$t('api_test.automation.report_name_info')); + return; + } + if (!this.currentProjectId) { + this.$warning(this.$t('api_test.select_project')); + return; + } + this.loading = true; + this.report.projectId = this.currentProjectId; + let url = "/api/scenario/report/add"; + if (this.infoDb === true) { + url = "/api/scenario/report/update"; + } + this.result = this.$post(url, this.report, response => { + this.$success(this.$t('commons.save_success')); + this.loading = false; + this.$emit('refresh'); + }); + }, exportReportReset() { this.$router.go(0); } diff --git a/frontend/src/business/components/api/automation/report/ApiReportList.vue b/frontend/src/business/components/api/automation/report/ApiReportList.vue new file mode 100644 index 0000000000..6919193a43 --- /dev/null +++ b/frontend/src/business/components/api/automation/report/ApiReportList.vue @@ -0,0 +1,228 @@ + + + + + diff --git a/frontend/src/business/components/api/automation/report/ApiReportViewHeader.vue b/frontend/src/business/components/api/automation/report/ApiReportViewHeader.vue index ba02542881..6fa1940fa1 100644 --- a/frontend/src/business/components/api/automation/report/ApiReportViewHeader.vue +++ b/frontend/src/business/components/api/automation/report/ApiReportViewHeader.vue @@ -2,13 +2,17 @@
- {{ report.projectName === null || report.projectName ==='' ? "场景执行报告": report.projectName}} / - {{ report.testName }} + {{ report.createTime | timestampFormatDate }} - + + {{$t('test_track.plan_view.export_report')}} + + + {{$t('commons.save')}} + +
@@ -38,6 +42,9 @@ methods: { handleExport(name) { this.$emit('reportExport', name); + }, + handleSave(name) { + this.$emit('reportSave', name); } } } diff --git a/frontend/src/business/components/api/automation/report/components/ScenarioResult.vue b/frontend/src/business/components/api/automation/report/components/ScenarioResult.vue index 34d3b2f4ac..a380bdca36 100644 --- a/frontend/src/business/components/api/automation/report/components/ScenarioResult.vue +++ b/frontend/src/business/components/api/automation/report/components/ScenarioResult.vue @@ -1,10 +1,24 @@ diff --git a/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue b/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue index f4837a1249..bcd3e5a51d 100644 --- a/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue +++ b/frontend/src/business/components/api/automation/scenario/ApiScenarioList.vue @@ -1,62 +1,72 @@ diff --git a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue index 13f9682169..50bd67ebbe 100644 --- a/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue +++ b/frontend/src/business/components/api/automation/scenario/EditApiScenario.vue @@ -261,7 +261,7 @@ @runRefresh="runRefresh" ref="runTest"/> - +
@@ -284,7 +284,7 @@ import {getUUID} from "@/common/js/utils"; import ApiEnvironmentConfig from "../../definition/components/environment/ApiEnvironmentConfig"; import MsAddTag from "./AddTag"; - import MsRun from "./Run"; + import MsRun from "./DebugRun"; import MsImportApiScenario from "./ImportApiScenario"; import MsApiScenarioComponent from "./ApiScenarioComponent"; import MsApiReportDetail from "../report/ApiReportDetail"; @@ -333,7 +333,7 @@ expandedNode: [], scenarioDefinition: [], path: "/api/automation/create", - debugData: [], + debugData: {}, reportId: "", } }, @@ -539,9 +539,7 @@ this.$error(this.$t('api_test.environment.select_environment')); return; } - let scenario = {id: this.currentScenario.id, name: this.currentScenario.name, type: "scenario", referenced: 'Created', environmentId: this.currentEnvironmentId, hashTree: this.scenarioDefinition}; - this.debugData = []; - this.debugData.push(scenario); + this.debugData = {id: this.currentScenario.id, name: this.currentScenario.name, type: "scenario", referenced: 'Created', environmentId: this.currentEnvironmentId, hashTree: this.scenarioDefinition}; this.reportId = getUUID().substring(0, 8); }, getEnvironments() { @@ -592,11 +590,68 @@ }); return path[0].path; }, + setFiles(item, bodyUploadFiles, obj) { + if (item.body) { + item.body.kvs.forEach(param => { + if (param.files) { + param.files.forEach(item => { + if (item.file) { + if (!item.id) { + let fileId = getUUID().substring(0, 12); + item.name = item.file.name; + item.id = fileId; + } + obj.bodyUploadIds.push(item.id); + bodyUploadFiles.push(item.file); + } + }); + } + }); + item.body.binary.forEach(param => { + if (param.files) { + param.files.forEach(item => { + if (item.file) { + if (!item.id) { + let fileId = getUUID().substring(0, 12); + item.name = item.file.name; + item.id = fileId; + } + obj.bodyUploadIds.push(item.id); + bodyUploadFiles.push(item.file); + } + }); + } + }); + } + }, + recursiveFile(arr, bodyUploadFiles, obj) { + arr.forEach(item => { + this.setFiles(item, bodyUploadFiles, obj); + if (item.hashTree != undefined && item.hashTree.length > 0) { + this.recursiveFile(item.hashTree, bodyUploadFiles, obj); + } + }); + }, + getBodyUploadFiles(obj) { + let bodyUploadFiles = []; + obj.bodyUploadIds = []; + this.scenarioDefinition.forEach(item => { + this.setFiles(item, bodyUploadFiles, obj); + if (item.hashTree != undefined && item.hashTree.length > 0) { + this.recursiveFile(item.hashTree, bodyUploadFiles, obj); + } + }) + return bodyUploadFiles; + }, editScenario() { this.$refs['currentScenario'].validate((valid) => { if (valid) { this.setParameter(); - this.result = this.$post(this.path, this.currentScenario, () => { + let bodyFiles = this.getBodyUploadFiles(this.currentScenario); + console.log(bodyFiles) + console.log(this.currentScenario.bodyUploadIds) + + this.$fileUpload(this.path, null, bodyFiles, this.currentScenario, () => { this.$success(this.$t('commons.save_success')); this.path = "/api/automation/update"; this.currentScenario.tagId = JSON.parse(this.currentScenario.tagId); diff --git a/frontend/src/business/components/api/automation/scenario/Run.vue b/frontend/src/business/components/api/automation/scenario/Run.vue deleted file mode 100644 index 055123b5df..0000000000 --- a/frontend/src/business/components/api/automation/scenario/Run.vue +++ /dev/null @@ -1,118 +0,0 @@ - - diff --git a/frontend/src/business/components/api/definition/components/jmeter/components/test-plan/index.js b/frontend/src/business/components/api/definition/components/jmeter/components/test-plan/index.js index d849d93f1e..a8c12386d2 100644 --- a/frontend/src/business/components/api/definition/components/jmeter/components/test-plan/index.js +++ b/frontend/src/business/components/api/definition/components/jmeter/components/test-plan/index.js @@ -12,12 +12,7 @@ export const TYPE = "TestPlan"; export default class TestPlan extends HashTreeElement { constructor(options = DEFAULT_OPTIONS) { super(options); - this.$type = TYPE; this.type = TYPE; - this.functionalMode = this.initBoolProp('TestPlan.functional_mode', false); - this.serializeThreadGroups = this.initBoolProp('TestPlan.serialize_threadgroups', false); - this.tearDownOnShutdown = this.initBoolProp('TestPlan.tearDown_on_shutdown', true); - this.userDefineClasspath = this.initStringProp('TestPlan.user_define_classpath'); this.hashTree = []; this.userDefinedVariables = []; diff --git a/frontend/src/business/components/api/definition/components/jmeter/components/thread-group/index.js b/frontend/src/business/components/api/definition/components/jmeter/components/thread-group/index.js index ff84008fd7..c9e5a0c416 100644 --- a/frontend/src/business/components/api/definition/components/jmeter/components/thread-group/index.js +++ b/frontend/src/business/components/api/definition/components/jmeter/components/thread-group/index.js @@ -11,21 +11,7 @@ export const TYPE = "ThreadGroup"; export default class ThreadGroup extends HashTreeElement { constructor(options = DEFAULT_OPTIONS) { super(options); - this.$type = TYPE; this.type = TYPE; - this.onSampleError = this.initStringProp('ThreadGroup.on_sample_error', 'continue'); - this.numThreads = this.initStringProp('ThreadGroup.num_threads', 1); - this.rampTime = this.initStringProp('ThreadGroup.ramp_time', 1); - - let loopController = this.initElementProp('ThreadGroup.main_controller', 'LoopController'); - this.continueForever = loopController.initBoolProp('LoopController.continue_forever', false); - this.loops = loopController.initStringProp('LoopController.loops', 1); - - this.sameUserOnNextIteration = this.initBoolProp('ThreadGroup.same_user_on_next_iteration', true); - this.delayedStart = this.initBoolProp('ThreadGroup.delayedStart'); - this.scheduler = this.initBoolProp('ThreadGroup.scheduler', false); - this.delay = this.initStringProp('ThreadGroup.delay'); - this.duration = this.initStringProp('ThreadGroup.duration'); } } diff --git a/frontend/src/business/components/api/head/ApiHeaderMenus.vue b/frontend/src/business/components/api/head/ApiHeaderMenus.vue index 6450671fe2..fc21bf0ef6 100644 --- a/frontend/src/business/components/api/head/ApiHeaderMenus.vue +++ b/frontend/src/business/components/api/head/ApiHeaderMenus.vue @@ -15,6 +15,10 @@ {{ $t("i18n.automation") }} + + {{ $t("i18n.report") }} + + diff --git a/frontend/src/business/components/api/router.js b/frontend/src/business/components/api/router.js index 41e9a2ed14..6df34af109 100644 --- a/frontend/src/business/components/api/router.js +++ b/frontend/src/business/components/api/router.js @@ -48,6 +48,11 @@ export default { path: "automation", name: "ApiAutomation", component: () => import('@/business/components/api/automation/ApiAutomation'), + }, + { + path: "automation/report", + name: "ApiReportList", + component: () => import('@/business/components/api/automation/report/ApiReportList'), } ] } diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 4b38945ed0..8b08620ce3 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -163,7 +163,7 @@ export default { current_user: "Current user" } }, - monitor:"monitor" + monitor: "monitor" }, license: { title: 'Authorization management', @@ -543,6 +543,7 @@ export default { customize_script: "Custom script", customize_req: "Custom request", reference_info: "Please select interface or use case", + report_name_info: 'Please enter the registration name', }, environment: { name: "Environment Name", @@ -779,14 +780,14 @@ export default { not_exist: "Test report does not exist", }, api_monitor: { - to:"to", - start_time:"Start Time", - end_time:"End Time", - today:"Today", - this_week:"This Week", - this_mouth:"This Mouth", - please_search:"Please Search", - date:"Date" + to: "to", + start_time: "Start Time", + end_time: "End Time", + today: "Today", + this_week: "This Week", + this_mouth: "This Mouth", + please_search: "Please Search", + date: "Date" }, test_track: { test_track: "Track", @@ -1096,6 +1097,7 @@ export default { home: 'Home', definition: 'Api Definition', automation: 'Api Automation', + report: 'Test report', }, ldap: { url: 'LDAP URL', diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index b5e4c1fdbd..b61350a48a 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -570,7 +570,8 @@ export default { follow_people: "关注人", select_table: "选择可见数据", select_all: "选择全部数据" - } + }, + report_name_info: '请输入报名名称', }, environment: { name: "环境名称", @@ -809,14 +810,14 @@ export default { not_exist: "测试报告不存在", }, api_monitor: { - to:"至", - start_time:"开始日期", - end_time:"结束日期", - today:"今日", - this_week:"本周", - this_mouth:"本月", - please_search:"请搜索", - date:"日期" + to: "至", + start_time: "开始日期", + end_time: "结束日期", + today: "今日", + this_week: "本周", + this_mouth: "本月", + please_search: "请搜索", + date: "日期" }, test_track: { test_track: "测试跟踪", @@ -1125,6 +1126,7 @@ export default { home: '首页', definition: '接口定义', automation: '接口自动化', + report: '测试报告', }, ldap: { url: 'LDAP地址', diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index eaf646e206..4578115771 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -543,8 +543,8 @@ export default { scenario_import: "場景導入", customize_script: "自定義腳本", customize_req: "自定義請求", - reference_info: "請選擇接口或用例" - + reference_info: "請選擇接口或用例", + report_name_info: '请输入报名名称', }, environment: { name: "環境名稱", @@ -1098,6 +1098,7 @@ export default { home: '首頁', definition: '接口定義', automation: '接口自動化', + report: '測試報告', }, ldap: { url: 'LDAP地址',