> {
/**
* 用于测试caseXml文件,编码结束后删除
*/
-// public File getCaseXml() throws IOException {
-// File file = new File("src/test/java/pres/auxiliary/work/testcase/用例xml文件.xml");
-// FileWriter fw = new FileWriter(file);
-// caseXml.write(fw);
-// fw.close();
-//
-// return file;
-// }
+ public File getCaseXml() throws IOException {
+ File file = new File("src/test/java/pres/auxiliary/work/testcase/用例xml文件.xml");
+ FileWriter fw = new FileWriter(file);
+ contentXml.write(fw);
+ fw.close();
+
+ return file;
+ }
/**
*
@@ -1067,7 +1111,8 @@ public abstract class AbstractWriteExcel> {
*/
public class FieldMark {
// 用于存储case标签元素
- Element caseElement;
+// Element caseElement;
+ protected String uuid;
/**
* 构造类,但不允许外部进行构造
@@ -1075,125 +1120,213 @@ public abstract class AbstractWriteExcel> {
* @param uuid 用例的uuid
*/
private FieldMark(String uuid) {
- caseElement = ((Element) (contentXml.selectSingleNode("//*[@id='" + uuid + "']")));
+ this.uuid = uuid;
}
/**
- * 向单元格(字段)上添加一个标记(备注),以记录内容
+ * 向当前指向的sheet中的单元格(字段)上添加一个标记(备注),以记录内容
+ *
+ * @param field 字段id
+ * @param content 标记中记录的内容
+ * @return 类本身
+ */
+ public FieldMark fieldComment(String field, String content) {
+ return fieldComment(nowSheetName, field, content);
+ }
+
+ /**
+ * 向sheet中的单元格(字段)上添加一个标记(备注),以记录内容
*
* @param field 字段id
* @param content 标记中记录的内容
* @return 类本身
*/
@SuppressWarnings("unchecked")
- public FieldMark fieldComment(String field, String content) {
+ public FieldMark fieldComment(String sheetName, String field, String content) {
+ //查找nowSheetName指向的sheet中的与uuid一致的单元格
+ Element caseElement = getCaseElement(sheetName);
+
// 判断字段是否存在,若不存在,则抛出异常
- if (!fieldMap.containsKey(field)) {
+ if (!fieldMap.get(nowSheetName).containsKey(field)) {
throw new LabelNotFoundException("当前sheet不存在的标签id:" + field);
}
// 向包含uuid的标签下添加相应的属性
- ((List) (caseElement.elements())).stream().filter(e -> e.attributeValue("name").equals(field))
+ ((List) (caseElement.elements())).stream().filter(e -> e.attributeValue("id").equals(field))
.forEach(e -> e.addAttribute("comment", content));
return this;
}
/**
- * 用于对字段所在的单元格的背景色进行修改
+ * 用于对当前指向的sheet中字段所在的单元格的背景色进行修改
*
* @param field 字段id
- * @param colors {@link MarkColorsType}类枚举
+ * @param markColorsType {@link MarkColorsType}类枚举
+ * @return 类本身
+ */
+ public FieldMark changeFieldBackground(String field, MarkColorsType markColorsType) {
+ return changeFieldBackground(nowSheetName, field, markColorsType);
+ }
+
+ /**
+ * 用于对指定sheet中字段所在的单元格的背景色进行修改
+ *
+ * @param field 字段id
+ * @param markColorsType {@link MarkColorsType}类枚举
* @return 类本身
*/
@SuppressWarnings("unchecked")
- public FieldMark changeFieldBackground(String field, MarkColorsType color) {
+ public FieldMark changeFieldBackground(String sheetName, String field, MarkColorsType markColorsType) {
+ //查找nowSheetName指向的sheet中的与uuid一致的单元格
+ Element caseElement = getCaseElement(sheetName);
+
// 判断字段是否存在,若不存在,则抛出异常
- if (!fieldMap.containsKey(field)) {
+ if (!fieldMap.get(nowSheetName).containsKey(field)) {
throw new LabelNotFoundException("当前sheet不存在的标签id:" + field);
}
// 向包含uuid的标签下添加相应的属性
- ((List) (caseElement.elements())).stream().filter(e -> e.attributeValue("name").equals(field))
- .forEach(e -> e.addAttribute("background", String.valueOf(color.getColorsValue())));
+ ((List) (caseElement.elements())).stream().filter(e -> e.attributeValue("id").equals(field))
+ .forEach(e -> e.addAttribute("background", String.valueOf(markColorsType.getColorsValue())));
return this;
}
/**
- * 对整行用例的背景色进行更改(标记)
+ * 对当前指向的sheet的整行用例的背景色进行更改(标记)
*
- * @param colors {@link MarkColorsType}类枚举
+ * @param markColorsType {@link MarkColorsType}类枚举
+ * @return 类本身
+ */
+ public FieldMark changeRowBackground(MarkColorsType markColorsType) {
+ return changeRowBackground(nowSheetName, markColorsType);
+ }
+
+ /**
+ * 对指定sheet的整行用例的背景色进行更改(标记)
+ *
+ * @param markColorsType {@link MarkColorsType}类枚举
* @return 类本身
*/
@SuppressWarnings("unchecked")
- public FieldMark changeRowBackground(MarkColorsType color) {
+ public FieldMark changeRowBackground(String sheetName, MarkColorsType markColorsType) {
+ //查找nowSheetName指向的sheet中的与uuid一致的单元格
+ Element caseElement = getCaseElement(sheetName);
+
// 将case下所有标签的name属性传至fieldBackground方法
((List) (caseElement.elements())).stream()
- .forEach(e -> changeFieldBackground(e.attributeValue("name"), color));
+ .forEach(e -> changeFieldBackground(e.attributeValue("id"), markColorsType));
return this;
}
/**
- * 该方法用于对整行用例文本的颜色进行标记
+ * 该方法用于对当前指向的sheet的整行用例文本的颜色进行标记
*
- * @param color {@link MarkColorsType}类枚举
+ * @param markColorsType {@link MarkColorsType}类枚举
+ * @return 类本身
+ */
+ public FieldMark changeRowTextColor(MarkColorsType markColorsType) {
+ return changeRowTextColor(nowSheetName, markColorsType);
+ }
+
+ /**
+ * 该方法用于对指定的sheet中整行用例文本的颜色进行标记
+ *
+ * @param markColorsType {@link MarkColorsType}类枚举
* @return 类本身
*/
@SuppressWarnings("unchecked")
- public FieldMark changeRowTextColor(MarkColorsType color) {
+ public FieldMark changeRowTextColor(String sheetName, MarkColorsType markColorsType) {
+ //查找nowSheetName指向的sheet中的与uuid一致的单元格
+ Element caseElement = getCaseElement(sheetName);
+
// 将case下所有标签的name属性传至fieldBackground方法
((List) (caseElement.elements())).forEach(fieldElement -> {
List textElements = fieldElement.elements();
- changeTextColor(fieldElement.attributeValue("name"), 0, textElements.size(), color);
+ changeTextColor(fieldElement.attributeValue("id"), 0, textElements.size(), markColorsType);
});
return this;
}
/**
- * 用于对字段的文本进行颜色标记,下标从0开始计算,若下标小于0时,则标记第一段;
+ * 用于对当前指向的sheet字段的文本进行颜色标记,下标从0开始计算,若下标小于0时,则标记第一段;
* 若下标大于最大段落数时,则编辑最后一段。若所传字段下不存在文本标签,则不进行标记
*
* @param field 字段id
* @param index 字段文本的段标(段落)
- * @param colors {@link MarkColorsType}类枚举
+ * @param markColorsType {@link MarkColorsType}类枚举
* @return 类本身
*/
- public FieldMark changeTextColor(String field, int index, MarkColorsType color) {
- return changeTextColor(field, index, index, color);
+ public FieldMark changeTextColor(String field, int index, MarkColorsType markColorsType) {
+ return changeTextColor(nowSheetName, field, index, index, markColorsType);
+ }
+
+ /**
+ * 用于对指定的sheet字段的文本进行颜色标记,下标从0开始计算,若下标小于0时,则标记第一段;
+ * 若下标大于最大段落数时,则编辑最后一段。若所传字段下不存在文本标签,则不进行标记
+ *
+ * @param field 字段id
+ * @param index 字段文本的段标(段落)
+ * @param markColorsType {@link MarkColorsType}类枚举
+ * @return 类本身
+ */
+ public FieldMark changeTextColor(String sheetName, String field, int index, MarkColorsType markColorsType) {
+ return changeTextColor(sheetName, field, index, index, markColorsType);
}
/**
- * 用于对字段的多段文本进行颜色标记,下标从0开始计算,若下标小于0时,则标记第一段;
+ * 用于对当前指向的sheet中字段的多段文本进行颜色标记,下标从0开始计算,若下标小于0时,则标记第一段;
* 若下标大于最大段落数时,则编辑最后一段。若所传字段下不存在文本标签,则不进行标记。
* 注意,标记的段落包括开始段落,但不包括结束段落;若开始与结束的段落数相同,则标记对应的一行
*
* @param field 字段id
* @param startIndex 字段文本的开始段标(段落)
* @param endIndex 字段文本的结束段标(段落)
- * @param color {@link MarkColorsType}类枚举
+ * @param markColorsType {@link MarkColorsType}类枚举
+ * @return 类本身
+ */
+ public FieldMark changeTextColor(String field, int startIndex, int endIndex, MarkColorsType markColorsType) {
+ return changeTextColor(nowSheetName, field, startIndex, endIndex, markColorsType);
+ }
+
+ /**
+ * 用于对指定的sheet字段的多段文本进行颜色标记,下标从0开始计算,若下标小于0时,则标记第一段;
+ * 若下标大于最大段落数时,则编辑最后一段。若所传字段下不存在文本标签,则不进行标记。
+ * 注意,标记的段落包括开始段落,但不包括结束段落;若开始与结束的段落数相同,则标记对应的一行
+ *
+ * @param field 字段id
+ * @param startIndex 字段文本的开始段标(段落)
+ * @param endIndex 字段文本的结束段标(段落)
+ * @param markColorsType {@link MarkColorsType}类枚举
* @return 类本身
*/
@SuppressWarnings("unchecked")
- public FieldMark changeTextColor(String field, int startIndex, int endIndex, MarkColorsType color) {
+ public FieldMark changeTextColor(String sheetName, String field, int startIndex, int endIndex, MarkColorsType markColorsType) {
+ //查找nowSheetName指向的sheet中的与uuid一致的单元格
+ Element caseElement = getCaseElement(sheetName);
// 获取case下的name属性与所传参数相同的field标签
- ((List) (caseElement.elements())).stream().filter(e -> e.attributeValue("name").equals(field))
+ ((List) (caseElement.elements())).stream().filter(e -> e.attributeValue("id").equals(field))
.forEach(fieldElement -> {
// 获取其下的所有field标签
List textElements = (fieldElement.elements());
// 判断是否存在text标签,若不存在,则结束
if (textElements.size() != 0) {
+ //转换下标
+ int changeStartIndex = getPoiIndex(textElements.size(), startIndex);
+ int changeEndIndex = getPoiIndex(textElements.size(), endIndex);
+
// 处理最大与最小值,保证数据不会错误
- boolean endIndexBig = startIndex < endIndex;
- int smallIndex = endIndexBig ? startIndex : endIndex;
- int bigIndex = endIndexBig ? endIndex : startIndex;
+ boolean endIndexBig = changeStartIndex < changeEndIndex;
+ int smallIndex = endIndexBig ? changeStartIndex : changeEndIndex;
+ int bigIndex = endIndexBig ? changeEndIndex : changeStartIndex;
// 判断最大最小值是否相同,相同则最大值+1
bigIndex = bigIndex == smallIndex ? (bigIndex + 1) : bigIndex;
for (int index = smallIndex; index < bigIndex; index++) {
- setTextColor(textElements, index, color);
+ setTextColor(textElements, index, markColorsType);
}
}
});
@@ -1205,14 +1338,15 @@ public abstract class AbstractWriteExcel> {
*
* @param textElements 字段标签下的文本标签
* @param index 标签的位置
- * @param color 颜色
+ * @param markColorsType 颜色
* @return 颜色是否正常进行设置,即传入的index是否正常
*/
- private void setTextColor(List textElements, int index, MarkColorsType color) {
+ private void setTextColor(List textElements, int index, MarkColorsType markColorsType) {
// 判断传入的index参数:
// 若参数小于0,则标记第一个标签
// 若参数大于0且小于text最大标签数,则标记相应的标签
// 若参数大于text最大标签数,则标记最后一个标签
+ /*
Element textElement;
if (index < 0) {
textElement = textElements.get(0);
@@ -1221,7 +1355,91 @@ public abstract class AbstractWriteExcel> {
} else {
textElement = textElements.get(textElements.size() - 1);
}
- textElement.addAttribute("colors", String.valueOf(color.getColorsValue()));
+ */
+
+ Element textElement = textElements.get(getPoiIndex(textElements.size(), index));
+ textElement.addAttribute("colors", String.valueOf(markColorsType.getColorsValue()));
+ }
+
+ /**
+ * 用于向当前指向的sheet下的指定字段添加超链接。超链接文本可传入excel允许的超链接形式
+ * @param field 字段id
+ * @param linkContent 需要链接的内容
+ * @return 类本身
+ */
+ public FieldMark fieldLink(String field, String linkContent) {
+ return fieldLink(nowSheetName, field, linkContent);
+ }
+
+ /**
+ * 用于向指定的的sheet下的指定字段添加超链接。超链接文本可传入excel允许的超链接形式
+ *
+ * @param field 字段id
+ * @param linkContent 需要链接的内容
+ * @return 类本身
+ */
+ public FieldMark fieldLink(String sheetName, String field, String linkContent) {
+ //查找sheetName指向的sheet中的与uuid一致的单元格
+ Element fieldElement = getFieldElement(getCaseElement(sheetName), field);
+
+ fieldElement.addAttribute("link", judgelinkText(linkContent));
+
+ return this;
+ }
+
+ /**
+ * 用于根据链接内容,返回相应的超链接类型名称,返回的形式为“超链接类型=超链接内容”
+ * @param linkContent 标签中link属性的内容
+ * @return 超链接类型名称
+ */
+ private String judgelinkText(String linkContent) {
+ //文件超链接判定规则
+ String fileRegex = "(([a-zA-Z]:(\\/|\\\\))|(\\.(\\/|\\\\)))([^/:*?<>\\\"|\\\\]+(\\/|\\\\)?)+[^/:*?<>\\\"|\\\\].[^/:*?<>\\\"|\\\\]";
+ //文档内超链接判定规则
+ String domRegex = "'[^\\\\\\/\\?\\*\\[\\]]{1,31}'![A-Za-z]+\\d+";
+
+ //根据链接内容,与相应的正则进行判断,根据结果,返回相应的HyperlinkType类
+ if (RegexType.URL.judgeString(linkContent)) {
+ return LinkType.URL.getName() + "=" + linkContent;
+ } else if (RegexType.EMAIL.judgeString(linkContent)) {
+ return LinkType.EMAIL.getName() + "=" + linkContent;
+ } else if (linkContent.matches(fileRegex)) {
+ return LinkType.FILE.getName() + "=" + linkContent;
+ } else if (linkContent.matches(domRegex)) {
+ return LinkType.DOMCUMENT.getName() + "=" + linkContent;
+ } else {
+ throw new IncorrectIndexException("无法识别的超链接:" + linkContent);
+ }
+ }
+
+ /**
+ * 用于根据指定的sheet名称获取其下相应的case标签,并返回其元素,若查不到元素,则返回null
+ * @param sheetName sheet名称
+ * @return 指定sheet名称下的case标签元素
+ */
+ public Element getCaseElement(String sheetName) {
+ /*
+ if (!writeSheetNameList.contains(sheetName)) {
+ return null;
+ }
+ */
+ return ((Element) (contentXml.selectSingleNode("//sheet[@name='" + sheetName +"']/case[@id='" + uuid + "']")));
+ }
+
+ /**
+ * 用于获取在指定的case标签元素中的字段元素
+ * @param caseElement case标签元素
+ * @param field case标签下的字段id
+ * @return
+ */
+ private Element getFieldElement(Element caseElement, String field) {
+ for (Object fieldElement : caseElement.elements("field")) {
+ if (((Element)fieldElement).attributeValue("id").equals(field)) {
+ return (Element)fieldElement;
+ }
+ }
+
+ throw new IncorrectIndexException("当前sheet(" + caseElement.getParent().attributeValue("name") + ")中不存在字段:" + field);
}
}
@@ -1249,6 +1467,10 @@ public abstract class AbstractWriteExcel> {
* 用于存储字段在配置文件中的id
*/
public String id;
+ /**
+ * 用于存储字段在配置文件中的name
+ */
+ public String name;
/**
* 用于存储字段对应单元格内文本的水平对齐方式
*/
@@ -1265,10 +1487,6 @@ public abstract class AbstractWriteExcel> {
* 用于标记是否对字段进行编号
*/
public boolean serialNumber = false;
- /**
- * 用于标记超链接内容
- */
- public String link;
/**
* 用于存储字段在用例中对应的内容
@@ -1291,14 +1509,14 @@ public abstract class AbstractWriteExcel> {
* @param numberSign 字段是否需要编号
* @param link 超链接内容
*/
- public Field(String id, String align, int index, String rowText, ArrayList datas, boolean numberSign, String link) {
+ public Field(String id, String name, String align, int index, String rowText, ArrayList datas, boolean numberSign) {
this.id = id;
+ this.name = name;
this.align = align;
this.index = index;
this.datas = datas;
this.rowText = rowText == null ? -1 : Integer.valueOf(rowText);
this.serialNumber = numberSign;
- this.link = link == null ? "" : link;
}
/**
@@ -1409,7 +1627,7 @@ public abstract class AbstractWriteExcel> {
}
// 拼接当前数据在数据有效性页中的名称(sheetName来自外层类)
- String dataCellTitle = sheetName + CreateExcelFile.SIGN + id;
+ String dataCellTitle = nowSheetName + CreateExcelFile.SIGN + id;
// 遍历第一行相应的单元格,查看是否存在与sheetName相同的
int cellindex = 0;
for (; cellindex < xr.getLastCellNum(); cellindex++) {
@@ -1445,5 +1663,14 @@ public abstract class AbstractWriteExcel> {
DataValidation d = new XSSFDataValidationHelper(caseSheet).createValidation(constraint, regions);
caseSheet.addValidationData(d);
}
+
+ /**
+ * 根据下标返回字段中存储的内容,下标允许传入负数,表示从后向前遍历
+ * @param index 下标
+ * @return 下标对应的字段内容
+ */
+ public String getContent(int index) {
+ return content.get(getPoiIndex(content.size(), index));
+ }
}
}
diff --git a/src/main/java/pres/auxiliary/tool/file/excel/LinkType.java b/src/main/java/pres/auxiliary/tool/file/excel/LinkType.java
new file mode 100644
index 0000000..4e96d84
--- /dev/null
+++ b/src/main/java/pres/auxiliary/tool/file/excel/LinkType.java
@@ -0,0 +1,52 @@
+package pres.auxiliary.tool.file.excel;
+
+/**
+ * 文件名:LinkType.java
+ * 用途:
+ * 用于枚举excel中可用的超链接类型
+ *
+ * 编码时间:2020年8月22日下午4:43:35
+ * 修改时间:2020年8月22日下午4:43:35
+ * @author 彭宇琦
+ * @version Ver1.0
+ *
+ */
+public enum LinkType {
+ /**
+ * 表示文件超链接
+ */
+ FILE("file"),
+ /**
+ * 表示网页超链接
+ */
+ URL("url"),
+ /**
+ * 表示邮箱超链接
+ */
+ EMAIL("email"),
+ /**
+ * 表示文档内超链接
+ */
+ DOMCUMENT("dom");
+
+ /**
+ * 用于标记超链接名称
+ */
+ private String name;
+
+ /**
+ * 初始化枚举的名称
+ * @param name 枚举名称
+ */
+ private LinkType(String name) {
+ this.name = name;
+ }
+
+ /**
+ * 用于返回枚举的名称
+ * @return 枚举名称
+ */
+ public String getName() {
+ return name;
+ }
+}
diff --git a/src/main/java/pres/auxiliary/tool/file/excel/NoSuchTypeException.java b/src/main/java/pres/auxiliary/tool/file/excel/NoSuchTypeException.java
new file mode 100644
index 0000000..4f2408e
--- /dev/null
+++ b/src/main/java/pres/auxiliary/tool/file/excel/NoSuchTypeException.java
@@ -0,0 +1,38 @@
+package pres.auxiliary.tool.file.excel;
+
+/**
+ * 文件名:NoSuchTypeException.java
+ * 用途:
+ * 当枚举类型不存在时抛出的异常
+ *
+ * 编码时间:2020年8月22日下午4:40:44
+ * 修改时间:2020年8月22日下午4:40:44
+ * @author 彭宇琦
+ * @version Ver1.0
+ *
+ */
+public class NoSuchTypeException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public NoSuchTypeException() {
+ super();
+ }
+
+ public NoSuchTypeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ public NoSuchTypeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public NoSuchTypeException(String message) {
+ super(message);
+ }
+
+ public NoSuchTypeException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/src/main/java/pres/auxiliary/tool/file/excel/ReplactFunction.java b/src/main/java/pres/auxiliary/tool/file/excel/ReplactFunction.java
new file mode 100644
index 0000000..40f2795
--- /dev/null
+++ b/src/main/java/pres/auxiliary/tool/file/excel/ReplactFunction.java
@@ -0,0 +1,22 @@
+package pres.auxiliary.tool.file.excel;
+
+/**
+ * 文件名:ReplactFunction.java
+ * 用途:
+ * 用于根据替换词语,设置相应的替换方法,并在读取到该词语时执行设置方法的接口
+ *
+ * 编码时间:2020年9月3日上午8:24:58
+ * 修改时间:2020年9月3日上午8:24:58
+ * @author 彭宇琦
+ * @version Ver1.0
+ *
+ */
+public interface ReplactFunction {
+ /**
+ * 根据替换的词语,以及在该位置上的原始内容,对词语所在位置内容进行替换
+ * @param replactWord 需要替换的词语
+ * @param value 原始内容
+ * @return 被替换的内容
+ */
+ public String replact(String replactWord, String value);
+}
diff --git a/src/main/java/pres/auxiliary/work/selenium/brower/AbstractBrower.java b/src/main/java/pres/auxiliary/work/selenium/brower/AbstractBrower.java
index a338dbf..ce0a0cd 100644
--- a/src/main/java/pres/auxiliary/work/selenium/brower/AbstractBrower.java
+++ b/src/main/java/pres/auxiliary/work/selenium/brower/AbstractBrower.java
@@ -371,6 +371,7 @@ public abstract class AbstractBrower {
pageMap.put(popuHandle, popuPage);
//将当前页面指向到弹窗页面上
nowPage = popuPage;
+ windowHandleSet.add(popuHandle);
//返回切换弹窗成功
return true;
diff --git a/src/main/java/pres/auxiliary/work/selenium/element/AbstractBy.java b/src/main/java/pres/auxiliary/work/selenium/element/AbstractBy.java
index 5c05639..4e266eb 100644
--- a/src/main/java/pres/auxiliary/work/selenium/element/AbstractBy.java
+++ b/src/main/java/pres/auxiliary/work/selenium/element/AbstractBy.java
@@ -22,10 +22,9 @@ import pres.auxiliary.work.selenium.xml.ReadXml;
/**
* 文件名:AbstractElement.java
* 用途:
- *
- * 对辅助化测试工具selenium的获取元素代码进行的二次封装,通过类中提供的方法以及配合相应存储元素的
+ * 对辅助化测试工具selenium的获取元素代码进行的二次封装,通过类中提供的方法以及配合相应存储元素的
* xml文件,以更简便的方式对页面元素进行获取,减少编程时的代码量。
- *
+ *
* 编码时间:2020年4月25日 下午4:18:37
* 修改时间:2020年4月25日 下午4:18:37
* @author 彭宇琦
@@ -34,7 +33,7 @@ import pres.auxiliary.work.selenium.xml.ReadXml;
*/
public abstract class AbstractBy {
/**
- * 用于存储浏览器的WebDriver对象,设为静态,保证所有的子类只使用一个WebDriver对象,以避免造成WebDriver不正确导致的Bug
+ * 用于存储浏览器的WebDriver对象
*/
WebDriver driver;
/**
@@ -70,7 +69,7 @@ public abstract class AbstractBy {
private long waitTime = 5;
/**
- * 控制是否自动切换窗体,由于通过Event类调用时会构造另一个事件类,但每个类都应共享一个开关,故需要加上static
+ * 控制是否自动切换窗体,由于通过Event类调用时会构造另一个事件类
*/
boolean isAutoSwitchIframe = true;
@@ -109,9 +108,9 @@ public abstract class AbstractBy {
}
/**
- * 用于设置事件等待时间,默认时间为5秒
+ * 用于设置元素等待时间,默认时间为5秒
*
- * @param waitTime 事件等待时间
+ * @param waitTime 元素等待时间
*/
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
diff --git a/src/main/java/pres/auxiliary/work/selenium/element/DataListBy.java b/src/main/java/pres/auxiliary/work/selenium/element/DataListBy.java
index e4a4b75..651d64e 100644
--- a/src/main/java/pres/auxiliary/work/selenium/element/DataListBy.java
+++ b/src/main/java/pres/auxiliary/work/selenium/element/DataListBy.java
@@ -76,14 +76,6 @@ public class DataListBy extends ListBy {
super(driver);
}
- /**
- * 通过{@link AbstractBy}对象对类进行构造,将传入的AbstractBy类中的关键参数设置到当前类对象中
- * @param brower {@link AbstractBy}对象
- */
- public DataListBy(AbstractBy by) {
- super(by);
- }
-
/**
* 用于设置首行元素是否为标题元素
* @param isFristRowTitle 首行是否为标题元素
diff --git a/src/main/java/pres/auxiliary/work/selenium/element/ListBy.java b/src/main/java/pres/auxiliary/work/selenium/element/ListBy.java
index 4c93005..f93574d 100644
--- a/src/main/java/pres/auxiliary/work/selenium/element/ListBy.java
+++ b/src/main/java/pres/auxiliary/work/selenium/element/ListBy.java
@@ -45,14 +45,6 @@ public abstract class ListBy extends MultiBy {
super(driver);
}
- /**
- * 通过{@link AbstractBy}对象对类进行构造,将传入的AbstractBy类中的关键参数设置到当前类对象中
- * @param brower {@link AbstractBy}对象
- */
- public ListBy(AbstractBy by) {
- super(by);
- }
-
/**
* 返回列表名称对应的元素个数,若该列未被获取,则返回-1
* @param name 被获取的列名称
diff --git a/src/main/java/pres/auxiliary/work/selenium/element/MultiBy.java b/src/main/java/pres/auxiliary/work/selenium/element/MultiBy.java
index e00969f..c88b602 100644
--- a/src/main/java/pres/auxiliary/work/selenium/element/MultiBy.java
+++ b/src/main/java/pres/auxiliary/work/selenium/element/MultiBy.java
@@ -39,14 +39,6 @@ public abstract class MultiBy extends AbstractBy {
super(driver);
}
- /**
- * 通过{@link AbstractBy}对象对类进行构造,将传入的AbstractBy类中的关键参数设置到当前类对象中
- * @param brower {@link AbstractBy}对象
- */
- public MultiBy(AbstractBy by) {
- super(by);
- }
-
/**
* 用于根据传入的元素在xml文件中的名称或者元素的定位内容,添加元素。由于该方法不指定元素的定位
* 方式,若传入的参数不是xml元素且非xpath路径或绝对css路径时,其识别效率较慢,建议在该情况下
diff --git a/src/main/java/pres/auxiliary/work/selenium/element/SelectBy.java b/src/main/java/pres/auxiliary/work/selenium/element/SelectBy.java
index c0ed031..40e0817 100644
--- a/src/main/java/pres/auxiliary/work/selenium/element/SelectBy.java
+++ b/src/main/java/pres/auxiliary/work/selenium/element/SelectBy.java
@@ -90,14 +90,6 @@ public class SelectBy extends MultiBy {
super(driver);
}
- /**
- * 通过{@link AbstractBy}对象对类进行构造,将传入的AbstractBy类中的关键参数设置到当前类对象中
- * @param brower {@link AbstractBy}对象
- */
- public SelectBy(AbstractBy by) {
- super(by);
- }
-
/**
* 设置首个选项是否为不可选择的选项
* @param fristIsEmpty 首个选项是否为不可选择
diff --git a/src/main/java/pres/auxiliary/work/selenium/tool/ExcelRecord.java b/src/main/java/pres/auxiliary/work/selenium/tool/ExcelRecord.java
index e1e77aa..1872d89 100644
--- a/src/main/java/pres/auxiliary/work/selenium/tool/ExcelRecord.java
+++ b/src/main/java/pres/auxiliary/work/selenium/tool/ExcelRecord.java
@@ -1,12 +1,16 @@
package pres.auxiliary.work.selenium.tool;
import java.io.File;
+import java.util.ArrayList;
import org.dom4j.Document;
import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import pres.auxiliary.tool.date.Time;
import pres.auxiliary.tool.file.excel.AbstractWriteExcel;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
+import pres.auxiliary.work.testcase.file.MarkColorsType;
/**
* 文件名:ExcelRecord.java
@@ -21,30 +25,324 @@ import pres.auxiliary.work.selenium.brower.AbstractBrower;
*/
public class ExcelRecord extends AbstractWriteExcel {
/**
- * 存储浏览器对象
+ * 用于记录当前出现BUG的结果位置
*/
- AbstractBrower brower;
+ private ArrayList resultBugList = new ArrayList<>();
+ /**
+ * 用于指向当前记录的运行截图文件
+ */
+ private File runScreenhotFile = null;
+ /**
+ * 用于指向当前记录的异常截图文件
+ */
+ private File errorScreenhotFile = null;
+ /**
+ * 用于指向当前是否存在异常
+ */
+ boolean isError = false;
+ /**
+ * 用于记录开始执行的时间
+ */
+ private long startTime = 0L;
/**
- * 通过
- * @param configDocument
- * @param tempFile
- * @param brower
+ * 根据xml配置文件的{@link Document}类对象进行构造
+ * @param configDocument xml配置文件的{@link Document}类对象
+ * @param tempFile excel文件对象
*/
- public ExcelRecord(Document configDocument, File tempFile, AbstractBrower brower) {
+ public ExcelRecord(Document configDocument, File tempFile) {
super(configDocument, tempFile);
- this.brower = brower;
}
/**
- * @param configFile
- * @param tempFile
- * @param brower
- * @throws DocumentException
+ * 根据xml配置文件对象进行构造
+ * @param configFile xml配置文件对象
+ * @param tempFile excel文件对象
+ * @throws DocumentException 当读取xml配置文件对象失败时抛出的异常
*/
- public ExcelRecord(File configFile, File tempFile, AbstractBrower brower) throws DocumentException {
+ public ExcelRecord(File configFile, File tempFile) throws DocumentException {
super(configFile, tempFile);
- this.brower = brower;
}
+ /**
+ * 用于添加浏览器信息。该方法不能单独调用,必须配合其他
+ * 其他方法一起使用,否则在生成文件时,其写入的内容不会被填写到文件中
+ * @param brower 继承自{@link AbstractBrower}类的浏览器类对象
+ * @return 类本身
+ */
+ public ExcelRecord setBrowerInformation(AbstractBrower brower) {
+ //TODO 添加浏览器信息内容
+
+ return this;
+ }
+
+ /**
+ * 用于添加执行者。该方法不能单独调用,必须配合的其他其他方法一起使用,
+ * 否则在生成文件时,其写入的内容不会被填写到文件中
+ * @param actionName 执行者
+ * @return 类本身
+ */
+ public ExcelRecord setActionName(String actionName) {
+ switchSheet("运行记录").setFieldValue("active_person", actionName);
+
+ return this;
+ }
+
+ /**
+ * 用于添加运行类名以及运行方法名。多次调用时会清空上一次记录的内容
+ * @param className 类名
+ * @param methodName 方法名
+ * @return 类本身
+ */
+ public ExcelRecord runMethod(String className, String methodName) {
+ setFieldValue("运行记录", "class_name", className);
+ setFieldValue("运行记录", "method_name", methodName);
+ setFieldValue("错误记录", "class_name", className);
+ setFieldValue("错误记录", "method_name", methodName);
+ return this;
+ }
+
+ /**
+ * 用于记录执行开始时间,记录结束时,会写入相应的结束时间
+ */
+ public ExcelRecord reckonByTime() {
+ //若设定当前状态为开始记录状态,则存储当前的时间戳
+ startTime = System.currentTimeMillis();
+
+ return this;
+ }
+
+ /**
+ * 用于添加实际运行步骤,支持传入多条,每条数据将自动编号以及换行
+ *
+ * @param text 实际运行步骤
+ * @return 类本身
+ */
+ public ExcelRecord runStep(String... text) {
+ return switchSheet("运行记录").addContent("step", text);
+ }
+
+ /**
+ * 用于添加执行结果,根据传入的Bug判定来记录当前执行的Bug数量。该方法可调用多次,
+ * 将多个结果,结果将自动编号。
+ *
+ * @param text 结果
+ * @param bug 标记是否为Bug
+ * @return 类本身
+ */
+ public ExcelRecord runResult(String text, boolean bug) {
+ //若当前结果为BUG,则记录相应的编号
+ if (bug) {
+ //编号可根据相应sheet中字段的内容数量获取到当前出现BUG的内容位置
+ resultBugList.add(fieldMap.get("运行记录").get("result").content.size());
+ }
+
+ return switchSheet("运行记录").addContent("result", text);
+ }
+
+ /**
+ * 用于添加运行备注
+ *
+ * @param text 备注文本
+ * @return 类本身
+ */
+ public ExcelRecord runMark(String text) {
+ return switchSheet("运行记录").addContent("mark", text);
+ }
+
+ /**
+ * 用于添加运行时截图
+ *
+ * @param screenshotFile 截图文件对象
+ * @return 类本身
+ */
+ public ExcelRecord runScreenshot(File screenshotFile) {
+ //记录运行截图
+ runScreenhotFile = screenshotFile;
+
+ return switchSheet("运行记录")
+ .addContent("screenshot_position", screenshotFile.getPath());
+ }
+
+ /**
+ * 用于添加异常步骤的信息,传入异常类后,将会自动记录异常步骤
+ * @param exception 异常类
+ * @return 类本身
+ */
+ public ExcelRecord exception(Exception exception) {
+ isError = true;
+ return switchSheet("错误记录")
+ .addContent("error_step", fieldMap.get("运行记录").get("step").content.size() == 0 ? "" : fieldMap.get("运行记录").get("step").getContent(-1))
+ .addContent("error_class", exception.getClass().getName())
+ .addContent("error_information", exception.getMessage());
+ }
+
+ /**
+ * 用于添加异常步骤信息,并记录截图,可参见{@link #exception(Exception)}
+ * @param exception 异常类
+ * @param screenshotFile 截图文件对象
+ * @return 类本身
+ */
+ public ExcelRecord exception(Exception exception, File screenshotFile) {
+ errorScreenhotFile = screenshotFile;
+ return exception(exception)
+ .switchSheet("错误记录")
+ .addContent("screenshot_position", screenshotFile.getPath());
+ }
+
+ /**
+ * 用于添加测试用例的前置条件,支持传入多条,每条数据将自动编号以及换行
+ *
+ * @param text 前置条件
+ * @return 类本身
+ */
+ public ExcelRecord caseCondition(String... text) {
+ return switchSheet("测试用例").addContent("condition", text);
+ }
+
+ /**
+ * 用于添加测试用例的标题,不支持传入多个标题,每次调用方法后将覆盖之前传入的内容
+ * @param text 标题
+ * @return 类本身
+ */
+ public ExcelRecord caseTitle(String text) {
+ return switchSheet("测试用例")
+ .clearContent("title")
+ .addContent("title", text);
+ }
+
+ /**
+ * 用于添加测试用例的步骤,支持传入多条,每条数据将自动编号以及换行
+ * @param text 标题
+ * @return 类本身
+ */
+ public ExcelRecord caseStep(String... text) {
+ return switchSheet("测试用例")
+ .addContent("step", text);
+
+ }
+
+ /**
+ * 用于添加测试用例的预期,支持传入多条,每条数据将自动编号以及换行
+ * @param text 标题
+ * @return 类本身
+ */
+ public ExcelRecord caseExpect(String... text) {
+ return switchSheet("测试用例")
+ .addContent("expect", text);
+ }
+
+ @Override
+ public AbstractWriteExcel.FieldMark end() {
+ //记录运行状态,Bug数量,当前时间以及运行时间
+ switchSheet("运行记录")
+ .addContent("state", isError ? "2" : "1")
+ .addContent("bug_number", String.valueOf(resultBugList.size()))
+ .addContent("active_time", new Time().getFormatTime())
+ .addContent("use_time", startTime == 0L ? "" : (String.valueOf((System.currentTimeMillis() - startTime) / 1000.0) + "s"));
+
+ //获取父类的end方法,结束当前的记录
+ FieldMark fieldMark = super.end();
+
+ //判断是否存在BUG,并标记相应的结果文本为红色
+ resultBugList.forEach(bugIndex -> {
+ fieldMark.changeTextColor("result", bugIndex, MarkColorsType.RED);
+ });
+
+ //若存在异常,则将运行状态文本标记为红色,并添加相应的超链接
+ if (isError) {
+ //修改文本为红色
+ fieldMark.changeTextColor("运行记录", "state", 0, MarkColorsType.RED);
+
+ //添加运行记录与错误记录的内链关系
+ fieldMark.fieldLink("运行记录", "state", getDocumentLinkPath("错误记录|id|-1"));
+ fieldMark.fieldLink("错误记录", "method_name", getDocumentLinkPath("运行记录|method_name|-1"));
+ //若存在异常截图文件,则添加本地文件链接
+ if (errorScreenhotFile != null) {
+ fieldMark.fieldLink("错误记录", "screenshot_position", getScreenshotPath(errorScreenhotFile));
+ }
+ }
+
+ //若需要进行超链接,则添加相应的超链接
+ if (runScreenhotFile != null) {
+ fieldMark.fieldLink("运行记录", "screenshot_position", getScreenshotPath(runScreenhotFile));
+ }
+
+ //获取测试用例中相应的元素
+ Element caseElement = fieldMark.getCaseElement("测试用例");
+ Element runElement = fieldMark.getCaseElement("运行记录");
+ //若能获取到元素,则添加运行记录与测试用例之间的关联
+ if (caseElement != null && runElement != null) {
+ fieldMark.fieldLink("测试用例", "case_id", getDocumentLinkPath("运行记录|case_id|-1"));
+ fieldMark.fieldLink("运行记录", "case_id", getDocumentLinkPath("测试用例|case_id|-1"));
+ }
+
+
+ //初始化数据
+ initDta();
+ return fieldMark;
+ }
+
+ /**
+ * 用于初始化所有需要用作记录的数据
+ */
+ private void initDta() {
+ resultBugList.clear();
+ runScreenhotFile = null;
+ errorScreenhotFile = null;
+ startTime = 0L;
+ isError = false;
+ }
+
+ /**
+ * 将xml文件中编写的文档内部超链接内容进行转换
+ * @param linkContent 链接内容
+ * @return 转换后的在poi使用的超链接代码
+ */
+ private String getDocumentLinkPath(String linkContent) {
+ String[] linkContents = linkContent.split("\\|");
+ int length = linkContents.length;
+
+ //获取超链接的sheet名称
+ String linkSheetName = linkContents[0];
+ //根据sheet名称以及字段id,获取该字段在sheet中的列数字下标,并将数字下标转换为英文下标
+ String linkColumnIndex = num2CharIndex(getColumnNumIndex(linkSheetName, linkContents[1]));
+
+ String linkRowIndex = "";
+ //获取当前表格的最后一行元素个数
+
+ int lastIndex = ((Element) (contentXml.selectSingleNode("//sheet[@name='" + linkSheetName + "']"))).elements().size();
+ //判断当前linkContents是否存在链接行数(即第三个元素)且链接的文本为数字
+ //若符合规则,则将linkRowIndex设置为当前编写的内容
+ //若不符合规则,则将linkRowIndex设置为当前sheet的最后一行
+ //由于存在标题行,调用getPoiIndex()方法得到的数值需要向下平移一位才能得到真实的数据
+ if (length > 2) {
+ linkRowIndex = String.valueOf(getPoiIndex(lastIndex + 1, Integer.valueOf(linkContents[2])) + 1);
+ } else {
+ linkRowIndex = String.valueOf(lastIndex + 1);
+ }
+
+ //返回文档链接的内容
+ return "'" + linkSheetName + "'!" + linkColumnIndex + linkRowIndex;
+ }
+
+ /**
+ * 用于返回需要链接的截图文件路径,若截图文件在tempFile下,则返回相应的相对路径;
+ * 若不在其下,则返回截图文件的绝对路径
+ * @param screenshotFile 截图文件对象
+ * @return 截图文件路径
+ */
+ private String getScreenshotPath(File screenshotFile) {
+ //获取excel文件以及截图文件存储路径
+ String excelFolderPath = tempFile.getParentFile().getAbsolutePath();
+ String screenhotPath = screenshotFile.getAbsolutePath();
+
+ //判断当前截图文件的路径是否在excel文件路径下,若存在其下,则返回相应的相对路径;
+ //若不存在,则返回截图文件的绝对路径
+ if (screenhotPath.indexOf(excelFolderPath) == -1) {
+ return screenhotPath;
+ } else {
+ return "." + screenhotPath.substring(excelFolderPath.length()).replaceAll("\\\\", "/");
+ }
+ }
}
diff --git a/src/main/java/pres/auxiliary/work/selenium/tool/Log.java b/src/main/java/pres/auxiliary/work/selenium/tool/Log_Old.java
similarity index 95%
rename from src/main/java/pres/auxiliary/work/selenium/tool/Log.java
rename to src/main/java/pres/auxiliary/work/selenium/tool/Log_Old.java
index ea13a9e..6e7b3ac 100644
--- a/src/main/java/pres/auxiliary/work/selenium/tool/Log.java
+++ b/src/main/java/pres/auxiliary/work/selenium/tool/Log_Old.java
@@ -15,7 +15,7 @@ import java.util.Date;
* @version Ver1.0
* @since JDK 12
*/
-public class Log {
+public class Log_Old {
/**
* 用于存储文件的保存路径
*/
@@ -45,7 +45,7 @@ public class Log {
* 默认位置为:C:\\AutoTestting\\TestResults\\
* 默认文件名为(不带后缀):TestResults
*/
- public Log() {
+ public Log_Old() {
}
/**
@@ -59,7 +59,7 @@ public class Log {
* @throws IncorrectDirectoryException
* 传入路径不合法时抛出的异常
*/
- public Log(String savePath) {
+ public Log_Old(String savePath) {
setSavePath(savePath);
}
@@ -73,7 +73,7 @@ public class Log {
* @throws IncorrectDirectoryException
* 传入的路径不合法或者文件名不合法时抛出的异常
*/
- public Log(String savePath, String fileName) {
+ public Log_Old(String savePath, String fileName) {
setSavePath(savePath);
setFileName(fileName);
}
diff --git a/src/main/java/pres/auxiliary/work/selenium/tool/RecordTool.java b/src/main/java/pres/auxiliary/work/selenium/tool/RecordTool.java
index f768baa..dbee629 100644
--- a/src/main/java/pres/auxiliary/work/selenium/tool/RecordTool.java
+++ b/src/main/java/pres/auxiliary/work/selenium/tool/RecordTool.java
@@ -66,7 +66,7 @@ public class RecordTool {
/**
* Log类对象,默认构造
*/
- private static Log log = new Log(DEFAULT_FILE_PATH);
+ private static Log_Old log = new Log_Old(DEFAULT_FILE_PATH);
/**
* Record类对象,默认构造
*/
@@ -127,11 +127,11 @@ public class RecordTool {
private static boolean startRecord = false;
/**
- * 返回{@link Log}类对象
+ * 返回{@link Log_Old}类对象
*
- * @return {@link Log}类对象
+ * @return {@link Log_Old}类对象
*/
- public static Log getLog() {
+ public static Log_Old getLog() {
return log;
}
diff --git a/src/main/java/pres/auxiliary/work/selenium/tool/RunLog.java b/src/main/java/pres/auxiliary/work/selenium/tool/RunLog.java
new file mode 100644
index 0000000..ae6b2fb
--- /dev/null
+++ b/src/main/java/pres/auxiliary/work/selenium/tool/RunLog.java
@@ -0,0 +1,32 @@
+package pres.auxiliary.work.selenium.tool;
+
+import java.io.File;
+
+/**
+ * 文件名:RunLog.java
+ * 用途:
+ * 以纯文本的形式记录自动化运行过程
+ *
+ * 编码时间:2020年9月3日上午8:02:37
+ * 修改时间:2020年9月3日上午8:02:37
+ * @author 彭宇琦
+ * @version Ver1.0
+ *
+ */
+public class RunLog {
+ /**
+ * 指向日志文件类对象
+ */
+ private File logFile = null;
+
+ public RunLog() {
+ }
+
+ /**
+ * 构造对象,并指定日志存放位置
+ * @param logFile 日志文件类对象
+ */
+ public RunLog(File logFile) {
+ this.logFile = logFile;
+ }
+}
diff --git a/src/main/java/pres/auxiliary/work/testcase/file/AbstractTestCaseWrite.java b/src/main/java/pres/auxiliary/work/testcase/file/AbstractTestCaseWrite.java
index e28cede..2104ab1 100644
--- a/src/main/java/pres/auxiliary/work/testcase/file/AbstractTestCaseWrite.java
+++ b/src/main/java/pres/auxiliary/work/testcase/file/AbstractTestCaseWrite.java
@@ -71,7 +71,7 @@ public abstract class AbstractTestCaseWrite>
*/
public void relevanceCase(String field, String labelType) {
// 判断字段是否存在,若不存在,则抛出异常
- if (!fieldMap.containsKey(field)) {
+ if (!fieldMap.get(nowSheetName).containsKey(field)) {
throw new LabelNotFoundException("当前sheet不存在的标签id:" + field);
}
diff --git a/src/main/java/pres/auxiliary/work/testcase/file/BasicTestCaseWrite.java b/src/main/java/pres/auxiliary/work/testcase/file/BasicTestCaseWrite.java
index 876e2c5..ae0f59f 100644
--- a/src/main/java/pres/auxiliary/work/testcase/file/BasicTestCaseWrite.java
+++ b/src/main/java/pres/auxiliary/work/testcase/file/BasicTestCaseWrite.java
@@ -2,6 +2,8 @@ package pres.auxiliary.work.testcase.file;
import java.io.File;
+import org.dom4j.DocumentException;
+
/**
* 文件名:BasicTestCaseWrite.java
* 用途:在无相应的测试用例文件类时,可使用本类,对自定义的一个测试用例模板进行编辑
@@ -19,9 +21,10 @@ public class BasicTestCaseWrite extends AbstractTestCaseWrite文件名:CommonTestCaseWrite.java
* 用途:定义了测试用例中一些基本方法的添加,如添加步骤、预期方法等,使编码时更加直观
@@ -21,9 +23,10 @@ public abstract class CommonTestCaseWrite> exte
*
* @param configFile 测试文件模板xml配置文件类对象
* @param caseFile 测试用例文件类对象
+ * @throws DocumentException
* @throws IncorrectFileException 文件格式或路径不正确时抛出的异常
*/
- public CommonTestCaseWrite(File configFile, File caseFile) {
+ public CommonTestCaseWrite(File configFile, File caseFile) throws DocumentException {
super(configFile, caseFile);
}
@@ -117,7 +120,7 @@ public abstract class CommonTestCaseWrite> exte
//1.命中一个结果,则直接存入结果
//2.命中多个结果或未命中结果,则以“/key1/key2/key3/.../keyN”的形式拼接字符串
//获取数据有效性
- ArrayList dataList = fieldMap.get(getModuleName()).matchDataValidation(keys);
+ ArrayList dataList = fieldMap.get(nowSheetName).get(getModuleName()).matchDataValidation(keys);
//存储最终得到的模块信息
StringBuilder dataText = new StringBuilder();
if (dataList.size() == 1) {
diff --git a/src/main/java/pres/auxiliary/work/testcase/file/JiraTestCaseWrite.java b/src/main/java/pres/auxiliary/work/testcase/file/JiraTestCaseWrite.java
index c8e824a..2fe90f2 100644
--- a/src/main/java/pres/auxiliary/work/testcase/file/JiraTestCaseWrite.java
+++ b/src/main/java/pres/auxiliary/work/testcase/file/JiraTestCaseWrite.java
@@ -2,6 +2,8 @@ package pres.auxiliary.work.testcase.file;
import java.io.File;
+import org.dom4j.DocumentException;
+
import pres.auxiliary.work.testcase.templet.LabelType;
/**
@@ -24,9 +26,10 @@ public class JiraTestCaseWrite extends CommonTestCaseWrite {
*
* @param configFile 测试文件模板xml配置文件类对象
* @param caseFile 测试用例文件类对象
+ * @throws DocumentException
* @throws IncorrectFileException 文件格式或路径不正确时抛出的异常
*/
- public JiraTestCaseWrite(File configFile, File caseFile) {
+ public JiraTestCaseWrite(File configFile, File caseFile) throws DocumentException {
super(configFile, caseFile);
//TODO 添加与测试用例模板的关联,若测试用例模板字段有所改变,则在此改变关联字段
diff --git a/src/main/java/pres/auxiliary/work/testcase/templet/Case.java b/src/main/java/pres/auxiliary/work/testcase/templet/Case.java
index ca2fae9..0074b70 100644
--- a/src/main/java/pres/auxiliary/work/testcase/templet/Case.java
+++ b/src/main/java/pres/auxiliary/work/testcase/templet/Case.java
@@ -27,16 +27,16 @@ public abstract class Case {
/**
* 用于标记获取标签下所有的文本
*/
- final String ALL = "-1:getAllText";
+ protected final String ALL = "-1:getAllText";
/**
* 用于存储需要替换的词语的开始标记
*/
- final String START_SIGN = "*{";
+ protected final String START_SIGN = "*{";
/**
* 用于存储需要替换的词语的结束标记
*/
- final String END_SIGN = "}*";
+ protected final String END_SIGN = "}*";
/**
* 用于存储传入到正则表达式中的开始标记
@@ -46,17 +46,17 @@ public abstract class Case {
/**
* 用于指向测试用例xml文件的Document对象
*/
- Document configXml;
+ protected Document configXml;
/**
* 存储xml文件中其需要替换的词语
*/
- HashMap wordMap = new HashMap(16);
+ protected HashMap wordMap = new HashMap(16);
/**
* 存储字段的文本内容
*/
- HashMap> fieldTextMap = new HashMap>(16);
+ protected HashMap> fieldTextMap = new HashMap>(16);
/**
* 根据用例xml文件来构造Case类
@@ -96,7 +96,7 @@ public abstract class Case {
* @param text 需要替换的文本
* @return 替换后的文本
*/
- String replaceText(String text) {
+ protected String replaceText(String text) {
StringBuilder sb = new StringBuilder(text);
//存储替换符的位置
int index = 0;
@@ -119,11 +119,24 @@ public abstract class Case {
/**
* 用于获取用例xml中对应用例的标签内的文本,并返回替换词语后的文本
* @param caseName 用例名称
- * @param label 标签枚举
+ * @param labelType 标签枚举{@link LabelType}
* @param id 对应标签的id属性
* @return 标签中存储的文本,并进行处理
*/
- String getLabelText(String caseName, LabelType label, String id) {
+ protected String getLabelText(String caseName, LabelType labelType, String id) {
+ //返回处理替换的单词后相应的文本
+ return getLabelText(caseName, labelType.getName(), id);
+
+ }
+
+ /**
+ * 用于获取用例xml中对应用例的标签内的文本,并返回替换词语后的文本
+ * @param caseName 用例名称
+ * @param labelName 标签名称
+ * @param id 对应标签的id属性
+ * @return 标签中存储的文本,并进行处理
+ */
+ protected String getLabelText(String caseName, String labelName, String id) {
//定位case标签的名称属性名
String caseLabelNameAttribute = "name";
//定位标签中能指向调用用例的属性(id)
@@ -134,7 +147,7 @@ public abstract class Case {
//拼接xpath,规则"//case[@name='caseName']//标签名称[@id='id']"
String xpath = "//" + LabelType.CASE.getName() +
"[@" + caseLabelNameAttribute + "='" +
- caseName + "']//" + label.getName() +
+ caseName + "']//" + labelName +
"[@" + labelIdAttribute + "='" + id +"']";
//获取相应的文本内容
@@ -143,7 +156,7 @@ public abstract class Case {
//判断集合是否存在元素,若不存在元素,则抛出异常
if (textElement == null) {
- throw new LabelNotFoundException("不存在的标签:<" + label.getName() + " " + labelIdAttribute + "='" + id +"'...>");
+ throw new LabelNotFoundException("不存在的标签:<" + labelName + " " + labelIdAttribute + "='" + id +"'...>");
}
//返回处理替换的单词后相应的文本
@@ -158,7 +171,7 @@ public abstract class Case {
* @return 标签中存储的文本,并进行处理
*/
@SuppressWarnings("unchecked")
- ArrayList getAllLabelText(String caseName, LabelType label) {
+ protected ArrayList getAllLabelText(String caseName, LabelType label) {
//定位case标签的名称属性名
String caseLabelNameAttribute = "name";
//定位相应标签中存储用例内容的属性
@@ -209,7 +222,7 @@ public abstract class Case {
* 用于保存xml文件中的字段
*/
@SuppressWarnings("unchecked")
- void saveField() {
+ protected void saveField() {
//获取case标签下所有的标签,存储至fieldTextMap,以初始化所有的字段名称
((List) (configXml.getRootElement().elements("case"))).forEach(caseElement -> {
((List) caseElement.elements()).forEach(labelElement -> {
@@ -225,23 +238,41 @@ public abstract class Case {
* @param label 标签名称(枚举)
* @param text 相应内容
*/
- void addFieldText(LabelType label, String text) {
+ protected void addFieldText(LabelType label, String text) {
fieldTextMap.get(label.getName()).add(text);
}
+ /**
+ * 用于添加多行文本
+ * @param label 标签名称
+ * @param texts 相应内容
+ */
+ protected void addFieldText(String labelName, List texts) {
+ fieldTextMap.get(labelName).addAll(texts);
+ }
+
+ /**
+ * 用于添加一行文本
+ * @param label 标签名称
+ * @param text 相应内容
+ */
+ protected void addFieldText(String labelName, String text) {
+ fieldTextMap.get(labelName).add(text);
+ }
+
/**
* 用于添加多行文本
* @param label 标签名称(枚举)
* @param texts 相应内容
*/
- void addFieldText(LabelType label, List texts) {
+ protected void addFieldText(LabelType label, List texts) {
fieldTextMap.get(label.getName()).addAll(texts);
}
/**
* 用于清空字段的内容,以避免存储上一次输入的用例
*/
- void clearFieldText() {
+ protected void clearFieldText() {
fieldTextMap.forEach((key, value) -> {
fieldTextMap.get(key).clear();
});
@@ -255,7 +286,7 @@ public abstract class Case {
return fieldTextMap;
}
- /**`
+ /**
* 由于添加与参数相关的数据时需要将关联的字段(如步骤及结果)都添加至其中,
* 若后期关联字段增加,则代码量将是成倍的增加,故将关联的内容提取出来,在
* 外部进行添加,之后修改关联字段时只需修改该方法即可。若传入-1,则表示
@@ -268,7 +299,7 @@ public abstract class Case {
* @param caseName 读取的用例名称
* @param ids id参数串
*/
- void relevanceAddData(String caseName, String...ids) {
+ protected void relevanceAddData(String caseName, String...ids) {
//添加步骤
if (ids[0].equals(ALL)) {
addFieldText(LabelType.STEP, getAllLabelText(caseName, LabelType.STEP));
diff --git a/src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.java b/src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.java
new file mode 100644
index 0000000..f5db741
--- /dev/null
+++ b/src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.java
@@ -0,0 +1,47 @@
+package pres.auxiliary.tool.file.excel;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.dom4j.DocumentException;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class WriteExcelTest {
+ final File configXml = new File("src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.xml");
+ final File excelFile = new File("src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.xlsx");
+
+ WriteExcel we;
+
+ @BeforeClass
+ public void init() throws DocumentException, IOException {
+ CreateExcelFile cef = new CreateExcelFile(configXml, excelFile);
+ cef.setCoverFile(true);
+ cef.create();
+
+ we = new WriteExcel(configXml, excelFile);
+ }
+
+ @AfterClass
+ public void writeFile() throws IOException {
+ we.writeFile();
+ java.awt.Desktop.getDesktop().open(excelFile.getParentFile());
+ }
+
+ @Test
+ public void mark_fieldLink() {
+ we.switchSheet("测试Sheet1")
+ .addContent("标题", "测试标题")
+ .addContent("状态", "1")
+ .switchSheet("测试Sheet2")
+ .addContent("关键用例", "2")
+ .addContent("设计者", "测试")
+ .switchSheet("测试Sheet1")
+ .addContent("步骤", "步骤1", "步骤2", "步骤3")
+ .end()
+ .fieldLink("标题", "'测试Sheet2'!A1")
+ .fieldLink("测试Sheet2", "设计者", "'测试Sheet1'!B2")
+ ;
+ }
+}
diff --git a/src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.xlsx b/src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.xlsx
new file mode 100644
index 0000000..ce80e70
Binary files /dev/null and b/src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.xlsx differ
diff --git a/src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.xml b/src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.xml
new file mode 100644
index 0000000..6dee54e
--- /dev/null
+++ b/src/test/java/pres/auxiliary/tool/file/excel/WriteExcelTest.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/pres/auxiliary/work/selenium/tool/ExcelRecordTest.java b/src/test/java/pres/auxiliary/work/selenium/tool/ExcelRecordTest.java
new file mode 100644
index 0000000..8f907e5
--- /dev/null
+++ b/src/test/java/pres/auxiliary/work/selenium/tool/ExcelRecordTest.java
@@ -0,0 +1,140 @@
+package pres.auxiliary.work.selenium.tool;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import org.dom4j.DocumentException;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import pres.auxiliary.tool.file.excel.CreateExcelFile;
+
+public class ExcelRecordTest {
+ CreateExcelFile cef;
+ ExcelRecord er;
+
+ final File configXml = new File("ConfigurationFiles/SeleniumConfigurationFile/LogConfiguration/ExcelRecordTemplet.xml");
+ final File tempFile = new File("src/test/java/pres/auxiliary/work/selenium/tool/Test.xlsx");
+ final File imageFile = new File("src/test/java/pres/auxiliary/work/selenium/tool/微信图片_20200828101657.png");
+
+ @BeforeTest
+ public void init() throws DocumentException, IOException {
+ cef = new CreateExcelFile(configXml, tempFile);
+ cef.setCoverFile(true);
+ cef.create();
+
+ er = new ExcelRecord(configXml, tempFile);
+ }
+
+ @AfterTest
+ public void writeFile() throws IOException {
+ er.writeFile();
+ Desktop.getDesktop().open(tempFile.getParentFile());
+ Desktop.getDesktop().open(er.getCaseXml());
+ }
+
+ @BeforeClass
+ public void recordBaseInfo() {
+ er.setActionName("yuqipeng_d");
+ }
+
+ @BeforeMethod
+ public void startRecord(Method method) {
+ er.runMethod(this.getClass().getName(), method.getName());
+ er.reckonByTime();
+ }
+
+ @AfterMethod
+ public void endRecord() {
+ er.end();
+ }
+
+ @Test
+ public void runStepTest() {
+ er.runStep("第一步", "第二步", "第三步");
+ }
+
+ @Test
+ public void runResultTest() {
+ er.runResult("结果1,不是BUG", false);
+ er.runResult("结果2,是BUG", true);
+ }
+
+ @Test
+ public void runMarkTest() {
+ er.runMark("这是备注信息");
+ }
+
+ @Test
+ public void runScreenshotTest() throws IOException {
+ er.runScreenshot(imageFile);
+ }
+
+ @Test
+ public void exceptionTest_NotFile() {
+ er.exception(new NullPointerException("抛出了NullPointerException异常"));
+ }
+
+ @Test
+ public void exceptionTest_HasFile() {
+ er.exception(new RecordStateException("抛出了RecordStateException异常"), imageFile);
+ }
+
+ @Test
+ public void caseConditionTest() {
+ er.caseCondition("测试用例前置条件1", "测试用例前置条件2");
+ }
+
+ @Test
+ public void caseTitleTest() {
+ er.caseTitle("测试用例标题");
+ }
+
+ @Test
+ public void caseStepTest() {
+ er.caseStep("测试用例步骤1", "测试用例步骤2");
+ }
+
+ @Test
+ public void caseExpectTest() {
+ er.caseExpect("测试用例预期1", "测试用例预期2");
+ }
+
+ @Test
+ public void addAllContentTest() {
+ er.caseTitle("测试成功运行标题")
+ .caseStep("测试第1步")
+ .caseExpect("测试第1预期")
+ .caseCondition("前置条件1")
+ .runStep("实际第1步")
+ .runStep("实际第2步")
+ .runStep("实际第3步", "实际第4步")
+ .runResult("实际结果1", false)
+ .runResult("实际结果2", true)
+ .runMark("实际备注")
+ .runScreenshot(imageFile)
+ .end();
+
+ er.reckonByTime()
+ .caseTitle("测试失败运行标题")
+ .caseStep("测试第1步")
+ .caseExpect("测试第1预期")
+ .caseCondition("前置条件1")
+ .runStep("实际第1步")
+ .runStep("实际第2步", "实际第3步")
+ .exception(new NullPointerException("此时抛出了NullPointerException异常"), imageFile)
+ .runStep("实际第4步")
+ .runStep("实际第5步")
+ .exception(new RecordStateException("这里出现了RecordStateException异常"))
+ .runResult("实际结果1", false)
+ .runResult("实际结果2", true)
+ .runMark("实际备注")
+ .runScreenshot(imageFile);
+ }
+}
diff --git a/src/test/java/pres/auxiliary/work/selenium/tool/Test.xlsx b/src/test/java/pres/auxiliary/work/selenium/tool/Test.xlsx
new file mode 100644
index 0000000..407de16
Binary files /dev/null and b/src/test/java/pres/auxiliary/work/selenium/tool/Test.xlsx differ
diff --git a/src/test/java/pres/auxiliary/work/selenium/tool/微信图片_20200828101657.png b/src/test/java/pres/auxiliary/work/selenium/tool/微信图片_20200828101657.png
new file mode 100644
index 0000000..296c531
Binary files /dev/null and b/src/test/java/pres/auxiliary/work/selenium/tool/微信图片_20200828101657.png differ
diff --git a/src/test/java/pres/auxiliary/work/testcase/file/BasicTestCaseWriteTest.java b/src/test/java/pres/auxiliary/work/testcase/file/BasicTestCaseWriteTest.java
index 6242cc0..b0f3c3c 100644
--- a/src/test/java/pres/auxiliary/work/testcase/file/BasicTestCaseWriteTest.java
+++ b/src/test/java/pres/auxiliary/work/testcase/file/BasicTestCaseWriteTest.java
@@ -73,9 +73,7 @@ public class BasicTestCaseWriteTest {
public void openFolder() throws IOException {
wtc.writeFile();
System.out.println("----------------------------");
-// System.out.println("优先级:");
-// Arrays.stream(wtc.getRank()).forEach(System.out::println);
-// wtc.getCaseXml();
+ wtc.getCaseXml();
// java.awt.Desktop.getDesktop().open(wtc.getCaseXml());
java.awt.Desktop.getDesktop().open(tempFile.getParentFile());
java.awt.Desktop.getDesktop().open(tempFile);
diff --git a/src/test/java/pres/auxiliary/work/testcase/file/JiraTestCaseWriteTest.java b/src/test/java/pres/auxiliary/work/testcase/file/JiraTestCaseWriteTest.java
index fc0b732..d1bfd88 100644
--- a/src/test/java/pres/auxiliary/work/testcase/file/JiraTestCaseWriteTest.java
+++ b/src/test/java/pres/auxiliary/work/testcase/file/JiraTestCaseWriteTest.java
@@ -56,7 +56,7 @@ public class JiraTestCaseWriteTest {
wtc.writeFile();
System.out.println("----------------------------");
java.awt.Desktop.getDesktop().open(tempFile.getParentFile());
- java.awt.Desktop.getDesktop().open(tempFile);
+// java.awt.Desktop.getDesktop().open(tempFile);
}
@BeforeMethod
diff --git a/src/test/java/pres/auxiliary/work/testcase/用例xml文件.xml b/src/test/java/pres/auxiliary/work/testcase/用例xml文件.xml
new file mode 100644
index 0000000..decf45d
--- /dev/null
+++ b/src/test/java/pres/auxiliary/work/testcase/用例xml文件.xml
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/pres/readme/code/MyCase.java b/src/test/java/pres/readme/code/MyCase.java
deleted file mode 100644
index b78d7f4..0000000
--- a/src/test/java/pres/readme/code/MyCase.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package pres.readme.code;
-
-import java.io.File;
-
-import pres.auxiliary.work.testcase.templet.Case;
-import pres.auxiliary.work.testcase.templet.LabelType;
-
-public class MyCase extends Case {
-
- public MyCase(File configXmlFile) {
- super(configXmlFile);
- }
-
- /**
- * 用于生成app上浏览列表的测试用例
- * @return 类本身
- */
- public Case myCase1() {
- //清空字段的内容
- clearFieldText();
- // 存储case标签的name属性内容
- String caseName = "myTest001";
-
- //存储标题信息
- addFieldText(LabelType.TITLE, getLabelText(caseName, LabelType.TITLE, "1"));
-
- //添加步骤与预期
- relevanceAddData(caseName, ALL, ALL);
-
- //存储前置条件信息
- addFieldText(LabelType.PRECONDITION, getAllLabelText(caseName, LabelType.PRECONDITION));
-
- //存储关键词信息
- addFieldText(LabelType.KEY, getLabelText(caseName, LabelType.KEY, "1"));
- //存储优先级信息
- addFieldText(LabelType.RANK, getLabelText(caseName, LabelType.RANK, "1"));
-
- return this;
- }
-
- /**
- * 用于生成web上列表的测试用例
- * @return 类本身
- */
- public Case myCase2(String word) {
- //清空字段的内容
- clearFieldText();
- // 存储case标签的name属性内容
- String caseName = "myTest002";
-
- wordMap.put("词语", word);
- //存储标题信息
- addFieldText(LabelType.TITLE, getLabelText(caseName, LabelType.TITLE, "1"));
-
- //添加步骤与预期
- relevanceAddData(caseName, ALL, ALL);
-
- //存储前置条件信息
- addFieldText(LabelType.PRECONDITION, getAllLabelText(caseName, LabelType.PRECONDITION));
-
- //存储关键词信息
- addFieldText(LabelType.KEY, getLabelText(caseName, LabelType.KEY, "1"));
- //存储优先级信息
- addFieldText(LabelType.RANK, getLabelText(caseName, LabelType.RANK, "1"));
-
- return this;
- }
-
- /**
- * 用于生成web上列表的测试用例
- * @return 类本身
- */
- public Case myCase3() {
- //清空字段的内容
- clearFieldText();
- // 存储case标签的name属性内容
- String caseName = "myTest001";
-
- //添加替换词语
- wordMap.put("条件", "混合");
- //存储标题信息
- addFieldText(LabelType.TITLE, getLabelText(caseName, LabelType.TITLE, "1"));
-
- //添加步骤与预期
- relevanceAddData(caseName, ALL, ALL);
-
- //存储前置条件信息
- addFieldText(LabelType.PRECONDITION, getAllLabelText(caseName, LabelType.PRECONDITION));
-
- //存储关键词信息
- addFieldText(LabelType.KEY, getLabelText(caseName, LabelType.KEY, "1"));
- //存储优先级信息
- addFieldText(LabelType.RANK, getLabelText(caseName, LabelType.RANK, "1"));
-
- return this;
- }
-}
\ No newline at end of file
diff --git a/src/test/java/pres/readme/code/MyCase.xml b/src/test/java/pres/readme/code/MyCase.xml
new file mode 100644
index 0000000..e3cbfdf
--- /dev/null
+++ b/src/test/java/pres/readme/code/MyCase.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/pres/readme/code/TestWriteCase.java b/src/test/java/pres/readme/code/TestWriteCase.java
index 9fe68dc..974f34e 100644
--- a/src/test/java/pres/readme/code/TestWriteCase.java
+++ b/src/test/java/pres/readme/code/TestWriteCase.java
@@ -10,7 +10,6 @@ import org.testng.annotations.Test;
import pres.auxiliary.tool.file.excel.CreateExcelFile;
import pres.auxiliary.work.testcase.file.BasicTestCaseWrite;
-import pres.auxiliary.work.testcase.file.JiraTestCaseWrite.JiraFieldIdType;
import pres.auxiliary.work.testcase.templet.InformationCase;
import pres.auxiliary.work.testcase.templet.LabelType;
@@ -71,6 +70,7 @@ public class TestWriteCase {
@AfterClass
public void openFolder() throws IOException {
+ java.awt.Desktop.getDesktop().open(wtc.getCaseXml());
//将测试用例内容写入到文件中
wtc.writeFile();
}
@@ -79,5 +79,16 @@ public class TestWriteCase {
public void addCase() {
wtc.addCase(ic.addBasicTextboxCase("姓名", false, true, false)).end();
wtc.addCase(ic.addIdCardCase("身份证", true, false, false)).end();
+
+ wtc.setFieldValue("模块", "/测试项目/账号管理/创建账号2");
+ wtc.addCase(ic.addIdCardCase("护照号", true, false, false)).end();
+ }
+
+ @Test
+ public void myCaseTest() {
+ MyCase mc = new MyCase(new File("src/test/java/pres/readme/code/MyCase.xml"));
+ wtc.addCase(mc.myCase1()).end();
+ wtc.addCase(mc.myCase2("测试")).end();
+ wtc.addCase(mc.myCase3()).end();
}
}
diff --git a/src/test/java/test/javase/testResultFile.java b/src/test/java/test/javase/testResultFile.java
index 80bf6a8..9f12b26 100644
--- a/src/test/java/test/javase/testResultFile.java
+++ b/src/test/java/test/javase/testResultFile.java
@@ -1,10 +1,10 @@
package test.javase;
-import pres.auxiliary.work.selenium.tool.Log;
+import pres.auxiliary.work.selenium.tool.Log_Old;
public class testResultFile {
public static void main(String[] args) {
- Log trf = new Log();
+ Log_Old trf = new Log_Old();
trf.setSavePath("\\a");
}