ui自动化执行接口

This commit is contained in:
2025-04-28 17:00:42 +08:00
parent 5442c6b688
commit 2d8be3482a
6 changed files with 107 additions and 74 deletions

View File

@@ -107,7 +107,7 @@ public class UiAutomationController extends BaseController
*/
// @PreAuthorize("@ss.hasPermi('system:automation:remove')")
@GetMapping("/executeStep")
public AjaxResult remove(@RequestParam Long id)
public AjaxResult executeStep(@RequestParam Long id)
{
try{
log.info("执行完成!");

View File

@@ -187,7 +187,7 @@ public class UiAutomationServiceImpl implements IUiAutomationService {
uiAutomation.setUpdateTime(DateUtils.getNowDate());
uiAutomation.setCreateBy(SecurityUtils.getUsername());
uiAutomation.setUpdateBy(SecurityUtils.getUsername());
uiAutomation.setStatus("1"); //未开始
// uiAutomation.setStatus("1"); //未开始
uiAutomation.setDutyBy(SecurityUtils.getUsername());
uiAutomation.setDelFlag(0);
uiAutomation.setCrontabStatus(0); //未开启

View File

@@ -24,6 +24,7 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -45,7 +46,8 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
@Resource
private UiAutomationMapper uiAutomationMapper;
@Value("${test.selenium.chrome-driver-path}")
private String chromeDriverPath;
/**
@@ -63,15 +65,15 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
//修改ui_automation 状态为进行中 执行结果为running
UiAutomation uiAutomation = new UiAutomation();
uiAutomation.setStatus("2");
uiAutomation.setId(automationId);
uiAutomation.setExecutionResult("1");
uiAutomation.setUpdateBy(DateUtils.getTime());
uiAutomation.setUpdateTime(DateUtils.getNowDate());
uiAutomationMapper.updateUiAutomation(uiAutomation);
Date startTime = DateUtils.getNowDate();
// 2. 创建执行报告
Long reportId = uiReportService.insertUiReport(startTime, automationId, "1", steps.size());
Long reportId = uiReportService.insertUiReport(startTime, automationId, "1", steps.size());
UiReport uiReport = new UiReport();
result.put("id", reportId);
uiReport.setId(reportId);
@@ -80,7 +82,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
for (UiSceneSteps step : steps) {
orderNumber++;
//创建报告步骤表
createSceneStepsReport(orderNumber,step, reportId);
createSceneStepsReport(orderNumber, step, reportId);
}
try {
// 3. 执行所有步骤
@@ -133,20 +135,21 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
uiReport.setStepsNotNumber(stepsNotNumber);
uiReport.setFaiiRate(
stepsErrorNumber == 0 ? "0%" :
String.format("%.2f%%", (double)stepsErrorNumber / steps.size() * 100)
String.format("%.2f%%", (double) stepsErrorNumber / steps.size() * 100)
);
uiReportService.updateUiReport(uiReport);
//修改ui_automation
uiAutomation = new UiAutomation();
if (!uiAutomation.getExecutionResult().equals("2")){
uiAutomation.setExecutionResult("3");
uiAutomation.setStatus("3");
UiAutomation uiAutomation1 = new UiAutomation();
uiAutomation1.setId(automationId);
uiAutomation1.setExecutionResult("2");
if (!uiAutomation.getExecutionResult().equals("2")) {
uiAutomation1.setExecutionResult("3");
}
uiAutomation.setUpdateBy(DateUtils.getTime());
uiAutomation.setPassRate(stepsSucceedNumber == 0 ? "0%" :
String.format("%.2f%%", (double)stepsSucceedNumber / steps.size() * 100));
uiAutomationMapper.updateUiAutomation(uiAutomation);
uiAutomation1.setUpdateTime(DateUtils.getNowDate());
uiAutomation1.setPassRate(stepsSucceedNumber == 0 ? "0%" :
String.format("%.2f%%", (double) stepsSucceedNumber / steps.size() * 100));
uiAutomationMapper.updateUiAutomation(uiAutomation1);
}
return result;
}
@@ -159,7 +162,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
*/
private List<UiSceneSteps> validateAndGetSteps(Long automationId) {
List<UiSceneSteps> steps = uiSceneStepsMapper.selectUiSceneStepsById(automationId);
steps = steps.stream().filter(e->e.getIsDisabled() == 0).collect(Collectors.toList());
steps = steps.stream().filter(e -> e.getIsDisabled() == 0).collect(Collectors.toList());
if (CollectionUtils.isEmpty(steps)) {
throw new IllegalArgumentException("步骤不能为空");
}
@@ -176,7 +179,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
* @param steps
* @param reportId
*/
private Long createSceneStepsReport(Integer orderNumber,UiSceneSteps steps, Long reportId) {
private Long createSceneStepsReport(Integer orderNumber, UiSceneSteps steps, Long reportId) {
UiSceneStepsReport uiSceneStepsReport = new UiSceneStepsReport();
uiSceneStepsReport.setReportId(reportId);
uiSceneStepsReport.setName(steps.getName());
@@ -194,7 +197,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
* @param steps
*/
private void executeAllSteps(List<UiSceneSteps> steps, Long reportId) {
System.setProperty("webdriver.chrome.driver", "D:/chromedriver-win64/chromedriver.exe");
System.setProperty("webdriver.chrome.driver", chromeDriverPath);
WebDriver driver = new ChromeDriver();
SeleniumUtils seleniumUtils = new SeleniumUtils(driver);
Integer orderNumber = 0;
@@ -265,14 +268,13 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
}
/**
* 执行步骤并记录日志
*
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
* @param sceneStepsReportId 报告步骤ID
* @param stepExecution 具体的步骤执行方法
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
* @param sceneStepsReportId 报告步骤ID
* @param stepExecution 具体的步骤执行方法
* @param uiHighSettingVOList 高级设置列表
* @return boolean 是否继续执行后续步骤 (true=继续, false=终止)
*/
@@ -285,7 +287,14 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
OtherSettingsQO otherSettingsQO = otherSetting.getOtherSettingsQO();
Integer screenshotConfiguration = otherSettingsQO.getScreenshotConfiguration(); //是否截图 1当前步骤截图 2异常截图 3 不截图
//等待元素超时时间
Integer waitElementTime = otherSettingsQO.getWaitElementTime()==null?0:otherSettingsQO.getWaitElementTime();
Integer waitElementTime = otherSettingsQO.getWaitElementTime() == null ? 0 : otherSettingsQO.getWaitElementTime();
if (waitElementTime > 0) {
// 转换为秒至少1秒
long timeoutInSeconds = Math.max(1, waitElementTime / 1000);
log.info("元素等待时间{}秒", timeoutInSeconds);
seleniumUtils.setWaitTimeout(timeoutInSeconds);
}
//前置操作设置
List<UiHighSettingVO> beforeSettingList = extractbeforeSetting(uiHighSettingVOList);
//后置操作设置
@@ -309,7 +318,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
if (screenshotConfiguration == 1) {
report.setScreenshot(seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
log.info("截图成功,路径:{}",seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
log.info("截图成功,路径:{}", seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
}
// 3. 执行具体步骤
stepExecution.execute(step, seleniumUtils);
@@ -332,7 +341,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
}
if (screenshotConfiguration == 2) {
report.setScreenshot(seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
log.info("截图成功,路径:{}",seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
log.info("截图成功,路径:{}", seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
}
log.error("步骤执行失败: {}", e.getMessage());
} finally {
@@ -340,7 +349,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
// 更新报告
report.setCreateTime(startTime);
report.setUpdateTime(endTime);
report.setTake(DateUtils.differenceInMilliseconds(startTime,endTime) + "ms");
report.setTake(DateUtils.differenceInMilliseconds(startTime, endTime) + "ms");
uiSceneStepsReportMapper.updateUiSceneStepsReport(report);
}
@@ -350,6 +359,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 提取前置操作
*
* @param settings
* @return
*/
@@ -361,10 +371,11 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 获取(前置//后置)等待时间
*
* @param settingList
* @return
*/
private int getAwaitTime(List<UiHighSettingVO> settingList){
private int getAwaitTime(List<UiHighSettingVO> settingList) {
//获取前置等待时间
int totalWaitTime = settingList.stream()
.map(UiHighSettingVO::getAwateTime)
@@ -384,6 +395,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 提取后置操作
*
* @param settings
* @return
*/
@@ -395,6 +407,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 提取错误处理设置
*
* @param settings
* @return
*/
@@ -406,10 +419,9 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
}
/**
* 提取错误处理设置
*
* @param settings
* @return
*/
@@ -421,56 +433,60 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
}
//---------------------浏览器操作---------------------------
/**
* 打开网页
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void openWebPage(UiSceneSteps step, SeleniumUtils seleniumUtils) {
log.info("打开网页:{}",step.getUrl());
seleniumUtils.openUrl(step.getUrl());
//追加页面在新的页面打开url不勾选覆盖当前url 0不追加 1追加
Integer isAppendPage = step.getIsAppendPage(); // 0=当前页1=新标签页
String url = step.getUrl();
log.info("打开网页:{}, 模式:{}", url, isAppendPage == 1 ? "新标签页" : "当前页");
if (isAppendPage != null && isAppendPage == 1) {
// 新标签页打开
seleniumUtils.openUrlInNewTab(url);
} else {
// 默认当前页打开
seleniumUtils.openUrl(url);
}
}
/**
* 关闭网页
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void closeBrowser(UiSceneSteps step, SeleniumUtils seleniumUtils) {
log.info("关闭网页");
seleniumUtils.quit();
seleniumUtils.closeCurrentWindow();
}
/**
* 切换窗口
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void switchWindow(UiSceneSteps step, SeleniumUtils seleniumUtils) {
if (step.getOperate()==1){
if (step.getOperate() == 1) {
log.info("根据句柄 ID 切换到指定窗口");
//句柄id
String handleId = step.getHandleId();
seleniumUtils.switchToWindowByHandle(handleId);
}else if (step.getOperate()==2){
} else if (step.getOperate() == 2) {
log.info("根据网页索引号切换到指定窗口");
//网页索引号
Integer frameIndex = step.getFrameIndex();
seleniumUtils.switchToWindowByIndex(frameIndex);
}else if (step.getOperate()==3){
} else if (step.getOperate() == 3) {
log.info("切换到初始窗口");
seleniumUtils.switchToDefaultWindow();
}else{
} else {
log.info("无效的窗口切换操作类型");
throw new IllegalArgumentException("无效的窗口切换操作类型");
}
@@ -479,22 +495,22 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 设置窗口大小
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void resizeWindow(UiSceneSteps step, SeleniumUtils seleniumUtils) {
if (step.getOperate()==1){
if (step.getOperate() == 1) {
log.info("窗口最大化");
//窗口最大化
seleniumUtils.maximizeWindow();
}else if (step.getOperate()==2){
} else if (step.getOperate() == 2) {
log.info("设置窗口大小");
String windowSize = step.getWindowSize();
String[] dimensions = windowSize.split("\\*");
int width = Integer.parseInt(dimensions[0]);
int height = Integer.parseInt(dimensions[1]);
seleniumUtils.setWindowSize(width, height);
}else{
} else {
log.info("无效的设置窗口大小");
throw new IllegalArgumentException("无效的设置窗口大小");
}
@@ -504,18 +520,18 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 选择内嵌网页
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void selectEmbeddedPage(UiSceneSteps step, SeleniumUtils seleniumUtils) {
if (step.getOperate()==1){
if (step.getOperate() == 1) {
log.info("退出当前 frame(回到主页面)");
seleniumUtils.switchToDefaultContent();
}else if (step.getOperate()==2){
} else if (step.getOperate() == 2) {
log.info("根据 frame 索引号切换到指定 frame");
//网页索引号
seleniumUtils.switchToFrameByIndex(step.getFrameIndex());
}else if (step.getOperate()==3){
} else if (step.getOperate() == 3) {
log.info("根据定位方式切换 frame");
if ("2".equals(step.getOperateObject())) {
//元素对象
@@ -525,7 +541,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
operateLocType,
operateLocValue
);
}else{
} else {
//元素定位
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
if (uiElement == null) {
@@ -538,7 +554,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
elementLoc
);
}
} else{
} else {
log.info("无效的选择内嵌网页");
throw new IllegalArgumentException("无效的选择内嵌网页");
}
@@ -550,11 +566,11 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 弹窗操作
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void handlePopup(UiSceneSteps step, SeleniumUtils seleniumUtils) {
if (step.getOperate()==1){
if (step.getOperate() == 1) {
log.info("弹窗操作");
// 获取输入内容(如果需要)
String inputValue = "1".equals(step.getIsEnter()) ? step.getInputValue() : null;
@@ -564,7 +580,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
Integer.parseInt(operateWay), // 操作方式 (1=确定, 2=取消)
inputValue // 输入内容
);
}else{
} else {
log.info("无效的弹窗操作");
throw new IllegalArgumentException("无效的弹窗操作");
}
@@ -575,7 +591,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 提交表单
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void submitForm(UiSceneSteps step, SeleniumUtils seleniumUtils) {
@@ -586,7 +602,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
// 根据属性和值定位元素并提交表单
seleniumUtils.findElement(operateLocType, operateLocValue).submit();
log.info("通过元素对象提交表单,定位方式:{},定位值:{}", operateLocType, operateLocValue);
}else{
} else {
//元素定位
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
if (uiElement == null) {
@@ -603,7 +619,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 下拉框操作
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void handleDropdown(UiSceneSteps step, SeleniumUtils seleniumUtils) {
@@ -616,7 +632,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
String operateLocValue = step.getOperateLocValue(); //值
dropdownElement = seleniumUtils.findElement(operateLocType, operateLocValue);
log.info("通过元素对象定位下拉框,定位方式:{},定位值:{}", operateLocType, operateLocValue);
}else{
} else {
//元素定位
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
if (uiElement == null) {
@@ -648,7 +664,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 设置选项
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void setOption(UiSceneSteps step, SeleniumUtils seleniumUtils) {
@@ -696,7 +712,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 等待元素
*
* @param step 步骤对象
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void waitForElement(UiSceneSteps step, SeleniumUtils seleniumUtils) {
@@ -712,7 +728,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
operateLocType,
operateLocValue
);
}else{
} else {
//元素定位
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
String locType = uiElement.getLocType(); //属性
@@ -746,7 +762,8 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
/**
* 鼠标点击操作
* @param step 步骤对象
*
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void mouseClick(UiSceneSteps step, SeleniumUtils seleniumUtils) {
@@ -781,13 +798,14 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
throw new RuntimeException("鼠标操作类型必须是数字(1-5)", e);
} catch (Exception e) {
log.error("鼠标操作执行失败", e);
throw new RuntimeException("鼠标操作失败: " + e.getMessage(), e);
throw new RuntimeException("鼠标操作失败: " + e, e);
}
}
/**
* 鼠标移动操作
* @param step 步骤对象
*
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
private void mouseMove(UiSceneSteps step, SeleniumUtils seleniumUtils) {
@@ -824,13 +842,14 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
throw new RuntimeException("鼠标移动类型必须是数字(1-2)", e);
} catch (Exception e) {
log.error("鼠标移动操作执行失败", e);
throw new RuntimeException("鼠标移动操作失败: " + e.getMessage(), e);
throw new RuntimeException("鼠标移动操作失败: " + e, e);
}
}
/**
* 输入操作
* @param step 步骤对象
*
* @param step 步骤对象
* @param seleniumUtils Selenium工具类
*/
public void inputText(UiSceneSteps step, SeleniumUtils seleniumUtils) {
@@ -883,16 +902,17 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
} catch (Exception e) {
log.error("输入操作执行失败", e);
throw new RuntimeException("输入操作失败: " + e.getMessage(), e);
throw new RuntimeException("输入操作失败: " + e, e);
}
}
/**
* 文件上传
*
* @param step
* @param seleniumUtils
*/
public void uploadFile(UiSceneSteps step, SeleniumUtils seleniumUtils){
public void uploadFile(UiSceneSteps step, SeleniumUtils seleniumUtils) {
}

View File

@@ -56,7 +56,7 @@
<if test="stepsErrorNumber != null "> and steps_error_number = #{stepsErrorNumber}</if>
<if test="stepsNotNumber != null "> and steps_not_number = #{stepsNotNumber}</if>
</where>
order by create_time asc
order by create_time desc
</select>
<select id="selectUiReportById" parameterType="Long" resultMap="UiReportResult">