@@ -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 . getTim e ( ) ) ;
uiAutomation . setUpdateTime ( DateUtils . getNowDat e ( ) ) ;
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 . s etStatu s( " 3 " ) ;
UiAutomation uiAutomation1 = new UiAutomation ( ) ;
uiAutomation1 . setId ( automationId ) ;
uiAutomation1 . setExecutionResult ( " 2 " ) ;
if ( ! uiAutomation . g etExecutionResult ( ) . equal s( " 2 " ) ) {
uiAutomation1 . setExecutionResult ( " 3 " ) ;
}
uiAutomation . setUpdateBy ( DateUtils . getTim e ( ) ) ;
uiAutomation . setPassRate ( stepsSucceedNumber = = 0 ? " 0% " :
String . format ( " %.2f%% " , ( double ) stepsSucceedNumber / steps . size ( ) * 100 ) ) ;
uiAutomationMapper . updateUiAutomation ( uiAutomation ) ;
uiAutomation1 . setUpdateTime ( DateUtils . getNowDat e ( ) ) ;
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:/ chromed river-win64/chromedriver.exe " ) ;
System . setProperty ( " webdriver.chrome.driver " , chromeD riverPath ) ;
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 ) {
}