上传获取列表元素的类,准备添加一个自定义等待

This commit is contained in:
彭宇琦 2020-04-30 18:09:47 +08:00
parent bb6797d4f7
commit cd6a5cfb58
10 changed files with 498 additions and 207 deletions

View File

@ -101,5 +101,13 @@
<artifactId>hutool-all</artifactId>
<version>5.0.2</version>
</dependency>
<!-- HttpClient 用于接口测试 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
</dependencies>
</project>

View File

@ -1,7 +1,9 @@
package pres.auxiliary.work.selenium.brower;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.openqa.selenium.JavascriptExecutor;
@ -33,7 +35,7 @@ public abstract class AbstractBrower {
/**
* 存储打开的页面
*/
HashMap<String, Page> pageList = new HashMap<String, Page>(16);
HashMap<String, Page> pageMap = new HashMap<String, Page>(16);
/**
* 用于存储WebDriver当前指向的页面信息
@ -135,9 +137,9 @@ public abstract class AbstractBrower {
// 若pageList无元素则表明此为第一次打开浏览器则无论openNewLabel是何值均按照同一规则打开页面
// 若pageList有元素则根据openNewLabel参数来决定如何打开新的页面
if (pageList.size() == 0) {
if (pageMap.size() == 0) {
// 存储页面对象
pageList.put(newPage.getPageName(), newPage);
pageMap.put(newPage.getPageName(), newPage);
// 将当前页面对象指向newPage
nowPage = newPage;
// 在当前标签上打开页面
@ -145,15 +147,15 @@ public abstract class AbstractBrower {
} else {
if (openNewLabel) {
// 存储页面对象
pageList.put(newPage.getPageName(), newPage);
pageMap.put(newPage.getPageName(), newPage);
// 将当前页面对象指向newPage
nowPage = newPage;
// 在标签页上打开页面
openNewLabelPage();
} else {
// 先在pageList移除nowPage
pageList.remove(nowPage.getPageName());
pageList.put(newPage.getPageName(), newPage);
pageMap.remove(nowPage.getPageName());
pageMap.put(newPage.getPageName(), newPage);
// 将nowPage指向newPage
nowPage = newPage;
// 在当前标签上打开页面
@ -193,7 +195,7 @@ public abstract class AbstractBrower {
public JSONObject getAllInformation() {
// 遍历所有标签页存储标签页信息
JSONArray labelInformation = new JSONArray();
pageList.forEach((name, page) -> {
pageMap.forEach((name, page) -> {
labelInformation.add(page.getPageInformation());
});
// 存储标签页信息
@ -203,28 +205,20 @@ public abstract class AbstractBrower {
}
/**
* 用于根据名称返回对浏览器的各项信息若信息不存在则返回空
*
* @param key 需要搜索的信息名称
* @return 名称对应的浏览器信息
* 用于返回当前在浏览器中被打开的页面
* @return 在浏览器中被打开的{@link Page}对象
*/
public String getInformation(String key) {
if (informationJson.containsKey(key)) {
//若需要查看标签信息则对标签信息即时进行存储
if ("标签信息".equals(key)) {
// 遍历所有标签页存储标签页信息
JSONArray labelInformation = new JSONArray();
pageList.forEach((name, page) -> {
labelInformation.add(page.getPageInformation());
});
// 存储标签页信息
informationJson.put("标签信息", labelInformation);
public List<Page> getOpenPage() {
List<Page> pageList = new ArrayList<>();
//遍历pageMap存储所有存在handle的Page对象
pageMap.forEach((k, v) -> {
if (!v.getHandle().isEmpty()) {
pageList.add(v);
}
return informationJson.getString(key);
} else {
return "";
}
});
return pageList;
}
/**
@ -261,14 +255,14 @@ public abstract class AbstractBrower {
driver.switchTo().window(newHandle);
// 将标签内容全部置空及当前页面内容置空
pageList.clear();
pageMap.clear();
nowPage = null;
} else {
// 根据当前窗口handle查找相应的page对象
Page page = findPage(driver.getWindowHandle());
// 若窗口指向的页面存在则将该页面从类中移除
if (page != null) {
pageList.remove(page.getPageName());
pageMap.remove(page.getPageName());
}
// 关闭当前标签
@ -290,7 +284,7 @@ public abstract class AbstractBrower {
//将driver指定为null
driver = null;
// 清空页面存储的内容
pageList.clear();
pageMap.clear();
nowPage = null;
}
@ -314,7 +308,7 @@ public abstract class AbstractBrower {
*/
public void switchWindow(Page page) {
// 查找pageList中是否存在传入的page若存在则获取相应的handle后对窗口进行切换
if (pageList.containsKey(page.getPageName())) {
if (pageMap.containsKey(page.getPageName())) {
try {
driver.switchTo().window(page.getHandle());
} catch (NoSuchWindowException e) {
@ -404,8 +398,8 @@ public abstract class AbstractBrower {
* @return 页面对应窗口的Handle
*/
private String findPageHandle(String pageName) {
if (pageList.containsKey(pageName)) {
return pageList.get(pageName).getHandle();
if (pageMap.containsKey(pageName)) {
return pageMap.get(pageName).getHandle();
} else {
return "";
}
@ -419,10 +413,10 @@ public abstract class AbstractBrower {
*/
private Page findPage(String handle) {
// 遍历所有的page查询与传入相同的handle
for (String pageName : pageList.keySet()) {
for (String pageName : pageMap.keySet()) {
// 若存储的handle与传入的handle相同则对其进行
if (handle.equals(pageList.get(pageName).getHandle())) {
return pageList.get(pageName);
if (handle.equals(pageMap.get(pageName).getHandle())) {
return pageMap.get(pageName);
}
}

View File

@ -6,18 +6,20 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.selenium.event.NoSuchWindownException;
import pres.auxiliary.selenium.xml.ByType;
import pres.auxiliary.selenium.xml.ReadXml;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.brower.Page;
/**
* <p><b>文件名</b>AbstractElement.java</p>
@ -40,7 +42,12 @@ public abstract class AbstractElement {
/**
* 用于指向存储控件定位方式的xml文件
*/
ReadXml xml = new ReadXml();
ReadXml xml;
/**
* 用于存储浏览器对象
*/
AbstractBrower brower;
/**
* 存储单个控件的等待时间
*/
@ -55,7 +62,7 @@ public abstract class AbstractElement {
private ArrayList<String> iframeNameList = new ArrayList<>();
/**
* 用于存储元素通用的等待时间
* 用于存储元素通用的等待时间默认5秒
*/
private long waitTime = 5;
@ -65,15 +72,24 @@ public abstract class AbstractElement {
boolean isAutoSwitchIframe = true;
/**
* 构造对象并存储浏览器的WebDriver对象
* 通过{@link WebDriver}对象进行构造
*
* @param driver 浏览器的WebDriver对象
* @param driver {@link WebDriver}对象
*/
public AbstractElement(WebDriver driver) {
this.driver = driver;
browserHandles = this.driver.getWindowHandle();
}
/**
* 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象
*/
public AbstractElement(AbstractBrower brower) {
this.brower = brower;
this.driver = brower.getDriver();
}
/**
* 用于对单个控件设置等待时间
*
@ -115,7 +131,11 @@ public abstract class AbstractElement {
* @param isBreakRootFrame 是否需要将窗体切回到顶层
*/
public void setXmlFile(File xmlFile, boolean isBreakRootFrame) {
xml.setXmlPath(xmlFile);
if (xml == null) {
xml = new ReadXml(xmlFile);
} else {
xml.setXmlPath(xmlFile);
}
if (isBreakRootFrame) {
switchRootFrame();
@ -199,16 +219,24 @@ public abstract class AbstractElement {
* @see #switchFrame(String)
*/
public void switchFrame(String name, ByType byType) {
List<ElementInformation> nameList = new ArrayList<ElementInformation>();
List<String> nameList = new ArrayList<String>();
//判断传入的元素名称是否存在于xml文件中若存在则将该元素的父层名称存储至nameList
if (xml != null && xml.isElement(name) && isAutoSwitchIframe) {
nameList.addAll(getParentFrameName(name));
}
//将相应的元素存入nameList中
nameList.add(new ElementInformation(name, byType, controlWaitTime.containsKey(name) ? controlWaitTime.get(name) : waitTime));
//调用
//调用切换窗体的方法
switchFrame(nameList);
//将相应的元素存入nameList中
if (byType != null) {
driver.switchTo().frame(recognitionElements(new ElementInformation(name, byType, getWaitTime(name))).get(0));
} else {
driver.switchTo().frame(recognitionElements(new ElementInformation(name, getWaitTime(name))).get(0));
}
//切换窗体
iframeNameList.add(name);
}
/**
@ -230,12 +258,12 @@ public abstract class AbstractElement {
*
* @param elementInformationList 存储窗体的名称或xpath与css定位方式的List集合
*/
private void switchFrame(List<ElementInformation> elementInformationList) {
elementInformationList.forEach(elementInformation -> {
void switchFrame(List<String> frameNameList) {
frameNameList.forEach(frameName -> {
//判断name指向的窗体是否在iframeNameList中若存在则向上切换父层直到切换到name指向的窗体若不存在则直接切换并添加窗体名称
if (iframeNameList.contains(elementInformation.name)) {
if (iframeNameList.contains(frameName)) {
//获取name窗体在iframeNameList中的位置
int index = iframeNameList.indexOf(elementInformation.name);
int index = iframeNameList.indexOf(frameName);
//获取需要向上切换窗体的次数公式为推断出来
int count = iframeNameList.size() - index - 1;
for (int i = 0; i < count; i++) {
@ -243,36 +271,12 @@ public abstract class AbstractElement {
}
} else {
//切换窗体
driver.switchTo().frame(recognitionElements(elementInformation).get(0));
iframeNameList.add(elementInformation.name);
driver.switchTo().frame(recognitionElements(new ElementInformation(frameName, getWaitTime(frameName))).get(0));
iframeNameList.add(frameName);
}
});
}
/**
* 该方法可用于切换弹出的窗口新标签或新窗口并返回新窗口的WebDriver对象若无新窗口则返回当前的窗口的WebDriver对象
* 注意该方法只能切换弹出一个窗口的情况若有多个窗口通过该方法无法准确定位可参考方法{@link #switchWindow(String)}
*/
public void switchWindow() {
Set<String> handles = driver.getWindowHandles();
// 判断是否只存在一个窗体若只存在一个则直接返回当前浏览器的WebDriver对象
if (handles.size() == 1) {
return;
}
// 获取当前窗口的handle
String winHandle = driver.getWindowHandle();
// 循环获取所有的页面handle
for (String newWinHandle : handles) {
// 判断获取到的窗体handle是否为当前窗口的handle若不是则将其定位到获取的handle对应的窗体上
if (!newWinHandle.equals(winHandle)) {
driver.switchTo().window(newWinHandle);
}
}
throw new NoSuchWindownException("未找到相应的窗体");
}
/**
* 该方法用于将窗口切换回最原始的窗口上
*/
@ -294,18 +298,46 @@ public abstract class AbstractElement {
if (handles.size() == 1) {
return;
}
List<Page> pageList = new ArrayList<>();
//若浏览器对象存在则将已打开的页面的handle进行存储优先遍历新打开的标签
if (brower != null) {
pageList.addAll(brower.getOpenPage());
}
//移除已打开的窗口
handles.removeAll(pageList.stream().map(page -> {
return page.getHandle();
}).collect(Collectors.toList()));
// 循环获取所有的页面handle
for (String newWinHandle : handles) {
//切换窗口并查找元素是否在窗口上若存在则结束切换
driver.switchTo().window(newWinHandle);
// 调用judgeElementMode()方法来判断元素是否存在如果元素存在则返回相应页面的WebDriver对象若抛出异常元素不存在则返回当前
try {
recognitionElements(controlName).get(0);
} catch (TimeoutException e) {
//构造信息因为在构造过程中会判断元素是否存在
new ElementInformation(controlName, getWaitTime(controlName));
return;
}catch (Exception e) {
continue;
}
}
//若不在新打开的窗口上则遍历已打开的窗口
if (brower != null) {
for (Page page : pageList) {
//切换窗口并查找元素是否在窗口上若存在则结束切换
brower.switchWindow(page);
try {
new ElementInformation(controlName, getWaitTime(controlName));
return;
}catch (Exception e) {
continue;
}
}
}
//若遍历所有窗口后均未能查到元素则抛出异常
throw new NoSuchWindownException("未找到存在元素" + controlName + "所在的窗体");
}
@ -375,118 +407,20 @@ public abstract class AbstractElement {
* @throws UnrecognizableLocationModeException 元素无法识别时抛出的异常
*/
List<WebElement> recognitionElements(ElementInformation element) {
//判断元素是否存在于xml文件中根据返回的状态来判断调用的方法
if (xml.isElement(element.name)) {
return findXmlElement(element);
} else {
return findCommonElement(element);
}
}
/**
* 根据传入的元素定位方式返回在页面上查找到的WebElement对象
* @param name 元素内容
* @return
*/
private List<WebElement> findCommonElement(ElementInformation element) {
//若未对元素的定位方式进行存储则调用方法对元素的定位方式进行识别
if (element.byType == null) {
element.byType = judgeElementLocationMode(element.value);
}
if (isExistElement(element)) {
return driver.findElements(getBy(element.byType, element.value));
}
// 若循环结束后仍未能找到该元素则返回一个空串
throw new TimeoutException("元素“" + element.name + "”无法查找,请核对定位方式:" + element.byType.getValue() + "=" + element.value);
}
/**
* 根据传入的元素名称到指定的xml文件中查找相应的有效的定位方式并在页面中查找返回查找到的元素对象
* @param name 需要查找的元素名称
* @return 页面中查找到的元素
* @throws TimeoutException 当元素不能找到时抛出的异常
*/
private List<WebElement> findXmlElement(ElementInformation element) {
//若元素的定位方式未被存储则调用方法对元素的定位方式进行获取
if (element.byType == null || element.value.isEmpty()) {
// 循环逐个在页面上配对有效的标签对应的定位方式
for (ByType mode : xml.getElementMode(element.name)) {
//存储当前查询到的元素信息
element.byType = mode;
element.value = xml.getValue(element.name, mode);
//若元素能被找到则结束循环
if (isExistElement(element)) {
break;
}
}
// 若循环结束后仍未能找到该元素则抛出异常
throw new TimeoutException("元素“" + element.name + "”无法查找请核对xml文件" + xml.getXmlFile().getName() + "\n文件路径" + xml.getXmlFile().getAbsolutePath());
}
return driver.findElements(getBy(element.byType, element.value));
return driver.findElements(element.getBy());
}
/**
* 用于判断传入参数的定位方式只识别xpath路径与绝对的css路径两种定位方式
*
* @param text 元素定位方式
* @return {@link ByType}枚举
* 用于返回控件的等待时间若设置单个控件的等待时间使用{@link #setContorlWaitTime(String, long)}方法设置
* 则返回设置的控件等待时间若未设置单个控件的等待时间则返回设置的通用等待时间使用{@link #setWaitTime(long)}方法
* 若未对通用时间进行设置则返回默认时间{@link #waitTime}
* @param name 控件名称
* @return 相应控件的等待时间
* @see #setContorlWaitTime(String, long)
* @see #setWaitTime(long)
*/
private ByType judgeElementLocationMode(String text) {
// 如果抛出元素名称查找不到的的异常则对应匹配xpath和绝对css路径两种定位方式
// 匹配xpath定位判定方法判断text的第一个字符是否是/
if (text.indexOf("/") == 0) {
// 查找该定位方式在有限的时间内是否内被查到
return ByType.XPATH;
} else if (text.indexOf("html") == 0) {
return ByType.CSS;
} else {
throw new UnrecognizableLocationModeException("元素定位方式类型无法识别:" + text);
}
}
/**
* 根据页面的等待时间和元素定位方式在页面上查找相应的元素返回是否能查到元素
* @param time 控件等待时间
* @param by 元素定位方式
* @return 是否能查找到的元素
*/
boolean isExistElement(ElementInformation element) {
// new WebDriverWait(driver, time, 200).until(ExpectedConditions.elementToBeClickable(by));
By by = getBy(element.byType, element.value);
//当查找到元素时则返回true若查不到元素则会抛出异常故返回false
try {
new WebDriverWait(driver, element.waitTime, 200).until(ExpectedConditions.presenceOfElementLocated(by));
return true;
} catch (Exception e) {
return false;
}
}
By getBy(ByType byType, String value) {
//根据元素的定位方式对定位内容进行选择返回相应的By对象
switch (byType) {
case XPATH:
return By.xpath(value);
case CLASSNAME:
return By.className(value);
case CSS:
return By.cssSelector(value);
case ID:
return By.id(value);
case LINKTEXT:
return By.linkText(value);
case NAME:
return By.name(value);
case TAGNAME:
return By.tagName(value);
default:
throw new UnrecognizableLocationModeException("无法识别的定位类型:" + byType);
}
long getWaitTime(String name) {
return controlWaitTime.containsKey(name) ? controlWaitTime.get(name) : waitTime;
}
/**
@ -495,16 +429,16 @@ public abstract class AbstractElement {
* @param name 元素在xml文件中的名称
* @return 元素在xml文件中所有的父窗体集合
*/
List<ElementInformation> getParentFrameName(String name) {
List<String> getParentFrameName(String name) {
//存储获取到的父层窗体名称
List<ElementInformation> nameList = new ArrayList<ElementInformation>();
List<String> nameList = new ArrayList<String>();
//获取元素所在窗体的名称
String iframeName = xml.getIframeName(name);
//循环判断窗体是否存在方法返回不为空若存在则再将父窗体进行存储
while(!iframeName.isEmpty()) {
//存储窗体
nameList.add(new ElementInformation(iframeName, controlWaitTime.containsKey(iframeName) ? controlWaitTime.get(iframeName) : waitTime));
nameList.add(iframeName);
//再以当前窗体的名称再次获取该窗体的父窗体
iframeName = xml.getIframeName(iframeName);
}
@ -570,9 +504,13 @@ public abstract class AbstractElement {
this.name = name;
this.waitTime = waitTime;
//若未指定xml文件或xml文件中不存在name对应的元素则将name的值赋给value表示
//若未指定xml文件或者在xml文件中无法查到相应的元素时则将name的值赋给value且根据value判断相应定位方式
if (xml == null || !xml.isElement(name)) {
value = name;
setCommonElementLocationMode();
} else {
//若指定了xml文件且传入的元素名称存在与xml文件中则判断元素相应的定位方式及定位内容
setXmlElementLocation();
}
}
@ -589,12 +527,13 @@ public abstract class AbstractElement {
//若未指定xml文件则将name的值赋给value
if (xml == null) {
value = name;
}
//xml文件中不存在name对应的元素则将name的值赋给value反之则在xml文件中查找对应的定位内容
if (!xml.isElement(name)) {
value = name;
} else {
value = xml.getValue(name, byType);
//xml文件中不存在name对应的元素则将name的值赋给value反之则在xml文件中查找对应的定位内容
if (!xml.isElement(name)) {
value = name;
} else {
value = xml.getValue(name, byType);
}
}
}
@ -621,5 +560,109 @@ public abstract class AbstractElement {
public String getValue() {
return value;
}
/**
* 用于根据传入的参数识别非xml文件内的元素定位方式
* 该方法能快速识别xpath定位方式以及绝对css定位方式若不是以上两种定位方式
* 则会遍历所有的定位方式此时会降低运行速度建议在不是以上两种定位方式的
* 情况下直接指定元素的定位方式以提高效率
*/
void setCommonElementLocationMode() {
// 如果抛出元素名称查找不到的的异常则对应匹配xpath和绝对css路径两种定位方式
// 匹配xpath定位判定方法判断text的第一个字符是否是/
if (value.indexOf("/") == 0) {
// 查找该定位方式在有限的时间内是否内被查到
byType = ByType.XPATH;
//在页面中查找元素若元素能找到则结束查找
if (isExistElement()) {
return;
}
} else if (value.indexOf("html") == 0) {
byType = ByType.CSS;
//在页面中查找元素若元素能找到则结束查找
if (isExistElement()) {
return;
}
} else {
//若元素无法识别则将所有的定位类型排除xpath类型与之进行对比直到在页面上找到元素为止
for(ByType type : ByType.values()) {
if (type == ByType.XPATH) {
continue;
}
byType = type;
//在页面中查找元素若元素能找到则结束查找
if (isExistElement()) {
return;
}
}
}
//若所有的定位方式均无法查找到元素则抛出异常
throw new UnrecognizableLocationModeException("元素定位方式类型无法识别:" + value);
}
/**
* 用于设置xml文件内的元素的定位方式及定位内容
*/
void setXmlElementLocation() {
// 循环逐个在页面上配对有效的标签对应的定位方式
for (ByType mode : xml.getElementMode(name)) {
//存储当前查询到的元素信息
byType = mode;
value = xml.getValue(name, mode);
//若元素能被找到则结束循环
if (isExistElement()) {
break;
}
// 若循环结束后仍未能找到该元素则抛出异常
throw new TimeoutException("元素“" + name + "”无法查找请核对xml文件" + xml.getXmlFile().getName() + "\n文件路径" + xml.getXmlFile().getAbsolutePath());
}
}
/**
* 根据元素的参数返回元素的By对象
* @return 元素的By对象
*/
By getBy() {
//根据元素的定位方式对定位内容进行选择返回相应的By对象
switch (byType) {
case XPATH:
return By.xpath(value);
case CLASSNAME:
return By.className(value);
case CSS:
return By.cssSelector(value);
case ID:
return By.id(value);
case LINKTEXT:
return By.linkText(value);
case NAME:
return By.name(value);
case TAGNAME:
return By.tagName(value);
default:
throw new UnrecognizableLocationModeException("无法识别的定位类型:" + byType);
}
}
/**
* 根据页面的等待时间和元素定位方式在页面上查找相应的元素返回是否能查到元素
* @param time 控件等待时间
* @param by 元素定位方式
* @return 是否能查找到的元素
*/
boolean isExistElement() {
// new WebDriverWait(driver, time, 200).until(ExpectedConditions.elementToBeClickable(by));
// new WebDriverWait(driver, time, 200).until(ExpectedConditions.titleContains(""));
//当查找到元素时则返回true若查不到元素则会抛出异常故返回false
return new WebDriverWait(driver, waitTime, 200).
until((driver) -> {
WebElement element = driver.findElement(getBy());
return element != null;
});
}
}
}

View File

@ -3,6 +3,23 @@ package pres.auxiliary.work.selenium.element;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import pres.auxiliary.selenium.xml.ByType;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
/**
* <p><b>文件名</b>CommonElement.java</p>
* <p><b>用途</b>
* 提供在辅助化测试中对页面单一元素获取的方法类中获取元素的方法兼容传入定位方式对
* 元素进行查找建议使用xml对页面元素的定位方式进行存储以简化编码时的代码量也便于
* 对代码的维护
* </p>
* <p><b>编码时间</b>2020年4月26日下午10:34:55</p>
* <p><b>修改时间</b>2020年4月26日下午10:34:55</p>
* @author
* @version Ver1.0
* @since JDK 12
*
*/
public class CommonElement extends AbstractElement {
/**
* 构造对象并存储浏览器的WebDriver对象
@ -13,22 +30,43 @@ public class CommonElement extends AbstractElement {
super(driver);
}
/**
* 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象
*/
public CommonElement(AbstractBrower brower) {
super(brower);
}
/**
* 用于根据xml文件中元素的名称返回对应的WebElement对象该方法亦可传入元素
* 的xpath或css定位内容来获取元素的WebElement对象
* 定位内容通过遍历所有的定位方式在页面上查找元素来获取元素的WebElement对象
* 建议传入的定位内容为xpath路径或绝对的css路径若非这两路径则在识别元素时会很慢降低
* 程序运行速度若非xml文件中的元素且不是xpath路径或绝对的css路径建议使用{@link #getWebElement(String, ByType)}方法
* @param name 元素的名称或元素定位内容
* @return WebElement对象
*/
public WebElement getWebElement(String name) {
//判断传入的元素是否在xml文件中若存在再判断是否自动切换窗体若需要则获取元素的所有父窗体并进行切换
if (xml.isElement(name)) {
//判断元素是否需要自动切换窗体
if (isAutoSwitchIframe) {
switchFrame(getParentFrameName(name));
}
if (xml != null && xml.isElement(name) && isAutoSwitchIframe) {
switchFrame(getParentFrameName(name));
}
return null;
return recognitionElements(new ElementInformation(name, getWaitTime(name))).get(0);
}
/**
* 用于根据xml文件中元素的名称与定位方式返回对应的WebElement对象该方法亦可传入元素
* 定位内容并根据定位方式对页面数据进行查找
* @param name 元素的名称或元素定位内容
* @return WebElement对象
*/
public WebElement getWebElement(String name, ByType byType) {
//判断传入的元素是否在xml文件中若存在再判断是否自动切换窗体若需要则获取元素的所有父窗体并进行切换
if (xml != null && xml.isElement(name) && isAutoSwitchIframe) {
switchFrame(getParentFrameName(name));
}
return recognitionElements(new ElementInformation(name, byType, getWaitTime(name))).get(0);
}
}

View File

@ -0,0 +1,80 @@
package pres.auxiliary.work.selenium.element;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
/**
* <p><b>文件名</b>DataListElement.java</p>
* <p><b>用途</b>
* 提供在辅助化测试中对页面列表元素获取的方法并对列表元素的获取做了优化
* 类中获取元素的方法兼容传入定位方式对元素进行查找建议使用xml对页面元素的
* 定位方式进行存储以简化编码时的代码量也便于对代码的维护
* </p>
* <p><b>编码时间</b>2020年4月29日下午6:18:46</p>
* <p><b>修改时间</b>2020年4月29日下午6:18:46</p>
* @author 彭宇琦
* @version Ver1.0
* @since JDK 12
*
*/
public class DataListElement extends AbstractElement {
/**
* 用于存储获取到的列表一列元素key为列表名称value为列表元素
*/
private HashMap<String, List<WebElement>> elementMap = new HashMap<>(16);
/**
* 用于判断列表的第一行元素是否为标题元素
*/
private boolean isFristRowTitle = false;
/**
* 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象
*/
public DataListElement(AbstractBrower brower) {
super(brower);
}
/**
* 构造对象并存储浏览器的WebDriver对象
*
* @param driver 浏览器的WebDriver对象
*/
public DataListElement(WebDriver driver) {
super(driver);
}
/**
* 用于设置首行元素是否为标题元素
* @param isFristRowTitle 首行是否为标题元素
*/
public void setFristRowTitle(boolean isFristRowTitle) {
this.isFristRowTitle = isFristRowTitle;
}
/**
* 用于根据xml文件中元素的名称返回对应的获取到的一组WebElement对象该方法亦可传入元素
* 定位内容通过遍历所有的定位方式在页面上查找元素来获取元素的WebElement对象
* 建议传入的定位内容为xpath路径或绝对的css路径若非这两路径则在识别元素时会很慢降低
* 程序运行速度
*
* @param names 一组控件的名称或xpath与css定位方式
*/
public void add(String name) {
//判断当前列名是否存在不存在则先存储其类名
if (!elementMap.containsKey(name)) {
elementMap.put(name, new ArrayList<WebElement>());
}
}
}

View File

@ -0,0 +1,28 @@
package pres.auxiliary.work.selenium.element;
public class NoSuchWindownException extends RuntimeException {
private static final long serialVersionUID = 1L;
public NoSuchWindownException() {
super();
}
public NoSuchWindownException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
super(arg0, arg1, arg2, arg3);
}
public NoSuchWindownException(String arg0, Throwable arg1) {
super(arg0, arg1);
}
public NoSuchWindownException(String arg0) {
super(arg0);
}
public NoSuchWindownException(Throwable arg0) {
super(arg0);
}
}

View File

@ -357,7 +357,7 @@ public abstract class AbstractTestCaseWrite<T extends AbstractTestCaseWrite<T>>
}
/**
* 用于将生成测试用例方法继承自{@link Case}类的方法成的测试用例添加到测试用例文件中
* 用于将测试用例模板继承自{@link Case}类的方法成的测试用例添加到测试用例文件中
*
* @param testCase 测试用例生成方法
* @return 类本身

View File

@ -67,7 +67,7 @@ public class JiraTestCaseWrite extends CommonTestCaseWrite<JiraTestCaseWrite> {
* @since JDK 12
*
*/
enum JiraFieldIdType {
public enum JiraFieldIdType {
/**
* 标题Name
*/

View File

@ -0,0 +1,79 @@
package pres.auxiliary.work.selenium.element;
import java.io.File;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import pres.auxiliary.work.selenium.brower.ChromeBrower;
import pres.auxiliary.work.selenium.brower.ChromeBrower.ChromeOptionType;
/**
* <p><b>文件名</b>CommonElementTest.java</p>
* <p><b>用途</b>
* {@link CommonElement}类方法进行单元测试
* </p>
* <p><b>测试对象</b>桂建通工资管理的工资单管理模块获取第一条数据的单位信息</p>
* <p><b>编码时间</b>2020年4月30日上午7:44:34</p>
* <p><b>修改时间</b>2020年4月30日上午7:44:34</p>
* @author
* @version Ver1.0
* @since JDK 12
*
*/
public class CommonElementTest {
ChromeBrower cb = new ChromeBrower(new File("Resource/BrowersDriver/Chrom/78.0394.70/chromedriver.exe"));
CommonElement ce;
@BeforeClass
public void initDate() {
cb.addConfig(ChromeOptionType.CONTRAL_OPEN_BROWER, "127.0.0.1:9222");
ce = new CommonElement(cb);
}
/**
* 用于测试非xml文件中的传参进行窗体切换与元素的获取
*/
@Test
public void getCommonElementTest() {
ce.switchFrame("//iframe[contains(@src, '/Regulatory/admin/index.jsp')]");
ce.switchFrame("//iframe[contains(@src, '工资单管理')]");
System.out.println(ce.getWebElement("//*[@id=\"listBox\"]/li[1]/div[1]/p/span[1]").getText());
}
/**
* 用于测试xml文件中的传参进行窗体切换与元素的获取
*/
@Test
public void getXmlElementTest() {
File xmlFile = new File("src/test/java/pres/auxiliary/work/selenium/element/测试文件.xml");
ce.setXmlFile(xmlFile, false);
ce.setAutoSwitchIframe(false);
ce.switchFrame("主窗体");
ce.switchFrame("工资发放详情");
System.out.println(ce.getWebElement("单位名称").getText());
}
/**
* 用于测试xml文件的自动定位窗体
*/
@Test
public void autoLocationElementTest() {
File xmlFile = new File("src/test/java/pres/auxiliary/work/selenium/element/测试文件.xml");
ce.setXmlFile(xmlFile, false);
System.out.println(ce.getWebElement("单位名称").getText());
}
/**
* 用于测试xml文件的多次切换窗体后自动定位窗体
*/
@Test
public void exceptAutoLocationElementTest() {
File xmlFile = new File("src/test/java/pres/auxiliary/work/selenium/element/测试文件.xml");
ce.setXmlFile(xmlFile, false);
//先切主窗体
ce.switchFrame("主窗体");
//在获取元素前会判断元素所在窗体由于主窗体是爷爷辈窗体获取元素前会切换工资发放详情窗体
System.out.println(ce.getWebElement("单位名称").getText());
}
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="工资专户管理">
<templet>
<!-- 窗体模板 -->
<xpath id='1'>//iframe[contains(@src,'${src}')]</xpath>
</templet>
<iframe name='主窗体'>
<xpath is_use='true' temp_id='1'
src='/Regulatory/admin/index.jsp' />
<iframe name='工资发放详情'>
<xpath is_use='true' temp_id='1' src='工资单管理' />
<!-- 搜索项 -->
<element name='单位名称'>
<xpath is_use='true'>//*[@id="listBox"]/li[1]/div[1]/p/span[1]</xpath>
</element>
</iframe>
</iframe>
</project>