diff --git a/ConfigurationFiles/SeleniumConfigurationFile/LogConfiguration/ExcelRecordTemplet.xml b/ConfigurationFiles/SeleniumConfigurationFile/LogConfiguration/ExcelRecordTemplet.xml index f1a8db6..1f27337 100644 --- a/ConfigurationFiles/SeleniumConfigurationFile/LogConfiguration/ExcelRecordTemplet.xml +++ b/ConfigurationFiles/SeleniumConfigurationFile/LogConfiguration/ExcelRecordTemplet.xml @@ -1,55 +1,43 @@ - - - + + - - + - + - + - - - - - + + + - - + + - - - - - - - + + + + + + - - - - - - - - - - - - + + + + + \ No newline at end of file diff --git a/Result/测试用例.xlsx b/Result/测试用例.xlsx new file mode 100644 index 0000000..ee0646e Binary files /dev/null and b/Result/测试用例.xlsx differ diff --git a/src/main/java/pres/auxiliary/tool/file/excel/AbstractWriteExcel.java b/src/main/java/pres/auxiliary/tool/file/excel/AbstractWriteExcel.java index 2695072..6a70873 100644 --- a/src/main/java/pres/auxiliary/tool/file/excel/AbstractWriteExcel.java +++ b/src/main/java/pres/auxiliary/tool/file/excel/AbstractWriteExcel.java @@ -3,6 +3,7 @@ package pres.auxiliary.tool.file.excel; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -18,6 +19,7 @@ import org.apache.poi.ss.usermodel.DataValidation; import org.apache.poi.ss.usermodel.DataValidationConstraint; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.xssf.usermodel.XSSFCell; @@ -37,8 +39,6 @@ import org.dom4j.io.SAXReader; import pres.auxiliary.tool.regex.RegexType; import pres.auxiliary.work.selenium.datadriven.ListFileRead; -import pres.auxiliary.work.selenium.xml.UndefinedElementException; -import pres.auxiliary.work.testcase.file.FieldType; import pres.auxiliary.work.testcase.file.IncorrectFileException; import pres.auxiliary.work.testcase.file.MarkColorsType; import pres.auxiliary.work.testcase.templet.LabelNotFoundException; @@ -54,7 +54,7 @@ import pres.auxiliary.work.testcase.templet.LabelNotFoundException; * 编码时间:2020年2月17日下午9:36:00 *

*

- * 修改时间:2020年8月12日 下午14:29:37 + * 修改时间:2020年8月22日 下午17:29:37 *

* * @author 彭宇琦 @@ -71,34 +71,39 @@ public abstract class AbstractWriteExcel> { /** * 用于对待替换词语的标记 */ - private final String WORD_SIGN = "\\#"; + protected final String WORD_SIGN = "\\#"; /** * 用于存储一条用例的信息,第一个参数指向配置文件中的字段id,第二个字段为xml文件中字段的相应信息 */ - protected HashMap fieldMap = new HashMap<>(16); -// protected HashMap> fieldMap = new HashMap<>(16); +// protected HashMap fieldMap = new HashMap<>(16); + protected HashMap> fieldMap = new HashMap<>(16); /** * 用于存储所有用例均使用的字段常值 */ - private HashMap constValueMap = new HashMap<>(16); -// private HashMap> constValueMap = new HashMap<>(16); +// private HashMap constValueMap = new HashMap<>(16); + protected HashMap> constValueMap = new HashMap<>(16); /** * 用于存储待替换的词语以及被替换的词语 */ - private HashMap replaceWordMap = new HashMap<>(16); + protected HashMap replaceWordMap = new HashMap<>(16); + + /** + * 用于存储当前用例中正在编写的 + */ + protected ArrayList writeSheetNameList = new ArrayList<>(); /** * 用于存储当前对应的sheet名称 */ - private String sheetName = ""; + protected String nowSheetName = ""; /** * 指向模板文件 */ - private File tempFile; + protected File tempFile; /** * 指向配置文件的Document对象 @@ -144,7 +149,8 @@ public abstract class AbstractWriteExcel> { } // 获取xml文件中的第一个sheet标签,则将该标签的name属性内容传入getColumnId中 - switchSheet(configXml.getRootElement().element("sheet").attributeValue("name")); +// switchSheet(configXml.getRootElement().element("sheet").attributeValue("name")); + getAllColumnId(); // 创建存储字段内容的document类对象 contentXml = DocumentHelper.createDocument(); @@ -159,25 +165,31 @@ public abstract class AbstractWriteExcel> { * * @param sheetName xml配置文件中sheet的name字段内容 */ - public void switchSheet(String sheetName) { + @SuppressWarnings("unchecked") + public T switchSheet(String sheetName) { // 每次切换sheet时,要重新获取一次sheet下的字段id。 // 切换sheet后需要清空预设字段中的内容 // 重新获取id,包括清空fieldMap - getColumnId(sheetName); +// getColumnId(sheetName); // 清空常值map - constValueMap.clear(); +// constValueMap.clear(); // 清空标记map // fieldMarkMap.clear(); // 清空预设字段枚举值 // Arrays.stream(FieldType.values()).forEach(e -> e.setValue("")); // 将相应的sheet标签的name属性存储至sheetName中 - this.sheetName = sheetName; + this.nowSheetName = sheetName; + if (!writeSheetNameList.contains(sheetName)) { + writeSheetNameList.add(sheetName); + } + + return (T) this; } /** - * 设置字段名称的常值,通过该设置,则之后该字段将直接填入设置的值,无需再次写入字段的值 + * 用于在当前指向的sheet中设置字段名称的常值,通过该设置,则之后该字段将直接填入设置的值,无需再次写入字段的值 * * @param field 字段id * @param content 相应字段的内容 @@ -185,15 +197,29 @@ public abstract class AbstractWriteExcel> { * @throws LabelNotFoundException 当在sheet标签中查不到相应的单元格id不存在时抛出的异常 */ public void setFieldValue(String field, String content) { - // 为保证在写用例的时候也能生效,故将值设置进入fieldMap - //为保证内容被重复添加,故需要清空原始内容 - clearContent(field); - addContent(field, content); - - // 先将值设置入fieldMap中可以保证field字段是存在于fieldMap中,以减少此处再做判断 - // 将字段内容写入caseValueMap - constValueMap.put(field, content); + setFieldValue(nowSheetName, field, content); } + + /** + * 用于在指定的sheet中设置字段名称的常值,通过该设置,则之后该字段将直接填入设置的值,无需再次写入字段的值 + * + * @param sheetName 指定的sheet名称 + * @param field 字段id + * @param content 相应字段的内容 + * + * @throws LabelNotFoundException 当在sheet标签中查不到相应的单元格id不存在时抛出的异常 + */ + public void setFieldValue(String sheetName, String field, String content) { + //若当前sheetName中不存在常量,则先构造HashMap + if (!constValueMap.containsKey(sheetName)) { + constValueMap.put(sheetName, new HashMap(16)); + } + + //添加常量 + constValueMap.get(sheetName).put(field, content); + } + + /** * 用于设置需要被替换的词语。添加词语时无需添加特殊字符 @@ -205,7 +231,7 @@ public abstract class AbstractWriteExcel> { word = WORD_SIGN + word + WORD_SIGN; replaceWordMap.put(word, replactWord); } - + /** * 通过传入的字段id,将对应的字段内容写入到用例最后的段落中,字段id对应xml配置文件中的单元格标签的id属性。 * 若需要使用替换的词语,则需要使用“#XX#”进行标记,如传参:
@@ -222,7 +248,7 @@ public abstract class AbstractWriteExcel> { * @throws LabelNotFoundException 当在sheet标签中查不到相应的单元格id不存在时抛出的异常 */ public T addContent(String field, String... contents) { - return insertContent(field, fieldMap.get(field).content.size(), contents); + return insertContent(field, -1, contents); } /** @@ -235,14 +261,14 @@ public abstract class AbstractWriteExcel> { @SuppressWarnings("unchecked") public T removeContent(String field, int...indexs) { // 判断字段是否存在,若不存在,则抛出异常 - if (!fieldMap.containsKey(field)) { + if (!fieldMap.get(nowSheetName).containsKey(field)) { throw new LabelNotFoundException("当前sheet不存在的标签id:" + field); } //移除相关的内容,若输入的序号不存在,则不进行 Arrays.stream(indexs).forEach(index -> { try { - fieldMap.get(field).content.remove(index); + fieldMap.get(nowSheetName).get(field).content.remove(index); } catch (Exception e) { } }); @@ -268,9 +294,15 @@ public abstract class AbstractWriteExcel> { */ @SuppressWarnings("unchecked") public T insertContent(String field, int index, String... contents) { + //若writeSheetNameList中未存储内容,则将当前的sheet名称存储到writeSheetNameList中, + //用于记录当前sheet有内容更新 + if (!writeSheetNameList.contains(nowSheetName)) { + writeSheetNameList.add(nowSheetName); + } + // 判断字段是否存在,若不存在,则抛出异常 - if (!fieldMap.containsKey(field)) { - throw new LabelNotFoundException("当前sheet不存在的标签id:" + field); + if (!fieldMap.get(nowSheetName).containsKey(field)) { + throw new LabelNotFoundException("当前“" + nowSheetName + "”sheet中不存在标签id:" + field); } //若未传值或传入null,则直接结束 @@ -278,21 +310,24 @@ public abstract class AbstractWriteExcel> { return (T) this; } - //若传入的下标大于相应的最大段落数时,则直接结束 - if (index > fieldMap.get(field).content.size()) { - return (T) this; - } + //还原下标 + /* + System.out.print(nowSheetName + " = "); + System.out.print(fieldMap.get(nowSheetName).get(field).name + " = "); + System.out.println(fieldMap.get(nowSheetName).get(field).content.size()); + */ + index = getPoiIndex(fieldMap.get(nowSheetName).get(field).content.size(), index); - if (fieldMap.get(field).datas.size() != 0) { + if (fieldMap.get(nowSheetName).get(field).datas.size() != 0) { //查找数据有效性,若当前字段存在数据有效性,则将数据有效性转义,若添加的字段无法转义,则存储原内容 - contents = dataValidityChange(contents, fieldMap.get(field)); + contents = dataValidityChange(contents, fieldMap.get(nowSheetName).get(field)); } // 查找特殊词语,并对词语进行替换 contents = replaceWord(contents); // 将字段内容写入fieldMap,若插入的下标不正确,则不做任何处理 try { - fieldMap.get(field).content.addAll(index, Arrays.asList(contents)); + fieldMap.get(nowSheetName).get(field).content.addAll(fieldMap.get(nowSheetName).get(field).content.size() == 0 ? 0 : index + 1, Arrays.asList(contents)); } catch (Exception e) { } @@ -314,7 +349,7 @@ public abstract class AbstractWriteExcel> { @SuppressWarnings("unchecked") public T replaceContent(String field, int index, String... contents) { // 判断字段是否存在,若不存在,则抛出异常 - if (!fieldMap.containsKey(field)) { + if (!fieldMap.get(nowSheetName).containsKey(field)) { throw new LabelNotFoundException("当前sheet不存在的标签id:" + field); } @@ -324,7 +359,7 @@ public abstract class AbstractWriteExcel> { } //若传入的下标大于相应的最大段落数时,则直接结束 - if (index >= fieldMap.get(field).content.size()) { + if (index >= fieldMap.get(nowSheetName).get(field).content.size()) { return (T) this; } @@ -345,11 +380,11 @@ public abstract class AbstractWriteExcel> { @SuppressWarnings("unchecked") public T clearContent(String field) { // 判断字段是否存在,若不存在,则抛出异常 - if (!fieldMap.containsKey(field)) { + if (!fieldMap.get(nowSheetName).containsKey(field)) { throw new LabelNotFoundException("当前sheet不存在的标签id:" + field); } - fieldMap.get(field).content.clear(); + fieldMap.get(nowSheetName).get(field).content.clear(); return (T) this; } @@ -357,64 +392,79 @@ public abstract class AbstractWriteExcel> { /** * 用于结束一条用例写作的标志,调用该方法后将结束一条用例的编写, 该方法以下的添加用例内容的方法均为编辑另一条用例 */ - @SuppressWarnings("unchecked") public FieldMark end() { - // 写入到caseXml中 - // 获取所有的sheet标签, 并筛选出name属性为sheetName的标签 - List sheetList = ((List) (contentXml.getRootElement().elements("sheet"))).stream() - .filter(e -> e.attributeValue("name").equals(sheetName)).collect(Collectors.toList()); - Element sheetElement = null; - // 判断是否存在sheet标签,若存在,则直接获筛选后的第一个数据,若不存在,则创建 - if (sheetList.size() != 0) { - sheetElement = sheetList.get(0); - } else { - sheetElement = contentXml.getRootElement().addElement("sheet").addAttribute("name", sheetName); + if (writeSheetNameList.isEmpty()) { + throw new IncorrectIndexException("当前不存在需要写入的sheet内容"); } - // 创建case标签 + //生成case标签的uuid String caseUuid = UUID.randomUUID().toString(); - Element caseElement = sheetElement.addElement("case").addAttribute("id", caseUuid); - // 为fieldMap中的所有key创建field标签,并记录相应的value - fieldMap.forEach((id, field) -> { - //判断字段是否需要进行编号,若需要编号,则调用编号方法 - if (field.serialNumber) { - addSerialNumber(field); - } - - // 添加field标签,并设置name属性(字段名称),mark属性(备注内容) - // dom4j当属性值传入null时,则直接不会创建该属性,故此处无需做判断字段id是否在fieldMarkMap中 - Element fieldElement = caseElement.addElement("field").addAttribute("name", id); - - //若字段上存在超链接,则在xml上加上超链接属性 + // 创建case标签 + writeSheetNameList.forEach(sheetName -> { + // 写入到caseXml中 + // 通过xpath查询到相应的sheet标签 + String finSheetXpath = "//sheet[@name='" + sheetName + "']"; + Element sheetElement = (Element) (contentXml.selectSingleNode(finSheetXpath)); /* - if (!field.link.isEmpty()) { - fieldElement.addAttribute("link", field.link); + for (Element element : ((List) (contentXml.getRootElement().elements("sheet")))) { + if (element.attributeValue("name").equals(sheetName)) { + sheetElement = element; + break; + } } */ - // 判断当前是否有添加内容,若未添加内容,则创建一个value属性为空的text标签 - if (field.content != null) { - // 读取所有texts(字符串数组)的所有内容,并为每一元素创建一个text标签,将值加入属性中 - field.content.forEach(text -> { - fieldElement.addElement("text").addAttribute("value", text); - }); - } else { - fieldElement.addElement("text").addAttribute("value", ""); + // 判断是否存在sheet标签,若不存在,则创建相应的标签 + if (sheetElement == null) { + sheetElement = contentXml.getRootElement().addElement("sheet").addAttribute("name", sheetName); } - }); - - // 清空fieldMap中的内容 - clearFieldContent(); - // 将字段常值设置入fieldMap中,若抛出异常,则不进行处理 - if (constValueMap != null && constValueMap.size() != 0) { - constValueMap.forEach((field, content) -> { - try { - addContent(field, content); - } catch (LabelNotFoundException e) { + + Element caseElement = sheetElement.addElement("case").addAttribute("id", caseUuid); + // 为fieldMap中的所有key创建field标签,并记录相应的value + fieldMap.get(sheetName).forEach((id, field) -> { + //判断字段是否需要进行编号,若需要编号,则调用编号方法 + if (field.serialNumber) { + addSerialNumber(field); + } + + // 添加field标签,并设置name属性(字段名称),mark属性(备注内容) + // dom4j当属性值传入null时,则直接不会创建该属性,故此处无需做判断字段id是否在fieldMarkMap中 + Element fieldElement = caseElement.addElement("field").addAttribute("id", id).addAttribute("name", field.name); + + // 判断当前是否有添加内容,若未添加内容,则创建一个value属性为空的text标签 + if (field.content != null && !field.content.isEmpty()) { + // 读取所有texts(字符串数组)的所有内容,并为每一元素创建一个text标签,将值加入属性中 + field.content.forEach(text -> { + fieldElement.addElement("text").addAttribute("value", text); + }); + } else { + //判断当前字段是否存在于constValueMap中,若存在,则填写constValueMap中的内容 + if (constValueMap != null && constValueMap.get(nowSheetName) != null && constValueMap.get(nowSheetName).containsKey(field.id)) { + //TODO 解决常值只能添加一个问题时需要修改此处代码 + fieldElement.addElement("text").addAttribute("value", dataValidityChange(new String[] {constValueMap.get(nowSheetName).get(field.id)}, field)[0]); + } else { + fieldElement.addElement("text").addAttribute("value", ""); + } } }); - } - + + // 清空fieldMap中的内容 + clearFieldContent(sheetName); + // 将字段常值设置入fieldMap中,若抛出异常,则不进行处理 + /* + if (constValueMap != null && constValueMap.size() != 0) { + constValueMap.get(nowSheetName).forEach((field, content) -> { + try { + addContent(field, content); + } catch (LabelNotFoundException e) { + } + }); + } + */ + }); + + //清空sheet写入记录 + writeSheetNameList.clear(); return new FieldMark(caseUuid); } @@ -473,9 +523,9 @@ public abstract class AbstractWriteExcel> { // 遍历所有的field标签,将标签的内容写入到文件中 for (Element fieldElement : fieldElements) { // 获取相应的Field对象 - String fieldId = fieldElement.attributeValue("name"); + String fieldId = fieldElement.attributeValue("id"); // 获取字段的field对象 - Field field = fieldMap.get(fieldId); + Field field = fieldMap.get(xs.getSheetName()).get(fieldId); // 获取text标签 List textList = fieldElement.elements("text"); @@ -485,9 +535,6 @@ public abstract class AbstractWriteExcel> { } else { writeSpecificField(xs, fieldElement, fieldId, field, textList, index); } - - //TODO 根据field中的link字段,添加超链接信息 - } } @@ -522,6 +569,8 @@ public abstract class AbstractWriteExcel> { // 将字段内容写入单元格 writeText(xc, textList); + //向单元格中添加超链接 + addLink(xc, fieldElement.attributeValue("link")); } /** @@ -568,6 +617,8 @@ public abstract class AbstractWriteExcel> { field.addDataValidation(xs, index, index); // 向单元格中添加Comment注解 addComment(xs, xc, fieldElement); + //向单元格中添加超链接 + addLink(xc, fieldElement.attributeValue("link")); // 存储裁剪后的text元素 ArrayList subTextList = new ArrayList(); @@ -589,10 +640,9 @@ public abstract class AbstractWriteExcel> { } /** - * 用于添加超链接内容 - * @param xc - * @param excel - * @param linkContent + * 用于根据超链接内容,向单元格中添加超链接 + * @param xc 单元格对象 + * @param linkContent 超链接内容(形式“超链接类型=超链接内容”) */ private void addLink(XSSFCell xc, String linkContent) { //若不存在链接内容,则不添加链接 @@ -600,72 +650,64 @@ public abstract class AbstractWriteExcel> { return; } + //获取分隔超链接类型与内容的符号位置 + int splitIndex = linkContent.indexOf("="); + //拆分读取到的超链接文本,以此分为超链接类型与超链接内容 + String linkTypeName = linkContent.substring(0, splitIndex); + String linkText = linkContent.substring(splitIndex + 1); + CreationHelper createHelper = xw.getCreationHelper(); XSSFHyperlink link = null; // 添加本地文件链接 - HyperlinkType hyperlinkType = getHyperlinkType(linkContent); + HyperlinkType hyperlinkType = getHyperlinkType(linkTypeName); link = (XSSFHyperlink) createHelper.createHyperlink(hyperlinkType); - //添加超链接,若添加超链接类型为DOCUMENT,则将链接文本进行转换后写入到链接中 - link.setAddress(hyperlinkType == HyperlinkType.DOCUMENT ? getDocumentLinkPath(linkContent) : linkContent); + //添加超链接 + link.setAddress(linkText); // 在单元格上添加超链接 xc.setHyperlink(link); // 新增单元格的样式 - CellStyleType.LINK_TEXT.getXSSFCellStyle(xc); +// CellStyleType.LINK_TEXT.getXSSFCellStyle(xc); + // 获取字体信息 + XSSFFont xf = xc.getCellStyle().getFont(); + // 添加下划线 + xf.setUnderline((byte) 1); + // 设置字体颜色为蓝色 + xf.setColor(IndexedColors.BLUE.getIndex()); } /** - * 用于根据链接内容,返回相应的超链接枚举({@link HyperlinkType}) - * @param linkContent 标签中link属性的内容 + * 用于根据链接类型名称,返回相应的超链接枚举({@link HyperlinkType}) + * @param linkTypeName 超链接类型名称 * @return 超链接枚举 */ - protected HyperlinkType getHyperlinkType(String linkContent) { - //根据链接内容,与相应的正则进行判断,根据结果,返回相应的HyperlinkType类 - if (RegexType.URL.judgeString(linkContent)) { - return HyperlinkType.URL; - } else if (RegexType.EMAIL.judgeString(linkContent)) { - return HyperlinkType.EMAIL; - } else if (RegexType.FOLDER_PATH.judgeString(linkContent)) { - return HyperlinkType.FILE; - } else { + protected HyperlinkType getHyperlinkType(String linkTypeName) { + LinkType linkType = null; + for (LinkType type : LinkType.values()) { + if (type.getName().equals(linkTypeName)) { + linkType = type; + } + } + + if (linkType == null) { + throw new NoSuchTypeException("错误的枚举名称:" + linkTypeName); + } + + switch (linkType) { + case DOMCUMENT: return HyperlinkType.DOCUMENT; + case EMAIL: + return HyperlinkType.EMAIL; + case FILE: + return HyperlinkType.FILE; + case URL: + return HyperlinkType.URL; + default: + return HyperlinkType.NONE; } } - /** - * 将xml文件中编写的文档内部超链接内容进行转换 - * @param linkContent 链接内容 - * @return 转换后的在poi使用的超链接代码 - */ - protected String getDocumentLinkPath(String linkContent) { - String[] linkContents = linkContent.split("|"); - int length = linkContents.length; - - //若切分后,其长度小于2位,则抛出异常 - if (length < 2) { - throw new IncorrectIndexException("文档内部链接编写错误,缺少分隔符“|”:" + linkContent); - } - - //获取超链接的sheet名称 - String linkSheetName = linkContents[0]; - //根据sheet名称以及字段id,获取该字段在sheet中的列数字下标,并将数字下标转换为英文下标 - String linkColumnIndex = num2CharIndex(getColumnNumIndex(linkSheetName, linkContents[1])); - - String linkRowIndex = ""; - //判断当前linkContents是否存在链接行数(即第三个元素)且链接的文本为数字 - //若符合规则,则将linkRowIndex设置为当前编写的内容 - //若不符合规则,则将linkRowIndex设置为当前sheet的最后一行 - if (length > 2 && linkContents[2].matches("[0-9]+")) { - linkRowIndex = linkContents[2]; - } else { - linkRowIndex = String.valueOf(xw.getSheet(linkSheetName).getLastRowNum()); - } - - //返回文档链接的内容 - return "'" + sheetName + "'!" + linkColumnIndex + linkRowIndex; - } - /** * 返回文本中字段对应的样式,可在该方法中添加字段需要添加的相应样式 * @@ -758,8 +800,10 @@ public abstract class AbstractWriteExcel> { /** * 清空fieldMap内的存储字段信息,不清除字段 */ - private void clearFieldContent() { - fieldMap.forEach((key, value) -> value.clearContent()); + private void clearFieldContent(String sheetName) { + fieldMap.get(sheetName).forEach((fieldId, field) -> { + field.clearContent(); + }); } /** @@ -768,43 +812,54 @@ public abstract class AbstractWriteExcel> { * @param sheetName sheet的name属性 */ @SuppressWarnings("unchecked") - private void getColumnId(String sheetName) { + private void getAllColumnId() { // 清空fieldMap中的内容 - fieldMap.clear(); +// fieldMap.clear(); // 获取相应的sheet标签元素 - Element sheetElement = (Element) (configXml.selectSingleNode("//sheet[@name='" + sheetName + "']")); - // 获取相应的sheet标签下的column标签 - List column = sheetElement.elements("column"); +// Element sheetElement = (Element) (configXml.selectSingleNode("//sheet[@name='" + sheetName + "']")); + configXml.getRootElement().elements("sheet").forEach(sheetElement -> { + // 获取相应的sheet标签下的column标签 + List column = ((Element) sheetElement).elements("column"); - // 初始化fieldMap中的字段及其值 - for (int index = 0; index < column.size(); index++) { - // 查找xml文件中数据有效性标签 - List datasList = sheetElement.elements("datas"); - ArrayList datas = new ArrayList(); - // 遍历所有的数据有效性标签,若存在,则存储相应的数据有效性 - for (Element datasElemenet : datasList) { - if (datasElemenet.attributeValue("id").equals(column.get(index).attributeValue("id"))) { - //存储当前的数据有效性的内容 - ((List)(datasElemenet.elements())).forEach(textElement -> { - //判断数据有效性的存放位置,并按照相应的方法读取数据有效性 - if ("file".equalsIgnoreCase(textElement.getName())) { - datas.addAll(getFileDataValidity(textElement)); - } else { - datas.add(getLabelDataValidity(textElement)); - } - }); - break; + // 初始化fieldMap中的字段及其值 + for (int index = 0; index < column.size(); index++) { + // 查找xml文件中数据有效性标签 + List datasList = ((Element) sheetElement).elements("datas"); + ArrayList datas = new ArrayList(); + // 遍历所有的数据有效性标签,若存在,则存储相应的数据有效性 + for (Element datasElemenet : datasList) { + if (datasElemenet.attributeValue("id").equals(column.get(index).attributeValue("id"))) { + //存储当前的数据有效性的内容 + ((List)(datasElemenet.elements())).forEach(textElement -> { + //判断数据有效性的存放位置,并按照相应的方法读取数据有效性 + if ("file".equalsIgnoreCase(textElement.getName())) { + datas.addAll(getFileDataValidity(textElement)); + } else { + datas.add(getLabelDataValidity(textElement)); + } + }); + break; + } } + + //若fieldMap中不存在sheetName,则添加相应的内容 + String sheetName = ((Element) sheetElement).attributeValue("name"); + if (!fieldMap.containsKey(sheetName)) { + fieldMap.put(sheetName, new HashMap(16)); + } + + nowSheetName = nowSheetName.isEmpty() ? sheetName : nowSheetName; + + // 存储字段信息 + fieldMap.get(sheetName).put(column.get(index).attributeValue("id"), + new Field(column.get(index).attributeValue("id"), + column.get(index).attributeValue("name"), + column.get(index).attributeValue("align"), index, + column.get(index).attributeValue("row_text"), datas, + Boolean.valueOf(column.get(index).attributeValue("index")))); } - - // 存储字段信息 - fieldMap.put(column.get(index).attributeValue("id"), - new Field(column.get(index).attributeValue("id"), column.get(index).attributeValue("align"), index, - column.get(index).attributeValue("row_text"), datas, - Boolean.valueOf(column.get(index).attributeValue("index")), - column.get(index).attributeValue("link"))); - } + }); } /** @@ -907,33 +962,6 @@ public abstract class AbstractWriteExcel> { } } - /** - * 用于根据xml配置文件中的标签元素下标,返回其在excel中对应的字母 - * @param sheetName sheet标签的name属性值 - * @param columenId columen标签的id属性值 - * @return 对应columen在excel中的列标字母 - */ - /* - protected String getColumn(String sheetName, String columenId) { - //根据sheet名称获取相应的sheet元素 - Element sheetElement = (Element) configXml.selectSingleNode("//sheet[@name='" + sheetName +"']"); - - //查找元素下所有column标签 - List columnElementList = sheetElement.elements("column"); - //遍历columnElementList,根据columenId反推对应的元素所在的下标 - int index = 0; - for (; index < columnElementList.size(); index++) { - if (((Element) columnElementList.get(index)).attributeValue("id").equals(columenId)) { - break; - } - } - - //根据下标,计算列表元素相应的字母,并以字符串的形式返回 - //A的ascii为65 - return String.valueOf((char) (65 + index)); - } - */ - /** * 用于根据xml文件中columenId字段所在的位置,推出字段在excel中的数字下标 * @param sheetName 字段所在的sheet名称 @@ -1020,12 +1048,28 @@ public abstract class AbstractWriteExcel> { return numberIndex; } + /** + * 用于将传入的下标转换为poi识别的下标,主要用于处理负数下标问题,以方便其他的方法的调用。 + * 若传入的下标大于总长度,则输出总长度-1,若负数的绝对值超过总长度,则输出0 + * @param length 总行数或总列数 + * @param index 传入的下标 + * @return 能被poi识别的下标 + */ + protected int getPoiIndex(int length, int index) { + //判断下标的绝对值是否大于总长度,若大于总长度,则根据index的正负来判断返回值 + if (Math.abs(index) >= length) { + return index > 0 ? length - 1 : 0; + } + + //若下标绝对值小于length,则判断下标正负,正数则直接返回,负数,则通过总长度 + //减去下标(由于下标是负数,故计算时用总长度加上下标) + return index < 0 ? length + index : index; + } + /** * 用于测试fieldMap中的内容,编码结束后删除 */ - /* - * public HashMap getCharMap() { return fieldMap; } - */ + public HashMap.Field>> getCharMap() { return fieldMap; } /** * 用于测试rank中的内容,编码结束后删除 @@ -1037,14 +1081,14 @@ public abstract class AbstractWriteExcel> { /** * 用于测试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 @@ + + + + + + + + + + + + + + </titles> + <preconditions> + <precondition id='1' value='myTest001_前置1' /> + <precondition id='2' value='myTest001_前置2' /> + </preconditions> + <ranks> + <rank id='1' value='myTest001_优先级1' /> + </ranks> + <keys> + <key id='1' value='myTest001_关键词1' /> + </keys> + </case> + + <case name='myTest002'> + <steps> + <step id='1' value='myTest002_步骤1_*{词语}*'/> + <step id='2' value='myTest002_步骤2'/> + <step id='3' value='myTest002_步骤3'/> + </steps> + <excepts> + <except id='1' value='myTest002_预期1'/> + </excepts> + <titles> + <title id='1' value='myTest002_标题1' /> + </titles> + <preconditions> + <precondition id='1' value='myTest002_前置1' /> + <precondition id='2' value='myTest002_前置2' /> + </preconditions> + <ranks> + <rank id='1' value='myTest002_优先级1' /> + </ranks> + <keys> + <key id='1' value='myTest002_关键词1' /> + </keys> + </case> +</cases> \ 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"); }