Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
0da578c0ce
|
@ -11,7 +11,7 @@ import io.metersphere.commons.utils.PageUtils;
|
|||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.dto.DashboardTestDTO;
|
||||
import io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -27,7 +27,7 @@ public class APIReportController {
|
|||
@Resource
|
||||
private APIReportService apiReportService;
|
||||
@Resource
|
||||
private CheckOwnerService checkOwnerService;
|
||||
private CheckPermissionService checkPermissionService;
|
||||
|
||||
@GetMapping("recent/{count}")
|
||||
public List<APIReportResult> recentTest(@PathVariable int count) {
|
||||
|
@ -41,7 +41,7 @@ public class APIReportController {
|
|||
|
||||
@GetMapping("/list/{testId}/{goPage}/{pageSize}")
|
||||
public Pager<List<APIReportResult>> listByTestId(@PathVariable String testId, @PathVariable int goPage, @PathVariable int pageSize) {
|
||||
checkOwnerService.checkApiTestOwner(testId);
|
||||
checkPermissionService.checkApiTestOwner(testId);
|
||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||
return PageUtils.setPageInfo(page, apiReportService.listByTestId(testId));
|
||||
|
||||
|
|
|
@ -15,11 +15,13 @@ import io.metersphere.base.domain.ApiTest;
|
|||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.commons.constants.ScheduleGroup;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.commons.utils.CronUtils;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.QueryScheduleRequest;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.service.CheckOwnerService;
|
||||
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.service.ScheduleService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
|
@ -27,7 +29,6 @@ import org.springframework.web.bind.annotation.*;
|
|||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
@ -46,7 +47,7 @@ public class APITestController {
|
|||
@Resource
|
||||
private ApiDefinitionService apiDefinitionService;
|
||||
@Resource
|
||||
private CheckOwnerService checkownerService;
|
||||
private CheckPermissionService checkownerService;
|
||||
@Resource
|
||||
private ApiTestCaseService apiTestCaseService;
|
||||
@Resource
|
||||
|
@ -253,7 +254,7 @@ public class APITestController {
|
|||
* */
|
||||
long dateCountByCreateInThisWeek = apiAutomationService.countScenarioByProjectIDAndCreatInThisWeek(projectId);
|
||||
apiCountResult.setThisWeekAddedCount(dateCountByCreateInThisWeek);
|
||||
long executedInThisWeekCountNumber = apiScenarioReportService.countByProjectIDAndCreateInThisWeek(projectId);
|
||||
long executedInThisWeekCountNumber = apiScenarioReportService.countByProjectIdAndCreateInThisWeek(projectId);
|
||||
apiCountResult.setThisWeekExecutedCount(executedInThisWeekCountNumber);
|
||||
long executedCountNumber = apiScenarioReportService.countByProjectID(projectId);
|
||||
apiCountResult.setExecutedCount(executedCountNumber);
|
||||
|
@ -274,21 +275,27 @@ public class APITestController {
|
|||
|
||||
}
|
||||
|
||||
@GetMapping("/scheduleTaskInfoCount/{workSpaceID}")
|
||||
public ApiDataCountDTO scheduleTaskInfoCount(@PathVariable String workSpaceID) {
|
||||
@GetMapping("/scheduleTaskInfoCount/{projectId}")
|
||||
public ApiDataCountDTO scheduleTaskInfoCount(@PathVariable String projectId) {
|
||||
ApiDataCountDTO apiCountResult = new ApiDataCountDTO();
|
||||
|
||||
long allTaskCount = scheduleService.countTaskByWorkspaceIdAndGroup(workSpaceID,ScheduleGroup.API_TEST.name());
|
||||
long allTaskCount = scheduleService.countTaskByProjectId(projectId);
|
||||
|
||||
apiCountResult.setAllApiDataCountNumber(allTaskCount);
|
||||
|
||||
long taskCountInThisWeek = scheduleService.countTaskByWorkspaceIdAndGroupInThisWeek(workSpaceID,ScheduleGroup.API_TEST.name());
|
||||
long taskCountInThisWeek = scheduleService.countTaskByProjectIdInThisWeek(projectId);
|
||||
apiCountResult.setThisWeekAddedCount(taskCountInThisWeek);
|
||||
long executedInThisWeekCountNumber = apiReportService.countByWorkspaceIdAndGroupAndCreateInThisWeek(workSpaceID,ScheduleGroup.API_TEST.name());
|
||||
long api_executedInThisWeekCountNumber = apiReportService.countByProjectIdAndCreateInThisWeek(projectId);
|
||||
long scene_executedInThisWeekCountNumber = apiScenarioReportService.countByProjectIdAndCreateAndByScheduleInThisWeek(projectId);
|
||||
long executedInThisWeekCountNumber = api_executedInThisWeekCountNumber+scene_executedInThisWeekCountNumber;
|
||||
apiCountResult.setThisWeekExecutedCount(executedInThisWeekCountNumber);
|
||||
|
||||
//统计 失败 成功 以及总数
|
||||
List<ApiDataCountResult> allExecuteResult = apiReportService.countByWorkspaceIdAndGroupGroupByExecuteResult(workSpaceID,ScheduleGroup.API_TEST.name());
|
||||
List<ApiDataCountResult> api_allExecuteResult = apiReportService.countByProjectIdGroupByExecuteResult(projectId);
|
||||
List<ApiDataCountResult> scene_allExecuteResult = apiScenarioReportService.countByProjectIdGroupByExecuteResult(projectId);
|
||||
List<ApiDataCountResult> allExecuteResult = new ArrayList<>();
|
||||
allExecuteResult.addAll(api_allExecuteResult);
|
||||
allExecuteResult.addAll(scene_allExecuteResult);
|
||||
apiCountResult.countScheduleExecute(allExecuteResult);
|
||||
|
||||
long allCount = apiCountResult.getExecutedCount();
|
||||
|
@ -329,10 +336,10 @@ public class APITestController {
|
|||
return returnList;
|
||||
}
|
||||
|
||||
@GetMapping("/runningTask/{workspaceID}")
|
||||
public List<TaskInfoResult> runningTask(@PathVariable String workspaceID) {
|
||||
@GetMapping("/runningTask/{projectID}")
|
||||
public List<TaskInfoResult> runningTask(@PathVariable String projectID) {
|
||||
|
||||
List<TaskInfoResult> resultList = scheduleService.findRunningTaskInfoByWorkspaceID(workspaceID);
|
||||
List<TaskInfoResult> resultList = scheduleService.findRunningTaskInfoByProjectID(projectID);
|
||||
for (TaskInfoResult taskInfo :
|
||||
resultList) {
|
||||
Date nextExecutionTime = CronUtils.getNextTriggerTime(taskInfo.getRule());
|
||||
|
|
|
@ -31,6 +31,7 @@ public class ApiAutomationController {
|
|||
|
||||
|
||||
@PostMapping("/list/{goPage}/{pageSize}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||
public Pager<List<ApiScenarioDTO>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody ApiScenarioRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||
request.setWorkspaceId(SessionUtils.getCurrentWorkspaceId());
|
||||
|
|
|
@ -14,6 +14,7 @@ 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 io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
|
@ -30,6 +31,8 @@ import java.util.List;
|
|||
public class ApiDefinitionController {
|
||||
@Resource
|
||||
private ApiDefinitionService apiDefinitionService;
|
||||
@Resource
|
||||
private CheckPermissionService checkPermissionService;
|
||||
|
||||
@PostMapping("/list/{goPage}/{pageSize}")
|
||||
public Pager<List<ApiDefinitionResult>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody ApiDefinitionRequest request) {
|
||||
|
@ -41,18 +44,21 @@ public class ApiDefinitionController {
|
|||
@PostMapping(value = "/create", consumes = {"multipart/form-data"})
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR)
|
||||
public void create(@RequestPart("request") SaveApiDefinitionRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
||||
checkPermissionService.checkReadOnlyUser();
|
||||
apiDefinitionService.create(request, bodyFiles);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/update", consumes = {"multipart/form-data"})
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR)
|
||||
public void update(@RequestPart("request") SaveApiDefinitionRequest request, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
||||
checkPermissionService.checkReadOnlyUser();
|
||||
apiDefinitionService.update(request, bodyFiles);
|
||||
}
|
||||
|
||||
@GetMapping("/delete/{id}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR)
|
||||
public void delete(@PathVariable String id) {
|
||||
checkPermissionService.checkReadOnlyUser();
|
||||
apiDefinitionService.delete(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import io.metersphere.api.dto.definition.DragModuleRequest;
|
|||
import io.metersphere.api.service.ApiModuleService;
|
||||
import io.metersphere.base.domain.ApiModule;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -21,17 +21,17 @@ public class ApiModuleController {
|
|||
@Resource
|
||||
ApiModuleService apiModuleService;
|
||||
@Resource
|
||||
private CheckOwnerService checkOwnerService;
|
||||
private CheckPermissionService checkPermissionService;
|
||||
|
||||
@GetMapping("/list/{projectId}/{protocol}")
|
||||
public List<ApiModuleDTO> getNodeByProjectId(@PathVariable String projectId,@PathVariable String protocol) {
|
||||
checkOwnerService.checkProjectOwner(projectId);
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return apiModuleService.getNodeTreeByProjectId(projectId,protocol);
|
||||
}
|
||||
|
||||
@GetMapping("/list/plan/{planId}/{protocol}")
|
||||
public List<ApiModuleDTO> getNodeByPlanId(@PathVariable String planId, @PathVariable String protocol) {
|
||||
checkOwnerService.checkTestPlanOwner(planId);
|
||||
checkPermissionService.checkTestPlanOwner(planId);
|
||||
return apiModuleService.getNodeByPlanId(planId, protocol);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,14 +5,13 @@ import io.metersphere.api.dto.automation.DragApiScenarioModuleRequest;
|
|||
import io.metersphere.api.service.ApiScenarioModuleService;
|
||||
import io.metersphere.base.domain.ApiScenarioModule;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@RequestMapping("/api/automation/module")
|
||||
@RestController
|
||||
|
@ -22,11 +21,11 @@ public class ApiScenarioModuleController {
|
|||
@Resource
|
||||
ApiScenarioModuleService apiScenarioModuleService;
|
||||
@Resource
|
||||
private CheckOwnerService checkOwnerService;
|
||||
private CheckPermissionService checkPermissionService;
|
||||
|
||||
@GetMapping("/list/{projectId}")
|
||||
public List<ApiScenarioModuleDTO> getNodeByProjectId(@PathVariable String projectId) {
|
||||
checkOwnerService.checkProjectOwner(projectId);
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return apiScenarioModuleService.getNodeTreeByProjectId(projectId);
|
||||
}
|
||||
|
||||
|
@ -44,7 +43,7 @@ public class ApiScenarioModuleController {
|
|||
|
||||
@GetMapping("/list/plan/{planId}")
|
||||
public List<ApiScenarioModuleDTO> getNodeByPlanId(@PathVariable String planId) {
|
||||
checkOwnerService.checkTestPlanOwner(planId);
|
||||
checkPermissionService.checkTestPlanOwner(planId);
|
||||
return apiScenarioModuleService.getNodeByPlanId(planId);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package io.metersphere.api.controller;
|
|||
import io.metersphere.api.service.ApiTestEnvironmentService;
|
||||
import io.metersphere.base.domain.ApiTestEnvironmentWithBLOBs;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -19,11 +19,11 @@ public class ApiTestEnvironmentController {
|
|||
@Resource
|
||||
ApiTestEnvironmentService apiTestEnvironmentService;
|
||||
@Resource
|
||||
private CheckOwnerService checkOwnerService;
|
||||
private CheckPermissionService checkPermissionService;
|
||||
|
||||
@GetMapping("/list/{projectId}")
|
||||
public List<ApiTestEnvironmentWithBLOBs> list(@PathVariable String projectId) {
|
||||
checkOwnerService.checkProjectOwner(projectId);
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return apiTestEnvironmentService.list(projectId);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ public class RunDefinitionRequest {
|
|||
|
||||
private String reportId;
|
||||
|
||||
private String name;
|
||||
|
||||
private String type;
|
||||
|
||||
private String projectId;
|
||||
|
|
|
@ -110,7 +110,9 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
if (useEnvironment != null) {
|
||||
ApiTestEnvironmentService environmentService = CommonBeanFactory.getBean(ApiTestEnvironmentService.class);
|
||||
ApiTestEnvironmentWithBLOBs environment = environmentService.get(useEnvironment);
|
||||
config.setConfig(JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class));
|
||||
if (environment != null && environment.getConfig() != null) {
|
||||
config.setConfig(JSONObject.parseObject(environment.getConfig(), EnvironmentConfig.class));
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (config != null && config.getConfig() != null) {
|
||||
|
@ -119,9 +121,15 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
sampler.setPort(config.getConfig().getHttpConfig().getPort());
|
||||
sampler.setProtocol(config.getConfig().getHttpConfig().getProtocol());
|
||||
url = config.getConfig().getHttpConfig().getProtocol() + "://" + config.getConfig().getHttpConfig().getSocket();
|
||||
// 补充如果是完整URL 则用自身URL
|
||||
boolean isUrl = false;
|
||||
if (StringUtils.isNotEmpty(this.getUrl()) && isURL(this.getUrl())) {
|
||||
url = this.getUrl();
|
||||
isUrl = true;
|
||||
}
|
||||
URL urlObject = new URL(url);
|
||||
String envPath = StringUtils.equals(urlObject.getPath(), "/") ? "" : urlObject.getPath();
|
||||
if (StringUtils.isNotBlank(this.getPath())) {
|
||||
if (StringUtils.isNotBlank(this.getPath()) && !isUrl) {
|
||||
envPath += this.getPath();
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(this.getRest()) && this.isRest()) {
|
||||
|
@ -243,6 +251,15 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
tree.add(headerManager);
|
||||
}
|
||||
|
||||
public boolean isURL(String str) {
|
||||
//转换为小写
|
||||
try {
|
||||
new URL(str);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRest() {
|
||||
return this.getRest().stream().filter(KeyValue::isEnable).filter(KeyValue::isValid).toArray().length > 0;
|
||||
|
|
|
@ -98,11 +98,14 @@ public class Body {
|
|||
return StringUtils.equals(type, XML);
|
||||
}
|
||||
|
||||
public boolean isWwwFROM() {
|
||||
return StringUtils.equals(type, WWW_FROM);
|
||||
public void initKvs() {
|
||||
this.kvs = new ArrayList<>();
|
||||
this.kvs.add(new KeyValue());
|
||||
}
|
||||
|
||||
public boolean isFromData() {
|
||||
return StringUtils.equals(type, FORM_DATA);
|
||||
public void initBinary() {
|
||||
this.binary = new ArrayList<>();
|
||||
this.binary.add(new KeyValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ public class KeyValue {
|
|||
private List<BodyFile> files;
|
||||
private String description;
|
||||
private String contentType;
|
||||
private boolean enable;
|
||||
private boolean enable = true;
|
||||
private boolean encode = true;
|
||||
private boolean required;
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.BufferedReader;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -72,7 +73,7 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
|||
protected ApiDefinitionResult buildApiDefinition(String id, String name, String path, String method) {
|
||||
ApiDefinitionResult apiDefinition = new ApiDefinitionResult();
|
||||
apiDefinition.setName(name);
|
||||
apiDefinition.setPath(path);
|
||||
apiDefinition.setPath(formatPath(path));
|
||||
apiDefinition.setProtocol(RequestType.HTTP);
|
||||
apiDefinition.setMethod(method);
|
||||
apiDefinition.setId(id);
|
||||
|
@ -81,17 +82,34 @@ public abstract class ApiImportAbstractParser implements ApiImportParser {
|
|||
return apiDefinition;
|
||||
}
|
||||
|
||||
private String formatPath(String url) {
|
||||
try {
|
||||
URL urlObject = new URL(url);
|
||||
StringBuffer pathBuffer = new StringBuffer(urlObject.getPath());
|
||||
if (StringUtils.isNotEmpty(urlObject.getQuery())) {
|
||||
pathBuffer.append("?").append(urlObject.getQuery());
|
||||
}
|
||||
return pathBuffer.toString();
|
||||
} catch (Exception ex) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
protected MsHTTPSamplerProxy buildRequest(String name, String path, String method) {
|
||||
MsHTTPSamplerProxy request = new MsHTTPSamplerProxy();
|
||||
request.setName(name);
|
||||
request.setPath(path);
|
||||
// 路径去掉域名/IP 地址,保留方法名称及参数
|
||||
request.setPath(formatPath(path));
|
||||
request.setMethod(method);
|
||||
request.setProtocol(RequestType.HTTP);
|
||||
request.setId(UUID.randomUUID().toString());
|
||||
request.setHeaders(new ArrayList<>());
|
||||
request.setArguments(new ArrayList<>());
|
||||
request.setRest(new ArrayList<>());
|
||||
request.setBody(new Body());
|
||||
Body body = new Body();
|
||||
body.initKvs();
|
||||
body.initBinary();
|
||||
request.setBody(body);
|
||||
return request;
|
||||
}
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ public class APIReportService {
|
|||
apiTestReportMapper.deleteByExample(apiTestReportExample);
|
||||
}
|
||||
|
||||
public long countByWorkspaceIdAndGroupAndCreateInThisWeek(String workspaceID, String group) {
|
||||
public long countByProjectIdAndCreateInThisWeek(String projectId) {
|
||||
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
|
||||
|
||||
Date firstTime = startAndEndDateInWeek.get("firstTime");
|
||||
|
@ -221,11 +221,11 @@ public class APIReportService {
|
|||
if(firstTime==null || lastTime == null){
|
||||
return 0;
|
||||
}else {
|
||||
return extApiTestReportMapper.countByProjectIDAndCreateInThisWeek(workspaceID,group,firstTime.getTime(),lastTime.getTime());
|
||||
return extApiTestReportMapper.countByProjectIDAndCreateInThisWeek(projectId,firstTime.getTime(),lastTime.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public List<ApiDataCountResult> countByWorkspaceIdAndGroupGroupByExecuteResult(String workspaceID, String group) {
|
||||
return extApiTestReportMapper.countByWorkspaceIdAndGroupGroupByExecuteResult(workspaceID,group);
|
||||
public List<ApiDataCountResult> countByProjectIdGroupByExecuteResult(String projectId) {
|
||||
return extApiTestReportMapper.countByProjectIdGroupByExecuteResult(projectId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,9 @@ import io.metersphere.api.dto.scenario.environment.EnvironmentConfig;
|
|||
import io.metersphere.api.jmeter.JMeterService;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanScenarioCaseMapper;
|
||||
import io.metersphere.commons.constants.*;
|
||||
|
@ -28,6 +30,9 @@ import io.metersphere.service.ScheduleService;
|
|||
import io.metersphere.track.dto.TestPlanDTO;
|
||||
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
|
||||
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
|
||||
import io.metersphere.track.request.testcase.TestPlanApiCaseBatchRequest;
|
||||
import io.metersphere.track.service.TestPlanApiCaseService;
|
||||
import io.metersphere.track.service.TestPlanScenarioCaseService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
|
@ -53,8 +58,8 @@ public class ApiAutomationService {
|
|||
private ApiDefinitionService apiDefinitionService;
|
||||
@Resource
|
||||
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||
// @Resource
|
||||
// private ApiTagMapper apiTagMapper;
|
||||
@Resource
|
||||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||
@Resource
|
||||
private JMeterService jMeterService;
|
||||
@Resource
|
||||
|
@ -150,10 +155,56 @@ public class ApiAutomationService {
|
|||
}
|
||||
|
||||
public void delete(String id) {
|
||||
//及连删除外键表
|
||||
this.preDelete(id);
|
||||
apiScenarioMapper.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public void preDelete(String scenarioID){
|
||||
scheduleService.deleteByResourceId(scenarioID);
|
||||
|
||||
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
|
||||
example.createCriteria().andApiScenarioIdEqualTo(scenarioID);
|
||||
List<TestPlanApiScenario> testPlanApiScenarioList = testPlanApiScenarioMapper.selectByExample(example);
|
||||
|
||||
List<String> idList = new ArrayList<>(testPlanApiScenarioList.size());
|
||||
for (TestPlanApiScenario api :
|
||||
testPlanApiScenarioList) {
|
||||
idList.add(api.getId());
|
||||
}
|
||||
example = new TestPlanApiScenarioExample();
|
||||
|
||||
if(!idList.isEmpty()){
|
||||
example.createCriteria().andIdIn(idList);
|
||||
testPlanApiScenarioMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
}
|
||||
public void preDelete(List<String> scenarioIDList){
|
||||
List<String> testPlanApiScenarioIdList = new ArrayList<>();
|
||||
List<String> scheduleIdList = new ArrayList<>();
|
||||
for (String id :scenarioIDList) {
|
||||
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
|
||||
example.createCriteria().andApiScenarioIdEqualTo(id);
|
||||
List<TestPlanApiScenario> testPlanApiScenarioList = testPlanApiScenarioMapper.selectByExample(example);
|
||||
for (TestPlanApiScenario api :testPlanApiScenarioList) {
|
||||
if(!testPlanApiScenarioIdList.contains(api.getId())){
|
||||
testPlanApiScenarioIdList.add(api.getId());
|
||||
}
|
||||
}
|
||||
|
||||
scheduleService.deleteByResourceId(id);
|
||||
}
|
||||
if(!testPlanApiScenarioIdList.isEmpty()){
|
||||
TestPlanApiScenarioExample example = new TestPlanApiScenarioExample();
|
||||
example.createCriteria().andIdIn(testPlanApiScenarioIdList);
|
||||
testPlanApiScenarioMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
}
|
||||
public void deleteBatch(List<String> ids) {
|
||||
//及连删除外键表
|
||||
preDelete(ids);;
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
example.createCriteria().andIdIn(ids);
|
||||
apiScenarioMapper.deleteByExample(example);
|
||||
|
@ -246,6 +297,7 @@ public class ApiAutomationService {
|
|||
});
|
||||
scenario.setVariables(variables);
|
||||
}
|
||||
group.setEnableCookieShare(scenario.isEnableCookieShare());
|
||||
LinkedList<MsTestElement> scenarios = new LinkedList<>();
|
||||
scenarios.add(scenario);
|
||||
group.setHashTree(scenarios);
|
||||
|
@ -301,7 +353,7 @@ public class ApiAutomationService {
|
|||
QueryTestPlanRequest planRequest = new QueryTestPlanRequest();
|
||||
planRequest.setScenarioId(request.getId());
|
||||
planRequest.setProjectId(request.getProjectId());
|
||||
dto.setTestPlanList(extTestPlanMapper.selectReference(planRequest));
|
||||
dto.setTestPlanList(extTestPlanMapper.selectTestPlanByRelevancy(planRequest));
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
@ -312,37 +364,66 @@ public class ApiAutomationService {
|
|||
List<TestPlanDTO> list = extTestPlanMapper.selectByIds(request.getPlanIds());
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ExtTestPlanMapper mapper = sqlSession.getMapper(ExtTestPlanMapper.class);
|
||||
list.forEach(item -> {
|
||||
if (CollectionUtils.isNotEmpty(request.getApiIds())) {
|
||||
if (CollectionUtils.isNotEmpty(request.getApiIds())) {
|
||||
if (StringUtils.isEmpty(item.getApiIds())) {
|
||||
item.setApiIds(JSON.toJSONString(request.getApiIds()));
|
||||
} else {
|
||||
// 合并api
|
||||
List<String> dbApiIDs = JSON.parseArray(item.getApiIds(), String.class);
|
||||
List<String> result = Stream.of(request.getApiIds(), dbApiIDs)
|
||||
.flatMap(Collection::stream).distinct().collect(Collectors.toList());
|
||||
item.setApiIds(JSON.toJSONString(result));
|
||||
}
|
||||
item.setScenarioIds(null);
|
||||
ExtTestPlanScenarioCaseMapper scenarioBatchMapper = sqlSession.getMapper(ExtTestPlanScenarioCaseMapper.class);
|
||||
ExtTestPlanApiCaseMapper apiCaseBatchMapper = sqlSession.getMapper(ExtTestPlanApiCaseMapper.class);
|
||||
|
||||
for (TestPlanDTO testPlan:list) {
|
||||
if(request.getScenarioIds()!=null){
|
||||
for (String scenarioId : request.getScenarioIds()) {
|
||||
TestPlanApiScenario testPlanApiScenario = new TestPlanApiScenario();
|
||||
testPlanApiScenario.setId(UUID.randomUUID().toString());
|
||||
testPlanApiScenario.setApiScenarioId(scenarioId);
|
||||
testPlanApiScenario.setTestPlanId(testPlan.getId());
|
||||
testPlanApiScenario.setCreateTime(System.currentTimeMillis());
|
||||
testPlanApiScenario.setUpdateTime(System.currentTimeMillis());
|
||||
scenarioBatchMapper.insertIfNotExists(testPlanApiScenario);
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(request.getScenarioIds())) {
|
||||
if (CollectionUtils.isNotEmpty(request.getScenarioIds())) {
|
||||
if (StringUtils.isEmpty(item.getScenarioIds())) {
|
||||
item.setScenarioIds(JSON.toJSONString(request.getScenarioIds()));
|
||||
} else {
|
||||
// 合并场景ID
|
||||
List<String> dbScenarioIDs = JSON.parseArray(item.getScenarioIds(), String.class);
|
||||
List<String> result = Stream.of(request.getScenarioIds(), dbScenarioIDs)
|
||||
.flatMap(Collection::stream).distinct().collect(Collectors.toList());
|
||||
item.setScenarioIds(JSON.toJSONString(result));
|
||||
}
|
||||
item.setApiIds(null);
|
||||
if(request.getApiIds()!=null){
|
||||
for (String caseId : request.getApiIds()) {
|
||||
TestPlanApiCase testPlanApiCase = new TestPlanApiCase();
|
||||
testPlanApiCase.setId(UUID.randomUUID().toString());
|
||||
testPlanApiCase.setApiCaseId(caseId);
|
||||
testPlanApiCase.setTestPlanId(testPlan.getId());
|
||||
testPlanApiCase.setCreateTime(System.currentTimeMillis());
|
||||
testPlanApiCase.setUpdateTime(System.currentTimeMillis());
|
||||
apiCaseBatchMapper.insertIfNotExists(testPlanApiCase);
|
||||
}
|
||||
}
|
||||
mapper.updatePlan(item);
|
||||
});
|
||||
|
||||
}
|
||||
// testPlan的ID先不存储
|
||||
// list.forEach(item -> {
|
||||
// if (CollectionUtils.isNotEmpty(request.getApiIds())) {
|
||||
// if (CollectionUtils.isNotEmpty(request.getApiIds())) {
|
||||
// if (StringUtils.isEmpty(item.getApiIds())) {
|
||||
// item.setApiIds(JSON.toJSONString(request.getApiIds()));
|
||||
// } else {
|
||||
// // 合并api
|
||||
// List<String> dbApiIDs = JSON.parseArray(item.getApiIds(), String.class);
|
||||
// List<String> result = Stream.of(request.getApiIds(), dbApiIDs)
|
||||
// .flatMap(Collection::stream).distinct().collect(Collectors.toList());
|
||||
// item.setApiIds(JSON.toJSONString(result));
|
||||
// }
|
||||
// item.setScenarioIds(null);
|
||||
// }
|
||||
// }
|
||||
// if (CollectionUtils.isNotEmpty(request.getScenarioIds())) {
|
||||
// if (CollectionUtils.isNotEmpty(request.getScenarioIds())) {
|
||||
// if (StringUtils.isEmpty(item.getScenarioIds())) {
|
||||
// item.setScenarioIds(JSON.toJSONString(request.getScenarioIds()));
|
||||
// } else {
|
||||
// // 合并场景ID
|
||||
// List<String> dbScenarioIDs = JSON.parseArray(item.getScenarioIds(), String.class);
|
||||
// List<String> result = Stream.of(request.getScenarioIds(), dbScenarioIDs)
|
||||
// .flatMap(Collection::stream).distinct().collect(Collectors.toList());
|
||||
// item.setScenarioIds(JSON.toJSONString(result));
|
||||
// }
|
||||
// item.setApiIds(null);
|
||||
// }
|
||||
// }
|
||||
// mapper.updatePlan(item);
|
||||
// });
|
||||
sqlSession.flushStatements();
|
||||
return "success";
|
||||
}
|
||||
|
|
|
@ -29,8 +29,6 @@ public class ApiDefinitionExecResultService {
|
|||
|
||||
public void saveApiResult(TestResult result, String type) {
|
||||
result.getScenarios().get(0).getRequestResults().forEach(item -> {
|
||||
// 清理原始资源,每个执行 保留一条结果
|
||||
extApiDefinitionExecResultMapper.deleteByResourceId(item.getName());
|
||||
ApiDefinitionExecResult saveResult = new ApiDefinitionExecResult();
|
||||
saveResult.setId(UUID.randomUUID().toString());
|
||||
saveResult.setCreateTime(System.currentTimeMillis());
|
||||
|
|
|
@ -392,7 +392,7 @@ public class ApiDefinitionService {
|
|||
QueryTestPlanRequest planRequest = new QueryTestPlanRequest();
|
||||
planRequest.setApiId(request.getId());
|
||||
planRequest.setProjectId(request.getProjectId());
|
||||
dto.setTestPlanList(extTestPlanMapper.selectReference(planRequest));
|
||||
dto.setTestPlanList(extTestPlanMapper.selectTestPlanByRelevancy(planRequest));
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.api.dto.DeleteAPIReportRequest;
|
|||
import io.metersphere.api.dto.QueryAPIReportRequest;
|
||||
import io.metersphere.api.dto.automation.APIScenarioReportResult;
|
||||
import io.metersphere.api.dto.automation.ExecuteType;
|
||||
import io.metersphere.api.dto.datacount.ApiDataCountResult;
|
||||
import io.metersphere.api.jmeter.ScenarioResult;
|
||||
import io.metersphere.api.jmeter.TestResult;
|
||||
import io.metersphere.base.domain.*;
|
||||
|
@ -16,10 +17,13 @@ import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
|
|||
import io.metersphere.base.mapper.ext.ExtApiScenarioReportMapper;
|
||||
import io.metersphere.commons.constants.APITestStatus;
|
||||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.constants.ReportTriggerMode;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.DateUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.ServiceUtils;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -28,10 +32,7 @@ import sun.security.util.Cache;
|
|||
import javax.annotation.Resource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
@ -55,6 +56,13 @@ public class ApiScenarioReportService {
|
|||
MSException.throwException(Translator.get("api_report_is_null"));
|
||||
}
|
||||
APIScenarioReportResult report = (APIScenarioReportResult) obj;
|
||||
if (CollectionUtils.isNotEmpty(result.getScenarios())) {
|
||||
try {
|
||||
report.setName(result.getScenarios().get(0).getName() + "-" + DateUtils.getTimeString(System.currentTimeMillis()));
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
// report detail
|
||||
ApiScenarioReportDetail detail = new ApiScenarioReportDetail();
|
||||
detail.setReportId(result.getTestId());
|
||||
|
@ -72,7 +80,9 @@ public class ApiScenarioReportService {
|
|||
}
|
||||
report.setContent(new String(detail.getContent(), StandardCharsets.UTF_8));
|
||||
this.save(report, runMode);
|
||||
cache.put(report.getId(), report);
|
||||
if (!report.getTriggerMode().equals(ReportTriggerMode.SCHEDULE.name())) {
|
||||
cache.put(report.getId(), report);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,7 +255,7 @@ public class ApiScenarioReportService {
|
|||
return extApiScenarioReportMapper.countByProjectID(projectId);
|
||||
}
|
||||
|
||||
public long countByProjectIDAndCreateInThisWeek(String projectId) {
|
||||
public long countByProjectIdAndCreateAndByScheduleInThisWeek(String projectId) {
|
||||
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
|
||||
|
||||
Date firstTime = startAndEndDateInWeek.get("firstTime");
|
||||
|
@ -254,7 +264,24 @@ public class ApiScenarioReportService {
|
|||
if (firstTime == null || lastTime == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return extApiScenarioReportMapper.countByProjectIDAndCreateInThisWeek(projectId, firstTime.getTime(), lastTime.getTime());
|
||||
return extApiScenarioReportMapper.countByProjectIdAndCreateAndByScheduleInThisWeek(projectId, firstTime.getTime(), lastTime.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public long countByProjectIdAndCreateInThisWeek(String projectId) {
|
||||
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
|
||||
|
||||
Date firstTime = startAndEndDateInWeek.get("firstTime");
|
||||
Date lastTime = startAndEndDateInWeek.get("lastTime");
|
||||
|
||||
if (firstTime == null || lastTime == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return extApiScenarioReportMapper.countByProjectIdAndCreateInThisWeek(projectId, firstTime.getTime(), lastTime.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public List<ApiDataCountResult> countByProjectIdGroupByExecuteResult(String projectId) {
|
||||
return extApiScenarioReportMapper.countByProjectIdGroupByExecuteResult(projectId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import io.metersphere.base.mapper.ApiTestFileMapper;
|
|||
import io.metersphere.base.mapper.ext.ExtApiDefinitionExecResultMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiTestCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanApiCaseMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtTestPlanTestCaseMapper;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.*;
|
||||
import io.metersphere.i18n.Translator;
|
||||
|
@ -48,6 +49,8 @@ public class ApiTestCaseService {
|
|||
@Resource
|
||||
private ApiTestFileMapper apiTestFileMapper;
|
||||
@Resource
|
||||
private ExtTestPlanTestCaseMapper extTestPlanTestCaseMapper;
|
||||
@Resource
|
||||
private FileService fileService;
|
||||
@Resource
|
||||
private ExtApiDefinitionExecResultMapper extApiDefinitionExecResultMapper;
|
||||
|
@ -131,8 +134,12 @@ public class ApiTestCaseService {
|
|||
}
|
||||
|
||||
public void delete(String testId) {
|
||||
|
||||
extTestPlanTestCaseMapper.deleteByTestCaseID(testId);
|
||||
|
||||
deleteFileByTestId(testId);
|
||||
extApiDefinitionExecResultMapper.deleteByResourceId(testId);
|
||||
|
||||
apiTestCaseMapper.deleteByPrimaryKey(testId);
|
||||
deleteBodyFiles(testId);
|
||||
}
|
||||
|
@ -253,6 +260,9 @@ public class ApiTestCaseService {
|
|||
}
|
||||
|
||||
public void deleteBatch(List<String> ids) {
|
||||
for (String testId:ids) {
|
||||
extTestPlanTestCaseMapper.deleteByTestCaseID(testId);
|
||||
}
|
||||
ApiTestCaseExample example = new ApiTestCaseExample();
|
||||
example.createCriteria().andIdIn(ids);
|
||||
apiTestCaseMapper.deleteByExample(example);
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
SELECT testCase.testCaseName AS caseName,testCase.testPlanName AS testPlan ,caseErrorCountData.dataCountNumber AS failureTimes,'apiCase' AS caseType
|
||||
FROM (
|
||||
SELECT apiCase.id AS testCaseID,apiCase.`name` AS testCaseName,group_concat(testPlan.`name`) AS testPlanName FROM api_test_case apiCase
|
||||
LEFT JOIN test_plan testPlan ON testPlan.api_ids like concat('%"',apiCase.id,'"%')
|
||||
LEFT JOIN test_plan_api_case testPlanCase ON testPlanCase.api_case_id = apiCase.id
|
||||
LEFT JOIN test_plan testPlan ON testPlan.id = testPlanCase.test_plan_id
|
||||
GROUP BY apiCase.id
|
||||
ORDER BY apiCase.create_time DESC
|
||||
)testCase
|
||||
|
|
|
@ -2,6 +2,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 org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
|
@ -14,6 +15,9 @@ public interface ExtApiScenarioReportMapper {
|
|||
|
||||
long countByProjectID(String projectId);
|
||||
|
||||
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
|
||||
long countByProjectIdAndCreateInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
|
||||
|
||||
long countByProjectIdAndCreateAndByScheduleInThisWeek(@Param("projectId") String projectId, @Param("firstDayTimestamp") long firstDayTimestamp, @Param("lastDayTimestamp") long lastDayTimestamp);
|
||||
|
||||
List<ApiDataCountResult> countByProjectIdGroupByExecuteResult(String projectId);
|
||||
}
|
|
@ -169,9 +169,28 @@
|
|||
<select id="countByProjectID" resultType="java.lang.Long">
|
||||
SELECT count(id) AS countNumber FROM api_scenario_report WHERE project_id = #{0}
|
||||
</select>
|
||||
<select id="countByProjectIDAndCreateInThisWeek" resultType="java.lang.Long">
|
||||
<select id="countByProjectIdAndCreateInThisWeek" resultType="java.lang.Long">
|
||||
SELECT count(id) AS countNumber FROM api_scenario_report
|
||||
WHERE project_id = #{projectId}
|
||||
AND create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
|
||||
</select>
|
||||
|
||||
<select id="countByProjectIdAndCreateAndByScheduleInThisWeek" resultType="java.lang.Long">
|
||||
SELECT count(acr.report_id) AS countNumber FROM api_scenario_report_detail acr
|
||||
INNER JOIN api_scenario_report ar ON ar.id = acr.report_id
|
||||
INNER JOIN (
|
||||
SELECT acitem.id FROM api_scenario acitem INNER JOIN `schedule` sc ON acitem.id = sc.resource_id
|
||||
) ac on acr.content like CONCAT('%', ac.id,'%')
|
||||
WHERE acr.project_id = #{projectId} AND ar.create_time BETWEEN #{firstDayTimestamp} AND #{lastDayTimestamp}
|
||||
</select>
|
||||
|
||||
<select id="countByProjectIdGroupByExecuteResult" resultType="io.metersphere.api.dto.datacount.ApiDataCountResult">
|
||||
SELECT count(acr.report_id) AS countNumber,ar.status AS groupField
|
||||
FROM api_scenario_report_detail acr
|
||||
INNER JOIN api_scenario_report ar ON ar.id = acr.report_id
|
||||
INNER JOIN (
|
||||
SELECT acitem.id FROM api_scenario acitem INNER JOIN `schedule` sc ON acitem.id = sc.resource_id
|
||||
) ac on acr.content like CONCAT('%', ac.id,'%')
|
||||
WHERE acr.project_id = #{projectId}
|
||||
</select>
|
||||
</mapper>
|
|
@ -18,7 +18,7 @@ public interface ExtApiTestReportMapper {
|
|||
|
||||
List<DashboardTestDTO> selectDashboardTests(@Param("workspaceId") String workspaceId, @Param("startTimestamp") long startTimestamp);
|
||||
|
||||
List<ApiDataCountResult> countByWorkspaceIdAndGroupGroupByExecuteResult(@Param("workspaceID") String workspaceID, @Param("group")String group);
|
||||
List<ApiDataCountResult> countByProjectIdGroupByExecuteResult(String projectId);
|
||||
|
||||
long countByProjectIDAndCreateInThisWeek(@Param("workspaceID") String workspaceID, @Param("group")String group, @Param("startTime") long startTime, @Param("endTime")long endTime);
|
||||
long countByProjectIDAndCreateInThisWeek(@Param("projectId") String projectId, @Param("startTime") long startTime, @Param("endTime")long endTime);
|
||||
}
|
||||
|
|
|
@ -152,19 +152,24 @@
|
|||
GROUP BY x
|
||||
</select>
|
||||
|
||||
<select id="countByWorkspaceIdAndGroupGroupByExecuteResult" resultType="io.metersphere.api.dto.datacount.ApiDataCountResult">
|
||||
<select id="countByProjectIdGroupByExecuteResult" resultType="io.metersphere.api.dto.datacount.ApiDataCountResult">
|
||||
SELECT testReport.`status` AS groupField,COUNT(testReportDetail.report_id) AS countNumber
|
||||
FROM api_test_report_detail testReportDetail
|
||||
INNER JOIN `schedule` sch ON sch.resource_id = testReportDetail.test_id
|
||||
INNER JOIN api_test_report testReport ON testReportDetail.report_id = testReport.id
|
||||
WHERE workspace_id = #{workspaceID} AND `group` = #{group}
|
||||
WHERE sch.resource_id IN (
|
||||
SELECT id FROM api_test WHERE project_id = #{projectId,jdbcType=VARCHAR}
|
||||
)
|
||||
AND `group` = #{group}
|
||||
</select>
|
||||
|
||||
<select id="countByProjectIDAndCreateInThisWeek" resultType="java.lang.Long">
|
||||
SELECT COUNT(testReportDetail.report_id) AS countNumber FROM api_test_report_detail testReportDetail
|
||||
INNER JOIN `schedule` sch ON sch.resource_id = testReportDetail.test_id
|
||||
INNER JOIN api_test_report testReport ON testReportDetail.report_id = testReport.id
|
||||
WHERE workspace_id = #{workspaceID} AND `group` = #{group}
|
||||
WHERE sch.resource_id IN (
|
||||
SELECT id FROM api_test WHERE project_id = #{projectId,jdbcType=VARCHAR}
|
||||
)
|
||||
AND testReport.create_time BETWEEN #{startTime} and #{endTime}
|
||||
</select>
|
||||
</mapper>
|
|
@ -10,9 +10,9 @@ import java.util.List;
|
|||
public interface ExtScheduleMapper {
|
||||
List<ScheduleDao> list(@Param("request") QueryScheduleRequest request);
|
||||
|
||||
long countTaskByWorkspaceIdAndGroup(@Param("workspaceId") String workspaceId,@Param("group") String group);
|
||||
long countTaskByProjectId(String workspaceId);
|
||||
|
||||
long countTaskByWorkspaceIdAndGroupAndCreateTimeRange(@Param("workspaceId")String workspaceId,@Param("group") String group, @Param("startTime") long startTime, @Param("endTime") long endTime);
|
||||
long countTaskByProjectIdAndCreateTimeRange(@Param("projectId")String projectId, @Param("startTime") long startTime, @Param("endTime") long endTime);
|
||||
|
||||
List<TaskInfoResult> findRunningTaskInfoByWorkspaceID(String workspaceID);
|
||||
List<TaskInfoResult> findRunningTaskInfoByProjectID(String workspaceID);
|
||||
}
|
|
@ -36,26 +36,33 @@
|
|||
</if>
|
||||
</select>
|
||||
|
||||
<select id="countTaskByWorkspaceIdAndGroup" resultType="java.lang.Long">
|
||||
SELECT COUNT(id) AS countNumber FROM `schedule` WHERE `workspace_id` = #{workspaceId} AND `group` = #{group}
|
||||
<select id="countTaskByProjectId" resultType="java.lang.Long">
|
||||
SELECT COUNT(id) AS countNumber FROM `schedule` WHERE resource_id IN (
|
||||
SELECT id FROM api_test WHERE project_id = #{0,jdbcType=VARCHAR}
|
||||
UNION
|
||||
SELECT id FROM api_scenario WHERE project_id = #{0,jdbcType=VARCHAR}
|
||||
)
|
||||
</select>
|
||||
<select id="countTaskByWorkspaceIdAndGroupAndCreateTimeRange" resultType="java.lang.Long">
|
||||
<select id="countTaskByProjectIdAndCreateTimeRange" resultType="java.lang.Long">
|
||||
SELECT COUNT(id) AS countNumber FROM `schedule`
|
||||
WHERE workspace_id = #{workspaceId}
|
||||
AND `group` = #{group}
|
||||
WHERE resource_id IN (
|
||||
SELECT id FROM api_test WHERE project_id = #{projectId,jdbcType=VARCHAR}
|
||||
UNION
|
||||
SELECT id FROM api_scenario WHERE project_id = #{projectId,jdbcType=VARCHAR}
|
||||
)
|
||||
AND create_time BETWEEN #{startTime} and #{endTime}
|
||||
</select>
|
||||
<select id="findRunningTaskInfoByWorkspaceID" resultType="io.metersphere.api.dto.datacount.response.TaskInfoResult">
|
||||
<select id="findRunningTaskInfoByProjectID" resultType="io.metersphere.api.dto.datacount.response.TaskInfoResult">
|
||||
SELECT apiTest.`name` AS scenario,sch.id AS taskID,sch.`value` AS rule,sch.`enable` AS `taskStatus`,u.`name` AS creator,sch.update_time AS updateTime
|
||||
FROM api_test apiTest
|
||||
INNER JOIN `schedule` sch ON apiTest.id = sch.resource_id
|
||||
INNER JOIN `user` u ON u.id = sch.user_id
|
||||
WHERE sch.`enable` = true AND sch.workspace_id = #{0,jdbcType=VARCHAR}
|
||||
WHERE sch.`enable` = true AND apiTest.project_id = #{0,jdbcType=VARCHAR}
|
||||
UNION
|
||||
SELECT apiTest.`name` AS scenario,sch.id AS taskID,sch.`value` AS rule,sch.`enable` AS `taskStatus`,u.`name` AS creator,sch.update_time AS updateTime
|
||||
FROM api_scenario apiTest
|
||||
INNER JOIN `schedule` sch ON apiTest.id = sch.resource_id
|
||||
SELECT apiScene.`name` AS scenario,sch.id AS taskID,sch.`value` AS rule,sch.`enable` AS `taskStatus`,u.`name` AS creator,sch.update_time AS updateTime
|
||||
FROM api_scenario apiScene
|
||||
INNER JOIN `schedule` sch ON apiScene.id = sch.resource_id
|
||||
INNER JOIN `user` u ON u.id = sch.user_id
|
||||
WHERE sch.`enable` = true AND sch.workspace_id = #{0,jdbcType=VARCHAR}
|
||||
WHERE sch.`enable` = true AND apiScene.project_id = #{0,jdbcType=VARCHAR}
|
||||
</select>
|
||||
</mapper>
|
|
@ -21,5 +21,12 @@ public interface ExtTestPlanMapper {
|
|||
|
||||
List<TestPlanDTO> selectReference(@Param("request") QueryTestPlanRequest params);
|
||||
|
||||
/**
|
||||
* 通过关联表(test_plan_api_case/test_plan_api_scenario)查询testPlan
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
List<TestPlanDTO> selectTestPlanByRelevancy(@Param("request") QueryTestPlanRequest params);
|
||||
|
||||
int checkIsHave(@Param("planId") String planId, @Param("workspaceIds") Set<String> workspaceIds);
|
||||
}
|
||||
|
|
|
@ -227,4 +227,16 @@
|
|||
</foreach>
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectTestPlanByRelevancy" resultMap="BaseResultMap" parameterType="io.metersphere.track.request.testcase.QueryTestPlanRequest">
|
||||
SELECT * FROM TEST_PLAN p LEFT JOIN test_plan_project t ON t.test_plan_id=p.id
|
||||
<where>
|
||||
<if test="request.scenarioId != null">
|
||||
AND p.id IN (SELECT test_plan_id FROM test_plan_api_scenario WHERE api_scenario_id = #{request.scenarioId} )
|
||||
</if>
|
||||
<if test="request.apiId != null">
|
||||
AND p.id IN (SELECT test_plan_id FROM test_plan_api_case WHERE api_case_id = #{request.apiId})
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
|
@ -7,6 +7,8 @@ import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
|||
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||
import io.metersphere.base.domain.TestPlanApiCase;
|
||||
import io.metersphere.base.domain.TestPlanApiScenario;
|
||||
import io.metersphere.track.dto.TestPlanDTO;
|
||||
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -15,4 +17,5 @@ public interface ExtTestPlanScenarioCaseMapper {
|
|||
void insertIfNotExists(@Param("request") TestPlanApiScenario request);
|
||||
|
||||
List<ApiScenarioDTO> list(@Param("request") TestPlanScenarioRequest request);
|
||||
|
||||
}
|
|
@ -40,4 +40,5 @@ public interface ExtTestPlanTestCaseMapper {
|
|||
|
||||
TestPlanCaseDTO get(String testPlanTestCaseId);
|
||||
|
||||
void deleteByTestCaseID(String id);
|
||||
}
|
||||
|
|
|
@ -122,13 +122,13 @@
|
|||
|
||||
<select id="list" resultType="io.metersphere.track.dto.TestPlanCaseDTO">
|
||||
select test_plan_test_case.id as id, test_case.id as caseId, test_case.name, test_case.priority,
|
||||
test_case.type,test_case.test_id as testId,
|
||||
test_case.type,test_case.test_id as testId,test_case.node_id,
|
||||
test_case.node_path, test_case.method, test_case.num, test_plan_test_case.executor, test_plan_test_case.status,
|
||||
test_plan_test_case.update_time, test_case_node.name as model, project.name as projectName,
|
||||
test_plan_test_case.plan_id as planId
|
||||
from test_plan_test_case
|
||||
inner join test_case on test_plan_test_case.case_id = test_case.id
|
||||
left join test_case_node on test_case_node.id=test_case.node_id
|
||||
left join test_case_node on test_case_node.id = test_case.node_id
|
||||
inner join project on project.id = test_case.project_id
|
||||
<where>
|
||||
<if test="request.combine != null">
|
||||
|
@ -342,4 +342,8 @@
|
|||
#{id}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<delete id="deleteByTestCaseID" parameterType="java.lang.String">
|
||||
delete from test_plan_api_case where api_case_id = #{id,jdbcType=VARCHAR}
|
||||
</delete>
|
||||
</mapper>
|
|
@ -9,7 +9,7 @@ import io.metersphere.commons.utils.Pager;
|
|||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.controller.request.ProjectRequest;
|
||||
import io.metersphere.dto.ProjectDTO;
|
||||
import io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.service.ProjectService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
|
@ -24,7 +24,7 @@ public class ProjectController {
|
|||
@Resource
|
||||
private ProjectService projectService;
|
||||
@Resource
|
||||
private CheckOwnerService checkOwnerService;
|
||||
private CheckPermissionService checkPermissionService;
|
||||
|
||||
@GetMapping("/listAll")
|
||||
public List<ProjectDTO> listAll() {
|
||||
|
@ -74,7 +74,7 @@ public class ProjectController {
|
|||
@GetMapping("/delete/{projectId}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER,}, logical = Logical.OR)
|
||||
public void deleteProject(@PathVariable(value = "projectId") String projectId) {
|
||||
checkOwnerService.checkProjectOwner(projectId);
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
projectService.deleteProject(projectId);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package io.metersphere.job.sechedule;
|
||||
|
||||
import io.metersphere.api.dto.SaveAPITestRequest;
|
||||
import io.metersphere.api.dto.automation.ExecuteType;
|
||||
import io.metersphere.api.dto.automation.RunScenarioRequest;
|
||||
import io.metersphere.api.service.APITestService;
|
||||
import io.metersphere.api.service.ApiAutomationService;
|
||||
import io.metersphere.commons.constants.ReportTriggerMode;
|
||||
import io.metersphere.commons.constants.ScheduleGroup;
|
||||
|
@ -56,7 +54,7 @@ public class ApiScenarioTestJob extends MsScheduleJob {
|
|||
request.setId(id);
|
||||
request.setReportId(id);
|
||||
request.setProjectId(projectID);
|
||||
request.setTriggerMode(ReportTriggerMode.MANUAL.name());
|
||||
request.setTriggerMode(ReportTriggerMode.SCHEDULE.name());
|
||||
request.setExecuteType(ExecuteType.Completed.name());
|
||||
request.setScenarioIds(this.scenarioIds);
|
||||
request.setReportUserID(this.userId);
|
||||
|
|
|
@ -14,7 +14,7 @@ import io.metersphere.dto.DashboardTestDTO;
|
|||
import io.metersphere.dto.LoadTestDTO;
|
||||
import io.metersphere.dto.ScheduleDao;
|
||||
import io.metersphere.performance.service.PerformanceTestService;
|
||||
import io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.service.FileService;
|
||||
import io.metersphere.track.request.testplan.*;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
|
@ -37,7 +37,7 @@ public class PerformanceTestController {
|
|||
@Resource
|
||||
private FileService fileService;
|
||||
@Resource
|
||||
private CheckOwnerService checkOwnerService;
|
||||
private CheckPermissionService checkPermissionService;
|
||||
|
||||
@GetMapping("recent/{count}")
|
||||
public List<LoadTestDTO> recentTestPlans(@PathVariable int count) {
|
||||
|
@ -59,14 +59,14 @@ public class PerformanceTestController {
|
|||
|
||||
@GetMapping("/list/{projectId}")
|
||||
public List<LoadTest> list(@PathVariable String projectId) {
|
||||
checkOwnerService.checkProjectOwner(projectId);
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return performanceTestService.getLoadTestByProjectId(projectId);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/state/get/{testId}")
|
||||
public LoadTest listByTestId(@PathVariable String testId) {
|
||||
checkOwnerService.checkPerformanceTestOwner(testId);
|
||||
checkPermissionService.checkPerformanceTestOwner(testId);
|
||||
return performanceTestService.getLoadTestBytestId(testId);
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,7 @@ public class PerformanceTestController {
|
|||
@RequestPart("request") SaveTestPlanRequest request,
|
||||
@RequestPart(value = "file") List<MultipartFile> files
|
||||
) {
|
||||
checkPermissionService.checkReadOnlyUser();
|
||||
return performanceTestService.save(request, files);
|
||||
}
|
||||
|
||||
|
@ -83,37 +84,39 @@ public class PerformanceTestController {
|
|||
@RequestPart("request") EditTestPlanRequest request,
|
||||
@RequestPart(value = "file", required = false) List<MultipartFile> files
|
||||
) {
|
||||
checkOwnerService.checkPerformanceTestOwner(request.getId());
|
||||
checkPermissionService.checkReadOnlyUser();
|
||||
checkPermissionService.checkPerformanceTestOwner(request.getId());
|
||||
return performanceTestService.edit(request, files);
|
||||
}
|
||||
|
||||
@GetMapping("/get/{testId}")
|
||||
public LoadTestDTO get(@PathVariable String testId) {
|
||||
checkOwnerService.checkPerformanceTestOwner(testId);
|
||||
checkPermissionService.checkPerformanceTestOwner(testId);
|
||||
return performanceTestService.get(testId);
|
||||
}
|
||||
|
||||
@GetMapping("/get-advanced-config/{testId}")
|
||||
public String getAdvancedConfiguration(@PathVariable String testId) {
|
||||
checkOwnerService.checkPerformanceTestOwner(testId);
|
||||
checkPermissionService.checkPerformanceTestOwner(testId);
|
||||
return performanceTestService.getAdvancedConfiguration(testId);
|
||||
}
|
||||
|
||||
@GetMapping("/get-load-config/{testId}")
|
||||
public String getLoadConfiguration(@PathVariable String testId) {
|
||||
checkOwnerService.checkPerformanceTestOwner(testId);
|
||||
checkPermissionService.checkPerformanceTestOwner(testId);
|
||||
return performanceTestService.getLoadConfiguration(testId);
|
||||
}
|
||||
|
||||
@GetMapping("/get-jmx-content/{testId}")
|
||||
public String getJmxContent(@PathVariable String testId) {
|
||||
checkOwnerService.checkPerformanceTestOwner(testId);
|
||||
checkPermissionService.checkPerformanceTestOwner(testId);
|
||||
return performanceTestService.getJmxContent(testId);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public void delete(@RequestBody DeleteTestPlanRequest request) {
|
||||
checkOwnerService.checkPerformanceTestOwner(request.getId());
|
||||
checkPermissionService.checkReadOnlyUser();
|
||||
checkPermissionService.checkPerformanceTestOwner(request.getId());
|
||||
performanceTestService.delete(request);
|
||||
}
|
||||
|
||||
|
@ -129,7 +132,7 @@ public class PerformanceTestController {
|
|||
|
||||
@GetMapping("/file/metadata/{testId}")
|
||||
public List<FileMetadata> getFileMetadata(@PathVariable String testId) {
|
||||
checkOwnerService.checkPerformanceTestOwner(testId);
|
||||
checkPermissionService.checkPerformanceTestOwner(testId);
|
||||
return fileService.getFileMetadataByTestId(testId);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import io.metersphere.commons.utils.SessionUtils;
|
|||
import io.metersphere.i18n.Translator;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -18,7 +17,7 @@ import java.util.Set;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class CheckOwnerService {
|
||||
public class CheckPermissionService {
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
|
@ -32,6 +31,20 @@ public class CheckOwnerService {
|
|||
@Resource
|
||||
private ExtTestCaseReviewMapper extTestCaseReviewMapper;
|
||||
|
||||
|
||||
public void checkReadOnlyUser() {
|
||||
String currentWorkspaceId = SessionUtils.getCurrentWorkspaceId();
|
||||
Set<String> collect = Objects.requireNonNull(SessionUtils.getUser()).getUserRoles().stream()
|
||||
.filter(ur ->
|
||||
StringUtils.equals(ur.getRoleId(), RoleConstants.TEST_VIEWER))
|
||||
.map(UserRole::getSourceId)
|
||||
.filter(sourceId -> StringUtils.equals(currentWorkspaceId, sourceId))
|
||||
.collect(Collectors.toSet());
|
||||
if (CollectionUtils.isNotEmpty(collect)) {
|
||||
throw new RuntimeException(Translator.get("check_owner_read_only"));
|
||||
}
|
||||
}
|
||||
|
||||
public void checkProjectOwner(String projectId) {
|
||||
Set<String> workspaceIds = getUserRelatedWorkspaceIds();
|
||||
Project project = projectMapper.selectByPrimaryKey(projectId);
|
||||
|
@ -42,7 +55,7 @@ public class CheckOwnerService {
|
|||
return;
|
||||
}
|
||||
if (!workspaceIds.contains(project.getWorkspaceId())) {
|
||||
throw new UnauthorizedException(Translator.get("check_owner_project"));
|
||||
throw new RuntimeException(Translator.get("check_owner_project"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +80,7 @@ public class CheckOwnerService {
|
|||
int result = extApiTestMapper.checkApiTestOwner(testId, workspaceIds);
|
||||
|
||||
if (result == 0) {
|
||||
throw new UnauthorizedException(Translator.get("check_owner_test"));
|
||||
throw new RuntimeException(Translator.get("check_owner_test"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +96,7 @@ public class CheckOwnerService {
|
|||
int result = extLoadTestMapper.checkLoadTestOwner(testId, workspaceIds);
|
||||
|
||||
if (result == 0) {
|
||||
throw new UnauthorizedException(Translator.get("check_owner_test"));
|
||||
throw new RuntimeException(Translator.get("check_owner_test"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +108,7 @@ public class CheckOwnerService {
|
|||
|
||||
int result = extTestCaseMapper.checkIsHave(caseId, workspaceIds);
|
||||
if (result == 0) {
|
||||
throw new UnauthorizedException(Translator.get("check_owner_case"));
|
||||
throw new RuntimeException(Translator.get("check_owner_case"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +119,7 @@ public class CheckOwnerService {
|
|||
}
|
||||
int result = extTestPlanMapper.checkIsHave(planId, workspaceIds);
|
||||
if (result == 0) {
|
||||
throw new UnauthorizedException(Translator.get("check_owner_plan"));
|
||||
throw new RuntimeException(Translator.get("check_owner_plan"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,7 +130,7 @@ public class CheckOwnerService {
|
|||
}
|
||||
int result = extTestCaseReviewMapper.checkIsHave(reviewId, workspaceIds);
|
||||
if (result == 0) {
|
||||
throw new UnauthorizedException(Translator.get("check_owner_review"));
|
||||
throw new RuntimeException(Translator.get("check_owner_review"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,6 @@ import io.metersphere.dto.ScheduleDao;
|
|||
import io.metersphere.job.sechedule.ApiTestJob;
|
||||
import io.metersphere.job.sechedule.ScheduleManager;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.quartz.TriggerKey;
|
||||
|
@ -168,11 +167,11 @@ public class ScheduleService {
|
|||
});
|
||||
}
|
||||
|
||||
public long countTaskByWorkspaceIdAndGroup(String workspaceId,String group) {
|
||||
return extScheduleMapper.countTaskByWorkspaceIdAndGroup(workspaceId,group);
|
||||
public long countTaskByProjectId(String projectId) {
|
||||
return extScheduleMapper.countTaskByProjectId(projectId);
|
||||
}
|
||||
|
||||
public long countTaskByWorkspaceIdAndGroupInThisWeek(String workspaceID, String group) {
|
||||
public long countTaskByProjectIdInThisWeek(String projectId) {
|
||||
Map<String, Date> startAndEndDateInWeek = DateUtils.getWeedFirstTimeAndLastTime(new Date());
|
||||
|
||||
Date firstTime = startAndEndDateInWeek.get("firstTime");
|
||||
|
@ -181,12 +180,12 @@ public class ScheduleService {
|
|||
if(firstTime==null || lastTime == null){
|
||||
return 0;
|
||||
}else {
|
||||
return extScheduleMapper.countTaskByWorkspaceIdAndGroupAndCreateTimeRange(workspaceID,group,firstTime.getTime(),lastTime.getTime());
|
||||
return extScheduleMapper.countTaskByProjectIdAndCreateTimeRange(projectId,firstTime.getTime(),lastTime.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
public List<TaskInfoResult> findRunningTaskInfoByWorkspaceID(String workspaceID) {
|
||||
List<TaskInfoResult> runningTaskInfoList = extScheduleMapper.findRunningTaskInfoByWorkspaceID(workspaceID);
|
||||
public List<TaskInfoResult> findRunningTaskInfoByProjectID(String projectID) {
|
||||
List<TaskInfoResult> runningTaskInfoList = extScheduleMapper.findRunningTaskInfoByProjectID(projectID);
|
||||
return runningTaskInfoList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,11 @@ public class ReportComponentFactory {
|
|||
} else if (StringUtils.equals("2", componentId)) {
|
||||
return new ReportResultComponent(testPlan);
|
||||
} else if (StringUtils.equals("3", componentId)) {
|
||||
return new ReportResultChartComponent(testPlan);
|
||||
return new ReportResultAdvancedChartComponent(testPlan);
|
||||
// return new ReportResultChartComponent(testPlan);
|
||||
} else if (StringUtils.equals("4", componentId)) {
|
||||
return new ReportFailureResultComponent(testPlan);
|
||||
// return new ReportFailureResultComponent(testPlan);
|
||||
return new ReportFailureAdvanceResultComponent(testPlan);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import io.metersphere.commons.utils.PageUtils;
|
|||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import io.metersphere.excel.domain.ExcelResponse;
|
||||
import io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.service.FileService;
|
||||
import io.metersphere.track.dto.TestCaseDTO;
|
||||
import io.metersphere.track.request.testcase.EditTestCaseRequest;
|
||||
|
@ -39,7 +39,7 @@ public class TestCaseController {
|
|||
@Resource
|
||||
TestCaseService testCaseService;
|
||||
@Resource
|
||||
private CheckOwnerService checkOwnerService;
|
||||
private CheckPermissionService checkPermissionService;
|
||||
@Resource
|
||||
private FileService fileService;
|
||||
|
||||
|
@ -51,7 +51,7 @@ public class TestCaseController {
|
|||
|
||||
@GetMapping("/list/{projectId}")
|
||||
public List<TestCaseDTO> list(@PathVariable String projectId) {
|
||||
checkOwnerService.checkProjectOwner(projectId);
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
QueryTestCaseRequest request = new QueryTestCaseRequest();
|
||||
request.setProjectId(projectId);
|
||||
return testCaseService.listTestCase(request);
|
||||
|
@ -94,13 +94,13 @@ public class TestCaseController {
|
|||
|
||||
@GetMapping("/get/{testCaseId}")
|
||||
public TestCaseWithBLOBs getTestCase(@PathVariable String testCaseId) {
|
||||
checkOwnerService.checkTestCaseOwner(testCaseId);
|
||||
checkPermissionService.checkTestCaseOwner(testCaseId);
|
||||
return testCaseService.getTestCase(testCaseId);
|
||||
}
|
||||
|
||||
@GetMapping("/project/{testCaseId}")
|
||||
public Project getProjectByTestCaseId(@PathVariable String testCaseId) {
|
||||
checkOwnerService.checkTestCaseOwner(testCaseId);
|
||||
checkPermissionService.checkTestCaseOwner(testCaseId);
|
||||
return testCaseService.getProjectByTestCaseId(testCaseId);
|
||||
}
|
||||
|
||||
|
@ -119,14 +119,14 @@ public class TestCaseController {
|
|||
@PostMapping("/delete/{testCaseId}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public int deleteTestCase(@PathVariable String testCaseId) {
|
||||
checkOwnerService.checkTestCaseOwner(testCaseId);
|
||||
checkPermissionService.checkTestCaseOwner(testCaseId);
|
||||
return testCaseService.deleteTestCase(testCaseId);
|
||||
}
|
||||
|
||||
@PostMapping("/import/{projectId}/{userId}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public ExcelResponse testCaseImport(MultipartFile file, @PathVariable String projectId, @PathVariable String userId) {
|
||||
checkOwnerService.checkProjectOwner(projectId);
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return testCaseService.testCaseImport(file, projectId, userId);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package io.metersphere.track.controller;
|
|||
|
||||
import io.metersphere.base.domain.TestCaseNode;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.track.dto.TestCaseNodeDTO;
|
||||
import io.metersphere.track.request.testcase.DragNodeRequest;
|
||||
import io.metersphere.track.request.testcase.QueryNodeRequest;
|
||||
|
@ -22,11 +22,11 @@ public class TestCaseNodeController {
|
|||
@Resource
|
||||
TestCaseNodeService testCaseNodeService;
|
||||
@Resource
|
||||
private CheckOwnerService checkOwnerService;
|
||||
private CheckPermissionService checkPermissionService;
|
||||
|
||||
@GetMapping("/list/{projectId}")
|
||||
public List<TestCaseNodeDTO> getNodeByProjectId(@PathVariable String projectId) {
|
||||
checkOwnerService.checkProjectOwner(projectId);
|
||||
checkPermissionService.checkProjectOwner(projectId);
|
||||
return testCaseNodeService.getNodeTreeByProjectId(projectId);
|
||||
}
|
||||
|
||||
|
@ -43,13 +43,13 @@ public class TestCaseNodeController {
|
|||
|
||||
@GetMapping("/list/plan/{planId}")
|
||||
public List<TestCaseNodeDTO> getNodeByPlanId(@PathVariable String planId) {
|
||||
checkOwnerService.checkTestPlanOwner(planId);
|
||||
checkPermissionService.checkTestPlanOwner(planId);
|
||||
return testCaseNodeService.getNodeByPlanId(planId);
|
||||
}
|
||||
|
||||
@GetMapping("/list/review/{reviewId}")
|
||||
public List<TestCaseNodeDTO> getNodeByReviewId(@PathVariable String reviewId) {
|
||||
checkOwnerService.checkTestReviewOwner(reviewId);
|
||||
checkPermissionService.checkTestReviewOwner(reviewId);
|
||||
return testCaseNodeService.getNodeByReviewId(reviewId);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ 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 io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.track.dto.TestCaseReviewDTO;
|
||||
import io.metersphere.track.dto.TestReviewDTOWithMetric;
|
||||
import io.metersphere.track.request.testreview.QueryCaseReviewRequest;
|
||||
|
@ -35,7 +35,7 @@ public class TestCaseReviewController {
|
|||
@Resource
|
||||
TestReviewProjectService testReviewProjectService;
|
||||
@Resource
|
||||
CheckOwnerService checkOwnerService;
|
||||
CheckPermissionService checkPermissionService;
|
||||
|
||||
@PostMapping("/list/{goPage}/{pageSize}")
|
||||
public Pager<List<TestCaseReviewDTO>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryCaseReviewRequest request) {
|
||||
|
@ -75,7 +75,7 @@ public class TestCaseReviewController {
|
|||
@GetMapping("/delete/{reviewId}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public void deleteCaseReview(@PathVariable String reviewId) {
|
||||
checkOwnerService.checkTestReviewOwner(reviewId);
|
||||
checkPermissionService.checkTestReviewOwner(reviewId);
|
||||
testCaseReviewService.deleteCaseReview(reviewId);
|
||||
}
|
||||
|
||||
|
@ -107,14 +107,14 @@ public class TestCaseReviewController {
|
|||
|
||||
@GetMapping("/get/{reviewId}")
|
||||
public TestCaseReview getTestReview(@PathVariable String reviewId) {
|
||||
checkOwnerService.checkTestReviewOwner(reviewId);
|
||||
checkPermissionService.checkTestReviewOwner(reviewId);
|
||||
return testCaseReviewService.getTestReview(reviewId);
|
||||
}
|
||||
|
||||
@PostMapping("/edit/status/{reviewId}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public void editTestPlanStatus(@PathVariable String reviewId) {
|
||||
checkOwnerService.checkTestReviewOwner(reviewId);
|
||||
checkPermissionService.checkTestReviewOwner(reviewId);
|
||||
testCaseReviewService.editTestReviewStatus(reviewId);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ 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 io.metersphere.service.CheckOwnerService;
|
||||
import io.metersphere.service.CheckPermissionService;
|
||||
import io.metersphere.track.dto.TestCaseReportMetricDTO;
|
||||
import io.metersphere.track.dto.TestPlanDTO;
|
||||
import io.metersphere.track.dto.TestPlanDTOWithMetric;
|
||||
|
@ -34,7 +34,7 @@ public class TestPlanController {
|
|||
@Resource
|
||||
TestPlanProjectService testPlanProjectService;
|
||||
@Resource
|
||||
CheckOwnerService checkOwnerService;
|
||||
CheckPermissionService checkPermissionService;
|
||||
|
||||
@PostMapping("/list/{goPage}/{pageSize}")
|
||||
public Pager<List<TestPlanDTOWithMetric>> list(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryTestPlanRequest request) {
|
||||
|
@ -73,7 +73,7 @@ public class TestPlanController {
|
|||
|
||||
@PostMapping("/get/{testPlanId}")
|
||||
public TestPlan getTestPlan(@PathVariable String testPlanId) {
|
||||
checkOwnerService.checkTestPlanOwner(testPlanId);
|
||||
checkPermissionService.checkTestPlanOwner(testPlanId);
|
||||
return testPlanService.getTestPlan(testPlanId);
|
||||
}
|
||||
|
||||
|
@ -92,14 +92,14 @@ public class TestPlanController {
|
|||
@PostMapping("/edit/status/{planId}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public void editTestPlanStatus(@PathVariable String planId) {
|
||||
checkOwnerService.checkTestPlanOwner(planId);
|
||||
checkPermissionService.checkTestPlanOwner(planId);
|
||||
testPlanService.editTestPlanStatus(planId);
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{testPlanId}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_USER, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public int deleteTestPlan(@PathVariable String testPlanId) {
|
||||
checkOwnerService.checkTestPlanOwner(testPlanId);
|
||||
checkPermissionService.checkTestPlanOwner(testPlanId);
|
||||
return testPlanService.deleteTestPlan(testPlanId);
|
||||
}
|
||||
|
||||
|
@ -113,6 +113,11 @@ public class TestPlanController {
|
|||
return testPlanService.getMetric(planId);
|
||||
}
|
||||
|
||||
@GetMapping("/get/statistics/metric/{planId}")
|
||||
public TestCaseReportMetricDTO getStatisticsMetric(@PathVariable String planId) {
|
||||
return testPlanService.getStatisticsMetric(planId);
|
||||
}
|
||||
|
||||
@GetMapping("/project/name/{planId}")
|
||||
public String getProjectNameByPlanId(@PathVariable String planId) {
|
||||
return testPlanService.getProjectNameByPlanId(planId);
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package io.metersphere.track.domain;
|
||||
|
||||
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||
import io.metersphere.commons.constants.APITestStatus;
|
||||
import io.metersphere.track.dto.TestCaseReportMetricDTO;
|
||||
import io.metersphere.track.dto.TestPlanCaseDTO;
|
||||
import io.metersphere.track.dto.TestPlanDTO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public abstract class ReportComponent {
|
||||
protected String componentId;
|
||||
|
@ -15,4 +19,11 @@ public abstract class ReportComponent {
|
|||
public abstract void readRecord(TestPlanCaseDTO testCase);
|
||||
|
||||
public abstract void afterBuild(TestCaseReportMetricDTO testCaseReportMetric);
|
||||
|
||||
public void readRecord(TestPlanApiCaseDTO testCase) {
|
||||
}
|
||||
|
||||
public void readRecord(ApiScenarioDTO testCase) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package io.metersphere.track.domain;
|
||||
|
||||
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||
import io.metersphere.api.dto.automation.ScenarioStatus;
|
||||
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
|
||||
import io.metersphere.track.dto.FailureTestCasesAdvanceDTO;
|
||||
import io.metersphere.track.dto.TestCaseReportMetricDTO;
|
||||
import io.metersphere.track.dto.TestPlanCaseDTO;
|
||||
import io.metersphere.track.dto.TestPlanDTO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ReportFailureAdvanceResultComponent extends ReportComponent {
|
||||
private List<TestPlanCaseDTO> functionalTestCases = new ArrayList<>();
|
||||
private List<TestPlanApiCaseDTO> apiTestCases = new ArrayList<>();
|
||||
private List<ApiScenarioDTO> scenarioTestCases = new ArrayList<>();
|
||||
|
||||
public ReportFailureAdvanceResultComponent(TestPlanDTO testPlan) {
|
||||
super(testPlan);
|
||||
componentId = "4";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readRecord(TestPlanCaseDTO testCase) {
|
||||
if (StringUtils.equals(testCase.getStatus(), TestPlanTestCaseStatus.Failure.name())) {
|
||||
this.functionalTestCases.add(testCase);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readRecord(TestPlanApiCaseDTO testCase) {
|
||||
if (StringUtils.equals(testCase.getExecResult(), "error")) {
|
||||
this.apiTestCases.add(testCase);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readRecord(ApiScenarioDTO testCase) {
|
||||
if (StringUtils.equals(testCase.getLastResult(), ScenarioStatus.Fail.name())) {
|
||||
this.scenarioTestCases.add(testCase);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
||||
FailureTestCasesAdvanceDTO failureTestCasesAdvanceDTO = new FailureTestCasesAdvanceDTO();
|
||||
failureTestCasesAdvanceDTO.setFunctionalTestCases(functionalTestCases);
|
||||
failureTestCasesAdvanceDTO.setApiTestCases(apiTestCases);
|
||||
failureTestCasesAdvanceDTO.setScenarioTestCases(scenarioTestCases);
|
||||
testCaseReportMetric.setFailureTestCases(failureTestCasesAdvanceDTO);
|
||||
}
|
||||
}
|
|
@ -26,6 +26,6 @@ public class ReportFailureResultComponent extends ReportComponent {
|
|||
|
||||
@Override
|
||||
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
||||
testCaseReportMetric.setFailureTestCases(failureTestCases);
|
||||
// testCaseReportMetric.setFailureTestCases(failureTestCases);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
package io.metersphere.track.domain;
|
||||
|
||||
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||
import io.metersphere.api.dto.automation.ScenarioStatus;
|
||||
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
|
||||
import io.metersphere.track.dto.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ReportResultAdvancedChartComponent extends ReportComponent {
|
||||
Map<String, TestCaseReportStatusResultDTO> functionalStatusResultMap = new HashMap<>();
|
||||
Map<String, TestCaseReportStatusResultDTO> apiStatusResultMap = new HashMap<>();
|
||||
Map<String, TestCaseReportStatusResultDTO> scenarioStatusResultMap = new HashMap<>();
|
||||
|
||||
private static Map<String, String> apiResultMap = new HashMap<>();
|
||||
private static Map<String, String> scenarioResultMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
apiResultMap.put("success", TestPlanTestCaseStatus.Pass.name());
|
||||
apiResultMap.put("error", TestPlanTestCaseStatus.Failure.name());
|
||||
scenarioResultMap.put(ScenarioStatus.Success.name(), TestPlanTestCaseStatus.Pass.name());
|
||||
scenarioResultMap.put(ScenarioStatus.Fail.name(), TestPlanTestCaseStatus.Failure.name());
|
||||
}
|
||||
|
||||
public ReportResultAdvancedChartComponent(TestPlanDTO testPlan) {
|
||||
super(testPlan);
|
||||
componentId = "3";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readRecord(TestPlanCaseDTO testCase) {
|
||||
getStatusResultMap(functionalStatusResultMap, testCase.getStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readRecord(TestPlanApiCaseDTO testCase) {
|
||||
getStatusResultMap(apiStatusResultMap, apiResultMap.get(testCase.getExecResult()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readRecord(ApiScenarioDTO testCase) {
|
||||
getStatusResultMap(scenarioStatusResultMap, scenarioResultMap.get(testCase.getLastResult()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
||||
testCaseReportMetric.setExecuteResult(getReportStatusResult());
|
||||
}
|
||||
|
||||
private TestCaseReportAdvanceStatusResultDTO getReportStatusResult() {
|
||||
TestCaseReportAdvanceStatusResultDTO reportStatusResult = new TestCaseReportAdvanceStatusResultDTO();
|
||||
buildFunctionalStatusResult(reportStatusResult);
|
||||
buildApiStatusResult(reportStatusResult);
|
||||
buildScenarioStatusResult(reportStatusResult);
|
||||
return reportStatusResult;
|
||||
}
|
||||
|
||||
private void buildFunctionalStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) {
|
||||
List<TestCaseReportStatusResultDTO> functionalStatusResult = new ArrayList<>();
|
||||
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Pass.name());
|
||||
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Failure.name());
|
||||
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Blocking.name());
|
||||
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Skip.name());
|
||||
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Underway.name());
|
||||
addToReportStatusResultList(functionalStatusResultMap, functionalStatusResult, TestPlanTestCaseStatus.Prepare.name());
|
||||
reportStatusResult.setFunctionalResult(functionalStatusResult);
|
||||
}
|
||||
|
||||
private void buildApiStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) {
|
||||
List<TestCaseReportStatusResultDTO> apiStatusResult = new ArrayList<>();
|
||||
addToReportStatusResultList(apiStatusResultMap, apiStatusResult, TestPlanTestCaseStatus.Pass.name());
|
||||
addToReportStatusResultList(apiStatusResultMap, apiStatusResult, TestPlanTestCaseStatus.Failure.name());
|
||||
addToReportStatusResultList(apiStatusResultMap, apiStatusResult, TestPlanTestCaseStatus.Underway.name());
|
||||
reportStatusResult.setApiResult(apiStatusResult);
|
||||
}
|
||||
|
||||
private void buildScenarioStatusResult(TestCaseReportAdvanceStatusResultDTO reportStatusResult) {
|
||||
List<TestCaseReportStatusResultDTO> scenarioStatusResult = new ArrayList<>();
|
||||
addToReportStatusResultList(scenarioStatusResultMap, scenarioStatusResult, TestPlanTestCaseStatus.Pass.name());
|
||||
addToReportStatusResultList(scenarioStatusResultMap, scenarioStatusResult, TestPlanTestCaseStatus.Failure.name());
|
||||
addToReportStatusResultList(scenarioStatusResultMap, scenarioStatusResult, TestPlanTestCaseStatus.Underway.name());
|
||||
reportStatusResult.setScenarioResult(scenarioStatusResult);
|
||||
}
|
||||
|
||||
private void addToReportStatusResultList(Map<String, TestCaseReportStatusResultDTO> resultMap, List<TestCaseReportStatusResultDTO> reportStatusResultList, String status) {
|
||||
if (resultMap.get(status) != null) {
|
||||
reportStatusResultList.add(resultMap.get(status));
|
||||
}
|
||||
}
|
||||
|
||||
private void getStatusResultMap(Map<String, TestCaseReportStatusResultDTO> reportStatusResultMap, String result) {
|
||||
if (StringUtils.isBlank(result)) {
|
||||
result = TestPlanTestCaseStatus.Underway.name();
|
||||
}
|
||||
TestCaseReportStatusResultDTO statusResult = reportStatusResultMap.get(result);
|
||||
if (statusResult == null) {
|
||||
statusResult = new TestCaseReportStatusResultDTO();
|
||||
statusResult.setStatus(result);
|
||||
statusResult.setCount(0);
|
||||
}
|
||||
statusResult.setCount(statusResult.getCount() + 1);
|
||||
reportStatusResultMap.put(result, statusResult);
|
||||
}
|
||||
}
|
|
@ -27,7 +27,7 @@ public class ReportResultChartComponent extends ReportComponent {
|
|||
|
||||
@Override
|
||||
public void afterBuild(TestCaseReportMetricDTO testCaseReportMetric) {
|
||||
testCaseReportMetric.setExecuteResult(getReportStatusResult());
|
||||
// testCaseReportMetric.setExecuteResult(getReportStatusResult());
|
||||
}
|
||||
|
||||
private List<TestCaseReportStatusResultDTO> getReportStatusResult() {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.track.dto;
|
||||
|
||||
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FailureTestCasesAdvanceDTO {
|
||||
private List<TestPlanCaseDTO> functionalTestCases;
|
||||
private List<TestPlanApiCaseDTO> apiTestCases;
|
||||
private List<ApiScenarioDTO> scenarioTestCases;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package io.metersphere.track.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TestCaseReportAdvanceStatusResultDTO {
|
||||
private List<TestCaseReportStatusResultDTO> functionalResult;
|
||||
private List<TestCaseReportStatusResultDTO> apiResult;
|
||||
private List<TestCaseReportStatusResultDTO> scenarioResult;
|
||||
}
|
||||
|
|
@ -10,9 +10,11 @@ import java.util.List;
|
|||
@Setter
|
||||
public class TestCaseReportMetricDTO {
|
||||
|
||||
private List<TestCaseReportStatusResultDTO> executeResult;
|
||||
// private List<TestCaseReportStatusResultDTO> executeResult;
|
||||
private TestCaseReportAdvanceStatusResultDTO executeResult;
|
||||
private List<TestCaseReportModuleResultDTO> moduleExecuteResult;
|
||||
private List<TestPlanCaseDTO> failureTestCases;
|
||||
private FailureTestCasesAdvanceDTO failureTestCases;
|
||||
// private List<TestPlanCaseDTO> failureTestCases;
|
||||
private List<Issues> Issues;
|
||||
private List<String> executors;
|
||||
private String principal;
|
||||
|
|
|
@ -3,6 +3,10 @@ package io.metersphere.track.service;
|
|||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.metersphere.api.dto.automation.ApiScenarioDTO;
|
||||
import io.metersphere.api.dto.automation.TestPlanScenarioRequest;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseRequest;
|
||||
import io.metersphere.api.dto.definition.TestPlanApiCaseDTO;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtProjectMapper;
|
||||
|
@ -22,6 +26,7 @@ import io.metersphere.notice.service.NoticeSendService;
|
|||
import io.metersphere.service.SystemParameterService;
|
||||
import io.metersphere.track.Factory.ReportComponentFactory;
|
||||
import io.metersphere.track.domain.ReportComponent;
|
||||
|
||||
import io.metersphere.track.dto.TestCaseReportMetricDTO;
|
||||
import io.metersphere.track.dto.TestPlanCaseDTO;
|
||||
import io.metersphere.track.dto.TestPlanDTO;
|
||||
|
@ -80,6 +85,10 @@ public class TestPlanService {
|
|||
private NoticeSendService noticeSendService;
|
||||
@Resource
|
||||
private SystemParameterService systemParameterService;
|
||||
@Resource
|
||||
private TestPlanApiCaseService testPlanApiCaseService;
|
||||
@Resource
|
||||
private TestPlanScenarioCaseService testPlanScenarioCaseService;
|
||||
|
||||
public synchronized void addTestPlan(AddTestPlanRequest testPlan) {
|
||||
if (getTestPlanByName(testPlan.getName()).size() > 0) {
|
||||
|
@ -459,7 +468,6 @@ public class TestPlanService {
|
|||
}
|
||||
|
||||
public TestCaseReportMetricDTO getMetric(String planId) {
|
||||
IssuesService issuesService = (IssuesService) CommonBeanFactory.getBean("issuesService");
|
||||
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
|
||||
queryTestPlanRequest.setId(planId);
|
||||
|
||||
|
@ -472,31 +480,8 @@ public class TestPlanService {
|
|||
JSONArray componentIds = content.getJSONArray("components");
|
||||
|
||||
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
|
||||
List<Issues> issues = buildFunctionalCaseReport(planId, components);
|
||||
|
||||
List<TestPlanCaseDTO> testPlanTestCases = listTestCaseByPlanId(planId);
|
||||
List<Issues> issues = new ArrayList<>();
|
||||
for (TestPlanCaseDTO testCase : testPlanTestCases) {
|
||||
List<Issues> issue = issuesService.getIssues(testCase.getCaseId());
|
||||
if (issue.size() > 0) {
|
||||
for (Issues i : issue) {
|
||||
i.setModel(testCase.getNodePath());
|
||||
i.setProjectName(testCase.getProjectName());
|
||||
String des = i.getDescription().replaceAll("<p>", "").replaceAll("</p>", "");
|
||||
i.setDescription(des);
|
||||
if (i.getLastmodify() == null || i.getLastmodify() == "") {
|
||||
if (i.getReporter() != null || i.getReporter() != "") {
|
||||
i.setLastmodify(i.getReporter());
|
||||
}
|
||||
}
|
||||
}
|
||||
issues.addAll(issue);
|
||||
Collections.sort(issues, Comparator.comparing(Issues::getCreateTime, (t1, t2) -> t2.compareTo(t1)));
|
||||
}
|
||||
|
||||
components.forEach(component -> {
|
||||
component.readRecord(testCase);
|
||||
});
|
||||
}
|
||||
TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
|
||||
components.forEach(component -> {
|
||||
component.afterBuild(testCaseReportMetricDTO);
|
||||
|
@ -609,4 +594,78 @@ public class TestPlanService {
|
|||
return context;
|
||||
}
|
||||
|
||||
public TestCaseReportMetricDTO getStatisticsMetric(String planId) {
|
||||
QueryTestPlanRequest queryTestPlanRequest = new QueryTestPlanRequest();
|
||||
queryTestPlanRequest.setId(planId);
|
||||
|
||||
TestPlanDTO testPlan = extTestPlanMapper.list(queryTestPlanRequest).get(0);
|
||||
String projectName = getProjectNameByPlanId(planId);
|
||||
testPlan.setProjectName(projectName);
|
||||
|
||||
TestCaseReport testCaseReport = testCaseReportMapper.selectByPrimaryKey(testPlan.getReportId());
|
||||
JSONObject content = JSONObject.parseObject(testCaseReport.getContent());
|
||||
JSONArray componentIds = content.getJSONArray("components");
|
||||
|
||||
List<ReportComponent> components = ReportComponentFactory.createComponents(componentIds.toJavaList(String.class), testPlan);
|
||||
List<Issues> issues = buildFunctionalCaseReport(planId, components);
|
||||
buildApiCaseReport(planId, components);
|
||||
buildScenarioCaseReport(planId, components);
|
||||
|
||||
TestCaseReportMetricDTO testCaseReportMetricDTO = new TestCaseReportMetricDTO();
|
||||
components.forEach(component -> {
|
||||
component.afterBuild(testCaseReportMetricDTO);
|
||||
});
|
||||
testCaseReportMetricDTO.setIssues(issues);
|
||||
return testCaseReportMetricDTO;
|
||||
}
|
||||
|
||||
public void buildApiCaseReport(String planId, List<ReportComponent> components) {
|
||||
ApiTestCaseRequest request = new ApiTestCaseRequest();
|
||||
request.setPlanId(planId);
|
||||
List<TestPlanApiCaseDTO> apiCaseDTOS = testPlanApiCaseService.list(request);
|
||||
for (TestPlanApiCaseDTO item : apiCaseDTOS) {
|
||||
for (ReportComponent component : components) {
|
||||
component.readRecord(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void buildScenarioCaseReport(String planId, List<ReportComponent> components) {
|
||||
TestPlanScenarioRequest request = new TestPlanScenarioRequest();
|
||||
request.setPlanId(planId);
|
||||
List<ApiScenarioDTO> scenarioDTOS = testPlanScenarioCaseService.list(request);
|
||||
for (ApiScenarioDTO item : scenarioDTOS) {
|
||||
for (ReportComponent component : components) {
|
||||
component.readRecord(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Issues> buildFunctionalCaseReport(String planId, List<ReportComponent> components) {
|
||||
IssuesService issuesService = (IssuesService) CommonBeanFactory.getBean("issuesService");
|
||||
List<TestPlanCaseDTO> testPlanTestCases = listTestCaseByPlanId(planId);
|
||||
List<Issues> issues = new ArrayList<>();
|
||||
for (TestPlanCaseDTO testCase : testPlanTestCases) {
|
||||
List<Issues> issue = issuesService.getIssues(testCase.getCaseId());
|
||||
if (issue.size() > 0) {
|
||||
for (Issues i : issue) {
|
||||
i.setModel(testCase.getNodePath());
|
||||
i.setProjectName(testCase.getProjectName());
|
||||
String des = i.getDescription().replaceAll("<p>", "").replaceAll("</p>", "");
|
||||
i.setDescription(des);
|
||||
if (i.getLastmodify() == null || i.getLastmodify() == "") {
|
||||
if (i.getReporter() != null || i.getReporter() != "") {
|
||||
i.setLastmodify(i.getReporter());
|
||||
}
|
||||
}
|
||||
}
|
||||
issues.addAll(issue);
|
||||
Collections.sort(issues, Comparator.comparing(Issues::getCreateTime, (t1, t2) -> t2.compareTo(t1)));
|
||||
}
|
||||
components.forEach(component -> {
|
||||
component.readRecord(testCase);
|
||||
});
|
||||
}
|
||||
return issues;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,6 +164,7 @@ check_owner_case=The current user does not have permission to operate this use c
|
|||
check_owner_plan=The current user does not have permission to operate this plan
|
||||
check_owner_review=The current user does not have permission to operate this review
|
||||
check_owner_comment=The current user does not have permission to manipulate this comment
|
||||
check_owner_read_only=The current user in this workspace is a read-only user
|
||||
upload_content_is_null=Imported content is empty
|
||||
test_plan_notification=Test plan notification
|
||||
task_defect_notification=Task defect notification
|
||||
|
|
|
@ -165,6 +165,7 @@ check_owner_case=当前用户没有操作此用例的权限
|
|||
check_owner_plan=当前用户没有操作此计划的权限
|
||||
check_owner_review=当前用户没有操作此评审的权限
|
||||
check_owner_comment=当前用户没有操作此评论的权限
|
||||
check_owner_read_only=当前用户在此工作空间为只读用户
|
||||
upload_content_is_null=导入内容为空
|
||||
test_plan_notification=测试计划通知
|
||||
task_defect_notification=缺陷任务通知
|
||||
|
|
|
@ -166,6 +166,7 @@ check_owner_case=當前用戶沒有操作此用例的權限
|
|||
check_owner_plan=當前用戶沒有操作此計劃的權限
|
||||
check_owner_review=當前用戶沒有操作此評審的權限
|
||||
check_owner_comment=當前用戶沒有操作此評論的權限
|
||||
check_owner_read_only=當前用戶在此工作空間為只讀用戶
|
||||
upload_content_is_null=導入內容為空
|
||||
test_plan_notification=測試計畫通知
|
||||
task_defect_notification=缺陷任務通知
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
import MsContainer from "../../../common/components/MsContainer";
|
||||
import MsMainContainer from "../../../common/components/MsMainContainer";
|
||||
import MsApiReportStatus from "./ApiReportStatus";
|
||||
import {_filter, _sort} from "@/common/js/utils";
|
||||
import {_filter, _sort,getCurrentProjectID} from "@/common/js/utils";
|
||||
import MsTableOperatorButton from "../../../common/components/MsTableOperatorButton";
|
||||
import ReportTriggerModeItem from "../../../common/tableItem/ReportTriggerModeItem";
|
||||
import {REPORT_CONFIGS} from "../../../common/components/search/search-components";
|
||||
|
@ -130,6 +130,7 @@
|
|||
if (this.testId !== 'all') {
|
||||
this.condition.testId = this.testId;
|
||||
}
|
||||
this.condition.projectId = getCurrentProjectID();
|
||||
let url = "/api/scenario/report/list/" + this.currentPage + "/" + this.pageSize;
|
||||
this.result = this.$post(url, this.condition, response => {
|
||||
let data = response.data;
|
||||
|
|
|
@ -19,19 +19,14 @@
|
|||
<el-tabs v-model="activeName" v-show="isActive" v-if="hasSub">
|
||||
<el-tab-pane :label="$t('api_report.sub_result')" name="sub">
|
||||
<ms-request-sub-result class="sub-result" v-for="(sub, index) in request.subRequestResults"
|
||||
:key="index" :request="sub"/>
|
||||
:key="index" :indexNumber="index" :request="sub"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_report.request_result')" name="result">
|
||||
<ms-request-metric :request="request"/>
|
||||
<ms-request-text :request="request"/>
|
||||
<br>
|
||||
<ms-response-text :request-type="requestType" :response="request.responseResult"/>
|
||||
<ms-response-text :request-type="requestType" :response="request.responseResult" :request="request"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div v-else>
|
||||
<ms-request-text v-if="isCodeEditAlive" :request="request"/>
|
||||
<br>
|
||||
<ms-response-text :request-type="requestType" v-if="isCodeEditAlive" :response="request.responseResult"/>
|
||||
<ms-response-text :request-type="requestType" v-if="isCodeEditAlive" :response="request.responseResult" :request="request"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<p class="el-divider--horizontal"></p>
|
||||
<div @click="active">
|
||||
<el-row :gutter="10" type="flex" align="middle" class="info">
|
||||
<el-col :span="14" v-if="indexNumber!=undefined">
|
||||
<el-col :span="6" v-if="indexNumber!=undefined">
|
||||
<div class="method">
|
||||
<div class="el-step__icon is-text ms-api-col" v-if="indexNumber%2 ==0">
|
||||
<div class="el-step__icon-inner"> {{ indexNumber+1 }}</div>
|
||||
|
@ -14,7 +14,16 @@
|
|||
{{ request.name }}
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="2">
|
||||
<div>
|
||||
{{ request.method }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="url">
|
||||
{{ request.url }}
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-tooltip effect="dark" :content="request.responseResult.responseCode" placement="bottom" :open-delay="800">
|
||||
<div class="url" style="color: #5daf34">{{ request.responseResult.responseCode }}</div>
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
<template>
|
||||
<div class="text-container">
|
||||
<div @click="active" class="collapse">
|
||||
<i class="icon el-icon-arrow-right" :class="{'is-active': isActive}"/>
|
||||
{{ $t('api_report.response') }}
|
||||
</div>
|
||||
<el-collapse-transition>
|
||||
<el-tabs v-model="activeName" v-show="isActive">
|
||||
<el-tab-pane :class="'body-pane'" label="Body" name="body" class="pane">
|
||||
<el-tab-pane :label="$t('api_test.definition.request.response_header')" name="headers" class="pane">
|
||||
<pre>{{ response.headers }}</pre>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :class="'body-pane'" :label="$t('api_test.definition.request.response_body')" name="body" class="pane">
|
||||
<ms-sql-result-table v-if="isSqlType" :body="response.body"/>
|
||||
<ms-code-edit v-if="!isSqlType" :mode="mode" :read-only="true" :data="response.body" :modes="modes" ref="codeEdit"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="Headers" name="headers" class="pane">
|
||||
<pre>{{ response.headers }}</pre>
|
||||
<el-tab-pane :label="$t('api_test.definition.request.console')" name="console" class="pane">
|
||||
<pre>{{response.console}}</pre>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('api_report.assertions')" name="assertions" class="pane assertions">
|
||||
<ms-assertion-results :assertions="response.assertions"/>
|
||||
</el-tab-pane>
|
||||
|
@ -21,79 +22,97 @@
|
|||
<pre>{{response.vars}}</pre>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane :label="$t('api_report.request_body')" name="request_body" class="pane">
|
||||
<div class="ms-div">
|
||||
{{$t('api_test.request.address')}} :
|
||||
<pre>{{ request.url }}</pre>
|
||||
</div>
|
||||
<div class="ms-div">
|
||||
{{$t('api_test.scenario.headers')}} :
|
||||
<pre>{{ request.headers }}</pre>
|
||||
</div>
|
||||
<div class="ms-div">
|
||||
Cookies :
|
||||
<pre>{{request.cookies}}</pre>
|
||||
</div>
|
||||
<div class="ms-div">
|
||||
Body :
|
||||
<pre>{{request.body}}</pre>
|
||||
</div>
|
||||
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane v-if="activeName == 'body'" :disabled="true" name="mode" class="pane assertions">
|
||||
<template v-slot:label>
|
||||
<ms-dropdown v-if="!isSqlType" :commands="modes" :default-command="mode" @command="modeChange"/>
|
||||
<ms-dropdown v-if="isSqlType" :commands="sqlModes" :default-command="mode" @command="sqlModeChange"/>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_test.definition.request.console')" name="console" class="pane">
|
||||
<pre>{{response.console}}</pre>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-collapse-transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsAssertionResults from "./AssertionResults";
|
||||
import MsCodeEdit from "../../../../common/components/MsCodeEdit";
|
||||
import MsDropdown from "../../../../common/components/MsDropdown";
|
||||
import {BODY_FORMAT, RequestFactory, Request, SqlRequest} from "../../../definition/model/ApiTestModel";
|
||||
import MsSqlResultTable from "./SqlResultTable";
|
||||
import MsAssertionResults from "./AssertionResults";
|
||||
import MsCodeEdit from "../../../../common/components/MsCodeEdit";
|
||||
import MsDropdown from "../../../../common/components/MsDropdown";
|
||||
import {BODY_FORMAT, RequestFactory, Request, SqlRequest} from "../../../definition/model/ApiTestModel";
|
||||
import MsSqlResultTable from "./SqlResultTable";
|
||||
|
||||
export default {
|
||||
name: "MsResponseText",
|
||||
export default {
|
||||
name: "MsResponseText",
|
||||
|
||||
components: {
|
||||
MsSqlResultTable,
|
||||
MsDropdown,
|
||||
MsCodeEdit,
|
||||
MsAssertionResults,
|
||||
},
|
||||
|
||||
props: {
|
||||
requestType: String,
|
||||
response: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isActive: true,
|
||||
activeName: "body",
|
||||
modes: ['text', 'json', 'xml', 'html'],
|
||||
sqlModes: ['text', 'table'],
|
||||
mode: BODY_FORMAT.TEXT
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
active() {
|
||||
this.isActive = !this.isActive;
|
||||
components: {
|
||||
MsSqlResultTable,
|
||||
MsDropdown,
|
||||
MsCodeEdit,
|
||||
MsAssertionResults,
|
||||
},
|
||||
modeChange(mode) {
|
||||
this.mode = mode;
|
||||
|
||||
props: {
|
||||
requestType: String,
|
||||
request: {},
|
||||
response: Object
|
||||
},
|
||||
sqlModeChange(mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (!this.response.headers) {
|
||||
return;
|
||||
}
|
||||
if (this.response.headers.indexOf("Content-Type: application/json") > 0) {
|
||||
this.mode = BODY_FORMAT.JSON;
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isActive: true,
|
||||
activeName: "body",
|
||||
modes: ['text', 'json', 'xml', 'html'],
|
||||
sqlModes: ['text', 'table'],
|
||||
mode: BODY_FORMAT.TEXT
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isSqlType() {
|
||||
return (this.requestType === RequestFactory.TYPES.SQL && this.response.responseCode === '200');
|
||||
methods: {
|
||||
active() {
|
||||
this.isActive = !this.isActive;
|
||||
},
|
||||
modeChange(mode) {
|
||||
this.mode = mode;
|
||||
},
|
||||
sqlModeChange(mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (!this.response.headers) {
|
||||
return;
|
||||
}
|
||||
if (this.response.headers.indexOf("Content-Type: application/json") > 0) {
|
||||
this.mode = BODY_FORMAT.JSON;
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
isSqlType() {
|
||||
return (this.requestType === RequestFactory.TYPES.SQL && this.response.responseCode === '200');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -134,4 +153,7 @@ export default {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.ms-div {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-dialog :close-on-click-modal="false" :title="$t('api_test.definition.request.title')" :visible.sync="visible"
|
||||
<el-dialog :close-on-click-modal="false" :title="$t('api_test.automation.add_scenario')" :visible.sync="visible"
|
||||
width="45%"
|
||||
:destroy-on-close="true">
|
||||
<el-form :model="scenarioForm" label-position="right" label-width="80px" size="small" :rules="rule"
|
||||
|
|
|
@ -5,15 +5,22 @@
|
|||
<div class="el-step__icon is-text ms-api-col" v-if="request.referenced!=undefined && request.referenced==='Deleted' || request.referenced=='REF' || request.referenced==='Copy'">
|
||||
<div class="el-step__icon-inner">{{request.index}}</div>
|
||||
</div>
|
||||
<div class="el-step__icon is-text ms-api-col-ot-import" v-else-if="request.referenced!=undefined && request.referenced==='OT_IMPORT'">
|
||||
<div class="el-step__icon-inner">{{request.index}}</div>
|
||||
</div>
|
||||
<div class="el-step__icon is-text ms-api-col-create" v-else>
|
||||
<div class="el-step__icon-inner">{{request.index}}</div>
|
||||
</div>
|
||||
|
||||
<el-button v-if="request.referenced!=undefined && request.referenced==='Deleted' || request.referenced=='REF' || request.referenced==='Copy'" class="ms-left-buttion" size="small">
|
||||
<el-button v-if="request.referenced!=undefined && request.referenced==='Deleted' || request.referenced=='REF' || request.referenced==='Copy'" class="ms-left-button" size="small">
|
||||
{{$t('api_test.automation.api_list_import')}}
|
||||
</el-button>
|
||||
|
||||
<el-button v-if="request.referenced==undefined || request.referenced==='Created' " class="ms-create-buttion" size="small">
|
||||
<el-button v-if="request.referenced!=undefined && request.referenced==='OT_IMPORT'" class="ms-api-col-ot-import-button" size="small">
|
||||
{{$t('api_test.automation.external_import')}}
|
||||
</el-button>
|
||||
|
||||
<el-button v-if="request.referenced==undefined || request.referenced==='Created' " class="ms-create-button" size="small">
|
||||
{{$t('api_test.automation.customize_req')}}
|
||||
</el-button>
|
||||
|
||||
|
@ -37,7 +44,12 @@
|
|||
<el-collapse-transition>
|
||||
<div v-if="request.active">
|
||||
<div v-if="request.protocol === 'HTTP'">
|
||||
<el-input :placeholder="$t('api_test.definition.request.path_all_info')" v-model="request.url" style="width: 85%;margin-top: 10px" size="small">
|
||||
<el-input :placeholder="$t('api_test.definition.request.path_all_info')" v-if="request.url" v-model="request.url" style="width: 85%;margin-top: 10px" size="small">
|
||||
<el-select v-model="request.method" slot="prepend" style="width: 100px" size="small">
|
||||
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-input>
|
||||
<el-input :placeholder="$t('api_test.definition.request.path_all_info')" v-else v-model="request.path" style="width: 85%;margin-top: 10px" size="small">
|
||||
<el-select v-model="request.method" slot="prepend" style="width: 100px" size="small">
|
||||
<el-option v-for="item in reqOptions" :key="item.id" :label="item.label" :value="item.id"/>
|
||||
</el-select>
|
||||
|
@ -96,20 +108,10 @@
|
|||
try {
|
||||
let urlObject = new URL(this.request.url);
|
||||
let url = urlObject.protocol + "//" + urlObject.host + "/";
|
||||
if (url) {
|
||||
let path = this.request.url.substr(url.length);
|
||||
if (!path.startsWith('/')) {
|
||||
path = "/" + path;
|
||||
}
|
||||
this.request.path = path;
|
||||
} else {
|
||||
this.request.url = this.request.path;
|
||||
}
|
||||
} catch (e) {
|
||||
if (this.request.url) {
|
||||
this.request.path = this.request.url;
|
||||
} else {
|
||||
this.request.url = this.request.path;
|
||||
this.request.url = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +203,7 @@
|
|||
color: #F56C6C;
|
||||
}
|
||||
|
||||
.ms-left-buttion {
|
||||
.ms-left-button {
|
||||
color: #F56C6C;
|
||||
background-color: #FCF1F1;
|
||||
margin-right: 20px;
|
||||
|
@ -214,6 +216,19 @@
|
|||
color: #008080;
|
||||
}
|
||||
|
||||
.ms-api-col-ot-import {
|
||||
background-color: #EEF5FE;
|
||||
border-color: #409EFF;
|
||||
margin-right: 10px;
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
.ms-api-col-ot-import-button {
|
||||
background-color: #EEF5FE;
|
||||
margin-right: 20px;
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
/deep/ .el-card__body {
|
||||
padding: 15px;
|
||||
}
|
||||
|
@ -222,7 +237,7 @@
|
|||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.ms-create-buttion {
|
||||
.ms-create-button {
|
||||
color: #008080;
|
||||
background-color: #EBF2F2;
|
||||
margin-right: 20px;
|
||||
|
|
|
@ -226,6 +226,7 @@
|
|||
},
|
||||
reductionApi(row) {
|
||||
row.scenarioDefinition = null;
|
||||
row.tags = null;
|
||||
let rows = [row];
|
||||
this.$post("/api/automation/reduction", rows, response => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
|
|
|
@ -201,7 +201,7 @@
|
|||
</div>
|
||||
|
||||
<!--接口列表-->
|
||||
<el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="true" :modal="false" size="90%">
|
||||
<el-drawer :visible.sync="apiListVisible" :destroy-on-close="true" direction="ltr" :withHeader="false" :modal="false" size="90%">
|
||||
<ms-api-definition :visible="visibleRef" :currentRow="currentRow"/>
|
||||
<el-button style="float: right;margin: 0px 20px 0px" type="primary" @click="pushApiOrCase('REF')">{{$t('api_test.scenario.reference')}}</el-button>
|
||||
<el-button style="float: right;" type="primary" @click="pushApiOrCase('Copy')">{{ $t('commons.copy') }}</el-button>
|
||||
|
@ -876,7 +876,7 @@
|
|||
apiImport(importData) {
|
||||
if (importData && importData.data) {
|
||||
importData.data.forEach(item => {
|
||||
this.setApiParameter(item, "API", "Copy");
|
||||
this.setApiParameter(item, "API", "OT_IMPORT");
|
||||
})
|
||||
this.sort();
|
||||
this.reload();
|
||||
|
@ -933,7 +933,7 @@
|
|||
}
|
||||
|
||||
.ms-col-one {
|
||||
margin-top: 6px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#fab {
|
||||
|
@ -986,8 +986,4 @@
|
|||
font-size: 13px;
|
||||
}
|
||||
|
||||
/deep/ .el-form-item__content {
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -4,21 +4,24 @@
|
|||
<el-header style="width: 100% ;padding: 0px">
|
||||
<el-card>
|
||||
<el-row>
|
||||
<el-col :span="api.protocol==='HTTP'? 3:5">
|
||||
<el-col :span="2" class="ms-api-col">
|
||||
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="api.protocol==='HTTP'? 3:6" class="ms-api-col">
|
||||
<div class="variable-combine"> {{api.name}}</div>
|
||||
</el-col>
|
||||
<el-col :span="api.protocol==='HTTP'? 1:3">
|
||||
<el-col :span="api.protocol==='HTTP'? 1:3" class="ms-api-col">
|
||||
<el-tag size="mini" :style="{'background-color': getColor(true, api.method), border: getColor(true, api.method)}" class="api-el-tag">
|
||||
{{ api.method}}
|
||||
</el-tag>
|
||||
</el-col>
|
||||
<el-col :span="api.protocol==='HTTP'? 4:0">
|
||||
<el-col :span="api.protocol==='HTTP'? 5:0" class="ms-api-col">
|
||||
<div class="variable-combine" style="margin-left: 10px">{{api.path ===null ? " " : api.path}}</div>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-col :span="2" class="ms-api-col">
|
||||
<div>{{$t('test_track.plan_view.case_count')}}:{{apiCaseList.length}}</div>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-col :span="4">
|
||||
<div>
|
||||
<el-select size="small" :placeholder="$t('api_test.definition.request.grade_info')" v-model="priorityValue"
|
||||
class="ms-api-header-select" @change="getApiTest">
|
||||
|
@ -26,28 +29,7 @@
|
|||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div>
|
||||
<el-select :disabled="isReadOnly" v-model="environment" size="small" class="ms-api-header-select"
|
||||
:placeholder="$t('api_test.definition.request.run_env')"
|
||||
@change="environmentChange" clearable>
|
||||
<el-option v-for="(environment, index) in environments" :key="index"
|
||||
:label="environment.name + (environment.config.httpConfig.socket ? (': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '')"
|
||||
:value="environment.id"/>
|
||||
<el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">
|
||||
{{ $t('api_test.environment.environment_config') }}
|
||||
</el-button>
|
||||
<template v-slot:empty>
|
||||
<div class="empty-environment">
|
||||
<el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">
|
||||
{{ $t('api_test.environment.environment_config') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-col :span="4">
|
||||
<div class="ms-api-header-select">
|
||||
<el-input size="small" :placeholder="$t('api_test.definition.request.select_case')"
|
||||
v-model="name" @blur="getApiTest"/>
|
||||
|
@ -61,76 +43,67 @@
|
|||
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
||||
<!-- 环境 -->
|
||||
<api-environment-config ref="environmentConfig" @close="environmentConfigClose"/>
|
||||
</el-header>
|
||||
|
||||
<!-- 用例部分 -->
|
||||
<el-main v-loading="loading" style="overflow: auto">
|
||||
<div v-for="(item,index) in apiCaseList" :key="index">
|
||||
<el-card style="margin-top: 5px">
|
||||
<el-row>
|
||||
<el-col :span="1">
|
||||
<el-checkbox v-model="item.checked" @change="caseChecked(item)"/>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<div class="el-step__icon is-text ms-api-col">
|
||||
<div class="el-step__icon-inner">{{index+1}}</div>
|
||||
</div>
|
||||
|
||||
<label class="ms-api-label">{{$t('test_track.case.priority')}}</label>
|
||||
<el-select size="small" v-model="item.priority" class="ms-api-select">
|
||||
<el-option v-for="grd in priority" :key="grd.id" :label="grd.name" :value="grd.id"/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<i class="icon el-icon-arrow-right" :class="{'is-active': item.active}"
|
||||
@click="active(item)"/>
|
||||
<el-input v-if="item.type==='create'" size="small" v-model="item.name" :name="index" :key="index"
|
||||
class="ms-api-header-select" style="width: 180px"
|
||||
@blur="saveTestCase(item)"/>
|
||||
<span v-else>
|
||||
{{item.type!= 'create' ? item.name:''}}
|
||||
<i class="el-icon-edit" style="cursor:pointer" @click="showInput(item)"/>
|
||||
</span>
|
||||
<div v-if="item.type!='create'" style="color: #999999;font-size: 12px">
|
||||
<span>
|
||||
{{item.createTime | timestampFormatDate }}
|
||||
{{item.createUser}} {{$t('api_test.definition.request.create_info')}}
|
||||
<el-main v-loading="loading" style="overflow: auto;padding: 5px 10px 10px">
|
||||
<el-checkbox-group v-model="checkedIndex" @change="handleCheckedChange">
|
||||
<div v-for="(item,index) in apiCaseList" :key="index">
|
||||
<el-card style="margin-top: 5px">
|
||||
<el-row>
|
||||
<el-col :span="1" class="ms-api-col">
|
||||
<el-checkbox :key="item.id" :label="index+1"/>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-select size="small" v-model="item.priority" class="ms-api-select">
|
||||
<el-option v-for="grd in priority" :key="grd.id" :label="grd.name" :value="grd.id"/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="14">
|
||||
<span v-if="item.type!='create'" style="color: #303132;font-size: 13px">
|
||||
<i class="icon el-icon-arrow-right" :class="{'is-active': item.active}"
|
||||
@click="active(item)"/>
|
||||
{{item.name}}
|
||||
</span>
|
||||
<span>
|
||||
{{item.updateTime | timestampFormatDate }}
|
||||
{{item.updateUser}} {{$t('api_test.definition.request.update_info')}}
|
||||
</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<div v-if="item.type!='create'" style="color: #999999;font-size: 12px">
|
||||
<span>
|
||||
{{item.createTime | timestampFormatDate }}
|
||||
{{item.createUser}} {{$t('api_test.definition.request.create_info')}}
|
||||
</span>
|
||||
<span>
|
||||
{{item.updateTime | timestampFormatDate }}
|
||||
{{item.updateUser}} {{$t('api_test.definition.request.update_info')}}
|
||||
</span>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="3">
|
||||
<div v-if="item.type!='create'">{{getResult(item.execResult)}}</div>
|
||||
<div v-if="item.type!='create'" style="color: #999999;font-size: 12px">
|
||||
<span> {{item.updateTime | timestampFormatDate }}</span>
|
||||
{{item.updateUser}}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 请求参数-->
|
||||
<el-collapse-transition>
|
||||
<div v-if="item.active">
|
||||
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
|
||||
<el-col :span="6">
|
||||
<div v-if="item.type!='create'">{{getResult(item.execResult)}}</div>
|
||||
<div v-if="item.type!='create'" style="color: #999999;font-size: 12px">
|
||||
<span> {{item.updateTime | timestampFormatDate }}</span>
|
||||
{{item.updateUser}}
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 请求参数-->
|
||||
<el-collapse-transition>
|
||||
<div v-if="item.active">
|
||||
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
|
||||
|
||||
<ms-api-request-form :is-read-only="isReadOnly" :headers="item.request.headers " :request="item.request" v-if="api.protocol==='HTTP'"/>
|
||||
<ms-tcp-basis-parameters :request="item.request" v-if="api.protocol==='TCP'"/>
|
||||
<ms-sql-basis-parameters :request="item.request" v-if="api.protocol==='SQL'"/>
|
||||
<ms-dubbo-basis-parameters :request="item.request" v-if="api.protocol==='DUBBO'"/>
|
||||
<!-- 保存操作 -->
|
||||
<el-button type="primary" size="small" style="margin: 20px; float: right" @click="saveTestCase(item)">
|
||||
{{$t('commons.save')}}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
|
||||
<ms-api-request-form :is-read-only="isReadOnly" :headers="item.request.headers " :request="item.request" v-if="api.protocol==='HTTP'"/>
|
||||
<ms-tcp-basis-parameters :request="item.request" v-if="api.protocol==='TCP'"/>
|
||||
<ms-sql-basis-parameters :request="item.request" v-if="api.protocol==='SQL'"/>
|
||||
<ms-dubbo-basis-parameters :request="item.request" v-if="api.protocol==='DUBBO'"/>
|
||||
<!-- 保存操作 -->
|
||||
<el-button type="primary" size="small" style="margin: 20px; float: right" @click="saveTestCase(item)">
|
||||
{{$t('commons.save')}}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-main>
|
||||
|
||||
</el-container>
|
||||
|
@ -143,8 +116,6 @@
|
|||
import MsTipButton from "../../../../common/components/MsTipButton";
|
||||
import MsApiRequestForm from "../../../definition/components/request/http/ApiRequestForm";
|
||||
import {downloadFile, getUUID, getCurrentProjectID} from "@/common/js/utils";
|
||||
import {parseEnvironment} from "../../../definition/model/EnvironmentModel";
|
||||
import ApiEnvironmentConfig from "../../../definition/components/environment/ApiEnvironmentConfig";
|
||||
import {PRIORITY, RESULT_MAP} from "../../../definition/model/JsonData";
|
||||
import MsApiAssertions from "../../../definition/components/assertion/ApiAssertions";
|
||||
import MsSqlBasisParameters from "../../../definition/components/request/database/BasisParameters";
|
||||
|
@ -159,7 +130,6 @@
|
|||
MsTag,
|
||||
MsTipButton,
|
||||
MsApiRequestForm,
|
||||
ApiEnvironmentConfig,
|
||||
MsApiAssertions,
|
||||
MsSqlBasisParameters,
|
||||
MsTcpBasisParameters,
|
||||
|
@ -192,8 +162,12 @@
|
|||
runData: [],
|
||||
reportId: "",
|
||||
projectId: "",
|
||||
checkedCases: new Set(),
|
||||
methodColorMap: new Map(API_METHOD_COLOUR),
|
||||
|
||||
checkAll: false,
|
||||
checkedIndex: [],
|
||||
isIndeterminate: true
|
||||
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -207,7 +181,6 @@
|
|||
},
|
||||
created() {
|
||||
this.projectId = getCurrentProjectID();
|
||||
this.getEnvironments();
|
||||
this.getApiTest();
|
||||
},
|
||||
methods: {
|
||||
|
@ -218,11 +191,6 @@
|
|||
return RESULT_MAP.get("default");
|
||||
}
|
||||
},
|
||||
handleCommand(e) {
|
||||
if (e === "run") {
|
||||
this.batchRun();
|
||||
}
|
||||
},
|
||||
showInput(row) {
|
||||
row.type = "create";
|
||||
row.active = true;
|
||||
|
@ -232,112 +200,12 @@
|
|||
this.apiCaseList = [];
|
||||
this.$emit('apiCaseClose');
|
||||
},
|
||||
batchRun() {
|
||||
if (!this.environment) {
|
||||
this.$warning(this.$t('api_test.environment.select_environment'));
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
if (this.apiCaseList.length > 0) {
|
||||
this.apiCaseList.forEach(item => {
|
||||
if (item.type != "create") {
|
||||
item.request.name = item.id;
|
||||
item.request.useEnvironment = this.environment.id;
|
||||
this.runData.push(item.request);
|
||||
}
|
||||
})
|
||||
this.loading = true;
|
||||
/*触发执行操作*/
|
||||
this.reportId = getUUID().substring(0, 8);
|
||||
} else {
|
||||
this.$warning("没有可执行的用例!");
|
||||
}
|
||||
},
|
||||
singleRun(row) {
|
||||
if (!this.environment) {
|
||||
this.$warning(this.$t('api_test.environment.select_environment'));
|
||||
return;
|
||||
}
|
||||
this.runData = [];
|
||||
this.loading = true;
|
||||
row.request.name = row.id;
|
||||
row.request.useEnvironment = this.environment.id;
|
||||
this.runData.push(row.request);
|
||||
/*触发执行操作*/
|
||||
this.reportId = getUUID().substring(0, 8);
|
||||
},
|
||||
runRefresh(data) {
|
||||
this.loading = false;
|
||||
this.$success(this.$t('schedule.event_success'));
|
||||
this.getApiTest();
|
||||
this.$emit('refresh');
|
||||
},
|
||||
deleteCase(index, row) {
|
||||
this.$get('/api/testcase/delete/' + row.id, () => {
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.apiCaseList.splice(index, 1);
|
||||
this.$emit('refresh');
|
||||
});
|
||||
},
|
||||
copyCase(data) {
|
||||
let obj = {name: data.name, priority: data.priority, type: 'create', active: false, request: data.request};
|
||||
this.apiCaseList.unshift(obj);
|
||||
},
|
||||
addCase() {
|
||||
// 初始化对象
|
||||
let request = {};
|
||||
if (this.api.request instanceof Object) {
|
||||
request = this.api.request;
|
||||
} else {
|
||||
request = JSON.parse(this.api.request);
|
||||
}
|
||||
let obj = {apiDefinitionId: this.api.id, name: '', priority: 'P0', type: 'create', active: false};
|
||||
obj.request = request;
|
||||
this.apiCaseList.unshift(obj);
|
||||
},
|
||||
|
||||
active(item) {
|
||||
item.active = !item.active;
|
||||
},
|
||||
getBodyUploadFiles(row) {
|
||||
let bodyUploadFiles = [];
|
||||
row.bodyUploadIds = [];
|
||||
let request = row.request;
|
||||
if (request.body && request.body.kvs) {
|
||||
request.body.kvs.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
row.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (request.body.binary) {
|
||||
request.body.binary.forEach(param => {
|
||||
if (param.files) {
|
||||
param.files.forEach(item => {
|
||||
if (item.file) {
|
||||
let fileId = getUUID().substring(0, 8);
|
||||
item.name = item.file.name;
|
||||
item.id = fileId;
|
||||
row.bodyUploadIds.push(fileId);
|
||||
bodyUploadFiles.push(item.file);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return bodyUploadFiles;
|
||||
},
|
||||
getApiTest() {
|
||||
if (this.api) {
|
||||
this.checkedCases = new Set();
|
||||
this.loading = true;
|
||||
if (this.currentRow) {
|
||||
this.currentRow.cases = [];
|
||||
|
@ -364,61 +232,40 @@
|
|||
return true;
|
||||
}
|
||||
},
|
||||
getEnvironments() {
|
||||
if (this.projectId) {
|
||||
this.$get('/api/environment/list/' + this.projectId, response => {
|
||||
this.environments = response.data;
|
||||
this.environments.forEach(environment => {
|
||||
parseEnvironment(environment);
|
||||
});
|
||||
let hasEnvironment = false;
|
||||
for (let i in this.environments) {
|
||||
if (this.api && this.environments[i].id === this.api.environmentId) {
|
||||
hasEnvironment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasEnvironment) {
|
||||
this.environment = undefined;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.environment = undefined;
|
||||
}
|
||||
},
|
||||
openEnvironmentConfig() {
|
||||
if (!this.projectId) {
|
||||
this.$error(this.$t('api_test.select_project'));
|
||||
return;
|
||||
}
|
||||
this.$refs.environmentConfig.open(this.projectId);
|
||||
},
|
||||
environmentChange(value) {
|
||||
for (let i in this.environments) {
|
||||
if (this.environments[i].id === value) {
|
||||
this.environment = this.environments[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
environmentConfigClose() {
|
||||
this.getEnvironments();
|
||||
},
|
||||
|
||||
getColor(enable, method) {
|
||||
if (enable) {
|
||||
return this.methodColorMap.get(method);
|
||||
}
|
||||
},
|
||||
caseChecked(row) {
|
||||
row.protocol = this.api.protocol;
|
||||
row.hashTree = [];
|
||||
if (this.checkedCases.has(row)) {
|
||||
this.checkedCases.delete(row);
|
||||
handleCheckAllChange(val) {
|
||||
this.currentRow.cases = [];
|
||||
if (val) {
|
||||
let index = 1;
|
||||
this.apiCaseList.forEach(item => {
|
||||
this.checkedIndex.push(index);
|
||||
item.protocol = this.api.protocol;
|
||||
item.hashTree = [];
|
||||
this.currentRow.cases.push(item)
|
||||
index++;
|
||||
})
|
||||
} else {
|
||||
this.checkedCases.add(row)
|
||||
this.checkedIndex = [];
|
||||
}
|
||||
let arr = Array.from(this.checkedCases);
|
||||
this.currentRow.cases = arr;
|
||||
this.isIndeterminate = false;
|
||||
},
|
||||
handleCheckedChange(value) {
|
||||
let checkedCount = value.length;
|
||||
this.checkAll = checkedCount === this.apiCaseList.length;
|
||||
this.isIndeterminate = checkedCount > 0 && checkedCount < this.apiCaseList.length;
|
||||
this.currentRow.cases = [];
|
||||
value.forEach(i => {
|
||||
let index = i - 1;
|
||||
let item = this.apiCaseList[index];
|
||||
item.protocol = this.api.protocol;
|
||||
item.hashTree = [];
|
||||
this.currentRow.cases.push(item);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -449,14 +296,11 @@
|
|||
}
|
||||
|
||||
.ms-api-label {
|
||||
color: #CCCCCC;
|
||||
/*color: #CCCCCC;*/
|
||||
}
|
||||
|
||||
.ms-api-col {
|
||||
background-color: #7C3985;
|
||||
border-color: #7C3985;
|
||||
margin-right: 10px;
|
||||
color: white;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.variable-combine {
|
||||
|
@ -486,6 +330,7 @@
|
|||
.api-el-tag {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.is-selected {
|
||||
background: #EFF7FF;
|
||||
}
|
||||
|
|
|
@ -50,10 +50,12 @@ function defaultCustomValidate() {
|
|||
}
|
||||
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./notice/NoticeTemplate.vue") : {};
|
||||
|
||||
|
||||
export default {
|
||||
name: "MsScheduleMaintain",
|
||||
components: {CrontabResult, Crontab, MsScheduleNotification},
|
||||
components: {CrontabResult, Crontab, MsScheduleNotification,"NoticeTemplate": noticeTemplate.default},
|
||||
|
||||
props: {
|
||||
customValidate: {
|
||||
|
|
|
@ -110,16 +110,19 @@
|
|||
</el-table>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <notice-template v-xpack ref="noticeTemplate"/>-->
|
||||
<notice-template v-xpack ref="noticeTemplate"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {hasLicense} from "@/common/js/utils";
|
||||
const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/);
|
||||
const noticeTemplate = requireComponent.keys().length > 0 ? requireComponent("./notice/NoticeTemplate.vue") : {};
|
||||
|
||||
export default {
|
||||
name: "ScheduleNotification",
|
||||
components: {
|
||||
"NoticeTemplate": noticeTemplate.default
|
||||
},
|
||||
props: {
|
||||
testId: String,
|
||||
|
|
|
@ -78,10 +78,10 @@
|
|||
|
||||
<!-- 测试-->
|
||||
<div v-else-if="item.type=== 'TEST'" class="ms-api-div">
|
||||
<ms-run-test-http-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" v-if="currentProtocol==='HTTP'"/>
|
||||
<ms-run-test-tcp-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" v-if="currentProtocol==='TCP'"/>
|
||||
<ms-run-test-sql-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" v-if="currentProtocol==='SQL'"/>
|
||||
<ms-run-test-dubbo-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" v-if="currentProtocol==='DUBBO'"/>
|
||||
<ms-run-test-http-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='HTTP'"/>
|
||||
<ms-run-test-tcp-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='TCP'"/>
|
||||
<ms-run-test-sql-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='SQL'"/>
|
||||
<ms-run-test-dubbo-page :currentProtocol="currentProtocol" :api-data="item.api" @saveAsApi="editApi" @refresh="refresh" v-if="currentProtocol==='DUBBO'"/>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<div>
|
||||
<el-select size="small" :placeholder="$t('api_test.definition.request.grade_info')" v-model="condition.priority"
|
||||
:disabled="isCaseEdit"
|
||||
class="ms-api-header-select" @change="getApiTest" clearable>
|
||||
class="ms-api-header-select" @change="getApiTest" clearable style="margin-right: 20px">
|
||||
<el-option v-for="grd in priorities" :key="grd.id" :label="grd.name" :value="grd.id"/>
|
||||
</el-select>
|
||||
</div>
|
||||
|
|
|
@ -172,9 +172,9 @@
|
|||
}
|
||||
}
|
||||
this.apiCaseList = response.data;
|
||||
// if (this.apiCaseList.length == 0) {
|
||||
// this.addCase();
|
||||
// }
|
||||
if (this.apiCaseList.length == 0 && !this.loaded) {
|
||||
this.addCase();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<!-- 请求参数 -->
|
||||
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
|
||||
<ms-basis-parameters :request="request"/>
|
||||
<ms-basis-parameters :showScript="false" :request="request"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
<!-- 请求参数 -->
|
||||
<div>
|
||||
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
|
||||
<ms-api-request-form :request="request" :headers="request.headers" :isShowEnable="isShowEnable"/>
|
||||
<ms-api-request-form :showScript="false" :request="request" :headers="request.headers" :isShowEnable="isShowEnable"/>
|
||||
</div>
|
||||
|
||||
</el-form>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<!-- 请求参数 -->
|
||||
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
|
||||
<ms-basis-parameters :request="request"/>
|
||||
<ms-basis-parameters :showScript="false" :request="request"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<el-form-item>
|
||||
<el-dropdown split-button type="primary" class="ms-api-buttion" @click="handleCommand"
|
||||
@command="handleCommand" size="small" v-if="testCase===undefined">
|
||||
@command="handleCommand" size="small" v-if="testCase===undefined && !scenario">
|
||||
{{$t('commons.test')}}
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="save_as">{{$t('api_test.definition.request.save_as')}}</el-dropdown-item>
|
||||
|
@ -76,7 +76,9 @@
|
|||
method: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
url: [
|
||||
{max: 500, required: true, message: this.$t('commons.input_limit', [1, 500]), trigger: 'blur'},
|
||||
{validator: validateURL, trigger: 'blur'}
|
||||
/*
|
||||
{validator: validateURL, trigger: 'blur'}
|
||||
*/
|
||||
],
|
||||
},
|
||||
debugForm: {method: REQ_METHOD[0].id, environmentId: ""},
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
<template>
|
||||
<el-card class="card-content" v-if="isShow">
|
||||
|
||||
<el-button-group v-if="isShowChangeButton">
|
||||
<el-button plain size="small" icon="el-icon-tickets" :class="{active: isApiListEnable}" @click="apiChange('api')"></el-button>
|
||||
<el-button plain class="case-button" size="small" icon="el-icon-paperclip" :class="{active: !isApiListEnable}" @click="caseChange('case')"></el-button>
|
||||
|
||||
<el-tooltip class="item" effect="dark" content="接口列表" placement="left">
|
||||
<el-button plain size="small" icon="el-icon-tickets" :class="{active: isApiListEnable}" @click="apiChange('api')"></el-button>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip class="item" effect="dark" content="用例列表" placement="right">
|
||||
<el-button plain class="case-button" size="small" icon="el-icon-paperclip" :class="{active: !isApiListEnable}" @click="caseChange('case')"></el-button>
|
||||
</el-tooltip>
|
||||
|
||||
</el-button-group>
|
||||
|
||||
<template v-slot:header>
|
||||
<slot name="header"></slot>
|
||||
</template>
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
<el-option v-for="(environment, index) in environments" :key="index"
|
||||
:label="environment.name + (environment.config.httpConfig.socket ? (': ' + environment.config.httpConfig.protocol + '://' + environment.config.httpConfig.socket) : '')"
|
||||
:value="environment.id"/>
|
||||
<el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">
|
||||
<el-button class="environment-button" size="small" type="primary" @click="openEnvironmentConfig">
|
||||
{{ $t('api_test.environment.environment_config') }}
|
||||
</el-button>
|
||||
<template v-slot:empty>
|
||||
<div class="empty-environment">
|
||||
<el-button class="environment-button" size="mini" type="primary" @click="openEnvironmentConfig">
|
||||
<el-button class="environment-button" size="small" type="primary" @click="openEnvironmentConfig">
|
||||
{{ $t('api_test.environment.environment_config') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
@ -43,11 +43,11 @@
|
|||
|
||||
|
||||
<el-form-item :label="$t('api_test.request.sql.result_variable')" prop="resultVariable">
|
||||
<el-input v-model="request.resultVariable" maxlength="300" show-word-limit/>
|
||||
<el-input v-model="request.resultVariable" maxlength="300" show-word-limit size="small"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('api_test.request.sql.variable_names')" prop="variableNames">
|
||||
<el-input v-model="request.variableNames" maxlength="300" show-word-limit/>
|
||||
<el-input v-model="request.variableNames" maxlength="300" show-word-limit size="small"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-tabs v-model="activeName">
|
||||
|
@ -77,7 +77,7 @@
|
|||
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="3" class="ms-left-cell">
|
||||
<el-col :span="3" class="ms-left-cell" v-if="showScript">
|
||||
|
||||
<el-button class="ms-left-buttion" size="small" style="color: #B8741A;background-color: #F9F1EA" @click="addPre">+{{$t('api_test.definition.request.pre_script')}}</el-button>
|
||||
<br/>
|
||||
|
@ -120,6 +120,10 @@
|
|||
request: {},
|
||||
basisData: {},
|
||||
moduleOptions: Array,
|
||||
showScript: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
@ -132,7 +136,7 @@
|
|||
isReloadData: false,
|
||||
activeName: "variables",
|
||||
rules: {
|
||||
environmentId: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
environmentId: [{required: true, message: this.$t('api_test.definition.request.run_env'), trigger: 'change'}],
|
||||
dataSourceId: [{required: true, message: this.$t('api_test.request.sql.dataSource'), trigger: 'change'}],
|
||||
},
|
||||
}
|
||||
|
@ -172,7 +176,7 @@
|
|||
this.reload();
|
||||
},
|
||||
copyRow(row) {
|
||||
let obj =JSON.parse(JSON.stringify(row));
|
||||
let obj = JSON.parse(JSON.stringify(row));
|
||||
obj.id = getUUID();
|
||||
this.request.hashTree.push(obj);
|
||||
this.reload();
|
||||
|
@ -205,6 +209,16 @@
|
|||
this.environments.forEach(environment => {
|
||||
parseEnvironment(environment);
|
||||
});
|
||||
let hasEnvironment = false;
|
||||
for (let i in this.environments) {
|
||||
if (this.environments[i].id === this.request.environmentId) {
|
||||
hasEnvironment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasEnvironment) {
|
||||
this.request.environmentId = undefined;
|
||||
}
|
||||
this.initDataSource();
|
||||
});
|
||||
},
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="3" class="ms-left-cell">
|
||||
<el-col :span="3" class="ms-left-cell" v-if="showScript">
|
||||
<el-button class="ms-left-buttion" size="small" style="color: #B8741A;background-color: #F9F1EA" @click="addPre">+{{$t('api_test.definition.request.pre_script')}}</el-button>
|
||||
<br/>
|
||||
<el-button class="ms-left-buttion" size="small" style="color: #783887;background-color: #F2ECF3" @click="addPost">+{{$t('api_test.definition.request.post_script')}}</el-button>
|
||||
|
@ -105,6 +105,10 @@
|
|||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
showScript: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -141,7 +145,7 @@
|
|||
this.reload();
|
||||
},
|
||||
copyRow(row) {
|
||||
let obj =JSON.parse(JSON.stringify(row));
|
||||
let obj = JSON.parse(JSON.stringify(row));
|
||||
obj.id = getUUID();
|
||||
this.request.hashTree.push(obj);
|
||||
this.reload();
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
</div>
|
||||
</el-col>
|
||||
<!--操作按钮-->
|
||||
<el-col :span="3" class="ms-left-cell" v-if="!referenced">
|
||||
<el-col :span="3" class="ms-left-cell" v-if="!referenced && showScript">
|
||||
<el-button class="ms-left-buttion" size="small" @click="addPre">+{{$t('api_test.definition.request.pre_script')}}</el-button>
|
||||
<br/>
|
||||
<el-button class="ms-left-buttion" size="small" @click="addPost">+{{$t('api_test.definition.request.post_script')}}</el-button>
|
||||
|
@ -131,6 +131,7 @@
|
|||
},
|
||||
props: {
|
||||
request: {},
|
||||
showScript: Boolean,
|
||||
headers: {
|
||||
type: Array,
|
||||
default() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="request-form">
|
||||
<component :is="component" :is-read-only="isReadOnly" :referenced="referenced" :request="request" :headers="headers" :isShowEnable="isShowEnable"/>
|
||||
<component :is="component" :showScript="showScript" :is-read-only="isReadOnly" :referenced="referenced" :request="request" :headers="headers" :isShowEnable="isShowEnable"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -17,6 +17,10 @@
|
|||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showScript: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
referenced: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</el-card>
|
||||
|
||||
<!-- 加载用例 -->
|
||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :currentApi="api"
|
||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @refresh="refresh" @selectTestCase="selectTestCase" :currentApi="api"
|
||||
:loaded="loaded" :refreshSign="refreshSign" :createCase="createCase"
|
||||
ref="caseList"/>
|
||||
|
||||
|
@ -104,6 +104,9 @@
|
|||
return this.runTest();
|
||||
}
|
||||
},
|
||||
refresh(){
|
||||
this.$emit('refresh');
|
||||
},
|
||||
runTest() {
|
||||
this.loading = true;
|
||||
this.api.request.name = this.api.id;
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
</el-card>
|
||||
|
||||
<!-- 加载用例 -->
|
||||
<ms-api-case-list @selectTestCase="selectTestCase"
|
||||
<ms-api-case-list @selectTestCase="selectTestCase" @refresh="refresh"
|
||||
:loaded="loaded"
|
||||
:refreshSign="refreshSign"
|
||||
:createCase="createCase"
|
||||
|
@ -273,6 +273,9 @@
|
|||
environmentConfigClose() {
|
||||
this.getEnvironments();
|
||||
},
|
||||
refresh(){
|
||||
this.$emit('refresh');
|
||||
},
|
||||
getResult() {
|
||||
let url = "/api/definition/report/getReport/" + this.api.id;
|
||||
this.$get(url, response => {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
</el-card>
|
||||
|
||||
<!-- 加载用例 -->
|
||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :currentApi="api" :refreshSign="refreshSign"
|
||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @refresh="refresh" @selectTestCase="selectTestCase" :currentApi="api" :refreshSign="refreshSign"
|
||||
:loaded="loaded" :createCase="createCase"
|
||||
ref="caseList"/>
|
||||
|
||||
|
@ -103,6 +103,9 @@
|
|||
return this.$refs['requestForm'].validate();
|
||||
}
|
||||
},
|
||||
refresh(){
|
||||
this.$emit('refresh');
|
||||
},
|
||||
runTest() {
|
||||
this.loading = true;
|
||||
this.api.request.name = this.api.id;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</el-card>
|
||||
|
||||
<!-- 加载用例 -->
|
||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @selectTestCase="selectTestCase" :currentApi="api" :refreshSign="refreshSign"
|
||||
<ms-api-case-list @apiCaseClose="apiCaseClose" @refresh="refresh" @selectTestCase="selectTestCase" :currentApi="api" :refreshSign="refreshSign"
|
||||
:loaded="loaded" :createCase="createCase"
|
||||
ref="caseList"/>
|
||||
<!-- 环境 -->
|
||||
|
@ -103,6 +103,9 @@
|
|||
return this.$refs['requestForm'].validate();
|
||||
}
|
||||
},
|
||||
refresh(){
|
||||
this.$emit('refresh');
|
||||
},
|
||||
runTest() {
|
||||
this.loading = true;
|
||||
this.api.request.name = this.api.id;
|
||||
|
|
|
@ -7,12 +7,8 @@
|
|||
</div>
|
||||
<div v-else-if="dateType==='2'">
|
||||
<el-link href="https://github.com/metersphere/metersphere/issues" target="_blank" type="primary">😔觉得MeterSphere不好用就来https://github.com/metersphere/metersphere/issues吐个槽吧!</el-link>
|
||||
<!-- <el-link href="https://jmeter.apache.org/usermanual/component_reference.html#BeanShell_PostProcessor"-->
|
||||
<!-- type="primary">{{$t('commons.reference_documentation')}}-->
|
||||
<!-- </el-link>-->
|
||||
</div>
|
||||
<div v-else-if="dateType==='3'">
|
||||
<!-- <el-link :herf="'https://github.com/metersphere/metersphere/issues'" target="_blank"></el-link>-->
|
||||
<el-link href="https://github.com/metersphere/metersphere" target="_blank" type="primary">😄觉得MeterSphere好用就来 https://github.com/metersphere/metersphere 点个star吧!</el-link>
|
||||
</div>
|
||||
<div v-else>
|
||||
|
@ -58,21 +54,15 @@ import MsSceneInfoCard from "./components/SceneInfoCard";
|
|||
import MsScheduleTaskInfoCard from "./components/ScheduleTaskInfoCard";
|
||||
import MsTestCaseInfoCard from "./components/TestCaseInfoCard";
|
||||
|
||||
// import MsApiDetailCard from "./components/ApiDetailCard";
|
||||
// import MsSceneDetailCard from "./components/SceneDetailCard";
|
||||
// import MsScheduleTaskDetailCard from "./components/ScheduleTaskDetailCard";
|
||||
// import MsTestCaseDetailCard from "./components/TestCaseDetailCard";
|
||||
|
||||
import MsFailureTestCaseList from "./components/FailureTestCaseList";
|
||||
import MsRunningTaskList from "./components/RunningTaskList"
|
||||
import {getCurrentProjectID,getCurrentWorkspaceId} from "@/common/js/utils";
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "ApiTestHomePage",
|
||||
|
||||
components: {
|
||||
MsApiInfoCard, MsSceneInfoCard, MsScheduleTaskInfoCard, MsTestCaseInfoCard,
|
||||
// MsApiDetailCard, MsSceneDetailCard, MsScheduleTaskDetailCard, MsTestCaseDetailCard,
|
||||
MsFailureTestCaseList,MsRunningTaskList,
|
||||
MsMainContainer, MsContainer
|
||||
},
|
||||
|
@ -121,8 +111,8 @@ export default {
|
|||
});
|
||||
|
||||
|
||||
let workSpaceID = getCurrentWorkspaceId();
|
||||
this.$get("/api/scheduleTaskInfoCount/"+workSpaceID, response => {
|
||||
// let workSpaceID = getCurrentWorkspaceId();
|
||||
this.$get("/api/scheduleTaskInfoCount/"+selectProjectId, response => {
|
||||
this.scheduleTaskCountData = response.data;
|
||||
});
|
||||
},
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {getCurrentProjectID,getCurrentWorkspaceId} from "@/common/js/utils";
|
||||
import {getCurrentProjectID} from "@/common/js/utils";
|
||||
export default {
|
||||
name: "MsRunningTaskList",
|
||||
|
||||
|
@ -56,8 +56,8 @@ export default {
|
|||
|
||||
methods: {
|
||||
search() {
|
||||
let workSpaceID = getCurrentWorkspaceId();
|
||||
this.result = this.$get("/api/runningTask/"+workSpaceID, response => {
|
||||
let projectID = getCurrentProjectID();
|
||||
this.result = this.$get("/api/runningTask/"+projectID, response => {
|
||||
this.tableData = response.data;
|
||||
});
|
||||
},
|
||||
|
|
|
@ -47,14 +47,14 @@
|
|||
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
:title="$t('test_resource_pool.create_resource_pool')"
|
||||
:visible.sync="createVisible" width="70%"
|
||||
:title="form.id ? $t('test_resource_pool.update_resource_pool') : $t('test_resource_pool.create_resource_pool')"
|
||||
:visible.sync="dialogVisible" width="70%"
|
||||
@closed="closeFunc"
|
||||
:destroy-on-close="true"
|
||||
v-loading="result.loading"
|
||||
>
|
||||
<el-form :model="form" label-position="right" label-width="120px" size="small" :rules="rule"
|
||||
ref="createTestResourcePoolForm">
|
||||
ref="testResourcePoolForm">
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
@ -75,22 +75,25 @@
|
|||
<div class="node-line" v-if="form.type === 'K8S'" v-xpack>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item prop="masterUrl" label="Master URL">
|
||||
<el-form-item label="Master URL"
|
||||
:rules="requiredRules">
|
||||
<el-input v-model="item.masterUrl" autocomplete="new-password"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item prop="password" label="Token">
|
||||
<el-form-item label="Token"
|
||||
:rules="requiredRules">
|
||||
<el-input v-model="item.token" type="password" show-password autocomplete="new-password"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item prop="maxConcurrency" :label="$t('test_resource_pool.max_threads')">
|
||||
<el-input-number v-model="item.maxConcurrency" :min="1" :max="1000000000"></el-input-number>
|
||||
<el-form-item :label="$t('test_resource_pool.max_threads')"
|
||||
:rules="requiredRules">
|
||||
<el-input-number v-model="item.maxConcurrency" :min="1" :max="1000000000"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -98,17 +101,19 @@
|
|||
<div class="node-line" v-if="form.type === 'NODE'">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="ip" label="IP">
|
||||
<el-form-item label="IP" :rules="requiredRules">
|
||||
<el-input v-model="item.ip" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item prop="port" label="Port" style="padding-left: 20px">
|
||||
<el-form-item label="Port" style="padding-left: 20px"
|
||||
:rules="requiredRules">
|
||||
<el-input-number v-model="item.port" :min="1" :max="65535"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item prop="maxConcurrency" :label="$t('test_resource_pool.max_threads')"
|
||||
<el-form-item :label="$t('test_resource_pool.max_threads')"
|
||||
:rules="requiredRules"
|
||||
style="padding-left: 20px">
|
||||
<el-input-number v-model="item.maxConcurrency" :min="1" :max="1000000000"></el-input-number>
|
||||
</el-form-item>
|
||||
|
@ -132,100 +137,15 @@
|
|||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer
|
||||
@cancel="createVisible = false"
|
||||
@confirm="createTestResourcePool('createTestResourcePoolForm')"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
:close-on-click-modal="false"
|
||||
v-loading="result.loading"
|
||||
:title="$t('test_resource_pool.update_resource_pool')" :visible.sync="updateVisible" width="70%"
|
||||
:destroy-on-close="true"
|
||||
@close="closeFunc">
|
||||
<el-form :model="form" label-position="right" label-width="120px" size="small" :rules="rule"
|
||||
ref="updateTestResourcePoolForm">
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.description')" prop="description">
|
||||
<el-input v-model="form.description" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.image')" prop="image">
|
||||
<el-input v-model="form.image" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('test_resource_pool.type')" prop="type">
|
||||
<el-select v-model="form.type" :placeholder="$t('test_resource_pool.select_pool_type')"
|
||||
@change="changeResourceType()">
|
||||
<el-option key="NODE" value="NODE" label="Node">Node</el-option>
|
||||
<el-option key="K8S" value="K8S" label="Kubernetes" v-xpack>Kubernetes</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div v-for="(item,index) in infoList " :key="index">
|
||||
<div class="node-line" v-if="form.type === 'K8S'" v-xpack>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item prop="masterUrl" label="Master URL">
|
||||
<el-input v-model="item.masterUrl" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item prop="password" label="Token">
|
||||
<el-input v-model="item.token" type="password" show-password autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item prop="maxConcurrency" :label="$t('test_resource_pool.max_threads')">
|
||||
<el-input-number v-model="item.maxConcurrency" :min="1" :max="1000000000"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="node-line" v-if="form.type === 'NODE'">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-form-item prop="ip" label="IP">
|
||||
<el-input v-model="item.ip" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item prop="port" label="Port" style="padding-left: 20px">
|
||||
<el-input-number v-model="item.port" :min="1" :max="65535"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item prop="maxConcurrency" :label="$t('test_resource_pool.max_threads')"
|
||||
style="padding-left: 20px">
|
||||
<el-input-number v-model="item.maxConcurrency" :min="1" :max="1000000000"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :offset="2" :span="2">
|
||||
<span class="box">
|
||||
<el-button @click="addResourceInfo()" type="success" size="mini" circle>
|
||||
<font-awesome-icon :icon="['fas', 'plus']"/>
|
||||
</el-button>
|
||||
</span>
|
||||
<span class="box">
|
||||
<el-button @click="removeResourceInfo(index)" type="danger" size="mini" circle>
|
||||
<font-awesome-icon :icon="['fas', 'minus']"/>
|
||||
</el-button>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
v-if="form.id"
|
||||
@cancel="dialogVisible = false"
|
||||
@confirm="updateTestResourcePool()"/>
|
||||
<ms-dialog-footer
|
||||
@cancel="updateVisible = false"
|
||||
@confirm="updateTestResourcePool('updateTestResourcePoolForm')"/>
|
||||
v-else
|
||||
@cancel="dialogVisible = false"
|
||||
@confirm="createTestResourcePool()"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -235,7 +155,7 @@ import MsTablePagination from "../../common/pagination/TablePagination";
|
|||
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {listenGoBack, removeGoBackListener} from "../../../../common/js/utils";
|
||||
import {listenGoBack, removeGoBackListener} from "@/common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "MsTestResourcePool",
|
||||
|
@ -243,9 +163,8 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
result: {},
|
||||
createVisible: false,
|
||||
dialogVisible: false,
|
||||
infoList: [],
|
||||
updateVisible: false,
|
||||
queryPath: "testresourcepool/list",
|
||||
condition: {},
|
||||
items: [],
|
||||
|
@ -253,6 +172,7 @@ export default {
|
|||
pageSize: 5,
|
||||
total: 0,
|
||||
form: {},
|
||||
requiredRules: [{required: true, message: this.$t('test_resource_pool.fill_the_data'), trigger: 'blur'}],
|
||||
rule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('test_resource_pool.input_pool_name'), trigger: 'blur'},
|
||||
|
@ -329,11 +249,11 @@ export default {
|
|||
this.initTableData();
|
||||
},
|
||||
create() {
|
||||
this.createVisible = true;
|
||||
this.dialogVisible = true;
|
||||
listenGoBack(this.closeFunc);
|
||||
},
|
||||
edit(row) {
|
||||
this.updateVisible = true;
|
||||
this.dialogVisible = true;
|
||||
this.form = JSON.parse(JSON.stringify(row));
|
||||
this.convertResources();
|
||||
listenGoBack(this.closeFunc);
|
||||
|
@ -363,8 +283,8 @@ export default {
|
|||
this.$info(this.$t('commons.delete_cancel'));
|
||||
});
|
||||
},
|
||||
createTestResourcePool(createTestResourcePoolForm) {
|
||||
this.$refs[createTestResourcePoolForm].validate(valid => {
|
||||
createTestResourcePool() {
|
||||
this.$refs.testResourcePoolForm.validate(valid => {
|
||||
if (valid) {
|
||||
let vri = this.validateResourceInfo();
|
||||
if (vri.validate) {
|
||||
|
@ -374,7 +294,7 @@ export default {
|
|||
type: 'success',
|
||||
message: this.$t('commons.save_success')
|
||||
},
|
||||
this.createVisible = false,
|
||||
this.dialogVisible = false,
|
||||
this.initTableData());
|
||||
});
|
||||
} else {
|
||||
|
@ -400,8 +320,8 @@ export default {
|
|||
});
|
||||
this.form.resources = resources;
|
||||
},
|
||||
updateTestResourcePool(updateTestResourcePoolForm) {
|
||||
this.$refs[updateTestResourcePoolForm].validate(valid => {
|
||||
updateTestResourcePool() {
|
||||
this.$refs.testResourcePoolForm.validate(valid => {
|
||||
if (valid) {
|
||||
let vri = this.validateResourceInfo();
|
||||
if (vri.validate) {
|
||||
|
@ -411,7 +331,7 @@ export default {
|
|||
type: 'success',
|
||||
message: this.$t('commons.modify_success')
|
||||
},
|
||||
this.updateVisible = false,
|
||||
this.dialogVisible = false,
|
||||
this.initTableData(),
|
||||
self.loading = false);
|
||||
});
|
||||
|
@ -426,8 +346,7 @@ export default {
|
|||
},
|
||||
closeFunc() {
|
||||
this.form = {};
|
||||
this.updateVisible = false;
|
||||
this.createVisible = false;
|
||||
this.dialogVisible = false;
|
||||
removeGoBackListener(this.closeFunc);
|
||||
},
|
||||
changeSwitch(row) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
@testCaseDetail="showTestCaseDetail"
|
||||
@batchMove="batchMove"
|
||||
@refresh="refresh"
|
||||
@refreshAll="refreshAll"
|
||||
@moveToNode="moveToNode"
|
||||
ref="testCaseList">
|
||||
</test-case-list>
|
||||
|
@ -131,6 +132,10 @@ export default {
|
|||
this.selectNode = {};
|
||||
this.refreshTable();
|
||||
},
|
||||
refreshAll() {
|
||||
this.$refs.nodeTree.list();
|
||||
this.refresh();
|
||||
},
|
||||
openRecentTestCaseEditDialog(caseId) {
|
||||
if (caseId) {
|
||||
// this.getProjectByCaseId(caseId);
|
||||
|
|
|
@ -204,7 +204,7 @@
|
|||
if (res.success) {
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.dialogVisible = false;
|
||||
this.$emit("refresh");
|
||||
this.$emit("refreshAll");
|
||||
} else {
|
||||
this.errList = res.errList;
|
||||
}
|
||||
|
@ -223,7 +223,7 @@
|
|||
if (res.success) {
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.dialogVisible = false;
|
||||
this.$emit("refresh");
|
||||
this.$emit("refreshAll");
|
||||
} else {
|
||||
this.xmindErrList = res.errList;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
</template>
|
||||
|
||||
<test-case-import @refresh="refresh" ref="testCaseImport"/>
|
||||
<test-case-import @refreshAll="refreshAll" ref="testCaseImport"/>
|
||||
|
||||
<el-table
|
||||
border
|
||||
|
@ -374,6 +374,10 @@ export default {
|
|||
this.selectRows.clear();
|
||||
this.$emit('refresh');
|
||||
},
|
||||
refreshAll() {
|
||||
this.selectRows.clear();
|
||||
this.$emit('refreshAll');
|
||||
},
|
||||
showDetail(row, event, column) {
|
||||
this.$emit('testCaseDetail', row);
|
||||
},
|
||||
|
|
|
@ -14,11 +14,13 @@
|
|||
class="el-menu-demo header-menu" mode="horizontal" @select="handleSelect">
|
||||
<el-menu-item index="functional">功能测试用例</el-menu-item>
|
||||
<el-menu-item index="api">接口测试用例</el-menu-item>
|
||||
<el-menu-item index="report">报告统计</el-menu-item>
|
||||
</el-menu>
|
||||
</template>
|
||||
</ms-test-plan-header-bar>
|
||||
<test-plan-functional v-if="activeIndex === 'functional'" :plan-id="planId"/>
|
||||
<test-plan-api v-if="activeIndex === 'api'" :plan-id="planId"/>
|
||||
<test-case-statistics-report-view :test-plan="currentPlan" v-if="activeIndex === 'report'"/>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
@ -35,10 +37,12 @@
|
|||
import MsTestPlanHeaderBar from "./comonents/head/TestPlanHeaderBar";
|
||||
import TestPlanFunctional from "./comonents/functional/TestPlanFunctional";
|
||||
import TestPlanApi from "./comonents/api/TestPlanApi";
|
||||
import TestCaseStatisticsReportView from "./comonents/report/statistics/TestCaseStatisticsReportView";
|
||||
|
||||
export default {
|
||||
name: "TestPlanView",
|
||||
components: {
|
||||
TestCaseStatisticsReportView,
|
||||
TestPlanApi,
|
||||
TestPlanFunctional,
|
||||
MsTestPlanHeaderBar,
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
<template>
|
||||
|
||||
<common-component :title="$t('test_track.plan_view.failure_case')">
|
||||
<functional-failure-cases-list v-if="showFunctional" :functional-test-cases="failureTestCases.functionalTestCases"/>
|
||||
<api-failure-cases-list v-if="showApi" :api-test-cases="failureTestCases.apiTestCases"/>
|
||||
<scenario-failure-cases-list v-if="showScenario" :scenario-test-cases="failureTestCases.scenarioTestCases"/>
|
||||
</common-component>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommonComponent from "./CommonComponent";
|
||||
import PriorityTableItem from "../../../../../common/tableItems/planview/PriorityTableItem";
|
||||
import TypeTableItem from "../../../../../common/tableItems/planview/TypeTableItem";
|
||||
import MethodTableItem from "../../../../../common/tableItems/planview/MethodTableItem";
|
||||
import StatusTableItem from "../../../../../common/tableItems/planview/StatusTableItem";
|
||||
import {hub} from "@/business/components/track/plan/event-bus";
|
||||
import FunctionalFailureCasesList from "./component/FunctionalFailureCasesList";
|
||||
import ApiFailureCasesList from "./component/ApiFailureCasesList";
|
||||
import ScenarioFailureCasesList from "./component/ScenarioFailureCasesList";
|
||||
export default {
|
||||
name: "FailureResultAdvanceComponent",
|
||||
components: {
|
||||
ScenarioFailureCasesList,
|
||||
ApiFailureCasesList,
|
||||
FunctionalFailureCasesList,
|
||||
StatusTableItem, MethodTableItem, TypeTableItem, PriorityTableItem, CommonComponent},
|
||||
props: {
|
||||
failureTestCases: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
functionalTestCases: [
|
||||
{
|
||||
name: 'testCase1',
|
||||
priority: 'P1',
|
||||
type: 'api',
|
||||
method: 'auto',
|
||||
nodePath: '/module1/module2',
|
||||
executorName: "Tom",
|
||||
status: "Failure",
|
||||
updateTime: new Date(),
|
||||
},
|
||||
{
|
||||
name: 'testCase2',
|
||||
priority: 'P0',
|
||||
type: 'functional',
|
||||
method: 'manual',
|
||||
nodePath: '/module1',
|
||||
executorName: "Micheal",
|
||||
status: "Failure",
|
||||
updateTime: new Date()
|
||||
}
|
||||
],
|
||||
apiTestCases: [
|
||||
{
|
||||
name: 'testCase3',
|
||||
priority: 'P2',
|
||||
path: '/module1/module2',
|
||||
createUser: "Tom",
|
||||
lastResult: "Failure",
|
||||
updateTime: new Date(),
|
||||
}
|
||||
],
|
||||
scenarioTestCases: [
|
||||
{
|
||||
name: 'testCase4',
|
||||
level: 'P3',
|
||||
modulePath: '/module1/module2',
|
||||
stepTotal: 10,
|
||||
passRate: '80%',
|
||||
userId: "Tom",
|
||||
lastResult: "Failure",
|
||||
updateTime: new Date(),
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showFunctional() {
|
||||
return this.failureTestCases.functionalTestCases.length > 0 || (this.failureTestCases.apiTestCases.length <= 0 && this.failureTestCases.scenarioTestCases.length <= 0);
|
||||
},
|
||||
showApi() {
|
||||
return this.failureTestCases.apiTestCases.length > 0;
|
||||
},
|
||||
showScenario() {
|
||||
return this.failureTestCases.scenarioTestCases.length > 0;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goFailureTestCase(row) {
|
||||
hub.$emit("openFailureTestCase", row);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
/deep/ .failure-cases-list-header {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.failure-cases-list {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -5,8 +5,10 @@
|
|||
<div v-if="!metric">
|
||||
<base-info-component :is-report="false" v-if="preview.id == 1"/>
|
||||
<test-result-component v-if="preview.id == 2"/>
|
||||
<test-result-chart-component v-if="preview.id == 3"/>
|
||||
<failure-result-component v-if="preview.id == 4"/>
|
||||
<!--<test-result-chart-component v-if="preview.id == 3"/>-->
|
||||
<test-result-advance-chart-component v-if="preview.id == 3"/>
|
||||
<!--<failure-result-component v-if="preview.id == 4"/>-->
|
||||
<failure-result-advance-component v-if="preview.id == 4"/>
|
||||
<defect-list-component v-if="preview.id == 5"/>
|
||||
<rich-text-component :preview="preview" v-if="preview.type != 'system'"/>
|
||||
</div>
|
||||
|
@ -15,8 +17,10 @@
|
|||
<div v-if="metric">
|
||||
<base-info-component id="baseInfoComponent" :report-info="metric" v-if="preview.id == 1"/>
|
||||
<test-result-component id="testResultComponent" :test-results="metric.moduleExecuteResult" v-if="preview.id == 2"/>
|
||||
<test-result-chart-component id="resultChartComponent" :execute-result="metric.executeResult" v-if="preview.id == 3"/>
|
||||
<failure-result-component id="failureResultComponent" :failure-test-cases="metric.failureTestCases" v-if="preview.id == 4"/>
|
||||
<!--<test-result-chart-component id="resultChartComponent" :execute-result="metric.executeResult" v-if="preview.id == 3"/>-->
|
||||
<test-result-advance-chart-component id="resultChartComponent" :execute-result="metric.executeResult" v-if="preview.id == 3"/>
|
||||
<!--<failure-result-component id="failureResultComponent" :failure-test-cases="metric.failureTestCases" v-if="preview.id == 4"/>-->
|
||||
<failure-result-advance-component id="failureResultComponent" :failure-test-cases="metric.failureTestCases" v-if="preview.id == 4"/>
|
||||
<defect-list-component id="defectListComponent" :defect-list="metric.issues" v-if="preview.id == 5"/>
|
||||
<rich-text-component id="richTextComponent" :is-report-view="isReportView" :preview="preview" v-if="preview.type != 'system'"/>
|
||||
</div>
|
||||
|
@ -32,10 +36,14 @@
|
|||
import FailureResultComponent from "./FailureResultComponent";
|
||||
import DefectListComponent from "./DefectListComponent";
|
||||
import html2canvas from 'html2canvas';
|
||||
import TestResultAdvanceChartComponent from "./TestResultAdvanceChartComponent";
|
||||
import FailureResultAdvanceComponent from "./FailureResultAdvanceComponent";
|
||||
|
||||
export default {
|
||||
name: "TemplateComponent",
|
||||
components: {
|
||||
FailureResultAdvanceComponent,
|
||||
TestResultAdvanceChartComponent,
|
||||
FailureResultComponent,DefectListComponent,
|
||||
RichTextComponent, TestResultChartComponent, TestResultComponent, BaseInfoComponent},
|
||||
props: {
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
<template>
|
||||
|
||||
<common-component :title="$t('test_track.plan_view.result_statistics')">
|
||||
|
||||
<div class="char-component">
|
||||
<div class="char-item" v-if="showFunctional">
|
||||
<ms-pie-chart v-if="isShow" :text="'功能测试用例'"
|
||||
:name="$t('test_track.plan_view.test_result')" :data="functionalCharData"/>
|
||||
</div>
|
||||
|
||||
<div class="char-item" v-if="showApi">
|
||||
<ms-pie-chart v-if="isShow" :text="'接口测试用例'"
|
||||
:name="$t('test_track.plan_view.test_result')" :data="apiCharData"/>
|
||||
</div>
|
||||
|
||||
<div class="char-item" v-if="showScenario">
|
||||
<ms-pie-chart v-if="isShow" :text="'场景测试用例'"
|
||||
:name="$t('test_track.plan_view.test_result')" :data="scenarioCharData"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</common-component>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommonComponent from "./CommonComponent";
|
||||
import MsPieChart from "../../../../../../common/components/MsPieChart";
|
||||
|
||||
export default {
|
||||
name: "TestResultAdvanceChartComponent",
|
||||
components: {MsPieChart, CommonComponent},
|
||||
data() {
|
||||
return {
|
||||
dataMap: new Map([
|
||||
["Pass", {name: this.$t('test_track.plan_view.pass'), itemStyle: {color: '#67C23A'}}],
|
||||
["Failure", {name: this.$t('test_track.plan_view.failure'), itemStyle: {color: '#F56C6C'}}],
|
||||
["Blocking", {name: this.$t('test_track.plan_view.blocking'), itemStyle: {color: '#E6A23C'}}],
|
||||
["Skip", {name: this.$t('test_track.plan_view.skip'), itemStyle: {color: '#909399'}}],
|
||||
["Underway", {name: this.$t('test_track.plan.plan_status_running'), itemStyle: {color: 'lightskyblue'}}],
|
||||
["Prepare", {name: this.$t('test_track.plan.plan_status_prepare'), itemStyle: {color: '#DEDE10'}}]
|
||||
]),
|
||||
functionalCharData: [],
|
||||
apiCharData: [],
|
||||
scenarioCharData: [],
|
||||
isShow: true
|
||||
}
|
||||
},
|
||||
props: {
|
||||
executeResult: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
functionalResult: [
|
||||
{status: 'Pass', count: '235'},
|
||||
{status: 'Failure', count: '310'},
|
||||
{status: 'Blocking', count: '274'},
|
||||
{status: 'Skip', count: '335'},
|
||||
{status: 'Underway', count: '245'},
|
||||
{status: 'Prepare', count: '265'},
|
||||
],
|
||||
apiResult: [
|
||||
{status: 'Pass', count: '235'},
|
||||
{status: 'Failure', count: '310'},
|
||||
{status: 'Underway', count: '245'},
|
||||
],
|
||||
scenarioResult: [
|
||||
{status: 'Pass', count: '205'},
|
||||
{status: 'Failure', count: '350'},
|
||||
{status: 'Underway', count: '110'},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showFunctional() {
|
||||
return this.executeResult.functionalResult.length > 0 || (this.executeResult.apiResult.length <= 0 && this.executeResult.scenarioResult.length <= 0);
|
||||
},
|
||||
showApi() {
|
||||
return this.executeResult.apiResult.length > 0;
|
||||
},
|
||||
showScenario() {
|
||||
return this.executeResult.scenarioResult.length > 0;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
executeResult() {
|
||||
this.getCharData();
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getCharData();
|
||||
},
|
||||
methods: {
|
||||
getCharData() {
|
||||
this.getFunctionalCharData();
|
||||
this.getApiCharData();
|
||||
this.getScenarioCharData();
|
||||
this.reload();
|
||||
},
|
||||
getFunctionalCharData() {
|
||||
this.functionalCharData = [];
|
||||
if (this.executeResult.functionalResult) {
|
||||
this.executeResult.functionalResult.forEach(item => {
|
||||
let data = this.dataMap.get(item.status);
|
||||
data.value = item.count;
|
||||
this.functionalCharData.push(data);
|
||||
});
|
||||
}
|
||||
},
|
||||
getApiCharData() {
|
||||
this.apiCharData = [];
|
||||
if (this.executeResult.apiResult) {
|
||||
this.executeResult.apiResult.forEach(item => {
|
||||
let data = this.dataMap.get(item.status);
|
||||
data.value = item.count;
|
||||
this.apiCharData.push(data);
|
||||
});
|
||||
}
|
||||
},
|
||||
getScenarioCharData() {
|
||||
this.scenarioCharData = [];
|
||||
if (this.executeResult.apiResult) {
|
||||
this.executeResult.scenarioResult.forEach(item => {
|
||||
let data = this.dataMap.get(item.status);
|
||||
data.value = item.count;
|
||||
this.scenarioCharData.push(data);
|
||||
});
|
||||
}
|
||||
},
|
||||
reload() {
|
||||
this.isShow = false;
|
||||
this.$nextTick(function () {
|
||||
this.isShow = true;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.echarts {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.char-item {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.char-component {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,73 @@
|
|||
<template>
|
||||
<div class="failure-cases-list">
|
||||
<div class="failure-cases-list-header">
|
||||
接口测试用例
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
row-key="id"
|
||||
@row-click="goFailureTestCase"
|
||||
:data="apiTestCases">
|
||||
|
||||
<el-table-column prop="name" :label="$t('api_test.definition.api_name')" show-overflow-tooltip/>
|
||||
|
||||
<el-table-column
|
||||
prop="priority"
|
||||
column-key="priority"
|
||||
:label="$t('test_track.case.priority')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<priority-table-item :value="scope.row.priority"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="path"
|
||||
:label="$t('test_track.case.module')"
|
||||
show-overflow-tooltip/>
|
||||
|
||||
<el-table-column
|
||||
prop="createUser"
|
||||
:label="'创建人'"
|
||||
show-overflow-tooltip/>
|
||||
|
||||
<el-table-column prop="lastResult" :label="$t('api_test.automation.last_result')">
|
||||
<template v-slot:default="{row}">
|
||||
<ms-tag type="danger" :content="$t('test_track.plan_view.failure')"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
width="160"
|
||||
:label="$t('api_test.definition.api_last_time')"
|
||||
prop="updateTime">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StatusTableItem from "../../../../../../common/tableItems/planview/StatusTableItem";
|
||||
import MethodTableItem from "../../../../../../common/tableItems/planview/MethodTableItem";
|
||||
import TypeTableItem from "../../../../../../common/tableItems/planview/TypeTableItem";
|
||||
import PriorityTableItem from "../../../../../../common/tableItems/planview/PriorityTableItem";
|
||||
import MsTag from "../../../../../../../common/components/MsTag";
|
||||
export default {
|
||||
name: "ApiFailureCasesList",
|
||||
components: {MsTag, PriorityTableItem, TypeTableItem, MethodTableItem, StatusTableItem},
|
||||
props: ['apiTestCases'],
|
||||
methods: {
|
||||
goFailureTestCase(row) {
|
||||
this.$emit("openFailureTestCase", row);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,108 @@
|
|||
<template>
|
||||
<div class="failure-cases-list">
|
||||
<div class="failure-cases-list-header">
|
||||
功能测试用例
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
row-key="id"
|
||||
@row-click="goFailureTestCase"
|
||||
:data="functionalTestCases">
|
||||
|
||||
<el-table-column
|
||||
prop="num"
|
||||
:label="$t('commons.id')"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('commons.name')"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="priority"
|
||||
column-key="priority"
|
||||
:label="$t('test_track.case.priority')">
|
||||
<template v-slot:default="scope">
|
||||
<priority-table-item :value="scope.row.priority" ref="priority"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="type"
|
||||
column-key="type"
|
||||
:label="$t('test_track.case.type')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<type-table-item :value="scope.row.type"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="method"
|
||||
column-key="method"
|
||||
:label="$t('test_track.case.method')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<method-table-item :value="scope.row.method"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="nodePath"
|
||||
:label="$t('test_track.case.module')"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="projectName"
|
||||
:label="$t('test_track.case.project_name')"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="executorName"
|
||||
:label="$t('test_track.plan_view.executor')">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="status"
|
||||
column-key="status"
|
||||
:label="$t('test_track.plan_view.execute_result')">
|
||||
<template v-slot:default="scope">
|
||||
<status-table-item :value="scope.row.status"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="updateTime"
|
||||
:label="$t('api_test.automation.update_time')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StatusTableItem from "../../../../../../common/tableItems/planview/StatusTableItem";
|
||||
import MethodTableItem from "../../../../../../common/tableItems/planview/MethodTableItem";
|
||||
import TypeTableItem from "../../../../../../common/tableItems/planview/TypeTableItem";
|
||||
import PriorityTableItem from "../../../../../../common/tableItems/planview/PriorityTableItem";
|
||||
export default {
|
||||
name: "FunctionalFailureCasesList",
|
||||
components: {PriorityTableItem, TypeTableItem, MethodTableItem, StatusTableItem},
|
||||
props: ['functionalTestCases'],
|
||||
methods: {
|
||||
goFailureTestCase(row) {
|
||||
this.$emit("openFailureTestCase", row);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,77 @@
|
|||
<template>
|
||||
<div class="failure-cases-list">
|
||||
<div class="failure-cases-list-header">
|
||||
场景测试用例
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
row-key="id"
|
||||
@row-click="goFailureTestCase"
|
||||
:data="scenarioTestCases">
|
||||
|
||||
<el-table-column prop="name" :label="$t('api_test.automation.scenario_name')" show-overflow-tooltip/>
|
||||
|
||||
<el-table-column prop="level" :label="$t('api_test.automation.case_level')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<priority-table-item :value="scope.row.level" ref="priority"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="tags" :label="$t('api_test.automation.tag')" width="200px">
|
||||
<template v-slot:default="scope">
|
||||
<div v-for="(itemName,index) in scope.row.tags" :key="index">
|
||||
<ms-tag type="success" effect="plain" :content="itemName"/>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="modulePath"
|
||||
:label="$t('test_track.case.module')"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="stepTotal" :label="$t('api_test.automation.step')" show-overflow-tooltip/>
|
||||
|
||||
<el-table-column prop="passRate" :label="$t('api_test.automation.passing_rate')" show-overflow-tooltip/>
|
||||
|
||||
<el-table-column prop="userId" :label="$t('api_test.automation.creator')" show-overflow-tooltip/>
|
||||
|
||||
<el-table-column prop="lastResult" :label="$t('api_test.automation.last_result')">
|
||||
<template v-slot:default="{row}">
|
||||
<ms-tag type="danger" :content="$t('test_track.plan_view.failure')"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="updateTime" :label="$t('api_test.automation.update_time')" width="180">
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StatusTableItem from "../../../../../../common/tableItems/planview/StatusTableItem";
|
||||
import MethodTableItem from "../../../../../../common/tableItems/planview/MethodTableItem";
|
||||
import TypeTableItem from "../../../../../../common/tableItems/planview/TypeTableItem";
|
||||
import PriorityTableItem from "../../../../../../common/tableItems/planview/PriorityTableItem";
|
||||
import MsTag from "../../../../../../../common/components/MsTag";
|
||||
export default {
|
||||
name: "ScenarioFailureCasesList",
|
||||
components: {MsTag, PriorityTableItem, TypeTableItem, MethodTableItem, StatusTableItem},
|
||||
props: ['scenarioTestCases'],
|
||||
methods: {
|
||||
goFailureTestCase(row) {
|
||||
this.$emit("openFailureTestCase", row);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,265 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
<el-row type="flex" class="head-bar">
|
||||
<el-col :span="12">
|
||||
</el-col>
|
||||
|
||||
<el-col v-if="!reportId" :span="11" class="head-right">
|
||||
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="openTemplateReport">
|
||||
{{$t('test_track.plan_view.create_report')}}
|
||||
</el-button>
|
||||
</el-col>
|
||||
|
||||
<el-col v-else :span="11" class="head-right">
|
||||
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="handleSave">
|
||||
{{$t('commons.save')}}
|
||||
</el-button>
|
||||
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="handleEdit">
|
||||
{{$t('test_track.plan_view.edit_component')}}
|
||||
</el-button>
|
||||
<el-button :disabled="!isTestManagerOrTestUser" plain size="mini" @click="handleExport(report.name)">
|
||||
{{$t('test_track.plan_view.export_report')}}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="container" ref="resume" id="app">
|
||||
<el-main>
|
||||
<div v-for="(item, index) in previews" :key="item.id">
|
||||
<template-component :isReportView="true" :metric="metric" :preview="item" :index="index" ref="templateComponent"/>
|
||||
</div>
|
||||
</el-main>
|
||||
</div>
|
||||
|
||||
<test-report-template-list @openReport="openReport" ref="testReportTemplateList"/>
|
||||
|
||||
<ms-test-case-report-export v-if="reportExportVisible" id="testCaseReportExport" :title="report.name" :metric="metric" :previews="previews"/>
|
||||
<test-case-report-template-edit :metric="metric" ref="templateEdit" @refresh="getReport"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {checkoutTestManagerOrTestUser, exportPdf, jsonToMap, mapToJson} from "../../../../../../../../common/js/utils";
|
||||
import BaseInfoComponent from "../TemplateComponent/BaseInfoComponent";
|
||||
import TestResultChartComponent from "../TemplateComponent/TestResultChartComponent";
|
||||
import TestResultComponent from "../TemplateComponent/TestResultComponent";
|
||||
import RichTextComponent from "../TemplateComponent/RichTextComponent";
|
||||
import TestCaseReportTemplateEdit from "../TestCaseReportTemplateEdit";
|
||||
import TemplateComponent from "../TemplateComponent/TemplateComponent";
|
||||
import html2canvas from "html2canvas";
|
||||
import MsTestCaseReportExport from "../../TestCaseReportExport";
|
||||
import TestReportTemplateList from "../../TestReportTemplateList";
|
||||
|
||||
export default {
|
||||
name: "TestCaseStatisticsReportView",
|
||||
components: {
|
||||
TestReportTemplateList,
|
||||
MsTestCaseReportExport,
|
||||
TemplateComponent,
|
||||
TestCaseReportTemplateEdit,
|
||||
RichTextComponent, TestResultComponent, TestResultChartComponent, BaseInfoComponent
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
imgUrl: "",
|
||||
previews: [],
|
||||
report: {},
|
||||
metric: {},
|
||||
reportExportVisible: false,
|
||||
componentMap: new Map(
|
||||
[
|
||||
[1, {name: this.$t('test_track.plan_view.base_info'), id: 1, type: 'system'}],
|
||||
[2, {name: this.$t('test_track.plan_view.test_result'), id: 2, type: 'system'}],
|
||||
[3, {name: this.$t('test_track.plan_view.result_distribution'), id: 3, type: 'system'}],
|
||||
[4, {name: this.$t('test_track.plan_view.failure_case'), id: 4, type: 'system'}],
|
||||
[5, {name: this.$t('test_track.plan_view.defect_list'), id: 5, type: 'system'}],
|
||||
[6, {name: this.$t('test_track.plan_view.custom_component'), id: 6, type: 'custom'}]
|
||||
]
|
||||
),
|
||||
isTestManagerOrTestUser: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.isTestManagerOrTestUser = checkoutTestManagerOrTestUser();
|
||||
this.getReport();
|
||||
},
|
||||
watch: {
|
||||
reportId() {
|
||||
this.getReport();
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
planId() {
|
||||
return this.testPlan.id;
|
||||
},
|
||||
reportId() {
|
||||
return this.testPlan.reportId;
|
||||
}
|
||||
},
|
||||
props: ['testPlan'],
|
||||
methods: {
|
||||
openTemplateReport() {
|
||||
this.$refs.testReportTemplateList.open(this.planId);
|
||||
},
|
||||
openReport(planId, id) {
|
||||
this.testPlan.reportId = id;
|
||||
},
|
||||
getReport() {
|
||||
if (this.reportId) {
|
||||
this.result = this.$get('/case/report/get/' + this.reportId, response => {
|
||||
this.report = response.data;
|
||||
this.report.content = JSON.parse(response.data.content);
|
||||
if (this.report.content.customComponent) {
|
||||
this.report.content.customComponent = jsonToMap(this.report.content.customComponent);
|
||||
}
|
||||
this.getMetric();
|
||||
this.initPreviews();
|
||||
});
|
||||
}
|
||||
},
|
||||
initPreviews() {
|
||||
this.previews = [];
|
||||
this.report.content.components.forEach(item => {
|
||||
let preview = this.componentMap.get(item);
|
||||
if (preview && preview.type != 'custom') {
|
||||
this.previews.push(preview);
|
||||
} else {
|
||||
if (this.report.content.customComponent) {
|
||||
let customComponent = this.report.content.customComponent.get(item.toString());
|
||||
if (customComponent) {
|
||||
this.previews.push({id: item, title: customComponent.title, content: customComponent.content});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleEdit() {
|
||||
this.$refs.templateEdit.open(this.reportId, true);
|
||||
},
|
||||
handleSave() {
|
||||
let param = {};
|
||||
this.buildParam(param);
|
||||
this.result = this.$post('/case/report/edit', param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
});
|
||||
},
|
||||
buildParam(param) {
|
||||
let content = {};
|
||||
content.components = [];
|
||||
this.previews.forEach(item => {
|
||||
content.components.push(item.id);
|
||||
if (!this.componentMap.get(item.id)) {
|
||||
content.customComponent = new Map();
|
||||
content.customComponent.set(item.id, {title: item.title, content: item.content})
|
||||
}
|
||||
});
|
||||
param.name = this.report.name;
|
||||
if (content.customComponent) {
|
||||
content.customComponent = mapToJson(content.customComponent);
|
||||
}
|
||||
param.content = JSON.stringify(content);
|
||||
param.id = this.report.id;
|
||||
if (this.metric.startTime) {
|
||||
param.startTime = this.metric.startTime.getTime();
|
||||
}
|
||||
if (this.metric.endTime) {
|
||||
param.endTime = this.metric.endTime.getTime();
|
||||
}
|
||||
},
|
||||
getMetric() {
|
||||
this.result = this.$get('/test/plan/get/statistics/metric/' + this.planId, response => {
|
||||
this.metric = response.data;
|
||||
|
||||
if (!this.metric.failureTestCases) {
|
||||
this.metric.failureTestCases = [];
|
||||
}
|
||||
if (!this.metric.executeResult) {
|
||||
this.metric.executeResult = [];
|
||||
}
|
||||
if (!this.metric.moduleExecuteResult) {
|
||||
this.metric.moduleExecuteResult = [];
|
||||
}
|
||||
/*缺陷列表*/
|
||||
if (!this.metric.issues) {
|
||||
this.metric.issues = [];
|
||||
}
|
||||
|
||||
|
||||
if (this.report.startTime) {
|
||||
this.metric.startTime = new Date(this.report.startTime);
|
||||
}
|
||||
if (this.report.endTime) {
|
||||
this.metric.endTime = new Date(this.report.endTime);
|
||||
}
|
||||
});
|
||||
},
|
||||
handleExport(name) {
|
||||
this.result.loading = true;
|
||||
this.reportExportVisible = true;
|
||||
let reset = this.exportReportReset;
|
||||
|
||||
this.$nextTick(function () {
|
||||
setTimeout(() => {
|
||||
html2canvas(document.getElementById('testCaseReportExport'), {
|
||||
scale: 2
|
||||
}).then(function(canvas) {
|
||||
exportPdf(name, [canvas]);
|
||||
reset();
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
exportReportReset() {
|
||||
this.reportExportVisible = false;
|
||||
this.result.loading = false;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>cd
|
||||
|
||||
<style scoped>
|
||||
|
||||
.el-main {
|
||||
height: calc(100vh - 70px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.head-bar {
|
||||
/*background: white;*/
|
||||
/*height: 45px;*/
|
||||
/*line-height: 45px;*/
|
||||
/*padding-left: 10px;*/
|
||||
/*padding: 0 10px;*/
|
||||
/*border: 1px solid #EBEEF5;*/
|
||||
/*box-shadow: 0 0 2px 0 rgba(31, 31, 31, 0.15), 0 1px 2px 0 rgba(31, 31, 31, 0.15);*/
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100vh;
|
||||
/*background: #F5F5F5;*/
|
||||
}
|
||||
|
||||
.el-card {
|
||||
width: 70%;
|
||||
margin: 5px auto;
|
||||
}
|
||||
|
||||
.head-right {
|
||||
text-align: right;
|
||||
|
||||
}
|
||||
|
||||
.head-bar .el-button {
|
||||
margin-bottom: 10px;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.head-bar {
|
||||
position: fixed;
|
||||
right: 10px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
Loading…
Reference in New Issue