完成对事件类的改造

This commit is contained in:
彭宇琦 2020-10-20 20:00:20 +08:00
parent d3d394f8a9
commit 1c54898f23
8 changed files with 728 additions and 80 deletions

View File

@ -1,9 +1,11 @@
package pres.auxiliary.work.selenium.event;
import java.time.Duration;
import java.util.Arrays;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
@ -82,18 +84,59 @@ public abstract class AbstractEvent {
public String getResultText() {
return resultText;
}
/**
* 用于返回当前指向的{@link AbstractBrower}类对象
* @return {@link AbstractBrower}类对象
*/
protected AbstractBrower getBrower() {
return brower;
}
/**
* 用于通过js脚本将页面定位元素所在位置
* @param element {@link Element}对象
*/
protected void locationElement(Element element) {
protected void locationElement(WebElement element) {
//若抛出NoSuchElementException异常则将异常抛出其他异常将不做处理
try {
((JavascriptExecutor) brower.getDriver()).executeScript(LOCATION_ELEMENT_JS, element.getWebElement());
} catch (NoSuchElementException e) {
throw e;
((JavascriptExecutor) brower.getDriver()).executeScript(LOCATION_ELEMENT_JS, element);
} catch (Exception e) {
throw e;
}
}
/**
* 用于判断元素是否存在
* @param element {@link Element}对象
* @return 当前指定的元素是否存在
*/
protected boolean isExistElement(Element element) {
//判断元素是否存在若返回元素时抛出异常则返回false
try {
element.getWebElement();
return true;
} catch (NoSuchElementException e) {
return false;
}
}
/**
* 用于将字符串数组内容转成字符串形式返回
* @param keys 字符串数组
* @return 数组文本
*/
protected String arrayToString(String...keys) {
if (keys == null || keys.length == 0) {
return "[]";
}
StringBuilder text = new StringBuilder("[");
Arrays.asList(keys).forEach(key -> {
text.append(key);
text.append(", ");
});
return text.substring(0, text.lastIndexOf(", "));
}
}

View File

@ -0,0 +1,386 @@
package pres.auxiliary.work.selenium.event;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.TimeoutException;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.AbstractBy.Element;
/**
* <p>
* <b>文件名</b>AssertEvent.java
* </p>
* <p>
* <b>用途</b> 定义了对控件进行断言的方法可通过该类对页面元素进行断言操作类中的所有断言均以
* boolean类型进行返回可通过类中提供的方法指定当断言失败时是否抛出一个异常默认 不抛出异常
* </p>
* <p>
* <b>编码时间</b>2020年10月20日上午7:48:05
* </p>
* <p>
* <b>修改时间</b>2020年10月20日上午7:48:05
* </p>
*
* @author 彭宇琦
* @version Ver1.0
*
*/
public class AssertEvent extends AbstractEvent {
/**
* 控制当断言失败时是否抛出一个异常
*/
boolean isThrowException = false;
/**
* 定义文本事件用于对元素的文本进行获取
*/
TextEvent textEvent;
/**
* 构造对象
*
* @param brower 浏览器{@link AbstractBrower}类对象
*/
public AssertEvent(AbstractBrower brower) {
super(brower);
// 初始化文本事件
textEvent = new TextEvent(brower);
}
/**
* 设置当前断言失败时是否抛出一个异常默认为false即不抛出异常
*
* @param isThrowException 是否抛出异常
*/
public void setThrowException(boolean isThrowException) {
this.isThrowException = isThrowException;
}
/**
* <p>
* 断言元素的文本内容中包含指定的关键词可设置元素的文本内容是否需要判断传入的所有关键词
* <ul>
* <li>当需要完全判断时则当且仅当文本包含所有关键词时断言方法返回true</li>
* <li>当不需要完全判断时则当前仅当文本不包含所有关键词时断言方法返回false</li>
* </ul>
* </p>
* <p>
* 例如,假设元素中存在文本你好世界
* <ul>
* <li>需要判断的关键词为["你好", "Java"]
* <ol>
* <li>需要判断所有文本此时断言方法返回false</li>
* <li>不需要判断所有文本此时断言方法返回true</li>
* </ol>
* </li>
* <li>需要判断的关键词为["你好", "世界"]
* <ol>
* <li>需要判断所有文本此时断言方法返回true</li>
* <li>不需要判断所有文本此时断言方法返回true</li>
* </ol>
* </li>
* <li>需要判断的关键词为["Hello", "Java"]
* <ol>
* <li>需要判断所有文本此时断言方法返回false</li>
* <li>不需要判断所有文本此时断言方法返回false</li>
* </ol>
* </li>
* </ul>
* </p>
* <p>
* <b>注意</b>若不传入关键词或关键词为null时则返回true
* </p>
*
* @param element {@link Element}对象
* @param isJudgeAllKey 是否需要完全判断所有关键词
* @param keys 关键词组
* @return 断言结果
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public boolean assertTextContainKey(Element element, boolean isJudgeAllKey, String... keys) {
//判断是否传入关键词
boolean result = true;
if (keys != null && keys.length != 0) {
result = judgetText(textEvent.getText(element), isJudgeAllKey, false, keys);
}
logText = "断言“" + element.getElementData().getName() + "”元素的文本内容包含"
+ (isJudgeAllKey ? "所有" : "部分") + "关键词" + arrayToString(keys);
resultText = String.valueOf(result);
return result;
}
/**
* <p>
* 断言元素的文本内容中不包含指定的关键词可设置元素的文本内容是否需要判断传入的所有关键词
* <ul>
* <li>当需要完全判断时则当且仅当文本不包含所有关键词时断言方法返回true</li>
* <li>当不需要完全判断时则当前仅当文本包含所有关键词时断言方法返回false</li>
* </ul>
* </p>
* <p>
* 例如,假设元素中存在文本你好世界
* <ul>
* <li>需要判断的关键词为["你好", "Java"]
* <ol>
* <li>需要判断所有文本此时断言方法返回false</li>
* <li>不需要判断所有文本此时断言方法返回true</li>
* </ol>
* </li>
* <li>需要判断的关键词为["你好", "世界"]
* <ol>
* <li>需要判断所有文本此时断言方法返回false</li>
* <li>不需要判断所有文本此时断言方法返回false</li>
* </ol>
* </li>
* <li>需要判断的关键词为["Hello", "Java"]
* <ol>
* <li>需要判断所有文本此时断言方法返回true</li>
* <li>不需要判断所有文本此时断言方法返回true</li>
* </ol>
* </li>
* </ul>
* </p>
* <p>
* <b>注意</b>若不传入关键词或关键词为null时则返回true
* </p>
*
* @param element {@link Element}对象
* @param isJudgeAllKey 是否需要完全判断所有关键词
* @param keys 关键词组
* @return 断言结果
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public boolean assertTextNotContainKey(Element element, boolean isJudgeAllKey, String... keys) {
//判断是否传入关键词
boolean result = true;
if (keys != null && keys.length != 0) {
result = judgetText(textEvent.getText(element), isJudgeAllKey, true, keys);
}
logText = "断言“" + element.getElementData().getName() + "”元素的文本内容不包含"
+ (isJudgeAllKey ? "所有" : "部分") + "关键词" + arrayToString(keys);
resultText = String.valueOf(result);
return result;
}
/**
* 断言元素的指定属性是否包含指定的关键词可设置元素的文本内容是否需要判断传入的所有关键词
* 具体参数介绍可参考{@link #assertTextContainKey(Element, boolean, String...)}方法
*
* @param element {@link Element}对象
* @param attributeName 属性名称
* @param isJudgeAllKey 是否需要完全判断所有关键词
* @param keys 关键词组
* @return 断言结果
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public boolean assertAttributeContainKey(Element element, String attributeName, boolean isJudgeAllKey,
String... keys) {
//判断是否传入关键词
boolean result = true;
if (keys != null && keys.length != 0) {
result = judgetText(textEvent.getAttributeValue(element, attributeName), isJudgeAllKey, false, keys);
}
logText = "断言“" + element.getElementData().getName() + "”元素的“" + attributeName
+ "”属性值包含"
+ (isJudgeAllKey ? "所有" : "部分") + "关键词" + arrayToString(keys);
resultText = String.valueOf(result);
return result;
}
/**
* 断言元素的文本内容中不包含指定的关键词可设置元素的文本内容是否需要判断传入的所有关键词
* 具体参数介绍可参考{@link #assertTextNotContainKey(Element, boolean, String...)}方法
*
* @param element {@link Element}对象
* @param attributeName 属性名称
* @param isJudgeAllKey 是否需要完全判断所有关键词
* @param keys 关键词组
* @return 断言结果
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public boolean assertAttributeNotContainKey(Element element, String attributeName, boolean isJudgeAllKey,
String... keys) {
//判断是否传入关键词
boolean result = true;
if (keys != null && keys.length != 0) {
result = judgetText(textEvent.getAttributeValue(element, attributeName), isJudgeAllKey, true, keys);
}
logText = "断言“" + element.getElementData().getName() + "”元素的“" + attributeName
+ "”属性值不包含"
+ (isJudgeAllKey ? "所有" : "部分") + "关键词" + arrayToString(keys);
resultText = String.valueOf(result);
return result;
}
/**
* 用于断言元素的内容与预期的文本一致
* @param element {@link Element}对象
* @param text 需要判断的文本内容
* @return 断言结果
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public boolean assertEqualsText(Element element, String text) {
//判断是否传入关键词
text = text == null ? "" : text;
boolean result = judgetText(textEvent.getText(element), true, false, text);
logText = "断言“" + element.getElementData().getName() + "”元素的文本内容为“" + text + "";
resultText = String.valueOf(result);
return result;
}
/**
* 用于断言元素的内容与传入的文本不一致
* @param element {@link Element}对象
* @param text 需要判断的文本内容
* @return 断言结果
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public boolean assertNotEqualsText(Element element, String text) {
//判断是否传入关键词
text = text == null ? "" : text;
boolean result = judgetText(textEvent.getText(element), true, true, text);
logText = "断言“" + element.getElementData().getName() + "”元素的文本内容不为“" + text + "";
resultText = String.valueOf(result);
return result;
}
/**
* 断言元素存在
* @param element {@link Element}对象
* @return 断言结果
*/
public boolean assertExistElement(Element element) {
boolean result = isExistElement(element);
logText = "断言“" + element.getElementData().getName() + "”元素存在";
resultText = String.valueOf(result);
return result;
}
/**
* 断言元素不存在
* @param element {@link Element}对象
* @return 断言结果
*/
public boolean assertNotExistElement(Element element) {
boolean result = !isExistElement(element);
logText = "断言“" + element.getElementData().getName() + "”元素不存在";
resultText = String.valueOf(result);
return result;
}
/**
* 断言元素中的数字内容与指定的数字按照{@link CompareNumberType}指定的比较类型进行比较若断言的
* 元素文本内容为非数字字符时则直接断言失败
*
* @param element {@link Element}对象
* @param compareNumberType {@link CompareNumberType}枚举类
* @param compareNumber 预期数字
* @return 断言结果
*/
public boolean assertNumber(Element element, CompareNumberType compareNumberType, double compareNumber) {
logText = "断言“" + element.getElementData().getName() + "”元素数字内容" + compareNumberType.getLogText() + compareNumber;
boolean result = false;
try {
double elementNumber = Double.valueOf(textEvent.getText(element));
//根据枚举内容返回对比结果
switch (compareNumberType) {
case EQUAL:
result = elementNumber == compareNumber;
break;
case GREATER:
result = elementNumber > compareNumber;
break;
case LESS:
result = elementNumber < compareNumber;
break;
case GREATER_OR_EQUAL:
result = elementNumber >= compareNumber;
break;
case LESS_OR_EQUAL:
result = elementNumber <= compareNumber;
break;
default:
break;
}
} catch (NumberFormatException e) {
}
resultText = String.valueOf(result);
return result;
}
/**
* 用于对文本信息与关键词进行对比
* @param text 需要判断的文本
* @param isJudgeAllKey 是否需要完全判断关键词
* @param isNot 是否为不包含关键词
* @param keys 关键词组
* @return 断言结果
*/
private boolean judgetText(String text, boolean isJudgeAllKey, boolean isNot, String... keys) {
boolean result = false;
// 循环判断keys中所有的内容
for (String key : keys) {
// 判断当前关键词是否包含于text中
if (text.contains(key)) {
// 若包含文本且不需要关键词完全包含且判断条件为需要包含文本则记录当前结果为True并结束循环
if (!isJudgeAllKey && !isNot) {
result = true;
break;
} else if (isJudgeAllKey && isNot) {
// 若包含文本且需要关键词完全包含且判断条件为不需要包含文本则记录当前结果为False并结束循环
result = false;
break;
} else if (!isJudgeAllKey && isNot) {
result = false;
continue;
} else {
result = true;
continue;
}
} else {
// 若不包含且需要关键词完全包含且判断条件为需要包含文本则记录当前结果为False并结束循环
if (isJudgeAllKey && !isNot) {
result = false;
break;
} else if (!isJudgeAllKey && isNot) {
// 若包含文本且需要关键词完全包含且判断条件为不需要包含文本则记录当前结果为False并结束循环
result = true;
break;
} else if (isJudgeAllKey && isNot) {
result = true;
continue;
} else {
result = false;
continue;
}
}
}
return result;
}
}

View File

@ -3,6 +3,7 @@ package pres.auxiliary.work.selenium.event;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
@ -35,17 +36,20 @@ public class ClickEvent extends AbstractEvent {
* 鼠标左键单击事件
*
* @param element {@link Element}对象
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public void click(Element element) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
//在指定的时间内判断是否能进行点击若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
element.getWebElement().click();
WebElement we = element.getWebElement();
//定位到元素上
locationElement(we);
we.click();
return true;
} catch (StaleElementReferenceException e) {
element.againFindElement();
@ -61,21 +65,24 @@ public class ClickEvent extends AbstractEvent {
* 鼠标左键双击事件
*
* @param element {@link Element}对象
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public void doubleClick(Element element) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
//在指定的时间内判断是否能进行点击若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
new Actions(driver).doubleClick(element.getWebElement()).perform();
WebElement we = element.getWebElement();
//定位到元素上
locationElement(we);
new Actions(driver).doubleClick(we).perform();
return true;
} catch (StaleElementReferenceException e) {
element.againFindElement();
throw e;
throw e ;
}
});
@ -86,17 +93,20 @@ public class ClickEvent extends AbstractEvent {
/**
* 鼠标右键点击事件
* @param element {@link Element}对象
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public void rightClick(Element element) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
//在指定的时间内判断是否能进行点击若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
new Actions(driver).contextClick(element.getWebElement()).perform();
WebElement we = element.getWebElement();
//定位到元素上
locationElement(we);
new Actions(driver).contextClick(we).perform();
return true;
} catch (StaleElementReferenceException e) {
element.againFindElement();
@ -113,8 +123,8 @@ public class ClickEvent extends AbstractEvent {
* @param element {@link Element}对象
* @param clickCount 点击次数
* @param sleepInMillis 操作时间间隔单位为毫秒
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public void continuousClick(Element element, int clickCount, long sleepInMillis) {
for(int i = 0; i < clickCount; i++) {

View File

@ -0,0 +1,56 @@
package pres.auxiliary.work.selenium.event;
/**
* <p><b>文件名</b>CompareNumberType.java</p>
* <p><b>用途</b>
* 用于枚举对数字比较的方式
* </p>
* <p><b>编码时间</b>2020年10月20日下午7:00:14</p>
* <p><b>修改时间</b>2020年10月20日下午7:00:14</p>
* @author 彭宇琦
* @version Ver1.0
*
*/
public enum CompareNumberType {
/**
* 等于
*/
EQUAL("等于"),
/**
* 大于
*/
GREATER("大于"),
/**
* 小于
*/
LESS("小于"),
/**
* 大于等于
*/
GREATER_OR_EQUAL("大于等于"),
/**
* 小于等于
*/
LESS_OR_EQUAL("小于等于");
/**
* 日志文本
*/
String logText;
/**
* 初始化枚举值
* @param logText 枚举值
*/
private CompareNumberType(String logText) {
this.logText = logText;
}
/**
* 返回枚举值
* @return 枚举值
*/
public String getLogText() {
return logText;
}
}

View File

@ -6,12 +6,13 @@ import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.regex.Pattern;
import org.openqa.selenium.WebDriver;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.brower.ChromeBrower;
import pres.auxiliary.work.selenium.element.AbstractBy.Element;
/**
* <p><b>文件名</b>EventProxy.java</p>
@ -28,11 +29,12 @@ import pres.auxiliary.work.selenium.brower.ChromeBrower;
* <li>方法最终通知根据方法名匹配到相应的方法后在执行事件后无论是否抛出异常执行的方法</li>
* </ol>
* 可参考以下示例
* </p>
* <p>
* 假设存在元素xpah:元素1//*[text()='登录']元素2//*[@name='account']元素3//*[@name='password']
* 在点击元素1前需要先在元素2和元素3中分别输入admin123456并且在此前定义了{@link ChromeBrower}浏览器对象变量名为
* chrome此时可以将代码写作<br>
* <pre>{@code
* <pre>
* EventProxy<ClickEvent> clickEventProxy = new EventProxy(new ClickEvent(chrome.getDriver()));
*
* clickProxy.addAcion(ActionType.ELEMENT_BEFORE, ".*登录.*", (info) -> {
@ -41,15 +43,16 @@ import pres.auxiliary.work.selenium.brower.ChromeBrower;
* text.input(by.getElement("//*[@name='password']"), "1111111");
* });
* clickEventProxy.getProxyInstance().click(new CommnBy(chrome).getElement("//*[text()='登录']"));
*
* </pre>
* </p>
* </p>
* <p><b>编码时间</b>2020年7月12日 下午1:35:22</p>
* <p><b>修改时间</b>2020年7月12日 下午1:35:22</p>
* @author 彭宇琦
* <p><b>修改时间</b>2020年10月20日下午7:54:15</p>
*
* @version Ver1.0
* @since JDK 12
* @since JDK 8
* @author 彭宇琦
*
* @param <T> 继承自{@link AbstractEvent}的事件类
*/
public class EventProxy<T extends AbstractEvent> implements MethodInterceptor {
/**
@ -81,7 +84,7 @@ public class EventProxy<T extends AbstractEvent> implements MethodInterceptor {
* 事件类对象
*/
private T target;
private WebDriver driver;
private AbstractBrower brower;
/**
* 构造代理类
@ -89,7 +92,7 @@ public class EventProxy<T extends AbstractEvent> implements MethodInterceptor {
*/
public EventProxy(T target) {
this.target = target;
driver = ((AbstractEvent) target).getDriver();
brower = ((AbstractEvent) target).getBrower();
}
/**
@ -106,7 +109,7 @@ public class EventProxy<T extends AbstractEvent> implements MethodInterceptor {
//设置回调函数
en.setCallback(this);
//创建子类(代理对象)
return (T) en.create(new Class[] {WebDriver.class}, new Object[] {driver});
return (T) en.create(new Class[] {AbstractBrower.class}, new Object[] {brower});
// return (T) en.create();
}
@ -204,9 +207,9 @@ public class EventProxy<T extends AbstractEvent> implements MethodInterceptor {
* @param actionMap 需要执行的通知
*/
private void runElementAction(EventInformation eventInformation, LinkedHashMap<String, ArrayList<EventAction>> actionMap) {
Arrays.stream(eventInformation.getParam()).filter(arg -> arg instanceof Element_Old).forEach(arg -> {
Arrays.stream(eventInformation.getParam()).filter(arg -> arg instanceof Element).forEach(arg -> {
actionMap.forEach((key, value) -> {
if (Pattern.compile(key).matcher(((Element_Old) arg).getName()).matches()) {
if (Pattern.compile(key).matcher(((Element) arg).getElementData().getName()).matches()) {
value.forEach(action -> {
try {
action.action(eventInformation);

View File

@ -5,7 +5,9 @@ import java.util.Arrays;
import java.util.UUID;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebElement;
import com.alibaba.fastjson.JSONArray;
@ -53,11 +55,13 @@ public class JsEvent extends AbstractEvent {
* @param element {@link Element}对象
* @param attributeName 属性名
* @return 元素对应属性的内容
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String getAttribute(Element element, String attributeName) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
// 获取对应元素的内容
String text = (String) (js.executeScript("return arguments[0].getAttribute('" + attributeName + "');",
wait.until(driver -> {
@ -82,10 +86,12 @@ public class JsEvent extends AbstractEvent {
* @param attributeName 需要设置的属性名
* @param value 需要设置的属性值
* @return 属性的原值
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String putAttribute(Element element, String attributeName, String value) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
// 获取原属性中的值
resultText = getAttribute(element, attributeName);
@ -111,11 +117,13 @@ public class JsEvent extends AbstractEvent {
* @param element {@link Element}对象
* @param elementName 新元素标签的名称
* @return 新增元素的定位方式
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String addElement(Element element, String elementName) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
// 获取并将其作为
String script = "var oldElement = arguments[0];";
// 拼接添加元素的代码
@ -162,13 +170,14 @@ public class JsEvent extends AbstractEvent {
* }
* </pre>
*
* @param element 元素
* @return 元素的信息
* @param element {@link Element}对象
* @return 被删除的元素信息
* @throws TimeoutException 元素无法操作时抛出的异常
*/
public JSONObject deleteElement(Element element) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
//获取元素信息
JSONObject json = getElementInfromation(wait.until(driver -> {
try {
@ -201,6 +210,7 @@ public class JsEvent extends AbstractEvent {
* @param script js脚本
* @param args 传入的参数
* @return 执行结果
* @throws TimeoutException 元素无法操作时抛出的异常
*/
public Object runScript(String script, Object... args) {
logText = "执行脚本:" + script;
@ -230,8 +240,9 @@ public class JsEvent extends AbstractEvent {
* }
* </pre>
*
* @param element 元素
* @param element {@link Element}对象
* @return 元素属性的信息以json的形式返回
* @throws TimeoutException 元素无法操作时抛出的异常
*/
@SuppressWarnings("unchecked")
private JSONObject getElementInfromation(WebElement element) {

View File

@ -48,10 +48,13 @@ public class TextEvent extends AbstractEvent {
* 文本
* @param element {@link Element}对象
* @return 被清空的文本内容
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String clear(Element element) {
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
//由于需要存储步骤若直接调用getText方法进行返回时其会更改存储的step为保证step正确故存储返回值进行返回
resultText = getText(element);
//由于在获取元素时已对元素进行相应操作等待故此处将不再重新获取
@ -66,17 +69,20 @@ public class TextEvent extends AbstractEvent {
* @param element {@link Element}对象
* @param attributeName 属性名称
* @return 对应属性的值
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String getAttributeValue(Element element, String attributeName) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
//在指定的时间内判断是否能进行操作若抛出StaleElementReferenceException异常则重新获取元素
resultText = wait.until((driver) -> {
try {
return element.getWebElement().getAttribute(attributeName);
WebElement we = element.getWebElement();
//定位到元素上
locationElement(we);
return we.getAttribute(attributeName);
} catch (StaleElementReferenceException e) {
element.againFindElement();
throw e;
@ -91,18 +97,20 @@ public class TextEvent extends AbstractEvent {
* 用于获取相应元素中的文本内容
* @param element {@link Element}对象
* @return 对应元素中的文本内容
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String getText(Element element) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
//在指定的时间内判断是否能进行操作若抛出StaleElementReferenceException异常则重新获取元素
resultText = wait.until((driver) -> {
try {
WebElement webElement = element.getWebElement();
return "input".equalsIgnoreCase(webElement.getTagName()) ? webElement.getAttribute("value") : webElement.getText();
WebElement we = element.getWebElement();
//定位到元素上
locationElement(we);
return "input".equalsIgnoreCase(we.getTagName()) ? we.getAttribute("value") : we.getText();
} catch (StaleElementReferenceException e) {
element.againFindElement();
throw e;
@ -118,15 +126,20 @@ public class TextEvent extends AbstractEvent {
* @param element {@link Element}对象
* @param text 需要输入到控件中的
* @return 在控件中输入的内容
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String input(Element element, String text) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
//在指定的时间内判断是否能进行操作若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
element.getWebElement().sendKeys(text);
WebElement we = element.getWebElement();
//定位到元素上
locationElement(we);
we.sendKeys(text);
return true;
} catch (StaleElementReferenceException e) {
element.againFindElement();
@ -148,15 +161,20 @@ public class TextEvent extends AbstractEvent {
* @param element {@link Element}对象
* @param keys 需要传入的按键可传入{@link Keys}枚举类或字符串,若传入字符串则只取字符串中第一个字母
* @return 发送按键组合每个按键间用 + 字符串连接
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String keyToSend(Element element, CharSequence... keys) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
element.getWebElement();
//在指定的时间内判断是否能进行操作若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
element.getWebElement().sendKeys(keys);
WebElement we = element.getWebElement();
//定位到元素上
locationElement(we);
we.sendKeys(keys);
return true;
} catch (StaleElementReferenceException e) {
element.againFindElement();
@ -178,7 +196,7 @@ public class TextEvent extends AbstractEvent {
});
//删除最后多余的符号
resultText = textBul.substring(0, textBul.indexOf(" + "));
resultText = textBul.substring(0, textBul.lastIndexOf(" + "));
logText = "在“" + element.getElementData().getName() + "”元素发送按键“" + resultText + "";
return resultText;
@ -192,8 +210,14 @@ public class TextEvent extends AbstractEvent {
* @param textElement 通过查找页面得到的文本框控件{@link Element}对象
* @param codeImageElement 通过查找页面得到的验证码图片控件{@link Element}对象
* @return 输入的内容
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String codeInput(Element textElement, Element codeImageElement) {
//由于在until()方法中无法直接抛出元素不存在的异常故此处直接调用返回元素的方法让元素不存在的异常抛出
codeImageElement.getWebElement();
textElement.getWebElement();
// 判断验证码信息是否加载加载后获取其Rectang对象
Rectangle r = codeImageElement.getWebElement().getRect();
// 构造截图对象并创建截图
@ -231,6 +255,8 @@ public class TextEvent extends AbstractEvent {
* @param textElements 通过查找页面得到的一组控件元素对象
* @return 由于涉及到多个文本框故其返回值有多个将以值1,值2,值3...的形式进行返回
* @deprecated 当前方法有些BUG请勿调用下个版本修复
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
@Deprecated
public String avgIntergeInput(int num, Element... elements) {
@ -278,6 +304,8 @@ public class TextEvent extends AbstractEvent {
* @param element {@link Element}对象
* @param updataFile 需要上传到控件中的文件
* @return 上传的文件路径
* @throws TimeoutException 元素无法操作时抛出的异常
* @throws NoSuchElementException 元素不存在或下标不正确时抛出的异常
*/
public String updataFile(Element element, File updataFile) {
resultText = input(element, updataFile.getAbsolutePath());

View File

@ -2,16 +2,31 @@ package pres.auxiliary.work.selenium.event;
import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.AbstractBy.Element;
/**
* <p><b>文件名</b>WaitEvent.java</p>
* <p><b>用途</b>
* 定义了对元素进行特殊事件等待的方法包括等待控件消失等待控件出现文字等
* 可通过该类等待元素进行一定的变化的操作
* </p>
* <p><b>编码时间</b>2020年10月19日上午7:21:05</p>
* <p><b>修改时间</b>2020年10月19日上午7:21:05</p>
* @author
* @version Ver1.0
*
*/
public class WaitEvent extends AbstractEvent{
/**
* 控制等待
*/
private WebDriverWait wait;
private WebDriverWait eventWait;
/**
* 构造对象
@ -29,8 +44,8 @@ public class WaitEvent extends AbstractEvent{
*/
public WaitEvent(AbstractBrower brower, long waitTime) {
super(brower);
wait = new WebDriverWait(brower.getDriver(), waitTime, 200);
wait.withMessage("等待超时,事件等待失败" + waitTime + "");
eventWait = new WebDriverWait(brower.getDriver(), waitTime, 200);
eventWait.withMessage("等待超时,事件等待失败,超时时间" + waitTime + "");
}
/**
@ -38,26 +53,122 @@ public class WaitEvent extends AbstractEvent{
* @param overtime 超时时间
*/
public void setOvertime(long overtime) {
wait.pollingEvery(Duration.ofSeconds(overtime));
eventWait.pollingEvery(Duration.ofSeconds(overtime < 0 ? 60L : overtime));
}
/**
* 用于等待元素消失
* @param waitElement 需要等待的元素
*/
public void disappear(Element_Old waitElement) {
wait.until(driver -> {
return !waitElement.getWebElement().isDisplayed();
* 用于等待元素消失若元素无法获取到则也判定为元素不存在
* @param element {@link Element}对象
* @return 元素是否已消失
* @throws TimeoutException 等待超时时抛出的异常
*/
public boolean disappear(Element element) {
eventWait.withMessage("等待超时,元素“" + element.getElementData().getName() +"”仍然存在,超时时间:" + waitTime + "");
boolean result = eventWait.until(driver -> {
//调用isDisplayed()方法判断元素是否存在
try {
return !element.getWebElement().isDisplayed();
} catch (NoSuchElementException e) {
//若在调用获取页面元素时抛出NoSuchElementException异常则说明元素本身不存在则直接返回true
return true;
} catch (StaleElementReferenceException e) {
//若抛出StaleElementReferenceException异常则说明页面过期重新获取元素后再进行判断
element.againFindElement();
return false;
}
});
logText = "等待“" + element.getElementData().getName() + "”元素从页面消失";
resultText = String.valueOf(result);
return result;
}
/**
* 用于等待元素元素内出现文本
* @param waitElement 需要等待的元素
*/
public void showText(Element_Old waitElement) {
wait.until(driver -> {
return !new TextEvent(driver).getText(waitElement).isEmpty();
* 该方法用于根据元素信息在元素被加载后等待元素在页面中出现并返回元素出现的结果
* 注意等待元素出现的超时时间与元素中设置的超时时间一致与类中超时时间无关
* @param element {@link Element}对象
* @return 元素是否出现
* @throws TimeoutException 等待超时时抛出的异常
*/
public boolean appear(Element element) {
eventWait.withMessage("等待超时,元素“" + element.getElementData().getName() +"”仍然不存在,超时时间:" + waitTime + "");
boolean result = eventWait.until(driver -> {
//调用isDisplayed()方法判断元素是否存在
try {
return element.getWebElement().isDisplayed();
} catch (StaleElementReferenceException | NoSuchElementException e) {
//若抛出StaleElementReferenceException异常则说明页面过期重新获取元素后再进行判断
//若抛出NoSuchElementException异常则说明当前元素不存在则再重新进行一次获取
element.againFindElement();
return false;
}
});
logText = "等待“" + element.getElementData().getName() + "”元素从页面消失";
resultText = String.valueOf(result);
return result;
}
/**
* 该方法用于等待指定元素中显示相应的文本可指定显示文本的关键词直到显示相应的关键词为止
* 若不传入关键词则只判断元素加载出文本若元素未出现则返回false
* @param element {@link Element}对象
* @return 元素是否存在文本或包含指定文本
* @throws TimeoutException 等待超时时抛出的异常
*/
public boolean showText(Element element, String...keys) {
//判断是否传入关键词数组根据是否传入数组调用不同的判断方式
if (keys == null || keys.length == 0) {
logText = "等待“" + element.getElementData().getName() + "”元素加载出文本内容";
//判断元素是否存在若不存在则直接返回false
if (isExistElement(element)) {
resultText = Boolean.toString(false);
return false;
} else {
eventWait.withMessage("等待超时,元素“" + element.getElementData().getName() +"”仍未出现文本,超时时间:" + waitTime + "");
TextEvent textEvent = new TextEvent(brower);
boolean result = eventWait.until(driver -> {
//调用isDisplayed()方法判断元素是否存在
try {
return !textEvent.getText(element).isEmpty();
} catch (StaleElementReferenceException e) {
//若抛出StaleElementReferenceException异常则说明页面过期重新获取元素后再进行判断
element.againFindElement();
return false;
}
});
resultText = String.valueOf(result);
return result;
}
} else {
String keyText = arrayToString(keys);
logText = "等待“" + element.getElementData().getName() + "”元素出现文本关键词:" + keyText;
//判断元素是否存在若不存在则直接返回false
if (isExistElement(element)) {
resultText = Boolean.toString(false);
return false;
} else {
eventWait.withMessage("等待超时,元素“" + element.getElementData().getName() +"”仍未出现关键词“" + keyText + "”,超时时间:" + waitTime + "");
AssertEvent assertEvent = new AssertEvent(brower);
boolean result = eventWait.until(driver -> {
//断言方法直到方法返回true为止
try {
return assertEvent.assertTextContainKey(element, true, keys);
} catch (StaleElementReferenceException e) {
//若抛出StaleElementReferenceException异常则说明页面过期重新获取元素后再进行判断
element.againFindElement();
return false;
}
});
resultText = String.valueOf(result);
return result;
}
}
}
}