feat: UI报告处理
This commit is contained in:
parent
a974dafb81
commit
9c222f0aea
|
@ -16,4 +16,5 @@ public class ApiScenarioReportBaseInfoDTO {
|
||||||
private long reqStartTime;
|
private long reqStartTime;
|
||||||
private String rspCode;
|
private String rspCode;
|
||||||
private long rspTime;
|
private long rspTime;
|
||||||
|
private String uiImg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,8 @@ import java.util.Map;
|
||||||
@Setter
|
@Setter
|
||||||
public class RequestResultExpandDTO extends RequestResult {
|
public class RequestResultExpandDTO extends RequestResult {
|
||||||
private String status;
|
private String status;
|
||||||
|
private String uiImg;
|
||||||
|
private long time;
|
||||||
private Map<String, String> attachInfoMap;
|
private Map<String, String> attachInfoMap;
|
||||||
|
|
||||||
public RequestResultExpandDTO() {
|
public RequestResultExpandDTO() {
|
||||||
|
@ -27,6 +29,9 @@ public class RequestResultExpandDTO extends RequestResult {
|
||||||
this.setSuccess(dto.isReqSuccess());
|
this.setSuccess(dto.isReqSuccess());
|
||||||
this.setError(dto.getReqError());
|
this.setError(dto.getReqError());
|
||||||
this.setStartTime(dto.getReqStartTime());
|
this.setStartTime(dto.getReqStartTime());
|
||||||
|
this.setTime(dto.getRspTime());
|
||||||
|
this.setEndTime(dto.getRspTime() - dto.getReqStartTime());
|
||||||
|
this.setUiImg(dto.getUiImg());
|
||||||
ResponseResult responseResult = this.getResponseResult();
|
ResponseResult responseResult = this.getResponseResult();
|
||||||
responseResult.setResponseCode(dto.getRspCode());
|
responseResult.setResponseCode(dto.getRspCode());
|
||||||
responseResult.setResponseTime(dto.getRspTime());
|
responseResult.setResponseTime(dto.getRspTime());
|
||||||
|
|
|
@ -10,6 +10,8 @@ import java.util.List;
|
||||||
@Data
|
@Data
|
||||||
public class StepTreeDTO {
|
public class StepTreeDTO {
|
||||||
private String type;
|
private String type;
|
||||||
|
// ui 指令的类型
|
||||||
|
private String cmdType;
|
||||||
private int index;
|
private int index;
|
||||||
private String resourceId;
|
private String resourceId;
|
||||||
private String label;
|
private String label;
|
||||||
|
|
|
@ -93,6 +93,19 @@ public class ApiScenarioReportResultService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApiScenarioReportResultWithBLOBs newUiScenarioReportResult(String reportId, String resourceId, JSONObject value) {
|
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();
|
ApiScenarioReportResultWithBLOBs report = new ApiScenarioReportResultWithBLOBs();
|
||||||
report.setId(UUID.randomUUID().toString());
|
report.setId(UUID.randomUUID().toString());
|
||||||
report.setResourceId(resourceId);
|
report.setResourceId(resourceId);
|
||||||
|
@ -100,33 +113,11 @@ public class ApiScenarioReportResultService {
|
||||||
report.setTotalAssertions(0L);
|
report.setTotalAssertions(0L);
|
||||||
report.setPassAssertions(0L);
|
report.setPassAssertions(0L);
|
||||||
report.setCreateTime(System.currentTimeMillis());
|
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;
|
return report;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ApiScenarioReportResultWithBLOBs newApiScenarioReportResult(String reportId, RequestResult baseResult) {
|
//记录基础信息
|
||||||
ApiScenarioReportResultWithBLOBs report = new ApiScenarioReportResultWithBLOBs();
|
private ApiScenarioReportBaseInfoDTO getBaseInfo(RequestResult result) {
|
||||||
//解析误报内容
|
|
||||||
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());
|
|
||||||
|
|
||||||
//记录基础信息
|
|
||||||
ApiScenarioReportBaseInfoDTO baseInfoDTO = new ApiScenarioReportBaseInfoDTO();
|
ApiScenarioReportBaseInfoDTO baseInfoDTO = new ApiScenarioReportBaseInfoDTO();
|
||||||
baseInfoDTO.setReqName(result.getName());
|
baseInfoDTO.setReqName(result.getName());
|
||||||
baseInfoDTO.setReqSuccess(result.isSuccess());
|
baseInfoDTO.setReqSuccess(result.isSuccess());
|
||||||
|
@ -136,7 +127,27 @@ public class ApiScenarioReportResultService {
|
||||||
baseInfoDTO.setRspCode(result.getResponseResult().getResponseCode());
|
baseInfoDTO.setRspCode(result.getResponseResult().getResponseCode());
|
||||||
baseInfoDTO.setRspTime(result.getResponseResult().getResponseTime());
|
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));
|
report.setContent(JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8));
|
||||||
return report;
|
return report;
|
||||||
}
|
}
|
||||||
|
@ -156,16 +167,7 @@ public class ApiScenarioReportResultService {
|
||||||
try {
|
try {
|
||||||
RequestResult requestResult = JSON.parseObject(new String(baseResult.getContent(), StandardCharsets.UTF_8), RequestResult.class);
|
RequestResult requestResult = JSON.parseObject(new String(baseResult.getContent(), StandardCharsets.UTF_8), RequestResult.class);
|
||||||
//记录基础信息
|
//记录基础信息
|
||||||
ApiScenarioReportBaseInfoDTO baseInfo = new ApiScenarioReportBaseInfoDTO();
|
baseResult.setBaseInfo(JSONObject.toJSONString(getBaseInfo(requestResult)));
|
||||||
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));
|
|
||||||
apiScenarioReportResultMapper.updateByPrimaryKeySelective(baseResult);
|
apiScenarioReportResultMapper.updateByPrimaryKeySelective(baseResult);
|
||||||
return baseResult;
|
return baseResult;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import io.metersphere.commons.utils.LogUtil;
|
||||||
import io.metersphere.constants.RunModeConstants;
|
import io.metersphere.constants.RunModeConstants;
|
||||||
import io.metersphere.dto.RequestResult;
|
import io.metersphere.dto.RequestResult;
|
||||||
import io.metersphere.utils.LoggerUtil;
|
import io.metersphere.utils.LoggerUtil;
|
||||||
|
import io.metersphere.commons.constants.CommandType;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -176,6 +177,7 @@ public class ApiScenarioReportStructureService {
|
||||||
children.setAllIndex("" + (children.getIndex() == 0 ? (i + 1) : children.getIndex()));
|
children.setAllIndex("" + (children.getIndex() == 0 ? (i + 1) : children.getIndex()));
|
||||||
children.setResourceId(resourceId + "_" + children.getAllIndex());
|
children.setResourceId(resourceId + "_" + children.getAllIndex());
|
||||||
}
|
}
|
||||||
|
children.setCmdType(element.getString("commandType"));
|
||||||
dto.getChildren().add(children);
|
dto.getChildren().add(children);
|
||||||
if (element.containsKey("hashTree") && !requests.contains(children.getType())) {
|
if (element.containsKey("hashTree") && !requests.contains(children.getType())) {
|
||||||
JSONArray elementJSONArray = element.getJSONArray("hashTree");
|
JSONArray elementJSONArray = element.getJSONArray("hashTree");
|
||||||
|
@ -307,7 +309,7 @@ public class ApiScenarioReportStructureService {
|
||||||
dto.setErrorCode(reportResults.get(0).getErrorCode());
|
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 requestResultExpandDTO = new RequestResultExpandDTO();
|
||||||
requestResultExpandDTO.setStatus("unexecute");
|
requestResultExpandDTO.setStatus("unexecute");
|
||||||
requestResultExpandDTO.setName(dto.getLabel());
|
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<ApiDefinitionExecResultVo> formatApiReport(String reportId, List<StepTreeDTO> stepList) {
|
private List<ApiDefinitionExecResultVo> formatApiReport(String reportId, List<StepTreeDTO> stepList) {
|
||||||
ApiDefinitionExecResultExample example = new ApiDefinitionExecResultExample();
|
ApiDefinitionExecResultExample example = new ApiDefinitionExecResultExample();
|
||||||
example.createCriteria().andIntegratedReportIdEqualTo(reportId);
|
example.createCriteria().andIntegratedReportIdEqualTo(reportId);
|
||||||
|
|
|
@ -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";
|
||||||
|
}
|
|
@ -13,14 +13,19 @@
|
||||||
<div>
|
<div>
|
||||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||||
<el-tab-pane :label="$t('api_report.total')" name="total">
|
<el-tab-pane :label="$t('api_report.total')" name="total">
|
||||||
<ms-scenario-results :treeData="fullTreeNodes" :console="content.console"
|
<ms-scenario-results :treeData="fullTreeNodes"
|
||||||
v-on:requestResult="requestResult" ref="resultsTree"/>
|
:console="content.console"
|
||||||
|
:report="report"
|
||||||
|
v-on:requestResult="requestResult"
|
||||||
|
ref="resultsTree"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane name="fail">
|
<el-tab-pane name="fail">
|
||||||
<template slot="label">
|
<template slot="label">
|
||||||
<span class="fail">{{ $t('api_report.fail') }}</span>
|
<span class="fail">{{ $t('api_report.fail') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<ms-scenario-results v-on:requestResult="requestResult" :console="content.console"
|
<ms-scenario-results v-on:requestResult="requestResult"
|
||||||
|
:console="content.console"
|
||||||
|
:report="report"
|
||||||
:treeData="fullTreeNodes" ref="failsTree"
|
:treeData="fullTreeNodes" ref="failsTree"
|
||||||
:errorReport="content.error"/>
|
:errorReport="content.error"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
@ -28,14 +33,18 @@
|
||||||
<template slot="label">
|
<template slot="label">
|
||||||
<span class="fail" style="color: #F6972A">{{ $t('error_report_library.option.name') }}</span>
|
<span class="fail" style="color: #F6972A">{{ $t('error_report_library.option.name') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<ms-scenario-results v-on:requestResult="requestResult" :console="content.console"
|
<ms-scenario-results v-on:requestResult="requestResult"
|
||||||
|
:report="report"
|
||||||
|
:console="content.console"
|
||||||
:treeData="fullTreeNodes" ref="errorReportTree"/>
|
:treeData="fullTreeNodes" ref="errorReportTree"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane name="unExecute" v-if="content.unExecute > 0">
|
<el-tab-pane name="unExecute" v-if="content.unExecute > 0">
|
||||||
<template slot="label">
|
<template slot="label">
|
||||||
<span class="fail" style="color: #9C9B9A">{{ $t('api_test.home_page.detail_card.unexecute') }}</span>
|
<span class="fail" style="color: #9C9B9A">{{ $t('api_test.home_page.detail_card.unexecute') }}</span>
|
||||||
</template>
|
</template>
|
||||||
<ms-scenario-results v-on:requestResult="requestResult" :console="content.console"
|
<ms-scenario-results v-on:requestResult="requestResult"
|
||||||
|
:report="report"
|
||||||
|
:console="content.console"
|
||||||
:treeData="fullTreeNodes" ref="unExecuteTree"/>
|
:treeData="fullTreeNodes" ref="unExecuteTree"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane name="console">
|
<el-tab-pane name="console">
|
||||||
|
|
|
@ -33,6 +33,7 @@ export default {
|
||||||
treeData: Array,
|
treeData: Array,
|
||||||
console: String,
|
console: String,
|
||||||
errorReport: Number,
|
errorReport: Number,
|
||||||
|
report: Object,
|
||||||
defaultExpand: {
|
defaultExpand: {
|
||||||
default: false,
|
default: false,
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="3">
|
<el-col :span="3">
|
||||||
<span v-if="!isUnexecute" :style="!result.success ? 'color: #FE6F71' : ''">
|
<span v-if="!isUnexecute" :style="result && !result.success ? 'color: #FE6F71' : ''">
|
||||||
{{ result.endTime - result.startTime }} ms
|
{{ result.time }} ms
|
||||||
</span>
|
</span>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@
|
||||||
v-if="!isUnexecute">
|
v-if="!isUnexecute">
|
||||||
<el-image
|
<el-image
|
||||||
style="width: 100px; height: 100px"
|
style="width: 100px; height: 100px"
|
||||||
:src="'/resource/ui/get?fileName=' + result.url"
|
:src="'/resource/ui/get?fileName=' + result.uiImg"
|
||||||
:preview-src-list="['/resource/ui/get?fileName=' + result.url]">
|
:preview-src-list="['/resource/ui/get?fileName=' + result.uiImg]">
|
||||||
</el-image>
|
</el-image>
|
||||||
<el-button slot="reference" type="text">{{ $t('截图') }}</el-button>
|
<el-button slot="reference" type="text">{{ $t('截图') }}</el-button>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<el-tag size="mini" v-if="isUnexecute">
|
<el-tag size="mini" v-if="isUnexecute">
|
||||||
{{ $t('api_test.home_page.detail_card.unexecute') }}
|
{{ $t('api_test.home_page.detail_card.unexecute') }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag size="mini" type="success" v-else-if="result.success">
|
<el-tag size="mini" type="success" v-else-if="result && result.success">
|
||||||
{{ $t('api_report.success') }}
|
{{ $t('api_report.success') }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tooltip v-else :content="result.body" placement="top">
|
<el-tooltip v-else :content="result.body" placement="top">
|
||||||
|
@ -70,7 +70,7 @@ export default {
|
||||||
return this.command.label;
|
return this.command.label;
|
||||||
},
|
},
|
||||||
isUnexecute() {
|
isUnexecute() {
|
||||||
return this.result && this.result.status === 'unexecute';
|
return !this.result || this.result.status === 'unexecute';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
Loading…
Reference in New Issue