添加下拉选项元素获取方法

This commit is contained in:
彭宇琦 2020-05-22 19:15:12 +08:00
parent 2987267baa
commit e62c68b777
12 changed files with 569 additions and 288 deletions

View File

@ -10,6 +10,7 @@ import org.dom4j.Attribute;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.DocumentException; import org.dom4j.DocumentException;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.InvalidXPathException;
import org.dom4j.io.SAXReader; import org.dom4j.io.SAXReader;
import org.openqa.selenium.By; import org.openqa.selenium.By;
@ -222,10 +223,15 @@ public class ReadXml {
//获取元素的xpath查找所有带name属性的与传入的name相同元素 //获取元素的xpath查找所有带name属性的与传入的name相同元素
String xpath = "//*[@name='" + name + "']"; String xpath = "//*[@name='" + name + "']";
//若不存在该节点则返回false反之则返回true //若不存在该节点则返回false反之则返回true
if (dom.getRootElement().selectSingleNode(xpath) == null) { try {
if (dom.getRootElement().selectSingleNode(xpath) == null) {
return false;
} else {
return true;
}
} catch (InvalidXPathException e) {
//当写入name为一个xpath时会抛出该异常若存在该异常则直接返回false
return false; return false;
} else {
return true;
} }
} }

View File

@ -87,6 +87,15 @@ public abstract class AbstractElement {
this.driver = brower.getDriver(); this.driver = brower.getDriver();
} }
/**
* 用于设置事件等待时间默认时间为5秒
*
* @param waitTime 事件等待时间
*/
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}
/** /**
* 用于对单个控件设置等待时间 * 用于对单个控件设置等待时间
* *
@ -97,14 +106,6 @@ public abstract class AbstractElement {
controlWaitTime.put(name, waitTime); controlWaitTime.put(name, waitTime);
} }
/**
* 用于设置控件的通用等待时间
* @param waitTime 控件通用的等待时间
*/
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}
/** /**
* 设置是否自动切换窗体 * 设置是否自动切换窗体
* @param switchIframe 是否自动切换窗体 * @param switchIframe 是否自动切换窗体
@ -203,7 +204,7 @@ public abstract class AbstractElement {
* @param name 窗体的名称或xpath与css定位方式 * @param name 窗体的名称或xpath与css定位方式
*/ */
public void switchFrame(String name) { public void switchFrame(String name) {
switchFrame(new ElementInformation(name, null)); switchFrame(new ElementInformation(name, null, ElementType.COMMON_ELEMENT));
} }
/** /**
@ -216,7 +217,7 @@ public abstract class AbstractElement {
* @see #switchFrame(String) * @see #switchFrame(String)
*/ */
public void switchFrame(String name, ByType byType) { public void switchFrame(String name, ByType byType) {
switchFrame(new ElementInformation(name, byType)); switchFrame(new ElementInformation(name, byType, ElementType.COMMON_ELEMENT));
} }
/** /**
@ -270,7 +271,7 @@ public abstract class AbstractElement {
} }
} else { } else {
//切换窗体 //切换窗体
driver.switchTo().frame(driver.findElement(recognitionElement(new ElementInformation(frameName, null)))); driver.switchTo().frame(driver.findElement(recognitionElement(new ElementInformation(frameName, null, ElementType.COMMON_ELEMENT))));
iframeNameList.add(frameName); iframeNameList.add(frameName);
} }
}); });
@ -315,7 +316,7 @@ public abstract class AbstractElement {
driver.switchTo().window(newWinHandle); driver.switchTo().window(newWinHandle);
try { try {
//构造信息因为在构造过程中会判断元素是否存在 //构造信息因为在构造过程中会判断元素是否存在
recognitionElement(new ElementInformation(controlName, null)); recognitionElement(new ElementInformation(controlName, null, ElementType.COMMON_ELEMENT));
return; return;
}catch (Exception e) { }catch (Exception e) {
continue; continue;
@ -328,7 +329,7 @@ public abstract class AbstractElement {
//切换窗口并查找元素是否在窗口上若存在则结束切换 //切换窗口并查找元素是否在窗口上若存在则结束切换
brower.switchWindow(page); brower.switchWindow(page);
try { try {
recognitionElement(new ElementInformation(controlName, null)); recognitionElement(new ElementInformation(controlName, null, ElementType.COMMON_ELEMENT));
return; return;
}catch (Exception e) { }catch (Exception e) {
continue; continue;
@ -606,9 +607,9 @@ public abstract class AbstractElement {
* 存储获取元素时的信息 * 存储获取元素时的信息
* </p> * </p>
* <p><b>编码时间</b>2020年5月9日上午7:57:24</p> * <p><b>编码时间</b>2020年5月9日上午7:57:24</p>
* <p><b>修改时间</b>2020年5月9日上午7:57:24</p> * <p><b>修改时间</b>2020年5月22日上午8:18:39</p>
* @author 彭宇琦 * @author 彭宇琦
* @version Ver1.0 * @version Ver1.1
* @since JDK 12 * @since JDK 12
* *
*/ */
@ -621,15 +622,48 @@ public abstract class AbstractElement {
* 存储元素的定位方式 * 存储元素的定位方式
*/ */
public ByType byType; public ByType byType;
/**
* 用于标记元素的类型
*/
public ElementType elementType;
/**
* 初始化信息
* @param name 元素名称或定位内容
* @param byType 元素定位
* @param elementType 元素类型
*/
public ElementInformation(String name, ByType byType, ElementType elementType) {
this(name, byType);
this.elementType = elementType;
}
/** /**
* 初始化信息 * 初始化信息
* @param name 元素名称或定位内容 * @param name 元素名称或定位内容
* @param byType 元素定位 * @param byType 元素定位
*/ */
public ElementInformation(String name, ByType byType) { public ElementInformation(String name, ByType byType) {
super();
this.name = name; this.name = name;
this.byType = byType; this.byType = byType;
} }
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ElementInformation other = (ElementInformation) obj;
if (byType != other.byType)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
} }
} }

View File

@ -7,7 +7,6 @@ import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.selenium.xml.ByType; import pres.auxiliary.selenium.xml.ByType;
import pres.auxiliary.work.selenium.brower.AbstractBrower; import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.Element.ElementType;
/** /**
* <p><b>文件名</b>CommonElement.java</p> * <p><b>文件名</b>CommonElement.java</p>
@ -60,7 +59,7 @@ public class CommonElement extends AbstractElement {
* @return {@link Element}对象 * @return {@link Element}对象
*/ */
public Element getElement(String name, ByType byType) { public Element getElement(String name, ByType byType) {
return getElement(new ElementInformation(name, byType)); return getElement(new ElementInformation(name, byType, ElementType.COMMON_ELEMENT));
} }
/** /**
@ -101,5 +100,10 @@ public class CommonElement extends AbstractElement {
WebElement element = driver.findElement(by); WebElement element = driver.findElement(by);
return element != null; return element != null;
}); });
/*
return new WebDriverWait(driver, waitTime, 200).
until(ExpectedConditions.and(ExpectedConditions.visibilityOfAllElementsLocatedBy(by),
ExpectedConditions.invisibilityOfElementLocated(by)));
*/
} }
} }

View File

@ -1,21 +1,17 @@
package pres.auxiliary.work.selenium.element; package pres.auxiliary.work.selenium.element;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait; import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.selenium.xml.ByType; import pres.auxiliary.selenium.xml.ByType;
import pres.auxiliary.work.selenium.brower.AbstractBrower; import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.Element.ElementType;
/** /**
* <p><b>文件名</b>DataListElement.java</p> * <p><b>文件名</b>DataListElement.java</p>
@ -30,27 +26,7 @@ import pres.auxiliary.work.selenium.element.Element.ElementType;
* @version Ver1.0 * @version Ver1.0
* @since JDK 12 * @since JDK 12
*/ */
public class DataListElement extends AbstractElement { public class DataListElement extends ListElement {
/**
* 用于存储获取到的列表一列元素key为列表名称value为列表元素
*/
private LinkedHashMap<ElementInformation, List<Element>> elementMap = new LinkedHashMap<>(16);
/**
* 用于存储元素列累计的个数
*/
private HashMap<String, Integer> elementSizeMap = new HashMap<String, Integer>(16);
/**
* 用于存储是否开始累加列表元素的个数
*/
// private boolean isStartAddSize = false;
/**
* 用于判断列表的第一行元素是否为标题元素
*/
private boolean isFristRowTitle = false;
/** /**
* 存储获取到的元素列表中最多元素列的元素个数 * 存储获取到的元素列表中最多元素列的元素个数
*/ */
@ -68,6 +44,21 @@ public class DataListElement extends AbstractElement {
*/ */
private ArrayList<String> minColumnNameList = new ArrayList<>(); private ArrayList<String> minColumnNameList = new ArrayList<>();
/**
* 用于判断列表的第一行元素是否为标题元素
*/
boolean isFristRowTitle = false;
/**
* 用于存储元素列累计的个数
*/
// private HashMap<String, Integer> elementSizeMap = new HashMap<String, Integer>(16);
/**
* 用于存储是否开始累加列表元素的个数
*/
// private boolean isStartAddSize = false;
/** /**
* 通过浏览器对象{@link AbstractBrower}进行构造 * 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象 * @param brower {@link AbstractBrower}对象
@ -135,75 +126,16 @@ public class DataListElement extends AbstractElement {
return minColumnNameList; return minColumnNameList;
} }
/** @Override
* 返回列表名称对应的元素个数若该列未被获取则返回-1
* @param name 被获取的列名称
* @return 列名对应列的元素个数
*/
public int getColumnSize(String name) {
ElementInformation element = nameToElementInformation(name);
if (element != null) {
return elementMap.get(element).size();
} else {
return -1;
}
}
/**
* 该方法用于返回所有列的名称
* @return 所有列的名称
*/
public ArrayList<String> getColumnName() {
ArrayList<String> nameList = new ArrayList<>();
elementMap.forEach((key, value) -> {
nameList.add(key.name);
});
return nameList;
}
/**
* 用于根据传入的元素在xml文件中的名称或者元素的定位内容添加元素列由于该方法不指定元素的定位
* 方式若传入的参数不是xml元素且非xpath路径或绝对css路径时其识别效率较慢建议在该情况下
* 调用{@link #add(String, ByType)}方法指定元素定位方法
* @param name 元素在xml文件或者元素的定位内容
// * @param isAddSize 是否对元素个数进行统计
* @see #add(String, ByType)
* @throws TimeoutException 元素在指定时间内无法找到时抛出的异常
*/
public void add(String name) {
add(name, null);
}
/**
* 用于根据传入的元素在xml文件中的名称或者元素的定位内容以及元素的定位方式添加元素列
* @param name 元素在xml文件或者元素的定位内容
* @param byType 元素定位方式枚举对象{@link ByType}枚举
// * @param isAddSize 是否对元素个数进行统计
* @see #add(String)
* @throws TimeoutException 元素在指定时间内无法找到时抛出的异常
*/
public void add(String name, ByType byType) { public void add(String name, ByType byType) {
add(new ElementInformation(name, byType)); add(new ElementInformation(name, byType, ElementType.DATA_LIST_ELEMENT));
} }
/** @Override
* 添加元素的底层方法 void add(ElementInformation elementInformation) {
* @param elementInformation 元素信息类对象 //重写父类的add方法使元素能进行极值的统计
* @param isAddSize 是否需要统计 super.add(elementInformation);
*/
private void add(ElementInformation elementInformation) {
List<Element> elementList = new ArrayList<Element>();
//获取元素
By by = recognitionElement(elementInformation);
int size = driver.findElements(by).size();
//构造Element对象
for (int i = 0; i < size; i++) {
elementList.add(new Element(driver, ElementType.DATA_LIST_ELEMENT, by, i));
}
//elementList = driver.findElements(recognitionElement(elementInformation));
//添加元素
elementMap.put(elementInformation, elementList);
//判断当前获取到的元素是否大于当前存储的元素的最大值或小于当前存储的最小值若是则将最大值或最小值进行替换 //判断当前获取到的元素是否大于当前存储的元素的最大值或小于当前存储的最小值若是则将最大值或最小值进行替换
findLimitColumn(elementInformation); findLimitColumn(elementInformation);
@ -226,95 +158,6 @@ public class DataListElement extends AbstractElement {
*/ */
} }
/**
* 用于清除或移除指定的列及列中的元素当参数传入false时则只清理列表中存储的元素不移除
* 整个列若传入true时则直接移除整个列若列名称对应的列未被获取则返回null
* @param name 已被获取的元素列名称
* @param isRemove 是否需要将该列移除
* @return 被移除列中存储的所有元素
*/
public List<Element> clearColumn(String name, boolean isRemove) {
ElementInformation element = nameToElementInformation(name);
//若元素不存在则直接返回null
if (element == null) {
return null;
}
//用于存储被移除的元素
List<Element> elementList = elementMap.get(element);
//判断元素是否需要被完全移除
if (isRemove) {
//若元素需要被完全移除则直接移除元素
elementMap.remove(element);
//由于元素被移除若该列存在元素个数统计则同样将该元素移除
if (elementSizeMap.containsKey(name)) {
elementSizeMap.remove(name);
}
} else {
//若元素无需移除则将元素存储的列表内容清空
elementMap.get(element).clear();
}
return elementList;
}
/**
* 该方法用于根据存入的元素名称或定位方式对元素进行重新获取的操作主要用于当列表数据翻页后
* 其原存入的数据将会失效必须重新获取注意调用该方法后会清空原存储的数据
*/
public void againGetElement() {
// 读取elements中的元素
elementMap.forEach((key, value) -> {
// 清空元素中的内容
clearColumn(key.name, false);
// 对页面内容重新进行获取
add(key);
});
}
/**
* 该方法用于根据列名称查找到相应的列并返回与传入下标对应的元素下标支持从后向前获取传入的下标
* 与元素实际所在位置一致当传入0时则表示随机获取一个元素<br>
* {@code getWebElement("姓名", 1)}表示获取名称为姓名的列中的第1个元素<br>
* {@code getWebElement("姓名", 0)}表示获取名称为姓名的列中在长度范围内随机一个元素<br>
* {@code getWebElement("//*[@id='name']", -1)}表示获取//*[@id='name']对应列中的倒数第1个元素<br>
*
* @param name 列名称
* @param index 元素下标即列表中对应的某一个元素
* @return 对应列指定的元素
* @throws NoSuchElementException 当未对name列进行获取数据或index的绝对值大于列表最大值时抛出的异常
*/
public Element getWebElement(String name, int index) {
//获取元素信息并判断元素是否存在不存在则抛出异常
ElementInformation element = nameToElementInformation(name);
if (element == null) {
throw new NoSuchElementException("不存在的定位方式:" + name);
}
// 转义下标
index = getIndex(element, index);
// 转义下标后返回对应的元素
return elementMap.get(element).get(index);
}
/**
* 该方法用于根据列名称获取该列下所有的元素
*
* @param name 列名称
* @return 对应列元素
* @throws NoSuchElementException 当未对name列进行获取数据时抛出的异常
*/
public List<Element> getAllWebElement(String name) {
//获取元素信息并判断元素是否存在不存在则抛出异常
ElementInformation element = nameToElementInformation(name);
if (element == null) {
throw new NoSuchElementException("不存在的定位方式:" + name);
}
return elementMap.get(element);
}
/** /**
* 用于返回列表多个指定的元素传入的下标可参见{@link #getWebElement(String, int)} * 用于返回列表多个指定的元素传入的下标可参见{@link #getWebElement(String, int)}
* *
@ -324,13 +167,13 @@ public class DataListElement extends AbstractElement {
* @throws NoSuchElementException 当未对name列进行获取数据或index的绝对值大于列表最大值时抛出的异常 * @throws NoSuchElementException 当未对name列进行获取数据或index的绝对值大于列表最大值时抛出的异常
* @see #getWebElement(String, int) * @see #getWebElement(String, int)
*/ */
public List<Element> getWebElements(String name, int... indexs) { public List<Element> getElements(String name, int... indexs) {
// 存储所有获取到的事件 // 存储所有获取到的事件
ArrayList<Element> events = new ArrayList<>(); ArrayList<Element> events = new ArrayList<>();
// 循环解析所有的下标并调用getEvent()方法存储至events // 循环解析所有的下标并调用getEvent()方法存储至events
for (int index : indexs) { for (int index : indexs) {
events.add(getWebElement(name, index)); events.add(getElement(name, index));
} }
return events; return events;
@ -343,7 +186,7 @@ public class DataListElement extends AbstractElement {
* @param length 需要返回列表事件的个数 * @param length 需要返回列表事件的个数
* @return 列表事件组 * @return 列表事件组
*/ */
public List<Element> getRandomWebElements(String name, int length) { public List<Element> getRandomElements(String name, int length) {
//获取元素信息并判断元素是否存在不存在则抛出异常 //获取元素信息并判断元素是否存在不存在则抛出异常
ElementInformation element = nameToElementInformation(name); ElementInformation element = nameToElementInformation(name);
if (element == null) { if (element == null) {
@ -352,7 +195,7 @@ public class DataListElement extends AbstractElement {
// 判断传入的长度是否大于等于当前 // 判断传入的长度是否大于等于当前
if (length >= elementMap.get(element).size()) { if (length >= elementMap.get(element).size()) {
return getAllWebElement(name); return getAllElement(name);
} }
// 存储通过随机得到的数字 // 存储通过随机得到的数字
@ -373,7 +216,7 @@ public class DataListElement extends AbstractElement {
indexs[i] = indexsList.get(i); indexs[i] = indexsList.get(i);
} }
return getWebElements(name, indexs); return getElements(name, indexs);
} }
/* /*
@ -409,49 +252,6 @@ public class DataListElement extends AbstractElement {
} }
} }
/**
* 由于方法允许传入负数和特殊数字0为下标并且下标的序号由1开始
* 故可通过该方法对下标的含义进行转义得到java能识别的下标
* @param element 元素信息类对象
* @param index 传入的下标
* @return 可识别的下标
* @throws NoSuchElementException 当元素无法查找到时抛出的异常
*/
int getIndex(ElementInformation element, int index) {
int length = elementMap.get(element).size();
//判断元素下标是否超出范围由于可以传入负数故需要使用绝对值
if (Math.abs(index) >= length) {
throw new NoSuchElementException("指定的选项值大于选项的最大值。选项总个数:" + length + ",指定项:" + index);
}
//判断index的值若大于0则从前向后遍历若小于0则从后往前遍历若等于0则随机输入
if (index > 0) {
//选择元素正数的选项值从1开始故需要减小1
return index - 1;
} else if (index < 0) {
//选择元素由于index为负数则长度加上选项值即可得到需要选择的选项
return length + index;
} else {
//为0则随机进行选择
return new Random().nextInt(length);
}
}
/**
* 根据元素名称反推元素信息类对象用于根据列名称查找数据以及判断列是否存在若列名不存在则返回null
* @return ElementInformation对象
*/
ElementInformation nameToElementInformation(String name) {
//遍历elementMap若查找与name一致的名称则结束循环并返回相应的ElementInformation对象
for (ElementInformation element : elementMap.keySet()) {
if (element.name.equals(name)) {
return element;
}
}
return null;
}
@Override @Override
boolean isExistElement(By by, long waitTime) { boolean isExistElement(By by, long waitTime) {
//TODO 修改等待方法改为获取到元素后才返回相应的状态 //TODO 修改等待方法改为获取到元素后才返回相应的状态

View File

@ -52,9 +52,6 @@ public class Element {
this.index = index; this.index = index;
this.driver = driver; this.driver = driver;
this.elementType = elementType; this.elementType = elementType;
//对元素进行一次查找
findElement();
} }
/** /**
@ -71,6 +68,12 @@ public class Element {
* @return 返回元素对应的WebElement对象 * @return 返回元素对应的WebElement对象
*/ */
public WebElement getWebElement() { public WebElement getWebElement() {
//若元素未进行查找则查找一次元素
if(element == null) {
//对元素进行一次查找
findElement();
}
return element; return element;
} }
@ -90,36 +93,4 @@ public class Element {
throw new IllegalArgumentException("Unexpected value: " + elementType); throw new IllegalArgumentException("Unexpected value: " + elementType);
} }
} }
/**
* <p><b>文件名</b>Element.java</p>
* <p><b>用途</b>
* 用于标记当前传入的元素是以何种方式进行获取
* </p>
* <p><b>编码时间</b>2020年5月20日上午7:43:38</p>
* <p><b>修改时间</b>2020年5月20日上午7:43:38</p>
* @author
* @version Ver1.0
* @since JDK 12
*
*/
public enum ElementType {
/**
* 指向普通类型元素
*/
COMMON_ELEMENT,
/**
* 指向数据列表类型元素
*/
DATA_LIST_ELEMENT,
/**
* 指向标准下拉框选择类型元素
*/
SELECT_OPTION_ELEMENT,
/**
* 指向列表型下拉框选择类型元素
*/
SELECT_DATAS_ELEMENT;
}
} }

View File

@ -0,0 +1,32 @@
package pres.auxiliary.work.selenium.element;
/**
* <p><b>文件名</b>EelementType.java</p>
* <p><b>用途</b>
* 用于标记当前传入的元素是以何种方式进行获取
* </p>
* <p><b>编码时间</b>2020年5月22日上午7:57:32</p>
* <p><b>修改时间</b>2020年5月22日上午7:57:32</p>
* @author
* @version Ver1.0
* @since JDK 12
*
*/
public enum ElementType {
/**
* 指向普通类型元素
*/
COMMON_ELEMENT,
/**
* 指向数据列表类型元素
*/
DATA_LIST_ELEMENT,
/**
* 指向标准下拉框选择类型元素
*/
SELECT_OPTION_ELEMENT,
/**
* 指向列表型下拉框选择类型元素
*/
SELECT_DATAS_ELEMENT;
}

View File

@ -0,0 +1,192 @@
package pres.auxiliary.work.selenium.element;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
/**
* <p><b>文件名</b>ListElement.java</p>
* <p><b>用途</b>
* 提供获取列表类型元素时的基本方法
* </p>
* <p><b>编码时间</b>2020年5月22日上午7:54:55</p>
* <p><b>修改时间</b>2020年5月22日上午7:54:55</p>
* @author 彭宇琦
* @version Ver1.0
* @since JDK 12
*
*/
public abstract class ListElement extends MultiElement {
/**
* 用于存储获取到的列表一列元素key为列表名称value为列表元素
*/
LinkedHashMap<ElementInformation, List<Element>> elementMap = new LinkedHashMap<>(16);
/**
* 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象
*/
public ListElement(AbstractBrower brower) {
super(brower);
}
/**
* 构造对象并存储浏览器的{@link WebDriver}对象
*
* @param driver 浏览器的{@link WebDriver}对象
*/
public ListElement(WebDriver driver) {
super(driver);
}
/**
* 返回列表名称对应的元素个数若该列未被获取则返回-1
* @param name 被获取的列名称
* @return 列名对应列的元素个数
*/
public int getSize(String name) {
ElementInformation element = nameToElementInformation(name);
if (element != null) {
return elementMap.get(element).size();
} else {
return -1;
}
}
/**
* 该方法用于返回所有列的名称
* @return 所有列的名称
*/
public ArrayList<String> getNames() {
ArrayList<String> nameList = new ArrayList<>();
elementMap.forEach((key, value) -> {
nameList.add(key.name);
});
return nameList;
}
@Override
void add(ElementInformation elementInformation) {
List<Element> elementList = new ArrayList<Element>();
//获取元素
By by = recognitionElement(elementInformation);
int size = driver.findElements(by).size();
//构造Element对象
for (int i = 0; i < size; i++) {
elementList.add(new Element(driver, ElementType.DATA_LIST_ELEMENT, by, i));
}
//elementList = driver.findElements(recognitionElement(elementInformation));
//添加元素
elementMap.put(elementInformation, elementList);
}
/**
* 用于清除或移除指定的列及列中的元素当参数传入false时则只清理列表中存储的元素不移除
* 整个列若传入true时则直接移除整个列若列名称对应的列未被获取则返回null
* @param name 已被获取的元素列名称
* @param isRemove 是否需要将该列移除
* @return 被移除列中存储的所有元素
*/
public List<Element> clearColumn(String name, boolean isRemove) {
ElementInformation element = nameToElementInformation(name);
//若元素不存在则直接返回null
if (element == null) {
return null;
}
//用于存储被移除的元素
List<Element> elementList = elementMap.get(element);
//判断元素是否需要被完全移除
if (isRemove) {
//若元素需要被完全移除则直接移除元素
elementMap.remove(element);
//由于元素被移除若该列存在元素个数统计则同样将该元素移除
/*
if (elementSizeMap.containsKey(name)) {
elementSizeMap.remove(name);
}
*/
} else {
//若元素无需移除则将元素存储的列表内容清空
elementMap.get(element).clear();
}
return elementList;
}
@Override
public void againGetElement() {
// 读取elements中的元素
elementMap.forEach((key, value) -> {
// 清空元素中的内容
clearColumn(key.name, false);
// 对页面内容重新进行获取
add(key);
});
}
/**
* 根据元素名称反推元素信息类对象用于根据列名称查找数据以及判断列是否存在若列名不存在则返回null
* @return ElementInformation对象
*/
ElementInformation nameToElementInformation(String name) {
//遍历elementMap若查找与name一致的名称则结束循环并返回相应的ElementInformation对象
for (ElementInformation element : elementMap.keySet()) {
if (element.name.equals(name)) {
return element;
}
}
return null;
}
/**
* 该方法用于根据列名称查找到相应的列并返回与传入下标对应的元素下标支持从后向前获取传入的下标
* 与元素实际所在位置一致当传入0时则表示随机获取一个元素<br>
* {@code getWebElement("姓名", 1)}表示获取名称为姓名的列中的第1个元素<br>
* {@code getWebElement("姓名", 0)}表示获取名称为姓名的列中在长度范围内随机一个元素<br>
* {@code getWebElement("//*[@id='name']", -1)}表示获取//*[@id='name']对应列中的倒数第1个元素<br>
*
* @param name 列名称
* @param index 元素下标即列表中对应的某一个元素
* @return 对应列指定的元素
* @throws NoSuchElementException 当未对name列进行获取数据或index的绝对值大于列表最大值时抛出的异常
*/
public Element getElement(String name, int index) {
//获取元素信息并判断元素是否存在不存在则抛出异常
ElementInformation element = nameToElementInformation(name);
if (element == null) {
throw new NoSuchElementException("不存在的定位方式:" + name);
}
// 转义下标
index = getIndex(elementMap.get(element).size(), index);
// 转义下标后返回对应的元素
return elementMap.get(element).get(index);
}
/**
* 该方法用于根据列名称获取该列下所有的元素
*
* @param name 列名称
* @return 对应列元素
* @throws NoSuchElementException 当未对name列进行获取数据时抛出的异常
*/
public List<Element> getAllElement(String name) {
//获取元素信息并判断元素是否存在不存在则抛出异常
ElementInformation element = nameToElementInformation(name);
if (element == null) {
throw new NoSuchElementException("不存在的定位方式:" + name);
}
return elementMap.get(element);
}
}

View File

@ -0,0 +1,111 @@
package pres.auxiliary.work.selenium.element;
import java.util.Random;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import pres.auxiliary.selenium.xml.ByType;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
/**
* <p><b>文件名</b>MultiElement.java</p>
* <p><b>用途</b>
* 提供获取多个元素时使用的基本方法
* </p>
* <p><b>编码时间</b>2020年5月22日上午7:54:28</p>
* <p><b>修改时间</b>2020年5月22日上午7:54:28</p>
* @author 彭宇琦
* @version Ver1.0
* @since JDK 12
*
*/
public abstract class MultiElement extends AbstractElement {
/**
* 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象
*/
public MultiElement(AbstractBrower brower) {
super(brower);
}
/**
* 构造对象并存储浏览器的{@link WebDriver}对象
*
* @param driver 浏览器的{@link WebDriver}对象
*/
public MultiElement(WebDriver driver) {
super(driver);
}
/**
* 用于根据传入的元素在xml文件中的名称或者元素的定位内容添加元素由于该方法不指定元素的定位
* 方式若传入的参数不是xml元素且非xpath路径或绝对css路径时其识别效率较慢建议在该情况下
* 调用{@link #add(String, ByType)}方法指定元素定位方法
* @param name 元素在xml文件或者元素的定位内容
* @see #add(String, ByType)
* @throws TimeoutException 元素在指定时间内无法找到时抛出的异常
*/
public void add(String name) {
add(name, null);
}
/**
* 用于根据传入的元素在xml文件中的名称或者元素的定位内容以及元素的定位方式添加元素
* @param name 元素在xml文件或者元素的定位内容
* @param byType 元素定位方式枚举对象{@link ByType}枚举
* @see #add(String)
* @throws TimeoutException 元素在指定时间内无法找到时抛出的异常
*/
public abstract void add(String name, ByType byType);
/**
* 添加元素的底层方法
* @param elementInformation 元素信息类对象
* @param isAddSize 是否需要统计
*/
abstract void add(ElementInformation elementInformation);
/**
* 该方法用于根据存入的元素名称或定位方式对元素进行重新获取的操作主要用于当列表数据翻页后
* 其原存入的数据将会失效必须重新获取注意调用该方法后会清空原存储的数据
*/
public abstract void againGetElement();
/**
* 用于清除或移除指定的列及列中的元素当参数传入false时则只清理列表中存储的元素不移除
* 整个列若传入true时则直接移除整个列若列名称对应的列未被获取则返回null
* @param name 已被获取的元素列名称
* @param isRemove 是否需要将该列移除
* @return 被移除列中存储的所有元素
*/
// public abstract List<Element> clearColumn(String name, boolean isRemove);
/**
* 由于方法允许传入负数和特殊数字0为下标并且下标的序号由1开始
* 故可通过该方法对下标的含义进行转义得到java能识别的下标
* @param length 元素的个数
* @param index 传入的下标
* @return 可识别的下标
* @throws NoSuchElementException 当元素无法查找到时抛出的异常
*/
int getIndex(int length, int index) {
//判断元素下标是否超出范围由于可以传入负数故需要使用绝对值
if (Math.abs(index) > length) {
throw new NoSuchElementException("指定的选项值大于选项的最大值。选项总个数:" + length + ",指定项:" + index);
}
//判断index的值若大于0则从前向后遍历若小于0则从后往前遍历若等于0则随机输入
if (index > 0) {
//选择元素正数的选项值从1开始故需要减小1
return index - 1;
} else if (index < 0) {
//选择元素由于index为负数则长度加上选项值即可得到需要选择的选项
return length + index;
} else {
//为0则随机进行选择
return new Random().nextInt(length);
}
}
}

View File

@ -0,0 +1,131 @@
package pres.auxiliary.work.selenium.element;
import java.util.ArrayList;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.selenium.xml.ByType;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
public class SelectElement extends MultiElement {
/**
* 用于存储获取下拉选项时的信息
*/
ElementInformation elementInfo;
/**
* 用于存储下拉选项的元素
*/
ArrayList<Element> option = new ArrayList<>();
/**
* 用于存储下拉选项的文本
*/
ArrayList<String> optionText = new ArrayList<>();
/**
* 设置获取的下拉选项的类型0表示标准的select-option型1表示非标准的下拉选项型
*/
private ElementType elementType;
/**
* 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象
*/
public SelectElement(AbstractBrower brower) {
super(brower);
}
/**
* 构造对象并存储浏览器的{@link WebDriver}对象
*
* @param driver 浏览器的{@link WebDriver}对象
*/
public SelectElement(WebDriver driver) {
super(driver);
}
@Override
public void add(String name, ByType byType) {
add(new ElementInformation(name, byType));
}
@Override
void add(ElementInformation elementInformation) {
//获取元素的By对象
By by = recognitionElement(elementInformation);
//根据By获取元素
List<WebElement> elementList = driver.findElements(by);
//获取元素个数
int size = elementList.size();
//根据获取到的元素个数来判断下拉选项的类型
if (size == 1) {
elementInformation.elementType = ElementType.SELECT_OPTION_ELEMENT;
//若是标准下拉选项型则需要改变size的值方便后续添加数据
Select select = new Select(driver.findElement(by));
//获取所有的选项内容并计算元素个数
elementList = select.getOptions();
size = elementList.size();
} else {
elementInformation.elementType = ElementType.SELECT_DATAS_ELEMENT;
}
//构造Element对象
for (int i = 0; i < size; i++) {
//获取元素
option.add(new Element(driver, elementType, by, i));
//获取元素的文本内容
optionText.add(elementList.get(0).getText());
}
}
/**
* 根据选项下标返回相应的选项元素下标与选项元素真实下标一致支持传入负数表示从后向前遍历元素
* 当传入0时表示随机选择一个选项
* @param index 选项下标
* @return 相应的选项元素
*/
public Element getElement(int index) {
return option.get(getIndex(option.size(), index));
}
/**
* 根据选项内容返回相应的选项元素当传入的元素名称不存在时则返回null当存在重复的选项
* 名称时则选择第一个选项
*
* @param elementName 选项名称
* @return 相应的选项元素
*/
public Element getElement(String elementName) {
//根据名称获取元素下标
int index = optionText.indexOf(elementName);
//判断下标是否为-1元素是否存在若不存在则返回null
if (index == -1) {
return null;
}
return option.get(optionText.indexOf(elementName));
}
@Override
public void againGetElement() {
option.clear();
optionText.clear();
add(elementInfo);
}
@Override
boolean isExistElement(By by, long waitTime) {
//当查找到元素时则返回true若查不到元素则会抛出异常故返回false
return new WebDriverWait(driver, waitTime, 200).
until((driver) -> {
WebElement element = driver.findElement(by);
return element != null;
});
}
}

View File

@ -29,7 +29,7 @@ public abstract class AbstractEvent {
/** /**
* 设置显示等待的超时时间默认3秒 * 设置显示等待的超时时间默认3秒
*/ */
long waitTime = 3; long waitTime = 5;
/** /**
* 用于在记录步骤时需要替换的元素名称文本 * 用于在记录步骤时需要替换的元素名称文本

View File

@ -14,10 +14,10 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import pres.auxiliary.work.selenium.element.Element; import pres.auxiliary.work.selenium.element.Element;
import pres.auxiliary.work.selenium.element.Element.ElementType; import pres.auxiliary.work.selenium.element.ElementType;
/** /**
* <p> * <p>
* <b>文件名</b>JsEvent.java * <b>文件名</b>JsEvent.java
* </p> * </p>
* <p> * <p>

View File

@ -88,7 +88,7 @@ public class SelectEvent extends AbstractEvent {
*/ */
private int getIndex(int length, int index) { private int getIndex(int length, int index) {
//判断元素下标是否超出范围由于可以传入负数故需要使用绝对值 //判断元素下标是否超出范围由于可以传入负数故需要使用绝对值
if (Math.abs(index) >= length) { if (Math.abs(index) > length) {
throw new NoSuchElementException("指定的选项值大于选项的最大值。选项总个数:" + length + ",指定项:" + index); throw new NoSuchElementException("指定的选项值大于选项的最大值。选项总个数:" + length + ",指定项:" + index);
} }