From fa30bb8bc578a9a6f8a5f981a5e79ed225d55537 Mon Sep 17 00:00:00 2001 From: guocan Date: Wed, 7 May 2025 16:40:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=A7=E8=A1=8C=E9=AB=98=E7=BA=A7=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=20=E6=96=AD=E8=A8=80=E5=92=8C=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=8F=90=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/test/common/utils/DateUtils.java | 11 + .../com/test/common/utils/SeleniumUtils.java | 37 ++ .../controller/UiAutomationController.java | 18 +- .../test/domain/qo/AssertionConfigQO.java | 21 + .../com/test/test/domain/qo/AssertionQO.java | 4 +- .../domain/qo/DataExtractionConfigQO.java | 16 + .../test/test/domain/qo/DataExtractionQO.java | 12 +- .../test/test/domain/qo/UiHighSettingQO.java | 11 +- .../test/domain/vo/AssertionReportVO.java | 25 + .../test/test/domain/vo/UiHighSettingVO.java | 11 +- .../test/service/IUiSceneStepsService.java | 2 +- .../service/impl/UiAutomationServiceImpl.java | 105 ++- .../service/impl/UiReportServiceImpl.java | 2 +- .../service/impl/UiSceneStepsServiceImpl.java | 610 +++++++++++++++++- 14 files changed, 823 insertions(+), 62 deletions(-) create mode 100644 test-test/src/main/java/com/test/test/domain/qo/AssertionConfigQO.java create mode 100644 test-test/src/main/java/com/test/test/domain/qo/DataExtractionConfigQO.java create mode 100644 test-test/src/main/java/com/test/test/domain/vo/AssertionReportVO.java 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 818476c..017b048 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 @@ -8,6 +8,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Date; import org.apache.commons.lang3.time.DateFormatUtils; @@ -232,4 +233,14 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils } return endTime.getTime() - startTime.getTime(); } + + /** + * 格式化日期为 yyyy-MM-dd HH:mm:ss + */ + public static String formatDateTime(Date date) { + return date.toInstant() + .atZone(ZoneId.systemDefault()) + .toLocalDateTime() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } } 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 c310f2b..5b7e56a 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 @@ -867,4 +867,41 @@ public class SeleniumUtils { driver.get(url); } + /** + * 数据提取提取窗口信息 + * @param windowType + * @return + */ + public String extractWindowInformation(String windowType) { + switch (windowType) { + case "1": // 窗口 Handle + return driver.getWindowHandle(); + case "2": // 网页标题 + return driver.getTitle(); + default: + throw new IllegalArgumentException("Invalid windowType: " + windowType); + } + } + + /** + * 查找多个元素 + * @param locType + * @param locValue + * @return + */ + public List findElements(String locType, String locValue) { + return driver.findElements(getLocator(locType, locValue)); + } + + /** + * 获取网页标题 + * @return + */ + public String getTitle(){ + return driver.getTitle(); + } + + + + } 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 e744b4d..a42e90d 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 @@ -2,13 +2,17 @@ package com.test.test.controller; import java.util.List; +import com.test.common.utils.SeleniumUtils; 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.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import com.test.common.annotation.Log; import com.test.common.core.controller.BaseController; @@ -32,6 +36,8 @@ public class UiAutomationController extends BaseController private IUiAutomationService uiAutomationService; @Autowired private IUiSceneStepsService uiSceneStepsService; + @Value("${test.selenium.chrome-driver-path}") + private String chromeDriverPath; /** * 查询ui自动化列表 @@ -110,11 +116,17 @@ public class UiAutomationController extends BaseController public AjaxResult executeStep(@RequestParam Long id) { try{ + String triggerMode = "1"; //手动执行 log.info("执行完成!"); - return success(uiSceneStepsService.executeStep(id)); + return success(uiSceneStepsService.executeStep(id,triggerMode)); } catch (Exception e) { - log.error("执行完成!",e); - return error("执行完成!"); + System.setProperty("webdriver.chrome.driver", chromeDriverPath); + WebDriver driver = new ChromeDriver(); + SeleniumUtils seleniumUtils = new SeleniumUtils(driver); + //关闭浏览器 + seleniumUtils.quit(); + log.error("执行错误!",e); + return error("执行错误!"+e.getMessage()); } } } diff --git a/test-test/src/main/java/com/test/test/domain/qo/AssertionConfigQO.java b/test-test/src/main/java/com/test/test/domain/qo/AssertionConfigQO.java new file mode 100644 index 0000000..e2963c4 --- /dev/null +++ b/test-test/src/main/java/com/test/test/domain/qo/AssertionConfigQO.java @@ -0,0 +1,21 @@ +package com.test.test.domain.qo; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class AssertionConfigQO { + /** 弹窗文本数组 */ + private List popupTexts = new ArrayList<>(); + + /** 元素断言数组 */ + private List elementAssertions = new ArrayList<>(); + + /** 下拉框数组 */ + private List dropdownBoxes = new ArrayList<>(); + + /** 网页标题数组 */ + private List webTitles = new ArrayList<>(); +} diff --git a/test-test/src/main/java/com/test/test/domain/qo/AssertionQO.java b/test-test/src/main/java/com/test/test/domain/qo/AssertionQO.java index d447797..c174f55 100644 --- a/test-test/src/main/java/com/test/test/domain/qo/AssertionQO.java +++ b/test-test/src/main/java/com/test/test/domain/qo/AssertionQO.java @@ -18,10 +18,10 @@ public class AssertionQO { private String operateObject; /** 元素库名称 */ - private Integer operateGroupId; + private Long operateGroupId; /** 元素id */ - private Integer operateElementId; + private Long operateElementId; /** 元素定位类型 id css ……*/ private String operateLocType; diff --git a/test-test/src/main/java/com/test/test/domain/qo/DataExtractionConfigQO.java b/test-test/src/main/java/com/test/test/domain/qo/DataExtractionConfigQO.java new file mode 100644 index 0000000..bc55640 --- /dev/null +++ b/test-test/src/main/java/com/test/test/domain/qo/DataExtractionConfigQO.java @@ -0,0 +1,16 @@ +package com.test.test.domain.qo; + +import lombok.Data; +import java.util.List; + +/** + * 数据提取配置(新版嵌套结构) + */ +@Data +public class DataExtractionConfigQO { + /** 窗口信息提取配置 */ + private List windowExtractions; + + /** 元素信息提取配置 */ + private List elementExtractions; +} \ No newline at end of file diff --git a/test-test/src/main/java/com/test/test/domain/qo/DataExtractionQO.java b/test-test/src/main/java/com/test/test/domain/qo/DataExtractionQO.java index 869b215..04efe68 100644 --- a/test-test/src/main/java/com/test/test/domain/qo/DataExtractionQO.java +++ b/test-test/src/main/java/com/test/test/domain/qo/DataExtractionQO.java @@ -8,14 +8,14 @@ import lombok.Data; @Data public class DataExtractionQO { - /** 1提取元素信息 2提取窗口信息 */ + /** 1提取窗口信息 2提取元素信息 */ private String informationType; - /** 1普通对象(store) 2元素文本(storeText) 3元素值(storeValue) 4元素属性(storeAttribute) + /** informationType为2时 1普通对象(store) 2元素文本(storeText) 3元素值(storeValue) 4元素属性(storeAttribute) * 5CSS属性(storeCssAttribute) 6匹配 xpath 的元素数量(storeXpathCount) */ private String elementType; - /** 1窗口 Handle(storeWindowHandle) 2网页标题(storeTitle) */ + /** informationType为1时 1窗口 Handle(storeWindowHandle) 2网页标题(storeTitle) */ private String windowType; /**值 */ @@ -26,10 +26,10 @@ public class DataExtractionQO { private String operateObject; /** 元素库名称 */ - private Integer operateGroupId; + private Long operateGroupId; /** 元素id */ - private Integer operateElementId; + private Long operateElementId; /** 元素定位类型 id css ……*/ private String operateLocType; @@ -37,7 +37,7 @@ public class DataExtractionQO { /** 元素定位值 */ private String operateLocValue; - /**元素属性*/ + /** 普通对象 元素属性 元素css属性*/ private String elementAttribute; /**是否禁用 0否 1是 */ diff --git a/test-test/src/main/java/com/test/test/domain/qo/UiHighSettingQO.java b/test-test/src/main/java/com/test/test/domain/qo/UiHighSettingQO.java index 4540ff3..82448ff 100644 --- a/test-test/src/main/java/com/test/test/domain/qo/UiHighSettingQO.java +++ b/test-test/src/main/java/com/test/test/domain/qo/UiHighSettingQO.java @@ -56,16 +56,13 @@ public class UiHighSettingQO extends BaseEntity /** 是否删除 */ private Integer delFlag; - /** 等待元素超时时间 */ - private Integer waitElementTime; - - /** 截图配置 */ - private Integer screenshotConfiguration; + /**其他设置*/ + OtherSettingsQO otherSettingsQO = new OtherSettingsQO(); /**数据提取*/ - private List dataExtractionQOList = new ArrayList<>(); + private DataExtractionConfigQO dataExtractionQOList = new DataExtractionConfigQO(); /**断言*/ - private List assertionQOList = new ArrayList<>(); + private AssertionConfigQO assertionQOList = new AssertionConfigQO(); } diff --git a/test-test/src/main/java/com/test/test/domain/vo/AssertionReportVO.java b/test-test/src/main/java/com/test/test/domain/vo/AssertionReportVO.java new file mode 100644 index 0000000..336e386 --- /dev/null +++ b/test-test/src/main/java/com/test/test/domain/vo/AssertionReportVO.java @@ -0,0 +1,25 @@ +package com.test.test.domain.vo; + +import lombok.Data; + +/** + * 断言报告结果 + */ +@Data +public class AssertionReportVO { + + /** + * 断言名称 + */ + private String name; + + /** + * 错误信息 + */ + private String errorInfo; + + /** + * 是否成功 0否 1是 + */ + private String isSuccess; +} diff --git a/test-test/src/main/java/com/test/test/domain/vo/UiHighSettingVO.java b/test-test/src/main/java/com/test/test/domain/vo/UiHighSettingVO.java index b7eaedb..fccc090 100644 --- a/test-test/src/main/java/com/test/test/domain/vo/UiHighSettingVO.java +++ b/test-test/src/main/java/com/test/test/domain/vo/UiHighSettingVO.java @@ -1,13 +1,10 @@ package com.test.test.domain.vo; -import com.test.common.annotation.Excel; -import com.test.common.core.domain.BaseEntity; +import com.test.test.domain.qo.AssertionConfigQO; import com.test.test.domain.qo.AssertionQO; -import com.test.test.domain.qo.DataExtractionQO; +import com.test.test.domain.qo.DataExtractionConfigQO; import com.test.test.domain.qo.OtherSettingsQO; 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; @@ -48,10 +45,10 @@ public class UiHighSettingVO private Integer isDisabled; /**断言*/ - private List assertionQOList = new ArrayList<>(); + private AssertionConfigQO assertionQOList = new AssertionConfigQO(); /**数据提取*/ - private List dataExtractionQOList = new ArrayList<>(); + private DataExtractionConfigQO dataExtractionQOList =new DataExtractionConfigQO(); /**其他设置*/ private OtherSettingsQO otherSettingsQO; 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 2d2fd6a..cfa0016 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 @@ -19,6 +19,6 @@ public interface IUiSceneStepsService * @param automationId 场景id * @return */ - Map executeStep(Long automationId); + Map executeStep(Long automationId,String triggerMode); } 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 70c8128..096bcca 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 @@ -76,16 +76,44 @@ public class UiAutomationServiceImpl implements IUiAutomationService { new TypeReference>() { } ); - uiHighSettingVO.setAssertionQOList(assertionList); + List popupTexts = new ArrayList<>(); + List elementAssertions = new ArrayList<>(); + List dropdownBoxes = new ArrayList<>(); + List webTitles = new ArrayList<>(); + for (AssertionQO extractionQO : assertionList) { + if ("1".equals(extractionQO.getAssertionType())) { + popupTexts.add(extractionQO); + } else if ("2".equals(extractionQO.getAssertionType())) { + elementAssertions.add(extractionQO); + }else if ("3".equals(extractionQO.getAssertionType())) { + dropdownBoxes.add(extractionQO); + }else if ("4".equals(extractionQO.getAssertionType())) { + webTitles.add(extractionQO); + } + } + uiHighSettingVO.getAssertionQOList().setPopupTexts(popupTexts); + uiHighSettingVO.getAssertionQOList().setElementAssertions(elementAssertions); + uiHighSettingVO.getAssertionQOList().setDropdownBoxes(dropdownBoxes); + uiHighSettingVO.getAssertionQOList().setWebTitles(webTitles); // 转换extractionDataJson 数据提取 if (StringUtils.isNotBlank(uiHighSetting.getExtractionDataJson())) { List extractionData = null; extractionData = objectMapper.readValue( uiHighSetting.getExtractionDataJson(), - new TypeReference>(){ + new TypeReference>() { } ); - uiHighSettingVO.setDataExtractionQOList(extractionData); + List windowExtractions = new ArrayList<>(); + List elementExtractions = new ArrayList<>(); + for (DataExtractionQO extractionQO : extractionData) { + if ("1".equals(extractionQO.getInformationType())) { + windowExtractions.add(extractionQO); + } else if ("2".equals(extractionQO.getInformationType())) { + elementExtractions.add(extractionQO); + } + } + uiHighSettingVO.getDataExtractionQOList().setWindowExtractions(windowExtractions); + uiHighSettingVO.getDataExtractionQOList().setElementExtractions(elementExtractions); } // 转换otherSetting 其他设置 if (StringUtils.isNotBlank(uiHighSetting.getOtherSetting())) { @@ -122,7 +150,25 @@ public class UiAutomationServiceImpl implements IUiAutomationService { new TypeReference>() { } ); - uiHighSettingVO.setAssertionQOList(assertionList); + List popupTexts = new ArrayList<>(); + List elementAssertions = new ArrayList<>(); + List dropdownBoxes = new ArrayList<>(); + List webTitles = new ArrayList<>(); + for (AssertionQO extractionQO : assertionList) { + if ("1".equals(extractionQO.getAssertionType())) { + popupTexts.add(extractionQO); + } else if ("2".equals(extractionQO.getAssertionType())) { + elementAssertions.add(extractionQO); + }else if ("3".equals(extractionQO.getAssertionType())) { + dropdownBoxes.add(extractionQO); + }else if ("4".equals(extractionQO.getAssertionType())) { + webTitles.add(extractionQO); + } + } + uiHighSettingVO.getAssertionQOList().setPopupTexts(popupTexts); + uiHighSettingVO.getAssertionQOList().setElementAssertions(elementAssertions); + uiHighSettingVO.getAssertionQOList().setDropdownBoxes(dropdownBoxes); + uiHighSettingVO.getAssertionQOList().setWebTitles(webTitles); // 转换extractionDataJson 数据提取 if (StringUtils.isNotBlank(uiHighSetting.getExtractionDataJson())) { List extractionData = null; @@ -131,7 +177,17 @@ public class UiAutomationServiceImpl implements IUiAutomationService { new TypeReference>() { } ); - uiHighSettingVO.setDataExtractionQOList(extractionData); + List windowExtractions = new ArrayList<>(); + List elementExtractions = new ArrayList<>(); + for (DataExtractionQO extractionQO : extractionData) { + if ("1".equals(extractionQO.getInformationType())) { + windowExtractions.add(extractionQO); + } else if ("2".equals(extractionQO.getInformationType())) { + elementExtractions.add(extractionQO); + } + } + uiHighSettingVO.getDataExtractionQOList().setWindowExtractions(windowExtractions); + uiHighSettingVO.getDataExtractionQOList().setElementExtractions(elementExtractions); } // 转换otherSetting 其他设置 if (StringUtils.isNotBlank(uiHighSetting.getOtherSetting())) { @@ -187,7 +243,6 @@ public class UiAutomationServiceImpl implements IUiAutomationService { uiAutomation.setUpdateTime(DateUtils.getNowDate()); uiAutomation.setCreateBy(SecurityUtils.getUsername()); uiAutomation.setUpdateBy(SecurityUtils.getUsername()); -// uiAutomation.setStatus("1"); //未开始 uiAutomation.setDutyBy(SecurityUtils.getUsername()); uiAutomation.setDelFlag(0); uiAutomation.setCrontabStatus(0); //未开启 @@ -218,22 +273,27 @@ public class UiAutomationServiceImpl implements IUiAutomationService { uiHighSetting.setCreateBy(SecurityUtils.getUsername()); uiHighSetting.setCreateTime(DateUtils.getNowDate()); try { + List combinedList1 = new ArrayList<>(); + combinedList1.addAll(uiHighSettingQO.getDataExtractionQOList().getWindowExtractions()); + combinedList1.addAll(uiHighSettingQO.getDataExtractionQOList().getElementExtractions()); //数据提取 - String jsonStr = objectMapper.writeValueAsString(uiHighSettingQO.getDataExtractionQOList()); + String jsonStr = objectMapper.writeValueAsString(combinedList1); if (jsonStr != null) { uiHighSetting.setExtractionDataJson(jsonStr); } //断言 - jsonStr = objectMapper.writeValueAsString(uiHighSettingQO.getAssertionQOList()); + List combinedList2 = new ArrayList<>(); + combinedList2.addAll(uiHighSettingQO.getAssertionQOList().getPopupTexts()); + combinedList2.addAll(uiHighSettingQO.getAssertionQOList().getElementAssertions()); + combinedList2.addAll(uiHighSettingQO.getAssertionQOList().getDropdownBoxes()); + combinedList2.addAll(uiHighSettingQO.getAssertionQOList().getWebTitles()); + jsonStr = objectMapper.writeValueAsString(combinedList2); if (jsonStr != null) { uiHighSetting.setAssertionJson(jsonStr); } //其他设置 - if (uiHighSettingQO.getWaitElementTime() != null || uiHighSettingQO.getScreenshotConfiguration() != null) { - OtherSettingsQO settings = new OtherSettingsQO(); - settings.setWaitElementTime(uiHighSettingQO.getWaitElementTime()); - settings.setScreenshotConfiguration(uiHighSettingQO.getScreenshotConfiguration()); - jsonStr = objectMapper.writeValueAsString(settings); + if (uiHighSettingQO.getOtherSettingsQO()!=null) { + jsonStr = objectMapper.writeValueAsString(uiHighSettingQO.getOtherSettingsQO()); uiHighSetting.setOtherSetting(jsonStr); } } catch (JsonProcessingException e) { @@ -297,22 +357,27 @@ public class UiAutomationServiceImpl implements IUiAutomationService { uiHighSetting.setCreateBy(SecurityUtils.getUsername()); uiHighSetting.setCreateTime(DateUtils.getNowDate()); try { + List combinedList1 = new ArrayList<>(); + combinedList1.addAll(uiHighSettingQO.getDataExtractionQOList().getWindowExtractions()); + combinedList1.addAll(uiHighSettingQO.getDataExtractionQOList().getElementExtractions()); //数据提取 - String jsonStr = objectMapper.writeValueAsString(uiHighSettingQO.getDataExtractionQOList()); + String jsonStr = objectMapper.writeValueAsString(combinedList1); if (jsonStr != null) { uiHighSetting.setExtractionDataJson(jsonStr); } //断言 - jsonStr = objectMapper.writeValueAsString(uiHighSettingQO.getAssertionQOList()); + List combinedList2 = new ArrayList<>(); + combinedList2.addAll(uiHighSettingQO.getAssertionQOList().getPopupTexts()); + combinedList2.addAll(uiHighSettingQO.getAssertionQOList().getElementAssertions()); + combinedList2.addAll(uiHighSettingQO.getAssertionQOList().getDropdownBoxes()); + combinedList2.addAll(uiHighSettingQO.getAssertionQOList().getWebTitles()); + jsonStr = objectMapper.writeValueAsString(combinedList2); if (jsonStr != null) { uiHighSetting.setAssertionJson(jsonStr); } //其他设置 - if (uiHighSettingQO.getWaitElementTime() != null || uiHighSettingQO.getScreenshotConfiguration() != null) { - OtherSettingsQO settings = new OtherSettingsQO(); - settings.setWaitElementTime(uiHighSettingQO.getWaitElementTime()); - settings.setScreenshotConfiguration(uiHighSettingQO.getScreenshotConfiguration()); - jsonStr = objectMapper.writeValueAsString(settings); + if (uiHighSettingQO.getOtherSettingsQO()!=null) { + jsonStr = objectMapper.writeValueAsString(uiHighSettingQO.getOtherSettingsQO()); uiHighSetting.setOtherSetting(jsonStr); } } catch (JsonProcessingException e) { 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 index fe18744..bd74752 100644 --- 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 @@ -95,7 +95,7 @@ public class UiReportServiceImpl implements IUiReportService UiAutomation automation = uiAutomationMapper.selectUiAutomationById(automationId); String name = automation.getName(); UiReport uiReport = new UiReport(); - uiReport.setName(name + "-" + DateUtils.getTime()); + uiReport.setName(name + "-" + DateUtils.formatDateTime(startTime)); uiReport.setReportType("场景"); uiReport.setCreateTime(startTime); uiReport.setCreateBy(SecurityUtils.getUsername()); 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 eca6a85..b9878ee 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,15 +1,22 @@ package com.test.test.service.impl; import java.util.*; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; 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.*; -import com.test.test.domain.qo.OtherSettingsQO; +import com.test.test.domain.qo.*; +import com.test.test.domain.vo.AssertionReportVO; import com.test.test.domain.vo.UiHighSettingVO; import com.test.test.mapper.UiAutomationMapper; import com.test.test.mapper.UiSceneStepsMapper; @@ -18,10 +25,10 @@ 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.*; import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.support.ui.Select; +import org.openqa.selenium.support.ui.UnexpectedTagNameException; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -56,10 +63,13 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { * @param automationId * @return */ - public Map executeStep(Long automationId) { + public Map executeStep(Long automationId,String triggerMode) { Map result = new HashMap<>(); result.put("msg", ""); result.put("id", 0L); + AtomicInteger totalAssertions = new AtomicInteger(0); + AtomicInteger successAssertions = new AtomicInteger(0); + Gson gson = new Gson(); // 1. 验证并获取步骤 List steps = validateAndGetSteps(automationId); @@ -73,7 +83,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { Date startTime = DateUtils.getNowDate(); // 2. 创建执行报告 - Long reportId = uiReportService.insertUiReport(startTime, automationId, "1", steps.size()); + Long reportId = uiReportService.insertUiReport(startTime, automationId, triggerMode, steps.size()); UiReport uiReport = new UiReport(); result.put("id", reportId); uiReport.setId(reportId); @@ -120,6 +130,24 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { } else if (report.getExecutionFlag().equals("0")) { stepsNotNumber++; } + //成功断言数 + String assertionJson = report.getAssertionJson(); + if (assertionJson != null && !assertionJson.trim().isEmpty()) { + try { + List assertions = gson.fromJson( + assertionJson, + new TypeToken>(){}.getType() + ); + int stepAssertionCount = assertions.size(); + int stepSuccessCount = (int) assertions.stream() + .filter(a -> "1".equals(a.getIsSuccess())) + .count(); + totalAssertions.addAndGet(stepAssertionCount); + successAssertions.addAndGet(stepSuccessCount); + } catch (Exception e) { + log.error("步骤[{}]断言数据解析失败: {}", report.getId(), assertionJson, e); + } + } } if (allSuccess) { scenesSucceedNumber = 1; @@ -127,6 +155,10 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { scenesErrorNumber = 1; } } + uiReport.setSuccessAssertion("0/0"); + String globalAssertionResult = successAssertions.get() + "/" + totalAssertions.get(); + uiReport.setSuccessAssertion(globalAssertionResult); + uiReport.setScenesSucceedNumber(scenesSucceedNumber); uiReport.setScenesErrorNumber(scenesErrorNumber); uiReport.setScenesNotNumber(0); @@ -136,6 +168,8 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { uiReport.setFaiiRate( stepsErrorNumber == 0 ? "0%" : String.format("%.2f%%", (double) stepsErrorNumber / steps.size() * 100) + + ); uiReportService.updateUiReport(uiReport); @@ -214,6 +248,8 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { List uiHighSettingVOList = uiAutomationService.getUiHighSettingVOList(step.getId()); executeSingleStep(step, seleniumUtils, uiSceneStepsReports.get(0).getId(), uiHighSettingVOList); } + //关闭浏览器 + seleniumUtils.quit(); } private void executeSingleStep(UiSceneSteps step, SeleniumUtils seleniumUtils, @@ -263,6 +299,8 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { boolean shouldContinue = executeStepWithLog(step, seleniumUtils, sceneStepsReportId, execution, uiHighSettingVOList); if (!shouldContinue) { + //关闭浏览器 + seleniumUtils.quit(); throw new IllegalArgumentException("步骤执行失败,根据设置终止场景执行"); } } @@ -285,20 +323,29 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { UiHighSettingVO errorSetting = extractErrorSetting(uiHighSettingVOList); UiHighSettingVO otherSetting = extractOtherSetting(uiHighSettingVOList); OtherSettingsQO otherSettingsQO = otherSetting.getOtherSettingsQO(); - Integer screenshotConfiguration = otherSettingsQO.getScreenshotConfiguration(); //是否截图 1当前步骤截图 2异常截图 3 不截图 - //等待元素超时时间 - 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); + Integer screenshotConfiguration = 0; + if (otherSettingsQO != null) { + screenshotConfiguration = otherSettingsQO.getScreenshotConfiguration() == null ? 0 : otherSettingsQO.getScreenshotConfiguration(); + //等待元素超时时间 + Integer waitElementTime = otherSettingsQO.getWaitElementTime() == null ? -1 : otherSettingsQO.getWaitElementTime(); + if (waitElementTime > 0) { + // 转换为秒(至少1秒) + long timeoutInSeconds = Math.max(1, waitElementTime / 1000); + log.info("元素等待时间{}秒", timeoutInSeconds); + seleniumUtils.setWaitTimeout(timeoutInSeconds); + } } + //前置操作设置 List beforeSettingList = extractbeforeSetting(uiHighSettingVOList); + // 获取前置操作数据集合(判空) + Map beforeData = CollectionUtils.isEmpty(beforeSettingList) + ? new HashMap<>() + : filterBydataExtractionQOList(beforeSettingList, seleniumUtils); //后置操作设置 List afterSettingList = extractafterSetting(uiHighSettingVOList); + //前置等待时间 int beforeAwaitTime = getAwaitTime(beforeSettingList); //后置等待时间 @@ -328,7 +375,6 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { log.info("执行后置等待: {}ms", afterAwaitTime); Thread.sleep(afterAwaitTime); } - report.setLogInfo("OK"); report.setExecutionFlag("1"); } catch (Exception e) { @@ -345,18 +391,50 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { } log.error("步骤执行失败: {}", e.getMessage()); } finally { + //获取后置操作数据集合 + Map afterData = CollectionUtils.isEmpty(afterSettingList) + ? new HashMap<>() + : filterBydataExtractionQOList(afterSettingList, seleniumUtils); + Map mergedData = new HashMap<>(); + if (!beforeData.isEmpty()) { + mergedData.put("前置数据提取", beforeData); + } + if (!afterData.isEmpty()) { + mergedData.put("后置数据提取", afterData); + } + // 设置到报告 + try { + String json = mergedData.isEmpty() ? null : new ObjectMapper().writeValueAsString(mergedData); + report.setExtractionDataJson(json); + } catch (JsonProcessingException e) { + report.setExtractionDataJson("JsonProcessingException error"); + } + Map stringObjectMap = filterByAssertionQOList(afterSettingList, seleniumUtils); + //断言失败是否终止 + String continueExecution1 = (String) stringObjectMap.get("continueExecution"); + if (continueExecution1.equals("1")){ + continueExecution = false; + report.setLogInfo(""); + report.setExecutionFlag("2"); + } + List assertionReportVOS = (List) stringObjectMap.get("assertionReportVOS"); + Gson gson = new Gson(); + report.setAssertionJson(assertionReportVOS.isEmpty() ? null : gson.toJson(assertionReportVOS)); endTime = DateUtils.getNowDate(); // 更新报告 report.setCreateTime(startTime); report.setUpdateTime(endTime); report.setTake(DateUtils.differenceInMilliseconds(startTime, endTime) + "ms"); uiSceneStepsReportMapper.updateUiSceneStepsReport(report); + } return continueExecution; } + + /** * 提取前置操作 * @@ -369,6 +447,505 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { .collect(Collectors.toList()); // 返回默认设置 } + /** + * 断言 + * @param settingList + * @param seleniumUtils + * @return + */ + public Map filterByAssertionQOList(List settingList, SeleniumUtils seleniumUtils) { + Map result = new HashMap<>(); + String continueExecution = "2"; + List assertionReports = new ArrayList<>(); + + result.put("continueExecution", continueExecution); + result.put("assertionReportVOS", assertionReports); + List uiHighSettingVOS = settingList.stream() + .filter(setting -> setting.getOperateType().equals("2") && 0 == setting.getIsDisabled()) + .toList(); + + if (CollectionUtils.isEmpty(uiHighSettingVOS)) { + return result; + } + for (UiHighSettingVO uiHighSettingVO : uiHighSettingVOS) { + AssertionConfigQO assertion = uiHighSettingVO.getAssertionQOList(); + List assertionQOList = new ArrayList<>(); + assertionQOList.addAll(assertion.getPopupTexts()); + assertionQOList.addAll(assertion.getElementAssertions()); + assertionQOList.addAll(assertion.getDropdownBoxes()); + assertionQOList.addAll(assertion.getWebTitles()); + if (!CollectionUtils.isEmpty(assertionQOList)) { + for (AssertionQO assertionQO : assertionQOList) { + if ("1".equals(assertionQO.getIsDisabled())) { + continue; + } + AssertionReportVO report = new AssertionReportVO(); + report.setName("1".equals(assertionQO.getIsFailedAbort())?"assert":"verify"); + report.setIsSuccess("1"); // 默认成功 + + try { + boolean assertionResult = false; + String errorDetail = ""; + + switch (assertionQO.getAssertionType()) { + case "1": // 弹窗文本断言 + assertionResult = handleAlertAssertion(assertionQO, seleniumUtils, report); + break; + case "2": // 元素断言 + assertionResult = handleElementAssertion(assertionQO, seleniumUtils, report); + break; + case "3": // 下拉框断言 + assertionResult = handleDropdownAssertion(assertionQO, seleniumUtils, report); + break; + case "4": // 网页标题断言 + assertionResult = handleTitleAssertion(assertionQO, seleniumUtils, report); + break; + default: + errorDetail = "不支持的断言类型: " + assertionQO.getAssertionType(); + report.setErrorInfo(errorDetail); + report.setIsSuccess("0"); + } + + if (!assertionResult && "1".equals(assertionQO.getIsFailedAbort())) { + continueExecution = "1"; + result.put("continueExecution", continueExecution); + } + } catch (Exception e) { + report.setErrorInfo("断言执行异常: " + e.getMessage()); + report.setIsSuccess("0"); + log.error("断言执行异常", e); + } + + assertionReports.add(report); + } + } + } + result.put("assertionReportVOS", assertionReports); + return result; + } + + private boolean handleAlertAssertion(AssertionQO assertionQO, + SeleniumUtils seleniumUtils, + AssertionReportVO report) { + try { + // 1. 获取弹窗文本(带10秒等待) + String actualText = seleniumUtils.getAlertText(); + String expectedText = assertionQO.getExpectations(); + report.setErrorInfo(""); + // 3. 文本比较 + if (!actualText.equals(expectedText)) { + report.setErrorInfo(String.format( + "弹窗文本不匹配,实际值:'%s',期望值:'%s'", + actualText, expectedText + )); + report.setIsSuccess("0"); + return false; + } + + // 4. 根据配置处理弹窗 + if ("1".equals(assertionQO.getIsPopText())) { + seleniumUtils.acceptAlert(); // 点击确认 + log.info("弹窗断言成功,已点击确认"); + } else { + log.info("弹窗断言成功,未执行点击操作"); + } + report.setIsSuccess("1"); + return true; + + } catch (NoAlertPresentException e) { + report.setErrorInfo("弹窗未出现:" + e.getMessage()); + report.setIsSuccess("0"); + return false; + } catch (Exception e) { + report.setErrorInfo("弹窗处理异常:" + e.getMessage()); + report.setIsSuccess("0"); + return false; + } + } + + /** + * 处理元素断言 + * @param assertionQO 断言配置 + * @param seleniumUtils Selenium工具类 + * @param report 断言报告 + * @return 断言是否成功 + */ + private boolean handleElementAssertion(AssertionQO assertionQO, + SeleniumUtils seleniumUtils, + AssertionReportVO report) { + WebElement element = null; + String locatorDescription = ""; + report.setErrorInfo(""); + try { + // 1. 获取元素定位信息 + if ("1".equals(assertionQO.getOperateObject())) { + // 从数据库查询元素信息 + //元素定位 + UiElement uiElement = uiElementService.selectUiElementById(assertionQO.getOperateElementId()); + if (uiElement == null) { + report.setErrorInfo("元素ID " + assertionQO.getOperateElementId() + " 不存在"); + report.setIsSuccess("0"); + return false; + } + element = seleniumUtils.findElement(uiElement.getLocType(), uiElement.getElementLoc()); + locatorDescription = String.format("元素ID:%d (%s=%s)", + assertionQO.getOperateElementId(), + uiElement.getLocType(), + uiElement.getElementLoc()); + } else if ("2".equals(assertionQO.getOperateObject())) { + // 直接使用配置的定位信息 + element = seleniumUtils.findElement( + assertionQO.getOperateLocType(), + assertionQO.getOperateLocValue() + ); + locatorDescription = String.format("直接定位 (%s=%s)", + assertionQO.getOperateLocType(), + assertionQO.getOperateLocValue()); + } + // 3. 执行断言 + boolean result = false; + String actualValue = ""; + String expectedValue = assertionQO.getExpectations(); + + switch (assertionQO.getAssertionMode()) { + case "1": // 元素被选中(Checked) + actualValue = String.valueOf(element.isSelected()); + result = element.isSelected(); + if (!result) { + report.setErrorInfo(locatorDescription + " 未被选中"); + } + break; + + case "2": // 元素可编辑(Editable) + actualValue = String.valueOf(element.isEnabled()); + result = element.isEnabled(); + if (!result) { + report.setErrorInfo(locatorDescription + " 不可编辑"); + } + break; + + case "3": // 元素存在(ElementPresent) + result = true; // 如果能找到元素,说明存在 + break; + + case "4": // 元素不存在(ElementNotPresent) + report.setErrorInfo("元素存在性断言应使用其他方式实现"); + return false; + + case "5": // 元素未被选中(NotChecked) + actualValue = String.valueOf(element.isSelected()); + result = !element.isSelected(); + if (!result) { + report.setErrorInfo(locatorDescription + " 已被选中"); + } + break; + + case "6": // 元素不可编辑(NotEditable) + actualValue = String.valueOf(element.isEnabled()); + result = !element.isEnabled(); + if (!result) { + report.setErrorInfo(locatorDescription + " 可编辑"); + } + break; + + case "7": // 元素文本不等于期望(NotText) + actualValue = element.getText(); + result = !actualValue.equals(expectedValue); + if (!result) { + report.setErrorInfo(String.format( + "%s 文本等于期望值(实际:'%s',期望不等于:'%s')", + locatorDescription, actualValue, expectedValue + )); + } + break; + + case "8": // 元素文本等于期望(Text) + actualValue = element.getText(); + result = actualValue.equals(expectedValue); + if (!result) { + report.setErrorInfo(String.format( + "%s 文本不等于期望值(实际:'%s',期望:'%s')", + locatorDescription, actualValue, expectedValue + )); + } + break; + + case "9": // 元素值等于期望(Value) + actualValue = element.getAttribute("value"); + result = actualValue.equals(expectedValue); + if (!result) { + report.setErrorInfo(String.format( + "%s 值不等于期望值(实际:'%s',期望:'%s')", + locatorDescription, actualValue, expectedValue + )); + } + break; + + case "10": // 元素文本包含期望(InText) + actualValue = element.getText(); + result = actualValue.contains(expectedValue); + if (!result) { + report.setErrorInfo(String.format( + "%s 文本不包含期望内容(实际:'%s',期望包含:'%s')", + locatorDescription, actualValue, expectedValue + )); + } + break; + + case "11": // 元素文本不包含期望(NotlnText) + actualValue = element.getText(); + result = !actualValue.contains(expectedValue); + if (!result) { + report.setErrorInfo(String.format( + "%s 文本包含不应出现的内容(实际:'%s',期望不包含:'%s')", + locatorDescription, actualValue, expectedValue + )); + } + break; + default: + report.setErrorInfo("不支持的断言方式: " + assertionQO.getAssertionMode()); + return false; + } + report.setIsSuccess(result ? "1" : "0"); + return result; + } catch (NoSuchElementException e) { + if ("3".equals(assertionQO.getAssertionMode())) { + // 元素存在断言时,找不到元素应该返回false + report.setErrorInfo(locatorDescription + " 不存在"); + report.setIsSuccess("0"); + return false; + } + report.setErrorInfo("元素定位失败: " + e.getMessage()); + report.setIsSuccess("0"); + return false; + } catch (Exception e) { + report.setErrorInfo("元素断言异常: " + e.getMessage()); + report.setIsSuccess("0"); + return false; + } + } + + + /** + * 处理下拉框断言 + * @param assertionQO 断言配置 + * @param seleniumUtils Selenium工具类 + * @param report 断言报告 + * @return 断言是否成功 + */ + private boolean handleDropdownAssertion(AssertionQO assertionQO, + SeleniumUtils seleniumUtils, + AssertionReportVO report) { + WebElement dropdown = null; + String locatorDescription = ""; + report.setErrorInfo(""); + try { + // 1. 获取下拉框元素 + if ("1".equals(assertionQO.getOperateObject())) { + UiElement uiElement = uiElementService.selectUiElementById(assertionQO.getOperateElementId()); + if (uiElement == null) { + report.setErrorInfo("元素ID " + assertionQO.getOperateElementId() + " 不存在"); + report.setIsSuccess("0"); + return false; + } + dropdown = seleniumUtils.findElement(uiElement.getLocType(), uiElement.getElementLoc()); + locatorDescription = String.format("下拉框ID:%d (%s=%s)", + assertionQO.getOperateElementId(), + uiElement.getLocType(), + uiElement.getElementLoc()); + } else { + dropdown = seleniumUtils.findElement( + assertionQO.getOperateLocType(), + assertionQO.getOperateLocValue() + ); + locatorDescription = String.format("下拉框 (%s=%s)", + assertionQO.getOperateLocType(), + assertionQO.getOperateLocValue()); + } + // 2. 转换为Select对象 + Select select = new Select(dropdown); + WebElement selectedOption = select.getFirstSelectedOption(); + String actualValue = selectedOption.getAttribute("value"); + String actualText = selectedOption.getText(); + String expectedValue = assertionQO.getExpectations(); + + // 4. 执行断言 + boolean result = false; + switch (assertionQO.getAssertionMode()) { + case "1": // 所选元素的值等于期望(SelectedValue) + result = actualValue.equals(expectedValue); + if (!result) { + report.setErrorInfo(String.format( + "下拉框选中值不匹配(实际:'%s',期望:'%s')", + actualValue, expectedValue + )); + } + break; + + case "2": // 下拉框选项显示的文本等于期望(SelectedLabel) + result = actualText.equals(expectedValue); + if (!result) { + report.setErrorInfo(String.format( + "下拉框选中文本不匹配(实际:'%s',期望:'%s')", + actualText, expectedValue + )); + } + break; + + case "3": // 所选元素的值不等于期望(NotSelectedValue) + result = !actualValue.equals(expectedValue); + if (!result) { + report.setErrorInfo(String.format( + "下拉框选中值不应匹配(实际:'%s',期望不等于:'%s')", + actualValue, expectedValue + )); + } + break; + default: + report.setErrorInfo("不支持的断言方式: " + assertionQO.getAssertionMode()); + return false; + } + + report.setIsSuccess(result ? "1" : "0"); + return result; + } catch (NoSuchElementException e) { + report.setErrorInfo("下拉框元素不存在: " + e.getMessage()); + report.setIsSuccess("0"); + return false; + } catch (UnexpectedTagNameException e) { + report.setErrorInfo("元素不是下拉框: " + e.getMessage()); + report.setIsSuccess("0"); + return false; + } catch (Exception e) { + report.setErrorInfo("下拉框断言异常: " + e.getMessage()); + report.setIsSuccess("0"); + return false; + } + } + + + /** + * 处理网页标题断言 + * @param assertionQO 断言配置 + * @param seleniumUtils Selenium工具类 + * @param report 断言报告 + * @return 断言是否成功 + */ + private boolean handleTitleAssertion(AssertionQO assertionQO, + SeleniumUtils seleniumUtils, + AssertionReportVO report) { + try { + // 1. 获取实际标题和期望标题 + String actualTitle = seleniumUtils.getTitle(); + String expectedTitle = assertionQO.getExpectations(); + report.setErrorInfo(""); + + // 3. 执行完全匹配比较 + boolean result = actualTitle.equals(expectedTitle); + if (!result) { + report.setErrorInfo(String.format( + "网页标题不匹配(实际:'%s',期望:'%s')", + actualTitle, expectedTitle + )); + } + report.setIsSuccess(result ? "1" : "0"); + return result; + } catch (Exception e) { + report.setErrorInfo("获取网页标题失败: " + e.getMessage()); + report.setIsSuccess("0"); + return false; + } + } + + /** + * 获取数据提取集合 + * @param settingList + * @return + */ + public Map filterBydataExtractionQOList(List settingList, SeleniumUtils seleniumUtils) { + List uiHighSettingVOS = settingList.stream() + .filter(setting -> setting.getOperateType().equals("3") && setting.getIsDisabled() == 0) + .toList(); + Map variableStorage = new HashMap<>(); + if (CollectionUtils.isEmpty(uiHighSettingVOS)) { + return variableStorage; + } + for (UiHighSettingVO uiHighSettingVO : uiHighSettingVOS) { + DataExtractionConfigQO dataExtractionQO = uiHighSettingVO.getDataExtractionQOList(); + List dataExtractionQOList = new ArrayList<>(); + dataExtractionQOList.addAll(dataExtractionQO.getElementExtractions()); + dataExtractionQOList.addAll(dataExtractionQO.getWindowExtractions()); + if (!CollectionUtils.isEmpty(dataExtractionQOList)) { + for (DataExtractionQO extraction : dataExtractionQOList) { + if ("1".equals(extraction.getIsDisabled())) { + continue; + } + try { + String variableName = extraction.getValue(); + String extractedValue = extractData(extraction,seleniumUtils); + variableStorage.put(variableName, extractedValue); + log.info("Extracted '{}' = {}", variableName, extractedValue); + } catch (NoSuchElementException e) { + log.info("Extracted '" + extraction.getValue() + "' = NoSuchElementException"); + variableStorage.put(extraction.getValue(), "NoSuchElementException"); + } catch (Exception e) { + log.error("Error extracting '" + extraction.getValue() + "': " + e.getMessage()); + } + } + } + + } + return variableStorage; + } + + /** + * 获取数据提取集合具体实现 + * @param extraction + * @param seleniumUtils + * @return + */ + private String extractData(DataExtractionQO extraction,SeleniumUtils seleniumUtils) { + if ("1".equals(extraction.getInformationType())) { + return seleniumUtils.extractWindowInformation(extraction.getWindowType()); + } else if ("2".equals(extraction.getInformationType())) { + WebElement element = null; + String locType = ""; + String elementLoc = ""; + if ("1".equals(extraction.getOperateObject())) { + //元素定位 + UiElement uiElement = uiElementService.selectUiElementById(extraction.getOperateElementId()); + if (uiElement == null) { + return ""; + } + locType = uiElement.getLocType(); //属性 + elementLoc = uiElement.getElementLoc();//值 + } else if ("2".equals(extraction.getOperateObject())) { + locType = extraction.getOperateLocType(); //属性 + elementLoc = extraction.getOperateLocValue();//值 + } + element = seleniumUtils.findElement(locType, elementLoc); + switch (extraction.getElementType()) { + case "1": // 普通对象 + return extraction.getElementAttribute(); // 直接返回属性值 + case "2": // 元素文本 + return element.getText(); + case "3": // 元素值 + return element.getAttribute("value"); + case "4": // 元素属性 + return element.getAttribute(extraction.getElementAttribute()); + case "5": // CSS属性 + return element.getCssValue(extraction.getElementAttribute()); + case "6": // 匹配 xpath 的元素数量(storeXpathCount) + return String.valueOf(seleniumUtils.findElements(locType,elementLoc).size()); + default: + return ""; + } + } + return ""; + } + + + /** * 获取(前置//后置)等待时间 * @@ -916,4 +1493,7 @@ public class UiSceneStepsServiceImpl implements IUiSceneStepsService { } + + + } \ No newline at end of file