diff --git a/src/main/java/pres/auxiliary/work/selenium/element/AbstractElement.java b/src/main/java/pres/auxiliary/work/selenium/element/AbstractElement.java
new file mode 100644
index 0000000..44d3f53
--- /dev/null
+++ b/src/main/java/pres/auxiliary/work/selenium/element/AbstractElement.java
@@ -0,0 +1,775 @@
+package pres.auxiliary.work.selenium.element;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.TimeoutException;
+import org.openqa.selenium.WebDriver;
+
+import pres.auxiliary.work.selenium.brower.AbstractBrower;
+import pres.auxiliary.work.selenium.brower.Page;
+import pres.auxiliary.work.selenium.xml.ByType;
+import pres.auxiliary.work.selenium.xml.ReadXml;
+
+/**
+ *
文件名:AbstractElement.java
+ * 用途:
+ * 对辅助化测试工具selenium的获取元素代码进行的二次封装,通过类中提供的方法以及配合相应存储元素的
+ * xml文件,以更简便的方式对页面元素进行获取,减少编程时的代码量。
+ *
+ * 编码时间:2020年4月25日 下午4:18:37
+ * 修改时间:2020年4月25日 下午4:18:37
+ * @author 彭宇琦
+ * @version Ver1.0
+ * @since JDK 1.8
+ */
+public abstract class AbstractElement {
+ /**
+ * 用于存储浏览器的WebDriver对象
+ */
+ WebDriver driver;
+ /**
+ * 用于存储元素信息,由于
+ */
+ static ElementData elementData;
+
+ /**
+ * 用于存储浏览器对象
+ */
+ static AbstractBrower brower;
+ /**
+ * 存储单个控件的等待时间
+ */
+ private HashMap controlWaitTime = new HashMap();
+ /**
+ * 用于存储当前浏览器窗口的Handles值
+ */
+ private String browserHandles;
+ /**
+ * 存储当前定位的窗体层级,由于多个子类之间需要相互通信,故此处标记为static
+ */
+ private static ArrayList iframeNameList = new ArrayList<>();
+
+ /**
+ * 用于当元素获取失败时执行的方法
+ */
+ ExceptionAction action;
+
+ /**
+ * 用于存储元素通用的等待时间,默认5秒
+ */
+ private long waitTime = 5;
+
+ /**
+ * 控制是否自动切换窗体,由于通过Event类调用时会构造另一个事件类
+ */
+ boolean isAutoSwitchIframe = true;
+
+ /**
+ * 通过元素信息类对象({@link ElementData})构造对象
+ * @param brower {@link AbstractBrower}类对象
+ * @param elementData {@link ElementData}类对象
+ */
+ public AbstractElement(AbstractBrower brower, ElementData elementData) {
+ this.brower = brower;
+ this.driver = brower.getDriver();
+ this.elementData = elementData;
+ }
+
+ public AbstractElement(AbstractBrower brower, String elemenetName) {
+
+ }
+
+ /**
+ * 设置元素查找失败时需要执行的方法
+ * @param action 执行方法
+ */
+ public void setAction(ExceptionAction action) {
+ this.action = action;
+ }
+
+ /**
+ * 用于清除元素查找失败时执行的方法
+ */
+ public void clearAction() {
+ this.action = null;
+ }
+
+ /**
+ * 用于设置元素等待时间,默认时间为5秒
+ *
+ * @param waitTime 元素等待时间
+ */
+ public void setWaitTime(long waitTime) {
+ this.waitTime = waitTime;
+ }
+
+ /**
+ * 用于对符合正则表达式的控件名称设置等待时间
+ *
+ * @param regex 正则表达式
+ * @param waitTime 等待时间
+ */
+ public void setContorlWaitTime(String regex, long waitTime) {
+ controlWaitTime.put(regex, waitTime);
+ }
+
+ /**
+ * 设置是否自动切换窗体
+ * @param switchIframe 是否自动切换窗体
+ */
+ public void setAutoSwitchIframe(boolean isAutoSwitchIframe) {
+ this.isAutoSwitchIframe = isAutoSwitchIframe;
+ }
+
+ /**
+ * 该方法用于返回浏览器的WebDriver对象
+ *
+ * @return 浏览器的WebDriver对象
+ */
+ public WebDriver getDriver() {
+ return driver;
+ }
+
+
+
+ /**
+ * 用于设置指向存储元素定位方式的xml文件对象,并根据传参,判断窗体是否需要回到顶层
+ * @param xmlFile 存储元素定位方式的xml文件对象
+ * @param isBreakRootFrame 是否需要将窗体切回到顶层
+ */
+ public void setXmlFile(File xmlFile, boolean isBreakRootFrame) {
+ if (xml == null) {
+ xml = new ReadXml(xmlFile);
+ } else {
+ xml.setXmlPath(xmlFile);
+ }
+
+ if (isBreakRootFrame) {
+ switchRootFrame();
+ }
+ }
+
+ /**
+ * 该方法用于将窗体切回顶层,当本身是在最顶层时,则该方法将使用无效
+ */
+ public void switchRootFrame() {
+ //切换窗口至顶层
+ driver.switchTo().defaultContent();
+ //清空iframeNameList中的内容
+ iframeNameList.clear();
+ }
+
+ /**
+ * 该方法用于将窗体切换到上一层(父层)。若当前层只有一层,则调用方法后切回顶层;
+ * 若当前层为最顶层时,则该方法将使用无效
+ */
+ public void switchParentFrame() {
+ //若iframeNameList大于1层,则向上切换窗体
+ if (iframeNameList.size() > 1) {
+ driver.switchTo().parentFrame();
+ iframeNameList.remove(iframeNameList.size() - 1);
+ } else if (iframeNameList.size() == 1) {
+ //若iframeNameList等于1层,则调用切换至顶层的方法
+ switchRootFrame();
+ } else {
+ //若iframeNameList小于1层,则不做操作
+ return;
+ }
+ }
+
+ /**
+ *
+ * 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件
+ * 名称对应的定位方式,或直接传入xpath与css定位方式,
+ * 根据定位方式对相应的窗体进行定位。当传入的窗体为当前窗体的前层(父层)窗体时,
+ * 通过该方法将调用切换父层的方法,将窗体切换到父层上,例如:
+ * 当前存在f1, f2, f3, f4四层窗体,则调用方法:
{@code
+ * switchFrame("f2");
+ * }
+ * 此时窗体将回到f2层,无需再从顶层开始向下切换。
+ *
+ *
+ * 若传入该方法的名称存在于xml文件中,且该元素存在父窗体时,调用
+ * 该方法会从xml文件中获取相应所有父窗体,并对相应的父窗体进行切换,
+ * 从而达到无须切换父窗体的目的,例如,存在以下xml文件片段:
{@code
+ * ...
+ *
+ * ...
+ * }
+ * 当调用该方法:
{@code
+ * switchFrame("f3");
+ * }
+ * 时,则会先将窗体从f1开始切换,至窗体f2,最后再切换为窗体f3
+ *
+ *
+ * @param name 窗体的名称或xpath与css定位方式
+ */
+ public void switchFrame(String name) {
+ switchFrame(new ElementInformation(name, null, ElementType.COMMON_ELEMENT));
+ }
+
+ /**
+ * 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件
+ * 名称对应的定位方式,或直接传入xpath与css定位方式,
+ * 根据定位方式对相应的窗体进行定位。通过该方法可以指定使用的定位类型,一般用于
+ * 传入非xml文件的元素,也可用于指定xml文件元素的定位方式,其他说明参见{@link #switchFrame(String)}
+ * @param name 窗体的名称或xpath与css定位方式
+ * @param byType 元素的定位方式
+ * @see #switchFrame(String)
+ */
+ public void switchFrame(String name, ByType byType) {
+ switchFrame(new ElementInformation(name, byType, ElementType.COMMON_ELEMENT));
+ }
+
+ /**
+ * 切换窗体的底层方法
+ * @param elementInformation 元素信息类对象
+ */
+ private void switchFrame(ElementInformation elementInformation) {
+ List nameList = new ArrayList();
+ //判断传入的元素名称是否存在于xml文件中,若存在,则将该元素的父层名称存储至nameList
+ if (isXmlElement(elementInformation.name) && isAutoSwitchIframe) {
+ nameList.addAll(getParentFrameName(elementInformation.name));
+ }
+
+ //调用切换窗体的方法
+ switchFrame(nameList);
+
+ driver.switchTo().frame(driver.findElement(recognitionElement(elementInformation)));
+ //切换窗体
+ iframeNameList.add(elementInformation.name);
+ }
+
+ /**
+ * 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件
+ * 名称对应的定位方式,或直接传入xpath与css定位方式,
+ * 根据定位方式对相应的窗体进行定位。当传入的窗体为当前窗体的前层(父层)窗体时,
+ * 通过该方法将调用切换父层的方法,将窗体切换到父层上,例如:
+ * 当前存在f1, f2, f3, f4四层窗体,则调用方法:{@code
+ * List nameList = new ArrayList();
+ * nameList.add("f2");
+ * switchFrame(nameList);
+ * }
+ * 此时窗体将回到f2层,无需再从顶层开始向下切换。
+ * 注意:
+ *
+ * - 窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
+ * - 传入的参数若在xml文件中且存在父窗体,调用该方法也不会对窗体进行切换
+ *
+ *
+ * @param elementInformationList 存储窗体的名称或xpath与css定位方式的List集合
+ */
+ void switchFrame(List frameNameList) {
+ //若传参为空,则切回到顶层
+ if (frameNameList.isEmpty()) {
+ switchRootFrame();
+ return;
+ }
+
+ //若原窗体和需要切换的窗体的最后一个元素一致,则无需切换
+ if (!iframeNameList.isEmpty() && frameNameList.get(frameNameList.size() - 1).equals(iframeNameList.get(iframeNameList.size() - 1))) {
+ return;
+ }
+
+ //若需要切换的窗体第一层均不在iframeNameList时,则需要切回到顶层
+ if (!iframeNameList.contains(frameNameList.get(0))) {
+ switchRootFrame();
+ }
+
+ //若不为空,则列表进行切换
+ frameNameList.forEach(frameName -> {
+ //判断name指向的窗体是否在iframeNameList中,若存在,则向上切换父层,直到切换到name指向的窗体;若不存在,则直接切换,并添加窗体名称
+ if (iframeNameList.contains(frameName)) {
+ //获取name窗体在iframeNameList中的位置
+ int index = iframeNameList.indexOf(frameName);
+ //获取需要向上切换窗体的次数,公式为推断出来
+ int count = iframeNameList.size() - index - 1;
+ for (int i = 0; i < count; i++) {
+ switchParentFrame();
+ }
+ } else {
+ //切换窗体
+ driver.switchTo().frame(driver.findElement(recognitionElement(new ElementInformation(frameName, null, ElementType.COMMON_ELEMENT))));
+ iframeNameList.add(frameName);
+ }
+ });
+ }
+
+ /**
+ * 该方法用于将窗口切换回最原始的窗口上。
+ */
+ public void switchOldWindow() {
+ driver.switchTo().window(browserHandles);
+ }
+
+ /**
+ * 该方法可根据控件名称,之后对比每一个弹窗,若某一个弹窗上存在元素名对应的元素,则返回相应
+ * 窗口的WebDriver对象,若无新窗口,则返回当前的窗口的WebDriver对象。当所有的窗体都
+ * 不包含相应的元素时,则抛出NoSuchWindownException异常
+ *
+ * @param controlName 控件名称
+ * @throws NoSuchWindownException 窗口未找到时抛出的异常
+ */
+ public void switchWindow(String controlName) {
+ Set handles = driver.getWindowHandles();
+ // 判断是否只存在一个窗体,若只存在一个,则直接返回当前浏览器的WebDriver对象
+ if (handles.size() == 1) {
+ return;
+ }
+
+ List 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);
+ try {
+ //构造信息,因为在构造过程中会判断元素是否存在,
+ recognitionElement(new ElementInformation(controlName, null, ElementType.COMMON_ELEMENT));
+ return;
+ }catch (Exception e) {
+ continue;
+ }
+ }
+
+ //若不在新打开的窗口上,则遍历已打开的窗口
+ if (brower != null) {
+ for (Page page : pageList) {
+ //切换窗口,并查找元素是否在窗口上,若存在,则结束切换
+ brower.switchWindow(page);
+ try {
+ recognitionElement(new ElementInformation(controlName, null, ElementType.COMMON_ELEMENT));
+ return;
+ }catch (Exception e) {
+ continue;
+ }
+ }
+ }
+
+ //若遍历所有窗口后均未能查到元素,则抛出异常
+ throw new NoSuchWindownException("未找到存在元素" + controlName + "所在的窗体");
+ }
+
+ /**
+ * 定位到弹框上并且点击确定按钮,并返回弹框上的文本
+ *
+ * @return 弹框上的文本
+ */
+ public String alertAccept() {
+ String text = alertGetText();
+ driver.switchTo().alert().accept();
+
+ return text;
+
+ }
+
+ /**
+ * 定位到弹框上并且点击取消按钮,并返回弹框上的文本
+ *
+ * @return 弹框上的文本
+ */
+ public String alertDimiss() {
+ String text = alertGetText();
+ driver.switchTo().alert().dismiss();
+
+ return text;
+ }
+
+ /**
+ * 定位到弹框上并且在其文本框中输入信息
+ *
+ * @param content 需要输入的信息
+ * @return 弹框上的文本
+ */
+ public String alertInput(String content) {
+ String text = alertGetText();
+ driver.switchTo().alert().sendKeys("");
+
+ return text;
+ }
+
+ /**
+ * 获取弹框上的文本
+ *
+ * @return 弹框上的文本
+ */
+ public String alertGetText() {
+ return driver.switchTo().alert().getText();
+ }
+
+ /**
+ *
+ * 用于根据传入的控件名称或定位方式,对控件在页面上定位,返回其WebElement对象。形参可以传入在xml文件中元素的名称,
+ * 亦可以传入页面元素的定位方式,但目前识别只支持xpath和css两种方式。
+ * 该方法获取的是一组元素,可用于对列表元素事件中。
+ *
+ *
+ * 元素识别判断方式按照以下步骤进行:
+ * 1.先对xml文件进行扫描,若存在该元素对应的标签,则读取xml文件的定位方式,并识别有效的定位方式一一匹配,直到正确为止;
+ * 2.若在xml文件中查找不到该元素,则按照xpath和css的规则进行匹配,直到判断出该元素的定位方式位置;
+ * 3.若仍找不到元素,则抛出UnrecognizableLocationModeException
+ *
+ *
+ * @param name 元素名称或元素的定位方式
+ * @return 返回页面一组元素WebElement的对象
+ * @throws TimeoutException 元素在指定时间内未查找到时,抛出的异常
+ * @throws UnrecognizableLocationModeException 元素无法识别时抛出的异常
+ */
+ By recognitionElement(ElementInformation elementInformation) {
+ By by;
+ if (isXmlElement(elementInformation.name)) {
+ //若指定了xml文件,且传入的元素名称存在与xml文件中,则判断元素相应的定位方式及定位内容
+ by = recognitionXmlElement(elementInformation);
+ } else {
+ //若未指定xml文件,或者在xml文件中无法查到相应的元素时,则将name的值赋给value,且根据value判断相应定位方式
+ by = recognitionCommonElement(elementInformation);
+ }
+
+// return driver.findElements(by);
+ return by;
+ }
+
+ /**
+ * 获取普通元素的By对象
+ * @param elementInformation 元素信息类对象
+ * @return 元素信息指向的By对象
+ */
+ private By recognitionCommonElement(ElementInformation elementInformation) {
+ //判断传入的ByType对象是否为null
+ if (elementInformation.byType == null) {
+ return judgeCommonElementBy(elementInformation.name);
+ } else {
+ By by = getBy(elementInformation.name, elementInformation.byType);
+ if (isExistElement(by, getWaitTime(elementInformation.name)))
+ return by;
+ else
+ throw new TimeoutException("普通元素定位方式类型无法识别:" + by);
+ }
+ }
+
+ /**
+ * 获取xml文件内元素的By对象
+ * @param elementInformation 元素信息类对象
+ * @return 元素信息指向的By对象
+ */
+ private By recognitionXmlElement(ElementInformation elementInformation) {
+ //判断传入的ByType对象是否为null
+ if (elementInformation.byType == null) {
+ return judgeXmlElementBy(elementInformation.name, elementInformation.linkKeyList);
+ } else {
+ By by = xml.getBy(elementInformation.name, elementInformation.byType, elementInformation.linkKeyList);
+ if (isExistElement(by, getWaitTime(elementInformation.name)))
+ return by;
+ else
+ throw new TimeoutException("普通元素定位方式类型无法识别:" + by);
+ }
+ }
+
+ /**
+ * 用于返回控件的等待时间,若设置单个控件的等待时间(使用{@link #setContorlWaitTime(String, long)}方法设置),
+ * 则返回设置的控件等待时间;若未设置单个控件的等待时间,则返回设置的通用等待时间(使用{@link #setWaitTime(long)}方法)
+ * ;若未对通用时间进行设置,则返回默认时间({@link #waitTime})
+ * @param name 控件名称
+ * @return 相应控件的等待时间
+ * @see #setContorlWaitTime(String, long)
+ * @see #setWaitTime(long)
+ */
+ long getWaitTime(String name) {
+ for (String regex : controlWaitTime.keySet()) {
+ if (Pattern.compile(regex).matcher(name).matches()) {
+ return controlWaitTime.get(regex);
+ }
+ }
+
+ return waitTime;
+ }
+
+ /**
+ * 用于获取元素在xml文件中所有的父窗体,并以集合的形式返回,存储的顺序为父窗体在前,子窗体在后,若当前元素没有窗体,
+ * 则集合的长度为0
+ * @param name 元素在xml文件中的名称
+ * @return 元素在xml文件中所有的父窗体集合
+ */
+ List getParentFrameName(String name) {
+ //存储获取到的父层窗体名称
+ List nameList = new ArrayList();
+
+ //获取元素所在窗体的名称
+ String iframeName = xml.getIframeName(name);
+ //循环,判断窗体是否存在(方法返回不为空),若存在,则再将父窗体进行存储
+ while(!iframeName.isEmpty()) {
+ //存储窗体
+ nameList.add(iframeName);
+ //再以当前窗体的名称再次获取该窗体的父窗体
+ iframeName = xml.getIframeName(iframeName);
+ }
+
+ //将nameList的内容倒序,保证父窗体在子窗体之前
+ Collections.reverse(nameList);
+
+ return nameList;
+ }
+
+ /**
+ * 用于根据传入的参数,识别非xml文件内的元素定位方式。
+ * 该方法能快速识别xpath定位方式以及绝对css定位方式,若不是以上两种定位方式
+ * 则会遍历所有的定位方式,此时会降低运行速度,建议在不是以上两种定位方式的
+ * 情况下,直接指定元素的定位方式,以提高效率
+ */
+ By judgeCommonElementBy(String value) {
+ // 如果抛出元素名称查找不到的的异常,则对应匹配xpath和绝对css路径两种定位方式
+ // 匹配xpath定位,判定方法,判断text的第一个字符是否是“/”
+ //由于是识别普通元素,非xml元素其value就是元素的名称name, 故获取等待时间时可直接将value传入
+ if (value.indexOf("/") == 0) {
+ //在页面中查找元素,若元素能找到,则结束查找
+ By by = getBy(value, ByType.XPATH);
+ if (isExistElement(by, getWaitTime(value))) {
+ return by;
+ }
+ } else if (value.indexOf("html") == 0) {
+ //在页面中查找元素,若元素能找到,则结束查找
+ By by = getBy(value, ByType.CSS);
+ if (isExistElement(by, getWaitTime(value))) {
+ return by;
+ }
+ }
+
+ //若元素无法识别,则将所有的定位类型(排除xpath类型)与之进行对比,直到在页面上找到元素为止
+ for(ByType type : ByType.values()) {
+ if (type == ByType.XPATH) {
+ continue;
+ }
+
+ By by = getBy(value, type);
+
+ //在页面中查找元素,若元素能找到,则结束查找
+ if (isExistElement(by, getWaitTime(value))) {
+ return by;
+ }
+ }
+
+ //若所有的定位方式均无法查找到元素,则抛出异常
+ throw new TimeoutException("普通元素定位方式类型无法识别:" + value);
+ }
+
+ /**
+ * 用于设置xml文件内的元素的定位方式及定位内容
+ */
+ By judgeXmlElementBy(String name, List linkList) {
+ By by;
+ // 循环,逐个在页面上配对有效的标签对应的定位方式
+ for (ByType mode : xml.getElementMode(name)) {
+ by = getBy(xml.getValue(name, mode, linkList), mode);
+
+ //若元素能被找到,则返回相应的By对象,若未找到,则再次循环
+ if (isExistElement(by, getWaitTime(name))) {
+ return by;
+ } else {
+ continue;
+ }
+ }
+
+ // 若循环结束后仍未能找到该元素,则抛出异常
+ throw new TimeoutException("xml文件内元素“" + name + "”无法查找,请核对xml文件:" + xml.getXmlFile().getName() + "\n文件路径:" + xml.getXmlFile().getAbsolutePath());
+ }
+
+ /**
+ * 根据元素的参数,返回元素的By对象
+ * @return 元素的By对象
+ */
+ By getBy(String value, ByType byType) {
+ //根据元素的定位方式,对定位内容进行选择,返回相应的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 是否能查找到的元素
+ */
+ abstract boolean isExistElement(By by, long waitTime);
+
+ /**
+ * 用于判断元素是否为xml文件内的元素
+ * @param name 元素名称
+ * @return 是否为xml文件内的元素
+ */
+ boolean isXmlElement(String name) {
+ return (xml != null && xml.isElement(name));
+ }
+
+ /**
+ * 文件名:AbstractElement.java
+ * 用途:
+ * 存储获取元素时的信息
+ *
+ * 编码时间:2020年5月9日上午7:57:24
+ * 修改时间:2020年5月22日上午8:18:39
+ * @author 彭宇琦
+ * @version Ver1.1
+ * @since JDK 1.8
+ *
+ */
+ class ElementInformation {
+ /**
+ * 存储元素的名称或定位内容
+ */
+ public String name;
+ /**
+ * 存储元素的定位方式
+ */
+ public ByType byType;
+ /**
+ * 用于标记元素的类型
+ */
+ public ElementType elementType;
+ /**
+ * 存储外链词语
+ */
+ public ArrayList linkKeyList;
+
+ /**
+ * 构造元素信息
+ * @param name 元素名称
+ * @param byType 元素定位的By类型,枚举
+ * @param elementType 元素类型,枚举
+ * @param linkKeyList xml文件中需要外部替换的词语
+ */
+ public ElementInformation(String name, ByType byType, ElementType elementType) {
+ super();
+ this.name = name;
+ this.byType = byType;
+ this.elementType = elementType;
+ splitLinkKey();
+ }
+
+ /**
+ * 用于判断其元素的使用的外链xml文件词语是否与存储的内容一致
+ * @param linkKey 需要判断的外链xml文件词语
+ * @return 是否与类中存储的词语一致
+ */
+ public boolean linkKeyEquals(List linkKey) {
+ //判断传入的linkKey是否为null,或未传入的linkKey为空,为空,则直接判断linkKeyList的状态
+ if (linkKey == null || linkKey.size() == 0) {
+ //若linkKeyList为null或为空,则可直接返回true;反之,则返回false
+ if (linkKeyList == null || linkKeyList.size() == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ //判断linkKey中的元素是否完全存在于linkKeyList,且两个集合的长度一致,若存在一项判断不符合,则返回false
+ if (linkKeyList.containsAll(linkKey) && linkKeyList.size() == linkKey.size()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * 用于对在名称后存在的外链词语进行切分
+ */
+ private void splitLinkKey() {
+ int index = name.indexOf("=");
+ //判断名称是否存在需要外部替换xml文件的词语
+ if (index < 0) {
+ return;
+ }
+
+ //对词语按照分隔符进行切分,并去除空格
+ String linkKeyText = name.substring(index).replaceAll(" ", "");
+ //再次按照词语分隔符进行切分
+ linkKeyList = new ArrayList<>(Arrays.asList(linkKeyText.split("\\,")));
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + getEnclosingInstance().hashCode();
+ result = prime * result + ((byType == null) ? 0 : byType.hashCode());
+ result = prime * result + ((elementType == null) ? 0 : elementType.hashCode());
+ result = prime * result + ((linkKeyList == null) ? 0 : linkKeyList.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @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 (!getEnclosingInstance().equals(other.getEnclosingInstance()))
+ return false;
+ if (byType != other.byType)
+ return false;
+ if (elementType != other.elementType)
+ return false;
+ if (linkKeyList == null) {
+ if (other.linkKeyList != null)
+ return false;
+ } else if (!linkKeyList.equals(other.linkKeyList))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+
+ private AbstractElement getEnclosingInstance() {
+ return AbstractElement.this;
+ }
+
+ }
+}
diff --git a/src/main/java/pres/auxiliary/work/selenium/element/ElementData.java b/src/main/java/pres/auxiliary/work/selenium/element/ElementData.java
index ed3a850..77139d4 100644
--- a/src/main/java/pres/auxiliary/work/selenium/element/ElementData.java
+++ b/src/main/java/pres/auxiliary/work/selenium/element/ElementData.java
@@ -3,7 +3,7 @@ package pres.auxiliary.work.selenium.element;
import java.util.ArrayList;
import pres.auxiliary.work.selenium.location.AbstractRead;
-import pres.auxiliary.work.selenium.xml.ByType;
+import pres.auxiliary.work.selenium.location.ByType;
/**
* 文件名:ElementData.java
@@ -40,22 +40,28 @@ public class ElementData {
* 存储元素
*/
private long waitTime;
+ /**
+ * 存储当前采用的读取文件的方式
+ */
+ private AbstractRead read;
/**
* 根据元素名称,在配置文件中查找元素,将元素的信息进行存储
* @param name 元素名称
- * @AbstractReadConfig 配置文件类对象
+ * @param AbstractRead 配置文件类对象
*/
- public ElementData(String name, AbstractRead arc) {
+ public ElementData(String name, AbstractRead read) {
//存储元素名称
this.name = name;
+ //存储读取文件的方式
+ this.read = read;
//根据传入的读取配置文件类对象,使用其中的返回方法,初始化元素信息
- byTypeList = arc.findElementByTypeList(name);
- valueList = arc.findValueList(name);
- elementType = arc.findElementType(name);
- iframeNameList = arc.findIframeNameList(name);
- waitTime = arc.findWaitTime(name);
+ byTypeList = read.findElementByTypeList(name);
+ valueList = read.findValueList(name);
+ elementType = read.findElementType(name);
+ iframeNameList = read.findIframeNameList(name);
+ waitTime = read.findWaitTime(name);
}
/**
@@ -105,6 +111,13 @@ public class ElementData {
public long getWaitTime() {
return waitTime;
}
-
+
+ /**
+ * 返回元素读取方式类对象
+ * @return {@link AbstractRead}子类对象
+ */
+ public AbstractRead getRead() {
+ return read;
+ }
}