修改元素存储机制,添加元素指定类型的定位方式
This commit is contained in:
parent
6cb4ae5322
commit
bb6797d4f7
|
@ -40,7 +40,7 @@ import org.openqa.selenium.WebElement;
|
|||
import pres.auxiliary.directory.exception.UndefinedDirectoryException;
|
||||
import pres.auxiliary.selenium.browers.FirefoxBrower;
|
||||
import pres.auxiliary.selenium.event.Event;
|
||||
import pres.auxiliary.selenium.xml.ElementLocationType;
|
||||
import pres.auxiliary.selenium.xml.ByType;
|
||||
import pres.auxiliary.selenium.xml.ReadXml;
|
||||
|
||||
/**
|
||||
|
@ -1040,7 +1040,7 @@ public class TestReport extends AbstractReport {
|
|||
// 由于禅道的项目搜索机制与其他页面不同,即使搜索了其<ul>标签下也显示所有的<li>,故不能通过搜索后获取第一个元素来对搜索到的项目进行定位
|
||||
List<WebElement> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* <p><b>文件名:</b>JsEvent.java</p>
|
||||
|
@ -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]
|
||||
|
|
|
@ -2,7 +2,7 @@ package pres.auxiliary.selenium.xml;
|
|||
|
||||
/**
|
||||
* <p>
|
||||
* <b>文件名:</b>PosMode.java
|
||||
* <b>文件名:</b>ByType.java
|
||||
* </p>
|
||||
* <p>
|
||||
* <b>用途:</b>用于枚举出能被识别的元素定位方式
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
@ -105,9 +105,9 @@ public class ReadXml {
|
|||
* @param name 元素名称
|
||||
* @return 当前元素有效的定位名称,多个标签名称以空格隔开
|
||||
*/
|
||||
public List<ElementLocationType> getElementMode(String name) {
|
||||
public List<ByType> getElementMode(String name) {
|
||||
// 用于存储元素定位方式的标签名称
|
||||
List<ElementLocationType> modes = new ArrayList<>();
|
||||
List<ByType> 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);
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 用于切换到当前页面
|
|
@ -40,7 +40,7 @@ import com.alibaba.fastjson.JSONArray;
|
|||
* @since JDK 1.8
|
||||
*
|
||||
*/
|
||||
public class ChromeBrower extends Brower {
|
||||
public class ChromeBrower extends AbstractBrower {
|
||||
/**
|
||||
* 用于存储需要对浏览器进行配置的参数
|
||||
*/
|
||||
|
|
|
@ -137,7 +137,7 @@ public class Page {
|
|||
/**
|
||||
* 用于通过浏览器加载页面,并根据页面断言,返回页面是否加载成功。若未设置断言,则无论
|
||||
* 页面是否成功加载,均返回true
|
||||
* @param driver WebDriver对象,通过可通过{@link Brower}类及其子类来生成
|
||||
* @param driver WebDriver对象,通过可通过{@link AbstractBrower}类及其子类来生成
|
||||
* @return 根据页面断言返回页面是否加载成功
|
||||
*/
|
||||
public boolean loadPage(WebDriver driver) {
|
||||
|
|
|
@ -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 {
|
||||
/**
|
||||
* <p><b>文件名:</b>AbstractElement.java</p>
|
||||
* <p><b>用途:</b></p>
|
||||
* <p><pre>
|
||||
* 对辅助化测试工具selenium的获取元素代码进行的二次封装,通过类中提供的方法以及配合相应存储元素的
|
||||
* xml文件,以更简便的方式对页面元素进行获取,减少编程时的代码量。
|
||||
* </pre></p>
|
||||
* <p><b>编码时间:</b>2020年4月25日 下午4:18:37</p>
|
||||
* <p><b>修改时间:</b>2020年4月25日 下午4:18:37</p>
|
||||
* @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<String> 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 {
|
|||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件
|
||||
* 名称对应的定位方式,或直接传入xpath与css定位方式,
|
||||
* 根据定位方式对相应的窗体进行定位。当传入的窗体为当前窗体的前层(父层)窗体时,
|
||||
* 通过该方法将调用切换父层的方法,将窗体切换到父层上,例如:<br>
|
||||
* 当前存在f1, f2, f3, f4四层窗体,则调用方法:<br>
|
||||
* switchFrame("f2")<br>
|
||||
* 此时窗体将回到f2层,无需再从顶层开始向下切换。<br>
|
||||
* 注意,窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
|
||||
* 当前存在f1, f2, f3, f4四层窗体,则调用方法:<br>{@code
|
||||
* switchFrame("f2");
|
||||
* }<br>
|
||||
* 此时窗体将回到f2层,无需再从顶层开始向下切换。
|
||||
* </p>
|
||||
* <p>
|
||||
* 若传入该方法的名称存在于xml文件中,且该元素存在父窗体时,调用
|
||||
* 该方法会从xml文件中获取相应所有父窗体,并对相应的父窗体进行切换,
|
||||
* 从而达到无须切换父窗体的目的,例如,存在以下xml文件片段:<pre>{@code
|
||||
* ...
|
||||
* <iframe name='f1'>
|
||||
* <xpath>...</xpath>
|
||||
* <iframe name='f2'>
|
||||
* <xpath>...</xpath>
|
||||
* <iframe name='f3'>
|
||||
* <xpath>...</xpath>
|
||||
* </iframe>
|
||||
* </iframe>
|
||||
* </iframe>
|
||||
* ...
|
||||
* }</pre>
|
||||
* 当调用该方法:<br>{@code
|
||||
* switchFrame("f3");
|
||||
* }<br>
|
||||
* 时,则会先将窗体从f1开始切换,至窗体f2,最后再切换为窗体f3
|
||||
* </p>
|
||||
*
|
||||
* @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<ElementInformation> nameList = new ArrayList<ElementInformation>();
|
||||
//判断传入的元素名称是否存在于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定位方式,
|
||||
* 根据定位方式对相应的窗体进行定位。当传入的窗体为当前窗体的前层(父层)窗体时,
|
||||
* 通过该方法将调用切换父层的方法,将窗体切换到父层上,例如:<br>
|
||||
* 当前存在f1, f2, f3, f4四层窗体,则调用方法:<br>
|
||||
* List<String> nameList = new ArrayList<String>();<br>
|
||||
* nameList.add("f2");<br>
|
||||
* switchFrame(nameList)<br>
|
||||
* 当前存在f1, f2, f3, f4四层窗体,则调用方法:<pre>{@code
|
||||
* List<String> nameList = new ArrayList<String>();
|
||||
* nameList.add("f2");
|
||||
* switchFrame(nameList);
|
||||
* }</pre>
|
||||
* 此时窗体将回到f2层,无需再从顶层开始向下切换。<br>
|
||||
* 注意,窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
|
||||
* <b>注意:</b>
|
||||
* <ol>
|
||||
* <li>窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反</li>
|
||||
* <li>传入的参数若在xml文件中且存在父窗体,调用该方法也不会对窗体进行切换</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param nameList 存储窗体的名称或xpath与css定位方式的List集合
|
||||
* @param elementInformationList 存储窗体的名称或xpath与css定位方式的List集合
|
||||
*/
|
||||
public void switchFrame(List<String> nameList) {
|
||||
nameList.forEach(name -> {
|
||||
private void switchFrame(List<ElementInformation> 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<WebElement> recognitionElements(String name) {
|
||||
List<WebElement> 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<WebElement> findCommonElement(String name, By by) {
|
||||
if (isFindWebElement(controlWaitTime.containsKey(name) ? controlWaitTime.get(name) : waitTime, by)) {
|
||||
return driver.findElements(by);
|
||||
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("元素“" + 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<WebElement> 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<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());
|
||||
}
|
||||
|
||||
// 若循环结束后仍未能找到该元素,则返回一个空串
|
||||
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<String> getParentFrameName(String name) {
|
||||
List<ElementInformation> getParentFrameName(String name) {
|
||||
//存储获取到的父层窗体名称
|
||||
List<String> nameList = new ArrayList<String>();
|
||||
List<ElementInformation> nameList = new ArrayList<ElementInformation>();
|
||||
|
||||
//获取元素所在窗体的名称
|
||||
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 是否能查找到的元素
|
||||
* <p><b>文件名:</b>AbstractElement.java</p>
|
||||
* <p><b>用途:</b>用于</p>
|
||||
* <p><b>编码时间:</b>2020年4月25日 下午5:43:59</p>
|
||||
* <p><b>修改时间:</b>2020年4月25日 下午5:43:59</p>
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package pres.auxiliary.work.selenium.element;
|
||||
|
||||
/**
|
||||
* <p><b>文件名:</b>UnrecognizableLocationModeException.java</p>
|
||||
* <p><b>用途:</b>在元素定位方式无法被识别的情况下,抛出的异常</p>
|
||||
* <p><b>编码时间:</b>2019年9月24日下午3:19:43</p>
|
||||
* <p><b>修改时间:</b>2019年9月24日下午3:19:43</p>
|
||||
* @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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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<String> parentIframeList = new ArrayList<String>();
|
||||
|
||||
ArrayList<String> iframeNameList = new ArrayList<String>();
|
||||
|
||||
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定位方式,
|
||||
* 根据定位方式对相应的窗体进行定位。当传入的窗体为当前窗体的前层(父层)窗体时,
|
||||
* 通过该方法将调用切换父层的方法,将窗体切换到父层上,例如:<br>
|
||||
* 当前存在f1, f2, f3, f4四层窗体,则调用方法:<br>
|
||||
* switchFrame("f2")<br>
|
||||
* 此时窗体将回到f2层,无需再从顶层开始向下切换。<br>
|
||||
* 注意,窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
|
||||
*
|
||||
* @param names 窗体的名称或xpath与css定位方式
|
||||
*/
|
||||
public void switchFrame(String...names) {
|
||||
switchFrame(Arrays.asList(names));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件
|
||||
* 名称对应的定位方式,或直接传入xpath与css定位方式,
|
||||
* 根据定位方式对相应的窗体进行定位。当传入的窗体为当前窗体的前层(父层)窗体时,
|
||||
* 通过该方法将调用切换父层的方法,将窗体切换到父层上,例如:<br>
|
||||
* 当前存在f1, f2, f3, f4四层窗体,则调用方法:<br>
|
||||
* List<String> nameList = new ArrayList<String>();<br>
|
||||
* nameList.add("f2");<br>
|
||||
* switchFrame(nameList)<br>
|
||||
* 此时窗体将回到f2层,无需再从顶层开始向下切换。<br>
|
||||
* 注意,窗体的切换按照从前向后的顺序进行切换,切换顺序不能相反
|
||||
*
|
||||
* @param nameList 存储窗体的名称或xpath与css定位方式的List集合
|
||||
*/
|
||||
public void switchFrame(List<String> 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue