l = null;
while (true) {
- l = d.findElements(r.getBy("项目选项", ElementLocationType.XPATH));
+ l = d.findElements(r.getBy("项目选项", ByType.XPATH));
if (l.size() != 0) {
break;
} else {
@@ -1072,7 +1072,7 @@ public class TestReport extends AbstractReport {
event.getSelectEvent().select("编码格式下拉框", 1);
event.getSelectEvent().select("记录下拉框", 0);
// 禅道的导出按钮无法点击,故需要通过提交表单的方法来导出
- d.findElement(r.getBy("导出数据表单", ElementLocationType.XPATH)).submit();
+ d.findElement(r.getBy("导出数据表单", ByType.XPATH)).submit();
d.close();
}
}
diff --git a/src/main/java/pres/auxiliary/selenium/event/AbstractEvent.java b/src/main/java/pres/auxiliary/selenium/event/AbstractEvent.java
index e6cad8d..fa4a7dd 100644
--- a/src/main/java/pres/auxiliary/selenium/event/AbstractEvent.java
+++ b/src/main/java/pres/auxiliary/selenium/event/AbstractEvent.java
@@ -18,7 +18,7 @@ import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.selenium.tool.RecordTool;
-import pres.auxiliary.selenium.xml.ElementLocationType;
+import pres.auxiliary.selenium.xml.ByType;
import pres.auxiliary.selenium.xml.ReadXml;
import pres.auxiliary.selenium.xml.UndefinedElementException;
@@ -175,7 +175,7 @@ public abstract class AbstractEvent {
// 2.若在xml文件中查找不到该元素,则按照xpath和css的规则进行匹配,直到判断出该元素的定位方式位置
// 3.若仍找不到元素,则抛出UnrecognizableLocationModeException
try {
- ElementLocationType mode = readXml(name);
+ ByType mode = readXml(name);
// 判断readXML()方法的返回值是否为空串,若为空串,则抛出TimeoutException
if (mode == null) {
// 将错误信息写入到记录工具的备注中
@@ -186,7 +186,7 @@ public abstract class AbstractEvent {
return mode + "=" + xml.getValue(name, mode);
}
} catch (UndefinedElementException | NullPointerException | InvalidXPathException e) {
- ElementLocationType mode = readValue(driver, name);
+ ByType mode = readValue(driver, name);
// 判断readValue()方法的返回值是否为空串,若为空串,则抛出UnrecognizableLocationModeException
if (mode == null) {
// 将错误信息写入到记录工具的备注中
@@ -197,9 +197,9 @@ public abstract class AbstractEvent {
//若有返回定位方式,则根据定位方式类型,获取其元素
switch (mode) {
case XPATH:
- return ElementLocationType.XPATH.getValue() + "=" + name;
+ return ByType.XPATH.getValue() + "=" + name;
case CSS:
- return ElementLocationType.CSS.getValue() + "=" + name;
+ return ByType.CSS.getValue() + "=" + name;
default:
return "";
}
@@ -428,7 +428,7 @@ public abstract class AbstractEvent {
// 2.若在xml文件中查找不到该元素,则按照xpath和css的规则进行匹配,直到判断出该元素的定位方式位置
// 3.若仍找不到元素,则抛出UnrecognizableLocationModeException
try {
- ElementLocationType mode = readXml(name);
+ ByType mode = readXml(name);
// 判断readXML()方法的返回值是否为空串,若为空串,则抛出TimeoutException
if (mode == null) {
// 将错误信息写入到记录工具的备注中
@@ -439,7 +439,7 @@ public abstract class AbstractEvent {
elements = driver.findElements(xml.getBy(name, mode));
}
} catch (UndefinedElementException | NullPointerException | InvalidXPathException e) {
- ElementLocationType mode = readValue(driver, name);
+ ByType mode = readValue(driver, name);
// 判断readValue()方法的返回值是否为空串,若为空串,则抛出UnrecognizableLocationModeException
if (mode == null) {
// 将错误信息写入到记录工具的备注中
@@ -473,9 +473,9 @@ public abstract class AbstractEvent {
* @param name 控件名称
* @return 查找到的定位方式名称
*/
- protected ElementLocationType readXml(String name) {
+ protected ByType readXml(String name) {
// 循环,逐个在页面上配对有效的标签对应的定位方式
- for (ElementLocationType mode : xml.getElementMode(name)) {
+ for (ByType mode : xml.getElementMode(name)) {
// 在页面上查找元素定位方式
try {
//自动定位元素所在的窗体
@@ -545,7 +545,7 @@ public abstract class AbstractEvent {
* @param text 定位方式
* @return 定位方式的类型
*/
- protected ElementLocationType readValue(WebDriver driver, String text) {
+ protected ByType readValue(WebDriver driver, String text) {
// 定义判断参数为xpath的字符
String judgeXpath = "/";
@@ -558,12 +558,12 @@ public abstract class AbstractEvent {
if (text.indexOf(judgeXpath) == 0) {
// 查找该定位方式在有限的时间内是否内被查到
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(text)));
- return ElementLocationType.XPATH;
+ return ByType.XPATH;
// 将等待时间设置回原来的
} else if (text.indexOf(judgeCss) == 0) {
// 匹配css,判断方法:判断text的前四个字符是否是“html”
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(text)));
- return ElementLocationType.CSS;
+ return ByType.CSS;
} else {
return null;
}
diff --git a/src/main/java/pres/auxiliary/selenium/event/JsEvent.java b/src/main/java/pres/auxiliary/selenium/event/JsEvent.java
index ef8ea93..1d07efc 100644
--- a/src/main/java/pres/auxiliary/selenium/event/JsEvent.java
+++ b/src/main/java/pres/auxiliary/selenium/event/JsEvent.java
@@ -6,7 +6,7 @@ import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
-import pres.auxiliary.selenium.xml.ElementLocationType;
+import pres.auxiliary.selenium.xml.ByType;
/**
* 文件名:JsEvent.java
@@ -158,10 +158,10 @@ public class JsEvent extends AbstractEvent {
String[] element = getElementPosition(text).split("=");
// 判断定位方式,若定位方式为css,则按照querySelector()方式进行选择,其他的方式均按照xpath来获取
- if (ElementLocationType.XPATH.getValue().equalsIgnoreCase(element[0])) {
+ if (ByType.XPATH.getValue().equalsIgnoreCase(element[0])) {
script = "document.evaluate('" + element[1]
+ "', document, null, XPathResult.ANY_TYPE, null).iterateNext()";
- } else if (ElementLocationType.CSS.getValue().equalsIgnoreCase(element[0])) {
+ } else if (ByType.CSS.getValue().equalsIgnoreCase(element[0])) {
script = "document.querySelector(" + element[1] + ")";
} else {
script = "document.evaluate('//*[@" + element[0] + "=\"" + element[1]
diff --git a/src/main/java/pres/auxiliary/selenium/xml/ElementLocationType.java b/src/main/java/pres/auxiliary/selenium/xml/ByType.java
similarity index 80%
rename from src/main/java/pres/auxiliary/selenium/xml/ElementLocationType.java
rename to src/main/java/pres/auxiliary/selenium/xml/ByType.java
index cc37dd4..1d3d133 100644
--- a/src/main/java/pres/auxiliary/selenium/xml/ElementLocationType.java
+++ b/src/main/java/pres/auxiliary/selenium/xml/ByType.java
@@ -2,7 +2,7 @@ package pres.auxiliary.selenium.xml;
/**
*
- * 文件名:PosMode.java
+ * 文件名:ByType.java
*
*
* 用途:用于枚举出能被识别的元素定位方式
@@ -19,7 +19,7 @@ package pres.auxiliary.selenium.xml;
* @since JDK 12
*
*/
-public enum ElementLocationType {
+public enum ByType {
/** 通过xpath方式进行定位 */
XPATH("xpath"),
/** 通过css方式进行定位 */
@@ -33,14 +33,19 @@ public enum ElementLocationType {
/** 通过name方式进行定位 */
NAME("name"),
/** 通过tagName方式进行定位 */
- TAGNAME("tagname");
+ TAGNAME("tagname"),
+ /**
+ * 通过jQuert的方式进行定位
+ */
+// JQ("jquert"),
+ ;
/**
* 定义枚举值
*/
private String value;
- private ElementLocationType(String value) {
+ private ByType(String value) {
this.value = value;
}
diff --git a/src/main/java/pres/auxiliary/selenium/xml/ReadXml.java b/src/main/java/pres/auxiliary/selenium/xml/ReadXml.java
index a9c48d0..454cc6a 100644
--- a/src/main/java/pres/auxiliary/selenium/xml/ReadXml.java
+++ b/src/main/java/pres/auxiliary/selenium/xml/ReadXml.java
@@ -105,9 +105,9 @@ public class ReadXml {
* @param name 元素名称
* @return 当前元素有效的定位名称,多个标签名称以空格隔开
*/
- public List getElementMode(String name) {
+ public List getElementMode(String name) {
// 用于存储元素定位方式的标签名称
- List modes = new ArrayList<>();
+ List modes = new ArrayList<>();
try {
@SuppressWarnings("unchecked")
@@ -134,13 +134,13 @@ public class ReadXml {
* 根据元素名称,在指定的xml文件中查找到相应的元素,返回其元素的信息,以{@link By}类返回
*
* @param name 元素名称
- * @param mode 定位方式枚举类对象,参见{@link ElementLocationType}
+ * @param mode 定位方式枚举类对象,参见{@link ByType}
* @return 元素对应的{@link By}类对象
*
* @throws UndefinedElementException 未找到相应的模板元素时抛出的异常
* @throws NoSuchSignValueException 模板中存在为定义值的标志时抛出的异常
*/
- public By getBy(String name, ElementLocationType mode) {
+ public By getBy(String name, ByType mode) {
// 存储从xml文件中读取到的元素定位
String elementPos = getValue(name, mode);
@@ -173,13 +173,13 @@ public class ReadXml {
* 用于根据元素名称及定位方式来返回其定位方式的值
*
* @param name 元素名称
- * @param mode 定位方式枚举类对象,参见{@link ElementLocationType}
+ * @param mode 定位方式枚举类对象,参见{@link ByType}
* @return xml文件中的相应元素的定位值
*
* @throws UndefinedElementException 未找到相应的模板元素时抛出的异常
* @throws NoSuchSignValueException 模板中存在为定义值的标志时抛出的异常
*/
- public String getValue(String name, ElementLocationType mode) {
+ public String getValue(String name, ByType mode) {
// 用于拼接读取XML中元素的xpath,为了兼容iframe标签,故此处使用“*”符号来查找元素
String xmlXpath = "//*[@name='" + name + "']/" + mode.getValue();
// 获取元素节点,并将其转为Element对象,以便于获取该元素的属性值
@@ -241,7 +241,7 @@ public class ReadXml {
* @throws NoSuchSignValueException 模板中存在为定义值的标志时抛出的异常
*/
@SuppressWarnings("unchecked")
- private String getTempletPath(Element element, String name, ElementLocationType mode) {
+ private String getTempletPath(Element element, String name, ByType mode) {
// 通过元素的temp_id定位到模板的id上
Element templetElement = (Element) dom.selectSingleNode(
"//templet/" + mode.getValue() + "[@id='" + element.attribute("temp_id").getValue() + "']");
@@ -281,22 +281,22 @@ public class ReadXml {
* @param modeName 定位标签名称
* @return ElementLocationType枚举
*/
- private static ElementLocationType getMode(String modeName) {
+ private static ByType getMode(String modeName) {
switch (modeName) {
case "xpath":
- return ElementLocationType.XPATH;
+ return ByType.XPATH;
case "css":
- return ElementLocationType.CSS;
+ return ByType.CSS;
case "classname":
- return ElementLocationType.CLASSNAME;
+ return ByType.CLASSNAME;
case "id":
- return ElementLocationType.ID;
+ return ByType.ID;
case "linktext":
- return ElementLocationType.LINKTEXT;
+ return ByType.LINKTEXT;
case "name":
- return ElementLocationType.NAME;
+ return ByType.NAME;
case "tagname":
- return ElementLocationType.TAGNAME;
+ return ByType.TAGNAME;
default:
throw new IllegalArgumentException("Unexpected value: " + modeName);
diff --git a/src/main/java/pres/auxiliary/work/selenium/brower/Brower.java b/src/main/java/pres/auxiliary/work/selenium/brower/AbstractBrower.java
similarity index 98%
rename from src/main/java/pres/auxiliary/work/selenium/brower/Brower.java
rename to src/main/java/pres/auxiliary/work/selenium/brower/AbstractBrower.java
index 3f085cf..2dc1de3 100644
--- a/src/main/java/pres/auxiliary/work/selenium/brower/Brower.java
+++ b/src/main/java/pres/auxiliary/work/selenium/brower/AbstractBrower.java
@@ -21,7 +21,7 @@ import com.alibaba.fastjson.JSONObject;
* @since JDK 12
*
*/
-public abstract class Brower {
+public abstract class AbstractBrower {
/**
* 用于接收浏览器启动所需的文件路径
*/
@@ -50,7 +50,7 @@ public abstract class Brower {
*
* @param driberFile 驱动文件对象
*/
- public Brower(File driverFile) {
+ public AbstractBrower(File driverFile) {
this.driverFile = driverFile;
// 存储页面信息
@@ -64,7 +64,7 @@ public abstract class Brower {
* @param url 待测站点
* @param pageName 待测站点名称,用于切换页面
*/
- public Brower(File driverFile, String url, String pageName) {
+ public AbstractBrower(File driverFile, String url, String pageName) {
this(driverFile);
nowPage = new Page(url, pageName);
}
@@ -75,7 +75,7 @@ public abstract class Brower {
* @param driverFile 驱动文件对象
* @param page {@link Page}类对象
*/
- public Brower(File driverFile, Page page) {
+ public AbstractBrower(File driverFile, Page page) {
this(driverFile);
nowPage = page;
}
@@ -322,6 +322,8 @@ public abstract class Brower {
}
}
}
+
+
/**
* 用于切换到当前页面
diff --git a/src/main/java/pres/auxiliary/work/selenium/brower/ChromeBrower.java b/src/main/java/pres/auxiliary/work/selenium/brower/ChromeBrower.java
index f295978..e8f6b6a 100644
--- a/src/main/java/pres/auxiliary/work/selenium/brower/ChromeBrower.java
+++ b/src/main/java/pres/auxiliary/work/selenium/brower/ChromeBrower.java
@@ -40,7 +40,7 @@ import com.alibaba.fastjson.JSONArray;
* @since JDK 1.8
*
*/
-public class ChromeBrower extends Brower {
+public class ChromeBrower extends AbstractBrower {
/**
* 用于存储需要对浏览器进行配置的参数
*/
diff --git a/src/main/java/pres/auxiliary/work/selenium/brower/Page.java b/src/main/java/pres/auxiliary/work/selenium/brower/Page.java
index 4403a8c..6100446 100644
--- a/src/main/java/pres/auxiliary/work/selenium/brower/Page.java
+++ b/src/main/java/pres/auxiliary/work/selenium/brower/Page.java
@@ -137,7 +137,7 @@ public class Page {
/**
* 用于通过浏览器加载页面,并根据页面断言,返回页面是否加载成功。若未设置断言,则无论
* 页面是否成功加载,均返回true
- * @param driver WebDriver对象,通过可通过{@link Brower}类及其子类来生成
+ * @param driver WebDriver对象,通过可通过{@link AbstractBrower}类及其子类来生成
* @return 根据页面断言返回页面是否加载成功
*/
public boolean loadPage(WebDriver driver) {
diff --git a/src/main/java/pres/auxiliary/work/selenium/element/Element.java b/src/main/java/pres/auxiliary/work/selenium/element/AbstractElement.java
similarity index 55%
rename from src/main/java/pres/auxiliary/work/selenium/element/Element.java
rename to src/main/java/pres/auxiliary/work/selenium/element/AbstractElement.java
index b228280..b5bb99e 100644
--- a/src/main/java/pres/auxiliary/work/selenium/element/Element.java
+++ b/src/main/java/pres/auxiliary/work/selenium/element/AbstractElement.java
@@ -2,14 +2,11 @@ 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.stream.Collectors;
-import org.junit.rules.ExpectedException;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.TimeoutException;
@@ -19,23 +16,31 @@ import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.selenium.event.NoSuchWindownException;
-import pres.auxiliary.selenium.event.UnrecognizableLocationModeException;
-import pres.auxiliary.selenium.xml.ElementLocationType;
+import pres.auxiliary.selenium.xml.ByType;
import pres.auxiliary.selenium.xml.ReadXml;
-public class Element {
+/**
+ * 文件名:AbstractElement.java
+ * 用途:
+ *
+ * 对辅助化测试工具selenium的获取元素代码进行的二次封装,通过类中提供的方法以及配合相应存储元素的
+ * xml文件,以更简便的方式对页面元素进行获取,减少编程时的代码量。
+ *
+ * 编码时间:2020年4月25日 下午4:18:37
+ * 修改时间:2020年4月25日 下午4:18:37
+ * @author 彭宇琦
+ * @version Ver1.0
+ * @since JDK 12
+ */
+public abstract class AbstractElement {
/**
* 用于存储浏览器的WebDriver对象,设为静态,保证所有的子类只使用一个WebDriver对象,以避免造成WebDriver不正确导致的Bug
*/
- private WebDriver driver;
+ WebDriver driver;
/**
* 用于指向存储控件定位方式的xml文件
*/
- private ReadXml xml = new ReadXml();
- /**
- * 全局控件等待时间
- */
- private long waitTime = 3;
+ ReadXml xml = new ReadXml();
/**
* 存储单个控件的等待时间
*/
@@ -49,36 +54,50 @@ public class Element {
*/
private ArrayList iframeNameList = new ArrayList<>();
+ /**
+ * 用于存储元素通用的等待时间
+ */
+ private long waitTime = 5;
+
/**
* 控制是否自动切换窗体,由于通过Event类调用时会构造另一个事件类,但每个类都应共享一个开关,故需要加上static
*/
- boolean switchIframe = true;
+ boolean isAutoSwitchIframe = true;
/**
* 构造对象并存储浏览器的WebDriver对象
*
* @param driver 浏览器的WebDriver对象
*/
- public Element(WebDriver driver) {
+ public AbstractElement(WebDriver driver) {
this.driver = driver;
browserHandles = this.driver.getWindowHandle();
}
/**
- * 用于设置等待时间
+ * 用于对单个控件设置等待时间
*
+ * @param name 控件名称
* @param waitTime 等待时间
*/
+ public void setContorlWaitTime(String name, long waitTime) {
+ controlWaitTime.put(name, waitTime);
+ }
+
+ /**
+ * 用于设置控件的通用等待时间
+ * @param waitTime 控件通用的等待时间
+ */
public void setWaitTime(long waitTime) {
-// wait = new WebDriverWait(driver, waitTime, 200);
+ this.waitTime = waitTime;
}
/**
* 设置是否自动切换窗体
* @param switchIframe 是否自动切换窗体
*/
- public void setSwitchIframe(boolean switchIframe) {
- this.switchIframe = switchIframe;
+ public void setAutoSwitchIframe(boolean isAutoSwitchIframe) {
+ this.isAutoSwitchIframe = isAutoSwitchIframe;
}
/**
@@ -103,17 +122,6 @@ public class Element {
}
}
-
- /**
- * 用于对单个控件设置等待时间
- *
- * @param name 控件名称
- * @param waitTime 等待时间
- */
- public void setContorlWaitTime(String name, long waitTime) {
- controlWaitTime.put(name, waitTime);
- }
-
/**
* 该方法用于将窗体切回顶层,当本身是在最顶层时,则该方法将使用无效
*/
@@ -143,19 +151,64 @@ public class Element {
}
/**
+ *
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件
* 名称对应的定位方式,或直接传入xpath与css定位方式,
* 根据定位方式对相应的窗体进行定位。当传入的窗体为当前窗体的前层(父层)窗体时,
* 通过该方法将调用切换父层的方法,将窗体切换到父层上,例如:
- * 当前存在f1, f2, f3, f4四层窗体,则调用方法:
- * switchFrame("f2")
- * 此时窗体将回到f2层,无需再从顶层开始向下切换。
- * 注意,窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
+ * 当前存在f1, f2, f3, f4四层窗体,则调用方法:
{@code
+ * switchFrame("f2");
+ * }
+ * 此时窗体将回到f2层,无需再从顶层开始向下切换。
+ *
+ *
+ * 若传入该方法的名称存在于xml文件中,且该元素存在父窗体时,调用
+ * 该方法会从xml文件中获取相应所有父窗体,并对相应的父窗体进行切换,
+ * 从而达到无须切换父窗体的目的,例如,存在以下xml文件片段:
{@code
+ * ...
+ *
+ * ...
+ * }
+ * 当调用该方法:
{@code
+ * switchFrame("f3");
+ * }
+ * 时,则会先将窗体从f1开始切换,至窗体f2,最后再切换为窗体f3
+ *
*
- * @param names 窗体的名称或xpath与css定位方式
+ * @param name 窗体的名称或xpath与css定位方式
*/
- public void switchFrame(String...names) {
- switchFrame(Arrays.asList(names));
+ public void switchFrame(String name) {
+ switchFrame(name, null);
+ }
+
+ /**
+ * 通过传入在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) {
+ List nameList = new ArrayList();
+ //判断传入的元素名称是否存在于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);
}
/**
@@ -163,21 +216,26 @@ public class Element {
* 名称对应的定位方式,或直接传入xpath与css定位方式,
* 根据定位方式对相应的窗体进行定位。当传入的窗体为当前窗体的前层(父层)窗体时,
* 通过该方法将调用切换父层的方法,将窗体切换到父层上,例如:
- * 当前存在f1, f2, f3, f4四层窗体,则调用方法:
- * List nameList = new ArrayList();
- * nameList.add("f2");
- * switchFrame(nameList)
+ * 当前存在f1, f2, f3, f4四层窗体,则调用方法:{@code
+ * List nameList = new ArrayList();
+ * nameList.add("f2");
+ * switchFrame(nameList);
+ * }
* 此时窗体将回到f2层,无需再从顶层开始向下切换。
- * 注意,窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
+ * 注意:
+ *
+ * - 窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
+ * - 传入的参数若在xml文件中且存在父窗体,调用该方法也不会对窗体进行切换
+ *
*
- * @param nameList 存储窗体的名称或xpath与css定位方式的List集合
+ * @param elementInformationList 存储窗体的名称或xpath与css定位方式的List集合
*/
- public void switchFrame(List nameList) {
- nameList.forEach(name -> {
+ private void switchFrame(List elementInformationList) {
+ elementInformationList.forEach(elementInformation -> {
//判断name指向的窗体是否在iframeNameList中,若存在,则向上切换父层,直到切换到name指向的窗体;若不存在,则直接切换,并添加窗体名称
- if (iframeNameList.contains(name)) {
+ if (iframeNameList.contains(elementInformation.name)) {
//获取name窗体在iframeNameList中的位置
- int index = iframeNameList.indexOf(name);
+ int index = iframeNameList.indexOf(elementInformation.name);
//获取需要向上切换窗体的次数,公式为推断出来
int count = iframeNameList.size() - index - 1;
for (int i = 0; i < count; i++) {
@@ -185,8 +243,8 @@ public class Element {
}
} else {
//切换窗体
- driver.switchTo().frame(recognitionElements(name).get(0));
- iframeNameList.add(name);
+ driver.switchTo().frame(recognitionElements(elementInformation).get(0));
+ iframeNameList.add(elementInformation.name);
}
});
}
@@ -250,7 +308,7 @@ public class Element {
throw new NoSuchWindownException("未找到存在元素" + controlName + "所在的窗体");
}
-
+
/**
* 定位到弹框上并且点击确定按钮,并返回弹框上的文本
*
@@ -316,12 +374,12 @@ public class Element {
* @throws TimeoutException 元素在指定时间内未查找到时,抛出的异常
* @throws UnrecognizableLocationModeException 元素无法识别时抛出的异常
*/
- List recognitionElements(String name) {
+ List recognitionElements(ElementInformation element) {
//判断元素是否存在于xml文件中,根据返回的状态,来判断调用的方法
- if (xml.isElement(name)) {
- return findXmlElement(name);
+ if (xml.isElement(element.name)) {
+ return findXmlElement(element);
} else {
- return findCommonElement(name, judgeElementLocationMode(name));
+ return findCommonElement(element);
}
}
@@ -330,13 +388,18 @@ public class Element {
* @param name 元素内容
* @return
*/
- private List findCommonElement(String name, By by) {
- if (isFindWebElement(controlWaitTime.containsKey(name) ? controlWaitTime.get(name) : waitTime, by)) {
- return driver.findElements(by);
+ private List 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("元素“" + name + "”无法查找,请核对定位方式:" + by.toString());
+ throw new TimeoutException("元素“" + element.name + "”无法查找,请核对定位方式:" + element.byType.getValue() + "=" + element.value);
}
/**
@@ -345,35 +408,84 @@ public class Element {
* @return 页面中查找到的元素
* @throws TimeoutException 当元素不能找到时抛出的异常
*/
- private List findXmlElement(String name) {
- // 循环,逐个在页面上配对有效的标签对应的定位方式
- for (ElementLocationType mode : xml.getElementMode(name)) {
- if (isFindWebElement(controlWaitTime.containsKey(name) ? controlWaitTime.get(name) : waitTime, xml.getBy(name, mode))) {
- driver.findElements(xml.getBy(name, mode));
+ private List 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());
}
-
- // 若循环结束后仍未能找到该元素,则返回一个空串
- throw new TimeoutException("元素“" + name + "”无法查找,请核对xml文件:" + xml.getXmlFile().getName() + "\n文件路径:" + xml.getXmlFile().getAbsolutePath());
+
+ return driver.findElements(getBy(element.byType, element.value));
}
/**
- * 用于判断传入参数的定位方式,只识别xpath与css两种定位方式。需要注意的是,该方法主要用于
- * 识别xptah,若元素的定位方式不是xpath定位,则根据css方式来返回
+ * 用于判断传入参数的定位方式,只识别xpath路径与绝对的css路径两种定位方式。
+ *
* @param text 元素定位方式
- * @return 相应的By对象
+ * @return {@link ByType}枚举
*/
- private By judgeElementLocationMode(String text) {
- // 定义判断参数为xpath的字符
- String judgeXpath = "/";
-
- // 如果抛出元素名称查找不到的的异常,则对应匹配xpath和css两种定位方式
+ private ByType judgeElementLocationMode(String text) {
+ // 如果抛出元素名称查找不到的的异常,则对应匹配xpath和绝对css路径两种定位方式
// 匹配xpath定位,判定方法,判断text的第一个字符是否是“/”
- if (text.indexOf(judgeXpath) == 0) {
+ if (text.indexOf("/") == 0) {
// 查找该定位方式在有限的时间内是否内被查到
- return By.xpath(text);
+ return ByType.XPATH;
+ } else if (text.indexOf("html") == 0) {
+ return ByType.CSS;
} else {
- return By.cssSelector(text);
+ 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);
}
}
@@ -383,16 +495,16 @@ public class Element {
* @param name 元素在xml文件中的名称
* @return 元素在xml文件中所有的父窗体集合
*/
- private List getParentFrameName(String name) {
+ List getParentFrameName(String name) {
//存储获取到的父层窗体名称
- List nameList = new ArrayList();
+ List nameList = new ArrayList();
//获取元素所在窗体的名称
String iframeName = xml.getIframeName(name);
//循环,判断窗体是否存在(方法返回不为空),若存在,则再将父窗体进行存储
while(!iframeName.isEmpty()) {
//存储窗体
- nameList.add(iframeName);
+ nameList.add(new ElementInformation(iframeName, controlWaitTime.containsKey(iframeName) ? controlWaitTime.get(iframeName) : waitTime));
//再以当前窗体的名称再次获取该窗体的父窗体
iframeName = xml.getIframeName(iframeName);
}
@@ -420,19 +532,94 @@ public class Element {
}
/**
- * 根据页面的等待时间和元素定位方式,在页面上查找相应的元素,返回是否能查到元素
- * @param time 控件等待时间
- * @param by 元素定位方式
- * @return 是否能查找到的元素
+ * 文件名:AbstractElement.java
+ * 用途:用于
+ * 编码时间:2020年4月25日 下午5:43:59
+ * 修改时间:2020年4月25日 下午5:43:59
+ * @author 彭宇琦
+ * @version Ver1.0
+ * @since JDK 12
*/
- boolean isFindWebElement(long time, By by) {
-// new WebDriverWait(driver, time, 200).until(ExpectedConditions.elementToBeClickable(by));
- //当查找到元素时,则返回true,若查不到元素,则会抛出异常,故返回false
- try {
- new WebDriverWait(driver, time, 200).until(ExpectedConditions.presenceOfElementLocated(by));
- return true;
- } catch (Exception e) {
- return false;
+ class ElementInformation {
+ /**
+ * 用于存储元素的名称
+ */
+ private String name;
+
+ /**
+ * 用于存储元素的定位内容
+ */
+ private String value = "";
+
+ /**
+ * 用于存储元素的定位方式
+ */
+ private ByType byType;
+
+ /**
+ * 用于存储在页面上查找的等待时间
+ */
+ private long waitTime;
+
+ /**
+ * 用于初始化元素的信息
+ * @param name 元素在xml文件的名称,或xpath路径,或绝对的css路径
+ * @param waitTime 元素控件的等待时间
+ */
+ public ElementInformation(String name, long waitTime) {
+ this.name = name;
+ this.waitTime = waitTime;
+
+ //若未指定xml文件或xml文件中不存在name对应的元素,则将name的值赋给value,表示
+ if (xml == null || !xml.isElement(name)) {
+ value = name;
+ }
+ }
+
+ /**
+ * 用于初始化元素的信息
+ * @param name 元素在xml文件的名称,或xpath路径,或绝对的css路径
+ * @param waitTime 元素控件的等待时间
+ */
+ public ElementInformation(String name, ByType byType, long waitTime) {
+ this.name = name;
+ this.byType = byType;
+ this.waitTime = waitTime;
+
+ //若未指定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);
+ }
+ }
+
+ /**
+ * 用于返回元素的名称,或定位方式
+ * @return 元素的名称
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * 用于返回元素的等待时间
+ * @return
+ */
+ public long getWaitTime() {
+ return waitTime;
+ }
+
+ /**
+ * 用于返回定位元素的内容,当未对元素进行查找时,返回空串
+ * @return 定位元素的内容
+ */
+ public String getValue() {
+ return value;
}
}
}
diff --git a/src/main/java/pres/auxiliary/work/selenium/element/CommonElement.java b/src/main/java/pres/auxiliary/work/selenium/element/CommonElement.java
index 56e0f03..20196b1 100644
--- a/src/main/java/pres/auxiliary/work/selenium/element/CommonElement.java
+++ b/src/main/java/pres/auxiliary/work/selenium/element/CommonElement.java
@@ -3,7 +3,7 @@ package pres.auxiliary.work.selenium.element;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
-public class CommonElement extends Element {
+public class CommonElement extends AbstractElement {
/**
* 构造对象并存储浏览器的WebDriver对象
*
@@ -20,18 +20,13 @@ public class CommonElement extends Element {
* @return WebElement对象
*/
public WebElement getWebElement(String name) {
- //TODO 编写返回元素的方法
- //1.判断传入的参数在xml文件中是否能找到
- //1.1 若能找到
- //1.1.1 获取元素内容
- //1.1.2 获取元素所在的frame以及父层的frame
- //1.1.3 对元素的frame自动进行切换
- //1.1.4 调用判断元素是否存在的方法,对元素进行存在判断
- //1.1.4.1 存在,获取并返回
- //1.1.4.2 不存在,抛出异常
- //1.2 若不能找到,调用判断方法对传入的内容判断是xpath或css
- //1.2.1 若均不是,抛出异常
- //1.2.2 若是,则调用判断元素是否存在的方法,对元素进行存在判断
+ //判断传入的元素是否在xml文件中,若存在再判断是否自动切换窗体,若需要,则获取元素的所有父窗体并进行切换
+ if (xml.isElement(name)) {
+ //判断元素是否需要自动切换窗体
+ if (isAutoSwitchIframe) {
+ switchFrame(getParentFrameName(name));
+ }
+ }
return null;
}
diff --git a/src/main/java/pres/auxiliary/work/selenium/element/UnrecognizableLocationModeException.java b/src/main/java/pres/auxiliary/work/selenium/element/UnrecognizableLocationModeException.java
new file mode 100644
index 0000000..a46ac37
--- /dev/null
+++ b/src/main/java/pres/auxiliary/work/selenium/element/UnrecognizableLocationModeException.java
@@ -0,0 +1,38 @@
+package pres.auxiliary.work.selenium.element;
+
+/**
+ * 文件名:UnrecognizableLocationModeException.java
+ * 用途:在元素定位方式无法被识别的情况下,抛出的异常
+ * 编码时间:2019年9月24日下午3:19:43
+ * 修改时间:2019年9月24日下午3:19:43
+ * @author 彭宇琦
+ * @version Ver1.0
+ * @since JDK 12
+ *
+ */
+public class UnrecognizableLocationModeException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public UnrecognizableLocationModeException() {
+ super();
+ }
+
+ public UnrecognizableLocationModeException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ public UnrecognizableLocationModeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public UnrecognizableLocationModeException(String message) {
+ super(message);
+ }
+
+ public UnrecognizableLocationModeException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/src/test/java/pres/auxiliary/selenium/xml/io/TestReadXml.java b/src/test/java/pres/auxiliary/selenium/xml/io/TestReadXml.java
index dd128a2..02667c6 100644
--- a/src/test/java/pres/auxiliary/selenium/xml/io/TestReadXml.java
+++ b/src/test/java/pres/auxiliary/selenium/xml/io/TestReadXml.java
@@ -7,7 +7,7 @@ import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
-import pres.auxiliary.selenium.xml.ElementLocationType;
+import pres.auxiliary.selenium.xml.ByType;
import pres.auxiliary.selenium.xml.ReadXml;
/**
@@ -37,73 +37,73 @@ public class TestReadXml {
}
/**
- * 用于测试{@link ReadXml#getBy(String, ElementLocationType)}方法,获取普通元素
+ * 用于测试{@link ReadXml#getBy(String, ByType)}方法,获取普通元素
*/
@Test
public void getByTest_Element() {
- System.out.println(r.getBy("XX控件7", ElementLocationType.XPATH));
+ System.out.println(r.getBy("XX控件7", ByType.XPATH));
}
/**
- * 用于测试{@link ReadXml#getBy(String, ElementLocationType)}方法,获取窗体元素
+ * 用于测试{@link ReadXml#getBy(String, ByType)}方法,获取窗体元素
*/
@Test
public void getByTest_Iframe() {
- System.out.println(r.getBy("窗体1.1", ElementLocationType.XPATH));
+ System.out.println(r.getBy("窗体1.1", ByType.XPATH));
}
/**
- * 用于测试{@link ReadXml#getBy(String, ElementLocationType)}方法,获取模板元素
+ * 用于测试{@link ReadXml#getBy(String, ByType)}方法,获取模板元素
*/
@Test
public void getByTest_Templet() {
- System.out.println(r.getBy("XX控件11", ElementLocationType.XPATH));
- System.out.println(r.getBy("窗体1", ElementLocationType.CSS));
+ System.out.println(r.getBy("XX控件11", ByType.XPATH));
+ System.out.println(r.getBy("窗体1", ByType.CSS));
}
/**
- * 用于测试{@link ReadXml#getBy(String, ElementLocationType)}方法,获取顶层元素
+ * 用于测试{@link ReadXml#getBy(String, ByType)}方法,获取顶层元素
*/
@Test
public void getByTest_RootElement() {
- System.out.println(r.getBy("XX控件1", ElementLocationType.XPATH));
+ System.out.println(r.getBy("XX控件1", ByType.XPATH));
}
/**
- * 用于测试{@link ReadXml#getValue(String, ElementLocationType)}方法,获取普通元素
+ * 用于测试{@link ReadXml#getValue(String, ByType)}方法,获取普通元素
*/
@Test
public void getElementValueTest_Element() {
- System.out.println(r.getValue("XX控件7", ElementLocationType.XPATH));
+ System.out.println(r.getValue("XX控件7", ByType.XPATH));
}
/**
- * 用于测试{@link ReadXml#getValue(String, ElementLocationType)}方法,获取窗体元素
+ * 用于测试{@link ReadXml#getValue(String, ByType)}方法,获取窗体元素
*/
@Test
public void getElementValueTest_Iframe() {
- System.out.println(r.getValue("窗体1.1", ElementLocationType.XPATH));
+ System.out.println(r.getValue("窗体1.1", ByType.XPATH));
}
/**
- * 用于测试{@link ReadXml#getValue(String, ElementLocationType)}方法,获取模板元素
+ * 用于测试{@link ReadXml#getValue(String, ByType)}方法,获取模板元素
*/
@Test
public void getElementValueTest_Templet() {
- System.out.println(r.getValue("XX控件11", ElementLocationType.XPATH));
- System.out.println(r.getValue("窗体1", ElementLocationType.CSS));
+ System.out.println(r.getValue("XX控件11", ByType.XPATH));
+ System.out.println(r.getValue("窗体1", ByType.CSS));
}
/**
- * 用于测试{@link ReadXml#getValue(String, ElementLocationType)}方法,获取顶层元素
+ * 用于测试{@link ReadXml#getValue(String, ByType)}方法,获取顶层元素
*/
@Test
public void getElementValueTest_RootElement() {
- System.out.println(r.getValue("XX控件1", ElementLocationType.XPATH));
+ System.out.println(r.getValue("XX控件1", ByType.XPATH));
}
/**
- * 用于测试{@link ReadXml#getIframeName(String, ElementLocationType)}方法,获取普通元素
+ * 用于测试{@link ReadXml#getIframeName(String, ByType)}方法,获取普通元素
*/
@Test
public void getIframeNameTest_Element() {
@@ -111,7 +111,7 @@ public class TestReadXml {
}
/**
- * 用于测试{@link ReadXml#getIframeName(String, ElementLocationType)}方法,获取窗体元素
+ * 用于测试{@link ReadXml#getIframeName(String, ByType)}方法,获取窗体元素
*/
@Test
public void getIframeNameTest_Iframe() {
@@ -119,7 +119,7 @@ public class TestReadXml {
}
/**
- * 用于测试{@link ReadXml#getIframeName(String, ElementLocationType)}方法,获取模板元素
+ * 用于测试{@link ReadXml#getIframeName(String, ByType)}方法,获取模板元素
*/
@Test
public void getIframeNameTest_Templet() {
diff --git a/src/test/java/test/javase/Test111.java b/src/test/java/test/javase/Test111.java
deleted file mode 100644
index e9b9f70..0000000
--- a/src/test/java/test/javase/Test111.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package test.javase;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileReader;
-import java.io.InputStreamReader;
-
-public class Test111 {
- public static void main(String[] args) throws Exception {
- File f1 = new File("D:\\1.txt");
- File f2 = new File("D:\\2.txt");
-
-// System.out.println(f1.getName());
-
- BufferedReader br1 = new BufferedReader(new FileReader(f1));
- BufferedReader br2 = new BufferedReader(new FileReader(f2));
-
-// BufferedReader br1 = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\1.txt"), "UTF-8"));
-// BufferedReader br2 = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\2.txt"), "UTF-8"));
-
- String text1 = "";
- String text2 = "";
-
- String s = "";
- while((s = br1.readLine()) != null) {
- text1 += s;
- text1 += "\n";
- }
-
- s = "";
- while((s = br2.readLine()) != null) {
- text2 += s;
- text2 += "\n";
- }
-
-// System.out.println(text1);
-// System.out.println("-----------------");
-// System.out.println(text2);
-
- String[] texts1 = text1.split("\\n");
- String[] texts2 = text2.split("\\n");
-
- for (String t1 : texts1) {
- for (String t2 : texts2) {
-// String tt1 = new String(t1.getBytes("ISO-8859-1"),"UTF-8");
-// String tt2 = new String(t2.getBytes("ISO-8859-1"), "UTF-8");
- System.out.println(t1.length());
- System.out.println(t2.length());
- System.out.println("字符串“" + t1 + "”与字符串“" + t2 + "”的比较结果为:" + t1.equals(t2));
- }
- }
-
- /*
- System.out.println("t1:" + texts1.length);
- System.out.println("t2:" + texts2.length);
-
- for (String t1 : texts1) {
- boolean b = true;
- for (String t2 : texts2) {
- if (t2.equals(t1)) {
- b = false;
- break;
- }
-
- b = true;
- }
-
- if(b) {
- System.out.println(t1);
- }
-
- }*/
-
- br1.close();
- br2.close();
- }
-}
diff --git a/src/test/java/test/javase/TestList.java b/src/test/java/test/javase/TestList.java
new file mode 100644
index 0000000..d4cf9e6
--- /dev/null
+++ b/src/test/java/test/javase/TestList.java
@@ -0,0 +1,100 @@
+package test.javase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+public class TestList {
+ @Test
+ public void test() {
+ //TODO
+ SwitchFrame sf = new SwitchFrame();
+ }
+
+ class SwitchFrame {
+ private ArrayList parentIframeList = new ArrayList();
+
+ ArrayList iframeNameList = new ArrayList();
+
+ public SwitchFrame() {
+ parentIframeList.add("f1");
+ parentIframeList.add("f2");
+ parentIframeList.add("f3");
+ }
+
+ /**
+ * 该方法用于将窗体切回顶层,当本身是在最顶层时,则该方法将使用无效
+ */
+ public void switchRootFrame() {
+ //清空iframeNameList中的内容
+ iframeNameList.clear();
+ }
+
+ /**
+ * 该方法用于将窗体切换到上一层(父层)。若当前层只有一层,则调用方法后切回顶层;
+ * 若当前层为最顶层时,则该方法将使用无效
+ */
+ public void switchParentFrame() {
+ //若iframeNameList大于1层,则向上切换窗体
+ if (iframeNameList.size() > 1) {
+ 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四层窗体,则调用方法:
+ * switchFrame("f2")
+ * 此时窗体将回到f2层,无需再从顶层开始向下切换。
+ * 注意,窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
+ *
+ * @param names 窗体的名称或xpath与css定位方式
+ */
+ public void switchFrame(String...names) {
+ switchFrame(Arrays.asList(names));
+ }
+
+ /**
+ * 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件
+ * 名称对应的定位方式,或直接传入xpath与css定位方式,
+ * 根据定位方式对相应的窗体进行定位。当传入的窗体为当前窗体的前层(父层)窗体时,
+ * 通过该方法将调用切换父层的方法,将窗体切换到父层上,例如:
+ * 当前存在f1, f2, f3, f4四层窗体,则调用方法:
+ * List nameList = new ArrayList();
+ * nameList.add("f2");
+ * switchFrame(nameList)
+ * 此时窗体将回到f2层,无需再从顶层开始向下切换。
+ * 注意,窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
+ *
+ * @param nameList 存储窗体的名称或xpath与css定位方式的List集合
+ */
+ public void switchFrame(List nameList) {
+ nameList.forEach(name -> {
+ //判断name指向的窗体是否在iframeNameList中,若存在,则向上切换父层,直到切换到name指向的窗体;若不存在,则直接切换,并添加窗体名称
+ if (iframeNameList.contains(name)) {
+ //获取name窗体在iframeNameList中的位置
+ int index = iframeNameList.indexOf(name);
+ //获取需要向上切换窗体的次数,公式为推断出来
+ int count = iframeNameList.size() - index - 1;
+ for (int i = 0; i < count; i++) {
+ switchParentFrame();
+ }
+ } else {
+ //切换窗体
+ iframeNameList.add(name);
+ }
+ });
+ }
+ }
+}