diff --git a/backend/src/main/java/io/metersphere/api/dto/ApiScenarioReportBaseInfoDTO.java b/backend/src/main/java/io/metersphere/api/dto/ApiScenarioReportBaseInfoDTO.java index e01bd72a6f..3d2335b75d 100644 --- a/backend/src/main/java/io/metersphere/api/dto/ApiScenarioReportBaseInfoDTO.java +++ b/backend/src/main/java/io/metersphere/api/dto/ApiScenarioReportBaseInfoDTO.java @@ -16,4 +16,5 @@ public class ApiScenarioReportBaseInfoDTO { private long reqStartTime; private String rspCode; private long rspTime; + private String uiImg; } diff --git a/backend/src/main/java/io/metersphere/api/dto/RequestResultExpandDTO.java b/backend/src/main/java/io/metersphere/api/dto/RequestResultExpandDTO.java index 6c879d5921..7814273d30 100644 --- a/backend/src/main/java/io/metersphere/api/dto/RequestResultExpandDTO.java +++ b/backend/src/main/java/io/metersphere/api/dto/RequestResultExpandDTO.java @@ -14,6 +14,8 @@ import java.util.Map; @Setter public class RequestResultExpandDTO extends RequestResult { private String status; + private String uiImg; + private long time; private Map attachInfoMap; public RequestResultExpandDTO() { @@ -27,6 +29,9 @@ public class RequestResultExpandDTO extends RequestResult { this.setSuccess(dto.isReqSuccess()); this.setError(dto.getReqError()); this.setStartTime(dto.getReqStartTime()); + this.setTime(dto.getRspTime()); + this.setEndTime(dto.getRspTime() - dto.getReqStartTime()); + this.setUiImg(dto.getUiImg()); ResponseResult responseResult = this.getResponseResult(); responseResult.setResponseCode(dto.getRspCode()); responseResult.setResponseTime(dto.getRspTime()); diff --git a/backend/src/main/java/io/metersphere/api/dto/StepTreeDTO.java b/backend/src/main/java/io/metersphere/api/dto/StepTreeDTO.java index 56b5809f3a..ded076f423 100644 --- a/backend/src/main/java/io/metersphere/api/dto/StepTreeDTO.java +++ b/backend/src/main/java/io/metersphere/api/dto/StepTreeDTO.java @@ -10,6 +10,8 @@ import java.util.List; @Data public class StepTreeDTO { private String type; + // ui 指令的类型 + private String cmdType; private int index; private String resourceId; private String label; diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportResultService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportResultService.java index 34edcbbc71..a1b0d24baf 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportResultService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportResultService.java @@ -93,6 +93,19 @@ public class ApiScenarioReportResultService { } private ApiScenarioReportResultWithBLOBs newUiScenarioReportResult(String reportId, String resourceId, JSONObject value) { + ApiScenarioReportResultWithBLOBs report = newScenarioReportResult(reportId, resourceId); + String status = value.getBooleanValue("success") ? ExecuteResult.Success.name() : ExecuteResult.Error.name(); + report.setStatus(status); + RequestResult result = JSONObject.parseObject(value.toJSONString(), RequestResult.class); + ApiScenarioReportBaseInfoDTO baseInfo = getBaseInfo(result); + baseInfo.setRspTime(result.getEndTime() - result.getStartTime()); + baseInfo.setUiImg(result.getUrl()); + report.setBaseInfo(JSONObject.toJSONString(baseInfo)); + report.setContent(value.toJSONString().getBytes(StandardCharsets.UTF_8)); + return report; + } + + private ApiScenarioReportResultWithBLOBs newScenarioReportResult(String reportId, String resourceId) { ApiScenarioReportResultWithBLOBs report = new ApiScenarioReportResultWithBLOBs(); report.setId(UUID.randomUUID().toString()); report.setResourceId(resourceId); @@ -100,33 +113,11 @@ public class ApiScenarioReportResultService { report.setTotalAssertions(0L); report.setPassAssertions(0L); report.setCreateTime(System.currentTimeMillis()); - String status = value.getBooleanValue("success") ? ExecuteResult.Success.name() : ExecuteResult.Error.name(); - report.setStatus(status); - report.setContent(value.toJSONString().getBytes(StandardCharsets.UTF_8)); return report; } - private ApiScenarioReportResultWithBLOBs newApiScenarioReportResult(String reportId, RequestResult baseResult) { - ApiScenarioReportResultWithBLOBs report = new ApiScenarioReportResultWithBLOBs(); - //解析误报内容 - ErrorReportLibraryParseDTO errorCodeDTO = ErrorReportLibraryUtil.parseAssertions(baseResult); - RequestResult result = errorCodeDTO.getResult(); - report.setId(UUID.randomUUID().toString()); - String resourceId = result.getResourceId(); - report.setResourceId(resourceId); - report.setReportId(reportId); - report.setTotalAssertions(Long.parseLong(result.getTotalAssertions() + "")); - report.setPassAssertions(Long.parseLong(result.getPassAssertions() + "")); - report.setCreateTime(System.currentTimeMillis()); - String status = result.getError() == 0 ? ExecuteResult.Success.name() : ExecuteResult.Error.name(); - if (CollectionUtils.isNotEmpty(errorCodeDTO.getErrorCodeList())) { - status = ExecuteResult.errorReportResult.name(); - report.setErrorCode(errorCodeDTO.getErrorCodeStr()); - } - report.setStatus(status); - report.setRequestTime(result.getEndTime() - result.getStartTime()); - - //记录基础信息 + //记录基础信息 + private ApiScenarioReportBaseInfoDTO getBaseInfo(RequestResult result) { ApiScenarioReportBaseInfoDTO baseInfoDTO = new ApiScenarioReportBaseInfoDTO(); baseInfoDTO.setReqName(result.getName()); baseInfoDTO.setReqSuccess(result.isSuccess()); @@ -136,7 +127,27 @@ public class ApiScenarioReportResultService { baseInfoDTO.setRspCode(result.getResponseResult().getResponseCode()); baseInfoDTO.setRspTime(result.getResponseResult().getResponseTime()); } - report.setBaseInfo(JSONObject.toJSONString(baseInfoDTO)); + return baseInfoDTO; + } + + private ApiScenarioReportResultWithBLOBs newApiScenarioReportResult(String reportId, RequestResult baseResult) { + //解析误报内容 + ErrorReportLibraryParseDTO errorCodeDTO = ErrorReportLibraryUtil.parseAssertions(baseResult); + RequestResult result = errorCodeDTO.getResult(); + String resourceId = result.getResourceId(); + + ApiScenarioReportResultWithBLOBs report = newScenarioReportResult(reportId, resourceId); + report.setTotalAssertions(Long.parseLong(result.getTotalAssertions() + "")); + report.setPassAssertions(Long.parseLong(result.getPassAssertions() + "")); + String status = result.getError() == 0 ? ExecuteResult.Success.name() : ExecuteResult.Error.name(); + if (CollectionUtils.isNotEmpty(errorCodeDTO.getErrorCodeList())) { + status = ExecuteResult.errorReportResult.name(); + report.setErrorCode(errorCodeDTO.getErrorCodeStr()); + } + report.setStatus(status); + report.setRequestTime(result.getEndTime() - result.getStartTime()); + + report.setBaseInfo(JSONObject.toJSONString(getBaseInfo(result))); report.setContent(JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8)); return report; } @@ -156,16 +167,7 @@ public class ApiScenarioReportResultService { try { RequestResult requestResult = JSON.parseObject(new String(baseResult.getContent(), StandardCharsets.UTF_8), RequestResult.class); //记录基础信息 - ApiScenarioReportBaseInfoDTO baseInfo = new ApiScenarioReportBaseInfoDTO(); - baseInfo.setReqName(StringUtils.isEmpty(requestResult.getName()) ? "" : requestResult.getName()); - baseInfo.setReqSuccess(requestResult.isSuccess()); - baseInfo.setReqError(requestResult.getError()); - baseInfo.setReqStartTime(requestResult.getStartTime()); - if (requestResult.getResponseResult() != null) { - baseInfo.setRspCode(requestResult.getResponseResult().getResponseCode()); - baseInfo.setRspTime(requestResult.getResponseResult().getResponseTime()); - } - baseResult.setBaseInfo(JSONObject.toJSONString(baseInfo)); + baseResult.setBaseInfo(JSONObject.toJSONString(getBaseInfo(requestResult))); apiScenarioReportResultMapper.updateByPrimaryKeySelective(baseResult); return baseResult; } catch (Exception e) { diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportStructureService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportStructureService.java index b0478d8343..32e15ad708 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportStructureService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportStructureService.java @@ -20,6 +20,7 @@ import io.metersphere.commons.utils.LogUtil; import io.metersphere.constants.RunModeConstants; import io.metersphere.dto.RequestResult; import io.metersphere.utils.LoggerUtil; +import io.metersphere.commons.constants.CommandType; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; @@ -176,6 +177,7 @@ public class ApiScenarioReportStructureService { children.setAllIndex("" + (children.getIndex() == 0 ? (i + 1) : children.getIndex())); children.setResourceId(resourceId + "_" + children.getAllIndex()); } + children.setCmdType(element.getString("commandType")); dto.getChildren().add(children); if (element.containsKey("hashTree") && !requests.contains(children.getType())) { JSONArray elementJSONArray = element.getJSONArray("hashTree"); @@ -307,7 +309,7 @@ public class ApiScenarioReportStructureService { dto.setErrorCode(reportResults.get(0).getErrorCode()); } } - if (StringUtils.isNotEmpty(dto.getType()) && requests.contains(dto.getType()) && dto.getValue() == null) { + if (StringUtils.isNotEmpty(dto.getType()) && requests.contains(dto.getType()) && dto.getValue() == null || isUiUnExecuteCommand(dto)) { RequestResultExpandDTO requestResultExpandDTO = new RequestResultExpandDTO(); requestResultExpandDTO.setStatus("unexecute"); requestResultExpandDTO.setName(dto.getLabel()); @@ -415,6 +417,14 @@ public class ApiScenarioReportStructureService { } } + private boolean isUiUnExecuteCommand(StepTreeDTO dto) { + if (dto.getType().equals("MsUiCommand") && dto.getValue() == null + && (StringUtils.isBlank(dto.getCmdType()) || !dto.getCmdType().equalsIgnoreCase(CommandType.COMMAND_TYPE_COMBINATION))) { + return true; + } + return false; + } + private List formatApiReport(String reportId, List stepList) { ApiDefinitionExecResultExample example = new ApiDefinitionExecResultExample(); example.createCriteria().andIntegratedReportIdEqualTo(reportId); diff --git a/backend/src/main/java/io/metersphere/commons/constants/CommandType.java b/backend/src/main/java/io/metersphere/commons/constants/CommandType.java new file mode 100644 index 0000000000..cb548e2403 --- /dev/null +++ b/backend/src/main/java/io/metersphere/commons/constants/CommandType.java @@ -0,0 +1,12 @@ +package io.metersphere.commons.constants; + +/** + * atomic 原子指令,前端 后端 一对一 + * combine 前端指令包含了多个指令实现 比如 IF 指令,if 指令必须有 start 和 end + * proxy 前端指令使用了代理模式 比如前端选择等待元素指令,实际上还有一个子类别具体选择,waitForElement 还是 waitForEditable + */ +public class CommandType { + public static final String COMMAND_TYPE_ATOM = "atom"; + public static final String COMMAND_TYPE_COMBINATION = "combination"; + public static final String COMMAND_TYPE_PROXY = "proxy"; +} diff --git a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue index 328a7f5795..47d1c99e61 100644 --- a/frontend/src/business/components/api/automation/report/ApiReportDetail.vue +++ b/frontend/src/business/components/api/automation/report/ApiReportDetail.vue @@ -13,14 +13,19 @@
- + - @@ -28,14 +33,18 @@ - - diff --git a/frontend/src/business/components/api/automation/report/components/ScenarioResults.vue b/frontend/src/business/components/api/automation/report/components/ScenarioResults.vue index 3da8a7f4f1..bbebfe17f0 100644 --- a/frontend/src/business/components/api/automation/report/components/ScenarioResults.vue +++ b/frontend/src/business/components/api/automation/report/components/ScenarioResults.vue @@ -33,6 +33,7 @@ export default { treeData: Array, console: String, errorReport: Number, + report: Object, defaultExpand: { default: false, type: Boolean, diff --git a/frontend/src/business/components/api/automation/report/components/UiCommandResult.vue b/frontend/src/business/components/api/automation/report/components/UiCommandResult.vue index 101dcc746c..095cf713af 100644 --- a/frontend/src/business/components/api/automation/report/components/UiCommandResult.vue +++ b/frontend/src/business/components/api/automation/report/components/UiCommandResult.vue @@ -13,8 +13,8 @@ - - {{ result.endTime - result.startTime }} ms + + {{ result.time }} ms @@ -26,8 +26,8 @@ v-if="!isUnexecute"> + :src="'/resource/ui/get?fileName=' + result.uiImg" + :preview-src-list="['/resource/ui/get?fileName=' + result.uiImg]"> {{ $t('截图') }} @@ -38,7 +38,7 @@ {{ $t('api_test.home_page.detail_card.unexecute') }} - + {{ $t('api_report.success') }} @@ -70,7 +70,7 @@ export default { return this.command.label; }, isUnexecute() { - return this.result && this.result.status === 'unexecute'; + return !this.result || this.result.status === 'unexecute'; } }, data() {