UI执行接口
This commit is contained in:
@@ -52,11 +52,11 @@ public class UiSceneSteps extends BaseEntity
|
||||
|
||||
/** 元素库名称 */
|
||||
@Excel(name = "元素库名称")
|
||||
private Integer operateGroupId;
|
||||
private Long operateGroupId;
|
||||
|
||||
/** 元素id */
|
||||
@Excel(name = "元素id")
|
||||
private Integer operateElementId;
|
||||
private Long operateElementId;
|
||||
|
||||
/** 元素定位类型 */
|
||||
@Excel(name = "元素定位类型")
|
||||
@@ -76,7 +76,7 @@ public class UiSceneSteps extends BaseEntity
|
||||
|
||||
/** 窗口尺寸 */
|
||||
@Excel(name = "窗口尺寸")
|
||||
private Integer windowSize;
|
||||
private String windowSize;
|
||||
|
||||
/** 子选项 */
|
||||
@Excel(name = "子选项")
|
||||
@@ -201,21 +201,21 @@ public class UiSceneSteps extends BaseEntity
|
||||
{
|
||||
return operateObject;
|
||||
}
|
||||
public void setOperateGroupId(Integer operateGroupId)
|
||||
public void setOperateGroupId(Long operateGroupId)
|
||||
{
|
||||
this.operateGroupId = operateGroupId;
|
||||
}
|
||||
|
||||
public Integer getOperateGroupId()
|
||||
public Long getOperateGroupId()
|
||||
{
|
||||
return operateGroupId;
|
||||
}
|
||||
public void setOperateElementId(Integer operateElementId)
|
||||
public void setOperateElementId(Long operateElementId)
|
||||
{
|
||||
this.operateElementId = operateElementId;
|
||||
}
|
||||
|
||||
public Integer getOperateElementId()
|
||||
public Long getOperateElementId()
|
||||
{
|
||||
return operateElementId;
|
||||
}
|
||||
@@ -255,12 +255,12 @@ public class UiSceneSteps extends BaseEntity
|
||||
{
|
||||
return inputValue;
|
||||
}
|
||||
public void setWindowSize(Integer windowSize)
|
||||
public void setWindowSize(String windowSize)
|
||||
{
|
||||
this.windowSize = windowSize;
|
||||
}
|
||||
|
||||
public Integer getWindowSize()
|
||||
public String getWindowSize()
|
||||
{
|
||||
return windowSize;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class UiSceneStepsQO extends BaseEntity
|
||||
private String inputValue;
|
||||
|
||||
/** 窗口尺寸 */
|
||||
private Integer windowSize;
|
||||
private String windowSize;
|
||||
|
||||
/** 子选项 */
|
||||
private String subOptions;
|
||||
|
||||
@@ -190,6 +190,7 @@ public class UiAutomationServiceImpl implements IUiAutomationService {
|
||||
uiAutomation.setStatus("1"); //未开始
|
||||
uiAutomation.setDutyBy(SecurityUtils.getUsername());
|
||||
uiAutomation.setDelFlag(0);
|
||||
uiAutomation.setCrontabStatus(0); //未开启
|
||||
uiAutomationMapper.insertUiAutomation(uiAutomation);
|
||||
Long automationId = uiAutomation.getId();
|
||||
//新增场景步骤
|
||||
|
||||
@@ -1,32 +1,26 @@
|
||||
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.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.test.common.config.TestConfig;
|
||||
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.*;
|
||||
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 com.test.test.service.*;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.checkerframework.checker.units.qual.C;
|
||||
import org.openqa.selenium.By;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.WebElement;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -46,18 +40,12 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
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;
|
||||
@Resource
|
||||
private IUiElementService uiElementService;
|
||||
@Resource
|
||||
private UiAutomationMapper uiAutomationMapper;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -72,7 +60,14 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
result.put("id", 0L);
|
||||
// 1. 验证并获取步骤
|
||||
List<UiSceneSteps> steps = validateAndGetSteps(automationId);
|
||||
stepsNotNumber = steps.size();
|
||||
|
||||
//修改ui_automation 状态为进行中 执行结果为running
|
||||
UiAutomation uiAutomation = new UiAutomation();
|
||||
uiAutomation.setStatus("2");
|
||||
uiAutomation.setExecutionResult("1");
|
||||
uiAutomation.setUpdateBy(DateUtils.getTime());
|
||||
uiAutomationMapper.updateUiAutomation(uiAutomation);
|
||||
|
||||
|
||||
Date startTime = DateUtils.getNowDate();
|
||||
// 2. 创建执行报告
|
||||
@@ -91,22 +86,48 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
// 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);
|
||||
uiAutomation.setExecutionResult("2");
|
||||
} finally {
|
||||
endTime = DateUtils.getNowDate();
|
||||
uiReport.setTake(DateUtils.calculateTimeDifference(startTime, endTime));
|
||||
uiReport.setUpdateTime(endTime);
|
||||
//查询report
|
||||
UiSceneStepsReport uiStepsReport = new UiSceneStepsReport();
|
||||
uiStepsReport.setReportId(reportId);
|
||||
List<UiSceneStepsReport> uiSceneStepsReports = uiSceneStepsReportMapper.selectUiSceneStepsReportList(uiStepsReport);
|
||||
int scenesSucceedNumber = 0;
|
||||
int scenesErrorNumber = 0;
|
||||
int stepsSucceedNumber = 0;
|
||||
int stepsErrorNumber = 0;
|
||||
int stepsNotNumber = 0;
|
||||
if (uiSceneStepsReports != null && !uiSceneStepsReports.isEmpty()) {
|
||||
boolean allSuccess = true;
|
||||
for (UiSceneStepsReport report : uiSceneStepsReports) {
|
||||
if (report.getExecutionFlag().equals("1")) {
|
||||
stepsSucceedNumber++;
|
||||
} else if (report.getExecutionFlag().equals("2")) {
|
||||
stepsErrorNumber++;
|
||||
allSuccess = false;
|
||||
} else if (report.getExecutionFlag().equals("0")) {
|
||||
stepsNotNumber++;
|
||||
}
|
||||
}
|
||||
if (allSuccess) {
|
||||
scenesSucceedNumber = 1;
|
||||
} else {
|
||||
scenesErrorNumber = 1;
|
||||
}
|
||||
}
|
||||
uiReport.setScenesSucceedNumber(scenesSucceedNumber);
|
||||
uiReport.setScenesErrorNumber(scenesErrorNumber);
|
||||
uiReport.setScenesNotNumber(scenesNotNumber);
|
||||
uiReport.setScenesNotNumber(0);
|
||||
uiReport.setStepsSucceedNumber(stepsSucceedNumber);
|
||||
uiReport.setStepsErrorNumber(stepsErrorNumber);
|
||||
uiReport.setStepsNotNumber(stepsNotNumber);
|
||||
@@ -116,6 +137,16 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
);
|
||||
uiReportService.updateUiReport(uiReport);
|
||||
|
||||
//修改ui_automation
|
||||
uiAutomation = new UiAutomation();
|
||||
if (!uiAutomation.getExecutionResult().equals("2")){
|
||||
uiAutomation.setExecutionResult("3");
|
||||
uiAutomation.setStatus("3");
|
||||
}
|
||||
uiAutomation.setUpdateBy(DateUtils.getTime());
|
||||
uiAutomation.setPassRate(stepsSucceedNumber == 0 ? "0%" :
|
||||
String.format("%.2f%%", (double)stepsSucceedNumber / steps.size() * 100));
|
||||
uiAutomationMapper.updateUiAutomation(uiAutomation);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -128,6 +159,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());
|
||||
if (CollectionUtils.isEmpty(steps)) {
|
||||
throw new IllegalArgumentException("步骤不能为空");
|
||||
}
|
||||
@@ -186,30 +218,29 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
// 定义所有操作类型的执行方法映射
|
||||
Map<String, Map<String, StepExecution>> operationStrategies = Map.of(
|
||||
"1", Map.of( // 浏览器操作
|
||||
"1", this::openWebPage
|
||||
// "2", this::closeBrowser,
|
||||
// "3", this::switchWindow,
|
||||
// "4", this::resizeWindow,
|
||||
// "5", this::selectEmbeddedPage
|
||||
"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
|
||||
),
|
||||
"5", Map.of( // 输入操作
|
||||
"1", this::inputText,
|
||||
"2", this::uploadFile
|
||||
)
|
||||
// "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
|
||||
// )
|
||||
);
|
||||
|
||||
// 获取对应的操作类型映射
|
||||
@@ -253,7 +284,16 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
UiHighSettingVO otherSetting = extractOtherSetting(uiHighSettingVOList);
|
||||
OtherSettingsQO otherSettingsQO = otherSetting.getOtherSettingsQO();
|
||||
Integer screenshotConfiguration = otherSettingsQO.getScreenshotConfiguration(); //是否截图 1当前步骤截图 2异常截图 3 不截图
|
||||
|
||||
//等待元素超时时间
|
||||
Integer waitElementTime = otherSettingsQO.getWaitElementTime()==null?0:otherSettingsQO.getWaitElementTime();
|
||||
//前置操作设置
|
||||
List<UiHighSettingVO> beforeSettingList = extractbeforeSetting(uiHighSettingVOList);
|
||||
//后置操作设置
|
||||
List<UiHighSettingVO> afterSettingList = extractafterSetting(uiHighSettingVOList);
|
||||
//前置等待时间
|
||||
int beforeAwaitTime = getAwaitTime(beforeSettingList);
|
||||
//后置等待时间
|
||||
int afterAwaitTime = getAwaitTime(afterSettingList);
|
||||
// 2. 准备报告对象
|
||||
UiSceneStepsReport report = new UiSceneStepsReport();
|
||||
report.setId(sceneStepsReportId);
|
||||
@@ -261,28 +301,42 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
Date endTime = null;
|
||||
boolean continueExecution = true; // 默认继续执行
|
||||
try {
|
||||
stepsSucceedNumber++;
|
||||
if (screenshotConfiguration == 1) {
|
||||
// 执行前置等待
|
||||
if (beforeAwaitTime > 0) {
|
||||
log.info("执行前置等待: {}ms", beforeAwaitTime);
|
||||
Thread.sleep(beforeAwaitTime);
|
||||
}
|
||||
|
||||
if (screenshotConfiguration == 1) {
|
||||
report.setScreenshot(seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
|
||||
log.info("截图成功,路径:{}",seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
|
||||
}
|
||||
// 3. 执行具体步骤
|
||||
stepExecution.execute(step, seleniumUtils);
|
||||
|
||||
// 执行后置等待
|
||||
if (afterAwaitTime > 0) {
|
||||
log.info("执行后置等待: {}ms", afterAwaitTime);
|
||||
Thread.sleep(afterAwaitTime);
|
||||
}
|
||||
|
||||
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; // 不继续执行后续步骤
|
||||
}
|
||||
if (screenshotConfiguration == 2) {
|
||||
report.setScreenshot(seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
|
||||
log.info("截图成功,路径:{}",seleniumUtils.takeScreenshotAsFile(TestConfig.getProfile()));
|
||||
}
|
||||
log.error("步骤执行失败: {}", e.getMessage());
|
||||
} finally {
|
||||
endTime = DateUtils.getNowDate();
|
||||
stepsNotNumber--;
|
||||
// 更新报告
|
||||
report.setCreateTime(startTime);
|
||||
report.setUpdateTime(endTime);
|
||||
@@ -293,6 +347,52 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
return continueExecution;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提取前置操作
|
||||
* @param settings
|
||||
* @return
|
||||
*/
|
||||
private List<UiHighSettingVO> extractbeforeSetting(List<UiHighSettingVO> settings) {
|
||||
return settings.stream()
|
||||
.filter(e -> "1".equals(e.getSettingType()) && e.getIsDisabled() == 0)
|
||||
.collect(Collectors.toList()); // 返回默认设置
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取(前置//后置)等待时间
|
||||
* @param settingList
|
||||
* @return
|
||||
*/
|
||||
private int getAwaitTime(List<UiHighSettingVO> settingList){
|
||||
//获取前置等待时间
|
||||
int totalWaitTime = settingList.stream()
|
||||
.map(UiHighSettingVO::getAwateTime)
|
||||
.filter(Objects::nonNull)
|
||||
.filter(s -> !s.isEmpty())
|
||||
.mapToInt(s -> {
|
||||
try {
|
||||
return Integer.parseInt(s);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
.sum();
|
||||
return totalWaitTime;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提取后置操作
|
||||
* @param settings
|
||||
* @return
|
||||
*/
|
||||
private List<UiHighSettingVO> extractafterSetting(List<UiHighSettingVO> settings) {
|
||||
return settings.stream()
|
||||
.filter(e -> "2".equals(e.getSettingType()) && e.getIsDisabled() == 0)
|
||||
.collect(Collectors.toList()); // 返回默认设置
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取错误处理设置
|
||||
* @param settings
|
||||
@@ -305,6 +405,9 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
.orElse(new UiHighSettingVO()); // 返回默认设置
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 提取错误处理设置
|
||||
* @param settings
|
||||
@@ -317,6 +420,14 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
.orElse(new UiHighSettingVO()); // 返回默认设置
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------浏览器操作---------------------------
|
||||
|
||||
/**
|
||||
* 打开网页
|
||||
*
|
||||
@@ -324,8 +435,465 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService {
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void openWebPage(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
log.info("打开网页:{}",step.getUrl());
|
||||
seleniumUtils.openUrl(step.getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭网页
|
||||
*
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void closeBrowser(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
log.info("关闭网页");
|
||||
seleniumUtils.quit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换窗口
|
||||
*
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void switchWindow(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
if (step.getOperate()==1){
|
||||
log.info("根据句柄 ID 切换到指定窗口");
|
||||
//句柄id
|
||||
String handleId = step.getHandleId();
|
||||
seleniumUtils.switchToWindowByHandle(handleId);
|
||||
}else if (step.getOperate()==2){
|
||||
log.info("根据网页索引号切换到指定窗口");
|
||||
//网页索引号
|
||||
Integer frameIndex = step.getFrameIndex();
|
||||
seleniumUtils.switchToWindowByIndex(frameIndex);
|
||||
}else if (step.getOperate()==3){
|
||||
log.info("切换到初始窗口");
|
||||
seleniumUtils.switchToDefaultWindow();
|
||||
}else{
|
||||
log.info("无效的窗口切换操作类型");
|
||||
throw new IllegalArgumentException("无效的窗口切换操作类型");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置窗口大小
|
||||
*
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void resizeWindow(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
if (step.getOperate()==1){
|
||||
log.info("窗口最大化");
|
||||
//窗口最大化
|
||||
seleniumUtils.maximizeWindow();
|
||||
}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{
|
||||
log.info("无效的设置窗口大小");
|
||||
throw new IllegalArgumentException("无效的设置窗口大小");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 选择内嵌网页
|
||||
*
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void selectEmbeddedPage(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
if (step.getOperate()==1){
|
||||
log.info("退出当前 frame(回到主页面)");
|
||||
seleniumUtils.switchToDefaultContent();
|
||||
}else if (step.getOperate()==2){
|
||||
log.info("根据 frame 索引号切换到指定 frame");
|
||||
//网页索引号
|
||||
seleniumUtils.switchToFrameByIndex(step.getFrameIndex());
|
||||
}else if (step.getOperate()==3){
|
||||
log.info("根据定位方式切换 frame");
|
||||
if ("2".equals(step.getOperateObject())) {
|
||||
//元素对象
|
||||
String operateLocType = step.getOperateLocType(); //属性
|
||||
String operateLocValue = step.getOperateLocValue(); //值
|
||||
seleniumUtils.switchToFrameByLocator(
|
||||
operateLocType,
|
||||
operateLocValue
|
||||
);
|
||||
}else{
|
||||
//元素定位
|
||||
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
|
||||
if (uiElement == null) {
|
||||
throw new IllegalArgumentException("未找到ID为 " + step.getOperateElementId() + " 的元素");
|
||||
}
|
||||
String locType = uiElement.getLocType(); //属性
|
||||
String elementLoc = uiElement.getElementLoc();//值
|
||||
seleniumUtils.switchToFrameByLocator(
|
||||
locType,
|
||||
elementLoc
|
||||
);
|
||||
}
|
||||
} else{
|
||||
log.info("无效的选择内嵌网页");
|
||||
throw new IllegalArgumentException("无效的选择内嵌网页");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------弹窗操作--------------------
|
||||
|
||||
/**
|
||||
* 弹窗操作
|
||||
*
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void handlePopup(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
if (step.getOperate()==1){
|
||||
log.info("弹窗操作");
|
||||
// 获取输入内容(如果需要)
|
||||
String inputValue = "1".equals(step.getIsEnter()) ? step.getInputValue() : null;
|
||||
String operateWay = step.getOperateWay(); //操作方式 1确定 2取消
|
||||
// 执行弹窗操作
|
||||
seleniumUtils.handleAlert(
|
||||
Integer.parseInt(operateWay), // 操作方式 (1=确定, 2=取消)
|
||||
inputValue // 输入内容
|
||||
);
|
||||
}else{
|
||||
log.info("无效的弹窗操作");
|
||||
throw new IllegalArgumentException("无效的弹窗操作");
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------元素操作----------------------------------
|
||||
|
||||
/**
|
||||
* 提交表单
|
||||
*
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void submitForm(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
if ("2".equals(step.getOperateObject())) {
|
||||
//元素对象
|
||||
String operateLocType = step.getOperateLocType(); //属性
|
||||
String operateLocValue = step.getOperateLocValue(); //值
|
||||
// 根据属性和值定位元素并提交表单
|
||||
seleniumUtils.findElement(operateLocType, operateLocValue).submit();
|
||||
log.info("通过元素对象提交表单,定位方式:{},定位值:{}", operateLocType, operateLocValue);
|
||||
}else{
|
||||
//元素定位
|
||||
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
|
||||
if (uiElement == null) {
|
||||
throw new IllegalArgumentException("未找到ID为 " + step.getOperateElementId() + " 的元素");
|
||||
}
|
||||
String locType = uiElement.getLocType(); //属性
|
||||
String elementLoc = uiElement.getElementLoc();//值
|
||||
seleniumUtils.findElement(locType, elementLoc).submit();
|
||||
log.info("通过元素定位提交表单,定位方式:{},定位值:{}", locType, elementLoc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 下拉框操作
|
||||
*
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void handleDropdown(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
log.info("下拉框操作");
|
||||
Integer operate = step.getOperate(); //操作 1选择 2取消
|
||||
WebElement dropdownElement;
|
||||
if ("2".equals(step.getOperateObject())) {
|
||||
//元素对象
|
||||
String operateLocType = step.getOperateLocType(); //属性
|
||||
String operateLocValue = step.getOperateLocValue(); //值
|
||||
dropdownElement = seleniumUtils.findElement(operateLocType, operateLocValue);
|
||||
log.info("通过元素对象定位下拉框,定位方式:{},定位值:{}", operateLocType, operateLocValue);
|
||||
}else{
|
||||
//元素定位
|
||||
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
|
||||
if (uiElement == null) {
|
||||
throw new IllegalArgumentException("未找到ID为 " + step.getOperateElementId() + " 的元素");
|
||||
}
|
||||
String locType = uiElement.getLocType(); //属性
|
||||
String elementLoc = uiElement.getElementLoc();//值
|
||||
dropdownElement = seleniumUtils.findElement(locType, elementLoc);
|
||||
log.info("通过元素定位定位下拉框,定位方式:{},定位值:{}", locType, elementLoc);
|
||||
}
|
||||
//子选项
|
||||
String subOptions = step.getSubOptions(); //1 选项 2索引 3值
|
||||
String subOptionsValue = step.getSubOptionsValue(); //值
|
||||
|
||||
if (operate == 1) {
|
||||
// 选择操作
|
||||
seleniumUtils.selectDropdownOption(dropdownElement, subOptions, subOptionsValue);
|
||||
} else if (operate == 2) {
|
||||
// 取消操作
|
||||
// 如果需要取消下拉框的选择,可以使用默认选项或其他逻辑
|
||||
log.info("取消下拉框选择");
|
||||
// 示例:取消选择(假设下拉框的第一个选项是默认选项)
|
||||
seleniumUtils.selectDropdownOption(dropdownElement, "2", "0");
|
||||
} else {
|
||||
throw new IllegalArgumentException("无效的操作类型: " + operate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置选项
|
||||
*
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void setOption(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
log.info("设置选项");
|
||||
Integer operate = step.getOperate(); // 操作 1选择 2取消
|
||||
WebElement element;
|
||||
|
||||
if ("2".equals(step.getOperateObject())) {
|
||||
// 元素对象
|
||||
String operateLocType = step.getOperateLocType(); // 属性
|
||||
String operateLocValue = step.getOperateLocValue(); // 值
|
||||
element = seleniumUtils.findElement(operateLocType, operateLocValue);
|
||||
log.info("通过元素对象定位选项,定位方式:{},定位值:{}", operateLocType, operateLocValue);
|
||||
} else {
|
||||
// 元素定位
|
||||
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
|
||||
if (uiElement == null) {
|
||||
log.error("未找到指定的元素,元素ID:{}", step.getOperateElementId());
|
||||
throw new IllegalArgumentException("未找到指定的元素");
|
||||
}
|
||||
String locType = uiElement.getLocType(); // 属性
|
||||
String elementLoc = uiElement.getElementLoc(); // 值
|
||||
element = seleniumUtils.findElement(locType, elementLoc);
|
||||
log.info("通过元素定位定位选项,定位方式:{},定位值:{}", locType, elementLoc);
|
||||
}
|
||||
|
||||
if (operate == 1) {
|
||||
// 选择操作
|
||||
if (!element.isSelected()) {
|
||||
element.click();
|
||||
log.info("设置选项为选中状态");
|
||||
}
|
||||
} else if (operate == 2) {
|
||||
// 取消操作
|
||||
if (element.isSelected()) {
|
||||
element.click();
|
||||
log.info("设置选项为未选中状态");
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("无效的操作类型: " + operate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 等待元素
|
||||
*
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void waitForElement(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
log.info("等待元素");
|
||||
//操作 1等待元素等于给定的定值(Text) 2 等待元素存在 3等待元素显示 4等待元素不显示 5等待元素不存在 6等待元素可编辑 7等待元素不可编辑
|
||||
By locator;
|
||||
if ("2".equals(step.getOperateObject())) {
|
||||
//元素对象
|
||||
String operateLocType = step.getOperateLocType(); //属性
|
||||
String operateLocValue = step.getOperateLocValue(); //值
|
||||
// 使用直接指定的定位方式
|
||||
locator = seleniumUtils.getLocator(
|
||||
operateLocType,
|
||||
operateLocValue
|
||||
);
|
||||
}else{
|
||||
//元素定位
|
||||
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
|
||||
String locType = uiElement.getLocType(); //属性
|
||||
String elementLoc = uiElement.getElementLoc();//值
|
||||
locator = seleniumUtils.getLocator(
|
||||
locType,
|
||||
elementLoc
|
||||
);
|
||||
}
|
||||
// 解析等待时间(默认15000ms)
|
||||
long timeout = 15000;
|
||||
if (step.getOperate() != 1 && step.getAwaitValue() != null) {
|
||||
try {
|
||||
timeout = Long.parseLong(step.getAwaitValue());
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("等待时间格式错误,使用默认值15000ms");
|
||||
}
|
||||
}
|
||||
// 执行等待操作
|
||||
seleniumUtils.waitForElement(
|
||||
locator,
|
||||
step.getOperate(),
|
||||
step.getOperate() == 1 ? step.getAwaitValue() : null,
|
||||
timeout
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------鼠标操作------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* 鼠标点击操作
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void mouseClick(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
try {
|
||||
log.info("执行鼠标操作,方式: {}", step.getClickMethod());
|
||||
// 获取定位器
|
||||
By locator;
|
||||
if ("2".equals(step.getOperateObject())) {
|
||||
// 使用直接指定的定位方式
|
||||
locator = seleniumUtils.getLocator(
|
||||
step.getOperateLocType(),
|
||||
step.getOperateLocValue()
|
||||
);
|
||||
} else {
|
||||
// 使用元素ID从数据库获取定位信息
|
||||
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
|
||||
if (uiElement == null) {
|
||||
throw new IllegalArgumentException("未找到ID为 " + step.getOperateElementId() + " 的元素");
|
||||
}
|
||||
locator = seleniumUtils.getLocator(
|
||||
uiElement.getLocType(),
|
||||
uiElement.getElementLoc()
|
||||
);
|
||||
}
|
||||
// 执行鼠标操作
|
||||
seleniumUtils.performMouseAction(
|
||||
locator,
|
||||
Integer.parseInt(step.getClickMethod())
|
||||
);
|
||||
} catch (NumberFormatException e) {
|
||||
log.error("鼠标操作类型格式错误: {}", step.getClickMethod());
|
||||
throw new RuntimeException("鼠标操作类型必须是数字(1-5)", e);
|
||||
} catch (Exception e) {
|
||||
log.error("鼠标操作执行失败", e);
|
||||
throw new RuntimeException("鼠标操作失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 鼠标移动操作
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
private void mouseMove(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
try {
|
||||
log.info("执行鼠标移动操作,方式: {}", step.getClickMethod());
|
||||
// 获取定位器
|
||||
By locator;
|
||||
if ("2".equals(step.getOperateObject())) {
|
||||
// 使用直接指定的定位方式
|
||||
locator = seleniumUtils.getLocator(
|
||||
step.getOperateLocType(),
|
||||
step.getOperateLocValue()
|
||||
);
|
||||
} else {
|
||||
// 使用元素ID从数据库获取定位信息
|
||||
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
|
||||
if (uiElement == null) {
|
||||
throw new IllegalArgumentException("未找到ID为 " + step.getOperateElementId() + " 的元素");
|
||||
}
|
||||
locator = seleniumUtils.getLocator(
|
||||
uiElement.getLocType(),
|
||||
uiElement.getElementLoc()
|
||||
);
|
||||
}
|
||||
// 执行鼠标移动操作
|
||||
seleniumUtils.performMouseMove(
|
||||
locator,
|
||||
Integer.parseInt(step.getClickMethod()) // 1=移出,2=移入
|
||||
);
|
||||
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
log.error("鼠标移动类型格式错误: {}", step.getClickMethod());
|
||||
throw new RuntimeException("鼠标移动类型必须是数字(1-2)", e);
|
||||
} catch (Exception e) {
|
||||
log.error("鼠标移动操作执行失败", e);
|
||||
throw new RuntimeException("鼠标移动操作失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 输入操作
|
||||
* @param step 步骤对象
|
||||
* @param seleniumUtils Selenium工具类
|
||||
*/
|
||||
public void inputText(UiSceneSteps step, SeleniumUtils seleniumUtils) {
|
||||
try {
|
||||
log.info("执行输入操作,类型: {}", step.getOperate());
|
||||
|
||||
// 获取定位器
|
||||
By locator;
|
||||
if ("2".equals(step.getOperateObject())) {
|
||||
// 使用直接指定的定位方式
|
||||
locator = seleniumUtils.getLocator(
|
||||
step.getOperateLocType(),
|
||||
step.getOperateLocValue()
|
||||
);
|
||||
} else {
|
||||
// 使用元素ID从数据库获取定位信息
|
||||
UiElement uiElement = uiElementService.selectUiElementById(step.getOperateElementId());
|
||||
if (uiElement == null) {
|
||||
throw new IllegalArgumentException("未找到ID为 " + step.getOperateElementId() + " 的元素");
|
||||
}
|
||||
locator = seleniumUtils.getLocator(
|
||||
uiElement.getLocType(),
|
||||
uiElement.getElementLoc()
|
||||
);
|
||||
}
|
||||
|
||||
// 获取输入内容
|
||||
String inputValue = step.getInputValue();
|
||||
if (inputValue == null || inputValue.trim().isEmpty()) {
|
||||
log.warn("输入内容为空,将执行清空操作");
|
||||
seleniumUtils.clearInput(locator);
|
||||
return;
|
||||
}
|
||||
// 执行输入操作
|
||||
if (step.getOperate() == 1) { // 普通输入框
|
||||
seleniumUtils.inputText(
|
||||
locator,
|
||||
inputValue,
|
||||
true, // 默认先清空
|
||||
1 // 默认使用普通输入方式
|
||||
);
|
||||
} else if (step.getOperate() == 2) { // 可编辑段落
|
||||
seleniumUtils.inputToEditableDiv(
|
||||
locator,
|
||||
inputValue
|
||||
);
|
||||
} else {
|
||||
throw new IllegalArgumentException("不支持的输入操作类型: " + step.getOperate());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("输入操作执行失败", e);
|
||||
throw new RuntimeException("输入操作失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param step
|
||||
* @param seleniumUtils
|
||||
*/
|
||||
public void uploadFile(UiSceneSteps step, SeleniumUtils seleniumUtils){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,10 +22,12 @@
|
||||
<result property="crontabStatus" column="crontab_status" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="description" column="description" />
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectUiAutomationVo">
|
||||
select id, group_id, name, case_level, status, label, create_by, duty_by, run_environment, update_time, steps_number, execution_result, pass_rate, crontab, crontab_status, del_flag,description from ui_automation
|
||||
select id, group_id, name, case_level, status, label, create_by, duty_by, run_environment, update_time, steps_number, execution_result, pass_rate, crontab, crontab_status, del_flag,create_time,update_by from ui_automation
|
||||
</sql>
|
||||
|
||||
<select id="selectUiAutomationList" parameterType="UiAutomation" resultMap="UiAutomationResult">
|
||||
@@ -126,6 +128,8 @@
|
||||
<if test="crontabStatus != null">crontab_status,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
<if test="description != null">description,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="groupId != null">#{groupId},</if>
|
||||
@@ -144,6 +148,8 @@
|
||||
<if test="crontabStatus != null">#{crontabStatus},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
<if test="description != null">#{description},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
@@ -166,6 +172,8 @@
|
||||
<if test="crontabStatus != null">crontab_status = #{crontabStatus},</if>
|
||||
<if test="delFlag != null">del_flag = #{delFlag},</if>
|
||||
<if test="description != null">description = #{description},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
Reference in New Issue
Block a user