添加TestNG数据驱动类及相应的单元测试类
This commit is contained in:
parent
f901f1b5e4
commit
4739333623
19
.classpath
19
.classpath
|
@ -6,19 +6,7 @@
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
<classpathentry kind="src" path="src/test/java"/>
|
||||||
<attributes>
|
|
||||||
<attribute name="test" value="true"/>
|
|
||||||
<attribute name="optional" value="true"/>
|
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-12">
|
|
||||||
<attributes>
|
|
||||||
<attribute name="module" value="true"/>
|
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
@ -27,5 +15,10 @@
|
||||||
<classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
|
<classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||||
<classpathentry kind="lib" path="lib/beautyeye_lnf.jar"/>
|
<classpathentry kind="lib" path="lib/beautyeye_lnf.jar"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
<classpathentry kind="output" path="target/classes"/>
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
encoding//src/main/java=UTF-8
|
encoding//src/main/java=UTF-8
|
||||||
encoding//src/test/java=UTF-8
|
encoding//src/test/java=UTF-8
|
||||||
|
encoding//src/test/java/pres/auxiliary/work/selenium/datadriven/Test.txt=GBK
|
||||||
encoding/<project>=UTF-8
|
encoding/<project>=UTF-8
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=12
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||||
org.eclipse.jdt.core.compiler.compliance=12
|
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||||
org.eclipse.jdt.core.compiler.release=enabled
|
org.eclipse.jdt.core.compiler.release=disabled
|
||||||
org.eclipse.jdt.core.compiler.source=12
|
org.eclipse.jdt.core.compiler.source=1.8
|
||||||
|
|
Binary file not shown.
|
@ -1,253 +0,0 @@
|
||||||
package pres.auxiliary.selenium.browers;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>AbstractBrower.java</p>
|
|
||||||
* <p><b>用途:</b>该类定义启动浏览器时必要的方法以及打开浏览器,创建WebDriver对象的操作,由新添加的各个浏览器子类可进行继承</p>
|
|
||||||
* <p><b>编码时间:</b>2020年4月6日 下午3:01:06</p>
|
|
||||||
* <p><b>修改时间:</b>2020年4月6日 下午3:01:06</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
* @since selenium 3.0.0
|
|
||||||
*/
|
|
||||||
public abstract class AbstractBrower {
|
|
||||||
/**
|
|
||||||
* 用于接收用户需要进入的网站
|
|
||||||
*/
|
|
||||||
private String url = "";
|
|
||||||
/**
|
|
||||||
* 用于接收浏览器启动所需的文件路径
|
|
||||||
*/
|
|
||||||
private String browserRunPath = "";
|
|
||||||
/**
|
|
||||||
* 存储页面加载等待时间
|
|
||||||
*/
|
|
||||||
private int loadTime = 120;
|
|
||||||
/**
|
|
||||||
* 用于存储目标站点的title
|
|
||||||
*/
|
|
||||||
private StringBuilder pageTitle = new StringBuilder("");
|
|
||||||
/**
|
|
||||||
* 用于存储页面自动刷新的次数,默认为0次
|
|
||||||
*/
|
|
||||||
private int rafreshCount = 0;
|
|
||||||
/**
|
|
||||||
* 用于存储获取到的浏览器对象
|
|
||||||
*/
|
|
||||||
WebDriver driver = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回待链接的站点
|
|
||||||
*
|
|
||||||
* @return 返回待链接的站点
|
|
||||||
*/
|
|
||||||
public String getURL() {
|
|
||||||
return url.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置待链接的站点
|
|
||||||
*
|
|
||||||
* @param uRL
|
|
||||||
* 待链接的站点
|
|
||||||
*/
|
|
||||||
public void setURL(String uRL) {
|
|
||||||
//判断待测站点是否有发生改变,若未发生改变,则不重新设置
|
|
||||||
if (!url.equalsIgnoreCase(uRL)) {
|
|
||||||
// 由于改变了浏览器的条件,故初始化driver变量,以便于重新打开浏览器
|
|
||||||
driver = null;
|
|
||||||
url = uRL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回浏览器的启动路径。对于火狐则为浏览器可执行文件所在路径,对于谷歌浏览器即浏览器驱动所在路径。
|
|
||||||
*
|
|
||||||
* @return 浏览器的启动路径
|
|
||||||
*/
|
|
||||||
public String getBrowserRunPath() {
|
|
||||||
return browserRunPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于设置浏览器的启动路径。对于火狐则为浏览器可执行文件所在路径,对于谷歌浏览器即浏览器驱动所在路径。
|
|
||||||
*
|
|
||||||
* @param startBrowserPath
|
|
||||||
* 浏览器的启动路径
|
|
||||||
*/
|
|
||||||
public void setBrowserRunPath(String browserRunPath) {
|
|
||||||
//判断待测站点是否有发生改变,若未发生改变,则不重新设置
|
|
||||||
if (!this.browserRunPath.equalsIgnoreCase(browserRunPath)) {
|
|
||||||
// 由于改变了浏览器的条件,故初始化driver变量,以便于重新打开浏览器
|
|
||||||
driver = null;
|
|
||||||
this.browserRunPath = browserRunPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回设置的目标站点的title
|
|
||||||
*
|
|
||||||
* @return 返回设置的目标站点的title
|
|
||||||
*/
|
|
||||||
public String getPageTitle() {
|
|
||||||
return pageTitle.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置目标站点的title,以便进行链接是否正确的判断
|
|
||||||
*
|
|
||||||
* @param pageTitle
|
|
||||||
* 设置的目标站点title
|
|
||||||
*/
|
|
||||||
public void setPageTitle(String pageTitle) {
|
|
||||||
this.pageTitle.delete(0, this.pageTitle.length());
|
|
||||||
this.pageTitle.append(pageTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回设置的页面等待时间,默认时间为120秒
|
|
||||||
*
|
|
||||||
* @return 返回页面等待时间
|
|
||||||
*/
|
|
||||||
public int getLoadTime() {
|
|
||||||
return loadTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置页面等待时间,整形,单位为秒
|
|
||||||
*
|
|
||||||
* @param LoadTime
|
|
||||||
* 传入的时间
|
|
||||||
*/
|
|
||||||
public void setLoadTime(int loadTime) {
|
|
||||||
this.loadTime = loadTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回自动刷新的次数,默认为0次
|
|
||||||
*
|
|
||||||
* @return 返回自动刷新的次数
|
|
||||||
*/
|
|
||||||
public int getRafreshCount() {
|
|
||||||
return rafreshCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置页面的自动刷新次数,当设置该值后则开启自动刷新
|
|
||||||
*
|
|
||||||
* @param rafreshCount
|
|
||||||
* 自动刷新的次数
|
|
||||||
*/
|
|
||||||
public void setRafreshCount(int rafreshCount) {
|
|
||||||
this.rafreshCount = rafreshCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于启动浏览器,并返回WebDriver对象
|
|
||||||
*
|
|
||||||
* @return 指向浏览器的WebDriver对象
|
|
||||||
*/
|
|
||||||
public abstract WebDriver getDriver();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取浏览器的名称
|
|
||||||
*
|
|
||||||
* @return 浏览器名称
|
|
||||||
*/
|
|
||||||
public abstract String getBrowerName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取浏览器版本
|
|
||||||
*
|
|
||||||
* @return 浏览器版本
|
|
||||||
*/
|
|
||||||
public abstract String getBrowerVersion();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取操作系统信息
|
|
||||||
*
|
|
||||||
* @return 操作系统信息
|
|
||||||
*/
|
|
||||||
public abstract String getSystemInformation();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于初始化浏览器
|
|
||||||
*/
|
|
||||||
public WebDriver initialization() {
|
|
||||||
driver.close();
|
|
||||||
driver = null;
|
|
||||||
return getDriver();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于关闭浏览器
|
|
||||||
*/
|
|
||||||
public void close() {
|
|
||||||
driver.quit();
|
|
||||||
driver = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于对浏览器的一系列操作,包括全屏浏览器,跳转相应的站点,等待页面加载以及自动刷新,
|
|
||||||
* 使用该方法时会抛出两个运行时异常,分别为IncorrectPageTitleException和PageNotFoundException
|
|
||||||
*
|
|
||||||
* @param driver
|
|
||||||
* 通过start()方法创建的WebDriver对象
|
|
||||||
* @return 返回对浏览器进行操作后的得到的WebDriver对象
|
|
||||||
* @throws IncorrectPageTitleException
|
|
||||||
* 页面title与设置的title不一致时抛出的异常
|
|
||||||
* @throws PageNotFoundException
|
|
||||||
* 页面加载失败时抛出的异常
|
|
||||||
*/
|
|
||||||
protected WebDriver oprateBrower(WebDriver driver) {
|
|
||||||
// 将设置的自动刷新次数存储在临时变量中,并加上1
|
|
||||||
// 加1的目的是自动刷新判断是用do...while循环实现,若不事先加上1在会导致循环少1次
|
|
||||||
int rafresh = rafreshCount + 1;
|
|
||||||
|
|
||||||
String errorTitle = "页面载入出错";
|
|
||||||
|
|
||||||
// 进入站点
|
|
||||||
driver.get(url);
|
|
||||||
// 全屏浏览器
|
|
||||||
driver.manage().window().maximize();
|
|
||||||
|
|
||||||
// 循环执行页面加载判断,判断其是否加载出目标站点,若加载出来页面,则结束循环,若用户设置的自动刷新次数循环完还没加载出页面,则
|
|
||||||
// 抛出PageNotFoundException异常。页面加载判断必须读取一次,所以使用do...while循环
|
|
||||||
do {
|
|
||||||
// 读取并设置浏览器等待时间
|
|
||||||
driver.manage().timeouts().pageLoadTimeout(loadTime, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
// 判断进入站点后页面的title是否为“页面载入出错”,若为该title,则刷新页面,重新加载
|
|
||||||
// 注意,在火狐浏览器中凡是加载不出的页面,其页面title都是“页面载入出错”,所以该方法只适用于火狐浏览器
|
|
||||||
if (errorTitle.equals(driver.getTitle())) {
|
|
||||||
// 将刷新次数减1
|
|
||||||
rafresh--;
|
|
||||||
// 刷新网页
|
|
||||||
driver.navigate().refresh();
|
|
||||||
// 不执行后续代码,继续循环
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 若页面加载成功,则判断加载的页面是否与用户设置的一致,若用户未设置目标站点的title,则跳过判断
|
|
||||||
// 判断pageTitle中存储的信息是否为空,若不为空则再判断页面的title是否与设置的title一致,若不一致,则抛出IncorrectPageTileException
|
|
||||||
if (!pageTitle.toString().equals("") && !driver.getTitle().equals(pageTitle.toString())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 若页面能正常加载,置空pageTitle并返回WebDriver对象
|
|
||||||
pageTitle.delete(0, pageTitle.length());
|
|
||||||
return driver;
|
|
||||||
|
|
||||||
// 判断的条件刷新次数rafresh为0时则结束循环
|
|
||||||
} while (rafresh != 0);
|
|
||||||
|
|
||||||
// 若循环结束,则说明页面无法正常加载,则置空pageTitle,抛出PageNotFountException
|
|
||||||
pageTitle.delete(0, pageTitle.length());
|
|
||||||
throw new IncorrectPageTitleException("页面载入出错");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,153 +0,0 @@
|
||||||
package pres.auxiliary.selenium.browers;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.chrome.ChromeDriver;
|
|
||||||
import org.openqa.selenium.chrome.ChromeOptions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ChromeBrower.java</p>
|
|
||||||
* <p><b>用途:</b>
|
|
||||||
* 该类用于启动谷歌浏览器,并通过getDriver()方法获取当前浏览器的WebDriver对象。调用本类时可通过
|
|
||||||
* set方法设置chromedriver的所在路径、待测试的站点,也可通过构造方法进行设置,亦可通过在
|
|
||||||
* getDriver()方法直接设置参数以达到启动浏览器的目的。
|
|
||||||
* </p>
|
|
||||||
* <p><b>修改时间:</b>2019年6月5日下午4:24:23</p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since Selenium 2.53.0
|
|
||||||
* @since JDK 1.7
|
|
||||||
*/
|
|
||||||
public class ChromeBrower extends AbstractBrower {
|
|
||||||
/**
|
|
||||||
* 定义ChromeOptions类,当需要控制已打开的浏览器时,则定义该类
|
|
||||||
* */
|
|
||||||
ChromeOptions cp = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 双参构造,用于设置谷歌浏览器启动驱动路径及待测试的站点,并创建对象
|
|
||||||
*
|
|
||||||
* @param driverPath
|
|
||||||
* 谷歌浏览器启动驱动路径
|
|
||||||
* @param url
|
|
||||||
* 待测试的站点
|
|
||||||
*/
|
|
||||||
public ChromeBrower(String driverPath, String url) {
|
|
||||||
setBrowserRunPath(driverPath);
|
|
||||||
setURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该构造用于使用已打开的浏览器,对浏览器进行操作
|
|
||||||
* @param port 端口号
|
|
||||||
*/
|
|
||||||
public ChromeBrower(String driverPath, int port) {
|
|
||||||
setBrowserRunPath(driverPath);
|
|
||||||
//构造ChromeOptions类,设置传入的浏览器打开的端口号
|
|
||||||
cp = new ChromeOptions();
|
|
||||||
cp.setExperimentalOption("debuggerAddress", "127.0.0.1:" + port);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBrowerName() {
|
|
||||||
return ((ChromeDriver) driver).getCapabilities().getBrowserName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBrowerVersion() {
|
|
||||||
return ((ChromeDriver) driver).getCapabilities().getVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSystemInformation() {
|
|
||||||
String s = ((ChromeDriver) driver).getCapabilities().getPlatform().name();
|
|
||||||
s += ((ChromeDriver) driver).getCapabilities().getPlatform().getMajorVersion();
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
//若是控制已打开的浏览器时,其quit()方法无法关闭浏览器,故需要用close()方法来关闭
|
|
||||||
if (cp == null) {
|
|
||||||
driver.quit();
|
|
||||||
driver = null;
|
|
||||||
} else {
|
|
||||||
driver.close();
|
|
||||||
driver = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置需要控制的已打开的浏览器端口<br>
|
|
||||||
* <b>注意,为了安全,调用该方法时,会将传入的url(待测站点)值清空</b>
|
|
||||||
* @param port 端口
|
|
||||||
*/
|
|
||||||
public void setPort(int port) {
|
|
||||||
//构造ChromeOptions类,设置传入的浏览器打开的端口号
|
|
||||||
cp = new ChromeOptions();
|
|
||||||
cp.setExperimentalOption("debuggerAddress", "127.0.0.1:" + port);
|
|
||||||
//将WebDriver对象置空,以便于重新制定WebDriver对象
|
|
||||||
driver = null;
|
|
||||||
//将待测站点的信息也置空
|
|
||||||
setURL("");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于解除对已打开的浏览器的控制,调用该方法后重新获取的WebDriver对象将重新打开浏览器
|
|
||||||
*/
|
|
||||||
public void removeControl() {
|
|
||||||
cp = null;
|
|
||||||
driver = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法通过类中的属性打开浏览器,跳转相应的站点,并创建WebDriver对象。使用前需要通过类中的set()方法为属性进行赋值。
|
|
||||||
* 在运行过程中可能会抛出两个运行时异常,分别为IncorrectPageTitleException和PageNotFoundException <br/>
|
|
||||||
* <b><i>注意,若未传入目标站点或者目标站点为空,则返回null</i></b>
|
|
||||||
*
|
|
||||||
* @return 返回浏览器的WebDriver对象
|
|
||||||
* @throws IncorrectPageTitleException
|
|
||||||
* 页面title与设置的title不一致时抛出的异常
|
|
||||||
* @throws PageNotFoundException
|
|
||||||
* 页面加载失败时抛出的异常
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public WebDriver getDriver() {
|
|
||||||
// 判断类中的driver是否为null,不为null,则直接返回
|
|
||||||
if (driver != null) {
|
|
||||||
return driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断传入的站点信息是否为空,若为空,则返回null
|
|
||||||
if ("".equals(getURL()) && cp == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断是否存在谷歌浏览器启动驱动的安装路径,若存在,则添加谷歌浏览器启动驱动启动路径,若不存在,则抛出ChromedriverNotFoundException异常
|
|
||||||
if (!"".equals(getBrowserRunPath())) {
|
|
||||||
System.setProperty("webdriver.chrome.driver", getBrowserRunPath());
|
|
||||||
} else {
|
|
||||||
throw new ChromedriverNotFoundException("chromedriver文件没有找到");
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断当前是否通过已打开的浏览器来进行测试
|
|
||||||
if (cp != null) {
|
|
||||||
//通过已打开的浏览器参数来创建WebDiver对象
|
|
||||||
driver = new ChromeDriver(cp);
|
|
||||||
//判断当前是否有传入url,若url为空,则不改变页面的url,若url不为空,则进行更改
|
|
||||||
if (!"".equals(getURL())) {
|
|
||||||
//获取并判断浏览器当前站点是否与传入的站点一致,若不一致,则改变url
|
|
||||||
if (!getURL().equalsIgnoreCase(driver.getCurrentUrl())) {
|
|
||||||
driver.get(getURL());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return driver;
|
|
||||||
} else {
|
|
||||||
// 创造WebDriver对象
|
|
||||||
driver = new ChromeDriver();
|
|
||||||
// 调用OprateBrower()方法并返回其操作后的WebDriver对象
|
|
||||||
return oprateBrower(driver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package pres.auxiliary.selenium.browers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该异常在没有找到Chromedriver路径时抛出的异常,继承于RuntimeException
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
*/
|
|
||||||
public class ChromedriverNotFoundException extends RuntimeException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public ChromedriverNotFoundException() {
|
|
||||||
super();
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChromedriverNotFoundException(String message, Throwable cause,
|
|
||||||
boolean enableSuppression, boolean writableStackTrace) {
|
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChromedriverNotFoundException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChromedriverNotFoundException(String message) {
|
|
||||||
super(message);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChromedriverNotFoundException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
package pres.auxiliary.selenium.browers;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebDriverException;
|
|
||||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该类用于启动火狐浏览器,并通过getDriver()方法获取当前浏览器的WebDriver对象。调用本类时可通过
|
|
||||||
* set方法设置火狐浏览器的启动路径、待测试的站点和配置文件的位置,也可通过构造方法进行设置,亦可通过在
|
|
||||||
* getDriver()方法直接设置参数以达到启动浏览器的目的。
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since Selenium 2.53.0
|
|
||||||
* @since JDK 1.7
|
|
||||||
*/
|
|
||||||
public class FirefoxBrower extends AbstractBrower {
|
|
||||||
// 存储配制文件名称
|
|
||||||
private String settingName = "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 单参构造,用于设置待测试的站点,并创建对象
|
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
* 待测试的站点
|
|
||||||
*/
|
|
||||||
public FirefoxBrower(String url) {
|
|
||||||
setURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 双参构造,用于设置火狐浏览器安装路径及待测试的站点,并创建对象
|
|
||||||
*
|
|
||||||
* @param firefoxPath
|
|
||||||
* 火狐浏览器的安装路径
|
|
||||||
* @param url
|
|
||||||
* 待测试的站点
|
|
||||||
*/
|
|
||||||
public FirefoxBrower(String firefoxPath, String url) {
|
|
||||||
setBrowserRunPath(firefoxPath);
|
|
||||||
setURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 叁参构造,用于设置火狐浏览器安装路径及待测试的站点,并创建对象
|
|
||||||
*
|
|
||||||
* @param firefoxPath
|
|
||||||
* 火狐浏览器的安装路径
|
|
||||||
* @param settingName
|
|
||||||
* 配置文件名称
|
|
||||||
* @param uRL
|
|
||||||
* 待测试的站点
|
|
||||||
*/
|
|
||||||
public FirefoxBrower(String firefoxPath, String settingName, String url) {
|
|
||||||
setBrowserRunPath(firefoxPath);
|
|
||||||
setSettingName(settingName);
|
|
||||||
setURL(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回火狐浏览器配置文件的文件名
|
|
||||||
*
|
|
||||||
* @return 返回火狐浏览器配置文件的文件名
|
|
||||||
*/
|
|
||||||
public String getSettingName() {
|
|
||||||
return settingName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置火狐浏览器配置文件的文件名
|
|
||||||
*
|
|
||||||
* @param settingName
|
|
||||||
* 配置文件的文件名
|
|
||||||
*/
|
|
||||||
public void setSettingName(String settingName) {
|
|
||||||
//若配置文件名未改变,则不重新赋值
|
|
||||||
if ( !this.settingName.equalsIgnoreCase(settingName) ) {
|
|
||||||
// 由于改变了浏览器的条件,故初始化driver变量,以便于重新打开浏览器
|
|
||||||
driver = null;
|
|
||||||
this.settingName = settingName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBrowerName() {
|
|
||||||
return ((FirefoxDriver) driver).getCapabilities().getBrowserName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getBrowerVersion() {
|
|
||||||
return ((FirefoxDriver) driver).getCapabilities().getVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getSystemInformation() {
|
|
||||||
String s = ((FirefoxDriver) driver).getCapabilities().getPlatform().name();
|
|
||||||
s += ((FirefoxDriver) driver).getCapabilities().getPlatform().getMajorVersion();
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法通过类中的属性打开浏览器,跳转相应的站点,并创建WebDriver对象。使用前需要通过类中的set()方法为属性进行赋值。
|
|
||||||
* 在运行过程中可能会抛出两个运行时异常,分别为IncorrectPageTitleException和PageNotFoundException <br/>
|
|
||||||
* <b><i>注意,若未传入目标站点或者目标站点为空,则返回null</i></b>
|
|
||||||
*
|
|
||||||
* @return 返回浏览器的WebDriver对象
|
|
||||||
* @throws IncorrectPageTitleException
|
|
||||||
* 页面title与设置的title不一致时抛出的异常
|
|
||||||
* @throws PageNotFoundException
|
|
||||||
* 页面加载失败时抛出的异常
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public WebDriver getDriver() {
|
|
||||||
// 判断类中的driver是否为null,不为null,则直接返回
|
|
||||||
if (driver != null) {
|
|
||||||
return driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断传入的站点信息是否为空,若为空,则返回null
|
|
||||||
if ("".equals(getURL())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断是否存在火狐的安装路径,若存在,则添加火狐启动路径
|
|
||||||
if (!"".equals(getBrowserRunPath())) {
|
|
||||||
System.setProperty("webdriver.firefox.bin", getBrowserRunPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断火狐的配置文件名是否为空,若不为空,则通过配置文件创建webdriver对象,若为空,则不使用配置文件创建对象
|
|
||||||
if (!"".equals(settingName)) {
|
|
||||||
// 通过配置文件,创建webdriver对象,并启动浏览器
|
|
||||||
//driver = new FirefoxDriver(new ProfilesIni().getProfile(settingName.toString()));
|
|
||||||
} else {
|
|
||||||
// 通过默认方式创建webdriver对象,并启动浏览器
|
|
||||||
// 在创建对象时若火狐的路径不正确,则会抛出WebDriverException异常,捕捉该异常后再抛出FirefoxPathNotFountException的异常
|
|
||||||
try {
|
|
||||||
driver = new FirefoxDriver();
|
|
||||||
} catch (WebDriverException e) {
|
|
||||||
throw new FirefoxPathNotFoundException("指定的火狐浏览器安装路径不正确");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调用OprateBrower()方法并返回其操作后的WebDriver对象
|
|
||||||
return oprateBrower(driver);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package pres.auxiliary.selenium.browers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该异常在没有找到火狐路径时抛出的异常,继承于RuntimeException
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
*/
|
|
||||||
public class FirefoxPathNotFoundException extends RuntimeException {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public FirefoxPathNotFoundException() {
|
|
||||||
super();
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public FirefoxPathNotFoundException(String message, Throwable cause, boolean enableSuppression,
|
|
||||||
boolean writableStackTrace) {
|
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public FirefoxPathNotFoundException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public FirefoxPathNotFoundException(String message) {
|
|
||||||
super(message);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public FirefoxPathNotFoundException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package pres.auxiliary.selenium.browers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该异常在目标站点Title与设置的目标站点Title不一致的情况下抛出的异常,继承于RuntimeException
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
*/
|
|
||||||
public class IncorrectPageTitleException extends RuntimeException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public IncorrectPageTitleException() {
|
|
||||||
super();
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectPageTitleException(String message, Throwable cause, boolean enableSuppression,
|
|
||||||
boolean writableStackTrace) {
|
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectPageTitleException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectPageTitleException(String message) {
|
|
||||||
super(message);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectPageTitleException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package pres.auxiliary.selenium.browers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该异常为在页面无法加载出来时抛出的异常,继承于RuntimeException
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
*/
|
|
||||||
public class PageNotFoundException extends RuntimeException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public PageNotFoundException() {
|
|
||||||
super();
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageNotFoundException(String message, Throwable cause, boolean enableSuppression,
|
|
||||||
boolean writableStackTrace) {
|
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageNotFoundException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageNotFoundException(String message) {
|
|
||||||
super(message);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public PageNotFoundException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,602 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.dom4j.InvalidXPathException;
|
|
||||||
import org.openqa.selenium.By;
|
|
||||||
import org.openqa.selenium.JavascriptExecutor;
|
|
||||||
import org.openqa.selenium.StaleElementReferenceException;
|
|
||||||
import org.openqa.selenium.TimeoutException;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebDriverException;
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
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.ByType;
|
|
||||||
import pres.auxiliary.selenium.xml.ReadXml;
|
|
||||||
import pres.auxiliary.selenium.xml.UndefinedElementException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>AbstractEvent.java</p>
|
|
||||||
* <p><b>用途:</b>所有事件类的基类,包含了事件类所用到的基础方法以及弹窗处理方法和窗体、窗口的切换方法</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月24日下午4:24:15</p>
|
|
||||||
* <p><b>修改时间:</b>2019年11月29日上午9:53:37</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class AbstractEvent {
|
|
||||||
/**
|
|
||||||
* 用于存储浏览器的WebDriver对象,设为静态,保证所有的子类只使用一个WebDriver对象,以避免造成WebDriver不正确导致的Bug
|
|
||||||
*/
|
|
||||||
private static WebDriver driver;
|
|
||||||
/**
|
|
||||||
* 用于指向存储控件定位方式的xml文件
|
|
||||||
*/
|
|
||||||
private static ReadXml xml;
|
|
||||||
/**
|
|
||||||
* 设置显示等待的超时时间(默认3秒)
|
|
||||||
*/
|
|
||||||
private long waitTime = 3;
|
|
||||||
/**
|
|
||||||
* 用于构造显示等待类对象
|
|
||||||
*/
|
|
||||||
private WebDriverWait wait;
|
|
||||||
/**
|
|
||||||
* 存储单个控件的等待时间
|
|
||||||
*/
|
|
||||||
private HashMap<String, Long> controlWaitTime = new HashMap<String, Long>();
|
|
||||||
/**
|
|
||||||
* 用于存储当前浏览器窗口的Handles值
|
|
||||||
*/
|
|
||||||
private String browserHandles;
|
|
||||||
/**
|
|
||||||
* 存储当前定位的窗体层级
|
|
||||||
*/
|
|
||||||
private static ArrayList<String> iframeNames = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 控制是否自动切换窗体,由于通过Event类调用时会构造另一个事件类,但每个类都应共享一个开关,故需要加上static
|
|
||||||
*/
|
|
||||||
private static boolean switchIframe = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于存储上一个获取到的元素
|
|
||||||
*/
|
|
||||||
private WebElement oldElement = null;
|
|
||||||
/**
|
|
||||||
* 用于存储上一个获取到的元素的style属性
|
|
||||||
*/
|
|
||||||
private String oldElementStyle = "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回是否自动切换窗体
|
|
||||||
* @return 是否自动切换窗体
|
|
||||||
*/
|
|
||||||
public boolean isSwitchIframe() {
|
|
||||||
return switchIframe;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置是否自动切换窗体
|
|
||||||
* @param switchIframe 是否自动切换窗体
|
|
||||||
*/
|
|
||||||
public void setSwitchIframe(boolean switchIframe) {
|
|
||||||
this.switchIframe = switchIframe;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造对象并存储浏览器的WebDriver对象
|
|
||||||
*
|
|
||||||
* @param driver 浏览器的WebDriver对象
|
|
||||||
*/
|
|
||||||
public AbstractEvent(WebDriver driver) {
|
|
||||||
this.driver = driver;
|
|
||||||
browserHandles = this.driver.getWindowHandle();
|
|
||||||
wait = new WebDriverWait(driver, waitTime, EventConstants.FIND_TIME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回等待时间
|
|
||||||
*
|
|
||||||
* @return 等待时间
|
|
||||||
*/
|
|
||||||
public long getWaitTime() {
|
|
||||||
return waitTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于设置等待时间
|
|
||||||
*
|
|
||||||
* @param waitTime 等待时间
|
|
||||||
*/
|
|
||||||
public void setWaitTime(long waitTime) {
|
|
||||||
this.waitTime = waitTime;
|
|
||||||
wait = new WebDriverWait(driver, this.waitTime, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回浏览器的WebDriver对象
|
|
||||||
*
|
|
||||||
* @return 浏览器的WebDriver对象
|
|
||||||
*/
|
|
||||||
public WebDriver getDriver() {
|
|
||||||
return driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置浏览器的WebDriver对象
|
|
||||||
*
|
|
||||||
* @param driver 浏览器的WebDriver对象
|
|
||||||
*/
|
|
||||||
public void setDriver(WebDriver driver) {
|
|
||||||
// 判断传入WebDriver对象是否为空,为空则抛出异常
|
|
||||||
if (driver == null) {
|
|
||||||
throw new WebDriverException("无效的WebDriver对象");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.driver = driver;
|
|
||||||
browserHandles = this.driver.getWindowHandle();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于设置指向存储元素定位方式的xml文件对象
|
|
||||||
*
|
|
||||||
* @param xmlFile 存储元素定位方式的xml文件对象
|
|
||||||
*/
|
|
||||||
public void setXmlFile(File xmlFile) {
|
|
||||||
xml = new ReadXml(xmlFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回ReadXml类对象
|
|
||||||
* @return ReadXml类对象
|
|
||||||
*/
|
|
||||||
public ReadXml getXml() {
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回写入xml文件的或传入的元素定位方式,以“mode=position”的形式输出
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return 元素定位方式
|
|
||||||
*/
|
|
||||||
public String getElementPosition(String name) {
|
|
||||||
// 智能匹配方式:
|
|
||||||
// 1.先对xml文件进行扫描,若存在该元素对应的标签,则读取xml文件的定位方式,并识别有效的定位方式一一匹配,直到正确为止;
|
|
||||||
// 2.若在xml文件中查找不到该元素,则按照xpath和css的规则进行匹配,直到判断出该元素的定位方式位置
|
|
||||||
// 3.若仍找不到元素,则抛出UnrecognizableLocationModeException
|
|
||||||
try {
|
|
||||||
ByType mode = readXml(name);
|
|
||||||
// 判断readXML()方法的返回值是否为空串,若为空串,则抛出TimeoutException
|
|
||||||
if (mode == null) {
|
|
||||||
// 将错误信息写入到记录工具的备注中
|
|
||||||
RecordTool.recordMark("元素查找超时或不存在,请检查xml文件中“" + name + "”对应元素的定位方式");
|
|
||||||
throw new TimeoutException("元素查找超时或不存在,请检查xml文件中“" + name + "”对应元素的定位方式");
|
|
||||||
} else {
|
|
||||||
// 页面查找元素,并存储该元素
|
|
||||||
return mode + "=" + xml.getValue(name, mode);
|
|
||||||
}
|
|
||||||
} catch (UndefinedElementException | NullPointerException | InvalidXPathException e) {
|
|
||||||
ByType mode = readValue(driver, name);
|
|
||||||
// 判断readValue()方法的返回值是否为空串,若为空串,则抛出UnrecognizableLocationModeException
|
|
||||||
if (mode == null) {
|
|
||||||
// 将错误信息写入到记录工具的备注中
|
|
||||||
RecordTool.recordMark("元素定位方式类型无法识别:" + name);
|
|
||||||
// 若都不匹配,则抛出异常
|
|
||||||
throw new UnrecognizableLocationModeException("元素定位方式类型无法识别:" + name);
|
|
||||||
} else {
|
|
||||||
//若有返回定位方式,则根据定位方式类型,获取其元素
|
|
||||||
switch (mode) {
|
|
||||||
case XPATH:
|
|
||||||
return ByType.XPATH.getValue() + "=" + name;
|
|
||||||
case CSS:
|
|
||||||
return ByType.CSS.getValue() + "=" + name;
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于对单个控件设置等待时间
|
|
||||||
*
|
|
||||||
* @param name 控件名称
|
|
||||||
* @param waitTime 等待时间
|
|
||||||
*/
|
|
||||||
public void setContorlWaitTime(String name, long waitTime) {
|
|
||||||
controlWaitTime.put(name, waitTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于将窗体切回顶层,当本身是在最顶层时,则该方法将使用无效
|
|
||||||
*/
|
|
||||||
public void switchRootFrame() {
|
|
||||||
driver.switchTo().defaultContent();
|
|
||||||
iframeNames.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于将窗体切换到上一层(父层),当本身是在最顶层时,则该方法将使用无效
|
|
||||||
*/
|
|
||||||
public void switchParentFrame() {
|
|
||||||
driver.switchTo().parentFrame();
|
|
||||||
iframeNames.remove(iframeNames.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于通过悬浮窗名称,使用xpath的定位方式将页面切换至悬浮窗(iframe标签)上
|
|
||||||
*
|
|
||||||
* @param name 悬浮窗的名称
|
|
||||||
*/
|
|
||||||
public void switchFrame(String name) {
|
|
||||||
//获取父窗体的窗体名称
|
|
||||||
String parentIframeName = xml.getIframeName(name);
|
|
||||||
|
|
||||||
//判断窗体是否存在父窗体,若不存在父窗体(返回值为空),则切换,若有,则递归调用该方法,直到找到最顶层窗体为止
|
|
||||||
if (parentIframeName.isEmpty()) {
|
|
||||||
//清空iframeNames中的内容
|
|
||||||
iframeNames.clear();
|
|
||||||
//将窗体切换到顶层
|
|
||||||
driver.switchTo().defaultContent();
|
|
||||||
} else {
|
|
||||||
switchFrame(parentIframeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//记录当前自动切换的窗体的状态
|
|
||||||
boolean isSwitchFrame = isSwitchIframe();
|
|
||||||
//切换窗体前设置不自动切换窗体,避免窗体的循环切换
|
|
||||||
setSwitchIframe(false);
|
|
||||||
//切换窗体
|
|
||||||
driver.switchTo().frame(judgeElementMode(name));
|
|
||||||
//切换窗体后还原原始的切换窗体状态
|
|
||||||
setSwitchIframe(isSwitchFrame);
|
|
||||||
//存储窗体切换记录
|
|
||||||
iframeNames.add(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法可用于切换弹出的窗口(新标签或新窗口),并返回新窗口的WebDriver对象,若无新窗口,则返回当前的窗口的WebDriver对象。
|
|
||||||
* 注意,该方法只能切换弹出一个窗口的情况,若有多个窗口,通过该方法无法准确定位,可参考方法{@link #switchWindow(String)}。
|
|
||||||
*/
|
|
||||||
public void switchWindow() {
|
|
||||||
Set<String> handles = driver.getWindowHandles();
|
|
||||||
// 判断是否只存在一个窗体,若只存在一个,则直接返回当前浏览器的WebDriver对象
|
|
||||||
if (handles.size() == 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前窗口的handle
|
|
||||||
String winHandle = driver.getWindowHandle();
|
|
||||||
// 循环,获取所有的页面handle
|
|
||||||
for (String newWinHandle : handles) {
|
|
||||||
// 判断获取到的窗体handle是否为当前窗口的handle,若不是,则将其定位到获取的handle对应的窗体上
|
|
||||||
if (!newWinHandle.equals(winHandle)) {
|
|
||||||
driver.switchTo().window(newWinHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NoSuchWindownException("未找到相应的窗体");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于将窗口切换回最原始的窗口上。
|
|
||||||
*/
|
|
||||||
public void switchOldWindow() {
|
|
||||||
driver.switchTo().window(browserHandles);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法可根据控件名称,之后对比每一个弹窗,若某一个弹窗上存在元素名对应的元素,则返回相应
|
|
||||||
* 窗口的WebDriver对象,若无新窗口,则返回当前的窗口的WebDriver对象。当所有的窗体都
|
|
||||||
* 不包含相应的元素时,则抛出NoSuchWindownException异常
|
|
||||||
*
|
|
||||||
* @param controlName 控件名称
|
|
||||||
* @throws NoSuchWindownException 窗口未找到时抛出的异常
|
|
||||||
*/
|
|
||||||
public void switchWindow(String controlName) {
|
|
||||||
Set<String> handles = driver.getWindowHandles();
|
|
||||||
// 判断是否只存在一个窗体,若只存在一个,则直接返回当前浏览器的WebDriver对象
|
|
||||||
if (handles.size() == 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 循环,获取所有的页面handle
|
|
||||||
for (String newWinHandle : handles) {
|
|
||||||
driver.switchTo().window(newWinHandle);
|
|
||||||
// 调用judgeElementMode()方法来判断元素是否存在,如果元素存在,则返回相应页面的WebDriver对象,若抛出异常(元素不存在),则返回当前
|
|
||||||
try {
|
|
||||||
judgeElementMode(controlName);
|
|
||||||
} catch (TimeoutException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new NoSuchWindownException("未找到存在元素" + controlName + "所在的窗体");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定位到弹框上并且点击确定按钮,并返回弹框上的文本
|
|
||||||
*
|
|
||||||
* @return 弹框上的文本
|
|
||||||
*/
|
|
||||||
public String alertAccept() {
|
|
||||||
String text = alertGetText();
|
|
||||||
driver.switchTo().alert().accept();
|
|
||||||
|
|
||||||
return text;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定位到弹框上并且点击取消按钮,并返回弹框上的文本
|
|
||||||
*
|
|
||||||
* @return 弹框上的文本
|
|
||||||
*/
|
|
||||||
public String alertDimiss() {
|
|
||||||
String text = alertGetText();
|
|
||||||
driver.switchTo().alert().dismiss();
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定位到弹框上并且在其文本框中输入信息
|
|
||||||
*
|
|
||||||
* @param content 需要输入的信息
|
|
||||||
* @return 弹框上的文本
|
|
||||||
*/
|
|
||||||
public String alertInput(String content) {
|
|
||||||
String text = alertGetText();
|
|
||||||
driver.switchTo().alert().sendKeys("");
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取弹框上的文本
|
|
||||||
*
|
|
||||||
* @return 弹框上的文本
|
|
||||||
*/
|
|
||||||
public String alertGetText() {
|
|
||||||
return driver.switchTo().alert().getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 用于根据传入的控件名称或定位方式,对控件在页面上定位,返回其WebElement对象。形参可以传入在xml文件中元素的名称,
|
|
||||||
* 亦可以传入页面元素的定位方式,但目前识别只支持xpath和css两种方式。
|
|
||||||
* 该方法获取的是单个元素,但本质是调用了{@link #judgeElementModes(String)}方法,只是将其容器中第一个元素进行返回。
|
|
||||||
* 可用于普通元素事件获取页面元素中使用
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 元素识别判断方式按照以下步骤进行:<br>
|
|
||||||
* 1.先对xml文件进行扫描,若存在该元素对应的标签,则读取xml文件的定位方式,并识别有效的定位方式一一匹配,直到正确为止;<br>
|
|
||||||
* 2.若在xml文件中查找不到该元素,则按照xpath和css的规则进行匹配,直到判断出该元素的定位方式位置;<br>
|
|
||||||
* 3.若仍找不到元素,则抛出UnrecognizableLocationModeException
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param text 元素名称或元素的定位方式
|
|
||||||
* @return 返回页面元素WebElement对象
|
|
||||||
* @throws TimeoutException 元素在指定时间内未查找到时,抛出的异常
|
|
||||||
* @throws UnrecognizableLocationModeException 元素无法识别时抛出的异常
|
|
||||||
*/
|
|
||||||
protected WebElement judgeElementMode(String name) {
|
|
||||||
return judgeElementModes(name).get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 用于根据传入的控件名称或定位方式,对控件在页面上定位,返回其WebElement对象。形参可以传入在xml文件中元素的名称,
|
|
||||||
* 亦可以传入页面元素的定位方式,但目前识别只支持xpath和css两种方式。
|
|
||||||
* 该方法获取的是一组元素,可用于对列表元素事件中。
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 元素识别判断方式按照以下步骤进行:<br>
|
|
||||||
* 1.先对xml文件进行扫描,若存在该元素对应的标签,则读取xml文件的定位方式,并识别有效的定位方式一一匹配,直到正确为止;<br>
|
|
||||||
* 2.若在xml文件中查找不到该元素,则按照xpath和css的规则进行匹配,直到判断出该元素的定位方式位置;<br>
|
|
||||||
* 3.若仍找不到元素,则抛出UnrecognizableLocationModeException
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param name 元素名称或元素的定位方式
|
|
||||||
* @return 返回页面一组元素WebElement的对象
|
|
||||||
* @throws TimeoutException 元素在指定时间内未查找到时,抛出的异常
|
|
||||||
* @throws UnrecognizableLocationModeException 元素无法识别时抛出的异常
|
|
||||||
*/
|
|
||||||
protected List<WebElement> judgeElementModes(String name) {
|
|
||||||
// 获取当前的等待时间,若有对单个控件设置等待时间时,此处可以将等待时间设置回原来的时间
|
|
||||||
long time = getWaitTime();
|
|
||||||
// 判断是否有设置对单个控件增加等待时间,若存在该控件,则将等待时间设置为该控件设置的等待时间
|
|
||||||
if (controlWaitTime.containsKey(name)) {
|
|
||||||
setWaitTime(controlWaitTime.get(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 存储最终识别得到元素
|
|
||||||
List<WebElement> elements = null;
|
|
||||||
|
|
||||||
// 智能匹配方式:
|
|
||||||
// 1.先对xml文件进行扫描,若存在该元素对应的标签,则读取xml文件的定位方式,并识别有效的定位方式一一匹配,直到正确为止;
|
|
||||||
// 2.若在xml文件中查找不到该元素,则按照xpath和css的规则进行匹配,直到判断出该元素的定位方式位置
|
|
||||||
// 3.若仍找不到元素,则抛出UnrecognizableLocationModeException
|
|
||||||
try {
|
|
||||||
ByType mode = readXml(name);
|
|
||||||
// 判断readXML()方法的返回值是否为空串,若为空串,则抛出TimeoutException
|
|
||||||
if (mode == null) {
|
|
||||||
// 将错误信息写入到记录工具的备注中
|
|
||||||
RecordTool.recordMark("元素查找超时或不存在,请检查xml文件中“" + name + "”对应元素的定位方式");
|
|
||||||
throw new TimeoutException("元素查找超时或不存在,请检查xml文件中“" + name + "”对应元素的定位方式");
|
|
||||||
} else {
|
|
||||||
// 页面查找元素,并存储该元素
|
|
||||||
elements = driver.findElements(xml.getBy(name, mode));
|
|
||||||
}
|
|
||||||
} catch (UndefinedElementException | NullPointerException | InvalidXPathException e) {
|
|
||||||
ByType mode = readValue(driver, name);
|
|
||||||
// 判断readValue()方法的返回值是否为空串,若为空串,则抛出UnrecognizableLocationModeException
|
|
||||||
if (mode == null) {
|
|
||||||
// 将错误信息写入到记录工具的备注中
|
|
||||||
RecordTool.recordMark("元素定位方式类型无法识别:" + name);
|
|
||||||
// 若都不匹配,则抛出异常
|
|
||||||
throw new UnrecognizableLocationModeException("元素定位方式类型无法识别:" + name);
|
|
||||||
} else {
|
|
||||||
//若有返回定位方式,则根据定位方式类型,获取其元素
|
|
||||||
switch (mode) {
|
|
||||||
case XPATH:
|
|
||||||
elements = driver.findElements(By.xpath(name));
|
|
||||||
break;
|
|
||||||
case CSS:
|
|
||||||
elements = driver.findElements(By.cssSelector(name));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置等待时间为原来的等待时间
|
|
||||||
setWaitTime(time);
|
|
||||||
// 返回页面元素对象
|
|
||||||
return elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于通过传入的控件名称,在xml文件中查找其元素相应的定位方式,并在页面上进行查找, 若在相应的时间内查找到该元素,则将其定位方式进行返回
|
|
||||||
*
|
|
||||||
* @param name 控件名称
|
|
||||||
* @return 查找到的定位方式名称
|
|
||||||
*/
|
|
||||||
protected ByType readXml(String name) {
|
|
||||||
// 循环,逐个在页面上配对有效的标签对应的定位方式
|
|
||||||
for (ByType mode : xml.getElementMode(name)) {
|
|
||||||
// 在页面上查找元素定位方式
|
|
||||||
try {
|
|
||||||
//自动定位元素所在的窗体
|
|
||||||
if (isSwitchIframe()) {
|
|
||||||
autoSwitchIframe(xml.getIframeName(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
//查找元素
|
|
||||||
wait.until(ExpectedConditions.presenceOfElementLocated(xml.getBy(name, mode)));
|
|
||||||
} catch (TimeoutException exception) {
|
|
||||||
// 若查找超时,则重新查找
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 若在页面上找到该元素,则将该元素的定位方式存储
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 若循环结束后仍未能找到该元素,则返回一个空串
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于自动定位元素所在窗体
|
|
||||||
* @param iframeName 元素所在窗体名称
|
|
||||||
*/
|
|
||||||
protected void autoSwitchIframe(String iframeName) {
|
|
||||||
//判断传入的窗体名称是否为空,若为空,说明元素在主窗体上
|
|
||||||
if (iframeName.isEmpty()) {
|
|
||||||
//判断当前定位是否在主窗体上(iframeNames无元素时),若不在主窗体上,则切换到主窗体,若在,则直接结束
|
|
||||||
if (iframeNames.size() != 0) {
|
|
||||||
//将窗体切换到顶层
|
|
||||||
switchRootFrame();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断当前元素所在的窗体是否与已切换的窗体列表中最后一个元素(当前窗体)的内容相同,相同则直接返回(无需操作)
|
|
||||||
//获取最后一层窗体的名称,若iframeNames为空,则返回空串
|
|
||||||
String nowIframeName = (iframeNames.isEmpty() ? "" : iframeNames.get(iframeNames.size() - 1));
|
|
||||||
if (iframeName.equals(nowIframeName)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//若传入的字符串不为空,则表示当前窗体不在主窗体上,则判断其是否在已切换的窗体列表中,若在,则通过层级返回,
|
|
||||||
//无需再次重新定位,避免等待时间太长,若不在,则重新定位窗体
|
|
||||||
int index = 0;
|
|
||||||
if ((index = iframeNames.indexOf(iframeName)) > -1) {
|
|
||||||
//循环,将窗体一层一层返回
|
|
||||||
for(int i = 1; i < iframeNames.size() - index; i++) {
|
|
||||||
switchParentFrame();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//若当前元素的窗体不在当前窗体的父窗体,则重新定位窗体
|
|
||||||
switchFrame(iframeName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于在xml文件查找不到对应的元素时,则再对传入的参数进行xpath和css的比较,
|
|
||||||
* 以确认是否为直接传值,若不为xpath和css中的一种,则抛出UnrecognizableLocationModeException
|
|
||||||
*
|
|
||||||
* @param driver WebDriver对象
|
|
||||||
* @param text 定位方式
|
|
||||||
* @return 定位方式的类型
|
|
||||||
*/
|
|
||||||
protected ByType readValue(WebDriver driver, String text) {
|
|
||||||
// 定义判断参数为xpath的字符
|
|
||||||
String judgeXpath = "/";
|
|
||||||
|
|
||||||
// 定义判断参数为css的字符
|
|
||||||
String judgeCss = "html";
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 如果抛出元素名称查找不到的的异常,则对应匹配xpath和css两种定位方式
|
|
||||||
// 匹配xpath定位,判定方法,判断text的第一个字符是否是“/”
|
|
||||||
if (text.indexOf(judgeXpath) == 0) {
|
|
||||||
// 查找该定位方式在有限的时间内是否内被查到
|
|
||||||
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(text)));
|
|
||||||
return ByType.XPATH;
|
|
||||||
// 将等待时间设置回原来的
|
|
||||||
} else if (text.indexOf(judgeCss) == 0) {
|
|
||||||
// 匹配css,判断方法:判断text的前四个字符是否是“html”
|
|
||||||
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(text)));
|
|
||||||
return ByType.CSS;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (TimeoutException exception) {
|
|
||||||
// 将错误信息写入到记录工具的备注中
|
|
||||||
RecordTool.recordMark("元素查找超时或不存在,请检查“" + text + "”定位方式");
|
|
||||||
throw new TimeoutException("元素查找超时或不存在,请检查“" + text + "”定位方式");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于将页面控件元素高亮显示
|
|
||||||
* @param newElement 当前指向的元素
|
|
||||||
*/
|
|
||||||
protected void elementHight(WebElement newElement) {
|
|
||||||
//判断当前指向的元素是否与原来存储的元素一致,若不一致且有之前有存储元素,则解除之前元素的控件高亮
|
|
||||||
if (oldElement != newElement && oldElement != null) {
|
|
||||||
// 解除控件高亮,若因为页面跳转导致页面过期时,则不处理其异常
|
|
||||||
try {
|
|
||||||
((JavascriptExecutor) getDriver()).executeScript("arguments[0].setAttribute('style',arguments[1])",
|
|
||||||
oldElement, oldElementStyle);
|
|
||||||
} catch (StaleElementReferenceException exception) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取当前指向的元素的style属性
|
|
||||||
String newElementStyle = newElement.getAttribute("style");
|
|
||||||
// 控件高亮
|
|
||||||
((JavascriptExecutor) getDriver()).executeScript("arguments[0].setAttribute('style',arguments[1])", newElement,
|
|
||||||
newElementStyle + "background:yellow;solid:red;");
|
|
||||||
|
|
||||||
//将当前指向的元素及其属性存储至属性中
|
|
||||||
oldElement = newElement;
|
|
||||||
oldElementStyle = newElementStyle;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,162 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import org.openqa.selenium.StaleElementReferenceException;
|
|
||||||
import org.openqa.selenium.TimeoutException;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.inter.ClickEventInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.ClickInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.DoubleClickInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.RightClickInter;
|
|
||||||
import pres.auxiliary.selenium.tool.RecordTool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>ClickEvent.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>定义了对控件进行点击操作相关的方法,可通过该类,对页面进行基本的点击操作
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年8月29日下午3:24:34
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年11月29日上午9:53:37
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ClickEvent extends CommenElementEvent implements ClickEventInter {
|
|
||||||
/**
|
|
||||||
* 构造ClickEvent类对象
|
|
||||||
*
|
|
||||||
* @param driver WebDriver类对象
|
|
||||||
*/
|
|
||||||
public ClickEvent(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event click(String name) {
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
/*
|
|
||||||
// 获取原style属性
|
|
||||||
style = element.getAttribute("style");
|
|
||||||
// 控件高亮
|
|
||||||
((JavascriptExecutor) getDriver()).executeScript("arguments[0].setAttribute('style',arguments[1])", element,
|
|
||||||
style + "background:yellow;solid:red;");
|
|
||||||
*/
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
ClickInter.click(element);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// 解除控件高亮,若因为页面跳转导致页面过期时,则不处理其异常
|
|
||||||
try {
|
|
||||||
((JavascriptExecutor) getDriver()).executeScript("arguments[0].setAttribute('style',arguments[1])",
|
|
||||||
element, style);
|
|
||||||
} catch (StaleElementReferenceException exception) {
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
} catch (TimeoutException timeException) {
|
|
||||||
RecordTool.recordException(new TimeoutException("元素查找超时或不存在,请检查“" + name + "”对应元素的定位方式"));
|
|
||||||
throw new TimeoutException("元素查找超时或不存在,请检查中“" + name + "”对应元素的定位方式");
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("点击“" + name + "”对应控件");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event doubleClick(String name) {
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
DoubleClickInter.doubleClick(getDriver(), element);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (TimeoutException timeException) {
|
|
||||||
RecordTool.recordException(new TimeoutException("元素查找超时或不存在,请检查“" + name + "”对应元素的定位方式"));
|
|
||||||
throw new TimeoutException("元素查找超时或不存在,请检查中“" + name + "”对应元素的定位方式");
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("双击“" + name + "”对应控件");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event rightClick(String name) {
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
RightClickInter.rightClick(getDriver(), element);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (TimeoutException timeException) {
|
|
||||||
RecordTool.recordException(new TimeoutException("元素查找超时或不存在,请检查“" + name + "”对应元素的定位方式"));
|
|
||||||
throw new TimeoutException("元素查找超时或不存在,请检查中“" + name + "”对应元素的定位方式");
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("右击“" + name + "”对应控件");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>AbstractEvent.java</p>
|
|
||||||
* <p><b>用途:</b>用于定义所有普通元素的事件类的基础方法,所有普通元素的事件类必须继承该类</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:23:30</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月25日下午3:04:30</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class CommenElementEvent extends AbstractEvent {
|
|
||||||
/**
|
|
||||||
* 存储元素的原style属性,用以控件高亮
|
|
||||||
*/
|
|
||||||
protected String style = "";
|
|
||||||
/**
|
|
||||||
* 存储获取到的元素
|
|
||||||
*/
|
|
||||||
protected WebElement element = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造对象并存储浏览器的WebDriver对象
|
|
||||||
*
|
|
||||||
* @param driver 浏览器的WebDriver对象
|
|
||||||
*/
|
|
||||||
public CommenElementEvent(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,723 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.openqa.selenium.ElementClickInterceptedException;
|
|
||||||
import org.openqa.selenium.NoSuchElementException;
|
|
||||||
import org.openqa.selenium.StaleElementReferenceException;
|
|
||||||
import org.openqa.selenium.TimeoutException;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.inter.ClearInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.ClickInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.DataListEventInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.DoubleClickInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.GetAttributeValueInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.GetTextInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.InputInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.JudgeKeyInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.JudgeTextInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.RightClickInter;
|
|
||||||
import pres.auxiliary.selenium.tool.RecordTool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>WebElementList.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>提供对页面多个使用相近定位方式的元素进行获取的方法,并根据get方法返回获得每个 元素后可对其元素进行基本操作的方法
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年7月19日下午3:23:50
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年11月29日上午9:53:37
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.3
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DataListEvent extends ListElementEvent {
|
|
||||||
/**
|
|
||||||
* 构造对象,存储储浏览器的WebDriver对象
|
|
||||||
*
|
|
||||||
* @param driver 浏览器的WebDriver对象
|
|
||||||
*/
|
|
||||||
public DataListEvent(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于根据存入的元素名称或定位方式,对元素进行重新获取的操作。主要用于当列表数据翻页后,
|
|
||||||
* 其原存入的数据将会失效,必须重新获取。注意,调用该方法后会清空原存储的数据。
|
|
||||||
*/
|
|
||||||
public void againGetElement() {
|
|
||||||
// 读取elements中的元素
|
|
||||||
elements.forEach((name, list) -> {
|
|
||||||
// 清空元素中的内容
|
|
||||||
clear(name);
|
|
||||||
// 对页面内容重新进行获取
|
|
||||||
add(name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于根据下标移除下标所在行的整行元素,下标允许传入负数,意为由后向前遍历
|
|
||||||
*
|
|
||||||
* @param index 下标
|
|
||||||
*
|
|
||||||
* @throws NoSuchElementException 传入的元素列或元素不存在时抛出的异常
|
|
||||||
*/
|
|
||||||
public void removeLineElement(int index) {
|
|
||||||
// 遍历整行元素,并调用removeElement方法删除对应列的元素,若存在异常,则跳过不处理
|
|
||||||
// 由于当传入0时会出现问题,但lambda表达式不能为变量赋值,故只能使用普通循环
|
|
||||||
for (String name : elements.keySet()) {
|
|
||||||
// 若下标为0,则先进行下标获取操作,并赋予index真实下标
|
|
||||||
index = index == 0 ? getIndex(name, index) : index;
|
|
||||||
|
|
||||||
// 判断是否能获取到元素,若不能获取到元素,则使用第二种构造方法
|
|
||||||
try {
|
|
||||||
removeElement(name, index);
|
|
||||||
} catch (NoSuchElementException e) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回最短列的长度
|
|
||||||
*
|
|
||||||
* @return 最短列的长度
|
|
||||||
*/
|
|
||||||
public String shortListName() {
|
|
||||||
// 初始化minSize,为int的最大值
|
|
||||||
int minSize = Integer.MAX_VALUE;
|
|
||||||
String name = "";
|
|
||||||
// 循环,遍历所有的key,获取其长度,查找最短的进行存储
|
|
||||||
for (String key : elements.keySet()) {
|
|
||||||
if (size(key) < minSize) {
|
|
||||||
minSize = size(key);
|
|
||||||
name = key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于根据根据指定的列下标返回相应列元素的个数,该方法根据存储时的顺序指定其列对应的下标,
|
|
||||||
* 若需要通过列表返回元素个数,可使用{@link #size(String)}进行返回
|
|
||||||
*
|
|
||||||
* @param columnNum 存储时相应列的下标
|
|
||||||
* @return 相应列元素的个数
|
|
||||||
*/
|
|
||||||
public int columnLength(int columnNum) {
|
|
||||||
//存储元素集合
|
|
||||||
Set<String> elemensSet = elements.keySet();
|
|
||||||
//存储最大下标
|
|
||||||
int maxListIndex = elemensSet.size();
|
|
||||||
|
|
||||||
//判断columnNum是否符合标准
|
|
||||||
if (columnNum < 0 || columnNum > maxListIndex) {
|
|
||||||
throw new ArrayIndexOutOfBoundsException("不存在的列下标:" + columnNum + "(列个数为:)" + maxListIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
//循环,遍历元素下标,返回其相应的列下标的元素个数
|
|
||||||
int i = 0;
|
|
||||||
for (String name : elements.keySet()) {
|
|
||||||
//判断当前循环的下标是否与columnNum相同,若相同,则返回相应的name
|
|
||||||
if (i == columnNum) {
|
|
||||||
return size(name);
|
|
||||||
}
|
|
||||||
//若不同,则循环下标+1
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回添加列的个数,即一行元素的个数,若某一列元素不存在,则每行元素个数同样将该行包含
|
|
||||||
* @return 添加列的个数
|
|
||||||
*/
|
|
||||||
public int rowLength() {
|
|
||||||
//存储元素集合
|
|
||||||
return elements.keySet().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于对列中元素的文本进行筛选,返qwa回符合筛选项序号
|
|
||||||
*
|
|
||||||
* @param name 列名
|
|
||||||
* @param index 筛选后所在的列下标(下标从1开始,1表示第一个元素)
|
|
||||||
*/
|
|
||||||
public int[] filterText(String name, String key, boolean keyFull) {
|
|
||||||
ArrayList<Integer> indexList = new ArrayList<>();
|
|
||||||
|
|
||||||
// 筛选文本
|
|
||||||
// 记录当前是否开启自动记录步骤的状态,并设置关闭自动记录操作步骤,加快操作进程
|
|
||||||
boolean recordStep = RecordTool.isRecordStep();
|
|
||||||
RecordTool.setRecordStep(false);
|
|
||||||
|
|
||||||
// 由于获取方法可能会出现异常,故使用finally,以保证无论获取方法是否有异常也能还原记录操作步骤的状态
|
|
||||||
try {
|
|
||||||
getEvents(name).forEach(event -> {
|
|
||||||
// 调用judgeText()方法进行判断,若符合要求,则indexList进行存储
|
|
||||||
if (event.judgeText(keyFull, key).getBooleanValue()) {
|
|
||||||
indexList.add(event.getIndex());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception e) {
|
|
||||||
// 抛出异常
|
|
||||||
throw e;
|
|
||||||
} finally {
|
|
||||||
// 还原自动记录操作步骤的状态
|
|
||||||
RecordTool.setRecordStep(recordStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将ArrayList转换成数组
|
|
||||||
int[] indexs = new int[indexList.size()];
|
|
||||||
for (int i = 0; i < indexs.length; i++) {
|
|
||||||
indexs[i] = indexList.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return indexs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据指定的翻页按钮,以及翻页次数,对列表进行翻页操作。该方法会自动判定是否翻页成功,但以下场景下
|
|
||||||
* 将无法自动判定翻页是否成功:
|
|
||||||
* <ol>
|
|
||||||
* <li>
|
|
||||||
* 当按钮的disable属性无法直接获取到(其disable卸载css中或style中时),
|
|
||||||
* 且列表的最后一页元素量与前一页一致时无法判断
|
|
||||||
* </li>
|
|
||||||
* <li>
|
|
||||||
* 当按钮在最后一页时仍能继续点击且且列表的最后一页元素量与前一页一致时无法判断
|
|
||||||
* </li>
|
|
||||||
* </ol>
|
|
||||||
* @param turnCount 翻页次数
|
|
||||||
* @param buttonName 翻页按钮
|
|
||||||
* @param sleepTime 翻页时间间隔,单位为毫秒
|
|
||||||
*
|
|
||||||
* @throws TimeoutException 翻页按钮查找不到或数据加载时间过长导致翻页按钮无法点击时抛出
|
|
||||||
*/
|
|
||||||
public void pageTurning(int turnCount, String buttonName, long sleepTime) {
|
|
||||||
//判断翻页数是否小于等于0,若小于等于0,则直接返回,不进行操作
|
|
||||||
if (turnCount <= 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//构造点击事件对象
|
|
||||||
ClickEvent ce = new ClickEvent(getDriver());
|
|
||||||
|
|
||||||
//记录当前步骤记录情况,为节约翻页事件,则先关闭自动记录步骤功能,在循环结束后再还原
|
|
||||||
boolean recordStep = RecordTool.isRecordStep();
|
|
||||||
RecordTool.setRecordStep(false);
|
|
||||||
//记录实际翻页数
|
|
||||||
int actualPageCount = 0;
|
|
||||||
//循环,对列表元素进行翻页
|
|
||||||
for (; actualPageCount < turnCount; actualPageCount++) {
|
|
||||||
//获取翻页前第一列的元素个数
|
|
||||||
int oldElementNum = columnLength(0);
|
|
||||||
|
|
||||||
//点击翻页按钮
|
|
||||||
//若抛出TimeoutException异常,则表示翻页按钮的指向有问题,则抛出该异常
|
|
||||||
//若抛出其他异常,则表示下一页按钮可能无法点击,则结束循环
|
|
||||||
//TODO 以上描述只表示已知的情况,若存在其他异常且不是按钮无法点击的情况下,则需要组织记录
|
|
||||||
try {
|
|
||||||
ce.click(buttonName);
|
|
||||||
} catch (ElementClickInterceptedException elementClickInterceptedException) {
|
|
||||||
RecordTool.recordException(new TimeoutException("页面未完全加载,翻页按钮点击超时"));
|
|
||||||
throw new TimeoutException("页面未完全加载,翻页按钮点击超时");
|
|
||||||
} catch (TimeoutException timeoutException) {
|
|
||||||
throw timeoutException;
|
|
||||||
} catch (Exception e) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//等待一定时间后再运行翻页
|
|
||||||
try {
|
|
||||||
Thread.sleep(sleepTime);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
//重新获取列表元素
|
|
||||||
againGetElement();
|
|
||||||
|
|
||||||
//获取翻页后第一列的元素个数
|
|
||||||
int nowElementNum = columnLength(0);
|
|
||||||
|
|
||||||
//对比翻页前后第一列元素的个数,若元素个数不同,则表示当前以翻到最后一页,则结束循环
|
|
||||||
if (nowElementNum != oldElementNum) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//还原之前的自动记录情况
|
|
||||||
RecordTool.setRecordStep(recordStep);
|
|
||||||
|
|
||||||
RecordTool.recordStep("点击" + buttonName + "指向的按钮,对列表进行" + turnCount + "翻页(实际翻页为" + actualPageCount + "页)");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于根据控件名称或定位方式,提供需要操作列表元素的下标,对相应的元素进行操作
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param index 元素下标(即列表中对应的某一个元素)
|
|
||||||
* @return 元素的可执行的事件
|
|
||||||
* @throws NoSuchElementException 当未对name列进行获取数据或index的绝对值大于列表最大值时抛出的异常
|
|
||||||
*/
|
|
||||||
public ListEvent getEvent(String name, int index) {
|
|
||||||
// 转义下标
|
|
||||||
index = getIndex(name, index);
|
|
||||||
|
|
||||||
// 判断元素是否存在
|
|
||||||
if (elements.containsKey(name)) {
|
|
||||||
// 转义下标后,返回对应的元素
|
|
||||||
return new ListEvent(elements.get(name).get(index), name, index + 1);
|
|
||||||
} else {
|
|
||||||
throw new NoSuchElementException("不存在的定位方式:" + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于根据控件名称或定位方式,获取该列下所有的元素
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return 一组元素的可执行的事件
|
|
||||||
* @throws NoSuchElementException 当未对name列进行获取数据时抛出的异常
|
|
||||||
*/
|
|
||||||
public ArrayList<ListEvent> getEvents(String name) {
|
|
||||||
if (elements.containsKey(name)) {
|
|
||||||
ArrayList<ListEvent> events = new ArrayList<>();
|
|
||||||
int index = 1;
|
|
||||||
|
|
||||||
for (WebElement element : elements.get(name)) {
|
|
||||||
events.add(new ListEvent(element, name, index++));
|
|
||||||
}
|
|
||||||
|
|
||||||
return events;
|
|
||||||
} else {
|
|
||||||
throw new NoSuchElementException("不存在的定位方式:" + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回多个指定的列表数据的事件
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param indexs 一组元素下标(即列表中对应的某一个元素)
|
|
||||||
* @return 指定下标的事件组
|
|
||||||
*/
|
|
||||||
public ArrayList<ListEvent> getEvents(String name, int... indexs) {
|
|
||||||
// 存储所有获取到的事件
|
|
||||||
ArrayList<ListEvent> events = new ArrayList<>();
|
|
||||||
|
|
||||||
// 循环,解析所有的下标,并调用getEvent()方法,存储至events
|
|
||||||
for (int index : indexs) {
|
|
||||||
events.add(getEvent(name, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
return events;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回指定个数列表事件,其列表的行下标将随机生成
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param length 需要返回列表事件的个数
|
|
||||||
* @return 列表事件组
|
|
||||||
*/
|
|
||||||
public ArrayList<ListEvent> getRandomCountEvent(String name, int length) {
|
|
||||||
// 判断元素是否存在,若元素不存在抛出异常
|
|
||||||
if (!elements.containsKey(name)) {
|
|
||||||
throw new NoSuchElementException("不存在的定位方式:" + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断传入的长度是否大于等于当前
|
|
||||||
if (length >= elements.get(name).size()) {
|
|
||||||
return getEvents(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 存储通过随机得到的数字
|
|
||||||
ArrayList<Integer> indexsList = new ArrayList<Integer>();
|
|
||||||
// 循环,随机获取下标数字
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
int randomIndex = 0;
|
|
||||||
// 循环,直到生成的随机数不在indexs中为止
|
|
||||||
while (indexsList.contains(randomIndex = new Random().nextInt(elements.get(name).size()) + 1)) {
|
|
||||||
}
|
|
||||||
indexsList.add(randomIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将indexsList转换成int[]
|
|
||||||
int[] indexs = new int[indexsList.size()];
|
|
||||||
for (int i = 0; i < indexsList.size(); i++) {
|
|
||||||
indexs[i] = indexsList.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getEvents(name, indexs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于根据指定的行数获取一行元素,当元素
|
|
||||||
*
|
|
||||||
* @param index 行数(元素下标所在的行)
|
|
||||||
* @return 指定行的事件组
|
|
||||||
*/
|
|
||||||
public LinkedHashMap<String, ListEvent> getLineEvent(int index) {
|
|
||||||
// 存储一行元素
|
|
||||||
LinkedHashMap<String, ListEvent> events = new LinkedHashMap<>(16);
|
|
||||||
// 由于当传入0时会出现问题,但lambda表达式不能为变量赋值,故只能使用普通循环
|
|
||||||
for (String name : elements.keySet()) {
|
|
||||||
// 若下标为0,则先进行下标获取操作,并赋予index真实下标
|
|
||||||
index = index == 0 ? getIndex(name, index) : index;
|
|
||||||
|
|
||||||
// 判断是否能获取到元素,若不能获取到元素,则使用第二种构造方法
|
|
||||||
ListEvent event;
|
|
||||||
try {
|
|
||||||
event = getEvent(name, index);
|
|
||||||
} catch (NoSuchElementException e) {
|
|
||||||
event = new ListEvent(name, index);
|
|
||||||
}
|
|
||||||
// 存储元素
|
|
||||||
events.put(name, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return events;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>DataListEvent.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>用于定义列表元素的操作事件
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年10月8日下午7:08:16
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年10月8日下午7:08:16
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ListEvent implements DataListEventInter {
|
|
||||||
/**
|
|
||||||
* 用于存储当前获取的页面元素
|
|
||||||
*/
|
|
||||||
private WebElement element;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于存储当前元素的下标
|
|
||||||
*/
|
|
||||||
private int index;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于存储列表的名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造对象
|
|
||||||
*
|
|
||||||
* @param elemnet WebElement对象
|
|
||||||
* @param name 列表的名称
|
|
||||||
* @param index 当前元素的下标
|
|
||||||
*/
|
|
||||||
public ListEvent(WebElement element, String name, int index) {
|
|
||||||
this.element = element;
|
|
||||||
this.index = index;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ListEvent(String name, int index) {
|
|
||||||
this.element = null;
|
|
||||||
this.index = index;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回当前元素的下标
|
|
||||||
*
|
|
||||||
* @return 当前元素的下标
|
|
||||||
*/
|
|
||||||
public int getIndex() {
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于判断元素是否为空,若为空,则抛出元素为空的异常
|
|
||||||
*/
|
|
||||||
private void isEmptyElement() {
|
|
||||||
if (element == null) {
|
|
||||||
throw new NoSuchElementException("不存在的元素;列名:" + name + ",行数:" + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event click() {
|
|
||||||
// 判断元素是否为空
|
|
||||||
isEmptyElement();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
// 操作元素
|
|
||||||
ClickInter.click(element);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("点击“" + name + "”对应列的第" + index + "条数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event doubleClick() {
|
|
||||||
// 判断元素是否为空
|
|
||||||
isEmptyElement();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
// 操作元素
|
|
||||||
DoubleClickInter.doubleClick(getDriver(), element);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("双击“" + name + "”对应列的第" + index + "条数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event rightClick() {
|
|
||||||
// 判断元素是否为空
|
|
||||||
isEmptyElement();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
// 操作元素
|
|
||||||
RightClickInter.rightClick(getDriver(), element);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("右击“" + name + "”对应列的第" + index + "条数据");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event getAttributeValue(String attributeName) {
|
|
||||||
// 判断元素是否为空
|
|
||||||
isEmptyElement();
|
|
||||||
|
|
||||||
// 自动记录异常
|
|
||||||
try {
|
|
||||||
// 修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
// 操作元素
|
|
||||||
// 调用GetAttributeValueInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
GetAttributeValueInter.getAttributeValue(element, attributeName);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("获取“" + name + "”对应列的第" + index + "条数据" + attributeName + "属性的内容");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event getText() {
|
|
||||||
// 判断元素是否为空
|
|
||||||
isEmptyElement();
|
|
||||||
|
|
||||||
// 自动记录异常
|
|
||||||
try {
|
|
||||||
// 修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
// 操作元素
|
|
||||||
// 调用GetTextInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
GetTextInter.getText(element);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("获取“" + name + "”对应列的第" + index + "条数据的内容");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event judgeKey(boolean keyFull, String... keys) {
|
|
||||||
// 判断元素是否为空
|
|
||||||
isEmptyElement();
|
|
||||||
|
|
||||||
// 自动记录异常
|
|
||||||
try {
|
|
||||||
// 修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
// 操作元素
|
|
||||||
// 调用JudgeKeyInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
JudgeKeyInter.judgeKey(element, keyFull, keys);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
// 记录步骤
|
|
||||||
// 拼接传入的关键词
|
|
||||||
String text = "";
|
|
||||||
for (String key : keys) {
|
|
||||||
text += (key + "、");
|
|
||||||
}
|
|
||||||
text = text.substring(0, text.length() - 1);
|
|
||||||
|
|
||||||
// 根据keyFull的不同记录的文本将有改变
|
|
||||||
if (keyFull) {
|
|
||||||
RecordTool.recordStep("判断“" + name + "”对应列的第" + index + "条数据中的内容是否包含所有关键词(关键词为:" + text + ")");
|
|
||||||
} else {
|
|
||||||
RecordTool.recordStep("判断“" + name + "”对应列的第" + index + "条数据中的内容是否包含部分关键词(关键词为:" + text + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event judgeText(boolean keyFull, String key) {
|
|
||||||
// 判断元素是否为空
|
|
||||||
isEmptyElement();
|
|
||||||
|
|
||||||
// 自动记录异常
|
|
||||||
try {
|
|
||||||
// 修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
// 操作元素
|
|
||||||
// 调用JudgeTextInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
JudgeTextInter.judgeText(element, keyFull, key);
|
|
||||||
} catch (Exception exception) {
|
|
||||||
// 捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
// 根据keyFull的不同记录的文本将有改变
|
|
||||||
if (keyFull) {
|
|
||||||
RecordTool.recordStep("判断“" + name + "”对应列的第" + index + "条数据中的内容是否与所有关键词“" + key + "”一致");
|
|
||||||
} else {
|
|
||||||
RecordTool.recordStep("判断“" + name + "”对应列的第" + index + "条数据中的内容是否包含关键词“" + key + "”");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event clear() {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
//调用ClearInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
ClearInter.clear(element);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("清空“" + name + "”对应控件中的内容");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event input(String text) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
//调用InputInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
InputInter.input(element, text);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("向“" + name + "”对应控件中输入“" + text + "”");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,202 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.inter.CommenElementClearInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.CommenElementClickInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.CommenElementGetTextInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.CommenElementInputInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.CommenElementJudgeTextInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.CommenElementSelectInter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>Event.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b> 该类提供各个事件类的入口,同时,所有的事件方法的返回值保存在类中,通过{@link #getStringValve()}或
|
|
||||||
* {@link #getBooleanValue()}方法,对返回值进行返回。类中提供基本的事件,包括鼠标左键单击事件、输入事件、获取文本事件
|
|
||||||
* 和清空事件以及选择下拉框事件。在该类允许直接切换窗体及iframe和对alert的操作。
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年8月28日下午5:01:33
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年9月25日下午3:03:33
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class Event extends AbstractEvent implements CommenElementClickInter, CommenElementClearInter,
|
|
||||||
CommenElementGetTextInter, CommenElementInputInter, CommenElementJudgeTextInter, CommenElementSelectInter {
|
|
||||||
/**
|
|
||||||
* 用于单例模式的设计
|
|
||||||
*/
|
|
||||||
private static Event event = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存储可返回的TextEvent类对象
|
|
||||||
*/
|
|
||||||
private TextEvent textEvent;
|
|
||||||
/**
|
|
||||||
* 存储可返回的ClickEvent类对象
|
|
||||||
*/
|
|
||||||
private ClickEvent clickEvent;
|
|
||||||
/**
|
|
||||||
* 存储可返回的SelectEvent类对象
|
|
||||||
*/
|
|
||||||
private SelectEvent selectEvent;
|
|
||||||
/**
|
|
||||||
* 存储可返回的JudgeEvent类对象
|
|
||||||
*/
|
|
||||||
private JudgeEvent judgeEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存储可返回的JsEvent类对象
|
|
||||||
*/
|
|
||||||
private JsEvent jsEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于存储各个事件的返回值
|
|
||||||
*/
|
|
||||||
private static EventResultEnum value;
|
|
||||||
|
|
||||||
// 私有所有的构造,保证类对象唯一
|
|
||||||
/**
|
|
||||||
* 传入WebDriver对象,构造Event类对象
|
|
||||||
*
|
|
||||||
* @param driver WebDriver对象
|
|
||||||
*/
|
|
||||||
private Event(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于通过WebDriver对象来创建Event类对象,当已创建过Event类对象时,则返回上次创建的Event类对象
|
|
||||||
*
|
|
||||||
* @param driver WebDriver对象
|
|
||||||
* @return Event类对象
|
|
||||||
*/
|
|
||||||
public static Event newInstance(WebDriver driver) {
|
|
||||||
// 判断对象是否存储,若不存在,则进行构造
|
|
||||||
// 若对象存在,则判断其当前WebDriver对象是否与传入的WebDriver对象相同,若不相同,则重新构造
|
|
||||||
return event == null ? (event = new Event(driver)) : (event.getDriver() == driver ? event : (event = new Event(driver)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回一个TextEvent(文本事件)类对象
|
|
||||||
*
|
|
||||||
* @return TextEvent类对象
|
|
||||||
*/
|
|
||||||
public TextEvent getTextEvent() {
|
|
||||||
// 先判断是否存在对象,若不存在,则创建,
|
|
||||||
return textEvent == null ? new TextEvent(getDriver()) : textEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回一个ClickEvent(点击事件)类对象
|
|
||||||
*
|
|
||||||
* @return ClickEvent类对象
|
|
||||||
*/
|
|
||||||
public ClickEvent getClickEvent() {
|
|
||||||
// 先判断是否存在对象,若不存在,则创建,
|
|
||||||
return clickEvent == null ? new ClickEvent(getDriver()) : clickEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回一个SelectEvent(下拉框选择事件)类对象
|
|
||||||
*
|
|
||||||
* @return SelectEvent类对象
|
|
||||||
*/
|
|
||||||
public SelectEvent getSelectEvent() {
|
|
||||||
// 先判断是否存在对象,若不存在,则创建,
|
|
||||||
return selectEvent == null ? new SelectEvent(getDriver()) : selectEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回一个JudgeEvent(文本判断事件)类对象
|
|
||||||
*
|
|
||||||
* @return JudgeEvent类对象
|
|
||||||
*/
|
|
||||||
public JudgeEvent getJudgeEvent() {
|
|
||||||
// 先判断是否存在对象,若不存在,则创建,
|
|
||||||
return judgeEvent == null ? new JudgeEvent(getDriver()) : judgeEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回一个JsEvent(Javascript事件)类对象
|
|
||||||
*
|
|
||||||
* @return JsEvent类对象
|
|
||||||
*/
|
|
||||||
public JsEvent getJsEvent() {
|
|
||||||
// 先判断是否存在对象,若不存在,则创建,
|
|
||||||
return jsEvent == null ? new JsEvent(getDriver()) : jsEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于设置事件类方法的返回值
|
|
||||||
*
|
|
||||||
* @param value 进行操作后得到的返回值
|
|
||||||
*/
|
|
||||||
public static void setValue(EventResultEnum value) {
|
|
||||||
Event.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回事件类方法的返回值
|
|
||||||
*
|
|
||||||
* @return 事件类方法的返回值
|
|
||||||
*/
|
|
||||||
public static String getStringValve() {
|
|
||||||
return value == null ? "" : value.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于当事件类方法的返回值为BOOLEAN_FALSE或BOOLEAN_TRUE类型时将返回值由字符串转为boolean类型返回
|
|
||||||
*
|
|
||||||
* @return 事件类方法的返回值
|
|
||||||
*/
|
|
||||||
public static boolean getBooleanValue() {
|
|
||||||
switch (value) {
|
|
||||||
case BOOLEAN_FALSE:
|
|
||||||
return false;
|
|
||||||
case BOOLEAN_TRUE:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("该返回值类型不是boolean类型: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event select(String name, int option) {
|
|
||||||
return getSelectEvent().select(name, option);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event judgeText(String name, boolean keyFull, String key) {
|
|
||||||
return getJudgeEvent().judgeText(name, keyFull, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event input(String name, String text) {
|
|
||||||
return getTextEvent().input(name, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event getText(String name) {
|
|
||||||
return getTextEvent().getText(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event clear(String name) {
|
|
||||||
return getTextEvent().clear(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event click(String name) {
|
|
||||||
return getClickEvent().click(name);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
public class EventConstants {
|
|
||||||
/**
|
|
||||||
* 用于将秒转为毫秒
|
|
||||||
*/
|
|
||||||
public static final int CURR_SEC_MS_SCALED = 1000;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于每次到页面查找控件的时间
|
|
||||||
*/
|
|
||||||
public static final int FIND_TIME = 200;
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>EventResultEnum.java</p>
|
|
||||||
* <p><b>用途:</b>用于枚举事件类的返回值类型,并可以通过类中提供的{@link #getValue()}方法对返回值进行返回</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月31日上午14:20:04</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月2日上午8:41:04</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public enum EventResultEnum {
|
|
||||||
/**
|
|
||||||
* 返回值为boolean类型false
|
|
||||||
*/
|
|
||||||
BOOLEAN_FALSE("false"),
|
|
||||||
/**
|
|
||||||
* 返回值为boolean类型true
|
|
||||||
*/
|
|
||||||
BOOLEAN_TRUE("true"),
|
|
||||||
/**
|
|
||||||
* 无返回值类型
|
|
||||||
*/
|
|
||||||
VOID(""),
|
|
||||||
/**
|
|
||||||
* 数字返回值类型
|
|
||||||
*/
|
|
||||||
NUMBER("0"),
|
|
||||||
/**
|
|
||||||
* 字符串返回值类型
|
|
||||||
*/
|
|
||||||
STRING("");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多组返回值时的分隔符
|
|
||||||
*/
|
|
||||||
public final static String TEXT_SEPARATOR = ",";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存储枚举的值
|
|
||||||
*/
|
|
||||||
private String value;
|
|
||||||
/**
|
|
||||||
* 用于作为判断传值是否为数字的正则表达式
|
|
||||||
*/
|
|
||||||
private final String NUMBER_REGEX = "-?\\d+(\\.\\d+)?";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化枚举中的值
|
|
||||||
* @param value 枚举值
|
|
||||||
*/
|
|
||||||
private EventResultEnum(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于返回枚举中的值
|
|
||||||
* @return 枚举中的值
|
|
||||||
*/
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于设置枚举中的值,请注意,只能修改STRING和符合正则的NUMBER类型的值,其他的类型或不符合正则的数字,修改无效,依然是原始值
|
|
||||||
* @param value 需要修改的值
|
|
||||||
*/
|
|
||||||
public EventResultEnum setValue(String value) {
|
|
||||||
if (this == EventResultEnum.STRING) {
|
|
||||||
this.value = value;
|
|
||||||
} else if (this == EventResultEnum.NUMBER) {
|
|
||||||
if (Pattern.compile(NUMBER_REGEX).matcher(value).matches()) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>IncorrectGrammarException.java</p>
|
|
||||||
* <p><b>用途:</b>文本语法有误时抛出的异常</p>
|
|
||||||
* <p><b>编码时间:</b>2019年10月9日下午5:34:34</p>
|
|
||||||
* <p><b>修改时间:</b>2019年10月9日下午5:34:34</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class IncorrectGrammarException extends RuntimeException {
|
|
||||||
|
|
||||||
public IncorrectGrammarException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectGrammarException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
|
|
||||||
super(arg0, arg1, arg2, arg3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectGrammarException(String arg0, Throwable arg1) {
|
|
||||||
super(arg0, arg1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectGrammarException(String arg0) {
|
|
||||||
super(arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectGrammarException(Throwable arg0) {
|
|
||||||
super(arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,175 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.openqa.selenium.JavascriptExecutor;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebDriverException;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.xml.ByType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>JsEvent.java</p>
|
|
||||||
* <p><b>用途:</b>提供通过Javascript来修改或者获取页面元素内容的方法</p>
|
|
||||||
* <p><b>编码时间:</b>2018年12月2日 下午12:51:19</p>
|
|
||||||
* <p><b>修改时间:</b>2019年10月7日下午4:54:52</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JsEvent extends AbstractEvent {
|
|
||||||
/**
|
|
||||||
* 用于使用js
|
|
||||||
*/
|
|
||||||
private JavascriptExecutor js;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造对象
|
|
||||||
* @param driver 页面WebDriver对象
|
|
||||||
*/
|
|
||||||
public JsEvent(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
js = (JavascriptExecutor) getDriver();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并获取元素的属性值,若属性不存在时,则返回空串。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为元素属性的值,可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param attributeName 元素属性名
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取
|
|
||||||
*/
|
|
||||||
public Event getAttribute(String name, String attributeName) {
|
|
||||||
try {
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue((String) (js.executeScript("return " + getScript(name) + ".getAttribute('" + attributeName + "')"))));
|
|
||||||
} catch ( WebDriverException e ) {
|
|
||||||
//当当前元素无此属性时,则返回空
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并设置元素的属性值或者添加属性。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为元素属性的原值,可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param attributeName 元素属性名
|
|
||||||
* @param value 需要设置的属性值
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取
|
|
||||||
*/
|
|
||||||
public Event setAttribute(String name, String attributeName, String value) {
|
|
||||||
// 存储脚本
|
|
||||||
String script = getScript(name);
|
|
||||||
// 获取原属性中的值
|
|
||||||
String oldValue = getAttribute(name, attributeName).getStringValve();
|
|
||||||
|
|
||||||
//判断传入的对象是否为null,为null则执行删除命令
|
|
||||||
if ( value != null ) {
|
|
||||||
// 拼接脚本
|
|
||||||
script += (".setAttribute('" + attributeName + "','" + value + "');");
|
|
||||||
} else {
|
|
||||||
// 拼接脚本
|
|
||||||
script += (".removeAttribute('" + attributeName + "');");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 执行代码
|
|
||||||
js.executeScript(script);
|
|
||||||
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(oldValue));
|
|
||||||
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并向元素下添加一个新的元素,并返回其元素的查找xpath。注意,通过该方法创建的元素会自带
|
|
||||||
* 一个名为“temp_attribute”的属性,其值为一个uuid,以方便查找元素。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为新节点的xpath,可参见{@link EventResultEnum}类。
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param elementName 待添加元素的标签名称
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取
|
|
||||||
*/
|
|
||||||
public Event addElement(String name, String elementName) {
|
|
||||||
// 获取并将其作为
|
|
||||||
String script = "var oldElement = " + getScript(name) + ";";
|
|
||||||
// 拼接添加元素的代码
|
|
||||||
script += "var newElement = document.createElement('" + elementName + "');";
|
|
||||||
// 给新的元素添加一个属性,并将其值设为UUID,使其可被搜索得到
|
|
||||||
String uuid = UUID.randomUUID().toString();
|
|
||||||
script += "newElement.setAttribute('temp_attribute', '" + uuid + "');";
|
|
||||||
// 向指定位置添加节点
|
|
||||||
script += "oldElement.appendChild(newElement);";
|
|
||||||
|
|
||||||
// 执行代码
|
|
||||||
js.executeScript(script);
|
|
||||||
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue("//" + elementName + "[@temp_attribute=\"" + uuid + "\"]"));
|
|
||||||
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并删除该元素。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#VOID},可参见{@link EventResultEnum}类。
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取
|
|
||||||
*/
|
|
||||||
public Event deleteElement(String name) {
|
|
||||||
//获取节点
|
|
||||||
String script = "var deleteNode = " + getScript(name) + ";";
|
|
||||||
//获取节点的父节点
|
|
||||||
script += "var parentNode = deleteNode.parentNode;";
|
|
||||||
//通过父节点来删除子节点
|
|
||||||
script += "parentNode.removeChild(deleteNode)";
|
|
||||||
|
|
||||||
// 执行代码
|
|
||||||
js.executeScript(script);
|
|
||||||
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于执行已经写好的js脚本
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#VOID},可参见{@link EventResultEnum}类。
|
|
||||||
* @param script js脚本
|
|
||||||
*/
|
|
||||||
public Event runScript(String script) {
|
|
||||||
// 执行代码
|
|
||||||
js.executeScript(script);
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于识别传入的控件模型,并将定位的代码的直接返回
|
|
||||||
*
|
|
||||||
* @param text 元素名称或元素的定位方式
|
|
||||||
* @return 返回页面元素WebElement对象
|
|
||||||
*/
|
|
||||||
private String getScript(String text) {
|
|
||||||
// 存储脚本
|
|
||||||
String script = "";
|
|
||||||
|
|
||||||
String[] element = getElementPosition(text).split("=");
|
|
||||||
// 判断定位方式,若定位方式为css,则按照querySelector()方式进行选择,其他的方式均按照xpath来获取
|
|
||||||
if (ByType.XPATH.getValue().equalsIgnoreCase(element[0])) {
|
|
||||||
script = "document.evaluate('" + element[1]
|
|
||||||
+ "', document, null, XPathResult.ANY_TYPE, null).iterateNext()";
|
|
||||||
} else if (ByType.CSS.getValue().equalsIgnoreCase(element[0])) {
|
|
||||||
script = "document.querySelector(" + element[1] + ")";
|
|
||||||
} else {
|
|
||||||
script = "document.evaluate('//*[@" + element[0] + "=\"" + element[1]
|
|
||||||
+ "\"]', document, null, XPathResult.ANY_TYPE, null).iterateNext()";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回页面元素对象
|
|
||||||
return script;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,141 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import org.openqa.selenium.StaleElementReferenceException;
|
|
||||||
import org.openqa.selenium.TimeoutException;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.inter.JudgeEventInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.JudgeKeyInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.JudgeTextInter;
|
|
||||||
import pres.auxiliary.selenium.tool.RecordTool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>JudgeEvent.java</p>
|
|
||||||
* <p><b>用途:</b>定义了对控件进行判断操作相关的方法,可通过该类,对页面数据进行基判断</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月2日下午7:09:13</p>
|
|
||||||
* <p><b>修改时间:</b>2019年11月29日上午9:53:37</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class JudgeEvent extends CommenElementEvent implements JudgeEventInter {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造JudgeEvent类对象
|
|
||||||
* @param driver WebDriver类对象
|
|
||||||
*/
|
|
||||||
public JudgeEvent(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event judgeKey(String name, boolean keyFull, String... keys) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
//调用JudgeKeyInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
JudgeKeyInter.judgeKey(element, keyFull, keys);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
//记录步骤
|
|
||||||
// 拼接传入的关键词
|
|
||||||
String text = "";
|
|
||||||
for (String key : keys) {
|
|
||||||
text += (key + "、");
|
|
||||||
}
|
|
||||||
text = text.substring(0, text.length() - 1);
|
|
||||||
|
|
||||||
//根据keyFull的不同记录的文本将有改变
|
|
||||||
if (keyFull) {
|
|
||||||
RecordTool.recordStep("判断“" + name + "”对应的控件中的内容是否包含所有关键词(关键词为:" + text + ")");
|
|
||||||
} else {
|
|
||||||
RecordTool.recordStep("判断“" + name + "”对应的控件中的内容是否包含部分关键词(关键词为:" + text + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event judgeText(String name, boolean keyFull, String key) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
//调用JudgeTextInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
JudgeTextInter.judgeText(element, keyFull, key);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
//根据keyFull的不同记录的文本将有改变
|
|
||||||
if (keyFull) {
|
|
||||||
RecordTool.recordStep("判断“" + name + "”对应的控件中的内容是否与所有关键词“" + key + "”一致");
|
|
||||||
} else {
|
|
||||||
RecordTool.recordStep("判断“" + name + "”对应的控件中的内容是否包含关键词“" + key + "”");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event judgeControl(String name) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
// 判断页面上是否存在该元素,若抛出TimeoutException或UnrecognizableLocationModeException异常则说明元素不存在
|
|
||||||
try {
|
|
||||||
judgeElementMode(name);
|
|
||||||
Event.setValue(EventResultEnum.BOOLEAN_TRUE);
|
|
||||||
} catch (TimeoutException | UnrecognizableLocationModeException e) {
|
|
||||||
Event.setValue(EventResultEnum.BOOLEAN_FALSE);
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("判断页面是否包含“" + name + "”控件");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,178 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.openqa.selenium.NoSuchElementException;
|
|
||||||
import org.openqa.selenium.TimeoutException;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.tool.RecordTool;
|
|
||||||
|
|
||||||
public abstract class ListElementEvent extends AbstractEvent {
|
|
||||||
/**
|
|
||||||
* 用于标记首行是否为标题行
|
|
||||||
*/
|
|
||||||
private boolean fristRowTitle = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于存储一列列表的数据并返回其相应的列表事件
|
|
||||||
*/
|
|
||||||
protected LinkedHashMap<String, ArrayList<WebElement>> elements = new LinkedHashMap<>(16);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当列表元素获取为空时,设置的重新获取次数
|
|
||||||
*/
|
|
||||||
private int toDataCount = 3;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置列表的首行是否为标题行
|
|
||||||
*
|
|
||||||
* @param isTitleRow 列表首行是否为标题行
|
|
||||||
*/
|
|
||||||
public void setFristRowTitle(boolean fristRowTitle) {
|
|
||||||
this.fristRowTitle = fristRowTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于设置列表数据获取为空时重新获取的次数,在限制次数内,列表未获取到元素,则重新对列表进行一次获取,直到获取到列表元素或达到次数上限为止
|
|
||||||
* @param toDataCount 自动重新获取次数
|
|
||||||
*/
|
|
||||||
public void setToDataCount(int toDataCount) {
|
|
||||||
this.toDataCount = toDataCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造对象
|
|
||||||
* @param driver 页面WebDriver对象
|
|
||||||
*/
|
|
||||||
public ListElementEvent(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并将查到的一组元素进行存储。该方法可传入多个元素定位参数。
|
|
||||||
*
|
|
||||||
* @param names 一组控件的名称或xpath与css定位方式
|
|
||||||
*/
|
|
||||||
public void add(String... names) {
|
|
||||||
for (String name : names) {
|
|
||||||
RecordTool.recordStep("获取“" + name + "”定位方式对应的列");
|
|
||||||
|
|
||||||
//判断当前列名是否存在,不存在,则先存储其类名
|
|
||||||
if (!elements.containsKey(name)) {
|
|
||||||
elements.put(name, new ArrayList<WebElement>());
|
|
||||||
}
|
|
||||||
|
|
||||||
//循环,直到获取到列表元素或者达到重获次数限制为止
|
|
||||||
for (int count = 0; count < toDataCount; count++) {
|
|
||||||
try {
|
|
||||||
//存储获取到的数据
|
|
||||||
elements.get(name).addAll(judgeElementModes(name));
|
|
||||||
|
|
||||||
//若首行为标题行,则删除当前存储列的第一个元素
|
|
||||||
if (fristRowTitle) {
|
|
||||||
elements.get(name).remove(0);
|
|
||||||
}
|
|
||||||
} catch (TimeoutException excetion) {
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断获取到的数据的个数是否为0,若为0,则
|
|
||||||
if (elements.get(name).size() == 0) {
|
|
||||||
if (count == toDataCount - 1) {
|
|
||||||
//若在页面未找到元素,则记录异常信息,但不结束获取
|
|
||||||
RecordTool.recordMark("“" + name + "”对应的定位方式获取超时");
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//若获取到元素或次数达到限制上限,则结束循环
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空指定的一列元素数据,若未对传入的控件名称或定位方式进行获取时,则该方法调用无效。
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
*/
|
|
||||||
public void clear(String name) {
|
|
||||||
if (elements.containsKey(name)) {
|
|
||||||
elements.get(name).clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定的一列元素的个数,若未对传入的控件名称或定位方式进行获取时,则该方法返回-1。
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return 指定列的元素个数
|
|
||||||
*/
|
|
||||||
public int size(String name) {
|
|
||||||
if (elements.containsKey(name)) {
|
|
||||||
return elements.get(name).size();
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于根据元素下标移除当前列下标对应元素,下标从1开始,1表示第一个元素,0表示随机选择一个元素进行移除。
|
|
||||||
* 下标亦允许传入负数,意为由后向前遍历
|
|
||||||
* @param name 元素列名称
|
|
||||||
* @param index 元素下标
|
|
||||||
*
|
|
||||||
* @throws NoSuchElementException 传入的元素列或元素不存在时抛出的异常
|
|
||||||
*/
|
|
||||||
public int removeElement(String name, int index) {
|
|
||||||
//判断元素是否存在,若元素不存在抛出异常
|
|
||||||
if (!elements.containsKey(name)) {
|
|
||||||
throw new NoSuchElementException("不存在的定位方式:" + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
//若传入的数值大于当前列的总长度,则跑出异常
|
|
||||||
int size = size(name);
|
|
||||||
if (size < Math.abs(index)) {
|
|
||||||
throw new NoSuchElementException("元素不存在,当前列总长度:" + size + ",传入的参数:" + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
//转义下标,删除相应的元素
|
|
||||||
index = getIndex(name, index);
|
|
||||||
elements.get(name).remove(index);
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 由于方法允许传入负数和特殊数字0为下标,并且下标的序号由1开始,故可通过该方法对下标的含义进行转义,得到java能识别的下标
|
|
||||||
* @param index
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected int getIndex(String name, int index) {
|
|
||||||
//判断元素是否存在
|
|
||||||
if (elements.containsKey(name)) {
|
|
||||||
int length = elements.get(name).size();
|
|
||||||
//判断元素下标是否超出范围,由于可以传入负数,故需要使用绝对值
|
|
||||||
if (Math.abs(index) > length) {
|
|
||||||
throw new NoSuchElementException("指定的选项值大于选项的最大值。选项总个数:" + length + ",指定项:" + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断index的值,若大于0,则从前向后遍历,若小于0,则从后往前遍历,若等于0,则随机输入
|
|
||||||
if (index > 0) {
|
|
||||||
//选择元素,正数的选项值从1开始,故需要减小1
|
|
||||||
return index - 1;
|
|
||||||
} else if (index < 0) {
|
|
||||||
//选择元素,由于index为负数,则长度加上选项值即可得到需要选择的选项
|
|
||||||
return length + index;
|
|
||||||
} else {
|
|
||||||
//为0,则随机进行选择
|
|
||||||
return new Random().nextInt(length);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new NoSuchElementException("不存在的定位方式:" + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
public class NoSuchWindownException extends RuntimeException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public NoSuchWindownException() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoSuchWindownException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
|
|
||||||
super(arg0, arg1, arg2, arg3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoSuchWindownException(String arg0, Throwable arg1) {
|
|
||||||
super(arg0, arg1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoSuchWindownException(String arg0) {
|
|
||||||
super(arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoSuchWindownException(Throwable arg0) {
|
|
||||||
super(arg0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,227 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import org.openqa.selenium.StaleElementReferenceException;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.support.ui.UnexpectedTagNameException;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.inter.SelectEventInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.SelectFirstInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.SelectInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.SelectLastInter;
|
|
||||||
import pres.auxiliary.selenium.tool.RecordTool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>SelectEvent.java</p>
|
|
||||||
* <p><b>用途:</b>定义了对控件进行点击操作相关的方法,可通过该类,对页面的下拉框控件进行选择操作</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月29日下午3:55:34</p>
|
|
||||||
* <p><b>修改时间:</b>2019年11月29日上午9:53:37</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SelectEvent extends CommenElementEvent implements SelectEventInter {
|
|
||||||
/**
|
|
||||||
* 构造SelectEvent类对象
|
|
||||||
* @param driver WebDriver类对象
|
|
||||||
*/
|
|
||||||
public SelectEvent(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event selectLast(String name) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
//调用SelectLastInter接口的静态方法,将对页面下拉框进行选择,若下拉选项不是标准的下拉框,则会抛出UnexpectedTagNameException
|
|
||||||
//异常,则此时再选择应对非标准下拉框的方法
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
SelectLastInter.selectLast(judgeElementMode(name));
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (UnexpectedTagNameException e) {
|
|
||||||
//非标准下拉框无法代码高亮
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
SelectLastInter.selectLast(judgeElementModes(name));
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException sere) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("选择“" + name + "”对应控件中的“" + Event.getStringValve() + "”选项");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event select(String name, int option) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
//调用SelectInter接口的静态方法,将对页面下拉框进行选择,若下拉选项不是标准的下拉框,则会抛出UnexpectedTagNameException
|
|
||||||
//异常,则此时再选择应对非标准下拉框的方法
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
SelectInter.select(judgeElementMode(name), option);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (UnexpectedTagNameException e) {
|
|
||||||
//非标准下拉框无法代码高亮
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
SelectInter.select(judgeElementModes(name), option);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException sere) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("选择“" + name + "”对应控件中的“" + Event.getStringValve() + "”选项");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event selectFirst(String name) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
//调用SelectFirstInter接口的静态方法,将对页面下拉框进行选择,若下拉选项不是标准的下拉框,则会抛出UnexpectedTagNameException
|
|
||||||
//异常,则此时再选择应对非标准下拉框的方法
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
SelectFirstInter.selectFirst(element);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (UnexpectedTagNameException e) {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//非标准下拉框无法代码高亮
|
|
||||||
SelectFirstInter.selectFirst(judgeElementModes(name));
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException sere) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("选择“" + name + "”对应控件中的“" + Event.getStringValve() + "”选项");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event select(String name, String optionStr) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
//调用SelectFirstInter接口的静态方法,将对页面下拉框进行选择,若下拉选项不是标准的下拉框,则会抛出UnexpectedTagNameException
|
|
||||||
//异常,则此时再选择应对非标准下拉框的方法
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
SelectInter.select(element, optionStr);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (UnexpectedTagNameException e) {
|
|
||||||
//非标准下拉框无法代码高亮
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
SelectInter.select(judgeElementModes(name), optionStr);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException sere) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("选择“" + name + "”对应控件中的“" + Event.getStringValve() + "”选项");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,309 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.openqa.selenium.Rectangle;
|
|
||||||
import org.openqa.selenium.StaleElementReferenceException;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebDriverException;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.inter.ClearInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.GetAttributeValueInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.GetTextInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.InputInter;
|
|
||||||
import pres.auxiliary.selenium.event.inter.TextEventInter;
|
|
||||||
import pres.auxiliary.selenium.tool.RecognitionImage;
|
|
||||||
import pres.auxiliary.selenium.tool.RecordTool;
|
|
||||||
import pres.auxiliary.selenium.tool.Screenshot;
|
|
||||||
import pres.auxiliary.tool.randomstring.RandomString;
|
|
||||||
import pres.auxiliary.tool.randomstring.StringMode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>TextEvent.java</p>
|
|
||||||
* <p><b>用途:</b>定义了对控件文本操作相关的方法,可通过该类,对页面进行对控件输入,文本获取等操作</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午9:28:59</p>
|
|
||||||
* <p><b>修改时间:</b>2019年11月29日上午9:53:37</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class TextEvent extends CommenElementEvent implements TextEventInter {
|
|
||||||
/**
|
|
||||||
* 定义验证码识别的制定文件夹名称
|
|
||||||
*/
|
|
||||||
private final String TESSDATA = "tessdata";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造TextEvent类对象
|
|
||||||
* @param driver WebDriver类对象
|
|
||||||
*/
|
|
||||||
public TextEvent(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event clear(String name) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
//调用ClearInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
ClearInter.clear(element);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("清空“" + name + "”对应控件中的内容");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event getAttributeValue(String name, String attributeName) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
//调用GetAttributeValueInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
GetAttributeValueInter.getAttributeValue(element, attributeName);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("获取“" + name + "”对应控件" + attributeName + "属性的内容");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event getText(String name) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
//调用GetTextInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
GetTextInter.getText(element);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("获取“" + name + "”对应控件的内容");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event input(String name, String text) {
|
|
||||||
//自动记录异常
|
|
||||||
try {
|
|
||||||
// 为避免出现抛出StaleElementReferenceException(页面过期异常),则通过循环的方式,
|
|
||||||
// 当抛出异常时,则重新获取并操作,若未抛出,则结束循环
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
//获取元素
|
|
||||||
element = judgeElementMode(name);
|
|
||||||
|
|
||||||
//修饰元素
|
|
||||||
elementHight(element);
|
|
||||||
|
|
||||||
//操作元素
|
|
||||||
//调用InputInter接口的静态方法,将从页面上搜索到的控件元素对象传入其中
|
|
||||||
InputInter.input(element, text);
|
|
||||||
break;
|
|
||||||
} catch (StaleElementReferenceException e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception exception) {
|
|
||||||
//捕捉到异常后将异常信息记录在工具中,并将异常抛出
|
|
||||||
RecordTool.recordException(exception);
|
|
||||||
throw exception;
|
|
||||||
} finally {
|
|
||||||
RecordTool.recordStep("向“" + name + "”对应控件中输入“" + text + "”");
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回Event类
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event codeInput(String textName, String codeName) {
|
|
||||||
// 判断验证码信息是否加载,加载后,获取其Rectang对象
|
|
||||||
Rectangle r = judgeElementMode(codeName).getRect();
|
|
||||||
// 构造截图对象,并创建截图
|
|
||||||
Screenshot sc = new Screenshot(getDriver(), "Temp");
|
|
||||||
File image = null;
|
|
||||||
try {
|
|
||||||
image = sc.creatImage("code");
|
|
||||||
} catch (WebDriverException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置图片识别的语言包存放位置
|
|
||||||
RecognitionImage.setTessdataPath(new File(TESSDATA));
|
|
||||||
// 识别图片
|
|
||||||
String text = RecognitionImage.judgeImage(image, r.x, r.y, r.width, r.height);
|
|
||||||
|
|
||||||
// 删除生成的图片及文件夹
|
|
||||||
image.delete();
|
|
||||||
new File("Temp").delete();
|
|
||||||
|
|
||||||
return input(textName, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event avgIntergeInput(int num, String... names) {
|
|
||||||
//定义存储控件数量及需要随机的数量
|
|
||||||
int contrlNum = names.length;
|
|
||||||
String inputNumText = "";
|
|
||||||
String[] inputNum = new String[contrlNum];
|
|
||||||
|
|
||||||
// 向下取整获得平均数
|
|
||||||
int avgNum = num / contrlNum;
|
|
||||||
// 向上取整获得差值
|
|
||||||
int diffNum = (int) Math.ceil(avgNum / 10.0);
|
|
||||||
|
|
||||||
//求取通过随机得出的值之和,用于计算最终其随机值之和与实际值的差值
|
|
||||||
int sum = 0;
|
|
||||||
//循环,生成控件个数个随机值,其随机值在给定数值的均值之前
|
|
||||||
for (int i = 0; i < contrlNum; i++) {
|
|
||||||
//注意:2 * diffNum为以下算式的简写:
|
|
||||||
//minNum = avgNum - diffNum;
|
|
||||||
//maxNum = avgNum + diffNum;
|
|
||||||
//int ranNum = new Random().nextInt(maxNum - minNum + 1) + minNum;
|
|
||||||
int ranNum = new Random().nextInt(2 * diffNum + 1) + (avgNum - diffNum);
|
|
||||||
sum += ranNum;
|
|
||||||
inputNum[i] = String.valueOf(ranNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
//由于数值是随机的,可能会出现随机值相加不为指定值,故需要补上差值,但由于差值通过算法后不会很大,故可随机附加到一个控件值上
|
|
||||||
if ( (diffNum = sum - num) != 0 ) {
|
|
||||||
inputNum[new Random().nextInt(contrlNum)] = String.valueOf(Integer.valueOf(inputNum[new Random().nextInt(contrlNum)]) - diffNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
//将随机值填写至控件中
|
|
||||||
for (int i = 0; i < contrlNum; i++) {
|
|
||||||
input(names[i], inputNum[i]);
|
|
||||||
inputNumText += (Event.getStringValve() + ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(inputNumText.substring(0, inputNumText.length() - 1)));
|
|
||||||
return Event.newInstance(getDriver());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event randomInput(String name, int minLength, int maxLength, StringMode... modes) {
|
|
||||||
// 判断传入的参数是否小于0,小于0则将其都设置为1
|
|
||||||
if (minLength < 0 || maxLength < 0) {
|
|
||||||
minLength = 1;
|
|
||||||
maxLength = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断传入的随机字符串最小生成长度是否大于最大生成长度,若大于,则调换两数字的位置
|
|
||||||
if (minLength > maxLength) {
|
|
||||||
int tem = minLength;
|
|
||||||
minLength = maxLength;
|
|
||||||
maxLength = tem;
|
|
||||||
}
|
|
||||||
|
|
||||||
//根据参数,生成随机字符串
|
|
||||||
String text = "";
|
|
||||||
if (minLength == maxLength) {
|
|
||||||
text = new RandomString(modes).toString(maxLength);
|
|
||||||
} else {
|
|
||||||
text = new RandomString(modes).toString(minLength, maxLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
//调用input方法进行返回
|
|
||||||
return input(name, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event randomInput(String name, int minLength, int maxLength, String mode) {
|
|
||||||
// 判断传入的参数是否小于0,小于0则将其都设置为1
|
|
||||||
if (minLength < 0 || maxLength < 0) {
|
|
||||||
minLength = 1;
|
|
||||||
maxLength = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断传入的随机字符串最小生成长度是否大于最大生成长度,若大于,则调换两数字的位置
|
|
||||||
if (minLength > maxLength) {
|
|
||||||
int tem = minLength;
|
|
||||||
minLength = maxLength;
|
|
||||||
maxLength = tem;
|
|
||||||
}
|
|
||||||
|
|
||||||
//根据参数,生成随机字符串
|
|
||||||
String text = "";
|
|
||||||
if (minLength == maxLength) {
|
|
||||||
text = new RandomString(mode).toString(maxLength);
|
|
||||||
} else {
|
|
||||||
text = new RandomString(mode).toString(minLength, maxLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
//调用input方法进行返回
|
|
||||||
return input(name, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Event updataFile(String name, File updataFile) {
|
|
||||||
return input(name, updataFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,264 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
import pres.auxiliary.tool.randomstring.RandomString;
|
|
||||||
import pres.auxiliary.tool.randomstring.StringMode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该类提供根据固定文本格式来选择相应的事件,其相应的文本为:
|
|
||||||
* <p>
|
|
||||||
* 1.输入事件:<br>
|
|
||||||
* 1.1 在 “XXX” 中 输入 “XXX”<br>
|
|
||||||
* 1.2 在 “XXX” 中 随机 输入 6位 “XXX” 字符<br>
|
|
||||||
* 1.3 在 “XXX” 中 随机 输入 6位 “XXX、XXX” 字符<br>
|
|
||||||
* 1.4 在 “XXX” 中 随机 输入 6-10位 “XXX” 字符<br>
|
|
||||||
* 1.5 在 “XXX” 中 随机 输入 6-10位 “XXX、XXX” 字符<br>
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 2.清除事件:<br>
|
|
||||||
* 2.1 清空 “XXX” 中的内容
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 3.获取事件:<br>
|
|
||||||
* 3.1 获取 “XXX” 中的内容
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 4.选择事件:<br>
|
|
||||||
* 4.1 选择 “XXX” 第X个 选项<br>
|
|
||||||
* 4.2 选择 “XXX” 最后 一个选项
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 5.点击事件:<br>
|
|
||||||
* 5.1 点击 “XXX”<br>
|
|
||||||
* 5.2 右击 “XXX”<br>
|
|
||||||
* 5.3 双击 “XXX”
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 6.定位窗体事件:<br>
|
|
||||||
* 6.1 定位 “XXX” 窗体<br>
|
|
||||||
* 6.2 定位“顶层窗体”
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 7.判断事件:<br>
|
|
||||||
* 7.1 判断 “XXX” 中是否 包含 “XXX”<br>
|
|
||||||
* 7.2 判断 “XXX” 中是否 为 “XXX”<br>
|
|
||||||
* 7.3 判断 “XXX” 是否存在
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
*/
|
|
||||||
public class TextToOperation {
|
|
||||||
// 定义事件类
|
|
||||||
private Event event;
|
|
||||||
|
|
||||||
public TextToOperation(Event event) {
|
|
||||||
this.event = event;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加中文步骤
|
|
||||||
*
|
|
||||||
* @param text
|
|
||||||
* 步骤内容
|
|
||||||
* @return 执行返回值
|
|
||||||
*/
|
|
||||||
public String step(String text) {
|
|
||||||
return judgeEventType(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于判根据传入的信息,判断其信息对应的是哪一种事件
|
|
||||||
*/
|
|
||||||
private String judgeEventType(String text) {
|
|
||||||
String name = null;
|
|
||||||
try {
|
|
||||||
// 处理控件名
|
|
||||||
name = text.substring(text.indexOf("“") + 1, text.indexOf("”"));
|
|
||||||
} catch (IndexOutOfBoundsException e) {
|
|
||||||
// 若抛出下标越界异常,则抛出语法错误异常
|
|
||||||
throw new IncorrectGrammarException("控件名缺失");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 对传入的text进行判断
|
|
||||||
if (text.indexOf("在") == 0) {
|
|
||||||
return inputEvent(text.substring(text.indexOf("”") + 1), name);
|
|
||||||
} else if (text.indexOf("清空") == 0) {
|
|
||||||
return clearEvent(name);
|
|
||||||
} else if (text.indexOf("获取") == 0) {
|
|
||||||
return getEvent(name);
|
|
||||||
} else if (text.indexOf("选择") == 0) {
|
|
||||||
return String.valueOf(selectEvent(text.substring(text.indexOf("”") + 1), name));
|
|
||||||
} else if (text.indexOf("击") == 1) {
|
|
||||||
return clickEvent(text.substring(0, text.indexOf("“")), name);
|
|
||||||
} else if (text.indexOf("定位") == 0) {
|
|
||||||
return frameEvent(name);
|
|
||||||
} else if (text.indexOf("判断") == 0) {
|
|
||||||
//return judgeEvent(text.substring(text.indexOf("”") + 1), name);
|
|
||||||
return "";
|
|
||||||
} else {
|
|
||||||
throw new IncorrectGrammarException("类型判断词无法识别");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理定位事件
|
|
||||||
*/
|
|
||||||
private String frameEvent(String name) {
|
|
||||||
String judeg_Text = "顶层窗体";
|
|
||||||
// 判断是否是定位到顶层窗体
|
|
||||||
if (judeg_Text.equals(name)) {
|
|
||||||
event.switchRootFrame();
|
|
||||||
} else {
|
|
||||||
event.switchFrame(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理判断事件
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
private String judgeEvent(String text, String name) {
|
|
||||||
// 处理方式,先将text按照双引号进行切分,若无内容,则说明可能是判断元素是否存在,若有内容,则说明可能是文本判断
|
|
||||||
// 按照双引号的前部分对text的内容进行切分,得到控件名和内容两部分,之后再分别处理
|
|
||||||
String content = null;
|
|
||||||
try {
|
|
||||||
// 处理判断内容
|
|
||||||
content = text.substring(text.indexOf("“") + 1, text.indexOf("”"));
|
|
||||||
// 若未抛出下标越界异常,则说明可能是文本判断
|
|
||||||
// 删除text判断内容的文本,以避免误判断
|
|
||||||
text = new StringBuilder(text).delete(text.indexOf("“"), text.indexOf("”") + 1).toString();
|
|
||||||
|
|
||||||
// 用于判断文本是包含包含还是需要一致
|
|
||||||
boolean f = false;
|
|
||||||
// 判断是文本包含还是元素包含(直接在if中加上对f变量的赋值,若text包含“为”,则赋为true,并可直接通过判断)
|
|
||||||
if ((f = text.indexOf("为") > -1 ? true : false) || text.indexOf("包含") > -1) {
|
|
||||||
// 添加事件
|
|
||||||
return String.valueOf(event.getJudgeEvent().judgeText(name, content, f));
|
|
||||||
} else {
|
|
||||||
// 若抛出下标越界异常,则抛出语法错误异常
|
|
||||||
throw new IncorrectGrammarException("无效的判断词");
|
|
||||||
}
|
|
||||||
} catch (StringIndexOutOfBoundsException e) {
|
|
||||||
// 若抛出下标越界异常,则说明可能是元素判断
|
|
||||||
if (text.indexOf("存在") > -1) {
|
|
||||||
// 添加事件
|
|
||||||
return String.valueOf(event.getJudgeEvent().judgeControl(name));
|
|
||||||
} else {
|
|
||||||
// 若未包含,则说明其表述有误
|
|
||||||
throw new IncorrectGrammarException("无效的判断词");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理点击事件
|
|
||||||
*/
|
|
||||||
private String clickEvent(String text, String name) {
|
|
||||||
// 判断需要使用哪一种点击事件
|
|
||||||
if (text.indexOf("点击") == 0) {
|
|
||||||
event.getClickEvent().click(name);
|
|
||||||
} else if (text.indexOf("双击") == 0) {
|
|
||||||
event.getClickEvent().doubleClick(name);
|
|
||||||
} else if (text.indexOf("右击") == 0) {
|
|
||||||
event.getClickEvent().rightClick(name);
|
|
||||||
} else {
|
|
||||||
throw new IncorrectGrammarException("选择下拉框选项语法缺失");
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理选择事件
|
|
||||||
*/
|
|
||||||
private String selectEvent(String text, String name) {
|
|
||||||
// 判断text中包含“第”或者“最后”,若头不包含,则抛出语法错误异常
|
|
||||||
if (text.indexOf("第") > -1) {
|
|
||||||
// 根据语法获取需要的选项
|
|
||||||
int option = Integer.valueOf(text.substring(text.indexOf("第") + 1, text.indexOf("个")));
|
|
||||||
// 添加事件
|
|
||||||
return event.getSelectEvent().select(name, option).getStringValve();
|
|
||||||
} else if (text.indexOf("最后") > -1) {
|
|
||||||
return event.getSelectEvent().selectLast(name).getStringValve();
|
|
||||||
} else {
|
|
||||||
throw new IncorrectGrammarException("选择下拉框选项语法缺失");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理获取事件
|
|
||||||
*/
|
|
||||||
private String getEvent(String name) {
|
|
||||||
// 添加事件
|
|
||||||
return event.getTextEvent().getText(name).getStringValve();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理清空事件
|
|
||||||
*/
|
|
||||||
private String clearEvent(String name) {
|
|
||||||
// 添加事件
|
|
||||||
return event.getTextEvent().clear(name).getStringValve();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理输入事件
|
|
||||||
*/
|
|
||||||
private String inputEvent(String text, String name) {
|
|
||||||
// 按照双引号的前部分对text的内容进行切分,得到控件名和内容两部分,之后再分别处理
|
|
||||||
String content = null;
|
|
||||||
try {
|
|
||||||
// 处理输入内容
|
|
||||||
content = text.substring(text.indexOf("“") + 1, text.indexOf("”"));
|
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
|
||||||
// 若抛出下标越界异常,则抛出语法错误异常
|
|
||||||
throw new IncorrectGrammarException("输入内容缺失");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断是否包含“随机”二字,有,则按照随机的方式进行处理
|
|
||||||
if (text.indexOf("随机") > -1) {
|
|
||||||
// 定义随机字符串类,用于生成相应的随机字符串
|
|
||||||
RandomString rs = new RandomString();
|
|
||||||
// 循环,读取所有的模型
|
|
||||||
for (String mode : content.split("、")) {
|
|
||||||
// 判断需要加入到随机字符串中的模型
|
|
||||||
if (mode.equalsIgnoreCase("中文")) {
|
|
||||||
rs.addMode(StringMode.CH);
|
|
||||||
} else if (mode.equalsIgnoreCase("小写字母")) {
|
|
||||||
rs.addMode(StringMode.LOW);
|
|
||||||
} else if (mode.equalsIgnoreCase("大写字母")) {
|
|
||||||
rs.addMode(StringMode.CAP);
|
|
||||||
} else if (mode.equalsIgnoreCase("数字")) {
|
|
||||||
rs.addMode(StringMode.NUM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断模型是否未加载
|
|
||||||
if ("".equals(rs.getStringSeed())) {
|
|
||||||
throw new IncorrectGrammarException("输入的随机模型信息有误");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 在判断是否有长度分隔符,根据其结果来对事件进行处理
|
|
||||||
if (text.indexOf("-") > -1) {
|
|
||||||
// 获取间隔长度的最小值
|
|
||||||
int min = Integer.valueOf(text.substring(text.indexOf("输入") + 2, text.indexOf("-")));
|
|
||||||
// 获取间隔长度的最大值
|
|
||||||
int max = Integer.valueOf(text.substring(text.indexOf("-") + 1, text.indexOf("位")));
|
|
||||||
|
|
||||||
// 添加事件
|
|
||||||
return event.getTextEvent().randomInput(name, min, max, rs.getStringSeed()).getStringValve();
|
|
||||||
} else {
|
|
||||||
// 获取需要输入的长度
|
|
||||||
int len = Integer.valueOf(text.substring(text.indexOf("输入") + 2, text.indexOf("位")));
|
|
||||||
|
|
||||||
// 添加事件
|
|
||||||
return event.getTextEvent().randomInput(name, len, len, rs.getStringSeed()).getStringValve();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 若不是随机输入,则按照正常的输入方式添加事件
|
|
||||||
return event.getTextEvent().input(name, content).getStringValve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ClearInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义控件内容清空事件的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午8:19:34</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月6日上午8:19:34</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface ClearInter {
|
|
||||||
/**
|
|
||||||
* 用于判断标签名是否为“input”
|
|
||||||
*/
|
|
||||||
static final String TAGNAME_INPUT = "input";
|
|
||||||
/**
|
|
||||||
* 该方法通过控件名称或定位方式对页面元素进行定位来清空控件中的内容,主要用于清空文本框中已有的数据。
|
|
||||||
* 本操作的的返回值是{@link EventResultEnum#STRING},其枚举的值为输入到控件的内容;参见{@link EventResultEnum}类。
|
|
||||||
* 该方法将返回值可通过类{@link Event}中的{@link Event#getStringValve()}方法进行返回。
|
|
||||||
* @param element 通过查找页面得到的控件元素对象
|
|
||||||
*/
|
|
||||||
static void clear(WebElement element) {
|
|
||||||
// 判断元素是否为input元素,如果是,则获取其value值,若不是则调用getText()方法
|
|
||||||
if (TAGNAME_INPUT.equalsIgnoreCase(element.getTagName())) {
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(element.getAttribute("value")));
|
|
||||||
} else {
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(element.getText()));
|
|
||||||
}
|
|
||||||
//清空元素中的内容
|
|
||||||
element.clear();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ClickEventInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口集合普通元素的所有点击相关的事件,可在此处扩展新的方法</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:15:39</p>
|
|
||||||
* <p><b>修改时间:</b>2019年8月29日下午3:15:39</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface ClickEventInter
|
|
||||||
extends CommenElementClickInter, CommenElementDoubleClickInter, CommenElementRightClickInter {
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ClickInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义鼠标左键单击事件的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:16:45</p>
|
|
||||||
* <p><b>修改时间:</b>2019年12月29日下午1:41:45</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface ClickInter {
|
|
||||||
/**
|
|
||||||
* 鼠标左键单击事件的处理方法。本操作的的返回值是{@link EventResultEnum#VOID},
|
|
||||||
* 其枚举的值为空串;参见{@link EventResultEnum}类。该方法将返回值可通过类{@link Event}中
|
|
||||||
* 的{@link Event#getStringValve()}方法进行返回。
|
|
||||||
*
|
|
||||||
* @param element 通过查找页面得到的控件元素对象
|
|
||||||
*/
|
|
||||||
static void click(WebElement element) {
|
|
||||||
//进行元素的点击事件
|
|
||||||
element.click();
|
|
||||||
//设置返回值为空
|
|
||||||
Event.setValue(EventResultEnum.VOID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>CommenElementClearInter.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>该接口定义了普通元素内容清空事件的实现标准
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年9月6日上午8:31:24
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年9月6日上午8:31:24
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementClearInter extends ClearInter {
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并对控件中的内容进行清空操作。主要用于清空文本框中已有的数据。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为控件中原有的内容,可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Event clear(String name);
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>CommenElementClickInter.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>该接口定义了普通元素鼠标左键单击事件的实现标准
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年8月29日下午3:18:14
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年8月29日下午3:18:14
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementClickInter extends ClickInter {
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并进行鼠标左键单击操作。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#VOID},其枚举的value值为空串,可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event click(String name);
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>CommenElementDoubleClickInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了普通元素鼠标左键双击事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:21:31</p>
|
|
||||||
* <p><b>修改时间:</b>2019年8月29日下午3:21:31</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementDoubleClickInter extends DoubleClickInter {
|
|
||||||
/**
|
|
||||||
* 通过传入传入的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,进行鼠标左键双击操作。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#VOID},其枚举的value值为空串,可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event doubleClick(String name);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>CommenElementGetAttributeValueInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了获取普通元素在html标签下属性值事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午8:45:54</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月6日上午8:45:54</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementGetAttributeValueInter extends GetAttributeValueInter {
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并获取元素的指定属性值的内容。本操作返回的枚举值
|
|
||||||
* 是{@link EventResultEnum#STRING},其枚举的value值为获取到的控件指定属性的内容,可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param attributeName 属性名称
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event getAttributeValue(String name, String attributeName);
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>CommenElementGetTextInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了获取普通元素内容事件事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午8:37:20</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月6日上午8:37:20</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementGetTextInter extends GetTextInter {
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并获取其中的内容。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为控件中的文本内容,可参见{@link EventResultEnum}类。
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event getText(String name);
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>CommenElementInputInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了普通元素输入事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午8:17:21</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月6日上午8:17:21</p>
|
|
||||||
* @author
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementInputInter extends InputInter {
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并在控件中输入指定的内容。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为输入到控件中的内容,可参见{@link EventResultEnum}类。
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param text 待输入的内容
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event input(String name, String text);
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>CommenElementJudgeKeyInter.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>该接口定义了普通元素对多个关键词判断事件的实现标准
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年9月2日下午2:28:59
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年9月2日下午2:28:59
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementJudgeKeyInter extends JudgeKeyInter {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并获取控件中的文本,判断文本中是否包含传入的关键词,根据keyFull来判断是否需要所有的
|
|
||||||
* 关键词都包含在文本中,例如有如下标签:<br>
|
|
||||||
* <p id="h">请输入正确填写关键词</p>
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 则如下调用时,结果为true:<br>
|
|
||||||
* judgeKey("//p[@id='h']", true, "请输入", "关键词");<br>
|
|
||||||
* judgeKey("//p[@id='h']", false, "标题", "关键词");
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 如下调用时,结果为false:<br>
|
|
||||||
* judgeKey("//p[@id='h']", true, "标题", "关键词");<br>
|
|
||||||
* judgeKey("//p[@id='h']", false, "标题", "内容");
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#BOOLEAN_FALSE}或,{@link EventResultEnum#BOOLEAN_TRUE}
|
|
||||||
* 其枚举的value值为判断的结果,以字符串的形式存储"false"及"true",可参见{@link EventResultEnum}类。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param keyFull 是否需要所有关键词都包含
|
|
||||||
* @param keys 关键词组
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值,
|
|
||||||
* 亦可通过{@link Event#getBooleanValve()}方法将枚举值转换为boolean进行返回
|
|
||||||
*/
|
|
||||||
Event judgeKey(String name, boolean keyFull, String... keys);
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>CommenElementJudgeTextInter.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>该接口定义了普通元素对单个关键词判断事件的实现标准
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年9月2日下午2:39:26
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年9月2日下午2:39:26
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementJudgeTextInter extends JudgeTextInter {
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并判断控件中的文本是否包含或者与关键词一致。本操作返回的枚举值是{@link EventResultEnum#BOOLEAN_FALSE}或,{@link EventResultEnum#BOOLEAN_TRUE}
|
|
||||||
* 其枚举的value值为判断的结果,以字符串的形式存储"false"及"true",可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param name 控件名称控件定位的xpath或者css路径
|
|
||||||
* @param textFull 是否需要与页面文本完全一致
|
|
||||||
* @param key 关键词
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值,
|
|
||||||
* 亦可通过{@link Event#getBooleanValve()}方法将枚举值转换为boolean进行返回
|
|
||||||
*/
|
|
||||||
Event judgeText(String name, boolean keyFull, String key);
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>CommenElementRightClickInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了普通元素鼠标右键单击事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:21:55</p>
|
|
||||||
* <p><b>修改时间:</b>2019年8月29日下午3:21:55</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementRightClickInter extends RightClickInter {
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并进行鼠标右键单击操作。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#BOOLEAN_FALSE}或,{@link EventResultEnum#BOOLEAN_TRUE}
|
|
||||||
* 其枚举的value值为判断的结果,以字符串的形式存储"false"及"true",可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值,
|
|
||||||
* 亦可通过{@link Event#getBooleanValve()}方法将枚举值转换为boolean进行返回
|
|
||||||
*/
|
|
||||||
Event rightClick(String name);
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>CommenElementSelectFirstInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了普通元素选择下拉框第一个选线事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月3日下午4:27:40</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月3日下午4:27:40</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementSelectFirstInter extends SelectFirstInter {
|
|
||||||
/**
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并对标准的web下拉框(由标签select和标签option构成)选择其下拉框第一个选项,
|
|
||||||
* 亦可以对非标准的下拉框(由大量的div等标签组成)进行操作,但对于非标准的下拉框,需要传入的是选项列表,例如:<br>
|
|
||||||
* 标准下拉框:<br>
|
|
||||||
* <select id='test'><br>
|
|
||||||
*  <option>男</option><br>
|
|
||||||
*  <option>女</option><br>
|
|
||||||
*  <option>其他</option><br>
|
|
||||||
* </select><br>
|
|
||||||
* 对于该标准的下拉框选项,只需要定位到//select[@id='test'],得到其WebElement对象即可,但对于非标准的下拉框其下拉框是由input和button标签构成:<br>
|
|
||||||
* <div><br>
|
|
||||||
*  <span><input/></span><br>
|
|
||||||
*  <span><button/></span><br>
|
|
||||||
* </div><br>
|
|
||||||
* 点击button对应的按钮后,其下也能弹出选项,但其选项是由div标签写入text构成:<br>
|
|
||||||
* <div id='test'><br>
|
|
||||||
*  <div>男</div><br>
|
|
||||||
*  <div>女</div><br>
|
|
||||||
*  <div>其他</div><br>
|
|
||||||
* </div><br>
|
|
||||||
* 对于这种非标准的下拉框选项,需要传入选项所在的所有div标签对应的WebElement元素,在上例,则需要定位到//div[@id='test']/div,
|
|
||||||
* 注意,末尾的div不指定数字,则可以代表整个选项。<br>
|
|
||||||
* <p>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为当前选择选项的内容,可参见{@link EventResultEnum}类。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event selectFirst(String name);
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.NoSuchElementException;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>CommenElementSelectInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了普通元素选择指定选项事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月3日下午4:32:25</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月3日下午4:32:25</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementSelectInter extends SelectInter {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并对标准的web下拉框(由标签select和标签option构成)进行选择,亦可以对非标准的下拉框(由大量的div等标签组成)进行操作,但对于非标准的
|
|
||||||
* 下拉框,需要传入的是选项列表,例如:<br>
|
|
||||||
* 标准下拉框:<br>
|
|
||||||
* <select id='test'><br>
|
|
||||||
*  <option>男</option><br>
|
|
||||||
*  <option>女</option><br>
|
|
||||||
*  <option>其他</option><br>
|
|
||||||
* </select><br>
|
|
||||||
* 对于该标准的下拉框选项,只需要定位到//select[@id='test'],得到其WebElement对象即可,但对于非标准的下拉框其下拉框是由input和button标签构成:<br>
|
|
||||||
* <div><br>
|
|
||||||
*  <span><input/></span><br>
|
|
||||||
*  <span><button/></span><br>
|
|
||||||
* </div><br>
|
|
||||||
* 点击button对应的按钮后,其下也能弹出选项,但其选项是由div标签写入text构成:<br>
|
|
||||||
* <div id='test'><br>
|
|
||||||
*  <div>男</div><br>
|
|
||||||
*  <div>女</div><br>
|
|
||||||
*  <div>其他</div><br>
|
|
||||||
* </div><br>
|
|
||||||
* 对于这种非标准的下拉框选项,需要传入选项所在的所有div标签对应的WebElement元素,在上例,则需要定位到//div[@id='test']/div,
|
|
||||||
* 注意,末尾的div不指定数字,则可以代表整个选项。
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为当前选择选项的内容,可参见{@link EventResultEnum}类。
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b><i>注意:</i></b>option序号从1开始,1表示第一个选项,亦可传入负数,-1表示倒数第一个选项,
|
|
||||||
* -2表示倒数第二个选项,以此类推;当传入的值为0时,则表示随机选择一个选项,但随机的值不包括第一个选项,
|
|
||||||
* 以避免第一个元素为空或为“请选择”之类的选项
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param option 选项的序号,正数表示从前向后选,负数表示从后往前选,0表示随机选择
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
* @throws NoSuchElementException 指定的选项值超过选项的最大值时抛出
|
|
||||||
*/
|
|
||||||
Event select(String name, int option);
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>CommenElementSelectLastInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了普通元素选择下拉框最后一个选项事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月3日下午4:40:46</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月3日下午4:40:46</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommenElementSelectLastInter extends SelectLastInter {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并对标准的web下拉框(由标签select和标签option构成)选择其下拉框最后一个选项,
|
|
||||||
* 亦可以对非标准的下拉框(由大量的div等标签组成)进行操作,但对于非标准的下拉框,需要传入的是选项列表,例如:<br>
|
|
||||||
* 标准下拉框:<br>
|
|
||||||
* <select id='test'><br>
|
|
||||||
*  <option>男</option><br>
|
|
||||||
*  <option>女</option><br>
|
|
||||||
*  <option>其他</option><br>
|
|
||||||
* </select><br>
|
|
||||||
* 对于该标准的下拉框选项,只需要定位到//select[@id='test'],得到其WebElement对象即可,但对于非标准的下拉框其下拉框是由input和button标签构成:<br>
|
|
||||||
* <div><br>
|
|
||||||
*  <span><input/></span><br>
|
|
||||||
*  <span><button/></span><br>
|
|
||||||
* </div><br>
|
|
||||||
* 点击button对应的按钮后,其下也能弹出选项,但其选项是由div标签写入text构成:<br>
|
|
||||||
* <div id='test'><br>
|
|
||||||
*  <div>男</div><br>
|
|
||||||
*  <div>女</div><br>
|
|
||||||
*  <div>其他</div><br>
|
|
||||||
* </div><br>
|
|
||||||
* 对于这种非标准的下拉框选项,需要传入选项所在的所有div标签对应的WebElement元素,在上例,则需要定位到//div[@id='test']/div,
|
|
||||||
* 注意,末尾的div不指定数字,则可以代表整个选项。
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为当前选择选项的内容,可参见{@link EventResultEnum}类。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event selectLast(String name);
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>DataListEventInter.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>该接口定义了列表元素需要使用的基本方法
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年10月8日下午6:50:43
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年10月8日下午6:50:43
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface DataListEventInter extends ListElementClickInter, ListElementDoubleClickInter,
|
|
||||||
ListElementRightClickInter, ListElementGetAttributeValueInter, ListElementGetTextInter,
|
|
||||||
ListElementJudgeKeyInter, ListElementJudgeTextInter, ListElementClearInter, ListElementInputInter {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
import org.openqa.selenium.interactions.Actions;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>DoubleClickInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义鼠标左键双击事件的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:18:21</p>
|
|
||||||
* <p><b>修改时间:</b>2019年12月29日下午1:41:45</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface DoubleClickInter {
|
|
||||||
/**
|
|
||||||
* 鼠标左键双击事件的处理方法。本操作的的返回值是{@link EventResultEnum#VOID},其
|
|
||||||
* 枚举的值为空串;参见{@link EventResultEnum}类。该方法将返回值可通过类{@link Event}中
|
|
||||||
* 的{@link Event#getStringValve()}方法进行返回。
|
|
||||||
*
|
|
||||||
* @param driver 页面WebDriver对象
|
|
||||||
* @param element 通过查找页面得到的控件元素的WebElement对象
|
|
||||||
*/
|
|
||||||
static void doubleClick(WebDriver driver, WebElement element) {
|
|
||||||
//进行元素的点击事件
|
|
||||||
new Actions(driver).doubleClick(element).perform();
|
|
||||||
|
|
||||||
Event.setValue(EventResultEnum.VOID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>GetAttributeValueInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义获取元素在html标签下属性值事件的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午8:39:57</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月26日下午7:02:57</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface GetAttributeValueInter {
|
|
||||||
/**
|
|
||||||
* 用于获取页面元素的某一属性值的内容
|
|
||||||
* @param element 控件的名称或xpath与css定位方式
|
|
||||||
* @param attributeName 属性名称
|
|
||||||
*/
|
|
||||||
static void getAttributeValue(WebElement element, String attributeName) {
|
|
||||||
//获取元素的属性值,将其存储至枚举中
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(element.getAttribute(attributeName)));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>GetTextInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义获取元素内容事件的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午8:33:47</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月26日下午7:02:57</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface GetTextInter {
|
|
||||||
/**
|
|
||||||
* 用于判断标签名是否为“input”
|
|
||||||
*/
|
|
||||||
static final String TAGNAME_INPUT = "input";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法通过传入页面元素对象进行定位来获取其中的内容
|
|
||||||
* @param element 通过查找页面得到的控件元素对象
|
|
||||||
*/
|
|
||||||
static void getText(WebElement element) {
|
|
||||||
// 判断元素是否为input元素,如果是,则获取其value值,若不是则调用getText()方法
|
|
||||||
if (TAGNAME_INPUT.equalsIgnoreCase(element.getTagName())) {
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(element.getAttribute("value")));
|
|
||||||
} else {
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(element.getText()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>InputInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义键盘输入事件的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月4日上午8:19:53</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月4日上午8:19:53</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface InputInter {
|
|
||||||
/**
|
|
||||||
* 根据定位得到的控件元素对象,在其控件中进行输入指定的内容
|
|
||||||
* @param element 通过查找页面得到的控件元素对象
|
|
||||||
* @param text 待输入的内容
|
|
||||||
*/
|
|
||||||
static void input(WebElement element, String text) {
|
|
||||||
//控件中输入内容
|
|
||||||
element.sendKeys(text);
|
|
||||||
//将输入的内容存储至枚举中
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(text));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>JudgeEventInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口集合普通元素的所有判断相关的事件,可在此处扩展新的方法</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月2日下午3:00:19</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月2日下午3:00:19</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface JudgeEventInter
|
|
||||||
extends CommenElementJudgeKeyInter, CommenElementJudgeTextInter {
|
|
||||||
/**
|
|
||||||
* 判断页面上是否存在name对应的控件。.本操作返回的枚举值是{@link EventResultEnum#BOOLEAN_FALSE}或,{@link EventResultEnum#BOOLEAN_TRUE}
|
|
||||||
* 其枚举的value值为判断的结果,以字符串的形式存储"false"及"true",可参见{@link EventResultEnum}类。
|
|
||||||
* @param name 控件名称控件定位的xpath或者css路径
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值,
|
|
||||||
* 亦可通过{@link Event#getBooleanValve()}方法将枚举值转换为boolean进行返回
|
|
||||||
*/
|
|
||||||
Event judgeControl(String name);
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>JudgeKey.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>该接口定义页面文本与指定文本的判断方法,该方法可传入多个关键词,对页面的数据进行逐一
|
|
||||||
* 比对,根据传参判断是否要完全满足。该关键词的对比为模糊对比 ,只需要关键词在页面文本中包含即可
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年9月1日上午9:52:04
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年9月1日上午9:52:04
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface JudgeKeyInter {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 用于判断文本中是否包含传入的关键词,根据keyFull来判断是否需要所有的关键词都包含在文本中,例如有如下标签:<br>
|
|
||||||
* <p id="h">请输入正确填写关键词</p><br>
|
|
||||||
* <br>
|
|
||||||
* 则如下调用时,结果为true:<br>
|
|
||||||
* judgeKey("//p[@id='h']", true, "请输入", "关键词");<br>
|
|
||||||
* judgeKey("//p[@id='h']", false, "标题", "关键词");<br>
|
|
||||||
* <br>
|
|
||||||
* 如下调用时,结果为false:<br>
|
|
||||||
* judgeKey("//p[@id='h']", true, "标题", "关键词");<br>
|
|
||||||
* judgeKey("//p[@id='h']", false, "标题", "内容");<br>
|
|
||||||
* </p>
|
|
||||||
* <p>本操作的的返回值是{@link EventResultEnum#BOOLEAN_FALSE}或,{@link EventResultEnum#BOOLEAN_TRUE},
|
|
||||||
* 其枚举的值为输入到控件的内容;参见{@link EventResultEnum}类。
|
|
||||||
* 该方法将返回值可通过类{@link Event}中的{@link Event#getStringValve()}方法进行返回,
|
|
||||||
* 亦可通过{@link Event#getBooleanValue()}方法进行返回。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param element 通过查找页面得到的控件元素的WebElement对象
|
|
||||||
* @param keyFull 是否需要所有关键词都包含
|
|
||||||
* @param keys 关键词组
|
|
||||||
*/
|
|
||||||
static void judgeKey(WebElement element, boolean keyFull, String... keys) {
|
|
||||||
//获取当前元素的文本
|
|
||||||
GetTextInter.getText(element);
|
|
||||||
// 将文本存储至text中
|
|
||||||
String text = Event.getStringValve();
|
|
||||||
|
|
||||||
// 循环,判断文本是否包含所有关键词
|
|
||||||
for (String key : keys) {
|
|
||||||
// 判断文字是否包含关键词,若未包含,则设置为false,若包含则设置为true
|
|
||||||
if (text.indexOf(key) == -1) {
|
|
||||||
//由于Event中存储的返回值是以最后一次存储的值为主,故此处可以直接使用此方法以达到存储返回值的目的
|
|
||||||
Event.setValue(EventResultEnum.BOOLEAN_FALSE);
|
|
||||||
// 若未包含且需要关键词全包含时(keyFull为true时),可直接返回false
|
|
||||||
if (keyFull) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Event.setValue(EventResultEnum.BOOLEAN_TRUE);
|
|
||||||
// 若未包含且不需要关键词全包含时(keyFull为false时),可直接返回true
|
|
||||||
if (!keyFull) {
|
|
||||||
Event.setValue(EventResultEnum.BOOLEAN_TRUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>JudgeKeyInter.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>该接口定义页面文本与指定文本的判断方法,该方法用传入的关键词与页面对比,可精准对比,亦可模糊对比
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年8月30日下午7:52:43
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年9月29日下午9:23:43
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface JudgeTextInter {
|
|
||||||
/**
|
|
||||||
* 判断控件中的文本是否包含或者与关键词一致
|
|
||||||
* <p>本操作的的返回值是{@link EventResultEnum#BOOLEAN_FALSE}或,{@link EventResultEnum#BOOLEAN_TRUE},
|
|
||||||
* 其枚举的值为输入到控件的内容;参见{@link EventResultEnum}类。
|
|
||||||
* 该方法将返回值可通过类{@link Event}中的{@link Event#getStringValve()}方法进行返回,
|
|
||||||
* 亦可通过{@link Event#getBooleanValue()}方法进行返回。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param element 通过查找页面得到的控件元素的WebElement对象
|
|
||||||
* @param keyFull 是否需要与页面文本完全一致
|
|
||||||
* @param text 需要判断的字符号串
|
|
||||||
*/
|
|
||||||
static void judgeText(WebElement element, boolean keyFull, String key) {
|
|
||||||
// 获取元素指向的信息的内容文本
|
|
||||||
GetTextInter.getText(element);
|
|
||||||
String text = Event.getStringValve();
|
|
||||||
|
|
||||||
// 判断控件文本是否需要完整包含
|
|
||||||
if (keyFull) {
|
|
||||||
// 判断获取的文字一致
|
|
||||||
if (text.equals(key)) {
|
|
||||||
Event.setValue(EventResultEnum.BOOLEAN_TRUE);
|
|
||||||
} else {
|
|
||||||
Event.setValue(EventResultEnum.BOOLEAN_FALSE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 判断文字是否包含
|
|
||||||
if (text.indexOf(key) > -1) {
|
|
||||||
Event.setValue(EventResultEnum.BOOLEAN_TRUE);
|
|
||||||
} else {
|
|
||||||
Event.setValue(EventResultEnum.BOOLEAN_FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>CommenElementClearInter.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>该接口定义了列表元素内容清空事件的实现标准
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年9月6日上午8:31:24
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年10月8日上午8:31:24
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ListElementClearInter extends ClearInter {
|
|
||||||
/**
|
|
||||||
* 该方法通过页面元素对象对页面元素进行清空内容的操作,主要用于清空文本框中已有的数据。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为控件中原有的内容,可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Event clear();
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ListElementClickInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了列表元素鼠标左键单击事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:22:22</p>
|
|
||||||
* <p><b>修改时间:</b>2019年8月29日下午3:22:22</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ListElementClickInter extends ClickInter {
|
|
||||||
/**
|
|
||||||
* 根据列表类返回的对象,进行鼠标左键单击操作。
|
|
||||||
*
|
|
||||||
* @return Event类对象,可通过该类继续写操作,以及获取返回值,参见{@link Event}类。
|
|
||||||
* 本操作的的返回值是EventResultEnum.VOID;参见{@link EventResultEnum}类。
|
|
||||||
*/
|
|
||||||
Event click();
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ListElementDoubleClickInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了列表元素鼠标左键双击事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:22:49</p>
|
|
||||||
* <p><b>修改时间:</b>2019年8月29日下午3:22:49</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ListElementDoubleClickInter extends DoubleClickInter {
|
|
||||||
/**
|
|
||||||
* 根据列表类返回的对象,进行鼠标左键双击操作。
|
|
||||||
*
|
|
||||||
* @return Event类对象,可通过该类继续写操作,以及获取返回值,参见{@link Event}类。
|
|
||||||
* 本操作的的返回值是EventResultEnum.VOID;参见{@link EventResultEnum}类。
|
|
||||||
*/
|
|
||||||
Event doubleClick();
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>CommenElementGetAttributeValueInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了获取列表元素在html标签下属性值事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午8:45:54</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月6日上午8:45:54</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ListElementGetAttributeValueInter extends GetAttributeValueInter {
|
|
||||||
/**
|
|
||||||
* 用于获取页面元素的某一属性值的内容。本操作返回的枚举值
|
|
||||||
* 是{@link EventResultEnum#STRING},其枚举的value值为获取到的控件指定属性的内容,可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param attributeName 属性名称
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event getAttributeValue(String attributeName);
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ListElementGetTextInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了获取普通元素内容事件事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午8:37:20</p>
|
|
||||||
* <p><b>修改时间:</b>2019年10月8日上午8:34:04</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ListElementGetTextInter extends GetTextInter {
|
|
||||||
/**
|
|
||||||
* 该方法通过传入控件名称或定位方式对页面元素进行定位来获取其中的内容。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为控件中的文本内容,可参见{@link EventResultEnum}类。
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event getText();
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ListElementInputInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了普通元素输入事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年10月8日上午8:25:39</p>
|
|
||||||
* <p><b>修改时间:</b>2019年10月8日上午8:25:39</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface ListElementInputInter extends InputInter {
|
|
||||||
/**
|
|
||||||
* 根据元素对象,在其控件中进行输入指定的内容。
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为输入到控件中的内容,可参见{@link EventResultEnum}类。
|
|
||||||
* @param text 待输入的内容
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event input(String text);
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ListElementJudgeKeyInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了列表元素对多个关键词判断事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年10月8日上午8:35:42</p>
|
|
||||||
* <p><b>修改时间:</b>2019年10月8日上午8:35:42</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ListElementJudgeKeyInter extends JudgeKeyInter {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 用于判断文本中是否包含传入的关键词,根据keyFull来判断是否需要所有的关键词都包含在文本中,例如有如下标签:<br>
|
|
||||||
* <p id="h">请输入正确填写关键词</p>
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 则如下调用时,结果为true:<br>
|
|
||||||
* judgeKey("//p[@id='h']", true, "请输入", "关键词");<br>
|
|
||||||
* judgeKey("//p[@id='h']", false, "标题", "关键词");
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 如下调用时,结果为false:<br>
|
|
||||||
* judgeKey("//p[@id='h']", true, "标题", "关键词");<br>
|
|
||||||
* judgeKey("//p[@id='h']", false, "标题", "内容");
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#BOOLEAN_FALSE}或,{@link EventResultEnum#BOOLEAN_TRUE}
|
|
||||||
* 其枚举的value值为判断的结果,以字符串的形式存储"false"及"true",可参见{@link EventResultEnum}类。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param keyFull 是否需要所有关键词都包含
|
|
||||||
* @param keys 关键词组
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值,
|
|
||||||
* 亦可通过{@link Event#getBooleanValve()}方法将枚举值转换为boolean进行返回
|
|
||||||
*/
|
|
||||||
Event judgeKey(boolean keyFull, String... keys);
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ListElementJudgeTextInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了列表元素对单个关键词判断事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年10月8日上午8:37:35</p>
|
|
||||||
* <p><b>修改时间:</b>2019年10月8日上午8:37:35</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ListElementJudgeTextInter extends JudgeTextInter {
|
|
||||||
/**
|
|
||||||
* 判断控件中的文本是否包含或者与关键词一致。本操作返回的枚举值是{@link EventResultEnum#BOOLEAN_FALSE}或,{@link EventResultEnum#BOOLEAN_TRUE}
|
|
||||||
* 其枚举的value值为判断的结果,以字符串的形式存储"false"及"true",可参见{@link EventResultEnum}类。
|
|
||||||
*
|
|
||||||
* @param textFull 是否需要与页面文本完全一致
|
|
||||||
* @param key 关键词
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值,
|
|
||||||
* 亦可通过{@link Event#getBooleanValve()}方法将枚举值转换为boolean进行返回
|
|
||||||
*/
|
|
||||||
Event judgeText(boolean keyFull, String key);
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ListElementRightClickInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义了列表元素鼠标右键单击事件的实现标准</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:23:09</p>
|
|
||||||
* <p><b>修改时间:</b>2019年8月29日下午3:23:09</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ListElementRightClickInter extends RightClickInter {
|
|
||||||
/**
|
|
||||||
* 根据列表类返回的对象,进行鼠标右键单击操作。
|
|
||||||
*
|
|
||||||
* @return Event类对象,可通过该类继续写操作,以及获取返回值,参见{@link Event}类。
|
|
||||||
* 本操作的的返回值是EventResultEnum.VOID;参见{@link EventResultEnum}类。
|
|
||||||
*/
|
|
||||||
Event rightClick();
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
import org.openqa.selenium.interactions.Actions;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>RightClickInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义鼠标右键单击事件的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月29日下午3:18:38</p>
|
|
||||||
* <p><b>修改时间:</b>2019年12月29日下午1:41:45</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface RightClickInter {
|
|
||||||
/**
|
|
||||||
* 鼠标右键单击事件的处理方法。本操作的的返回值是{@link EventResultEnum#VOID},其
|
|
||||||
* 枚举的值为空串;参见{@link EventResultEnum}类。该方法将返回值可通过类{@link Event}中
|
|
||||||
* 的{@link Event#getStringValve()}方法进行返回。
|
|
||||||
*
|
|
||||||
* @param driver 页面WebDriver对象
|
|
||||||
* @param element 通过查找页面得到的控件元素的WebElement对象
|
|
||||||
*/
|
|
||||||
static void rightClick(WebDriver driver, WebElement element) {
|
|
||||||
//进行元素的点击事件
|
|
||||||
new Actions(driver).contextClick(element).perform();
|
|
||||||
Event.setValue(EventResultEnum.VOID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import org.openqa.selenium.NoSuchElementException;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>SelectEventInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口集合普通元素的所有选择相关的事件,可在此处扩展新的方法</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月3日下午5:00:07</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月3日下午5:00:07</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface SelectEventInter
|
|
||||||
extends CommenElementSelectFirstInter, CommenElementSelectInter, CommenElementSelectLastInter {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 通过传入在xml文件中的控件名称,到类中指向的xml文件中查找控件名称对应的定位方式,或直接传入xpath与css定位方式,
|
|
||||||
* 根据定位方式在页面查找元素并对标准的web下拉框(由标签select和标签option构成)根据传入的选项进行选择,亦可以对非标准的下拉框(由大量的div等标签组成)进行操作,但对于非标准的
|
|
||||||
* 下拉框,需要传入的是选项列表,例如:<br>
|
|
||||||
* 标准下拉框:<br>
|
|
||||||
* <select id='test'><br>
|
|
||||||
*  <option>男</option><br>
|
|
||||||
*  <option>女</option><br>
|
|
||||||
*  <option>其他</option><br>
|
|
||||||
* </select><br>
|
|
||||||
* 对于该标准的下拉框选项,只需要定位到//select[@id='test'],得到其WebElement对象即可,但对于非标准的下拉框其下拉框是由input和button标签构成:<br>
|
|
||||||
* <div><br>
|
|
||||||
*  <span><input/></span><br>
|
|
||||||
*  <span><button/></span><br>
|
|
||||||
* </div><br>
|
|
||||||
* 点击button对应的按钮后,其下也能弹出选项,但其选项是由div标签写入text构成:<br>
|
|
||||||
* <div id='test'><br>
|
|
||||||
*  <div>男</div><br>
|
|
||||||
*  <div>女</div><br>
|
|
||||||
*  <div>其他</div><br>
|
|
||||||
* </div><br>
|
|
||||||
* 对于这种非标准的下拉框选项,需要传入选项所在的所有div标签对应的WebElement元素,在上例,则需要定位到//div[@id='test']/div,
|
|
||||||
* 注意,末尾的div不指定数字,则可以代表整个选项。
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为当前选择选项的内容,可参见{@link EventResultEnum}类。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param name 控件的名称或xpath与css定位方式
|
|
||||||
* @param optionStr 选项的内容
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
* @throws NoSuchElementException 指定的选项值不存在时抛出
|
|
||||||
*/
|
|
||||||
Event select(String name, String optionStr);
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
import org.openqa.selenium.support.ui.Select;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>SelectFirstInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义下拉框选择事件选择第一个选项的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月3日下午2:33:11</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月29日下午7:33:11</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface SelectFirstInter {
|
|
||||||
/**
|
|
||||||
* 该方法用于选择标准的web下拉框(由标签select和标签option构成)的第一个选项,例如:<br>
|
|
||||||
* <select id='test'><br>
|
|
||||||
*  <option>男</option><br>
|
|
||||||
*  <option>女</option><br>
|
|
||||||
*  <option>其他</option><br>
|
|
||||||
* </select><br>
|
|
||||||
* 对于该标准的下拉框选项,只需要定位到//select[@id='test'],得到其WebElement对象即可。
|
|
||||||
*
|
|
||||||
* @param element 通过查找页面得到的控件元素对象
|
|
||||||
*/
|
|
||||||
static void selectFirst(WebElement element) {
|
|
||||||
//定义Select类对象
|
|
||||||
Select select = new Select(element);
|
|
||||||
//选择元素
|
|
||||||
select.selectByIndex(0);
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(select.getOptions().get(0).getText()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于选择非标准的web标准下拉框(由input、button和大量的div标签组成)的第一个选项。对于非标准的下拉框,需要传入的是选项列表,例如:<br>
|
|
||||||
* <div><br>
|
|
||||||
*  <span><input/></span><br>
|
|
||||||
*  <span><button/></span><br>
|
|
||||||
* </div><br>
|
|
||||||
* 点击button对应的按钮后,其下也能弹出选项,但其选项是由div标签写入text构成:<br>
|
|
||||||
* <div id='test'><br>
|
|
||||||
*  <div>男</div><br>
|
|
||||||
*  <div>女</div><br>
|
|
||||||
*  <div>其他</div><br>
|
|
||||||
* </div><br>
|
|
||||||
* 对于这种非标准的下拉框选项,需要传入选项所在的所有div标签对应的WebElement元素,在上例,则需要定位到//div[@id='test']/div,
|
|
||||||
* 注意,末尾的div不指定数字,则可以代表整个选项。
|
|
||||||
*
|
|
||||||
* @param elements 通过查找页面得到的选项组对象
|
|
||||||
*/
|
|
||||||
static void selectFirst(List<WebElement> elements) {
|
|
||||||
elements.get(0).click();
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(elements.get(0).getText()));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,200 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.openqa.selenium.NoSuchElementException;
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
import org.openqa.selenium.support.ui.Select;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>SelectInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义下拉框选择事件的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月3日上午8:38:34</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月3日上午8:38:34</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface SelectInter {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 该方法用于对标准的web下拉框(由标签select和标签option构成)进行选择,例如:<br>
|
|
||||||
* <select id='test'><br>
|
|
||||||
*  <option>男</option><br>
|
|
||||||
*  <option>女</option><br>
|
|
||||||
*  <option>其他</option><br>
|
|
||||||
* </select><br>
|
|
||||||
* 对于该标准的下拉框选项,只需要定位到//select[@id='test'],得到其WebElement对象即可。
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b><i>注意:</i></b>option序号从1开始,1表示第一个选项,亦可传入负数,-1表示倒数第一个选项,
|
|
||||||
* -2表示倒数第二个选项,以此类推;当传入的值为0时,则表示随机选择一个选项,但随机的值不包括第一个选项,
|
|
||||||
* 以避免第一个元素为空或为“请选择”之类的选项
|
|
||||||
* </p>
|
|
||||||
* @param element 通过查找页面得到的控件元素对象
|
|
||||||
* @param option 选项的序号,正数表示从前向后选,负数表示从后往前选,0表示随机选择
|
|
||||||
* @throws NoSuchElementException 指定的选项值超过选项的最大值时抛出
|
|
||||||
*/
|
|
||||||
static void select(WebElement element, int option) {
|
|
||||||
//定义Select类对象
|
|
||||||
Select select = new Select(element);
|
|
||||||
//获取选项的长度
|
|
||||||
int length = select.getOptions().size();
|
|
||||||
|
|
||||||
//判断传入的选项值的绝对值(由于可传入负数,故取绝对值)是否大于选项的总长度,若大于总长度,则抛出NoSuchElementException
|
|
||||||
if (Math.abs(option) > length) {
|
|
||||||
throw new NoSuchElementException("指定的选项值大于选项的最大值。选项总个数:" + length + "指定项:" + option);
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断option的值,若大于0,则从前向后遍历,若小于0,则从后往前遍历,若等于0,则随机输入
|
|
||||||
if (option > 0) {
|
|
||||||
//选择元素,正数的选项值从1开始,故需要减小1才是正确的选项值
|
|
||||||
select.selectByIndex(option - 1);
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(select.getOptions().get(option - 1).getText()));
|
|
||||||
} else if (option < 0) {
|
|
||||||
//选择元素,由于option为负数,则长度加上选项值即可得到需要选择的选项
|
|
||||||
select.selectByIndex(length + option);
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(select.getOptions().get(length + option).getText()));
|
|
||||||
} else {
|
|
||||||
//为0,则在判断选项是否只有一个,若有多个,则随机抽取,若选项只有一个,则直接选择第一个
|
|
||||||
//进行随机选择,但不选择第一个元素,避免第一个元素为空或为“请选择”之类的选项
|
|
||||||
int index = length > 1 ? new Random().nextInt(length - 1) + 1 : 0;
|
|
||||||
select.selectByIndex(index);
|
|
||||||
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(select.getOptions().get(index).getText()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 该方法用于对非标准的web标准下拉框(由input、button和大量的div标签组成)进行选择。对于非标准的下拉框,需要传入的是选项列表,例如:<br>
|
|
||||||
* <div><br>
|
|
||||||
*  <span><input/></span><br>
|
|
||||||
*  <span><button/></span><br>
|
|
||||||
* </div><br>
|
|
||||||
* 点击button对应的按钮后,其下也能弹出选项,但其选项是由div标签写入text构成:<br>
|
|
||||||
* <div id='test'><br>
|
|
||||||
*  <div>男</div><br>
|
|
||||||
*  <div>女</div><br>
|
|
||||||
*  <div>其他</div><br>
|
|
||||||
* </div><br>
|
|
||||||
* 对于这种非标准的下拉框选项,需要传入选项所在的所有div标签对应的WebElement元素,在上例,则需要定位到//div[@id='test']/div,
|
|
||||||
* 注意,末尾的div不指定数字,则可以代表整个选项。
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b><i>注意:</i></b>option序号从1开始,1表示第一个选项,亦可传入负数,-1表示倒数第一个选项,
|
|
||||||
* -2表示倒数第二个选项,以此类推;当传入的值为0时,则表示随机选择一个选项,但随机的值不包括第一个选项,
|
|
||||||
* 以避免第一个元素为空或为“请选择”之类的选项
|
|
||||||
* </p>
|
|
||||||
* @param elements 通过查找页面得到的选项组对象
|
|
||||||
* @param option 选项的序号,正数表示从前向后选,负数表示从后往前选,0表示随机选择
|
|
||||||
* @throws NoSuchElementException 指定的选项值超过选项的最大值时抛出
|
|
||||||
*/
|
|
||||||
static void select(List<WebElement> elements, int option) {
|
|
||||||
//获取选项的长度
|
|
||||||
int length = elements.size();
|
|
||||||
|
|
||||||
//判断传入的选项值的绝对值(由于可传入负数,故取绝对值)是否大于选项的总长度,若大于总长度,则抛出NoSuchElementException
|
|
||||||
if (Math.abs(option) > length) {
|
|
||||||
throw new NoSuchElementException("指定的选项值大于选项的最大值。选项总个数:" + length + ",指定项:" + option);
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断option的值,若大于0,则从前向后遍历,若小于0,则从后往前遍历,若等于0,则随机输入
|
|
||||||
if (option > 0) {
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(elements.get(option - 1).getText()));
|
|
||||||
//选择元素,正数的选项值从1开始,故需要减小1才是正确的选项值
|
|
||||||
elements.get(option - 1).click();
|
|
||||||
} else if (option < 0) {
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(elements.get(length + option).getText()));
|
|
||||||
//选择元素,由于option为负数,则长度加上选项值即可得到需要选择的选项
|
|
||||||
elements.get(length + option).click();
|
|
||||||
} else {
|
|
||||||
//为0,则在判断选项是否只有一个,若有多个,则随机抽取,若选项只有一个,则直接选择第一个
|
|
||||||
int index = length > 1 ? new Random().nextInt(length - 1) + 1 : 0;
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(elements.get(index).getText()));
|
|
||||||
//进行随机选择,但不选择第一个元素,避免第一个元素为空或为“请选择”之类的选项
|
|
||||||
elements.get(index).click();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 该方法用于对标准的web下拉框(由标签select和标签option构成)根据选项的内容进行选择,例如:<br>
|
|
||||||
* <select id='test'><br>
|
|
||||||
*  <option>男</option><br>
|
|
||||||
*  <option>女</option><br>
|
|
||||||
*  <option>其他</option><br>
|
|
||||||
* </select><br>
|
|
||||||
* 对于该标准的下拉框选项,只需要定位到//select[@id='test'],得到其WebElement对象即可。
|
|
||||||
* </p>
|
|
||||||
* @param element 通过查找页面得到的控件元素对象
|
|
||||||
* @param optionStr 选项的内容
|
|
||||||
* @throws NoSuchElementException 指定的选项内容不存在时抛出
|
|
||||||
*/
|
|
||||||
static void select(WebElement element, String optionStr) {
|
|
||||||
//定义Select类对象
|
|
||||||
Select select = new Select(element);
|
|
||||||
|
|
||||||
//获取select的所有选项的选项值,并判断哪个选项与传入的值对应
|
|
||||||
int index = select.getOptions().stream().map(e -> e.getText()).collect(Collectors.toList()).indexOf(optionStr);
|
|
||||||
|
|
||||||
//判断选项值是否有与传入的选项值对应的选项,若没有,则抛出异常
|
|
||||||
if (index == -1) {
|
|
||||||
throw new NoSuchElementException("不存在的选项内容:" + optionStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
select.selectByIndex(index);
|
|
||||||
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(optionStr));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 该方法用于对非标准的web标准下拉框(由input、button和大量的div标签组成)根据指定的选项内容进行选择。对于非标准的下拉框,需要传入的是选项列表,例如:<br>
|
|
||||||
* <div><br>
|
|
||||||
*  <span><input/></span><br>
|
|
||||||
*  <span><button/></span><br>
|
|
||||||
* </div><br>
|
|
||||||
* 点击button对应的按钮后,其下也能弹出选项,但其选项是由div标签写入text构成:<br>
|
|
||||||
* <div id='test'><br>
|
|
||||||
*  <div>男</div><br>
|
|
||||||
*  <div>女</div><br>
|
|
||||||
*  <div>其他</div><br>
|
|
||||||
* </div><br>
|
|
||||||
* 对于这种非标准的下拉框选项,需要传入选项所在的所有div标签对应的WebElement元素,在上例,则需要定位到//div[@id='test']/div,
|
|
||||||
* 注意,末尾的div不指定数字,则可以代表整个选项。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param elements 通过查找页面得到的选项组对象
|
|
||||||
* @param optionStr 选项的内容
|
|
||||||
* @throws NoSuchElementException 指定的选项内容不存在时抛出
|
|
||||||
*/
|
|
||||||
static void select(List<WebElement> elements, String optionStr) {
|
|
||||||
//获取select的所有选项的选项值,并判断哪个选项与传入的值对应
|
|
||||||
int index = elements.stream().map(e -> e.getText()).collect(Collectors.toList()).indexOf(optionStr);
|
|
||||||
|
|
||||||
//判断选项值是否有与传入的选项值对应的选项,若没有,则抛出异常
|
|
||||||
if (index == -1) {
|
|
||||||
throw new NoSuchElementException("不存在的选项内容:" + optionStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
elements.get(index).click();
|
|
||||||
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(optionStr));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
import org.openqa.selenium.support.ui.Select;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>SelectLastInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口定义下拉框选择事件选择最后一个选项的实现方法,可直接使用</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月3日上午8:42:12</p>
|
|
||||||
* <p><b>修改时间:</b>2019年9月29日下午7:35:12</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface SelectLastInter {
|
|
||||||
/**
|
|
||||||
* 该方法用于选择标准的web下拉框(由标签select和标签option构成)的最后一个选项,例如:<br>
|
|
||||||
* <select id='test'><br>
|
|
||||||
*  <option>男</option><br>
|
|
||||||
*  <option>女</option><br>
|
|
||||||
*  <option>其他</option><br>
|
|
||||||
* </select><br>
|
|
||||||
* 对于该标准的下拉框选项,只需要定位到//select[@id='test'],得到其WebElement对象即可。
|
|
||||||
*
|
|
||||||
* @param element 通过查找页面得到的控件元素对象
|
|
||||||
*/
|
|
||||||
static void selectLast(WebElement element) {
|
|
||||||
//定义Select类对象
|
|
||||||
Select select = new Select(element);
|
|
||||||
//选择元素
|
|
||||||
select.selectByIndex(select.getOptions().size() - 1);
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(select.getOptions().get(select.getOptions().size() - 1).getText()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于选择非标准的web标准下拉框(由input、button和大量的div标签组成)的最后一个选项。对于非标准的下拉框,需要传入的是选项列表,例如:<br>
|
|
||||||
* <div><br>
|
|
||||||
*  <span><input/></span><br>
|
|
||||||
*  <span><button/></span><br>
|
|
||||||
* </div><br>
|
|
||||||
* 点击button对应的按钮后,其下也能弹出选项,但其选项是由div标签写入text构成:<br>
|
|
||||||
* <div id='test'><br>
|
|
||||||
*  <div>男</div><br>
|
|
||||||
*  <div>女</div><br>
|
|
||||||
*  <div>其他</div><br>
|
|
||||||
* </div><br>
|
|
||||||
* 对于这种非标准的下拉框选项,需要传入选项所在的所有div标签对应的WebElement元素,在上例,则需要定位到//div[@id='test']/div,
|
|
||||||
* 注意,末尾的div不指定数字,则可以代表整个选项。
|
|
||||||
*
|
|
||||||
* @param elements 通过查找页面得到的选项组对象
|
|
||||||
*/
|
|
||||||
static void selectLast(List<WebElement> elements) {
|
|
||||||
elements.get(elements.size() - 1).click();
|
|
||||||
//将下拉框的选项的值设置为枚举值
|
|
||||||
Event.setValue(EventResultEnum.STRING.setValue(elements.get(elements.size() - 1).getText()));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
package pres.auxiliary.selenium.event.inter;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.event.EventResultEnum;
|
|
||||||
import pres.auxiliary.tool.randomstring.RandomString;
|
|
||||||
import pres.auxiliary.tool.randomstring.StringMode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>TextEventInter.java</p>
|
|
||||||
* <p><b>用途:</b>该接口集合普通元素的所有文本相关的事件,可在此处扩展新的方法</p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月6日上午8:52:33</p>
|
|
||||||
* <p><b>修改时间:</b>2019年10月31日下午7:25:40</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.1
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface TextEventInter extends CommenElementClearInter, CommenElementGetAttributeValueInter,
|
|
||||||
CommenElementGetTextInter, CommenElementInputInter {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 通过图片识别的方法,根据codeName查找验证码图片元素位置,识别页面中的验证码,并将结果填入textName对应
|
|
||||||
* 的文本框中。注意,该方法识别验证码成功的概率不高,在数字+英文的验证码模式下,经常将数字识别为英文。
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为输入到控件的内容,可参见{@link EventResultEnum}类。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param textName 文本框控件的名称或xpath与css定位方式
|
|
||||||
* @param codeName 验证码图片控件的名称或xpath与css定位方式
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event codeInput(String textName, String codeName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 该方法用于将一个指定的整数随机填写到传入的控件组中<br>
|
|
||||||
* <b><i>建议在指定值远远大于控件的数量时再使用该方法,否则将会出现不可预期的问题</i></b>
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为输入到控件的内容,
|
|
||||||
* 由于涉及到多个文本框,故其返回值有多个,将以“值1,值2,值3...”的形式进行存储,可参见{@link EventResultEnum}类。
|
|
||||||
* </p>
|
|
||||||
* @param num 指定的整数
|
|
||||||
* @param names 控件的名称或xpath与css定位方式,可传入多个控件名称
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event avgIntergeInput(int num, String...names);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法通过指定的随机字符串长度与指定的随机字符串模型枚举({@link StringMode}枚举类),向控件中随机输入字符串操作。<br>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为输入到控件的内容,可参见{@link EventResultEnum}类。
|
|
||||||
* @param name 控件的名称或xpath与css定位方式,可传入多个控件名称
|
|
||||||
* @param minLength 字符串最小长度,设为小于等于0的数值时则默认为1
|
|
||||||
* @param maxLength 字符串最大长度,设为小于等于0的数值时则默认为1,若需要指定字符串的输入长度,可设置minLength数值与maxLength一致
|
|
||||||
* @param modes {@link StringMode}枚举,指定字符串输入的类型,可传入多种模型,参见{@link RandomString#RandomString(StringMode...)}
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event randomInput(String name, int minLength, int maxLength, StringMode... modes);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法通过指定的随机字符串长度与指定的随机字符串模型,向控件中随机输入字符串操作。<br>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为输入到控件的内容,可参见{@link EventResultEnum}类。
|
|
||||||
* @param name 控件的名称或xpath与css定位方式,可传入多个控件名称
|
|
||||||
* @param minLength 字符串最小长度,设为小于等于0的数值时则默认为1
|
|
||||||
* @param maxLength 字符串最大长度,设为小于等于0的数值时则默认为1,若需要指定字符串的输入长度,可设置minLength数值与maxLength一致
|
|
||||||
* @param mode 可用的随机字符串抽取范围,参见{@link RandomString#RandomString(String)}
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event randomInput(String name, int minLength, int maxLength, String mode);
|
|
||||||
/**
|
|
||||||
* 该方法用于向控件中上传指定的文件。<br>
|
|
||||||
* 本操作返回的枚举值是{@link EventResultEnum#STRING},其枚举的value值为文件在本地中的绝对路径,可参见{@link EventResultEnum}类。
|
|
||||||
* @param name 控件的名称或xpath与css定位方式,可传入多个控件名称
|
|
||||||
* @param updataFile 需要上传到控件中的文件
|
|
||||||
* @return {@link Event}类对象,可通过{@link Event#getStringValve()}方法获取操作的返回值
|
|
||||||
*/
|
|
||||||
Event updataFile(String name, File updataFile);
|
|
||||||
}
|
|
|
@ -46,8 +46,9 @@ public class Time {
|
||||||
/**
|
/**
|
||||||
* 定义日期约束类型的传入格式
|
* 定义日期约束类型的传入格式
|
||||||
*/
|
*/
|
||||||
private final String REGEX_DATE = "(\\d{4}[-\\.年\\\\\\/][01]?\\d[-\\.月\\\\\\/][0123]?\\d日?)?"
|
private final String REGEX_DATE = "(\\d{4}[-\\.年\\\\/][01]?\\d[-\\.月\\\\/][0123]?\\d日?"
|
||||||
+ "( ?[012]?\\d[:时][0123456]?\\d分?([:分][0123456]?\\d秒?)?)?";
|
+ "( [012]?\\d[:时][0123456]?\\d分?([:分][0123456]?\\d秒?)?)?)|"
|
||||||
|
+ "([012]?\\d[:时][0123456]?\\d分?([:分][0123456]?\\d秒?))";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造当前时间
|
* 构造当前时间
|
||||||
|
@ -111,6 +112,12 @@ public class Time {
|
||||||
* @throws IncorrectConditionException 时间转换错误时抛出的异常
|
* @throws IncorrectConditionException 时间转换错误时抛出的异常
|
||||||
*/
|
*/
|
||||||
public void setTime(String formatTime) {
|
public void setTime(String formatTime) {
|
||||||
|
//若formatTime传入为Null或为空串,则设置为当前时间
|
||||||
|
if (formatTime == null || formatTime.isEmpty()) {
|
||||||
|
setNowTime();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (formatTime.matches(REGEX_DATE)) {
|
if (formatTime.matches(REGEX_DATE)) {
|
||||||
try {
|
try {
|
||||||
date = new SimpleDateFormat(getDateFormat(formatTime)).parse(formatTime);
|
date = new SimpleDateFormat(getDateFormat(formatTime)).parse(formatTime);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.datadriven;
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
|
@ -0,0 +1,50 @@
|
||||||
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p><b>文件名:</b>DataDriverFunction.java</p>
|
||||||
|
* <p><b>用途:</b>
|
||||||
|
* 用于存储数据驱动中处理数据的公式
|
||||||
|
* </p>
|
||||||
|
* <p><b>编码时间:</b>2020年6月12日上午8:27:04</p>
|
||||||
|
* <p><b>修改时间:</b>2020年6月12日上午8:27:04</p>
|
||||||
|
* @author 彭宇琦
|
||||||
|
* @version Ver1.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DataDriverFunction {
|
||||||
|
/**
|
||||||
|
* 用于存储正则表达式
|
||||||
|
*/
|
||||||
|
private String regex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于存储处理数据的
|
||||||
|
*/
|
||||||
|
private DataFunction function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化数据
|
||||||
|
* @param regex 正则表达式
|
||||||
|
* @param function 数据对应的处理方法
|
||||||
|
*/
|
||||||
|
public DataDriverFunction(String regex, DataFunction function) {
|
||||||
|
this.regex = regex;
|
||||||
|
this.function = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回正则表达式
|
||||||
|
* @return 正则表达式
|
||||||
|
*/
|
||||||
|
public String getRegex() {
|
||||||
|
return regex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回数据处理的方法
|
||||||
|
* @return 数据处理的方法
|
||||||
|
*/
|
||||||
|
public DataFunction getFunction() {
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p><b>文件名:</b>DataFunction.java</p>
|
||||||
|
* <p><b>用途:</b>
|
||||||
|
* 用于定义在数据驱动文件中写入公式的处理方法
|
||||||
|
* </p>
|
||||||
|
* <p><b>编码时间:</b>2020年6月10日上午7:11:09</p>
|
||||||
|
* <p><b>修改时间:</b>2020年6月10日上午7:11:09</p>
|
||||||
|
* @author 彭宇琦
|
||||||
|
* @version Ver1.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface DataFunction extends Function<String, String> {
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.datadriven;
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于定义可向数据驱动中添加的预设模型
|
* 用于定义可向数据驱动中添加的预设模型
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.datadriven;
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
public class DataNotFoundException extends Exception {
|
public class DataNotFoundException extends Exception {
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
|
import pres.auxiliary.tool.date.Time;
|
||||||
|
import pres.auxiliary.tool.randomstring.RandomString;
|
||||||
|
import pres.auxiliary.tool.randomstring.StringMode;
|
||||||
|
|
||||||
|
public class Functions {
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 定义生成随机字符串函数,用法:<br>
|
||||||
|
* ${rs(字符串种子,生成字符串最短长度,生成字符串最大长度)}
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>参数解释:</b><br>
|
||||||
|
* <ul>
|
||||||
|
* <li>字符串种子:生成随机字符串的范围,该范围可自定义,也可以使用系统定义的特殊种子,包括
|
||||||
|
* NUM(数字)、CAP(大写字母)、LOW(小写字母)、CH(中文)、AREA(区域缩写)、SURNAME(姓氏);
|
||||||
|
* 使用自定义种子时需要使用双引号标识,即传入"ASD"(表示只在ASD中生成随机字符串)
|
||||||
|
* </li>
|
||||||
|
* <li>生成字符串最短长度:最终生成的随机字符串的最短长度</li>
|
||||||
|
* <li>生成字符串最大长度:<b>该字段可不传入</b>,用于指定最终生成的随机字符串的最大长度</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>示例:</b><br>
|
||||||
|
* ${rs("qwertyuiop", 10, 20)}——表示生成“qwertyuiop”范围内,10~20位(随机)长度的随机字符串<br>
|
||||||
|
* ${rs("qwertyuiop", 10)}——表示生成“qwertyuiop”范围内,10位长度的随机字符串<br>
|
||||||
|
* ${rs(CH,10)}——表示生成中文(1000个不重复的中文)范围内,10位长度的随机字符串<br>
|
||||||
|
* ${rs(num, 10,20)}——表示生成数字(0-9)范围内,10~20位(随机)长度的随机字符串<br>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>注意:</b>每个参数之间的分隔符号中允许存在一个空格,该空格可写可不写
|
||||||
|
* </p>
|
||||||
|
* @return {@link DataDriverFunction}类对象
|
||||||
|
*/
|
||||||
|
public static DataDriverFunction randomString() {
|
||||||
|
//定义规则
|
||||||
|
String regex = "rs\\(((\".+\")|NUM|num|CAP|cap|LOW|low|CH|ch|AREA|area|SURNAME|surname), ?\\d+(, ?\\d+)?\\)";
|
||||||
|
return new DataDriverFunction(regex, text -> {
|
||||||
|
//获取公式中有效部分
|
||||||
|
String str = text.substring(text.indexOf("(") + 1, text.indexOf(")"));
|
||||||
|
|
||||||
|
//将公式有效部分按照分隔符号进行切分
|
||||||
|
String[] parameters = str.split(", ?");
|
||||||
|
//切分的第一个元素为字符串种子
|
||||||
|
String seed = parameters[0];
|
||||||
|
//第二个元素为随机字符串最小长度
|
||||||
|
int startIndex = Integer.valueOf(parameters[1]);
|
||||||
|
//判断parameters是否存在第三个元素,若不存在,则将字符串最长长度设置为与最小字符串长度一致
|
||||||
|
int endIndex = parameters.length > 2 ? Integer.valueOf(parameters[2]) : startIndex;
|
||||||
|
|
||||||
|
//判断字符串种子是否包含双引号,若包含双引号,则去掉双引号后将其转换,若不包含,则
|
||||||
|
//表示字符串种子属于特殊种子,按照枚举进行添加
|
||||||
|
if (seed.indexOf("\"") > -1) {
|
||||||
|
seed = seed.substring(seed.indexOf("\"") + 1, seed.lastIndexOf("\""));
|
||||||
|
} else {
|
||||||
|
switch (seed.toUpperCase()) {
|
||||||
|
case "NUM":
|
||||||
|
seed = StringMode.NUM.getSeed();
|
||||||
|
break;
|
||||||
|
case "CAP":
|
||||||
|
seed = StringMode.CAP.getSeed();
|
||||||
|
break;
|
||||||
|
case "LOW":
|
||||||
|
seed = StringMode.LOW.getSeed();
|
||||||
|
break;
|
||||||
|
case "CH":
|
||||||
|
seed = StringMode.CH.getSeed();
|
||||||
|
break;
|
||||||
|
case "AREA":
|
||||||
|
seed = StringMode.AREA.getSeed();
|
||||||
|
break;
|
||||||
|
case "SURNAME":
|
||||||
|
seed = StringMode.SURNAME.getSeed();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回生成的随机字符串
|
||||||
|
return new RandomString(seed).toString(startIndex, endIndex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 定义对指定时间处理函数
|
||||||
|
* </p>
|
||||||
|
* @return 处理后的时间
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static DataDriverFunction getTime() {
|
||||||
|
//定义规则
|
||||||
|
String regex = "time\\(((\\d{4}[-\\.年\\\\/][01]?\\d[-\\.月\\\\\\/][0123]?\\d日?"
|
||||||
|
+ "( [012]?\\d[:时][0123456]?\\d分?"
|
||||||
|
+ "([:分][0123456]?\\d秒?)?)?)|"
|
||||||
|
+ "([012]?\\d[:时][0123456]?\\d分?([:分][0123456]?\\d秒?))|"
|
||||||
|
+ "(\\d+)), ?(-?\\d+(\\.\\d+)?"
|
||||||
|
+ "([ymwdhs]|(min)))+\\)";
|
||||||
|
return new DataDriverFunction(regex, text -> {
|
||||||
|
//获取公式中有效部分
|
||||||
|
String str = text.substring(text.indexOf("(") + 1, text.indexOf(")"));
|
||||||
|
//将公式有效部分按照分隔符号进行切分
|
||||||
|
String[] parameters = str.split(", ?");
|
||||||
|
|
||||||
|
return disposeTime(parameters[0], parameters[1]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义对当前时间处理函数
|
||||||
|
* @return 处理后的时间
|
||||||
|
*/
|
||||||
|
public static DataDriverFunction getNowTime() {
|
||||||
|
//定义规则
|
||||||
|
String regex = "time\\(((-?\\d+(\\.\\d+)?([ymwdhs]|(min)))+)?\\)";
|
||||||
|
return new DataDriverFunction(regex, text -> {
|
||||||
|
//获取公式中有效部分
|
||||||
|
String str = text.substring(text.indexOf("(") + 1, text.indexOf(")"));
|
||||||
|
|
||||||
|
return disposeTime("", str);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于对时间进行处理
|
||||||
|
* @param timeText 设置时间的文本
|
||||||
|
* @param pattern 时间处理规则
|
||||||
|
* @return 返回处理后的时间
|
||||||
|
*/
|
||||||
|
private static String disposeTime(String timeText, String pattern) {
|
||||||
|
Time time = new Time(timeText);
|
||||||
|
time.addTime(pattern);
|
||||||
|
|
||||||
|
return time.getFormatTime();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.tool.readfile;
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -14,6 +14,9 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.hwpf.HWPFDocument;
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
import org.apache.poi.hwpf.usermodel.Paragraph;
|
import org.apache.poi.hwpf.usermodel.Paragraph;
|
||||||
import org.apache.poi.hwpf.usermodel.Range;
|
import org.apache.poi.hwpf.usermodel.Range;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.CellType;
|
||||||
|
import org.apache.poi.ss.usermodel.DateUtil;
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
@ -23,6 +26,7 @@ import org.apache.poi.xwpf.usermodel.XWPFParagraph;
|
||||||
|
|
||||||
import com.opencsv.CSVReader;
|
import com.opencsv.CSVReader;
|
||||||
|
|
||||||
|
import pres.auxiliary.tool.date.Time;
|
||||||
import pres.auxiliary.tool.file.UnsupportedFileException;
|
import pres.auxiliary.tool.file.UnsupportedFileException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,43 +42,6 @@ import pres.auxiliary.tool.file.UnsupportedFileException;
|
||||||
* @since JDK 12
|
* @since JDK 12
|
||||||
*/
|
*/
|
||||||
public class ListFileRead {
|
public class ListFileRead {
|
||||||
/**
|
|
||||||
* 切分标记:tap
|
|
||||||
*/
|
|
||||||
public static final String SPLIT_TAB = "\\t";
|
|
||||||
/**
|
|
||||||
* 切分标记:空格
|
|
||||||
*/
|
|
||||||
public static final String SPLIT_SPACE = " ";
|
|
||||||
/**
|
|
||||||
* 切分标记:中文逗号
|
|
||||||
*/
|
|
||||||
public static final String SPLIT_COMMA_CH = ",";
|
|
||||||
/**
|
|
||||||
* 切分标记:英文逗号
|
|
||||||
*/
|
|
||||||
public static final String SPLIT_COMMA_EN = ",";
|
|
||||||
/**
|
|
||||||
* 切分标记:中文分号
|
|
||||||
*/
|
|
||||||
public static final String SPLIT_SEMICOLON_CH = ";";
|
|
||||||
/**
|
|
||||||
* 切分标记:英文分号
|
|
||||||
*/
|
|
||||||
public static final String SPLIT_SEMICOLON_EN = ";";
|
|
||||||
/**
|
|
||||||
* 切分标记:中文顿号
|
|
||||||
*/
|
|
||||||
public static final String SPLIT_STOP_CH = "、";
|
|
||||||
/**
|
|
||||||
* 切分标记:斜杠
|
|
||||||
*/
|
|
||||||
public static final String SPLIT_SLASH = "/";
|
|
||||||
/**
|
|
||||||
* 切分标记:反斜杠
|
|
||||||
*/
|
|
||||||
public static final String SPLIT_BACKSLASH = "\\\\";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储被切分的词语<br>
|
* 存储被切分的词语<br>
|
||||||
* 外层ArrayList:存在多列的情况,存储每一列<br>
|
* 外层ArrayList:存在多列的情况,存储每一列<br>
|
||||||
|
@ -109,13 +76,13 @@ public class ListFileRead {
|
||||||
* </ol>
|
* </ol>
|
||||||
* 除上述两种文件类型外,其他的文件调用该构造方法时,则等同于调用{@link #ListFileRead(File, String)}
|
* 除上述两种文件类型外,其他的文件调用该构造方法时,则等同于调用{@link #ListFileRead(File, String)}
|
||||||
* @param file 待读取的文件对象
|
* @param file 待读取的文件对象
|
||||||
* @param regex sheet名称或切分文本的规则
|
* @param pattern sheet名称或切分文本的规则
|
||||||
* @throws IOException 文件状态或路径不正确时抛出的异常
|
* @throws IOException 文件状态或路径不正确时抛出的异常
|
||||||
*/
|
*/
|
||||||
public ListFileRead(File file, String regex) throws IOException {
|
public ListFileRead(File file, String pattern) throws IOException {
|
||||||
//若regex为null,则赋为空
|
//若pattern为null,则赋为空
|
||||||
if (regex == null) {
|
if (pattern == null) {
|
||||||
regex = "";
|
pattern = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 存储文件的名称
|
// 存储文件的名称
|
||||||
|
@ -124,16 +91,16 @@ public class ListFileRead {
|
||||||
switch ( fileName.substring(fileName.lastIndexOf(".") + 1)) {
|
switch ( fileName.substring(fileName.lastIndexOf(".") + 1)) {
|
||||||
case "doc":
|
case "doc":
|
||||||
case "docx":
|
case "docx":
|
||||||
readWord(file, regex);
|
readWord(file, pattern);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "xls":
|
case "xls":
|
||||||
case "xlsx":
|
case "xlsx":
|
||||||
readExcel(file, regex);
|
readExcel(file, pattern);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "txt":
|
case "txt":
|
||||||
readTxt(file, regex);
|
readTxt(file, pattern);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "csv":
|
case "csv":
|
||||||
|
@ -430,7 +397,7 @@ public class ListFileRead {
|
||||||
for (int cellNum = 0; cellNum < row.getLastCellNum(); cellNum++) {
|
for (int cellNum = 0; cellNum < row.getLastCellNum(); cellNum++) {
|
||||||
//存储单元格的内容,若单元格为null,则存储空串
|
//存储单元格的内容,若单元格为null,则存储空串
|
||||||
try {
|
try {
|
||||||
texts.add(row.getCell(cellNum).toString());
|
texts.add(getCellContent(row.getCell(cellNum)));
|
||||||
}catch (NullPointerException e) {
|
}catch (NullPointerException e) {
|
||||||
texts.add("");
|
texts.add("");
|
||||||
}
|
}
|
||||||
|
@ -532,4 +499,38 @@ public class ListFileRead {
|
||||||
|
|
||||||
fip.close();
|
fip.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据单元格的类型,对其内容进行输出
|
||||||
|
* @param cell 单元格类对象
|
||||||
|
* @return 单元格中的文本
|
||||||
|
*/
|
||||||
|
private String getCellContent(Cell cell) {
|
||||||
|
//判断单元格中的内容的格式
|
||||||
|
if (CellType.NUMERIC == cell.getCellTypeEnum()) {
|
||||||
|
//数值类型
|
||||||
|
//判断单元格内的数据是否为日期
|
||||||
|
if (DateUtil.isCellDateFormatted(cell)) {
|
||||||
|
//将单元格内容转换为Date后,在time中进行存储
|
||||||
|
Time time = new Time(cell.getDateCellValue());
|
||||||
|
//根据存储的时间格式,对时间进行转换,输出格式化后的时间
|
||||||
|
return time.getFormatTime();
|
||||||
|
} else {
|
||||||
|
//若非日期格式,则强转为字符串格式,之后输出
|
||||||
|
cell.setCellType(CellType.STRING);
|
||||||
|
return cell.getStringCellValue();
|
||||||
|
}
|
||||||
|
} else if (CellType.FORMULA == cell.getCellTypeEnum()) {
|
||||||
|
//公式类型
|
||||||
|
//公式得到的值可能是一个字符串,也可能是一个数字,此时则需要进行区分(转换错误会抛出异常)
|
||||||
|
try {
|
||||||
|
return cell.getRichStringCellValue().getString();
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
return String.valueOf(cell.getNumericCellValue());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//其他类型,按照字符串进行读取
|
||||||
|
return cell.getStringCellValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.datadriven;
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
public class NumberDataDriven extends DataDriven {
|
public class NumberDataDriven extends DataDriven {
|
||||||
// /**
|
// /**
|
|
@ -0,0 +1,63 @@
|
||||||
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
|
public enum SplitType {
|
||||||
|
/**
|
||||||
|
* 切分标记:tap
|
||||||
|
*/
|
||||||
|
SPLIT_TAB("\\t"),
|
||||||
|
/**
|
||||||
|
* 切分标记:空格
|
||||||
|
*/
|
||||||
|
SPLIT_SPACE(" "),
|
||||||
|
/**
|
||||||
|
* 切分标记:中文逗号
|
||||||
|
*/
|
||||||
|
SPLIT_COMMA_CH(","),
|
||||||
|
/**
|
||||||
|
* 切分标记:英文逗号
|
||||||
|
*/
|
||||||
|
SPLIT_COMMA_EN(","),
|
||||||
|
/**
|
||||||
|
* 切分标记:中文分号
|
||||||
|
*/
|
||||||
|
SPLIT_SEMICOLON_CH(";"),
|
||||||
|
/**
|
||||||
|
* 切分标记:英文分号
|
||||||
|
*/
|
||||||
|
SPLIT_SEMICOLON_EN(";"),
|
||||||
|
/**
|
||||||
|
* 切分标记:中文顿号
|
||||||
|
*/
|
||||||
|
SPLIT_STOP_CH("、"),
|
||||||
|
/**
|
||||||
|
* 切分标记:斜杠
|
||||||
|
*/
|
||||||
|
SPLIT_SLASH("/"),
|
||||||
|
/**
|
||||||
|
* 切分标记:反斜杠
|
||||||
|
*/
|
||||||
|
SPLIT_BACKSLASH("\\\\"),
|
||||||
|
;
|
||||||
|
/**
|
||||||
|
* 分隔符号
|
||||||
|
*/
|
||||||
|
String splitSign = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化数据
|
||||||
|
* @param splitSign 分隔符号
|
||||||
|
*/
|
||||||
|
private SplitType(String splitSign) {
|
||||||
|
this.splitSign = splitSign;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于返回分隔文本的符号
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getSplitSign() {
|
||||||
|
return splitSign;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.datadriven;
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
public class StringDataDriven extends DataDriven {
|
public class StringDataDriven extends DataDriven {
|
||||||
|
|
|
@ -0,0 +1,423 @@
|
||||||
|
package pres.auxiliary.work.selenium.datadriven;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import pres.auxiliary.tool.date.Time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p><b>文件名:</b>TestNGDataDriver.java</p>
|
||||||
|
* <p><b>用途:</b>
|
||||||
|
* 根据文件中的数据内容返回适配TestNG的数据驱动,以便于在编写自动化脚本中使用。源数据文件支持
|
||||||
|
* xls/xlsx/csv/txt/doc/docx,支持自定义特殊关键词,其自定义的关键词用“${关键词}”
|
||||||
|
* 进行标记,系统根据在{@link #addFunction(String, DataFunction)}中定义的处理方式对数据进行处理。
|
||||||
|
* 具体的用法可以参考:
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* 在类中可按照以下方法定义:
|
||||||
|
* <pre>{@code
|
||||||
|
* dataDriver.addFunction("test", text -> "HelloWorld");
|
||||||
|
*dataDriver.addFunction("select(\\d+)", text -> {
|
||||||
|
* switch(Integer.value(text)) {
|
||||||
|
* case 1:
|
||||||
|
* return "function1"
|
||||||
|
* break;
|
||||||
|
* case 2:
|
||||||
|
* return "function2"
|
||||||
|
* break;
|
||||||
|
* }
|
||||||
|
*});
|
||||||
|
* </pre>
|
||||||
|
* 从数据驱动中读取到的数据有${test}、${select(1)},则按照字符串的形式输出后分别得到“HelloWorld”、“function1”。
|
||||||
|
* </p>
|
||||||
|
* <p><b>编码时间:</b>2020年6月3日上午7:04:51</p>
|
||||||
|
* <p><b>修改时间:</b>2020年6月3日上午7:04:51</p>
|
||||||
|
* @author 彭宇琦
|
||||||
|
* @version Ver1.0
|
||||||
|
* @since JDK 8
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TestNGDataDriver {
|
||||||
|
/**
|
||||||
|
* 用于存储数据列的名称
|
||||||
|
*/
|
||||||
|
private ArrayList<String> titleList = new ArrayList<>();
|
||||||
|
/**
|
||||||
|
* 用于存储读取到的数据
|
||||||
|
*/
|
||||||
|
private ArrayList<Data> dataList = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于存储自定义的公式
|
||||||
|
*/
|
||||||
|
private HashMap<String, DataFunction> dataFunctionMap = new HashMap<>(16);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于对日期格式或特殊字段输入的日期进行转换
|
||||||
|
*/
|
||||||
|
private Time time = new Time();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于返回数据驱动中列表的元素个数,即当前数据驱动中最大行元素个数
|
||||||
|
* @return 列元素个数
|
||||||
|
*/
|
||||||
|
public int columnSize() {
|
||||||
|
//当前添加的数据中,每一个元素都对应一个列名,故通过列名可判断最大行的元素个数
|
||||||
|
return titleList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于设置日期的输出格式,该方法仅对由excel读取的日期格式或由特殊字段输出的日期生效
|
||||||
|
*/
|
||||||
|
public void setDateFromat(String pattern) {
|
||||||
|
time.setTimeFormat(pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于添加自定义的公式,支持传入正则表达式,当数据驱动中的数据满足传入的正则时,则会
|
||||||
|
* 将其按照在公式中定义的处理方式对数据进行处理,生成对应的数据。注意,公式的返回值和
|
||||||
|
* 传参均为{@link String}类型
|
||||||
|
* @param regex 正则表达式
|
||||||
|
* @param function 数据处理方法
|
||||||
|
*/
|
||||||
|
public void addFunction(DataDriverFunction function) {
|
||||||
|
dataFunctionMap.put(function.getRegex(), function.getFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据传入文件格式,读取文件的内容添加至数据驱动中。该方法可用于读取xls/xlsx/csv/doc/docx/txt格式的文件,
|
||||||
|
* 根据不同的文件格式,其pattern参数具有不同的意义:
|
||||||
|
* <ol>
|
||||||
|
* <li>当读取的文件为Excel文件(xls/xlsx格式)时,其传入的pattern表示需要读取的sheet名称</li>
|
||||||
|
* <li>当读取的文件为文本文件(doc/docx/txt格式)时,其传入的pattern表示对每一行文本的切分规则,以得到一个列表</li>
|
||||||
|
* <li>当读取的文件为csv文件(csv格式)时,其传入的pattern不生效(无意义)</li>
|
||||||
|
* </ol>
|
||||||
|
* @param dataFile 源数据文件类对象
|
||||||
|
* @param pattern 读取规则
|
||||||
|
* @param isFirstTitle 首行是否为标题
|
||||||
|
* @throws IOException 当文件读取有误时抛出的异常
|
||||||
|
*/
|
||||||
|
public void addDataDriver(File dataFile, String pattern, boolean isFirstTitle) throws IOException {
|
||||||
|
//读取文件内的数据
|
||||||
|
ListFileRead data = new ListFileRead(dataFile, pattern);
|
||||||
|
//由于数据按照列的形式读取,故此处将数据转置
|
||||||
|
data.tableTransposition();
|
||||||
|
|
||||||
|
//若设定首行为标题行,则根据首行元素读取标题
|
||||||
|
if (isFirstTitle) {
|
||||||
|
//定位到首行
|
||||||
|
List<String> dataTitleList = data.getColumn(0);
|
||||||
|
|
||||||
|
//记录当前标题的个数
|
||||||
|
for (int i = 0; i < data.getMaxRowNumber(); i++) {
|
||||||
|
//判断单元格是否为空或者为空串,若为空串,则存储为“数据 + 列下标”的形式
|
||||||
|
if (dataTitleList.get(i).isEmpty()) {
|
||||||
|
//rowSize() + 1表示在整个数据驱动中其实际下标加上1
|
||||||
|
titleList.add("数据" + (1 + columnSize()));
|
||||||
|
} else {
|
||||||
|
//为避免添加多个文件时出现重复数据,此处做一个判断重复的工作,若列名重复,则添加序号
|
||||||
|
String title = dataTitleList.get(i);
|
||||||
|
int index = 1;
|
||||||
|
while(titleList.contains(title)) {
|
||||||
|
title += (++index);
|
||||||
|
}
|
||||||
|
titleList.add(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历所有行,读取所有的数据
|
||||||
|
for (int rowIndex = isFirstTitle ? 1 : 0; rowIndex < data.getMaxColumnNumber(); rowIndex++) {
|
||||||
|
addRowData(isFirstTitle ? rowIndex - 1 : rowIndex, data.getColumn(rowIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回当前存储的所有标题
|
||||||
|
* @return 返回存储的标题
|
||||||
|
*/
|
||||||
|
public ArrayList<String> getTitle() {
|
||||||
|
return titleList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回可以使用的TestNG数据驱动。注意,数组第一维代表获取到的数据驱动的行,第二维只包含
|
||||||
|
* 一个{@link Data}类对象,通过该对象,对获取到的所有数据进行返回,以简化在编写脚本时
|
||||||
|
* 的传参
|
||||||
|
*
|
||||||
|
* @return TestNG数据驱动
|
||||||
|
*/
|
||||||
|
public Object[][] getDataDriver() {
|
||||||
|
Object[][] objs = new Object[dataList.size()][1];
|
||||||
|
|
||||||
|
for (int i = 0; i < dataList.size(); i++) {
|
||||||
|
objs[i][0] = dataList.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于将一行的数据转为Data类对象
|
||||||
|
* @param rowDataList 一行数据
|
||||||
|
* @return 返回一行数据的Data类对象
|
||||||
|
*/
|
||||||
|
private void addRowData(int rowInde, List<String> rowDataList) {
|
||||||
|
//当rowInde大于dataList的总列数时,则表示未对该行进行存储,此时存在两种情况:
|
||||||
|
//1.第一次文件,此时dataList并无数据,调用方法时为初次添加数据,则按照正常方式添加
|
||||||
|
//2.非第一次读取文件,此时dataList已存在上次读取的数据,当写入的数据行数大于存储的行数
|
||||||
|
//时,直接添加数据会造成数据向左移,则需要读取原始列表的内容,将原来没有的数据补全后再
|
||||||
|
//添加数据
|
||||||
|
if (rowInde > dataList.size() - 1) {
|
||||||
|
Data data = new Data();
|
||||||
|
//判断rowDataList元素与上一行元素个数一致,若一致,则表示当前为第一次读取
|
||||||
|
if (dataList.size() != 0 && dataList.get(rowInde - 1).dataList.size() != rowDataList.size()) {
|
||||||
|
//若上一行的元素个数与rowDataList的元素个数不一致,则此时是非第一次读取文件,rowDataList存在数据,则
|
||||||
|
//将rowDataList之前的列都置为空串
|
||||||
|
int oldListSize = dataList.get(rowInde - 1).dataList.size();
|
||||||
|
for (int index = 0; index < oldListSize - rowDataList.size(); index++) {
|
||||||
|
data.dataList.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//存储数据
|
||||||
|
rowDataList.forEach(data.dataList :: add);
|
||||||
|
dataList.add(data);
|
||||||
|
} else {
|
||||||
|
rowDataList.forEach(dataList.get(rowInde).dataList :: add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p><b>文件名:</b>TestNGDataDriver.java</p>
|
||||||
|
* <p><b>用途:</b>
|
||||||
|
* 存储从文件中读取到的数据,根据列名或列下标,通过不同的get方法,获取不同类型的数据。当传入的
|
||||||
|
* 列名或下标不存在时,则返回空串
|
||||||
|
* </p>
|
||||||
|
* <p><b>编码时间:</b>2020年6月3日上午7:12:20</p>
|
||||||
|
* <p><b>修改时间:</b>2020年6月3日上午7:12:20</p>
|
||||||
|
* @author 彭宇琦
|
||||||
|
* @version Ver1.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Data {
|
||||||
|
/**
|
||||||
|
* 切分公式标记
|
||||||
|
*/
|
||||||
|
private final String SPLIT_START = "\\$\\{";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公式起始标记
|
||||||
|
*/
|
||||||
|
private final String FUNCTION_SIGN_START = "${";
|
||||||
|
/**
|
||||||
|
* 公式结束标记
|
||||||
|
*/
|
||||||
|
private final String FUNCTION_SIGN_END = "}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于存储数据
|
||||||
|
*/
|
||||||
|
private ArrayList<String> dataList = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列名称,以字符串的形式返回数据
|
||||||
|
* @param listName 列名称
|
||||||
|
* @return 字符串形式的数据
|
||||||
|
*/
|
||||||
|
public String getString(String listName) {
|
||||||
|
//判断列表是否存在,若列名不存在,则返回一个空串
|
||||||
|
return titleList.indexOf(listName) > -1 ? getString(titleList.indexOf(listName)) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列编号,以字符串的形式返回数据
|
||||||
|
* @param index 列下标
|
||||||
|
* @return 字符串形式的数据
|
||||||
|
*/
|
||||||
|
public String getString(int index) {
|
||||||
|
|
||||||
|
return index < dataList.size() ? disposeContent(dataList.get(index)) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列名称,以double的形式对数据进行返回
|
||||||
|
* @param listName 列表名称
|
||||||
|
* @return double类型的数据
|
||||||
|
* @throw NumberFormatException 数据无法转时抛出的异常
|
||||||
|
*/
|
||||||
|
public double getDouble(String listName) {
|
||||||
|
return Double.valueOf(getString(listName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列编号,以double的形式对数据进行返回
|
||||||
|
* @param index 列下标
|
||||||
|
* @return double类型的数据
|
||||||
|
* @throw NumberFormatException 数据无法转时抛出的异常
|
||||||
|
*/
|
||||||
|
public double getDouble(int index) {
|
||||||
|
return Double.valueOf(getString(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列名称,以int的形式对数据进行返回
|
||||||
|
* @param listName 列表名称
|
||||||
|
* @return int类型的数据
|
||||||
|
* @throw NumberFormatException 数据无法转换时抛出的异常
|
||||||
|
*/
|
||||||
|
public int getInt(String listName) {
|
||||||
|
return Integer.valueOf(getString(listName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列编号,以int的形式对数据进行返回
|
||||||
|
* @param index 列下标
|
||||||
|
* @return int类型的数据
|
||||||
|
* @throw NumberFormatException 数据无法转时抛出的异常
|
||||||
|
*/
|
||||||
|
public int getInt(int index) {
|
||||||
|
return Integer.valueOf(getString(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列名称,以long的形式对数据进行返回
|
||||||
|
* @param listName 列表名称
|
||||||
|
* @return long类型的数据
|
||||||
|
* @throw NumberFormatException 数据无法转换时抛出的异常
|
||||||
|
*/
|
||||||
|
public long getLong(String listName) {
|
||||||
|
return Long.valueOf(getString(listName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列编号,以long的形式对数据进行返回
|
||||||
|
* @param index 列下标
|
||||||
|
* @return long类型的数据
|
||||||
|
* @throw NumberFormatException 数据无法转时抛出的异常
|
||||||
|
*/
|
||||||
|
public long getLong(int index) {
|
||||||
|
return Long.valueOf(getString(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列名称,以boolean的形式对数据进行返回
|
||||||
|
* @param listName 列表名称
|
||||||
|
* @return boolean类型的数据
|
||||||
|
*/
|
||||||
|
public boolean getBoolean(String listName) {
|
||||||
|
return Boolean.valueOf(getString(listName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列编号,以boolean的形式对数据进行返回
|
||||||
|
* @param index 列下标
|
||||||
|
* @return boolean类型的数据
|
||||||
|
*/
|
||||||
|
public boolean getBoolean(int index) {
|
||||||
|
return Boolean.valueOf(getString(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列编号,以{@link File}的形式对数据进行返回
|
||||||
|
* @param index 列下标
|
||||||
|
* @return {@link File}类型的数据
|
||||||
|
*/
|
||||||
|
public File getFile(int index) {
|
||||||
|
return new File(getString(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列名称,以{@link File}的形式对数据进行返回
|
||||||
|
* @param listName 列表名称
|
||||||
|
* @return {@link File}类型的数据
|
||||||
|
*/
|
||||||
|
public File getFile(String listName) {
|
||||||
|
return new File(getString(listName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列编号,以{@link Time}的形式对数据进行返回
|
||||||
|
* @param index 列下标
|
||||||
|
* @return {@link Time}类型的数据
|
||||||
|
*/
|
||||||
|
public Time getTime(int index) {
|
||||||
|
return new Time(getString(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于根据列名称,以{@link Time}的形式对数据进行返回
|
||||||
|
* @param listName 列表名称
|
||||||
|
* @return {@link Time}类型的数据
|
||||||
|
*/
|
||||||
|
public Time getTime(String listName) {
|
||||||
|
return new Time(getString(listName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于处理读取得到的内容,并将处理后的内容进行返回
|
||||||
|
* @param content 读取的内容
|
||||||
|
* @return 处理后的内容
|
||||||
|
*/
|
||||||
|
private String disposeContent(String content) {
|
||||||
|
//判断传入的内容是否包含公式起始符号,若不包含,则返回原串
|
||||||
|
if (content.indexOf(FUNCTION_SIGN_START) < 0) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
//存储处理后的内容
|
||||||
|
StringBuilder newContent = new StringBuilder();
|
||||||
|
|
||||||
|
//按照公式起始符号对内容进行切分,遍历切分后的每一个元素
|
||||||
|
String[] texts = content.split(SPLIT_START);
|
||||||
|
for (int i = 0; i < texts.length; i++) {
|
||||||
|
//判断切分的元素是否包含公式结束符号
|
||||||
|
int index;
|
||||||
|
if ((index = texts[i].indexOf(FUNCTION_SIGN_END)) > -1) {
|
||||||
|
//截取公式串,处理公式
|
||||||
|
String disposeText = functionToData(texts[i].substring(0, index));
|
||||||
|
//判断处理后得到字符串是否为null,不为null,则拼接至newContent中
|
||||||
|
if (disposeText != null) {
|
||||||
|
newContent.append(disposeText + texts[i].substring(index + 1));
|
||||||
|
} else {
|
||||||
|
newContent.append(i == 0 ? texts[i] : (FUNCTION_SIGN_START + texts[i]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//若不包含公式结束符号,则直接拼接原串
|
||||||
|
newContent.append(i == 0 ? texts[i] : (FUNCTION_SIGN_START + texts[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//若原串中最后一个元素是公式结束标记,则将该标记拼接至新串的后面
|
||||||
|
if (content.lastIndexOf(FUNCTION_SIGN_START) + FUNCTION_SIGN_START.length() == content.length()) {
|
||||||
|
newContent.append(FUNCTION_SIGN_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newContent.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于对数据驱动中的公式进行处理,返回处理得到的数据,若数据不予存储的任何正则匹配,则
|
||||||
|
* 返回空串
|
||||||
|
* @param content 内容
|
||||||
|
* @return 处理后的内容
|
||||||
|
*/
|
||||||
|
private String functionToData(String content) {
|
||||||
|
//遍历所有的转译公式
|
||||||
|
for (String regex : dataFunctionMap.keySet()) {
|
||||||
|
//若传入的内容与正则匹配,则将数据进行处理,并返回处理结果
|
||||||
|
if (Pattern.compile(regex).matcher(content).matches()) {
|
||||||
|
return dataFunctionMap.get(regex).apply(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//若内容不与任何正则匹配,则返回原始内容
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,107 +0,0 @@
|
||||||
package pres.auxiliary.work.selenium.event;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import org.openqa.selenium.NoSuchElementException;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
import org.openqa.selenium.WebElement;
|
|
||||||
import org.openqa.selenium.support.ui.Select;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>SelectEvent.java</p>
|
|
||||||
* <p><b>用途:</b>定义了对控件进行选择操作相关的方法,可通过该类,对页面的下拉框控件进行选择操作
|
|
||||||
* 注意,该类中的方法仅对标准的下拉选项框(有<select>与<option>标签组成的下拉框)进行操作,对于非标准的
|
|
||||||
* 下拉框无法选择
|
|
||||||
* </p>
|
|
||||||
* <p><b>编码时间:</b>2019年9月29日下午3:55:34</p>
|
|
||||||
* <p><b>修改时间:</b>2020年5月11日上午7:55:26</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver2.0
|
|
||||||
* @since JDK 12
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SelectEvent extends AbstractEvent {
|
|
||||||
/**
|
|
||||||
* 构造SelectEvent类对象
|
|
||||||
* @param driver WebDriver类对象
|
|
||||||
*/
|
|
||||||
public SelectEvent(WebDriver driver) {
|
|
||||||
super(driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 选择下拉框中的最后一个元素
|
|
||||||
* @param element 下拉框控件对象
|
|
||||||
* @return 选择的选项内容
|
|
||||||
*/
|
|
||||||
public String selectLast(WebElement element) {
|
|
||||||
return select(element, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 选择下拉框中的指定下标的元素,下标支持从后向前获取,传入的下标
|
|
||||||
* 与元素实际所在位置一致,当传入0时,则表示随机获取一个元素,如:<br>
|
|
||||||
* {@code select(element, 1)}表示选择下拉框的第1个元素<br>
|
|
||||||
* {@code select(element, 0)}表示选择下拉框元素个数范围内随机一个元素<br>
|
|
||||||
* {@code select(element, -1)}表示选择下拉框的倒数第1个元素<br>
|
|
||||||
* @param element 下拉框控件对象
|
|
||||||
* @return 选择的选项内容
|
|
||||||
*/
|
|
||||||
public String select(WebElement element, int index) {
|
|
||||||
//元素高亮
|
|
||||||
elementHight(element);
|
|
||||||
//在等待时间内判断元素是否可以点击,若可以点击元素,则进行点击事件
|
|
||||||
String text = wait.until(driver -> {
|
|
||||||
try {
|
|
||||||
//定义Select类对象
|
|
||||||
Select select = new Select(element);
|
|
||||||
int newIndex = getIndex(select.getAllSelectedOptions().size(), index);
|
|
||||||
//选择元素
|
|
||||||
select.selectByIndex(newIndex);
|
|
||||||
return select.getOptions().get(newIndex).getText();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
step = "选择“" + ELEMENT_NAME + "”元素的第" + index + "个选项";
|
|
||||||
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 选择下拉框中的第一个元素
|
|
||||||
* @param element 下拉框控件对象
|
|
||||||
* @return 选择的选项内容
|
|
||||||
*/
|
|
||||||
public String selectFirst(WebElement element) {
|
|
||||||
return select(element, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 由于方法允许传入负数和特殊数字0为下标,并且下标的序号由1开始,
|
|
||||||
* 故可通过该方法对下标的含义进行转义,得到java能识别的下标
|
|
||||||
* @param length 元素的总长度
|
|
||||||
* @param index 传入的下标
|
|
||||||
* @return 可识别的下标
|
|
||||||
* @throws NoSuchElementException 当元素无法查找到时抛出的异常
|
|
||||||
*/
|
|
||||||
private int getIndex(int length, int index) {
|
|
||||||
//判断元素下标是否超出范围,由于可以传入负数,故需要使用绝对值
|
|
||||||
if (Math.abs(index) > length) {
|
|
||||||
throw new NoSuchElementException("指定的选项值大于选项的最大值。选项总个数:" + length + ",指定项:" + index);
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断index的值,若大于0,则从前向后遍历,若小于0,则从后往前遍历,若等于0,则随机输入
|
|
||||||
if (index > 0) {
|
|
||||||
//选择元素,正数的选项值从1开始,故需要减小1
|
|
||||||
return index - 1;
|
|
||||||
} else if (index < 0) {
|
|
||||||
//选择元素,由于index为负数,则长度加上选项值即可得到需要选择的选项
|
|
||||||
return length + index;
|
|
||||||
} else {
|
|
||||||
//为0,则随机进行选择,但不选择第一个选项,避免出现选择到一个空选项
|
|
||||||
return new Random().nextInt(length - 1) + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.tool;
|
package pres.auxiliary.work.selenium.tool;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -29,7 +29,7 @@ import org.dom4j.io.SAXReader;
|
||||||
|
|
||||||
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
|
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
|
||||||
import pres.auxiliary.directory.operate.MakeDirectory;
|
import pres.auxiliary.directory.operate.MakeDirectory;
|
||||||
import pres.auxiliary.selenium.browers.AbstractBrower;
|
import pres.auxiliary.work.selenium.brower.AbstractBrower;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.tool;
|
package pres.auxiliary.work.selenium.tool;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.tool;
|
package pres.auxiliary.work.selenium.tool;
|
||||||
|
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.tool;
|
package pres.auxiliary.work.selenium.tool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>RecordStateException.java</p>
|
* <p><b>文件名:</b>RecordStateException.java</p>
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.tool;
|
package pres.auxiliary.work.selenium.tool;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
|
@ -20,6 +20,7 @@ import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriverException;
|
import org.openqa.selenium.WebDriverException;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
|
||||||
|
@ -576,7 +577,7 @@ public class RecordTool {
|
||||||
bf.close();
|
bf.close();
|
||||||
|
|
||||||
//将模板中的json转换为JSONObject类,并添加标题与id
|
//将模板中的json转换为JSONObject类,并添加标题与id
|
||||||
JSONObject json = JSONObject.parseObject(jsonScript);
|
JSONObject json = JSON.parseObject(jsonScript);
|
||||||
json.getJSONObject("rootTopic").put("title", projectedName);
|
json.getJSONObject("rootTopic").put("title", projectedName);
|
||||||
json.getJSONObject("rootTopic").put("id", UUID.randomUUID());
|
json.getJSONObject("rootTopic").put("id", UUID.randomUUID());
|
||||||
|
|
||||||
|
@ -584,7 +585,7 @@ public class RecordTool {
|
||||||
int moduleIndex = 0;
|
int moduleIndex = 0;
|
||||||
for (String moduleName : module.keySet()) {
|
for (String moduleName : module.keySet()) {
|
||||||
//读取模块信息的json
|
//读取模块信息的json
|
||||||
JSONObject moduleJson = JSONObject.parseObject(RecordTool.getModuleJsonInformation(moduleName));
|
JSONObject moduleJson = JSON.parseObject(RecordTool.getModuleJsonInformation(moduleName));
|
||||||
//编写模块信息
|
//编写模块信息
|
||||||
addChildren(json.getJSONObject("rootTopic"), moduleName);
|
addChildren(json.getJSONObject("rootTopic"), moduleName);
|
||||||
|
|
||||||
|
@ -593,7 +594,7 @@ public class RecordTool {
|
||||||
//循环,读取所有的测试类信息
|
//循环,读取所有的测试类信息
|
||||||
for (int testClassIndex = 0; testClassIndex < testClassList.size(); testClassIndex++) {
|
for (int testClassIndex = 0; testClassIndex < testClassList.size(); testClassIndex++) {
|
||||||
//读取每一个测试类json
|
//读取每一个测试类json
|
||||||
JSONObject testClassJson = JSONObject.parseObject(testClassList.get(testClassIndex).toString());
|
JSONObject testClassJson = JSON.parseObject(testClassList.get(testClassIndex).toString());
|
||||||
//编写测试类信息
|
//编写测试类信息
|
||||||
addChildren(json.getJSONObject("rootTopic").
|
addChildren(json.getJSONObject("rootTopic").
|
||||||
getJSONObject("children").getJSONArray("attached").
|
getJSONObject("children").getJSONArray("attached").
|
||||||
|
@ -604,7 +605,7 @@ public class RecordTool {
|
||||||
//循环,读取测试类下所有的测试方法
|
//循环,读取测试类下所有的测试方法
|
||||||
for (int methodIndex = 0; methodIndex < methodList.size(); methodIndex++) {
|
for (int methodIndex = 0; methodIndex < methodList.size(); methodIndex++) {
|
||||||
//读取每一个测试方法的json
|
//读取每一个测试方法的json
|
||||||
JSONObject methodJson = JSONObject.parseObject(methodList.get(methodIndex).toString());
|
JSONObject methodJson = JSON.parseObject(methodList.get(methodIndex).toString());
|
||||||
//写入测试方法信息
|
//写入测试方法信息
|
||||||
String methodInformation = "方法名:";
|
String methodInformation = "方法名:";
|
||||||
methodInformation += (methodJson.getString("name") + "\n");
|
methodInformation += (methodJson.getString("name") + "\n");
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.tool;
|
package pres.auxiliary.work.selenium.tool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>RecordToolConfigException.java</p>
|
* <p><b>文件名:</b>RecordToolConfigException.java</p>
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.tool;
|
package pres.auxiliary.work.selenium.tool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>RecordType.java</p>
|
* <p><b>文件名:</b>RecordType.java</p>
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.tool;
|
package pres.auxiliary.work.selenium.tool;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -14,7 +14,6 @@ import org.openqa.selenium.WebDriverException;
|
||||||
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
|
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
|
||||||
import pres.auxiliary.directory.exception.UndefinedDirectoryException;
|
import pres.auxiliary.directory.exception.UndefinedDirectoryException;
|
||||||
import pres.auxiliary.directory.operate.MakeDirectory;
|
import pres.auxiliary.directory.operate.MakeDirectory;
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 该类用于在使用selenium进行自动化测试中进行截图的工具。使用该类时可以指定截图保存的位置以及
|
* 该类用于在使用selenium进行自动化测试中进行截图的工具。使用该类时可以指定截图保存的位置以及
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 该异常在XML文件不正确或XML路径不存在时抛出
|
* 该异常在XML文件不正确或XML路径不存在时抛出
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>NoSuchSignValueException.java</p>
|
* <p><b>文件名:</b>NoSuchSignValueException.java</p>
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 该异常在查找到相同文件名时抛出的异常
|
* 该异常在查找到相同文件名时抛出的异常
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>UndefinedElementException.java</p>
|
* <p><b>文件名:</b>UndefinedElementException.java</p>
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 若传入的模型参数有误时抛出的异常
|
* 若传入的模型参数有误时抛出的异常
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
import org.dom4j.DocumentException;
|
import org.dom4j.DocumentException;
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.selenium.xml;
|
package pres.auxiliary.work.selenium.xml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 该异常提示用户需要检查xml文件是否为空
|
* 该异常提示用户需要检查xml文件是否为空
|
Binary file not shown.
|
@ -9,10 +9,7 @@ import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import pres.auxiliary.selenium.browers.ChromeBrower;
|
import pres.auxiliary.work.selenium.tool.RecordTool;
|
||||||
import pres.auxiliary.selenium.event.ClickEvent;
|
|
||||||
import pres.auxiliary.selenium.event.Event;
|
|
||||||
import pres.auxiliary.selenium.tool.RecordTool;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>ClickEventTest.java</p>
|
* <p><b>文件名:</b>ClickEventTest.java</p>
|
||||||
|
|
|
@ -10,9 +10,7 @@ import org.testng.annotations.BeforeMethod;
|
||||||
import org.testng.annotations.BeforeTest;
|
import org.testng.annotations.BeforeTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import pres.auxiliary.selenium.browers.ChromeBrower;
|
import pres.auxiliary.work.selenium.tool.RecordTool;
|
||||||
import pres.auxiliary.selenium.event.DataListEvent.ListEvent;
|
|
||||||
import pres.auxiliary.selenium.tool.RecordTool;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue