调整类结构,删除无效的类

This commit is contained in:
彭宇琦 2020-12-05 17:57:04 +08:00
parent 40ad893020
commit 69ad08ac60
11 changed files with 338 additions and 1349 deletions

136
pom.xml
View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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();
}
} }

View File

@ -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();
}
}

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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和valueput入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;
}
}

View File

@ -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 {
//由于文件不存在则不需要计算任何的循环值rowcelli都为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;
}
}

View File

@ -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);
} }
} }
} }

View File

@ -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);
}
//---------------------单元测试区--------------------------- //---------------------单元测试区---------------------------
} }