From addbe3ecd441daf540f5dfbeb1de9e2492e057c7 Mon Sep 17 00:00:00 2001 From: FBODC Date: Fri, 25 Apr 2025 10:21:50 +0800 Subject: [PATCH] =?UTF-8?q?UI=E6=8A=A5=E5=91=8A=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/test/common/utils/DateUtils.java | 46 +++ .../com/test/common/utils/SeleniumUtils.java | 1 - .../controller/UiAutomationController.java | 41 +- .../test/controller/UiReportController.java | 73 ++++ .../java/com/test/test/domain/UiReport.java | 290 ++++++++++++++ .../com/test/test/domain/UiSceneSteps.java | 24 ++ .../test/test/domain/UiSceneStepsReport.java | 167 +++++++++ .../test/test/domain/qo/UiSceneStepsQO.java | 7 + .../com/test/test/domain/vo/UiReportVO.java | 69 ++++ .../test/domain/vo/UiSceneStepsReportVO.java | 48 +++ .../test/test/domain/vo/UiSceneStepsVO.java | 7 + .../com/test/test/mapper/UiReportMapper.java | 62 +++ .../test/mapper/UiSceneStepsReportMapper.java | 62 +++ .../test/service/IUiAutomationService.java | 8 + .../test/test/service/IUiReportService.java | 64 ++++ .../test/service/IUiSceneStepsService.java | 48 +-- .../com/test/test/service/StepExecution.java | 15 + .../service/impl/UiAutomationServiceImpl.java | 47 ++- .../service/impl/UiReportServiceImpl.java | 151 ++++++++ .../service/impl/UiSceneStepsServiceImpl.java | 354 +++++++++++++++--- .../resources/mapper/test/UiReportMapper.xml | 159 ++++++++ .../mapper/test/UiSceneStepsMapper.xml | 153 +++++--- .../mapper/test/UiSceneStepsReportMapper.xml | 131 +++++++ 23 files changed, 1847 insertions(+), 180 deletions(-) create mode 100644 test-test/src/main/java/com/test/test/controller/UiReportController.java create mode 100644 test-test/src/main/java/com/test/test/domain/UiReport.java create mode 100644 test-test/src/main/java/com/test/test/domain/UiSceneStepsReport.java create mode 100644 test-test/src/main/java/com/test/test/domain/vo/UiReportVO.java create mode 100644 test-test/src/main/java/com/test/test/domain/vo/UiSceneStepsReportVO.java create mode 100644 test-test/src/main/java/com/test/test/mapper/UiReportMapper.java create mode 100644 test-test/src/main/java/com/test/test/mapper/UiSceneStepsReportMapper.java create mode 100644 test-test/src/main/java/com/test/test/service/IUiReportService.java create mode 100644 test-test/src/main/java/com/test/test/service/StepExecution.java create mode 100644 test-test/src/main/java/com/test/test/service/impl/UiReportServiceImpl.java create mode 100644 test-test/src/main/resources/mapper/test/UiReportMapper.xml create mode 100644 test-test/src/main/resources/mapper/test/UiSceneStepsReportMapper.xml diff --git a/test-common/src/main/java/com/test/common/utils/DateUtils.java b/test-common/src/main/java/com/test/common/utils/DateUtils.java index dc834ff..818476c 100644 --- a/test-common/src/main/java/com/test/common/utils/DateUtils.java +++ b/test-common/src/main/java/com/test/common/utils/DateUtils.java @@ -186,4 +186,50 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault()); return Date.from(zdt.toInstant()); } + + public static String calculateTimeDifference(Date startTime, Date endTime) { + long diffInMillis = endTime.getTime() - startTime.getTime(); // 获取时间差(毫秒) + long totalSeconds = diffInMillis / 1000; // 转换为秒 + long totalMinutes = totalSeconds / 60; // 转换为分钟 + long totalHours = totalMinutes / 60; // 转换为小时 + + StringBuilder result = new StringBuilder(); + + // 如果时间差超过1小时 + if (totalHours > 0) { + result.append(totalHours).append("h"); + long remainingMinutes = totalMinutes % 60; // 剩余的分钟 + if (remainingMinutes > 0) { + result.append(remainingMinutes).append("min"); + } + long remainingSeconds = totalSeconds % 60; // 剩余的秒 + if (remainingSeconds > 0) { + result.append(remainingSeconds).append("s"); + } + } else if (totalMinutes > 0) { // 如果时间差在1分钟到1小时之间 + result.append(totalMinutes).append("min"); + long remainingSeconds = totalSeconds % 60; // 剩余的秒 + if (remainingSeconds > 0) { + result.append(remainingSeconds).append("s"); + } + } else { // 如果时间差小于1分钟 + result.append(totalSeconds).append("s"); + } + + return result.toString(); + } + + /** + * 计算两个时间点的时间差(单位为毫秒) + * + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 时间差(单位为毫秒) + */ + public static long differenceInMilliseconds(Date startTime, Date endTime) { + if (startTime == null || endTime == null) { + throw new IllegalArgumentException("开始时间和结束时间不能为空"); + } + return endTime.getTime() - startTime.getTime(); + } } diff --git a/test-common/src/main/java/com/test/common/utils/SeleniumUtils.java b/test-common/src/main/java/com/test/common/utils/SeleniumUtils.java index 1bb6472..0a0ecf8 100644 --- a/test-common/src/main/java/com/test/common/utils/SeleniumUtils.java +++ b/test-common/src/main/java/com/test/common/utils/SeleniumUtils.java @@ -25,7 +25,6 @@ public class SeleniumUtils { this.wait = new WebDriverWait(driver, Duration.ofSeconds(10)); this.actions = new Actions(driver); } - // 设置显式等待超时时间 public void setWaitTimeout(long seconds) { this.wait = new WebDriverWait(driver, Duration.ofSeconds(seconds)); diff --git a/test-test/src/main/java/com/test/test/controller/UiAutomationController.java b/test-test/src/main/java/com/test/test/controller/UiAutomationController.java index feaf040..601b580 100644 --- a/test-test/src/main/java/com/test/test/controller/UiAutomationController.java +++ b/test-test/src/main/java/com/test/test/controller/UiAutomationController.java @@ -6,15 +6,10 @@ import com.test.test.domain.UiAutomation; import com.test.test.domain.qo.UiAutomationDataQO; import com.test.test.domain.qo.UiAutomationQO; import com.test.test.service.IUiAutomationService; +import com.test.test.service.IUiSceneStepsService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.test.common.annotation.Log; import com.test.common.core.controller.BaseController; import com.test.common.core.domain.AjaxResult; @@ -35,6 +30,8 @@ public class UiAutomationController extends BaseController { @Autowired private IUiAutomationService uiAutomationService; + @Autowired + private IUiSceneStepsService uiSceneStepsService; /** * 查询ui自动化列表 @@ -48,19 +45,6 @@ public class UiAutomationController extends BaseController return getDataTable(list); } -// /** -// * 导出ui自动化列表 -// */ -// @PreAuthorize("@ss.hasPermi('system:automation:export')") -// @Log(title = "ui自动化", businessType = BusinessType.EXPORT) -// @PostMapping("/export") -// public void export(HttpServletResponse response, UiAutomation uiAutomation) -// { -// List list = uiAutomationService.selectUiAutomationList(uiAutomation); -// ExcelUtil util = new ExcelUtil(UiAutomation.class); -// util.exportExcel(response, list, "ui自动化数据"); -// } - /** * 获取ui自动化详细信息 */ @@ -116,4 +100,21 @@ public class UiAutomationController extends BaseController { return toAjax(uiAutomationService.deleteUiAutomationByIds(ids)); } + + + /** + * 执行场景步骤 + */ +// @PreAuthorize("@ss.hasPermi('system:automation:remove')") + @GetMapping("/executeStep") + public AjaxResult remove(@RequestParam Long id) + { + try{ + log.info("执行完成!"); + return success(uiSceneStepsService.executeStep(id)); + } catch (Exception e) { + log.error("执行完成!",e); + return error("执行完成!"); + } + } } diff --git a/test-test/src/main/java/com/test/test/controller/UiReportController.java b/test-test/src/main/java/com/test/test/controller/UiReportController.java new file mode 100644 index 0000000..4a0f23c --- /dev/null +++ b/test-test/src/main/java/com/test/test/controller/UiReportController.java @@ -0,0 +1,73 @@ +package com.test.test.controller; + +import java.util.List; + +import com.test.test.domain.UiReport; +import com.test.test.service.IUiReportService; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.test.common.annotation.Log; +import com.test.common.core.controller.BaseController; +import com.test.common.core.domain.AjaxResult; +import com.test.common.enums.BusinessType; +import com.test.common.utils.poi.ExcelUtil; +import com.test.common.core.page.TableDataInfo; + +/** + * ui报告Controller + * + * @author test + * @date 2025-04-24 + */ +@RestController +@RequestMapping("/test/report") +public class UiReportController extends BaseController +{ + @Autowired + private IUiReportService uiReportService; + + /** + * 查询ui报告列表 + */ +// @PreAuthorize("@ss.hasPermi('system:report:list')") + @GetMapping("/list") + public TableDataInfo list(UiReport uiReport) + { + startPage(); + List list = uiReportService.selectUiReportList(uiReport); + return getDataTable(list); + } + + + /** + * 获取ui报告详细信息 + */ +// @PreAuthorize("@ss.hasPermi('system:report:query')") + @GetMapping(value = "getInfo/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return success(uiReportService.selectUiReportById(id)); + } + + + + /** + * 删除ui报告 + */ +// @PreAuthorize("@ss.hasPermi('system:report:remove')") + @Log(title = "ui报告", businessType = BusinessType.UPDATE) + @PutMapping("delete/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(uiReportService.deleteUiReportByIds(ids)); + } +} diff --git a/test-test/src/main/java/com/test/test/domain/UiReport.java b/test-test/src/main/java/com/test/test/domain/UiReport.java new file mode 100644 index 0000000..b74508c --- /dev/null +++ b/test-test/src/main/java/com/test/test/domain/UiReport.java @@ -0,0 +1,290 @@ +package com.test.test.domain; + +import com.test.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.test.common.annotation.Excel; + +/** + * ui报告对象 ui_report + * + * @author test + * @date 2025-04-24 + */ +public class UiReport extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** */ + private Long id; + + /** 名称 */ + @Excel(name = "名称") + private String name; + + /** 报告类型 */ + @Excel(name = "报告类型") + private String reportType; + + /** 触发方式 */ + @Excel(name = "触发方式") + private String triggerMode; + + /** 描述 */ + @Excel(name = "描述") + private String description; + + /** 是否删除 0否 1是 */ + private Integer delFlag; + + /** 状态 1running 2error 3 success 4stopped 5 pending 6 Timeout */ + @Excel(name = "状态 1running 2error 3 success 4stopped 5 pending 6 Timeout") + private Integer status; + + /** 耗时 */ + @Excel(name = "耗时") + private String take; + + /** 失败率 */ + @Excel(name = "失败率") + private String faiiRate; + + /** 成功断言 */ + @Excel(name = "成功断言") + private String successAssertion; + + /** 场景数 */ + @Excel(name = "场景数") + private Integer scenesNumber; + + /** 场景成功数 */ + @Excel(name = "场景成功数") + private Integer scenesSucceedNumber; + + /** 场景失败数 */ + @Excel(name = "场景失败数") + private Integer scenesErrorNumber; + + /** 场景未执行数 */ + @Excel(name = "场景未执行数") + private Integer scenesNotNumber; + + /** 步骤数 */ + @Excel(name = "步骤数") + private Integer stepsNumber; + + /** 步骤成功数 */ + @Excel(name = "步骤成功数") + private Integer stepsSucceedNumber; + + /** 步骤失败数 */ + @Excel(name = "步骤失败数") + private Integer stepsErrorNumber; + + /** 步骤未执行数 */ + @Excel(name = "步骤未执行数") + private Integer stepsNotNumber; + + + private String consoleStr; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setReportType(String reportType) + { + this.reportType = reportType; + } + + public String getReportType() + { + return reportType; + } + public void setTriggerMode(String triggerMode) + { + this.triggerMode = triggerMode; + } + + public String getTriggerMode() + { + return triggerMode; + } + public void setDescription(String description) + { + this.description = description; + } + + public String getDescription() + { + return description; + } + public void setDelFlag(Integer delFlag) + { + this.delFlag = delFlag; + } + + public Integer getDelFlag() + { + return delFlag; + } + public void setStatus(Integer status) + { + this.status = status; + } + + public Integer getStatus() + { + return status; + } + public void setTake(String take) + { + this.take = take; + } + + public String getTake() + { + return take; + } + public void setFaiiRate(String faiiRate) + { + this.faiiRate = faiiRate; + } + + public String getFaiiRate() + { + return faiiRate; + } + public void setSuccessAssertion(String successAssertion) + { + this.successAssertion = successAssertion; + } + + public String getSuccessAssertion() + { + return successAssertion; + } + public void setScenesNumber(Integer scenesNumber) + { + this.scenesNumber = scenesNumber; + } + + public Integer getScenesNumber() + { + return scenesNumber; + } + public void setScenesSucceedNumber(Integer scenesSucceedNumber) + { + this.scenesSucceedNumber = scenesSucceedNumber; + } + + public Integer getScenesSucceedNumber() + { + return scenesSucceedNumber; + } + public void setScenesErrorNumber(Integer scenesErrorNumber) + { + this.scenesErrorNumber = scenesErrorNumber; + } + + public Integer getScenesErrorNumber() + { + return scenesErrorNumber; + } + public void setScenesNotNumber(Integer scenesNotNumber) + { + this.scenesNotNumber = scenesNotNumber; + } + + public Integer getScenesNotNumber() + { + return scenesNotNumber; + } + public void setStepsNumber(Integer stepsNumber) + { + this.stepsNumber = stepsNumber; + } + + public Integer getStepsNumber() + { + return stepsNumber; + } + public void setStepsSucceedNumber(Integer stepsSucceedNumber) + { + this.stepsSucceedNumber = stepsSucceedNumber; + } + + public Integer getStepsSucceedNumber() + { + return stepsSucceedNumber; + } + public void setStepsErrorNumber(Integer stepsErrorNumber) + { + this.stepsErrorNumber = stepsErrorNumber; + } + + public Integer getStepsErrorNumber() + { + return stepsErrorNumber; + } + public void setStepsNotNumber(Integer stepsNotNumber) + { + this.stepsNotNumber = stepsNotNumber; + } + + public Integer getStepsNotNumber() + { + return stepsNotNumber; + } + + + public String getConsoleStr() { + return consoleStr; + } + + public void setConsoleStr(String consoleStr) { + this.consoleStr = consoleStr; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("name", getName()) + .append("reportType", getReportType()) + .append("triggerMode", getTriggerMode()) + .append("description", getDescription()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("delFlag", getDelFlag()) + .append("status", getStatus()) + .append("take", getTake()) + .append("faiiRate", getFaiiRate()) + .append("successAssertion", getSuccessAssertion()) + .append("scenesNumber", getScenesNumber()) + .append("scenesSucceedNumber", getScenesSucceedNumber()) + .append("scenesErrorNumber", getScenesErrorNumber()) + .append("scenesNotNumber", getScenesNotNumber()) + .append("stepsNumber", getStepsNumber()) + .append("stepsSucceedNumber", getStepsSucceedNumber()) + .append("stepsErrorNumber", getStepsErrorNumber()) + .append("stepsNotNumber", getStepsNotNumber()) + .toString(); + } +} diff --git a/test-test/src/main/java/com/test/test/domain/UiSceneSteps.java b/test-test/src/main/java/com/test/test/domain/UiSceneSteps.java index e6ed466..04f8600 100644 --- a/test-test/src/main/java/com/test/test/domain/UiSceneSteps.java +++ b/test-test/src/main/java/com/test/test/domain/UiSceneSteps.java @@ -113,6 +113,13 @@ public class UiSceneSteps extends BaseEntity @Excel(name = "frame索引号") private Integer frameIndex; + /**是否输入*/ + private String isEnter; + + + /**操作方式*/ + private String operateWay; + public void setId(Long id) { this.id = id; @@ -339,6 +346,23 @@ public class UiSceneSteps extends BaseEntity return frameIndex; } + + public String getOperateWay() { + return operateWay; + } + + public void setOperateWay(String operateWay) { + this.operateWay = operateWay; + } + + public String getIsEnter() { + return isEnter; + } + + public void setIsEnter(String isEnter) { + this.isEnter = isEnter; + } + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/test-test/src/main/java/com/test/test/domain/UiSceneStepsReport.java b/test-test/src/main/java/com/test/test/domain/UiSceneStepsReport.java new file mode 100644 index 0000000..9961b8c --- /dev/null +++ b/test-test/src/main/java/com/test/test/domain/UiSceneStepsReport.java @@ -0,0 +1,167 @@ +package com.test.test.domain; + +import com.test.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.test.common.annotation.Excel; + +/** + * ui自动化场景报告对象 ui_scene_steps_report + * + * @author test + * @date 2025-04-24 + */ +public class UiSceneStepsReport extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** $column.columnComment */ + private Long id; + + /** 报告id */ + @Excel(name = "报告id") + private Long reportId; + + /** 名称 */ + @Excel(name = "名称") + private String name; + + /** 日志 */ + @Excel(name = "日志") + private String logInfo; + + /** 执行类型 1成功 0未执行 2执行失败 */ + @Excel(name = "执行类型 1成功 0未执行 2执行失败") + private String executionFlag; + + /** 耗时 */ + @Excel(name = "耗时") + private String take; + + /** 截图 */ + @Excel(name = "截图") + private String screenshot; + + /** 断言json */ + @Excel(name = "断言json") + private String assertionJson; + + /** 数据提取json */ + @Excel(name = "数据提取json") + private String extractionDataJson; + + /** 场景步骤序号 */ + @Excel(name = "场景步骤序号") + private Integer orderNumber; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setReportId(Long reportId) + { + this.reportId = reportId; + } + + public Long getReportId() + { + return reportId; + } + public void setName(String name) + { + this.name = name; + } + + public String getName() + { + return name; + } + public void setLogInfo(String logInfo) + { + this.logInfo = logInfo; + } + + public String getLogInfo() + { + return logInfo; + } + public void setExecutionFlag(String executionFlag) + { + this.executionFlag = executionFlag; + } + + public String getExecutionFlag() + { + return executionFlag; + } + public void setTake(String take) + { + this.take = take; + } + + public String getTake() + { + return take; + } + public void setScreenshot(String screenshot) + { + this.screenshot = screenshot; + } + + public String getScreenshot() + { + return screenshot; + } + public void setAssertionJson(String assertionJson) + { + this.assertionJson = assertionJson; + } + + public String getAssertionJson() + { + return assertionJson; + } + public void setExtractionDataJson(String extractionDataJson) + { + this.extractionDataJson = extractionDataJson; + } + + public String getExtractionDataJson() + { + return extractionDataJson; + } + public void setOrderNumber(Integer orderNumber) + { + this.orderNumber = orderNumber; + } + + public Integer getOrderNumber() + { + return orderNumber; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("reportId", getReportId()) + .append("name", getName()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("logInfo", getLogInfo()) + .append("executionFlag", getExecutionFlag()) + .append("take", getTake()) + .append("screenshot", getScreenshot()) + .append("assertionJson", getAssertionJson()) + .append("extractionDataJson", getExtractionDataJson()) + .append("orderNumber", getOrderNumber()) + .toString(); + } +} diff --git a/test-test/src/main/java/com/test/test/domain/qo/UiSceneStepsQO.java b/test-test/src/main/java/com/test/test/domain/qo/UiSceneStepsQO.java index 43624ed..8b14995 100644 --- a/test-test/src/main/java/com/test/test/domain/qo/UiSceneStepsQO.java +++ b/test-test/src/main/java/com/test/test/domain/qo/UiSceneStepsQO.java @@ -97,6 +97,13 @@ public class UiSceneStepsQO extends BaseEntity /** frame索引号 */ private Integer frameIndex; + /**是否输入*/ + private String isEnter; + + + /**操作方式*/ + private String operateWay; + /**高级设置*/ private List uiHighSettingList = new ArrayList<>(); diff --git a/test-test/src/main/java/com/test/test/domain/vo/UiReportVO.java b/test-test/src/main/java/com/test/test/domain/vo/UiReportVO.java new file mode 100644 index 0000000..2619e58 --- /dev/null +++ b/test-test/src/main/java/com/test/test/domain/vo/UiReportVO.java @@ -0,0 +1,69 @@ +package com.test.test.domain.vo; + +import com.test.common.annotation.Excel; +import com.test.common.core.domain.BaseEntity; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.util.ArrayList; +import java.util.List; + +/** + * ui报告对象 ui_report + * + * @author test + * @date 2025-04-24 + */ +@Data +public class UiReportVO extends BaseEntity +{ + + /** $column.columnComment */ + private Long id; + + /** 名称 */ + private String name; + + /** 耗时 */ + private String take; + + /** 失败率 */ + private String faiiRate; + + /** 成功断言 */ + private String successAssertion; + + /** 场景数 */ + private Integer scenesNumber; + + /** 场景成功数 */ + private Integer scenesSucceedNumber; + + /** 场景失败数 */ + private Integer scenesErrorNumber; + + /** 场景未执行数 */ + private Integer scenesNotNumber; + + /** 步骤数 */ + private Integer stepsNumber; + + /** 步骤成功数 */ + private Integer stepsSucceedNumber; + + /** 步骤失败数 */ + private Integer stepsErrorNumber; + + /** 步骤未执行数 */ + private Integer stepsNotNumber; + + /**报告步骤全部详情*/ + private List uiSceneStepsAllReportVOList = new ArrayList<>() ; + /**报告步骤失败详情*/ + private List uiSceneStepsErrorReportVOList = new ArrayList<>() ; + /**报告步骤未执行详情*/ + private List uiSceneStepsNotReportVOList = new ArrayList<>() ; + /**控制台信息*/ + private String consoleStr; +} diff --git a/test-test/src/main/java/com/test/test/domain/vo/UiSceneStepsReportVO.java b/test-test/src/main/java/com/test/test/domain/vo/UiSceneStepsReportVO.java new file mode 100644 index 0000000..ca4eb1e --- /dev/null +++ b/test-test/src/main/java/com/test/test/domain/vo/UiSceneStepsReportVO.java @@ -0,0 +1,48 @@ +package com.test.test.domain.vo; + +import com.test.common.annotation.Excel; +import com.test.common.core.domain.BaseEntity; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * ui自动化场景报告对象 ui_scene_steps_report + * + * @author test + * @date 2025-04-24 + */ +@Data +public class UiSceneStepsReportVO +{ + + + /** 报告id */ + private Long reportId; + + /** 名称 */ + private String name; + + /** 日志 */ + private String logInfo; + + /** 执行类型 1成功 0未执行 2执行失败 */ + private String executionFlag; + + /** 耗时 */ + private String take; + + /** 截图 */ + private String screenshot; + + /** 断言json */ + private String assertionJson; + + /** 数据提取json */ + private String extractionDataJson; + + /** 场景步骤序号 */ + private Integer orderNumber; + + +} diff --git a/test-test/src/main/java/com/test/test/domain/vo/UiSceneStepsVO.java b/test-test/src/main/java/com/test/test/domain/vo/UiSceneStepsVO.java index f2d71aa..d5363bd 100644 --- a/test-test/src/main/java/com/test/test/domain/vo/UiSceneStepsVO.java +++ b/test-test/src/main/java/com/test/test/domain/vo/UiSceneStepsVO.java @@ -91,6 +91,13 @@ public class UiSceneStepsVO /** frame索引号 */ private Integer frameIndex; + /**是否输入*/ + private String isEnter; + + + /**操作方式*/ + private String operateWay; + /**高级设置*/ private List uiHighSettingVOList = new ArrayList<>(); diff --git a/test-test/src/main/java/com/test/test/mapper/UiReportMapper.java b/test-test/src/main/java/com/test/test/mapper/UiReportMapper.java new file mode 100644 index 0000000..d516ea6 --- /dev/null +++ b/test-test/src/main/java/com/test/test/mapper/UiReportMapper.java @@ -0,0 +1,62 @@ +package com.test.test.mapper; + +import com.test.test.domain.UiReport; + +import java.util.List; + +/** + * ui报告Mapper接口 + * + * @author test + * @date 2025-04-24 + */ +public interface UiReportMapper +{ + /** + * 查询ui报告 + * + * @param id ui报告主键 + * @return ui报告 + */ + public UiReport selectUiReportById(Long id); + + /** + * 查询ui报告列表 + * + * @param uiReport ui报告 + * @return ui报告集合 + */ + public List selectUiReportList(UiReport uiReport); + + /** + * 新增ui报告 + * + * @param uiReport ui报告 + * @return 结果 + */ + public int insertUiReport(UiReport uiReport); + + /** + * 修改ui报告 + * + * @param uiReport ui报告 + * @return 结果 + */ + public int updateUiReport(UiReport uiReport); + + /** + * 删除ui报告 + * + * @param id ui报告主键 + * @return 结果 + */ + public int deleteUiReportById(Long id); + + /** + * 批量删除ui报告 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteUiReportByIds(Long[] ids); +} diff --git a/test-test/src/main/java/com/test/test/mapper/UiSceneStepsReportMapper.java b/test-test/src/main/java/com/test/test/mapper/UiSceneStepsReportMapper.java new file mode 100644 index 0000000..8331012 --- /dev/null +++ b/test-test/src/main/java/com/test/test/mapper/UiSceneStepsReportMapper.java @@ -0,0 +1,62 @@ +package com.test.test.mapper; + +import com.test.test.domain.UiSceneStepsReport; + +import java.util.List; + +/** + * ui自动化场景报告Mapper接口 + * + * @author test + * @date 2025-04-24 + */ +public interface UiSceneStepsReportMapper +{ + /** + * 查询ui自动化场景报告 + * + * @param id ui自动化场景报告主键 + * @return ui自动化场景报告 + */ + public UiSceneStepsReport selectUiSceneStepsReportById(Long id); + + /** + * 查询ui自动化场景报告列表 + * + * @param uiSceneStepsReport ui自动化场景报告 + * @return ui自动化场景报告集合 + */ + public List selectUiSceneStepsReportList(UiSceneStepsReport uiSceneStepsReport); + + /** + * 新增ui自动化场景报告 + * + * @param uiSceneStepsReport ui自动化场景报告 + * @return 结果 + */ + public int insertUiSceneStepsReport(UiSceneStepsReport uiSceneStepsReport); + + /** + * 修改ui自动化场景报告 + * + * @param uiSceneStepsReport ui自动化场景报告 + * @return 结果 + */ + public int updateUiSceneStepsReport(UiSceneStepsReport uiSceneStepsReport); + + /** + * 删除ui自动化场景报告 + * + * @param id ui自动化场景报告主键 + * @return 结果 + */ + public int deleteUiSceneStepsReportById(Long id); + + /** + * 批量删除ui自动化场景报告 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteUiSceneStepsReportByIds(Long[] ids); +} diff --git a/test-test/src/main/java/com/test/test/service/IUiAutomationService.java b/test-test/src/main/java/com/test/test/service/IUiAutomationService.java index 2df3dec..ec804b5 100644 --- a/test-test/src/main/java/com/test/test/service/IUiAutomationService.java +++ b/test-test/src/main/java/com/test/test/service/IUiAutomationService.java @@ -4,6 +4,7 @@ import com.test.test.domain.UiAutomation; import com.test.test.domain.qo.UiAutomationDataQO; import com.test.test.domain.qo.UiAutomationQO; import com.test.test.domain.vo.UiAutomationVO; +import com.test.test.domain.vo.UiHighSettingVO; import java.util.List; @@ -23,6 +24,13 @@ public interface IUiAutomationService */ public UiAutomationVO selectUiAutomationById(Long id); + + /** + * 查看高级设置 + * @param stepsId + * @return + */ + public List getUiHighSettingVOList(Long stepsId); /** * 查询ui自动化列表 * diff --git a/test-test/src/main/java/com/test/test/service/IUiReportService.java b/test-test/src/main/java/com/test/test/service/IUiReportService.java new file mode 100644 index 0000000..544a3f4 --- /dev/null +++ b/test-test/src/main/java/com/test/test/service/IUiReportService.java @@ -0,0 +1,64 @@ +package com.test.test.service; + +import com.test.test.domain.UiReport; +import com.test.test.domain.vo.UiReportVO; + +import java.util.Date; +import java.util.List; + +/** + * ui报告Service接口 + * + * @author test + * @date 2025-04-24 + */ +public interface IUiReportService +{ + /** + * 查询ui报告 + * + * @param id ui报告主键 + * @return ui报告 + */ + public UiReportVO selectUiReportById(Long id); + + /** + * 查询ui报告列表 + * + * @param uiReport ui报告 + * @return ui报告集合 + */ + public List selectUiReportList(UiReport uiReport); + + /** + * 新增ui报告 + * + * @param automationId ui报告 + * @return 结果 + */ + public Long insertUiReport(Date startTime, Long automationId, String triggerMode, Integer stepsNum); + + /** + * 修改ui报告 + * + * @param uiReport ui报告 + * @return 结果 + */ + public int updateUiReport(UiReport uiReport); + + /** + * 批量删除ui报告 + * + * @param ids 需要删除的ui报告主键集合 + * @return 结果 + */ + public int deleteUiReportByIds(Long[] ids); + + /** + * 删除ui报告信息 + * + * @param id ui报告主键 + * @return 结果 + */ + public int deleteUiReportById(Long id); +} diff --git a/test-test/src/main/java/com/test/test/service/IUiSceneStepsService.java b/test-test/src/main/java/com/test/test/service/IUiSceneStepsService.java index 8a3cc95..2d2fd6a 100644 --- a/test-test/src/main/java/com/test/test/service/IUiSceneStepsService.java +++ b/test-test/src/main/java/com/test/test/service/IUiSceneStepsService.java @@ -3,6 +3,7 @@ package com.test.test.service; import com.test.test.domain.UiSceneSteps; import java.util.List; +import java.util.Map; /** * ui自动化场景步骤Service接口 @@ -12,51 +13,12 @@ import java.util.List; */ public interface IUiSceneStepsService { - /** - * 查询ui自动化场景步骤 - * - * @param id ui自动化场景步骤主键 - * @return ui自动化场景步骤 - */ - public List selectUiSceneStepsById(Long id); /** - * 查询ui自动化场景步骤列表 - * - * @param uiSceneSteps ui自动化场景步骤 - * @return ui自动化场景步骤集合 + * 执行场景步骤 + * @param automationId 场景id + * @return */ - public List selectUiSceneStepsList(UiSceneSteps uiSceneSteps); + Map executeStep(Long automationId); - /** - * 新增ui自动化场景步骤 - * - * @param uiSceneSteps ui自动化场景步骤 - * @return 结果 - */ - public int insertUiSceneSteps(UiSceneSteps uiSceneSteps); - - /** - * 修改ui自动化场景步骤 - * - * @param uiSceneSteps ui自动化场景步骤 - * @return 结果 - */ - public int updateUiSceneSteps(UiSceneSteps uiSceneSteps); - - /** - * 批量删除ui自动化场景步骤 - * - * @param ids 需要删除的ui自动化场景步骤主键集合 - * @return 结果 - */ - public int deleteUiSceneStepsByIds(Long[] ids); - - /** - * 删除ui自动化场景步骤信息 - * - * @param id ui自动化场景步骤主键 - * @return 结果 - */ - public int deleteUiSceneStepsById(Long id); } diff --git a/test-test/src/main/java/com/test/test/service/StepExecution.java b/test-test/src/main/java/com/test/test/service/StepExecution.java new file mode 100644 index 0000000..f23c7d3 --- /dev/null +++ b/test-test/src/main/java/com/test/test/service/StepExecution.java @@ -0,0 +1,15 @@ +package com.test.test.service; + +import com.test.common.utils.SeleniumUtils; +import com.test.test.domain.UiSceneSteps; + +@FunctionalInterface +public interface StepExecution { + /** + * 步骤执行 + * @param step + * @param seleniumUtils + * @throws Exception + */ + void execute(UiSceneSteps step, SeleniumUtils seleniumUtils) throws Exception; +} \ No newline at end of file diff --git a/test-test/src/main/java/com/test/test/service/impl/UiAutomationServiceImpl.java b/test-test/src/main/java/com/test/test/service/impl/UiAutomationServiceImpl.java index d096f04..835426d 100644 --- a/test-test/src/main/java/com/test/test/service/impl/UiAutomationServiceImpl.java +++ b/test-test/src/main/java/com/test/test/service/impl/UiAutomationServiceImpl.java @@ -1,5 +1,6 @@ package com.test.test.service.impl; +import java.util.ArrayList; import java.util.List; import com.fasterxml.jackson.core.JsonProcessingException; @@ -82,7 +83,7 @@ public class UiAutomationServiceImpl implements IUiAutomationService { extractionData = objectMapper.readValue( uiHighSetting.getExtractionDataJson(), new TypeReference>(){ - } // 根据实际结构可以定义具体类 + } ); uiHighSettingVO.setDataExtractionQOList(extractionData); } @@ -105,6 +106,50 @@ public class UiAutomationServiceImpl implements IUiAutomationService { return uiAutomationVO; } + + public List getUiHighSettingVOList(Long stepsId) { + List uiHighSettingVOList = new ArrayList<>(); + List uiHighSettings = uiHighSettingMapper.selectUiHighSettingById(stepsId); + for (UiHighSetting uiHighSetting : uiHighSettings) { + UiHighSettingVO uiHighSettingVO = new UiHighSettingVO(); + BeanUtils.copyProperties(uiHighSetting, uiHighSettingVO); + // 转换assertionJson 断言 + if (StringUtils.isNotBlank(uiHighSetting.getAssertionJson())) { + List assertionList = null; + try { + assertionList = objectMapper.readValue( + uiHighSetting.getAssertionJson(), + new TypeReference>() { + } + ); + uiHighSettingVO.setAssertionQOList(assertionList); + // 转换extractionDataJson 数据提取 + if (StringUtils.isNotBlank(uiHighSetting.getExtractionDataJson())) { + List extractionData = null; + extractionData = objectMapper.readValue( + uiHighSetting.getExtractionDataJson(), + new TypeReference>() { + } + ); + uiHighSettingVO.setDataExtractionQOList(extractionData); + } + // 转换otherSetting 其他设置 + if (StringUtils.isNotBlank(uiHighSetting.getOtherSetting())) { + OtherSettingsQO otherSettings = objectMapper.readValue( + uiHighSetting.getOtherSetting(), + OtherSettingsQO.class + ); + uiHighSettingVO.setOtherSettingsQO(otherSettings); + } + uiHighSettingVOList.add(uiHighSettingVO); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + + } + } + return uiHighSettingVOList; + } /** * 查询ui自动化列表 * diff --git a/test-test/src/main/java/com/test/test/service/impl/UiReportServiceImpl.java b/test-test/src/main/java/com/test/test/service/impl/UiReportServiceImpl.java new file mode 100644 index 0000000..fe18744 --- /dev/null +++ b/test-test/src/main/java/com/test/test/service/impl/UiReportServiceImpl.java @@ -0,0 +1,151 @@ +package com.test.test.service.impl; + +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +import com.test.common.utils.DateUtils; +import com.test.common.utils.SecurityUtils; +import com.test.test.domain.UiAutomation; +import com.test.test.domain.UiReport; +import com.test.test.domain.UiSceneStepsReport; +import com.test.test.domain.vo.UiReportVO; +import com.test.test.domain.vo.UiSceneStepsReportVO; +import com.test.test.mapper.UiAutomationMapper; +import com.test.test.mapper.UiReportMapper; +import com.test.test.mapper.UiSceneStepsReportMapper; +import com.test.test.service.IUiReportService; +import jakarta.annotation.Resource; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +/** + * ui报告Service业务层处理 + * + * @author test + * @date 2025-04-24 + */ +@Service +public class UiReportServiceImpl implements IUiReportService +{ + @Resource + private UiReportMapper uiReportMapper; + @Resource + private UiSceneStepsReportMapper uiSceneStepsReportMapper; + @Resource + private UiAutomationMapper uiAutomationMapper; + + /** + * 查询ui报告 + * + * @param id ui报告主键 + * @return ui报告 + */ + @Override + public UiReportVO selectUiReportById(Long id) + { + UiReportVO uiReportVO = new UiReportVO(); + UiReport uiReport = uiReportMapper.selectUiReportById(id); + BeanUtils.copyProperties(uiReport, uiReportVO); + UiSceneStepsReport uiSceneStepsReport = new UiSceneStepsReport(); + uiSceneStepsReport.setReportId(id); + //查询报告步骤详情 + List uiSceneStepsReports = uiSceneStepsReportMapper.selectUiSceneStepsReportList(uiSceneStepsReport); + for (UiSceneStepsReport sceneStepsReport : uiSceneStepsReports) { + UiSceneStepsReportVO uiSceneStepsReportVO = new UiSceneStepsReportVO(); + BeanUtils.copyProperties(sceneStepsReport, uiSceneStepsReportVO); + //全部 + uiReportVO.getUiSceneStepsAllReportVOList().add(uiSceneStepsReportVO); + } + //执行失败 + List errorList = uiReportVO.getUiSceneStepsAllReportVOList().stream().filter(e -> e.getExecutionFlag().equals("2")).collect(Collectors.toList()); + uiReportVO.getUiSceneStepsErrorReportVOList().addAll(errorList); + //未执行 + List NotList = uiReportVO.getUiSceneStepsAllReportVOList().stream().filter(e -> e.getExecutionFlag().equals("0")).collect(Collectors.toList()); + uiReportVO.getUiSceneStepsNotReportVOList().addAll(NotList); + return uiReportVO; + } + + /** + * 查询ui报告列表 + * + * @param uiReport ui报告 + * @return ui报告 + */ + @Override + public List selectUiReportList(UiReport uiReport) + { + uiReport.setDelFlag(0); + return uiReportMapper.selectUiReportList(uiReport); + } + + /** + * 新增ui报告 + * + * @param automationId ui报告 + * @param triggerMode 触发方式 1手动触发 2批量执行 3定时任务 4 Api调用 + * @return 结果 + */ + @Override + public Long insertUiReport(Date startTime, Long automationId, String triggerMode, Integer stepsNum) + { + UiAutomation automation = uiAutomationMapper.selectUiAutomationById(automationId); + String name = automation.getName(); + UiReport uiReport = new UiReport(); + uiReport.setName(name + "-" + DateUtils.getTime()); + uiReport.setReportType("场景"); + uiReport.setCreateTime(startTime); + uiReport.setCreateBy(SecurityUtils.getUsername()); + uiReport.setUpdateBy(SecurityUtils.getUsername()); + uiReport.setTriggerMode(triggerMode); + uiReport.setDelFlag(0); + uiReport.setStepsNumber(stepsNum);//步骤数 + uiReport.setStatus(1);//正在执行 + uiReport.setScenesNumber(1); + uiReportMapper.insertUiReport(uiReport); + return uiReport.getId(); + } + + /** + * 修改ui报告 + * + * @param uiReport ui报告 + * @return 结果 + */ + @Override + public int updateUiReport(UiReport uiReport) + { + uiReport.setUpdateTime(DateUtils.getNowDate()); + return uiReportMapper.updateUiReport(uiReport); + } + + /** + * 批量删除ui报告 + * + * @param ids 需要删除的ui报告主键 + * @return 结果 + */ + @Override + @Transactional + public int deleteUiReportByIds(Long[] ids) + { + //删除报告详情 + uiSceneStepsReportMapper.deleteUiSceneStepsReportByIds(ids); + return uiReportMapper.deleteUiReportByIds(ids); + } + + /** + * 删除ui报告信息 + * + * @param id ui报告主键 + * @return 结果 + */ + @Override + public int deleteUiReportById(Long id) + { + return uiReportMapper.deleteUiReportById(id); + } +} diff --git a/test-test/src/main/java/com/test/test/service/impl/UiSceneStepsServiceImpl.java b/test-test/src/main/java/com/test/test/service/impl/UiSceneStepsServiceImpl.java index 0bb0e59..771da27 100644 --- a/test-test/src/main/java/com/test/test/service/impl/UiSceneStepsServiceImpl.java +++ b/test-test/src/main/java/com/test/test/service/impl/UiSceneStepsServiceImpl.java @@ -1,97 +1,331 @@ package com.test.test.service.impl; +import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import com.test.common.utils.DateUtils; +import com.test.common.utils.SecurityUtils; +import com.test.common.utils.SeleniumUtils; +import com.test.common.utils.StringUtils; +import com.test.test.domain.UiAutomation; +import com.test.test.domain.UiReport; import com.test.test.domain.UiSceneSteps; +import com.test.test.domain.UiSceneStepsReport; +import com.test.test.domain.qo.OtherSettingsQO; +import com.test.test.domain.vo.UiHighSettingVO; +import com.test.test.mapper.UiAutomationMapper; import com.test.test.mapper.UiSceneStepsMapper; +import com.test.test.mapper.UiSceneStepsReportMapper; +import com.test.test.service.IUiAutomationService; +import com.test.test.service.IUiReportService; import com.test.test.service.IUiSceneStepsService; +import com.test.test.service.StepExecution; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.checkerframework.checker.units.qual.C; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; -/** - * ui自动化场景步骤Service业务层处理 - * - * @author test - * @date 2025-04-23 - */ @Service -public class UiSceneStepsServiceImpl implements IUiSceneStepsService -{ - @Autowired +@Slf4j +public class UiSceneStepsServiceImpl implements IUiSceneStepsService { + + @Resource private UiSceneStepsMapper uiSceneStepsMapper; + @Resource + private IUiReportService uiReportService; + @Resource + private UiSceneStepsReportMapper uiSceneStepsReportMapper; + @Resource + private IUiAutomationService uiAutomationService; + //场景成功数 + private Integer scenesSucceedNumber = 0; + //场景失败数 + private Integer scenesErrorNumber = 0; + //场景未执行数 + private Integer scenesNotNumber = 0; + //步骤成功数 + private Integer stepsSucceedNumber = 0; + //步骤失败数 + private Integer stepsErrorNumber = 0; + //步骤未执行数 + private Integer stepsNotNumber = 0; + /** - * 查询ui自动化场景步骤 - * - * @param id ui自动化场景步骤主键 - * @return ui自动化场景步骤 + * 执行场景步骤 + * + * @param automationId + * @return */ - @Override - public List selectUiSceneStepsById(Long id) - { - return uiSceneStepsMapper.selectUiSceneStepsById(id); + public Map executeStep(Long automationId) { + Map result = new HashMap<>(); + result.put("msg", ""); + result.put("id", 0L); + // 1. 验证并获取步骤 + List steps = validateAndGetSteps(automationId); + stepsNotNumber = steps.size(); + + Date startTime = DateUtils.getNowDate(); + // 2. 创建执行报告 + Long reportId = uiReportService.insertUiReport(startTime, automationId, "1", steps.size()); + UiReport uiReport = new UiReport(); + result.put("id", reportId); + uiReport.setId(reportId); + Date endTime = null; + Integer orderNumber = 0; + for (UiSceneSteps step : steps) { + orderNumber++; + //创建报告步骤表 + createSceneStepsReport(orderNumber,step, reportId); + } + try { + // 3. 执行所有步骤 + executeAllSteps(steps, reportId); + log.info("场景执行成功: {}", automationId); + scenesSucceedNumber++; + uiReport.setConsoleStr("OK"); + uiReport.setStatus(3); + } catch (IllegalArgumentException e) { + result.put("msg", e.getMessage()); + log.error("场景执行失败: {}", e.getMessage()); + scenesErrorNumber++; + uiReport.setConsoleStr(e.toString()); + uiReport.setStatus(2); + } finally { + endTime = DateUtils.getNowDate(); + uiReport.setTake(DateUtils.calculateTimeDifference(startTime, endTime)); + uiReport.setUpdateTime(endTime); + uiReport.setScenesSucceedNumber(scenesSucceedNumber); + uiReport.setScenesErrorNumber(scenesErrorNumber); + uiReport.setScenesNotNumber(scenesNotNumber); + uiReport.setStepsSucceedNumber(stepsSucceedNumber); + uiReport.setStepsErrorNumber(stepsErrorNumber); + uiReport.setStepsNotNumber(stepsNotNumber); + uiReport.setFaiiRate( + stepsErrorNumber == 0 ? "0%" : + String.format("%.2f%%", (double)stepsErrorNumber / steps.size() * 100) + ); + uiReportService.updateUiReport(uiReport); + + } + return result; } /** - * 查询ui自动化场景步骤列表 - * - * @param uiSceneSteps ui自动化场景步骤 - * @return ui自动化场景步骤 + * 判断步骤是否为空 + * + * @param automationId + * @return */ - @Override - public List selectUiSceneStepsList(UiSceneSteps uiSceneSteps) - { - return uiSceneStepsMapper.selectUiSceneStepsList(uiSceneSteps); + private List validateAndGetSteps(Long automationId) { + List steps = uiSceneStepsMapper.selectUiSceneStepsById(automationId); + if (CollectionUtils.isEmpty(steps)) { + throw new IllegalArgumentException("步骤不能为空"); + } + //判断第一步是不是打开网页 + if (!"1".equals(steps.get(0).getOperateType()) || !"1".equals(steps.get(0).getStepType())) { + throw new IllegalArgumentException("第一步必须是打开网页"); + } + return steps; } /** - * 新增ui自动化场景步骤 - * - * @param uiSceneSteps ui自动化场景步骤 - * @return 结果 + * 创建报告步骤 + * + * @param steps + * @param reportId */ - @Override - public int insertUiSceneSteps(UiSceneSteps uiSceneSteps) - { - uiSceneSteps.setCreateTime(DateUtils.getNowDate()); - return uiSceneStepsMapper.insertUiSceneSteps(uiSceneSteps); + private Long createSceneStepsReport(Integer orderNumber,UiSceneSteps steps, Long reportId) { + UiSceneStepsReport uiSceneStepsReport = new UiSceneStepsReport(); + uiSceneStepsReport.setReportId(reportId); + uiSceneStepsReport.setName(steps.getName()); + uiSceneStepsReport.setCreateBy(SecurityUtils.getUsername()); + uiSceneStepsReport.setExecutionFlag("0");//未执行 + uiSceneStepsReport.setOrderNumber(orderNumber); + uiSceneStepsReportMapper.insertUiSceneStepsReport(uiSceneStepsReport); + return uiSceneStepsReport.getId(); + } + + + /** + * 场景步骤执行 + * + * @param steps + */ + private void executeAllSteps(List steps, Long reportId) { + System.setProperty("webdriver.chrome.driver", "D:/chromedriver-win64/chromedriver.exe"); + WebDriver driver = new ChromeDriver(); + SeleniumUtils seleniumUtils = new SeleniumUtils(driver); + Integer orderNumber = 0; + UiSceneStepsReport uiSceneStepsReport = new UiSceneStepsReport(); + uiSceneStepsReport.setReportId(reportId); + for (UiSceneSteps step : steps) { + orderNumber++; + uiSceneStepsReport.setOrderNumber(orderNumber); + List uiSceneStepsReports = uiSceneStepsReportMapper.selectUiSceneStepsReportList(uiSceneStepsReport); + if (CollectionUtils.isEmpty(uiSceneStepsReports)) { + continue; + } + //查看高级设置 + List uiHighSettingVOList = uiAutomationService.getUiHighSettingVOList(step.getId()); + executeSingleStep(step, seleniumUtils, uiSceneStepsReports.get(0).getId(), uiHighSettingVOList); + } + } + + private void executeSingleStep(UiSceneSteps step, SeleniumUtils seleniumUtils, + Long sceneStepsReportId, List uiHighSettingVOList) { + // 定义所有操作类型的执行方法映射 + Map> operationStrategies = Map.of( + "1", Map.of( // 浏览器操作 + "1", this::openWebPage +// "2", this::closeBrowser, +// "3", this::switchWindow, +// "4", this::resizeWindow, +// "5", this::selectEmbeddedPage + ) +// "2", Map.of( // 弹窗操作 +// "1", this::handlePopup +// ), +// "3", Map.of( // 元素操作 +// "1", this::submitForm, +// "2", this::handleDropdown, +// "3", this::setOption, +// "4", this::waitForElement +// ), +// "4", Map.of( // 鼠标操作 +// "1", this::mouseClick, +// "2", this::mouseMove, +// "3", this::mouseDrag +// ), +// "5", Map.of( // 输入操作 +// "1", this::inputText, +// "2", this::uploadFile +// ) + ); + + // 获取对应的操作类型映射 + Map operationMap = operationStrategies.get(step.getOperateType()); + if (operationMap == null) { + throw new IllegalArgumentException("不支持的操作类型: " + step.getOperateType()); + } + + // 获取具体的执行方法 + StepExecution execution = operationMap.get(step.getStepType()); + if (execution == null) { + throw new IllegalArgumentException("不支持的步骤类型: " + step.getStepType() + + " 对于操作类型: " + step.getOperateType()); + } + + // 执行步骤并处理结果 + boolean shouldContinue = executeStepWithLog(step, seleniumUtils, sceneStepsReportId, + execution, uiHighSettingVOList); + if (!shouldContinue) { + throw new IllegalArgumentException("步骤执行失败,根据设置终止场景执行"); + } + } + + + + /** + * 执行步骤并记录日志 + * + * @param step 步骤对象 + * @param seleniumUtils Selenium工具类 + * @param sceneStepsReportId 报告步骤ID + * @param stepExecution 具体的步骤执行方法 + * @param uiHighSettingVOList 高级设置列表 + * @return boolean 是否继续执行后续步骤 (true=继续, false=终止) + */ + private boolean executeStepWithLog(UiSceneSteps step, SeleniumUtils seleniumUtils, + Long sceneStepsReportId, StepExecution stepExecution, + List uiHighSettingVOList) { + // 1. 初始化设置对象 + UiHighSettingVO errorSetting = extractErrorSetting(uiHighSettingVOList); + UiHighSettingVO otherSetting = extractOtherSetting(uiHighSettingVOList); + OtherSettingsQO otherSettingsQO = otherSetting.getOtherSettingsQO(); + Integer screenshotConfiguration = otherSettingsQO.getScreenshotConfiguration(); //是否截图 1当前步骤截图 2异常截图 3 不截图 + + // 2. 准备报告对象 + UiSceneStepsReport report = new UiSceneStepsReport(); + report.setId(sceneStepsReportId); + Date startTime = DateUtils.getNowDate(); + Date endTime = null; + boolean continueExecution = true; // 默认继续执行 + try { + stepsSucceedNumber++; + if (screenshotConfiguration == 1) { + + } + // 3. 执行具体步骤 + stepExecution.execute(step, seleniumUtils); + report.setLogInfo("OK"); + report.setExecutionFlag("1"); + } catch (Exception e) { + // 4. 错误处理 + stepsErrorNumber++; + stepsSucceedNumber--; + report.setLogInfo(e.toString()); + report.setExecutionFlag("2"); + // 根据错误处理设置决定是否继续 + if ("1".equals(errorSetting.getErrorHandling())) { + continueExecution = false; // 不继续执行后续步骤 + } + log.error("步骤执行失败: {}", e.getMessage()); + } finally { + endTime = DateUtils.getNowDate(); + stepsNotNumber--; + // 更新报告 + report.setCreateTime(startTime); + report.setUpdateTime(endTime); + report.setTake(DateUtils.differenceInMilliseconds(startTime,endTime) + "ms"); + uiSceneStepsReportMapper.updateUiSceneStepsReport(report); + } + + return continueExecution; } /** - * 修改ui自动化场景步骤 - * - * @param uiSceneSteps ui自动化场景步骤 - * @return 结果 + * 提取错误处理设置 + * @param settings + * @return */ - @Override - public int updateUiSceneSteps(UiSceneSteps uiSceneSteps) - { - uiSceneSteps.setUpdateTime(DateUtils.getNowDate()); - return uiSceneStepsMapper.updateUiSceneSteps(uiSceneSteps); + private UiHighSettingVO extractErrorSetting(List settings) { + return settings.stream() + .filter(e -> "3".equals(e.getSettingType()) && e.getIsDisabled() == 0) + .findFirst() + .orElse(new UiHighSettingVO()); // 返回默认设置 } /** - * 批量删除ui自动化场景步骤 - * - * @param ids 需要删除的ui自动化场景步骤主键 - * @return 结果 + * 提取错误处理设置 + * @param settings + * @return */ - @Override - public int deleteUiSceneStepsByIds(Long[] ids) - { - return uiSceneStepsMapper.deleteUiSceneStepsByIds(ids); + private UiHighSettingVO extractOtherSetting(List settings) { + return settings.stream() + .filter(e -> "4".equals(e.getSettingType()) && e.getIsDisabled() == 0) + .findFirst() + .orElse(new UiHighSettingVO()); // 返回默认设置 } /** - * 删除ui自动化场景步骤信息 - * - * @param id ui自动化场景步骤主键 - * @return 结果 + * 打开网页 + * + * @param step 步骤对象 + * @param seleniumUtils Selenium工具类 */ - @Override - public int deleteUiSceneStepsById(Long id) - { - return uiSceneStepsMapper.deleteUiSceneStepsById(id); + private void openWebPage(UiSceneSteps step, SeleniumUtils seleniumUtils) { + seleniumUtils.openUrl(step.getUrl()); } -} + + +} \ No newline at end of file diff --git a/test-test/src/main/resources/mapper/test/UiReportMapper.xml b/test-test/src/main/resources/mapper/test/UiReportMapper.xml new file mode 100644 index 0000000..a31dd80 --- /dev/null +++ b/test-test/src/main/resources/mapper/test/UiReportMapper.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select id, name, report_type, trigger_mode, description, create_by, create_time, update_by, update_time, del_flag, status, take, faiI_rate, success_assertion, scenes_number, scenes_succeed_number, scenes_error_number, scenes_not_number, steps_number, steps_succeed_number, steps_error_number, steps_not_number,console_str from ui_report + + + + + + + + + insert into ui_report + + name, + report_type, + trigger_mode, + description, + create_by, + create_time, + update_by, + update_time, + del_flag, + status, + take, + faiI_rate, + success_assertion, + scenes_number, + scenes_succeed_number, + scenes_error_number, + scenes_not_number, + steps_number, + steps_succeed_number, + steps_error_number, + steps_not_number, + console_str, + + + #{name}, + #{reportType}, + #{triggerMode}, + #{description}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{delFlag}, + #{status}, + #{take}, + #{faiiRate}, + #{successAssertion}, + #{scenesNumber}, + #{scenesSucceedNumber}, + #{scenesErrorNumber}, + #{scenesNotNumber}, + #{stepsNumber}, + #{stepsSucceedNumber}, + #{stepsErrorNumber}, + #{stepsNotNumber}, + #{consoleStr}, + + + + + update ui_report + + name = #{name}, + report_type = #{reportType}, + trigger_mode = #{triggerMode}, + description = #{description}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + del_flag = #{delFlag}, + status = #{status}, + take = #{take}, + faiI_rate = #{faiiRate}, + success_assertion = #{successAssertion}, + scenes_number = #{scenesNumber}, + scenes_succeed_number = #{scenesSucceedNumber}, + scenes_error_number = #{scenesErrorNumber}, + scenes_not_number = #{scenesNotNumber}, + steps_number = #{stepsNumber}, + steps_succeed_number = #{stepsSucceedNumber}, + steps_error_number = #{stepsErrorNumber}, + steps_not_number = #{stepsNotNumber}, + console_str = #{consoleStr}, + + where id = #{id} + + + + + update ui_report set del_flag = 1 where id = #{id} + + + + update ui_report set del_flag = 1 where id in + + #{id} + + + \ No newline at end of file diff --git a/test-test/src/main/resources/mapper/test/UiSceneStepsMapper.xml b/test-test/src/main/resources/mapper/test/UiSceneStepsMapper.xml index 7e07fb8..6587621 100644 --- a/test-test/src/main/resources/mapper/test/UiSceneStepsMapper.xml +++ b/test-test/src/main/resources/mapper/test/UiSceneStepsMapper.xml @@ -5,68 +5,103 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - select id, automation_id, operate_type, name, step_type, url, is_append_page, operate, operate_object, operate_group_id, operate_element_id, operate_loc_type, operate_loc_value, click_method, Input_value, window_size, sub_options, sub_options_value, await_value, is_disabled, del_flag, create_by, create_time, update_by, update_time, order_number, handle_id, page_index, frame_index from ui_scene_steps + select id, + automation_id, + operate_type, + name, + step_type, + url, + is_append_page, + operate, + operate_object, + operate_group_id, + operate_element_id, + operate_loc_type, + operate_loc_value, + click_method, + Input_value, + window_size, + sub_options, + sub_options_value, + await_value, + is_disabled, + del_flag, + create_by, + create_time, + update_by, + update_time, + order_number, + handle_id, + page_index, + frame_index, + is_enter, + operate_way + from ui_scene_steps @@ -107,6 +142,8 @@ handle_id, page_index, frame_index, + is_enter, + operate_way, #{automationId}, @@ -137,6 +174,8 @@ #{handleId}, #{pageIndex}, #{frameIndex}, + #{isEnter}, + #{operateWay}, @@ -171,12 +210,16 @@ handle_id = #{handleId}, page_index = #{pageIndex}, frame_index = #{frameIndex}, + is_enter = #{isEnter}, + operate_way = #{operateWay}, where id = #{id} - delete from ui_scene_steps where automation_id = #{automationId} + delete + from ui_scene_steps + where automation_id = #{automationId} diff --git a/test-test/src/main/resources/mapper/test/UiSceneStepsReportMapper.xml b/test-test/src/main/resources/mapper/test/UiSceneStepsReportMapper.xml new file mode 100644 index 0000000..996d5d1 --- /dev/null +++ b/test-test/src/main/resources/mapper/test/UiSceneStepsReportMapper.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + select id, + report_id, + name, + create_by, + create_time, + update_by, + update_time, + log_info, + execution_flag, + take, + screenshot, + assertion_json, + extraction_data_json, + order_number + from ui_scene_steps_report + + + + + + + + insert into ui_scene_steps_report + + report_id, + name, + create_by, + create_time, + update_by, + update_time, + log_info, + execution_flag, + take, + screenshot, + assertion_json, + extraction_data_json, + order_number, + + + #{reportId}, + #{name}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{logInfo}, + #{executionFlag}, + #{take}, + #{screenshot}, + #{assertionJson}, + #{extractionDataJson}, + #{orderNumber}, + + + + + update ui_scene_steps_report + + report_id = #{reportId}, + name = #{name}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + log_info = #{logInfo}, + execution_flag = #{executionFlag}, + take = #{take}, + screenshot = #{screenshot}, + assertion_json = #{assertionJson}, + extraction_data_json = #{extractionDataJson}, + order_number = #{orderNumber}, + + where id = #{id} + + + + delete + from ui_scene_steps_report + where id = #{id} + + + + delete from ui_scene_steps_report where report_id in + + #{id} + + + \ No newline at end of file