diff --git a/pom.xml b/pom.xml index 0ef5339..d975084 100644 --- a/pom.xml +++ b/pom.xml @@ -1,30 +1,21 @@ - - 4.0.0 + + 4.0.0 - pres.appnium.test - Autest - 0.0.1-SNAPSHOT - jar + pres.appnium.test + Autest + 0.0.1-SNAPSHOT + jar - Autest - http://maven.apache.org - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.0.0 - - - + Autest + http://maven.apache.org - - UTF-8 - + + UTF-8 + - + org.seleniumhq.selenium selenium-java @@ -105,69 +96,74 @@ fastjson 1.2.61 - + cn.hutool hutool-all 5.0.2 - + - com.github.noraui - ojdbc7 - 12.1.0.2 + com.github.noraui + ojdbc7 + 12.1.0.2 - + - org.apache.httpcomponents - httpclient - 4.5.12 + org.apache.httpcomponents + httpclient + 4.5.12 - + - org.jsoup - jsoup - 1.13.1 + org.jsoup + jsoup + 1.13.1 - - - - org.springframework - spring-aop - 5.2.7.RELEASE - - - org.springframework - spring-core - 5.2.7.RELEASE - - - org.aspectj - aspectjrt - 1.9.5 - - - org.aspectj - aspectjweaver - 1.9.5 - - - + + - org.projectlombok - lombok - 1.18.12 - provided + org.springframework + spring-aop + 5.2.7.RELEASE - + org.springframework + spring-core + 5.2.7.RELEASE + + + org.aspectj + aspectjrt + 1.9.5 + + + org.aspectj + aspectjweaver + 1.9.5 + + + + + org.projectlombok + lombok + 1.18.12 + provided + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.0.0 + + + diff --git a/src/main/java/pres/auxiliary/tool/web/IncorrectConditionException.java b/src/main/java/pres/auxiliary/tool/date/IncorrectConditionException.java similarity index 93% rename from src/main/java/pres/auxiliary/tool/web/IncorrectConditionException.java rename to src/main/java/pres/auxiliary/tool/date/IncorrectConditionException.java index 8a6d6e2..4f126ad 100644 --- a/src/main/java/pres/auxiliary/tool/web/IncorrectConditionException.java +++ b/src/main/java/pres/auxiliary/tool/date/IncorrectConditionException.java @@ -1,4 +1,4 @@ -package pres.auxiliary.tool.web; +package pres.auxiliary.tool.date; /** *

文件名:IncorrectConditionException.java

diff --git a/src/main/java/pres/auxiliary/tool/date/Time.java b/src/main/java/pres/auxiliary/tool/date/Time.java index bc11f3e..be0cab2 100644 --- a/src/main/java/pres/auxiliary/tool/date/Time.java +++ b/src/main/java/pres/auxiliary/tool/date/Time.java @@ -6,8 +6,6 @@ import java.util.Calendar; import java.util.Date; import java.util.regex.Pattern; -import pres.auxiliary.tool.web.IncorrectConditionException; - /** *

* 文件名:Time.java diff --git a/src/main/java/pres/auxiliary/tool/file/ExcelConfigXmlTool.java b/src/main/java/pres/auxiliary/tool/file/ExcelConfigXmlTool.java index 52cff1a..fb0bfd9 100644 --- a/src/main/java/pres/auxiliary/tool/file/ExcelConfigXmlTool.java +++ b/src/main/java/pres/auxiliary/tool/file/ExcelConfigXmlTool.java @@ -5,7 +5,6 @@ import java.io.FileWriter; import java.io.IOException; import org.dom4j.Document; -import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; @@ -61,12 +60,4 @@ public class ExcelConfigXmlTool { writer.write(document); writer.close(); } - - private void root() { - document.setRootElement(document.addElement("templet")); - } - - private void sheet(String name, String freeze) { - Element root = document.getRootElement(); - } } diff --git a/src/main/java/pres/auxiliary/tool/web/Condition.java b/src/main/java/pres/auxiliary/tool/web/Condition.java deleted file mode 100644 index 61d27b3..0000000 --- a/src/main/java/pres/auxiliary/tool/web/Condition.java +++ /dev/null @@ -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; - -/** - *

- * 文件名:Condition.java - *

- *

- * 用途:用于页面统计中记录需要读取的列的定位方式 ,以及其统计的约束条件,并提供数据对比方法
- * 注意: - *

    - *
  1. 数字和日期的边界限制,可以用中括号"[]"和小括号"()"表示,中括号表可等于,小括号表示不能等于
  2. - *
  3. 数字和日期的分段限制,用英文逗号","隔开,逗号后可以有空格也可以没有空格,但逗号前不能包含空格
  4. - *
  5. 日期类型按照[小日期,大日期)或者(小日期,大日期]的形式传入,日期的格式应为yyyy-mm-dd
  6. - *
  7. 数字类型按照[小数字,大数字)或者(小数字,大数字]的形式传入
  8. - *
- *

- *

- * 编码时间:2019年7月28日下午2:13:59 - *

- *

- * 修改时间:2019年7月31日下午7:03:59 - *

- * - * @author 彭宇琦 - * @version Ver1.0 - * @since JDK 1.8 - * - */ -public class Condition { - - /** - * 用于存储元素定位方式 - */ - private String element; - /** - * 用于存储约束条件,当约束的类型为数字和日期时,此时存储的数据将是前后值是否允许包含的条件 - */ - private ArrayList constraints = new ArrayList(); - /** - * 约束类型 - */ - 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(); - } -} diff --git a/src/main/java/pres/auxiliary/tool/web/ConstraintType.java b/src/main/java/pres/auxiliary/tool/web/ConstraintType.java deleted file mode 100644 index ddb7f67..0000000 --- a/src/main/java/pres/auxiliary/tool/web/ConstraintType.java +++ /dev/null @@ -1,26 +0,0 @@ -package pres.auxiliary.tool.web; - -/** - *

文件名:ConstraintType.java

- *

用途:用于定义约束条件的类型

- *

编码时间:2019年7月28日下午2:24:40

- *

修改时间:2019年7月28日下午2:24:40

- * @author 彭宇琦 - * @version Ver1.0 - * @since JDK 1.8 - * - */ -public enum ConstraintType { - /** - * 字符串类型 - */ - STRING, - /** - * 日期类型 - */ - DATE, - /** - * 数字类型 - */ - NUMBER -} diff --git a/src/main/java/pres/auxiliary/tool/web/IncorrectFileException.java b/src/main/java/pres/auxiliary/tool/web/IncorrectFileException.java deleted file mode 100644 index 6773ed9..0000000 --- a/src/main/java/pres/auxiliary/tool/web/IncorrectFileException.java +++ /dev/null @@ -1,43 +0,0 @@ -package pres.auxiliary.tool.web; - -/** - *

文件名:IncorrectFileException.java

- *

用途:用于读取的文件与相应的代码不匹配时弹出的异常

- *

编码时间:2019年8月2日下午5:33:01

- *

修改时间:2019年8月2日下午5:33:01

- * @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 - } - -} diff --git a/src/main/java/pres/auxiliary/tool/web/WebDataCompare.java b/src/main/java/pres/auxiliary/tool/web/WebDataCompare.java deleted file mode 100644 index 20362e7..0000000 --- a/src/main/java/pres/auxiliary/tool/web/WebDataCompare.java +++ /dev/null @@ -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; - -/** - *

- * 文件名:WebDataCompare.java - *

- *

- * 用途:用于对页面数据的操作工具 - *

- *

- * 编码时间:2019年8月2日上午9:45:00 - *

- *

- * 修改时间:2019年8月3日上午10:42:00 - *

- * - * @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> datas = new LinkedHashMap>(); - // 定义map,用于存储组合条件的数据 - LinkedHashMap groupDatas = new LinkedHashMap(); - - // 创建文件夹 - 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()); - } - } - - // 指定当前获取列表的行数 - 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 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 readFile(File targeFile, String sheetName, int dataRow, int keyCell, - int valueCell) throws IOException { - //存储获取到的数据 - LinkedHashMap map = new LinkedHashMap(); - - 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; - } -} diff --git a/src/main/java/pres/auxiliary/tool/web/WebDataToFile.java b/src/main/java/pres/auxiliary/tool/web/WebDataToFile.java deleted file mode 100644 index c752a02..0000000 --- a/src/main/java/pres/auxiliary/tool/web/WebDataToFile.java +++ /dev/null @@ -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; - -/** - *

文件名:WebDataToFile.java

- *

用途:用于从页面爬取数据以文本的形式存储至本地的工具

- *

编码时间:2019年7月19日下午5:04:20

- *

修改时间:2019年7月20日下午6:17:20

- * @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; - } -} diff --git a/src/main/java/pres/auxiliary/work/selenium/event/extend/DataTableEvent.java b/src/main/java/pres/auxiliary/work/selenium/event/extend/DataTableEvent.java index 66537c6..377b811 100644 --- a/src/main/java/pres/auxiliary/work/selenium/event/extend/DataTableEvent.java +++ b/src/main/java/pres/auxiliary/work/selenium/event/extend/DataTableEvent.java @@ -21,12 +21,19 @@ import pres.auxiliary.work.selenium.event.TextEvent; import pres.auxiliary.work.selenium.event.WaitEvent; /** - *

文件名:OperateDataTable.java

- *

用途: - * 提供对数据表格进行基本操作的事件,包括对数据列表的翻页、跳页、获取等操作,以简化部分操作的代码 + *

+ * 文件名:OperateDataTable.java *

- *

编码时间:2020年11月17日上午7:58:40

- *

修改时间:2020年11月17日上午7:58:40

+ *

+ * 用途: 提供对数据表格进行基本操作的事件,包括对数据列表的翻页、跳页、获取等操作,以简化部分操作的代码 + *

+ *

+ * 编码时间:2020年11月17日上午7:58:40 + *

+ *

+ * 修改时间:2020年11月17日上午7:58:40 + *

+ * * @author 彭宇琦 * @version Ver1.0 * @since JDK 1.8 @@ -49,7 +56,7 @@ public final class DataTableEvent extends AbstractEvent { * 用于进行等待事件 */ private WaitEvent waitEvent; - + /** * 用于存储当前的列表的一列元素 */ @@ -63,17 +70,17 @@ public final class DataTableEvent extends AbstractEvent { * 指向列表加载等待控件 */ private Element waitElement; - + /** * 用于存储当前列表的长度 */ protected int listSize = -1; - + /** * 标记是否进行元素个数长度校验 */ protected boolean isExamine = true; - + /** * 构造对象 * @@ -81,24 +88,26 @@ public final class DataTableEvent extends AbstractEvent { */ public DataTableEvent(AbstractBrower brower) { super(brower); - + clickEvent = new ClickEvent(brower); textEvent = new TextEvent(brower); assertEvent = new AssertEvent(brower); waitEvent = new WaitEvent(brower); } - + /** * 用于设置是否对传入的元素列表的个数进行严格校验,即在调用{@link #add(DataListBy)}方法时, * 若元素个数与初次传入的个数不符且需要严格校验,则抛出异常;反之,则直接进行存储 + * * @param isExamine 是否严格校验元素个数 */ public void setExamine(boolean isExamine) { this.isExamine = isExamine; } - + /** * 用于设置列表加载等待元素,通过该元素,将应用与列表操作后,等待该控件消失后再进行断言的操作 + * * @param waitElement 列表加载等待控件 */ public void setWaitElement(Element waitElement) { @@ -108,64 +117,70 @@ public final class DataTableEvent extends AbstractEvent { /** * 用于添加一列元素,若启用严格校验(即通过{@link #setExamine(boolean)}方法设置为true), * 则调用该方法时将对存储的数据个数进行校验,若传入的列元素个数与当前存储的列表元素个数 - * 不一致时,则抛出{@link InvalidDataListException}异常 + * 不一致时,则抛出{@link InvalidDataListException}异常。 * *

- * 注意:传入的{@link DataListBy}类对象中元素的名称请勿与其他元素名称一致,否则会 - * 覆盖原有的元素列 + * 注意:传入的{@link DataListBy}类对象中元素的名称请勿与其他元素名称一致,否则会覆盖原有的元素列。 + * 其元素名称将作为列表名称,可通过该名称获取当前列 *

* * @param dataListBy 元素列查找对象 * @throws InvalidDataListException 启用严格校验且元素个数与存储列表元素个数不一致时抛出的异常 */ public void addList(DataListBy dataListBy) { - //判断当前是否存储元素,若未存储元素,则不进行元素个数判断 + // 判断当前是否存储元素,若未存储元素,则不进行元素个数判断 if (!tableMap.isEmpty()) { - //判断传入的列的元素个数是否与当前存储的元素个数一致,若不一致,则进行个数判定校验 + // 判断传入的列的元素个数是否与当前存储的元素个数一致,若不一致,则进行个数判定校验 int nowSize = dataListBy.size(); if (nowSize != listSize()) { - //若当前需要严格校验列表元素个数,则抛出异常 + // 若当前需要严格校验列表元素个数,则抛出异常 if (isExamine) { - throw new InvalidDataListException("当前传入的元素列个数与存储的元素列个数不一致!" - + "(当前元素列个数:" + listSize() + ",传入的元素列元素个数:" + nowSize + ")"); + throw new InvalidDataListException( + "当前传入的元素列个数与存储的元素列个数不一致!" + "(当前元素列个数:" + listSize() + ",传入的元素列元素个数:" + nowSize + ")"); } else { - //若无需校验元素个数,则判断传入的元素个数与存储的元素列个数,存储较小的数字 + // 若无需校验元素个数,则判断传入的元素个数与存储的元素列个数,存储较小的数字 listSize = listSize < nowSize ? listSize : nowSize; } } - + } else { listSize = dataListBy.size(); } - + tableMap.put(dataListBy.getElementData().getName(), dataListBy.getAllElement()); } - + /** * 用于添加列表控件的枚举,在调用部分列表操作方法时会使用在此处添加的映射 + * * @param dataTableKeywordType 列表可映射的控件枚举{@link DataTableKeywordType} - * @param by 控件相应的元素对象{@link Element} + * @param by 控件相应的元素对象{@link Element} */ public void putControl(DataTableKeywordType dataTableKeywordType, Element elemenet) { controlMap.put(dataTableKeywordType, elemenet); } - + /** - * 返回元素列中元素的个数,若设置了严格判断,则该数值为所有列的元素个数;反之,则该 - * 数值表示列表集合中,最短元素列的元素个数 + * 返回元素列中元素的个数,若设置了严格判断,则该数值为所有列的元素个数;反之,则该 数值表示列表集合中,最短元素列的元素个数 * * @return 元素列的元素个数 */ public int listSize() { return listSize; } - + + /** + * 获取列表名称指向列的元素个数 + * @param name 列表名称 + * @return 指向的列表元素个数 + */ public int listSize(String name) { return tableMap.get(name).size(); } - + /** * 用于返回元素表中的列数 + * * @return */ public int rowSize() { @@ -173,57 +188,58 @@ public final class DataTableEvent extends AbstractEvent { } /** - * 用于点击多次上一页按钮,并返回实际点击次数(实际点击次数)。若设置的翻页次数小于0 - * ,则持续翻页至无法翻页为止 + * 用于点击多次上一页按钮,并返回实际点击次数(实际点击次数)。若设置的翻页次数小于0 ,则持续翻页至无法翻页为止 + * * @param count 点击次数 * @return 实际点击次数 */ public int previousPage(int count) { return pageTurning(DataTableKeywordType.PREVIOUS_PAGE_BUTTON, count); } - + /** - * 用于点击多次下一页按钮,并返回实际点击次数(实际点击次数)。若设置的翻页次数小于0 - * ,则持续翻页至无法翻页为止 + * 用于点击多次下一页按钮,并返回实际点击次数(实际点击次数)。若设置的翻页次数小于0 ,则持续翻页至无法翻页为止 + * * @param count 点击次数 * @return 实际点击次数 */ public int nextPage(int count) { return pageTurning(DataTableKeywordType.NEXT_PAGE_BUTTON, count); } - + /** * 用于对列表进行翻页操作 + * * @param dataTableKeywordType 翻页按钮类型 - * @param count 指定的翻页次数 + * @param count 指定的翻页次数 * @return 实际翻页次数 */ private int pageTurning(DataTableKeywordType dataTableKeywordType, int count) { - //判断当前按钮是否存在映射 + // 判断当前按钮是否存在映射 if (!controlMap.containsKey(dataTableKeywordType)) { throw new ControlException(dataTableKeywordType.getName(), dataTableKeywordType.toString()); } - - //根据设置的点击次数循环点击翻页按钮 + + // 根据设置的点击次数循环点击翻页按钮 int nowCount = 0; - while(true) { - //判断翻页数,若当前翻页数大于指定翻页数时,则结束循环 - //若指定的翻页数小于0,则持续翻页,直到翻页失败为止 + while (true) { + // 判断翻页数,若当前翻页数大于指定翻页数时,则结束循环 + // 若指定的翻页数小于0,则持续翻页,直到翻页失败为止 if (nowCount >= count && count >= 0) { break; } - + Element controlElement = controlMap.get(dataTableKeywordType); - - boolean result = assertData(() -> { - //判断按钮是否可以点击 + + boolean result = assertData(() -> { + // 判断按钮是否可以点击 if (!controlElement.getWebElement().isEnabled()) { return false; } - + try { clickEvent.click(controlElement); - //等待控件消失 + // 等待控件消失 if (waitElement != null) { waitEvent.disappear(waitElement); } @@ -232,120 +248,117 @@ public final class DataTableEvent extends AbstractEvent { return false; } }); - - //若点击成功,则nowCount自增,若点击失败,则退出循环 + + // 若点击成功,则nowCount自增,若点击失败,则退出循环 if (!result) { break; } - + nowCount++; } - - logText = "点击“" - + controlMap.get(DataTableKeywordType.PREVIOUS_PAGE_BUTTON).getElementData().getName() - + "”元素,使列表返回至" - + (dataTableKeywordType == DataTableKeywordType.PREVIOUS_PAGE_BUTTON ? "上" : "下") + + logText = "点击“" + controlMap.get(DataTableKeywordType.PREVIOUS_PAGE_BUTTON).getElementData().getName() + + "”元素,使列表返回至" + (dataTableKeywordType == DataTableKeywordType.PREVIOUS_PAGE_BUTTON ? "上" : "下") + "页,其实际翻页数为:" + nowCount; resultText = String.valueOf(nowCount); - - //返回实际点击次数 + + // 返回实际点击次数 return nowCount; - } - + } + /** * 用于对列表进行点击跳页按钮后的跳页操作。若当前存储过元素列表,则对元素列表进行断言, * 即取存储的列表的第一行元素,若操作前后,该行元素不变,则判定为跳页失败 * - * @param pageTextbox 跳页文本框元素 + * @param pageTextbox 跳页文本框元素 * @param jumpPageButton 跳页按钮 - * @param pageCountText 页码文本 + * @param pageCountText 页码文本 */ public boolean jumpPage(String pageCount) { if (!controlMap.containsKey(DataTableKeywordType.PAGE_INPUT_TEXTBOX)) { - throw new ControlException(DataTableKeywordType.PAGE_INPUT_TEXTBOX.getName() - , DataTableKeywordType.PAGE_INPUT_TEXTBOX.toString()); + throw new ControlException(DataTableKeywordType.PAGE_INPUT_TEXTBOX.getName(), + DataTableKeywordType.PAGE_INPUT_TEXTBOX.toString()); } - + boolean result = assertData(() -> { - //输入页码 + // 输入页码 textEvent.input(controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX), pageCount); - //判断是否存在跳页按钮的映射,若不存在,则使用回车进行跳页 + // 判断是否存在跳页按钮的映射,若不存在,则使用回车进行跳页 if (controlMap.containsKey(DataTableKeywordType.JUMP_PAGE_BUTTON)) { - //点击跳页 + // 点击跳页 clickEvent.click(controlMap.get(DataTableKeywordType.JUMP_PAGE_BUTTON)); } else { textEvent.keyToSend(controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX), Keys.ENTER); } - - //清空输入框 + + // 清空输入框 textEvent.clear(controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX)); - - //等待控件消失 + + // 等待控件消失 if (waitElement != null) { waitEvent.disappear(waitElement); } - + return true; }); - - logText = "在“" - + controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX).getElementData().getName() - + "”元素中输入" + pageCount - + ",使列表跳转到相应的页码,其翻页" - + (result ? "" : "不") + "成功"; + + logText = "在“" + controlMap.get(DataTableKeywordType.PAGE_INPUT_TEXTBOX).getElementData().getName() + "”元素中输入" + + pageCount + ",使列表跳转到相应的页码,其翻页" + (result ? "" : "不") + "成功"; resultText = String.valueOf(result); - + return result; } - + /** * 通过条件,点击{@link DataTableKeywordType#SEARCH_BUTTON}映射的按钮,对列表进行搜索。方法中需要接收一个 * 返回值为boolean类型的操作,若操作的返回值为false时,则不会点击按钮,可参考以下写法: - *

+	 * 
+	 * 
+	 * 
 	 * DataTableEvent test = new DataTableEvent(brower);
 	 * test.searchList(() -> {
 	 * 	te.input(cb.getElement("账号搜索文本框"), "13000000000");
 	 * 	return true;
 	 * });
-	 * 
+ *
+ *
* * @param action 返回值为boolean类型的操作 * @return 列表是否有变化 */ public boolean searchList(BooleanSupplier action) { - //判断控件是否存在 + // 判断控件是否存在 if (!controlMap.containsKey(DataTableKeywordType.SEARCH_BUTTON)) { - throw new ControlException(DataTableKeywordType.SEARCH_BUTTON.getName() - , DataTableKeywordType.SEARCH_BUTTON.toString()); + throw new ControlException(DataTableKeywordType.SEARCH_BUTTON.getName(), + DataTableKeywordType.SEARCH_BUTTON.toString()); } - - boolean result = false; - //若操作成功,则点击搜索按钮 - if (action.getAsBoolean()) { - clickEvent.click(controlMap.get(DataTableKeywordType.SEARCH_BUTTON)); - - //等待控件消失 - if (waitElement != null) { - waitEvent.disappear(waitElement); + + boolean result = assertData(() -> { + // 若操作成功,则点击搜索按钮 + if (action.getAsBoolean()) { + clickEvent.click(controlMap.get(DataTableKeywordType.SEARCH_BUTTON)); + + // 等待控件消失 + if (waitElement != null) { + waitEvent.disappear(waitElement); + } + + return true; + } else { + return false; } - - //TODO 走列表文本断言 - result = true; - } else { - result = false; - } - + }); + logText = "通过搜索条件,点击“" + controlMap.get(DataTableKeywordType.SEARCH_BUTTON).getElementData().getName() + "”元素,对列表进行搜索"; resultText = String.valueOf(result); - + return result; } - + /** *

- * 获取指定的一行元素,下标允许传入负数,表示从后向前遍历,具体遍历逻辑 - * 可参考{@link DataListBy#getElement(int)}方法。 + * 获取指定的一行元素,下标允许传入负数,表示从后向前遍历,具体遍历逻辑可参考{@link DataListBy#getElement(int)}方法。 *

*

* 注意:下标将按照元素列长度进行计算,若下标的绝对值大于元素列长度,且下标为正数,则 @@ -356,19 +369,68 @@ public final class DataTableEvent extends AbstractEvent { * @return 指定行的元素集合 */ public ArrayList getRowElement(int rowIndex) { - //根据下标,获取元素,并进行存储 + // 根据下标,获取元素,并进行存储 ArrayList elementList = new ArrayList<>(); tableMap.forEach((key, value) -> { - //存储元素 + // 存储元素 elementList.add(value.get(toElementIndex(listSize(key), rowIndex))); }); - + return elementList; } + + /** + * 获取指定行的文本,其行号可传入负数,具体规则可参考{@link DataListBy#getElement(int)}方法 + * @param rowIndex 指定的行号 + * @return 该行元素的文本 + */ + public ArrayList getRowText(int rowIndex) { + //重新获取列表元素 + againFindDataList(); + + ArrayList 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 getListText(String listName) { + //重新获取列表元素 + againFindDataList(); + + //判断列元素是否存在,若不存在,则抛出异常 + if (!tableMap.containsKey(listName)) { + throw new ControlException("“" + listName + "”指向的列元素不存在"); + } + //判断当前列是否包含元素 + if (listSize(listName) == 0) { + throw new ControlException("“" + listName + "”指向的列无元素"); + } + + ArrayList 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 index 传入的下标 @@ -395,28 +457,28 @@ public final class DataTableEvent extends AbstractEvent { return new Random().nextInt(length); } } - + /** * 用于执行需要断言页面元素的列表操作,在其操作方法前后添加了断言操作 + * * @param action 需要执行的内容 * @return 是否翻页成功 */ protected boolean assertData(BooleanSupplier action) { - //若元素列表非空,则获取第一行元素,用于进行断言 + // 若元素列表非空,则获取第一行元素,用于进行断言 ArrayList oldTextList = new ArrayList<>(); if (!tableMap.isEmpty()) { - //获取第一行元素,并将其转换为文本后存储 - getRowElement(1).stream().map(textEvent :: getText).forEach(oldTextList :: add); + // 获取第一行元素,并将其转换为文本后存储 + getRowElement(1).stream().map(textEvent::getText).forEach(oldTextList::add); } - //获取当前集合的长度 + // 获取当前集合的长度 int oldListSize = listSize(); - - - //执行操作,并获取操作的返回结果;若返回值为true,则需要进行元素断言操作 + + // 执行操作,并获取操作的返回结果;若返回值为true,则需要进行元素断言操作 if (action.getAsBoolean()) { - //若当前未获取原元素的内容,则不进行列表断言 + // 若当前未获取原元素的内容,则不进行列表断言 if (oldTextList.size() != 0) { - //断言元素,并返回结果 + // 断言元素,并返回结果 return assertDataChange(oldTextList, oldListSize); } else { return true; @@ -425,87 +487,94 @@ public final class DataTableEvent extends AbstractEvent { return false; } } - + /** * 断言数据是否有改变,若数据改变,则返回true;反之,返回false + * * @param oldTextList 原始数据文本集合 - * @param oldElement 原始数据第一个元素的{@link WebElement}对象 + * @param oldElement 原始数据第一个元素的{@link WebElement}对象 * @return 元素是否存在改变 */ protected boolean assertDataChange(ArrayList oldTextList, int oldListSize) { - //重新获取集合元素 + // 重新获取集合元素 againFindDataList(); - - //获取操作后的第一行元素 + + // 获取操作后的第一行元素 ArrayList newElementList = getRowElement(1); - - //若集合的长度发生改变,则表示集合存在变化 + + // 若集合的长度发生改变,则表示集合存在变化 if (oldListSize != listSize) { return true; } - - //为避免不进行翻页时,列表也会进行一次刷新,则获取信息,对每个文本数据进行比对 + + // 为避免不进行翻页时,列表也会进行一次刷新,则获取信息,对每个文本数据进行比对 for (int index = 0; index < oldTextList.size(); index++) { if (assertEvent.assertNotEqualsText(newElementList.get(index), oldTextList.get(index))) { return true; } } - + return false; } - + /** * 用于重新获取元素信息 */ private void againFindDataList() { - //用于判断当前数列元素的个数 + // 用于判断当前数列元素的个数 AtomicInteger nowListSize = new AtomicInteger(-1); tableMap.forEach((key, value) -> { - //获取原集合个数 + // 获取原集合个数 int oldSize = value.size(); - - //对列表第一个元素进行重新获取 + + // 对列表第一个元素进行重新获取 Element element = value.get(0); - //重新获取当前元素,并存储当前列表长度 + // 重新获取当前元素,并存储当前列表长度 int elementListSize = element.againFindElement(); - - //判断当前size是否为初始化的状态,若为初始化的状态,则直接存储重新获取后的集合元素个数 + + // 判断当前size是否为初始化的状态,若为初始化的状态,则直接存储重新获取后的集合元素个数 if (nowListSize.get() == -1) { - nowListSize.set(elementListSize); + nowListSize.set(elementListSize); } else { - //若当前size已被初始化,则进行重获后的元素个数判断 + // 若当前size已被初始化,则进行重获后的元素个数判断 if (nowListSize.get() != elementListSize) { - //若当前需要严格校验列表元素个数,则抛出异常 + // 若当前需要严格校验列表元素个数,则抛出异常 if (isExamine) { - throw new InvalidDataListException("“" + key + "”元素列的元素个数与其他元素列的元素个数不一致!" - + "( “" + key + "”元素列元素列个数:" + elementListSize + "," - + "其他元素列的元素个数:" + nowListSize.get() + ")"); + throw new InvalidDataListException("“" + key + "”元素列的元素个数与其他元素列的元素个数不一致!" + "( “" + key + + "”元素列元素列个数:" + elementListSize + "," + "其他元素列的元素个数:" + nowListSize.get() + ")"); } else { - //若无需校验元素个数,则判断传入的元素个数与存储的元素列个数,存储较小的数字 + // 若无需校验元素个数,则判断传入的元素个数与存储的元素列个数,存储较小的数字 nowListSize.set(nowListSize.get() > elementListSize ? elementListSize : nowListSize.get()); } } } - - //判断当前元素个数与重新获取前元素个数是否一致,不一致,则需要对数组进行处理 + + // 判断当前元素个数与重新获取前元素个数是否一致,不一致,则需要对数组进行处理 int nowSize = nowListSize.get(); if (nowSize != oldSize) { - //根据元素返回的元素查找对象,强转为DataListBy后,再重新获取所有元素 + // 根据元素返回的元素查找对象,强转为DataListBy后,再重新获取所有元素 value = ((DataListBy) (element.getBy())).getAllElement(); - - //根据是否进行严格检查,来对listSize进行赋值,若无需严格检查,则取两者之间最小者 + + // 根据是否进行严格检查,来对listSize进行赋值,若无需严格检查,则取两者之间最小者 listSize = isExamine ? nowSize : Math.min(nowSize, listSize); } }); } - + /** - *

文件名:DataTableEvent.java

- *

用途: - * 枚举列表中可操作的控件,如上一页、下一页按钮等 + *

+ * 文件名:DataTableEvent.java *

- *

编码时间:2020年11月30日上午8:03:59

- *

修改时间:2020年11月30日上午8:03:59

+ *

+ * 用途: 枚举列表中可操作的控件,如上一页、下一页按钮等 + *

+ *

+ * 编码时间:2020年11月30日上午8:03:59 + *

+ *

+ * 修改时间:2020年11月30日上午8:03:59 + *

+ * * @author 彭宇琦 * @version Ver1.0 * @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 */ private DataTableKeywordType(String name) { @@ -557,20 +626,28 @@ public final class DataTableEvent extends AbstractEvent { /** * 返回枚举指向的控件名称 + * * @return 控件名称 */ public String getName() { return name; } } - + /** - *

文件名:DataTableEvent.java

- *

用途: - * 若元素列表无法添加时抛出的异常 + *

+ * 文件名:DataTableEvent.java *

- *

编码时间:2020年11月19日下午8:26:49

- *

修改时间:2020年11月19日下午8:26:49

+ *

+ * 用途: 若元素列表无法添加时抛出的异常 + *

+ *

+ * 编码时间:2020年11月19日下午8:26:49 + *

+ *

+ * 修改时间:2020年11月19日下午8:26:49 + *

+ * * @author 彭宇琦 * @version Ver1.0 * @since JDK 1.8 @@ -599,6 +676,6 @@ public final class DataTableEvent extends AbstractEvent { public InvalidDataListException(Throwable cause) { super(cause); } - + } } diff --git a/src/test/java/pres/auxiliary/work/selenium/event/extend/DataTableEventTest.java b/src/test/java/pres/auxiliary/work/selenium/event/extend/DataTableEventTest.java index 52824e2..cac837c 100644 --- a/src/test/java/pres/auxiliary/work/selenium/event/extend/DataTableEventTest.java +++ b/src/test/java/pres/auxiliary/work/selenium/event/extend/DataTableEventTest.java @@ -189,5 +189,25 @@ public class DataTableEventTest { .map(element -> te.getText(element)) .forEach(System.out :: println); } + + /** + * 用于测试{@link DataTableEvent#getRowText(int)}方法
+ * 预期:
+ * + */ + @Test + public void getRowTextTest() { + test.getRowText(2).forEach(System.out :: println); + } + + /** + * 用于测试{@link DataTableEvent#getListText(String)}方法
+ * 预期:
+ * + */ + @Test + public void getListTextTest() { + test.getListText("账号列").forEach(System.out :: println); + } //---------------------单元测试区--------------------------- }