调整类结构,删除无效的类
This commit is contained in:
parent
40ad893020
commit
69ad08ac60
136
pom.xml
136
pom.xml
|
@ -1,30 +1,21 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<modelVersion>4.0.0</modelVersion>
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>pres.appnium.test</groupId>
|
<groupId>pres.appnium.test</groupId>
|
||||||
<artifactId>Autest</artifactId>
|
<artifactId>Autest</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>Autest</name>
|
<name>Autest</name>
|
||||||
<url>http://maven.apache.org</url>
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
|
||||||
<version>3.0.0</version>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.seleniumhq.selenium</groupId>
|
<groupId>org.seleniumhq.selenium</groupId>
|
||||||
<artifactId>selenium-java</artifactId>
|
<artifactId>selenium-java</artifactId>
|
||||||
|
@ -105,69 +96,74 @@
|
||||||
<artifactId>fastjson</artifactId>
|
<artifactId>fastjson</artifactId>
|
||||||
<version>1.2.61</version>
|
<version>1.2.61</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-all</artifactId>
|
<artifactId>hutool-all</artifactId>
|
||||||
<version>5.0.2</version>
|
<version>5.0.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 数据库连接依赖包 -->
|
<!-- 数据库连接依赖包 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.noraui</groupId>
|
<groupId>com.github.noraui</groupId>
|
||||||
<artifactId>ojdbc7</artifactId>
|
<artifactId>ojdbc7</artifactId>
|
||||||
<version>12.1.0.2</version>
|
<version>12.1.0.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- HttpClient 用于接口测试 -->
|
<!-- HttpClient 用于接口测试 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents</groupId>
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
<artifactId>httpclient</artifactId>
|
<artifactId>httpclient</artifactId>
|
||||||
<version>4.5.12</version>
|
<version>4.5.12</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 解析html -->
|
<!-- 解析html -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jsoup</groupId>
|
<groupId>org.jsoup</groupId>
|
||||||
<artifactId>jsoup</artifactId>
|
<artifactId>jsoup</artifactId>
|
||||||
<version>1.13.1</version>
|
<version>1.13.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!--spring aop + aspectj 切面-->
|
<!--spring aop + aspectj 切面 -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-aop</artifactId>
|
|
||||||
<version>5.2.7.RELEASE</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-core</artifactId>
|
|
||||||
<version>5.2.7.RELEASE</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
|
||||||
<artifactId>aspectjrt</artifactId>
|
|
||||||
<version>1.9.5</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.aspectj</groupId>
|
|
||||||
<artifactId>aspectjweaver</artifactId>
|
|
||||||
<version>1.9.5</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- lombok注解生成get/set方法依赖 -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>spring-aop</artifactId>
|
||||||
<version>1.18.12</version>
|
<version>5.2.7.RELEASE</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.testng</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>testng</artifactId>
|
<artifactId>spring-core</artifactId>
|
||||||
<version>7.3.0</version>
|
<version>5.2.7.RELEASE</version>
|
||||||
<scope>test</scope>
|
</dependency>
|
||||||
</dependency>-->
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjrt</artifactId>
|
||||||
|
<version>1.9.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjweaver</artifactId>
|
||||||
|
<version>1.9.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- lombok注解生成get/set方法依赖 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.12</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId>
|
||||||
|
<version>7.3.0</version> <scope>test</scope> </dependency> -->
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package pres.auxiliary.tool.web;
|
package pres.auxiliary.tool.date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>IncorrectConditionException.java</p>
|
* <p><b>文件名:</b>IncorrectConditionException.java</p>
|
|
@ -6,8 +6,6 @@ import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import pres.auxiliary.tool.web.IncorrectConditionException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* <b>文件名:</b>Time.java
|
* <b>文件名:</b>Time.java
|
||||||
|
|
|
@ -5,7 +5,6 @@ import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
import org.dom4j.Element;
|
|
||||||
import org.dom4j.io.OutputFormat;
|
import org.dom4j.io.OutputFormat;
|
||||||
import org.dom4j.io.XMLWriter;
|
import org.dom4j.io.XMLWriter;
|
||||||
|
|
||||||
|
@ -61,12 +60,4 @@ public class ExcelConfigXmlTool {
|
||||||
writer.write(document);
|
writer.write(document);
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void root() {
|
|
||||||
document.setRootElement(document.addElement("templet"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sheet(String name, String freeze) {
|
|
||||||
Element root = document.getRootElement();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,506 +0,0 @@
|
||||||
package pres.auxiliary.tool.web;
|
|
||||||
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>Condition.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>用于页面统计中记录需要读取的列的定位方式 ,以及其统计的约束条件,并提供数据对比方法<br>
|
|
||||||
* <b>注意:</b>
|
|
||||||
* <ol>
|
|
||||||
* <li>数字和日期的边界限制,可以用中括号"[]"和小括号"()"表示,中括号表可等于,小括号表示不能等于</li>
|
|
||||||
* <li>数字和日期的分段限制,用英文逗号","隔开,逗号后可以有空格也可以没有空格,但逗号前不能包含空格</li>
|
|
||||||
* <li>日期类型按照[小日期,大日期)或者(小日期,大日期]的形式传入,日期的格式应为yyyy-mm-dd</li>
|
|
||||||
* <li>数字类型按照[小数字,大数字)或者(小数字,大数字]的形式传入</li>
|
|
||||||
* </ol>
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年7月28日下午2:13:59
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年7月31日下午7:03:59
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 1.8
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class Condition {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于存储元素定位方式
|
|
||||||
*/
|
|
||||||
private String element;
|
|
||||||
/**
|
|
||||||
* 用于存储约束条件,当约束的类型为数字和日期时,此时存储的数据将是前后值是否允许包含的条件
|
|
||||||
*/
|
|
||||||
private ArrayList<String> constraints = new ArrayList<String>();
|
|
||||||
/**
|
|
||||||
* 约束类型
|
|
||||||
*/
|
|
||||||
private ConstraintType type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于存储元素的标题
|
|
||||||
*/
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于通过列表元素定位方式获取到列表的WebElementEventList对象
|
|
||||||
*/
|
|
||||||
private DataListEvent listEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定义日期约束类型的传入格式
|
|
||||||
*/
|
|
||||||
private final String REGEX_DATE = "[\\[\\(]\\d{4}[-\\.年\\\\\\/][01]?\\d[-\\.月\\\\\\/][0123]?\\d日?"
|
|
||||||
+ "( [012]?\\d[:时][0123456]?\\d分?([:分][0123456]?\\d秒?)?)?, "
|
|
||||||
+ "*\\d{4}[-\\.年\\\\][01]?\\d[-\\.月\\\\][0123]?\\d日?"
|
|
||||||
+ "( [012]?\\d[:时][0123456]?\\d分?([:分][0123456]?\\d秒?)?)?[\\]\\)]";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定义数字约束类型传入格式
|
|
||||||
*/
|
|
||||||
private final String REGEX_NUMBER = "[\\[\\(]\\d+(.\\d+)?, *\\d+(.\\d+)?[\\]\\)]";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定义日期的格式约束
|
|
||||||
*/
|
|
||||||
private final String YEAR_TYPE = "^[-\\+]?[\\d]*$";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 日期和数字大小约束之间的分隔符号
|
|
||||||
*/
|
|
||||||
private final String DATA_SEVERANCE = ";";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定义边界相等的条件
|
|
||||||
*/
|
|
||||||
private final String LIMIT_EQUALS = "1";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 定义边界不等的条件
|
|
||||||
*/
|
|
||||||
private final String LIMIT_UN_EQUALS = "0";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该构造用于当元素需要做约束限制进行统计时,可以使用该构造
|
|
||||||
*
|
|
||||||
* @param title 元素标题
|
|
||||||
* @param element 元素的定位方式
|
|
||||||
* @param type 统计的约束类型,在{@link ConstraintType}枚举类中选择相应的约束类型
|
|
||||||
* @param constraints 约束条件
|
|
||||||
*/
|
|
||||||
public Condition(String title, String element, ConstraintType type, String... constraints) {
|
|
||||||
super();
|
|
||||||
this.element = element;
|
|
||||||
this.type = type;
|
|
||||||
this.title = title;
|
|
||||||
|
|
||||||
// 根据约束类型设置约束条件
|
|
||||||
if (constraints != null && constraints.length != 0) {
|
|
||||||
switch (this.type) {
|
|
||||||
case STRING:
|
|
||||||
setStringConstraint(constraints);
|
|
||||||
break;
|
|
||||||
case DATE:
|
|
||||||
setDateConstraint(constraints);
|
|
||||||
break;
|
|
||||||
case NUMBER:
|
|
||||||
setNumberConstraint(constraints);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该构造用于当元素不需要任何限制进行统计时,可使用该构造
|
|
||||||
*
|
|
||||||
* @param title 元素标题
|
|
||||||
* @param element 元素的定位方式
|
|
||||||
*/
|
|
||||||
public Condition(String title, String element) {
|
|
||||||
super();
|
|
||||||
this.element = element;
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回元素的标题
|
|
||||||
*
|
|
||||||
* @return 元素的标题
|
|
||||||
*/
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回元素的定位方式
|
|
||||||
*
|
|
||||||
* @return 元素的定位方式
|
|
||||||
*/
|
|
||||||
public String getElement() {
|
|
||||||
return element;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回传入的元素定位方式在页面上获取到的WebElementEventList对象
|
|
||||||
*
|
|
||||||
* @param driver 页面的WebDriver对象
|
|
||||||
* @return 返回列表的WebElementEventList对象
|
|
||||||
*/
|
|
||||||
public DataListEvent getListEvent(WebDriver driver) {
|
|
||||||
if (listEvent == null) {
|
|
||||||
listEvent = new DataListEvent(driver);
|
|
||||||
listEvent.add(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
return listEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于返回条件约束组中是否存在约束,若存在约束,则返回true,反之,返回false
|
|
||||||
* @return 返回是否存在约束条件
|
|
||||||
*/
|
|
||||||
public boolean isConstraint() {
|
|
||||||
if (constraints.size() == 0) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于判断传入的数据是否满足约束条件。若传入的数据与约束条件的类型不符合,则默认返回false
|
|
||||||
*
|
|
||||||
* @param data 待判断的数据
|
|
||||||
* @return 是否符合约束条件
|
|
||||||
*/
|
|
||||||
public boolean isConformToConstraint(String data) {
|
|
||||||
// 根据约束类型设置约束条件
|
|
||||||
if (constraints != null && constraints.size() != 0) {
|
|
||||||
switch (this.type) {
|
|
||||||
case STRING:
|
|
||||||
return compareString(data);
|
|
||||||
case DATE:
|
|
||||||
return compareDate(data);
|
|
||||||
case NUMBER:
|
|
||||||
return compareNumber(data);
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断数字类型数据
|
|
||||||
*
|
|
||||||
* @param data 数据
|
|
||||||
* @return 是否符合要求
|
|
||||||
*/
|
|
||||||
private boolean compareNumber(String data) {
|
|
||||||
// 由于指向返回结果
|
|
||||||
boolean a = false;
|
|
||||||
// 转换传入的数据,若抛出转换异常,则直接返回a值
|
|
||||||
double num = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
num = Double.valueOf(data);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 循环,读取所有的约束条件,将数据逐个和约束条件进行大小的对比
|
|
||||||
for (String constraint : constraints) {
|
|
||||||
|
|
||||||
// 由于约束条件中包含大小约束条件和边界的限制,故需要按照规则进行切分
|
|
||||||
String[] ss = constraint.split(DATA_SEVERANCE);
|
|
||||||
|
|
||||||
// 转换最大最小值
|
|
||||||
double minNum = Double.valueOf(ss[0]);
|
|
||||||
double maxNum = Double.valueOf(ss[2]);
|
|
||||||
|
|
||||||
// System.out.println("----------------------------");
|
|
||||||
// System.out.println("约束最小值:" + minNum);
|
|
||||||
// System.out.println("约束最大值:" + maxNum);
|
|
||||||
// System.out.println("待测元素:" + num);
|
|
||||||
|
|
||||||
// 对比最小值,若待测数据小于约束条件的最小值,不满足约束条件,可直接结束循环,节约时间
|
|
||||||
if (LIMIT_EQUALS.equals(ss[1]) && LIMIT_EQUALS.equals(ss[3])) {
|
|
||||||
a = num >= minNum && num <= maxNum;
|
|
||||||
} else if (LIMIT_UN_EQUALS.equals(ss[1]) && LIMIT_EQUALS.equals(ss[3])) {
|
|
||||||
a = num > minNum && num <= maxNum;
|
|
||||||
} else if (LIMIT_EQUALS.equals(ss[1]) && LIMIT_UN_EQUALS.equals(ss[3])) {
|
|
||||||
a = num >= minNum && num < maxNum;
|
|
||||||
} else {
|
|
||||||
a = num > minNum && num < maxNum;
|
|
||||||
}
|
|
||||||
if (a) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断日期类型
|
|
||||||
*
|
|
||||||
* @param data 待测数据
|
|
||||||
* @return 是否符合约束
|
|
||||||
*/
|
|
||||||
private boolean compareDate(String data) {
|
|
||||||
// 由于指向返回结果
|
|
||||||
boolean a = false;
|
|
||||||
// 转换传入的数据,若抛出转换异常,则直接返回a值
|
|
||||||
Long time = 0L;
|
|
||||||
try {
|
|
||||||
time = new SimpleDateFormat(getDateFormat(data)).parse(data).getTime();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 循环,读取所有的约束条件,将数据逐个和约束条件进行大小的对比
|
|
||||||
for (String constraint : constraints) {
|
|
||||||
|
|
||||||
// 由于约束条件中包含大小约束条件和边界的限制,故需要按照规则进行切分
|
|
||||||
String[] ss = constraint.split(DATA_SEVERANCE);
|
|
||||||
|
|
||||||
// 转换最大最小值
|
|
||||||
double minTime = Double.valueOf(ss[0]);
|
|
||||||
double maxTime = Double.valueOf(ss[2]);
|
|
||||||
|
|
||||||
// System.out.println("----------------------------");
|
|
||||||
// System.out.println("约束最小值:" + minTime);
|
|
||||||
// System.out.println("约束最大值:" + maxTime);
|
|
||||||
// System.out.println("待测元素:" + time);
|
|
||||||
|
|
||||||
// 对比最小值,若待测数据小于约束条件的最小值,不满足约束条件,可直接结束循环,节约时间
|
|
||||||
if (LIMIT_EQUALS.equals(ss[1]) && LIMIT_EQUALS.equals(ss[3])) {
|
|
||||||
a = time >= minTime && time <= maxTime;
|
|
||||||
} else if (LIMIT_UN_EQUALS.equals(ss[1]) && LIMIT_EQUALS.equals(ss[3])) {
|
|
||||||
a = time > minTime && time <= maxTime;
|
|
||||||
} else if (LIMIT_EQUALS.equals(ss[1]) && LIMIT_UN_EQUALS.equals(ss[3])) {
|
|
||||||
a = time >= minTime && time < maxTime;
|
|
||||||
} else {
|
|
||||||
a = time > minTime && time < maxTime;
|
|
||||||
}
|
|
||||||
if (a) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断字符串类型
|
|
||||||
*
|
|
||||||
* @param data 待测数据
|
|
||||||
* @return 是否符合约束
|
|
||||||
*/
|
|
||||||
private boolean compareString(String data) {
|
|
||||||
// 循环,读取所有的约束条件,将数据逐个和约束条件进行大小的对比
|
|
||||||
for (String constraint : constraints) {
|
|
||||||
// 判断数据是否与约束条件相同,相同,则返回true
|
|
||||||
if (constraint.equals(data)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 若数据与所有的约束都不符合,则返回false
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置数字类型的约束条件
|
|
||||||
*
|
|
||||||
* @param constraints 约束条件组
|
|
||||||
*/
|
|
||||||
private void setNumberConstraint(String[] constraints) {
|
|
||||||
// 循环,逐个读取约束条件
|
|
||||||
for (String constraint : constraints) {
|
|
||||||
// 判断传入的约束条件是否符合约束条件的传入规则,若不符合规则,则抛出IncorrectConditionException异常
|
|
||||||
if (!Pattern.compile(REGEX_NUMBER).matcher(constraint).matches()) {
|
|
||||||
throw new IncorrectConditionException("约束条件“" + constraint + "”不符合数字约束的传入规则");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定义存储约束条件的字符串
|
|
||||||
String dateConstraint = "";
|
|
||||||
|
|
||||||
// 按照逗号切分字符串
|
|
||||||
String[] c = constraint.split("\\,");
|
|
||||||
|
|
||||||
// 将约束时段的边界提取出来
|
|
||||||
StringBuilder cmin = new StringBuilder(c[0].trim());
|
|
||||||
StringBuilder cmax = new StringBuilder(c[1].trim());
|
|
||||||
|
|
||||||
// 存储边界值的判定条件(移除该字符串则时会返回该字符串)
|
|
||||||
String minSymbox = '[' == cmin.charAt(0) ? LIMIT_EQUALS : LIMIT_UN_EQUALS;
|
|
||||||
String maxSymbox = ']' == cmax.charAt(cmax.length() - 1) ? LIMIT_EQUALS : LIMIT_UN_EQUALS;
|
|
||||||
|
|
||||||
// 转换数字
|
|
||||||
double minNum = 0;
|
|
||||||
double maxNum = 0;
|
|
||||||
try {
|
|
||||||
minNum = Double.valueOf(cmin.delete(0, 1).toString());
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new IncorrectConditionException("约束条件“" + cmin + "”不符合数字约束的传入规则");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
maxNum = Double.valueOf(cmax.delete(cmax.length() - 1, cmax.length()).toString());
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new IncorrectConditionException("约束条件“" + cmax + "”不符合数字约束的传入规则");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断时间戳的大小,若两个时间戳大小相反,则反向存储
|
|
||||||
if (minNum > maxNum) {
|
|
||||||
dateConstraint += (maxNum + DATA_SEVERANCE + maxSymbox + DATA_SEVERANCE + minNum + DATA_SEVERANCE
|
|
||||||
+ minSymbox);
|
|
||||||
} else {
|
|
||||||
dateConstraint += (minNum + DATA_SEVERANCE + minSymbox + DATA_SEVERANCE + maxNum + DATA_SEVERANCE
|
|
||||||
+ maxSymbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.constraints.add(dateConstraint);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方用于设置时间类型的约束条件
|
|
||||||
*
|
|
||||||
* @param constraints 约束条件组
|
|
||||||
*/
|
|
||||||
private void setDateConstraint(String[] constraints) {
|
|
||||||
// 循环,逐个读取约束条件
|
|
||||||
for (String constraint : constraints) {
|
|
||||||
// 判断传入的约束条件是否符合约束条件的传入规则,若不符合规则,则抛出IncorrectConditionException异常
|
|
||||||
if (!Pattern.compile(REGEX_DATE).matcher(constraint).matches()) {
|
|
||||||
throw new IncorrectConditionException("约束条件“" + constraint + "”不符合日期约束传入的规则");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定义存储约束条件的字符串
|
|
||||||
String dateConstraint = "";
|
|
||||||
|
|
||||||
// 按照逗号切分字符串
|
|
||||||
String[] c = constraint.split("\\,");
|
|
||||||
// 将约束时段的边界提取出来
|
|
||||||
StringBuilder cmin = new StringBuilder(c[0].trim());
|
|
||||||
StringBuilder cmax = new StringBuilder(c[1].trim());
|
|
||||||
|
|
||||||
// 存储边界值的判定条件(移除该字符串则时会返回该字符串)
|
|
||||||
String minSymbox = '[' == cmin.charAt(0) ? LIMIT_EQUALS : LIMIT_UN_EQUALS;
|
|
||||||
String maxSymbox = ']' == cmax.charAt(cmax.length() - 1) ? LIMIT_EQUALS : LIMIT_UN_EQUALS;
|
|
||||||
|
|
||||||
// 将该日期转换成时间戳,拼接至字符串中
|
|
||||||
long minTime = 0L;
|
|
||||||
long maxTime = 0L;
|
|
||||||
try {
|
|
||||||
minTime = new SimpleDateFormat(getDateFormat(cmin.delete(0, 1).toString())).parse(cmin.toString())
|
|
||||||
.getTime();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
throw new IncorrectConditionException("约束条件“" + cmin + "”不符合日期约束传入的规则");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
maxTime = new SimpleDateFormat(getDateFormat(cmax.delete(cmax.length() - 1, cmax.length()).toString()))
|
|
||||||
.parse(cmax.toString()).getTime();
|
|
||||||
} catch (ParseException e) {
|
|
||||||
throw new IncorrectConditionException("约束条件“" + cmax + "”不符合日期约束传入的规则");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断时间戳的大小,若两个时间戳大小相反,则反向存储
|
|
||||||
if (minTime > maxTime) {
|
|
||||||
dateConstraint += (maxTime + ";" + maxSymbox + ";" + minTime + ";" + minSymbox);
|
|
||||||
} else {
|
|
||||||
dateConstraint += (minTime + ";" + minSymbox + ";" + maxTime + ";" + maxSymbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.constraints.add(dateConstraint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置字符串类型的约束条件
|
|
||||||
*
|
|
||||||
* @param constraints 约束条件组
|
|
||||||
*/
|
|
||||||
private void setStringConstraint(String[] constraints) {
|
|
||||||
// 存储整个约束条件
|
|
||||||
this.constraints.addAll(Arrays.asList(constraints));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 识别传入的时间格式
|
|
||||||
*
|
|
||||||
* @param time 时间
|
|
||||||
* @return 时间格式
|
|
||||||
*/
|
|
||||||
private String getDateFormat(String time) {
|
|
||||||
boolean year = false;
|
|
||||||
Pattern pattern = Pattern.compile(YEAR_TYPE);
|
|
||||||
if (pattern.matcher(time.substring(0, 4)).matches()) {
|
|
||||||
year = true;
|
|
||||||
}
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
int index = 0;
|
|
||||||
if (!year) {
|
|
||||||
if (time.contains("月") || time.contains("-") || time.contains("/")) {
|
|
||||||
if (Character.isDigit(time.charAt(0))) {
|
|
||||||
index = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
index = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < time.length(); i++) {
|
|
||||||
char chr = time.charAt(i);
|
|
||||||
if (Character.isDigit(chr)) {
|
|
||||||
if (index == 0) {
|
|
||||||
sb.append("y");
|
|
||||||
}
|
|
||||||
if (index == 1) {
|
|
||||||
sb.append("M");
|
|
||||||
}
|
|
||||||
if (index == 2) {
|
|
||||||
sb.append("d");
|
|
||||||
}
|
|
||||||
if (index == 3) {
|
|
||||||
sb.append("H");
|
|
||||||
}
|
|
||||||
if (index == 4) {
|
|
||||||
sb.append("m");
|
|
||||||
}
|
|
||||||
if (index == 5) {
|
|
||||||
sb.append("s");
|
|
||||||
}
|
|
||||||
if (index == 6) {
|
|
||||||
sb.append("S");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (i > 0) {
|
|
||||||
char lastChar = time.charAt(i - 1);
|
|
||||||
if (Character.isDigit(lastChar)) {
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.append(chr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package pres.auxiliary.tool.web;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>ConstraintType.java</p>
|
|
||||||
* <p><b>用途:</b>用于定义约束条件的类型</p>
|
|
||||||
* <p><b>编码时间:</b>2019年7月28日下午2:24:40</p>
|
|
||||||
* <p><b>修改时间:</b>2019年7月28日下午2:24:40</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 1.8
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public enum ConstraintType {
|
|
||||||
/**
|
|
||||||
* 字符串类型
|
|
||||||
*/
|
|
||||||
STRING,
|
|
||||||
/**
|
|
||||||
* 日期类型
|
|
||||||
*/
|
|
||||||
DATE,
|
|
||||||
/**
|
|
||||||
* 数字类型
|
|
||||||
*/
|
|
||||||
NUMBER
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package pres.auxiliary.tool.web;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>IncorrectFileException.java</p>
|
|
||||||
* <p><b>用途:</b>用于读取的文件与相应的代码不匹配时弹出的异常</p>
|
|
||||||
* <p><b>编码时间:</b>2019年8月2日下午5:33:01</p>
|
|
||||||
* <p><b>修改时间:</b>2019年8月2日下午5:33:01</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 1.8
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class IncorrectFileException extends RuntimeException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -5513588664798256321L;
|
|
||||||
|
|
||||||
public IncorrectFileException() {
|
|
||||||
super();
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectFileException(String message, Throwable cause, boolean enableSuppression,
|
|
||||||
boolean writableStackTrace) {
|
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectFileException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectFileException(String message) {
|
|
||||||
super(message);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
public IncorrectFileException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,305 +0,0 @@
|
||||||
package pres.auxiliary.tool.web;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.VerticalAlignment;
|
|
||||||
import org.apache.poi.ss.util.CellRangeAddress;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* <b>文件名:</b>WebDataCompare.java
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>用途:</b>用于对页面数据的操作工具
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>编码时间:</b>2019年8月2日上午9:45:00
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <b>修改时间:</b>2019年8月3日上午10:42:00
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 1.8
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class WebDataCompare {
|
|
||||||
/**
|
|
||||||
* 定义文件中的换行符
|
|
||||||
*/
|
|
||||||
private static final String FILE_LINK = "\r\n";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存储用户传入的WebDriver对象,当为null时,则使用默认的WebDriver对象,若用户定义时,则使用定义的WebDriver对象
|
|
||||||
*/
|
|
||||||
private static WebDriver driver = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于设置WebDriver对象
|
|
||||||
* @param driver WebDriver对象
|
|
||||||
*/
|
|
||||||
public static void setWebDriver(WebDriver driver) {
|
|
||||||
WebDataCompare.driver = driver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于统计页面数据,根据数据的约束条件进行数据的组合统计,并将统计存储指定的excel文件中
|
|
||||||
*
|
|
||||||
* @param folder 文件保存的文件夹
|
|
||||||
* @param fileName 文件名
|
|
||||||
* @param conditions 条件类对象组
|
|
||||||
* @param iframes 需要定位到列表所在的窗体
|
|
||||||
* @return 统计结果文件
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static File statisData(File folder, String fileName, Condition[] conditions, String... iframes)
|
|
||||||
throws IOException {
|
|
||||||
Event event = null;
|
|
||||||
if (driver == null) {
|
|
||||||
// 构造事件类对象
|
|
||||||
event = Event.newInstance(new ChromeBrower("resource/BrowserDriver/chromedriver.exe", 9222).getDriver());
|
|
||||||
// 循环,添加所有的iframe
|
|
||||||
for (String iframe : iframes) {
|
|
||||||
event.switchFrame(iframe);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
event = Event.newInstance(driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定义map对象,用于记录列表数据
|
|
||||||
LinkedHashMap<Condition, LinkedHashMap<String, Integer>> datas = new LinkedHashMap<Condition, LinkedHashMap<String, Integer>>();
|
|
||||||
// 定义map,用于存储组合条件的数据
|
|
||||||
LinkedHashMap<String, Integer> groupDatas = new LinkedHashMap<String, Integer>();
|
|
||||||
|
|
||||||
// 创建文件夹
|
|
||||||
folder.mkdirs();
|
|
||||||
// 定义目标文件
|
|
||||||
File targeFile = new File(folder, ("\\" + fileName + ".xlsx"));
|
|
||||||
// 判断文件是否存在,若文件存在,则读取文件
|
|
||||||
if (targeFile.exists()) {
|
|
||||||
// 循环,抽取title,用于指定Sheet的名称,并存储该Sheet
|
|
||||||
for (Condition condition : conditions) {
|
|
||||||
// 构造统计map
|
|
||||||
datas.put(condition, readFile(targeFile, condition.getTitle(), 1, 0, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 存储组合条件的map
|
|
||||||
groupDatas = readFile(targeFile, "组合条件", 1, 0, 1);
|
|
||||||
} else {
|
|
||||||
// 循环,抽取title,构造map
|
|
||||||
for (Condition condition : conditions) {
|
|
||||||
// 构造统计map
|
|
||||||
datas.put(condition, new LinkedHashMap<String, Integer>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 指定当前获取列表的行数
|
|
||||||
int index = 0;
|
|
||||||
// 循环,获取页面每一行的数据
|
|
||||||
while (true) {
|
|
||||||
// 用于指定循环是否继续
|
|
||||||
boolean hasData = true;
|
|
||||||
// 用于判断数据是否符合约束条件
|
|
||||||
boolean constraint = true;
|
|
||||||
// 用于存储组合查询符合约束条件的元素值
|
|
||||||
String constraintText = "";
|
|
||||||
|
|
||||||
// 循环,datas中存储的所有的Condition对象,以用于获取一行数据
|
|
||||||
for (Condition condition : datas.keySet()) {
|
|
||||||
try {
|
|
||||||
// 读取第index行数据
|
|
||||||
String text = condition.getListEvent(event.getDriver()).getEvent(condition.getElement(), index).getText().getStringValve();
|
|
||||||
// 判断该数据是否存在于condition指向的Map,若存在,则其Integer加1,不存在,则put如Map
|
|
||||||
if (datas.get(condition).containsKey(text)) {
|
|
||||||
datas.get(condition).put(text, datas.get(condition).get(text) + 1);
|
|
||||||
} else {
|
|
||||||
datas.get(condition).put(text, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断condition中是否存储了约束条件,若无约束条件,则无需判断
|
|
||||||
if (condition.isConstraint()) {
|
|
||||||
// 判断constraint是否已经为false,若已经为false,则表示某一列的元素已经不符合约束,则无需再对比其他列的数据
|
|
||||||
if (!constraint) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
// 若constraint为true,则对比当前列的数据是否符合约束,并将返回值存储至constraint中
|
|
||||||
if (constraint = condition.isConformToConstraint(text)) {
|
|
||||||
constraintText += (condition.getTitle() + ":" + text + FILE_LINK);
|
|
||||||
} else {
|
|
||||||
//当constraint为false时,则直接将constraintText置为空,以便于之后存储判断
|
|
||||||
constraintText = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 判断该值是否符合约束条件
|
|
||||||
} catch (IndexOutOfBoundsException e) {
|
|
||||||
// 若列表元素已被全部读取,则此会抛出IndexOutOfBoundsException,则可直接结束循环
|
|
||||||
hasData = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 判断hasData值,若hasData为false,则表示此时列表上某一列或所有列的数据读取完毕,则可以结束外层循环
|
|
||||||
if (!hasData) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// 判断需要存储的约束条件是否为空,若为空,则不进行存储
|
|
||||||
//注意,其为空只会有两种情况:
|
|
||||||
//1.constraint为true,但condition不存在约束条件,此时,循环中不走约束条件的判断,导致constraint恒为true,但constraintText仍为初始空值
|
|
||||||
//2.condition存在约束,但其中一个元素未通过约束判断,导致constraintText置为了空值
|
|
||||||
//故此处应用constraintText是否为空作为存储至map的条件依据
|
|
||||||
if (!constraintText.isEmpty()) {
|
|
||||||
constraintText = constraintText.substring(0, constraintText.length() - FILE_LINK.length());
|
|
||||||
if (groupDatas.containsKey(constraintText)) {
|
|
||||||
groupDatas.put(constraintText, groupDatas.get(constraintText) + 1);
|
|
||||||
} else {
|
|
||||||
groupDatas.put(constraintText, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化数据
|
|
||||||
index++;
|
|
||||||
constraintText = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
//循环,读取datas中存储的所有的数据,将其一一写入文件中
|
|
||||||
for (Condition condition : datas.keySet()) {
|
|
||||||
writeFile(targeFile, datas.get(condition), condition.getTitle(), 0, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (groupDatas.size() != 0) {
|
|
||||||
writeFile(targeFile, groupDatas, "组合条件", 0, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//若使用默认的WebDriver对象,则关闭其对象
|
|
||||||
if (driver == null) {
|
|
||||||
event.getDriver().quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
//打开文件夹
|
|
||||||
java.awt.Desktop.getDesktop().open(folder);
|
|
||||||
return targeFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于将读取到的列表文件存储至文件中
|
|
||||||
* @param targeFile 目标文件
|
|
||||||
* @param datas 存储了数据的map类对象
|
|
||||||
* @param sheetName 需要写入的Sheet名称
|
|
||||||
* @param dataRow 从哪一行开始写
|
|
||||||
* @param keyCell 标题列
|
|
||||||
* @param valueCell 数据值列
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private static void writeFile(File targeFile, LinkedHashMap<String, Integer> datas, String sheetName, int dataRow,
|
|
||||||
int keyCell, int valueCell) throws IOException {
|
|
||||||
// 定义xlsx操作类对象,若文件存在则续写,文件不存在则新写
|
|
||||||
XSSFWorkbook xlsx = null;
|
|
||||||
XSSFSheet sheet = null;
|
|
||||||
//判断文件是否存在,若文件不存在,则创建xlsx文件,若文件存在,则按照指定的数据读取xlsx
|
|
||||||
if (targeFile.exists()) {
|
|
||||||
xlsx = new XSSFWorkbook(new FileInputStream(targeFile));
|
|
||||||
//判断sheet是否存在,若sheet不存在,则创建sheet
|
|
||||||
if ((sheet = xlsx.getSheet(sheetName)) == null) {
|
|
||||||
sheet = xlsx.createSheet(sheetName);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
xlsx = new XSSFWorkbook();
|
|
||||||
sheet = xlsx.createSheet(sheetName);
|
|
||||||
}
|
|
||||||
//创建标题行
|
|
||||||
XSSFRow xr = sheet.createRow(dataRow++);
|
|
||||||
xr.createCell(keyCell).setCellValue("列表值");
|
|
||||||
xr.createCell(valueCell).setCellValue("出现次数");
|
|
||||||
|
|
||||||
//设置单元格自动换行并垂直居中
|
|
||||||
XSSFCellStyle xcs = xlsx.createCellStyle();
|
|
||||||
xcs.setWrapText(true);
|
|
||||||
xcs.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
||||||
|
|
||||||
//循环,读取map中所有的元素
|
|
||||||
for (String data : datas.keySet()) {
|
|
||||||
//创建一行数据,并将行数向下移
|
|
||||||
xr = sheet.createRow(dataRow++);
|
|
||||||
//创建并存储列表值及出现次数
|
|
||||||
xr.createCell(keyCell).setCellValue(data);
|
|
||||||
xr.getCell(keyCell).setCellStyle(xcs);
|
|
||||||
xr.createCell(valueCell).setCellValue(datas.get(data));
|
|
||||||
xr.getCell(valueCell).setCellStyle(xcs);
|
|
||||||
}
|
|
||||||
|
|
||||||
//添加筛选项
|
|
||||||
sheet.setAutoFilter(CellRangeAddress.valueOf((String.valueOf((char) (65 + keyCell - 1))
|
|
||||||
+ "1:" + String.valueOf((char) (65 + keyCell))
|
|
||||||
+ "1")));
|
|
||||||
|
|
||||||
sheet.setAutoFilter(CellRangeAddress.valueOf((String.valueOf((char) (65 + valueCell - 1))
|
|
||||||
+ "1:" + String.valueOf((char) (65 + valueCell))
|
|
||||||
+ "1")));
|
|
||||||
|
|
||||||
//写入文件
|
|
||||||
xlsx.write(new FileOutputStream(targeFile));
|
|
||||||
//关闭流
|
|
||||||
xlsx.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于读取指定的excel文件,将其转换成map进行返回
|
|
||||||
* @param targeFile 目标文件
|
|
||||||
* @param sheetName 需要读取的Sheet名
|
|
||||||
* @param dataRow 从哪一行开始读取
|
|
||||||
* @param keyCell key所在的列
|
|
||||||
* @param valueCell value所在的列
|
|
||||||
* @return 返回LinkedHashMap对象
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private static LinkedHashMap<String, Integer> readFile(File targeFile, String sheetName, int dataRow, int keyCell,
|
|
||||||
int valueCell) throws IOException {
|
|
||||||
//存储获取到的数据
|
|
||||||
LinkedHashMap<String, Integer> map = new LinkedHashMap<String, Integer>();
|
|
||||||
|
|
||||||
XSSFWorkbook xlsx = new XSSFWorkbook(new FileInputStream(targeFile));
|
|
||||||
//判断sheet是否存在,若sheet不存在,则创建sheet
|
|
||||||
XSSFSheet sheet = xlsx.getSheet(sheetName);
|
|
||||||
if (sheet == null) {
|
|
||||||
xlsx.close();
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
//循环,读取所有的行
|
|
||||||
for (int i = dataRow; i < sheet.getLastRowNum() + 1; i++) {
|
|
||||||
//读取相应的key和value,put入map中
|
|
||||||
String key = "";
|
|
||||||
try {
|
|
||||||
key = sheet.getRow(i).getCell(keyCell).toString();
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
xlsx.close();
|
|
||||||
throw new IncorrectFileException("文件读取错误,指定的行数:" + keyCell + "不存在");
|
|
||||||
}
|
|
||||||
int value = 0;
|
|
||||||
try {
|
|
||||||
String s = sheet.getRow(i).getCell(valueCell).toString();
|
|
||||||
value = Integer.valueOf(s.substring(0, s.indexOf(".")));
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
xlsx.close();
|
|
||||||
throw new IncorrectFileException("统计数据“" + sheet.getRow(i).getCell(valueCell).toString() + "”无法转换成数字");
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
xlsx.close();
|
|
||||||
throw new IncorrectFileException("文件读取错误,指定的行数:" + valueCell + "不存在");
|
|
||||||
}
|
|
||||||
map.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
xlsx.close();
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,213 +0,0 @@
|
||||||
package pres.auxiliary.tool.web;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
||||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p><b>文件名:</b>WebDataToFile.java</p>
|
|
||||||
* <p><b>用途:</b>用于从页面爬取数据以文本的形式存储至本地的工具</p>
|
|
||||||
* <p><b>编码时间:</b>2019年7月19日下午5:04:20</p>
|
|
||||||
* <p><b>修改时间:</b>2019年7月20日下午6:17:20</p>
|
|
||||||
* @author 彭宇琦
|
|
||||||
* @version Ver1.0
|
|
||||||
* @since JDK 1.8
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class WebDataToFile {
|
|
||||||
/**
|
|
||||||
* 定义元素行间的分隔方式
|
|
||||||
*/
|
|
||||||
private static final String LINE = "\n";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法可用于获取页面的数据,并以docx的文件形式进行存储
|
|
||||||
* @param folder 生成的文件存放位置
|
|
||||||
* @param fileName 生成的文件名
|
|
||||||
* @param element 需要获取文本的元素
|
|
||||||
* @param iframes 定位到元素前所需进入的iframe
|
|
||||||
* @return 返回生成的文件对象
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static File webTextDataToFile(File folder, String fileName, String element, String... iframes) throws IOException {
|
|
||||||
//定义浏览器对象,该对象暂时定义为已开启的浏览器对象
|
|
||||||
Event event = Event.newInstance(new ChromeBrower("resource/BrowserDriver/chromedriver.exe", 9222).getDriver());
|
|
||||||
|
|
||||||
//循环,添加所有的框架
|
|
||||||
for (String iframe : iframes) {
|
|
||||||
event.switchFrame(iframe);
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取页面数据
|
|
||||||
String text = event.getTextEvent().getText(element).getStringValve().trim();
|
|
||||||
|
|
||||||
//返回生成的文件的文件对象
|
|
||||||
return writeData(folder, fileName, text, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法可用于获取页面列表上的一页数据,并以xlsx的文件形式进行存储
|
|
||||||
* @param folder 生成的文件存放位置
|
|
||||||
* @param fileName 生成的文件名
|
|
||||||
* @param title 列表的标题
|
|
||||||
* @param element 元素的定位方式
|
|
||||||
* @param iframes 定位到元素前所需进入的iframe
|
|
||||||
* @return 返回生成的文件对象
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public static File webListDataToFile(File folder, String fileName, String title, String element, String... iframes) throws IOException {
|
|
||||||
//定义事件类,用于定位iframe
|
|
||||||
Event event = Event.newInstance(new ChromeBrower("resource/BrowserDriver/chromedriver.exe", 9222).getDriver());
|
|
||||||
|
|
||||||
//循环,添加所有的框架
|
|
||||||
for (String iframe : iframes) {
|
|
||||||
event.switchFrame(iframe);
|
|
||||||
}
|
|
||||||
|
|
||||||
//定义列表元素操作类对象
|
|
||||||
DataListEvent listEvent = new DataListEvent(event.getDriver());
|
|
||||||
//存储从页面上获取到的元素,并存储传入的标题
|
|
||||||
String text = title + LINE;
|
|
||||||
|
|
||||||
//获取页面列表数据
|
|
||||||
listEvent.add(element);
|
|
||||||
//循环,将获取到的文本存储至text中
|
|
||||||
for(ListEvent e : listEvent.getEvents(element)) {
|
|
||||||
text += (e.getText().getStringValve() + LINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
//返回生成的文件的文件对象
|
|
||||||
return writeData(folder, fileName, text, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 该方法用于将数据写入相应的文件中
|
|
||||||
* @param targeFile 目标文件对象
|
|
||||||
* @param text 需要写入文件的文本
|
|
||||||
* @param list 定义写入数据的方式是否为列表
|
|
||||||
* @return 生成的文件对象
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private static File writeData(File folder, String fileName, String text, boolean list) throws IOException {
|
|
||||||
//创建文件夹
|
|
||||||
folder.mkdirs();
|
|
||||||
File targeFile = null;
|
|
||||||
|
|
||||||
//判断写入数据的方式是否为列表,为列表,则按照excel形式存储,为文本则按照docx形式存储
|
|
||||||
if (list) {
|
|
||||||
//定义需要存储的目标文件
|
|
||||||
targeFile = new File(folder + "\\" + fileName + ".xlsx");
|
|
||||||
//打开文件夹
|
|
||||||
java.awt.Desktop.getDesktop().open(folder);
|
|
||||||
return writeXlsx(targeFile, text);
|
|
||||||
} else {
|
|
||||||
//定义需要存储的目标文件
|
|
||||||
targeFile = new File(folder + "\\" + fileName + ".docx");
|
|
||||||
//打开文件夹
|
|
||||||
java.awt.Desktop.getDesktop().open(folder);
|
|
||||||
return writeDocx(targeFile, text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于对docx文本的写入
|
|
||||||
* @param targeFile 目标文件
|
|
||||||
* @param text 文本
|
|
||||||
* @return 生成的文件对象
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private static File writeDocx(File targeFile, String text) throws IOException {
|
|
||||||
//定义docx操作类对象,若文件存在则续写,文件不存在则新写
|
|
||||||
XWPFDocument docx = null;
|
|
||||||
if (targeFile.exists()) {
|
|
||||||
docx = new XWPFDocument(new FileInputStream(targeFile));
|
|
||||||
} else {
|
|
||||||
docx = new XWPFDocument();
|
|
||||||
}
|
|
||||||
|
|
||||||
//创建新的段落,并写入text中的内容
|
|
||||||
docx.createParagraph().createRun().setText(text);
|
|
||||||
docx.write(new FileOutputStream(targeFile));
|
|
||||||
docx.close();
|
|
||||||
|
|
||||||
return targeFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于对xlsx文本的写入
|
|
||||||
* @param targeFile 目标文件
|
|
||||||
* @param text 文本
|
|
||||||
* @return 生成的文件
|
|
||||||
*/
|
|
||||||
private static File writeXlsx(File targeFile, String text) throws IOException {
|
|
||||||
//切割内容,便于后续的存储
|
|
||||||
String[] texts = text.split("\\n");
|
|
||||||
|
|
||||||
//定义xlsx操作类对象,若文件存在则续写,文件不存在则新写
|
|
||||||
XSSFWorkbook xlsx = null;
|
|
||||||
XSSFSheet sheet = null;
|
|
||||||
//定义需要写入文件中的行和列,用于指向文本内容在文件中的某列的某行写入
|
|
||||||
int row = 0;
|
|
||||||
int cell = 0;
|
|
||||||
//定义循环时需要从texts的哪一个元素开始循环读取
|
|
||||||
int i = 0;
|
|
||||||
if (targeFile.exists()) {
|
|
||||||
xlsx = new XSSFWorkbook(new FileInputStream(targeFile));
|
|
||||||
sheet = xlsx.getSheetAt(0);
|
|
||||||
|
|
||||||
//获取文件的标题,用于判断该标题是否存在于文件中
|
|
||||||
String title = texts[0].trim();
|
|
||||||
//循环,读取文件中标题行的所有列,以对比标题是否存在
|
|
||||||
for (; cell < sheet.getRow(0).getLastCellNum(); cell++) {
|
|
||||||
//对比标题是否存在,若存在,则结束循环,则可以得到cell的值
|
|
||||||
if (sheet.getRow(0).getCell(cell).toString().equals(title)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断当前需要写入的列是否为最后一列,若为不为最后一列,则不需要记录标题列,其i值设为1,表示从texts的第二个元素读取
|
|
||||||
//并记录从哪一行开始写入数据
|
|
||||||
if (cell != sheet.getRow(0).getLastCellNum()) {
|
|
||||||
i = 1;
|
|
||||||
//循环,判断当前的应从当前列的哪一行开始写入数据
|
|
||||||
//需要注意的是,此处去sheet中的最大行数作为循环结束的标志,这是因为文本中最长的列为sheet.getLastRowNum(),若该列的数据
|
|
||||||
//相较sheet.getLastRowNum()短时则直接结束循环,其结束的row + 1便是可写入数据的行
|
|
||||||
for (; row < sheet.getLastRowNum(); row++) {
|
|
||||||
if (sheet.getRow(row).getCell(cell) == null) {
|
|
||||||
row--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println(row);
|
|
||||||
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//由于文件不存在,则不需要计算任何的循环值(row、cell、i都为0)
|
|
||||||
xlsx = new XSSFWorkbook();
|
|
||||||
sheet = xlsx.createSheet();
|
|
||||||
}
|
|
||||||
|
|
||||||
//写入数据
|
|
||||||
for (; i < texts.length; i++, row++) {
|
|
||||||
XSSFRow xr = null;
|
|
||||||
//判断当前行是否存在,存在则不创新创建,以免清空之前的数据
|
|
||||||
if ((xr = sheet.getRow(row)) == null) {
|
|
||||||
xr = sheet.createRow(row);
|
|
||||||
}
|
|
||||||
xr.createCell(cell).setCellValue(texts[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
xlsx.write(new FileOutputStream(targeFile));
|
|
||||||
xlsx.close();
|
|
||||||
|
|
||||||
return targeFile;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,12 +21,19 @@ import pres.auxiliary.work.selenium.event.TextEvent;
|
||||||
import pres.auxiliary.work.selenium.event.WaitEvent;
|
import pres.auxiliary.work.selenium.event.WaitEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>OperateDataTable.java</p>
|
* <p>
|
||||||
* <p><b>用途:</b>
|
* <b>文件名:</b>OperateDataTable.java
|
||||||
* 提供对数据表格进行基本操作的事件,包括对数据列表的翻页、跳页、获取等操作,以简化部分操作的代码
|
|
||||||
* </p>
|
* </p>
|
||||||
* <p><b>编码时间:</b>2020年11月17日上午7:58:40</p>
|
* <p>
|
||||||
* <p><b>修改时间:</b>2020年11月17日上午7:58:40</p>
|
* <b>用途:</b> 提供对数据表格进行基本操作的事件,包括对数据列表的翻页、跳页、获取等操作,以简化部分操作的代码
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>编码时间:</b>2020年11月17日上午7:58:40
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>修改时间:</b>2020年11月17日上午7:58:40
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
* @author 彭宇琦
|
* @author 彭宇琦
|
||||||
* @version Ver1.0
|
* @version Ver1.0
|
||||||
* @since JDK 1.8
|
* @since JDK 1.8
|
||||||
|
@ -49,7 +56,7 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
* 用于进行等待事件
|
* 用于进行等待事件
|
||||||
*/
|
*/
|
||||||
private WaitEvent waitEvent;
|
private WaitEvent waitEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于存储当前的列表的一列元素
|
* 用于存储当前的列表的一列元素
|
||||||
*/
|
*/
|
||||||
|
@ -63,17 +70,17 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
* 指向列表加载等待控件
|
* 指向列表加载等待控件
|
||||||
*/
|
*/
|
||||||
private Element waitElement;
|
private Element waitElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于存储当前列表的长度
|
* 用于存储当前列表的长度
|
||||||
*/
|
*/
|
||||||
protected int listSize = -1;
|
protected int listSize = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标记是否进行元素个数长度校验
|
* 标记是否进行元素个数长度校验
|
||||||
*/
|
*/
|
||||||
protected boolean isExamine = true;
|
protected boolean isExamine = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造对象
|
* 构造对象
|
||||||
*
|
*
|
||||||
|
@ -81,24 +88,26 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
*/
|
*/
|
||||||
public DataTableEvent(AbstractBrower brower) {
|
public DataTableEvent(AbstractBrower brower) {
|
||||||
super(brower);
|
super(brower);
|
||||||
|
|
||||||
clickEvent = new ClickEvent(brower);
|
clickEvent = new ClickEvent(brower);
|
||||||
textEvent = new TextEvent(brower);
|
textEvent = new TextEvent(brower);
|
||||||
assertEvent = new AssertEvent(brower);
|
assertEvent = new AssertEvent(brower);
|
||||||
waitEvent = new WaitEvent(brower);
|
waitEvent = new WaitEvent(brower);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于设置是否对传入的元素列表的个数进行严格校验,即在调用{@link #add(DataListBy)}方法时,
|
* 用于设置是否对传入的元素列表的个数进行严格校验,即在调用{@link #add(DataListBy)}方法时,
|
||||||
* 若元素个数与初次传入的个数不符且需要严格校验,则抛出异常;反之,则直接进行存储
|
* 若元素个数与初次传入的个数不符且需要严格校验,则抛出异常;反之,则直接进行存储
|
||||||
|
*
|
||||||
* @param isExamine 是否严格校验元素个数
|
* @param isExamine 是否严格校验元素个数
|
||||||
*/
|
*/
|
||||||
public void setExamine(boolean isExamine) {
|
public void setExamine(boolean isExamine) {
|
||||||
this.isExamine = isExamine;
|
this.isExamine = isExamine;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于设置列表加载等待元素,通过该元素,将应用与列表操作后,等待该控件消失后再进行断言的操作
|
* 用于设置列表加载等待元素,通过该元素,将应用与列表操作后,等待该控件消失后再进行断言的操作
|
||||||
|
*
|
||||||
* @param waitElement 列表加载等待控件
|
* @param waitElement 列表加载等待控件
|
||||||
*/
|
*/
|
||||||
public void setWaitElement(Element waitElement) {
|
public void setWaitElement(Element waitElement) {
|
||||||
|
@ -108,64 +117,70 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
/**
|
/**
|
||||||
* 用于添加一列元素,若启用严格校验(即通过{@link #setExamine(boolean)}方法设置为true),
|
* 用于添加一列元素,若启用严格校验(即通过{@link #setExamine(boolean)}方法设置为true),
|
||||||
* 则调用该方法时将对存储的数据个数进行校验,若传入的列元素个数与当前存储的列表元素个数
|
* 则调用该方法时将对存储的数据个数进行校验,若传入的列元素个数与当前存储的列表元素个数
|
||||||
* 不一致时,则抛出{@link InvalidDataListException}异常
|
* 不一致时,则抛出{@link InvalidDataListException}异常。
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* <b>注意:</b>传入的{@link DataListBy}类对象中元素的名称请勿与其他元素名称一致,否则会
|
* <b>注意:</b>传入的{@link DataListBy}类对象中元素的名称请勿与其他元素名称一致,否则会覆盖原有的元素列。
|
||||||
* 覆盖原有的元素列
|
* 其元素名称将作为列表名称,可通过该名称获取当前列
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param dataListBy 元素列查找对象
|
* @param dataListBy 元素列查找对象
|
||||||
* @throws InvalidDataListException 启用严格校验且元素个数与存储列表元素个数不一致时抛出的异常
|
* @throws InvalidDataListException 启用严格校验且元素个数与存储列表元素个数不一致时抛出的异常
|
||||||
*/
|
*/
|
||||||
public void addList(DataListBy dataListBy) {
|
public void addList(DataListBy dataListBy) {
|
||||||
//判断当前是否存储元素,若未存储元素,则不进行元素个数判断
|
// 判断当前是否存储元素,若未存储元素,则不进行元素个数判断
|
||||||
if (!tableMap.isEmpty()) {
|
if (!tableMap.isEmpty()) {
|
||||||
//判断传入的列的元素个数是否与当前存储的元素个数一致,若不一致,则进行个数判定校验
|
// 判断传入的列的元素个数是否与当前存储的元素个数一致,若不一致,则进行个数判定校验
|
||||||
int nowSize = dataListBy.size();
|
int nowSize = dataListBy.size();
|
||||||
if (nowSize != listSize()) {
|
if (nowSize != listSize()) {
|
||||||
//若当前需要严格校验列表元素个数,则抛出异常
|
// 若当前需要严格校验列表元素个数,则抛出异常
|
||||||
if (isExamine) {
|
if (isExamine) {
|
||||||
throw new InvalidDataListException("当前传入的元素列个数与存储的元素列个数不一致!"
|
throw new InvalidDataListException(
|
||||||
+ "(当前元素列个数:" + listSize() + ",传入的元素列元素个数:" + nowSize + ")");
|
"当前传入的元素列个数与存储的元素列个数不一致!" + "(当前元素列个数:" + listSize() + ",传入的元素列元素个数:" + nowSize + ")");
|
||||||
} else {
|
} else {
|
||||||
//若无需校验元素个数,则判断传入的元素个数与存储的元素列个数,存储较小的数字
|
// 若无需校验元素个数,则判断传入的元素个数与存储的元素列个数,存储较小的数字
|
||||||
listSize = listSize < nowSize ? listSize : nowSize;
|
listSize = listSize < nowSize ? listSize : nowSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
listSize = dataListBy.size();
|
listSize = dataListBy.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
tableMap.put(dataListBy.getElementData().getName(), dataListBy.getAllElement());
|
tableMap.put(dataListBy.getElementData().getName(), dataListBy.getAllElement());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于添加列表控件的枚举,在调用部分列表操作方法时会使用在此处添加的映射
|
* 用于添加列表控件的枚举,在调用部分列表操作方法时会使用在此处添加的映射
|
||||||
|
*
|
||||||
* @param dataTableKeywordType 列表可映射的控件枚举{@link DataTableKeywordType}
|
* @param dataTableKeywordType 列表可映射的控件枚举{@link DataTableKeywordType}
|
||||||
* @param by 控件相应的元素对象{@link Element}
|
* @param by 控件相应的元素对象{@link Element}
|
||||||
*/
|
*/
|
||||||
public void putControl(DataTableKeywordType dataTableKeywordType, Element elemenet) {
|
public void putControl(DataTableKeywordType dataTableKeywordType, Element elemenet) {
|
||||||
controlMap.put(dataTableKeywordType, elemenet);
|
controlMap.put(dataTableKeywordType, elemenet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回元素列中元素的个数,若设置了严格判断,则该数值为所有列的元素个数;反之,则该
|
* 返回元素列中元素的个数,若设置了严格判断,则该数值为所有列的元素个数;反之,则该 数值表示列表集合中,最短元素列的元素个数
|
||||||
* 数值表示列表集合中,最短元素列的元素个数
|
|
||||||
*
|
*
|
||||||
* @return 元素列的元素个数
|
* @return 元素列的元素个数
|
||||||
*/
|
*/
|
||||||
public int listSize() {
|
public int listSize() {
|
||||||
return listSize;
|
return listSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取列表名称指向列的元素个数
|
||||||
|
* @param name 列表名称
|
||||||
|
* @return 指向的列表元素个数
|
||||||
|
*/
|
||||||
public int listSize(String name) {
|
public int listSize(String name) {
|
||||||
return tableMap.get(name).size();
|
return tableMap.get(name).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于返回元素表中的列数
|
* 用于返回元素表中的列数
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int rowSize() {
|
public int rowSize() {
|
||||||
|
@ -173,57 +188,58 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于点击多次上一页按钮,并返回实际点击次数(实际点击次数)。若设置的翻页次数小于0
|
* 用于点击多次上一页按钮,并返回实际点击次数(实际点击次数)。若设置的翻页次数小于0 ,则持续翻页至无法翻页为止
|
||||||
* ,则持续翻页至无法翻页为止
|
*
|
||||||
* @param count 点击次数
|
* @param count 点击次数
|
||||||
* @return 实际点击次数
|
* @return 实际点击次数
|
||||||
*/
|
*/
|
||||||
public int previousPage(int count) {
|
public int previousPage(int count) {
|
||||||
return pageTurning(DataTableKeywordType.PREVIOUS_PAGE_BUTTON, count);
|
return pageTurning(DataTableKeywordType.PREVIOUS_PAGE_BUTTON, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于点击多次下一页按钮,并返回实际点击次数(实际点击次数)。若设置的翻页次数小于0
|
* 用于点击多次下一页按钮,并返回实际点击次数(实际点击次数)。若设置的翻页次数小于0 ,则持续翻页至无法翻页为止
|
||||||
* ,则持续翻页至无法翻页为止
|
*
|
||||||
* @param count 点击次数
|
* @param count 点击次数
|
||||||
* @return 实际点击次数
|
* @return 实际点击次数
|
||||||
*/
|
*/
|
||||||
public int nextPage(int count) {
|
public int nextPage(int count) {
|
||||||
return pageTurning(DataTableKeywordType.NEXT_PAGE_BUTTON, count);
|
return pageTurning(DataTableKeywordType.NEXT_PAGE_BUTTON, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于对列表进行翻页操作
|
* 用于对列表进行翻页操作
|
||||||
|
*
|
||||||
* @param dataTableKeywordType 翻页按钮类型
|
* @param dataTableKeywordType 翻页按钮类型
|
||||||
* @param count 指定的翻页次数
|
* @param count 指定的翻页次数
|
||||||
* @return 实际翻页次数
|
* @return 实际翻页次数
|
||||||
*/
|
*/
|
||||||
private int pageTurning(DataTableKeywordType dataTableKeywordType, int count) {
|
private int pageTurning(DataTableKeywordType dataTableKeywordType, int count) {
|
||||||
//判断当前按钮是否存在映射
|
// 判断当前按钮是否存在映射
|
||||||
if (!controlMap.containsKey(dataTableKeywordType)) {
|
if (!controlMap.containsKey(dataTableKeywordType)) {
|
||||||
throw new ControlException(dataTableKeywordType.getName(), dataTableKeywordType.toString());
|
throw new ControlException(dataTableKeywordType.getName(), dataTableKeywordType.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
//根据设置的点击次数循环点击翻页按钮
|
// 根据设置的点击次数循环点击翻页按钮
|
||||||
int nowCount = 0;
|
int nowCount = 0;
|
||||||
while(true) {
|
while (true) {
|
||||||
//判断翻页数,若当前翻页数大于指定翻页数时,则结束循环
|
// 判断翻页数,若当前翻页数大于指定翻页数时,则结束循环
|
||||||
//若指定的翻页数小于0,则持续翻页,直到翻页失败为止
|
// 若指定的翻页数小于0,则持续翻页,直到翻页失败为止
|
||||||
if (nowCount >= count && count >= 0) {
|
if (nowCount >= count && count >= 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element controlElement = controlMap.get(dataTableKeywordType);
|
Element controlElement = controlMap.get(dataTableKeywordType);
|
||||||
|
|
||||||
boolean result = assertData(() -> {
|
boolean result = assertData(() -> {
|
||||||
//判断按钮是否可以点击
|
// 判断按钮是否可以点击
|
||||||
if (!controlElement.getWebElement().isEnabled()) {
|
if (!controlElement.getWebElement().isEnabled()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
clickEvent.click(controlElement);
|
clickEvent.click(controlElement);
|
||||||
//等待控件消失
|
// 等待控件消失
|
||||||
if (waitElement != null) {
|
if (waitElement != null) {
|
||||||
waitEvent.disappear(waitElement);
|
waitEvent.disappear(waitElement);
|
||||||
}
|
}
|
||||||
|
@ -232,120 +248,117 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//若点击成功,则nowCount自增,若点击失败,则退出循环
|
// 若点击成功,则nowCount自增,若点击失败,则退出循环
|
||||||
if (!result) {
|
if (!result) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nowCount++;
|
nowCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
logText = "点击“"
|
logText = "点击“" + controlMap.get(DataTableKeywordType.PREVIOUS_PAGE_BUTTON).getElementData().getName()
|
||||||
+ controlMap.get(DataTableKeywordType.PREVIOUS_PAGE_BUTTON).getElementData().getName()
|
+ "”元素,使列表返回至" + (dataTableKeywordType == DataTableKeywordType.PREVIOUS_PAGE_BUTTON ? "上" : "下")
|
||||||
+ "”元素,使列表返回至"
|
|
||||||
+ (dataTableKeywordType == DataTableKeywordType.PREVIOUS_PAGE_BUTTON ? "上" : "下")
|
|
||||||
+ "页,其实际翻页数为:" + nowCount;
|
+ "页,其实际翻页数为:" + nowCount;
|
||||||
resultText = String.valueOf(nowCount);
|
resultText = String.valueOf(nowCount);
|
||||||
|
|
||||||
//返回实际点击次数
|
// 返回实际点击次数
|
||||||
return nowCount;
|
return nowCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于对列表进行点击跳页按钮后的跳页操作。若当前存储过元素列表,则对元素列表进行断言,
|
* 用于对列表进行点击跳页按钮后的跳页操作。若当前存储过元素列表,则对元素列表进行断言,
|
||||||
* 即取存储的列表的第一行元素,若操作前后,该行元素不变,则判定为跳页失败
|
* 即取存储的列表的第一行元素,若操作前后,该行元素不变,则判定为跳页失败
|
||||||
*
|
*
|
||||||
* @param pageTextbox 跳页文本框元素
|
* @param pageTextbox 跳页文本框元素
|
||||||
* @param jumpPageButton 跳页按钮
|
* @param jumpPageButton 跳页按钮
|
||||||
* @param pageCountText 页码文本
|
* @param pageCountText 页码文本
|
||||||
*/
|
*/
|
||||||
public boolean jumpPage(String pageCount) {
|
public boolean jumpPage(String pageCount) {
|
||||||
if (!controlMap.containsKey(DataTableKeywordType.PAGE_INPUT_TEXTBOX)) {
|
if (!controlMap.containsKey(DataTableKeywordType.PAGE_INPUT_TEXTBOX)) {
|
||||||
throw new ControlException(DataTableKeywordType.PAGE_INPUT_TEXTBOX.getName()
|
throw new ControlException(DataTableKeywordType.PAGE_INPUT_TEXTBOX.getName(),
|
||||||
, DataTableKeywordType.PAGE_INPUT_TEXTBOX.toString());
|
DataTableKeywordType.PAGE_INPUT_TEXTBOX.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean result = assertData(() -> {
|
boolean result = assertData(() -> {
|
||||||
//输入页码
|
// 输入页码
|
||||||
textEvent.input(controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX), pageCount);
|
textEvent.input(controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX), pageCount);
|
||||||
//判断是否存在跳页按钮的映射,若不存在,则使用回车进行跳页
|
// 判断是否存在跳页按钮的映射,若不存在,则使用回车进行跳页
|
||||||
if (controlMap.containsKey(DataTableKeywordType.JUMP_PAGE_BUTTON)) {
|
if (controlMap.containsKey(DataTableKeywordType.JUMP_PAGE_BUTTON)) {
|
||||||
//点击跳页
|
// 点击跳页
|
||||||
clickEvent.click(controlMap.get(DataTableKeywordType.JUMP_PAGE_BUTTON));
|
clickEvent.click(controlMap.get(DataTableKeywordType.JUMP_PAGE_BUTTON));
|
||||||
} else {
|
} else {
|
||||||
textEvent.keyToSend(controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX), Keys.ENTER);
|
textEvent.keyToSend(controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX), Keys.ENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
//清空输入框
|
// 清空输入框
|
||||||
textEvent.clear(controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX));
|
textEvent.clear(controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX));
|
||||||
|
|
||||||
//等待控件消失
|
// 等待控件消失
|
||||||
if (waitElement != null) {
|
if (waitElement != null) {
|
||||||
waitEvent.disappear(waitElement);
|
waitEvent.disappear(waitElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
logText = "在“"
|
logText = "在“" + controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX).getElementData().getName() + "”元素中输入"
|
||||||
+ controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX).getElementData().getName()
|
+ pageCount + ",使列表跳转到相应的页码,其翻页" + (result ? "" : "不") + "成功";
|
||||||
+ "”元素中输入" + pageCount
|
|
||||||
+ ",使列表跳转到相应的页码,其翻页"
|
|
||||||
+ (result ? "" : "不") + "成功";
|
|
||||||
resultText = String.valueOf(result);
|
resultText = String.valueOf(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过条件,点击{@link DataTableKeywordType#SEARCH_BUTTON}映射的按钮,对列表进行搜索。方法中需要接收一个
|
* 通过条件,点击{@link DataTableKeywordType#SEARCH_BUTTON}映射的按钮,对列表进行搜索。方法中需要接收一个
|
||||||
* 返回值为boolean类型的操作,若操作的返回值为false时,则不会点击按钮,可参考以下写法:
|
* 返回值为boolean类型的操作,若操作的返回值为false时,则不会点击按钮,可参考以下写法:
|
||||||
* <pre><code>
|
*
|
||||||
|
* <pre>
|
||||||
|
* <code>
|
||||||
* DataTableEvent test = new DataTableEvent(brower);
|
* DataTableEvent test = new DataTableEvent(brower);
|
||||||
* test.searchList(() -> {
|
* test.searchList(() -> {
|
||||||
* te.input(cb.getElement("账号搜索文本框"), "13000000000");
|
* te.input(cb.getElement("账号搜索文本框"), "13000000000");
|
||||||
* return true;
|
* return true;
|
||||||
* });
|
* });
|
||||||
* </code></pre>
|
* </code>
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param action 返回值为boolean类型的操作
|
* @param action 返回值为boolean类型的操作
|
||||||
* @return 列表是否有变化
|
* @return 列表是否有变化
|
||||||
*/
|
*/
|
||||||
public boolean searchList(BooleanSupplier action) {
|
public boolean searchList(BooleanSupplier action) {
|
||||||
//判断控件是否存在
|
// 判断控件是否存在
|
||||||
if (!controlMap.containsKey(DataTableKeywordType.SEARCH_BUTTON)) {
|
if (!controlMap.containsKey(DataTableKeywordType.SEARCH_BUTTON)) {
|
||||||
throw new ControlException(DataTableKeywordType.SEARCH_BUTTON.getName()
|
throw new ControlException(DataTableKeywordType.SEARCH_BUTTON.getName(),
|
||||||
, DataTableKeywordType.SEARCH_BUTTON.toString());
|
DataTableKeywordType.SEARCH_BUTTON.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean result = false;
|
boolean result = assertData(() -> {
|
||||||
//若操作成功,则点击搜索按钮
|
// 若操作成功,则点击搜索按钮
|
||||||
if (action.getAsBoolean()) {
|
if (action.getAsBoolean()) {
|
||||||
clickEvent.click(controlMap.get(DataTableKeywordType.SEARCH_BUTTON));
|
clickEvent.click(controlMap.get(DataTableKeywordType.SEARCH_BUTTON));
|
||||||
|
|
||||||
//等待控件消失
|
// 等待控件消失
|
||||||
if (waitElement != null) {
|
if (waitElement != null) {
|
||||||
waitEvent.disappear(waitElement);
|
waitEvent.disappear(waitElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
//TODO 走列表文本断言
|
|
||||||
result = true;
|
|
||||||
} else {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
logText = "通过搜索条件,点击“" + controlMap.get(DataTableKeywordType.SEARCH_BUTTON).getElementData().getName()
|
logText = "通过搜索条件,点击“" + controlMap.get(DataTableKeywordType.SEARCH_BUTTON).getElementData().getName()
|
||||||
+ "”元素,对列表进行搜索";
|
+ "”元素,对列表进行搜索";
|
||||||
resultText = String.valueOf(result);
|
resultText = String.valueOf(result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 获取指定的一行元素,下标允许传入负数,表示从后向前遍历,具体遍历逻辑
|
* 获取指定的一行元素,下标允许传入负数,表示从后向前遍历,具体遍历逻辑可参考{@link DataListBy#getElement(int)}方法。
|
||||||
* 可参考{@link DataListBy#getElement(int)}方法。
|
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* <b>注意:</b>下标将按照元素列长度进行计算,若下标的绝对值大于元素列长度,且下标为正数,则
|
* <b>注意:</b>下标将按照元素列长度进行计算,若下标的绝对值大于元素列长度,且下标为正数,则
|
||||||
|
@ -356,19 +369,68 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
* @return 指定行的元素集合
|
* @return 指定行的元素集合
|
||||||
*/
|
*/
|
||||||
public ArrayList<Element> getRowElement(int rowIndex) {
|
public ArrayList<Element> getRowElement(int rowIndex) {
|
||||||
//根据下标,获取元素,并进行存储
|
// 根据下标,获取元素,并进行存储
|
||||||
ArrayList<Element> elementList = new ArrayList<>();
|
ArrayList<Element> elementList = new ArrayList<>();
|
||||||
tableMap.forEach((key, value) -> {
|
tableMap.forEach((key, value) -> {
|
||||||
//存储元素
|
// 存储元素
|
||||||
elementList.add(value.get(toElementIndex(listSize(key), rowIndex)));
|
elementList.add(value.get(toElementIndex(listSize(key), rowIndex)));
|
||||||
});
|
});
|
||||||
|
|
||||||
return elementList;
|
return elementList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定行的文本,其行号可传入负数,具体规则可参考{@link DataListBy#getElement(int)}方法
|
||||||
|
* @param rowIndex 指定的行号
|
||||||
|
* @return 该行元素的文本
|
||||||
|
*/
|
||||||
|
public ArrayList<String> getRowText(int rowIndex) {
|
||||||
|
//重新获取列表元素
|
||||||
|
againFindDataList();
|
||||||
|
|
||||||
|
ArrayList<String> rowTextList = new ArrayList<>();
|
||||||
|
// 遍历元素,将其转换为文本后进行存储
|
||||||
|
getRowElement(rowIndex).stream().map(textEvent::getText).forEach(rowTextList :: add);
|
||||||
|
|
||||||
|
//添加日志
|
||||||
|
resultText = rowTextList.toString();
|
||||||
|
logText = "获取列表第" + rowIndex + "行元素内容的文本,其获取到的文本内容为:" + resultText;
|
||||||
|
|
||||||
|
return rowTextList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 由于方法允许传入负数和特殊数字0为下标,并且下标的序号由1开始,
|
* 获取指定列的文本,若该列元素异常时,则抛出异常
|
||||||
* 故可通过该方法对下标的含义进行转义,得到java能识别的下标
|
* @param listName 列表名称
|
||||||
|
* @return 指定列的文本内容
|
||||||
|
* @throws ControlException 该列不存在或该列元素为空时抛出的异常
|
||||||
|
*/
|
||||||
|
public ArrayList<String> getListText(String listName) {
|
||||||
|
//重新获取列表元素
|
||||||
|
againFindDataList();
|
||||||
|
|
||||||
|
//判断列元素是否存在,若不存在,则抛出异常
|
||||||
|
if (!tableMap.containsKey(listName)) {
|
||||||
|
throw new ControlException("“" + listName + "”指向的列元素不存在");
|
||||||
|
}
|
||||||
|
//判断当前列是否包含元素
|
||||||
|
if (listSize(listName) == 0) {
|
||||||
|
throw new ControlException("“" + listName + "”指向的列无元素");
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<String> listTextList = new ArrayList<>();
|
||||||
|
// 遍历元素,将其转换为文本后进行存储
|
||||||
|
tableMap.get(listName).stream().map(textEvent::getText).forEach(listTextList :: add);
|
||||||
|
|
||||||
|
//添加日志
|
||||||
|
resultText = listTextList.toString();
|
||||||
|
logText = "获取列表的" + listName + "列元素内容的文本,其获取到的文本内容为:" + resultText;
|
||||||
|
|
||||||
|
return listTextList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 由于方法允许传入负数和特殊数字0为下标,并且下标的序号由1开始, 故可通过该方法对下标的含义进行转义,得到java能识别的下标
|
||||||
*
|
*
|
||||||
* @param length 元素的个数
|
* @param length 元素的个数
|
||||||
* @param index 传入的下标
|
* @param index 传入的下标
|
||||||
|
@ -395,28 +457,28 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
return new Random().nextInt(length);
|
return new Random().nextInt(length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于执行需要断言页面元素的列表操作,在其操作方法前后添加了断言操作
|
* 用于执行需要断言页面元素的列表操作,在其操作方法前后添加了断言操作
|
||||||
|
*
|
||||||
* @param action 需要执行的内容
|
* @param action 需要执行的内容
|
||||||
* @return 是否翻页成功
|
* @return 是否翻页成功
|
||||||
*/
|
*/
|
||||||
protected boolean assertData(BooleanSupplier action) {
|
protected boolean assertData(BooleanSupplier action) {
|
||||||
//若元素列表非空,则获取第一行元素,用于进行断言
|
// 若元素列表非空,则获取第一行元素,用于进行断言
|
||||||
ArrayList<String> oldTextList = new ArrayList<>();
|
ArrayList<String> oldTextList = new ArrayList<>();
|
||||||
if (!tableMap.isEmpty()) {
|
if (!tableMap.isEmpty()) {
|
||||||
//获取第一行元素,并将其转换为文本后存储
|
// 获取第一行元素,并将其转换为文本后存储
|
||||||
getRowElement(1).stream().map(textEvent :: getText).forEach(oldTextList :: add);
|
getRowElement(1).stream().map(textEvent::getText).forEach(oldTextList::add);
|
||||||
}
|
}
|
||||||
//获取当前集合的长度
|
// 获取当前集合的长度
|
||||||
int oldListSize = listSize();
|
int oldListSize = listSize();
|
||||||
|
|
||||||
|
// 执行操作,并获取操作的返回结果;若返回值为true,则需要进行元素断言操作
|
||||||
//执行操作,并获取操作的返回结果;若返回值为true,则需要进行元素断言操作
|
|
||||||
if (action.getAsBoolean()) {
|
if (action.getAsBoolean()) {
|
||||||
//若当前未获取原元素的内容,则不进行列表断言
|
// 若当前未获取原元素的内容,则不进行列表断言
|
||||||
if (oldTextList.size() != 0) {
|
if (oldTextList.size() != 0) {
|
||||||
//断言元素,并返回结果
|
// 断言元素,并返回结果
|
||||||
return assertDataChange(oldTextList, oldListSize);
|
return assertDataChange(oldTextList, oldListSize);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
|
@ -425,87 +487,94 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 断言数据是否有改变,若数据改变,则返回true;反之,返回false
|
* 断言数据是否有改变,若数据改变,则返回true;反之,返回false
|
||||||
|
*
|
||||||
* @param oldTextList 原始数据文本集合
|
* @param oldTextList 原始数据文本集合
|
||||||
* @param oldElement 原始数据第一个元素的{@link WebElement}对象
|
* @param oldElement 原始数据第一个元素的{@link WebElement}对象
|
||||||
* @return 元素是否存在改变
|
* @return 元素是否存在改变
|
||||||
*/
|
*/
|
||||||
protected boolean assertDataChange(ArrayList<String> oldTextList, int oldListSize) {
|
protected boolean assertDataChange(ArrayList<String> oldTextList, int oldListSize) {
|
||||||
//重新获取集合元素
|
// 重新获取集合元素
|
||||||
againFindDataList();
|
againFindDataList();
|
||||||
|
|
||||||
//获取操作后的第一行元素
|
// 获取操作后的第一行元素
|
||||||
ArrayList<Element> newElementList = getRowElement(1);
|
ArrayList<Element> newElementList = getRowElement(1);
|
||||||
|
|
||||||
//若集合的长度发生改变,则表示集合存在变化
|
// 若集合的长度发生改变,则表示集合存在变化
|
||||||
if (oldListSize != listSize) {
|
if (oldListSize != listSize) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//为避免不进行翻页时,列表也会进行一次刷新,则获取信息,对每个文本数据进行比对
|
// 为避免不进行翻页时,列表也会进行一次刷新,则获取信息,对每个文本数据进行比对
|
||||||
for (int index = 0; index < oldTextList.size(); index++) {
|
for (int index = 0; index < oldTextList.size(); index++) {
|
||||||
if (assertEvent.assertNotEqualsText(newElementList.get(index), oldTextList.get(index))) {
|
if (assertEvent.assertNotEqualsText(newElementList.get(index), oldTextList.get(index))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于重新获取元素信息
|
* 用于重新获取元素信息
|
||||||
*/
|
*/
|
||||||
private void againFindDataList() {
|
private void againFindDataList() {
|
||||||
//用于判断当前数列元素的个数
|
// 用于判断当前数列元素的个数
|
||||||
AtomicInteger nowListSize = new AtomicInteger(-1);
|
AtomicInteger nowListSize = new AtomicInteger(-1);
|
||||||
tableMap.forEach((key, value) -> {
|
tableMap.forEach((key, value) -> {
|
||||||
//获取原集合个数
|
// 获取原集合个数
|
||||||
int oldSize = value.size();
|
int oldSize = value.size();
|
||||||
|
|
||||||
//对列表第一个元素进行重新获取
|
// 对列表第一个元素进行重新获取
|
||||||
Element element = value.get(0);
|
Element element = value.get(0);
|
||||||
//重新获取当前元素,并存储当前列表长度
|
// 重新获取当前元素,并存储当前列表长度
|
||||||
int elementListSize = element.againFindElement();
|
int elementListSize = element.againFindElement();
|
||||||
|
|
||||||
//判断当前size是否为初始化的状态,若为初始化的状态,则直接存储重新获取后的集合元素个数
|
// 判断当前size是否为初始化的状态,若为初始化的状态,则直接存储重新获取后的集合元素个数
|
||||||
if (nowListSize.get() == -1) {
|
if (nowListSize.get() == -1) {
|
||||||
nowListSize.set(elementListSize);
|
nowListSize.set(elementListSize);
|
||||||
} else {
|
} else {
|
||||||
//若当前size已被初始化,则进行重获后的元素个数判断
|
// 若当前size已被初始化,则进行重获后的元素个数判断
|
||||||
if (nowListSize.get() != elementListSize) {
|
if (nowListSize.get() != elementListSize) {
|
||||||
//若当前需要严格校验列表元素个数,则抛出异常
|
// 若当前需要严格校验列表元素个数,则抛出异常
|
||||||
if (isExamine) {
|
if (isExamine) {
|
||||||
throw new InvalidDataListException("“" + key + "”元素列的元素个数与其他元素列的元素个数不一致!"
|
throw new InvalidDataListException("“" + key + "”元素列的元素个数与其他元素列的元素个数不一致!" + "( “" + key
|
||||||
+ "( “" + key + "”元素列元素列个数:" + elementListSize + ","
|
+ "”元素列元素列个数:" + elementListSize + "," + "其他元素列的元素个数:" + nowListSize.get() + ")");
|
||||||
+ "其他元素列的元素个数:" + nowListSize.get() + ")");
|
|
||||||
} else {
|
} else {
|
||||||
//若无需校验元素个数,则判断传入的元素个数与存储的元素列个数,存储较小的数字
|
// 若无需校验元素个数,则判断传入的元素个数与存储的元素列个数,存储较小的数字
|
||||||
nowListSize.set(nowListSize.get() > elementListSize ? elementListSize : nowListSize.get());
|
nowListSize.set(nowListSize.get() > elementListSize ? elementListSize : nowListSize.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//判断当前元素个数与重新获取前元素个数是否一致,不一致,则需要对数组进行处理
|
// 判断当前元素个数与重新获取前元素个数是否一致,不一致,则需要对数组进行处理
|
||||||
int nowSize = nowListSize.get();
|
int nowSize = nowListSize.get();
|
||||||
if (nowSize != oldSize) {
|
if (nowSize != oldSize) {
|
||||||
//根据元素返回的元素查找对象,强转为DataListBy后,再重新获取所有元素
|
// 根据元素返回的元素查找对象,强转为DataListBy后,再重新获取所有元素
|
||||||
value = ((DataListBy) (element.getBy())).getAllElement();
|
value = ((DataListBy) (element.getBy())).getAllElement();
|
||||||
|
|
||||||
//根据是否进行严格检查,来对listSize进行赋值,若无需严格检查,则取两者之间最小者
|
// 根据是否进行严格检查,来对listSize进行赋值,若无需严格检查,则取两者之间最小者
|
||||||
listSize = isExamine ? nowSize : Math.min(nowSize, listSize);
|
listSize = isExamine ? nowSize : Math.min(nowSize, listSize);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>DataTableEvent.java</p>
|
* <p>
|
||||||
* <p><b>用途:</b>
|
* <b>文件名:</b>DataTableEvent.java
|
||||||
* 枚举列表中可操作的控件,如上一页、下一页按钮等
|
|
||||||
* </p>
|
* </p>
|
||||||
* <p><b>编码时间:</b>2020年11月30日上午8:03:59</p>
|
* <p>
|
||||||
* <p><b>修改时间:</b>2020年11月30日上午8:03:59</p>
|
* <b>用途:</b> 枚举列表中可操作的控件,如上一页、下一页按钮等
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>编码时间:</b>2020年11月30日上午8:03:59
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>修改时间:</b>2020年11月30日上午8:03:59
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
* @author 彭宇琦
|
* @author 彭宇琦
|
||||||
* @version Ver1.0
|
* @version Ver1.0
|
||||||
* @since JDK 1.8
|
* @since JDK 1.8
|
||||||
|
@ -515,33 +584,32 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
/**
|
/**
|
||||||
* 上一页按钮
|
* 上一页按钮
|
||||||
*/
|
*/
|
||||||
PREVIOUS_PAGE_BUTTON("上一页按钮"),
|
PREVIOUS_PAGE_BUTTON("上一页按钮"),
|
||||||
/**
|
/**
|
||||||
* 下一页按钮
|
* 下一页按钮
|
||||||
*/
|
*/
|
||||||
NEXT_PAGE_BUTTON("下一页按钮"),
|
NEXT_PAGE_BUTTON("下一页按钮"),
|
||||||
/**
|
/**
|
||||||
* 首页按钮
|
* 首页按钮
|
||||||
*/
|
*/
|
||||||
FIRST_PAGE_BUTTON("首页按钮"),
|
FIRST_PAGE_BUTTON("首页按钮"),
|
||||||
/**
|
/**
|
||||||
* 尾页按钮
|
* 尾页按钮
|
||||||
*/
|
*/
|
||||||
LAST_PAGE_BUTTON("尾页按钮"),
|
LAST_PAGE_BUTTON("尾页按钮"),
|
||||||
/**
|
/**
|
||||||
* 跳页按钮
|
* 跳页按钮
|
||||||
*/
|
*/
|
||||||
JUMP_PAGE_BUTTON("跳页按钮"),
|
JUMP_PAGE_BUTTON("跳页按钮"),
|
||||||
/**
|
/**
|
||||||
* 页码输入文本框(用于跳页的输入)
|
* 页码输入文本框(用于跳页的输入)
|
||||||
*/
|
*/
|
||||||
PAGE_INPUT_TEXTBOX("页码输入文本框"),
|
PAGE_INPUT_TEXTBOX("页码输入文本框"),
|
||||||
/**
|
/**
|
||||||
* 搜索按钮
|
* 搜索按钮
|
||||||
*/
|
*/
|
||||||
SEARCH_BUTTON("搜索按钮")
|
SEARCH_BUTTON("搜索按钮");
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储枚举名称
|
* 存储枚举名称
|
||||||
*/
|
*/
|
||||||
|
@ -549,6 +617,7 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化枚举名称
|
* 初始化枚举名称
|
||||||
|
*
|
||||||
* @param name
|
* @param name
|
||||||
*/
|
*/
|
||||||
private DataTableKeywordType(String name) {
|
private DataTableKeywordType(String name) {
|
||||||
|
@ -557,20 +626,28 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回枚举指向的控件名称
|
* 返回枚举指向的控件名称
|
||||||
|
*
|
||||||
* @return 控件名称
|
* @return 控件名称
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><b>文件名:</b>DataTableEvent.java</p>
|
* <p>
|
||||||
* <p><b>用途:</b>
|
* <b>文件名:</b>DataTableEvent.java
|
||||||
* 若元素列表无法添加时抛出的异常
|
|
||||||
* </p>
|
* </p>
|
||||||
* <p><b>编码时间:</b>2020年11月19日下午8:26:49</p>
|
* <p>
|
||||||
* <p><b>修改时间:</b>2020年11月19日下午8:26:49</p>
|
* <b>用途:</b> 若元素列表无法添加时抛出的异常
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>编码时间:</b>2020年11月19日下午8:26:49
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* <b>修改时间:</b>2020年11月19日下午8:26:49
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
* @author 彭宇琦
|
* @author 彭宇琦
|
||||||
* @version Ver1.0
|
* @version Ver1.0
|
||||||
* @since JDK 1.8
|
* @since JDK 1.8
|
||||||
|
@ -599,6 +676,6 @@ public final class DataTableEvent extends AbstractEvent {
|
||||||
public InvalidDataListException(Throwable cause) {
|
public InvalidDataListException(Throwable cause) {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,5 +189,25 @@ public class DataTableEventTest {
|
||||||
.map(element -> te.getText(element))
|
.map(element -> te.getText(element))
|
||||||
.forEach(System.out :: println);
|
.forEach(System.out :: println);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于测试{@link DataTableEvent#getRowText(int)}方法<br>
|
||||||
|
* 预期:<br>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void getRowTextTest() {
|
||||||
|
test.getRowText(2).forEach(System.out :: println);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于测试{@link DataTableEvent#getListText(String)}方法<br>
|
||||||
|
* 预期:<br>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void getListTextTest() {
|
||||||
|
test.getListText("账号列").forEach(System.out :: println);
|
||||||
|
}
|
||||||
//---------------------单元测试区---------------------------
|
//---------------------单元测试区---------------------------
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue