修改元素获取方式

This commit is contained in:
彭宇琦 2020-08-01 18:48:04 +08:00
parent 95790ae4d9
commit 34b01d4796
41 changed files with 1397 additions and 2758 deletions

16
pom.xml
View File

@ -102,6 +102,13 @@
<version>5.0.2</version>
</dependency>
<!-- 数据库连接依赖包 -->
<dependency>
<groupId>com.github.noraui</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
<!-- HttpClient 用于接口测试 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
@ -138,5 +145,14 @@
<version>1.9.5</version>
</dependency>
<!-- lombok注解生成get/set方法依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,38 +0,0 @@
package pres.auxiliary.directory.exception;
/**
* 该异常为传入的文件夹路径不正确时抛出的异常继承RuntimeException
* @author 彭宇琦
* @version Ver1.0
*/
public class IncorrectDirectoryException extends RuntimeException {
private static final long serialVersionUID = 1L;
public IncorrectDirectoryException() {
super();
// TODO Auto-generated constructor stub
}
public IncorrectDirectoryException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public IncorrectDirectoryException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public IncorrectDirectoryException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public IncorrectDirectoryException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}

View File

@ -1,38 +0,0 @@
package pres.auxiliary.directory.exception;
/**
* 该异常在未指定文件路径或者文件名时抛出的异常继承RuntimeException
*
* @author 彭宇琦
* @version Ver1.0
*/
public class UndefinedDirectoryException extends RuntimeException {
private static final long serialVersionUID = 1L;
public UndefinedDirectoryException() {
super();
// TODO Auto-generated constructor stub
}
public UndefinedDirectoryException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
}
public UndefinedDirectoryException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
public UndefinedDirectoryException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
public UndefinedDirectoryException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}
}

View File

@ -1,233 +0,0 @@
package pres.auxiliary.directory.operate;
import java.io.File;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
import pres.auxiliary.directory.processor.directoryprocessor.impprocessorinterface.AddSeparatorProcessor;
import pres.auxiliary.directory.processor.directoryprocessor.impprocessorinterface.FormatSeparatorProcessor;
import pres.auxiliary.directory.processor.directoryprocessor.impprocessorinterface.RelativeToAbsoluteProcessor;
import pres.auxiliary.directory.processor.directoryprocessor.processorchain.ProcessorChain;
/**
* 该类为创建文件工具类通过该类可辅助创建文件
*
* @author Administrator
*
*/
public class MakeDirectory {
// 该属性用于存储文件的路径字符串
private static StringBuilder savePath = new StringBuilder("C:\\AutoTest\\");
/**
* 私有构造禁止创建对象
*/
private MakeDirectory() {
}
/**
* 该方法用于返回文件定位的路径
*
* @return 返回在类中存储的文件路径
*/
public static String getSavePath() {
return savePath.toString();
}
/**
* 用于设置文件夹的根路径
*
* @param savePath
* 传入的新文件夹目录
*/
public static void setSavePath(String savePath) {
// 将传入的参数进行格式化
StringBuilder sb = new StringBuilder(savePath);
sb = formatPath(sb);
// 判断格式化后的文件路径格式是否符合windonws下文件路径的命名规则,不符合则抛出异常
if (!isPath(sb.toString())) {
System.out.println(sb.toString());
throw new IncorrectDirectoryException("不合理的文件夹路径,文件路径:"
+ sb.toString());
}
// 判断传入的路径是否只是硬盘的根目录若是则加上AutoTest文件夹
if (isDisk(sb.toString())) {
// 判断传入的硬盘根目录中是否包含文件夹分隔符\\若不包含则在后面加上
if (sb.indexOf("\\") < 0) {
sb.append("\\");
}
// 补上AutoTest文件夹
sb.append("AutoTest\\");
}
// 将文件路径设置入属性中
MakeDirectory.savePath = sb;
}
/**
* 该方法用于判断传入的路径输入是否正确
*
* @param path
* 传入的文件路径
* @return 返回路径是否正确
*/
public static boolean isPath(String path) {
// 判断path是否为空为空则返回false
if (path == null) {
return false;
}
// 判断path的内容是否为空为空则返回false
if ("".equals(path)) {
return false;
}
// 判断path中的内容是否为满足路径的要求不满足则返回false
// 可匹配相对路径和绝对路径
// 正则中只检测windows下创建文件夹或文件时不允许输入的字符
if (!path.matches("^([A-z]:\\\\)?([^ :\\*\\?<\">|\\/\\\\]+?(\\\\)?)*$")) {
return false;
}
// 若能满足上述条件则返回true
return true;
}
/**
* 该方法用于判断传入的参数是否符合在windows下文件名的命名规则不判断后缀名
*
* @param fileName
* 传入的待判断的文件夹名称
* @return 返回判断的结果
*/
public static boolean isFileName(String fileName) {
// 判断path是否为空为空则返回false
if (fileName == null) {
return false;
}
// 判断path的内容是否为空为空则返回false
if ("".equals(fileName)) {
return false;
}
// 通过正则判断文件名中是否包含windows不允许输入的特殊字符并匹配在传入的文件名中是否至少包含一个.若符合正则则返回true
if (fileName.matches("^([^:\\*\\?<\">|\\/\\\\])+?$")) {
return true;
}
// 若未通过判断则返回false
return false;
}
/**
* 该方法用于判断路径是否是硬盘的根目录
*
* @param path
* 传入的路径
* @return 返回判断的结果
*/
public static boolean isDisk(String path) {
// 判断path是否为空为空则返回false
if (path == null) {
return false;
}
// 判断path的内容是否为空为空则返回false
if ("".equals(path)) {
return false;
}
// 匹配只有盘符时的正则
if (path.matches("^[A-z]:(\\\\)?$")) {
return true;
}
// 若未通过判断则返回false
return false;
}
/**
* 该方法将对传入文件路径进行三种处理
* <ol>
* <li>将所有的分隔符/改为\\</li>
* <li>末尾未添加分隔符的加上\\</li>
* <li>将传入的相对路径改为绝对路径</li>
* </ol>
*
* @param path
* 传入的文件路径为StringBuilder对象
* @return 返回格式化后的路径为StringBuilder对象
*/
public static StringBuilder formatPath(StringBuilder path) {
// 创建处理链
ProcessorChain pc = new ProcessorChain();
// 添加处理器
pc.add(new FormatSeparatorProcessor());
pc.add(new RelativeToAbsoluteProcessor());
pc.add(new AddSeparatorProcessor());
// 返回格式化后的路径
return pc.doProcessor(path, pc);
}
/**
* 该方法用于创建使用辅助包时需要创建的文件夹
*/
public static void createAllFolder() {
// TODO 创建日志文件
// 创建文件夹先判断文件夹是否已被创建未被创建则创建文件夹
// 创建根文件夹
File f = new File(savePath.toString());
if (!f.exists()) {
f.mkdir();
}
// 创建存放测试报告的文件夹
f = new File(savePath.toString() + "Report");
if (!f.exists()) {
f.mkdir();
}
// 创建存放Bug汇总表的文件夹
f = new File(savePath.toString() + "BugSummarySheet");
if (!f.exists()) {
f.mkdir();
}
// 创建存放自动化运行结果的文件夹
f = new File(savePath.toString() + "Selenium");
if (!f.exists()) {
f.mkdir();
}
// 创建存放自动化运行结果截图的文件夹
f = new File(savePath.toString() + "Selenium\\Screenshot");
if (!f.exists()) {
f.mkdir();
}
// 创建存放自动化运行结果日志的文件夹
f = new File(savePath.toString() + "Selenium\\Log");
if (!f.exists()) {
f.mkdir();
}
// 创建存放待测页面定位方式的xml文件的文件夹
f = new File(savePath.toString() + "Xml");
if (!f.exists()) {
f.mkdir();
}
// 创建存放生成的测试用例文件的文件夹
f = new File(savePath.toString() + "Case");
if (!f.exists()) {
f.mkdir();
}
// 创建存放浏览器下载的文件的文件夹
f = new File(savePath.toString() + "BrowersDownload");
if (!f.exists()) {
f.mkdir();
}
}
}

View File

@ -1,29 +0,0 @@
package pres.auxiliary.directory.processor.directoryprocessor.impprocessorinterface;
import pres.auxiliary.directory.processor.directoryprocessor.processorchain.ProcessorChain;
import pres.auxiliary.directory.processor.directoryprocessor.processorinterface.ProcessorInterface;
/**
* 该处理器用于判断路径末尾是否含有分隔符\\若不包含则添加上
* @author 彭宇琦
* @version Ver1.0
*/
public class AddSeparatorProcessor implements ProcessorInterface {
@Override
public StringBuilder doProcessor(StringBuilder path, ProcessorChain chain) {
// 判断字符串的最后一位是否为含分隔符若不为分隔符则说明路径末尾没有分隔符则说明文件路径的末尾不含\\需要再添加
if (path.lastIndexOf("\\") != (path.length() - 1)) {
path.append("\\");
}
chain.doProcessor(path, chain);
// 返回文件路径
return path;
}
@Override
public String toString() {
return "AddSeparatorProcessor";
}
}

View File

@ -1,46 +0,0 @@
package pres.auxiliary.directory.processor.directoryprocessor.impprocessorinterface;
import pres.auxiliary.directory.processor.directoryprocessor.processorchain.ProcessorChain;
import pres.auxiliary.directory.processor.directoryprocessor.processorinterface.ProcessorInterface;
/**
* 该类用于对传入的文件路径进行文件夹分隔符格式化的处理处理的方法是将所有的分隔符/改为\\
*
* @author 彭宇琦
* @version Ver1.0
*/
public class FormatSeparatorProcessor implements ProcessorInterface {
@Override
public StringBuilder doProcessor(StringBuilder path, ProcessorChain chain) {
// 用于存储循环查询字符串得到的下标
int i = 0;
// 循环查询path中的/并将/字符改为\\
while (true) {
// 判断字符串查询到的字符串是否为/若为/则修改
if ((i = path.indexOf("/")) > -1) {
// 删除当前字符
path.delete(i, i + 1);
// 将字符\\插入到删除的位置由于需要转译\\在存储时应为\\\\
path.insert(i, "\\");
// 继续循环
continue;
}
// 若未找到字符/则结束循环
break;
}
chain.doProcessor(path, chain);
// 返回格式化后的路径
return path;
}
@Override
public String toString() {
return "FormatSeparatorProcessor";
}
}

View File

@ -1,31 +0,0 @@
package pres.auxiliary.directory.processor.directoryprocessor.impprocessorinterface;
import pres.auxiliary.directory.processor.directoryprocessor.processorchain.ProcessorChain;
import pres.auxiliary.directory.processor.directoryprocessor.processorinterface.ProcessorInterface;
/**
* 该处理器用于将相对路径改为绝对路径判断相对路径的依据是路径中是否包含字符:
* 相对路径中不可能还含有字符:windows下不允许创建带:的字符故若路径
* 中含有:则说明路径为绝对路径<br/><br/>
* <i><b>注意使用该处理器时需要保证相对路径的命名正确</b></i>
* @author 彭宇琦
* @version Ver1.0
*/
public class RelativeToAbsoluteProcessor implements ProcessorInterface {
@Override
public StringBuilder doProcessor(StringBuilder path, ProcessorChain chain) {
// 判断传入的路径是绝对路径还是相对路径若是相对路径则在相对路径前加上当前位置
if (path.indexOf(":") < 0) {
path.insert(0, (System.getProperty("user.dir") + "\\"));
}
chain.doProcessor(path, chain);
return path;
}
@Override
public String toString() {
return "RelativeToAbsoluteProcessor";
}
}

View File

@ -1,171 +0,0 @@
package pres.auxiliary.directory.processor.directoryprocessor.processorchain;
import java.util.ArrayList;
import java.util.List;
import pres.auxiliary.directory.processor.directoryprocessor.processorchain.ProcessorChain;
import pres.auxiliary.directory.processor.directoryprocessor.processorinterface.ProcessorInterface;
public class ProcessorChain implements ProcessorInterface {
//用于存储处理方法的类对象
private List<ProcessorInterface> processorChain = new ArrayList<>();
//用于记录调用的处理器在processorChain中的下标
private int index = -1;
/**
* 该构造方法不做任何处理
*/
public ProcessorChain() {
}
/**
* 该构造方法用于向处理链中添加一条或多条处理器
* @param processor 待添加的处理器
*/
public ProcessorChain(ProcessorInterface... processor) {
//循环向集合中添加处理器
for ( ProcessorInterface p : processor ) {
add(p);
}
}
/**
* 该方法用于向处理器链末尾添加一个处理器
* @param processor 待添加的处理器
* @return 返回添加状态
*/
public boolean add(ProcessorInterface processor) {
return processorChain.add(processor);
}
/**
* 该方法用于向处理器链指定位置添加一个处理器
* @param index 指定的处理器链位置
* @param processor 待添加的处理器
*/
public void add(int index, ProcessorInterface processor) {
processorChain.add(index, processor);
}
/**
* 该方法用于向处理器链末尾添加一组处理器
* @param processors 待添加的处理器组
* @return 返回添加状态
*/
public boolean addAll(List<ProcessorInterface> processors) {
return processorChain.addAll(processors);
}
/**
* 该方法用于向处理器链指定位置添加一组处理器
* @param index 指定的处理器链位置
* @param processors 待添加的处理器组
* @return 返回添加状态
*/
public boolean addAll(int index, List<ProcessorInterface> processors) {
return processorChain.addAll(index, processors);
}
/**
* 该方法用于移除指定位置的处理器
* @param index 指定的位置
* @return 返回被移除的处理器
*/
public ProcessorInterface remove(int index) {
return processorChain.remove(index);
}
/**
* 该方法用于移除指定的处理器
* @param processor 指定的处理器
* @return 返回被移除的处理器
*/
public boolean remove(ProcessorInterface processor) {
return processorChain.remove(processor);
}
/**
* 该方法用于返回指定位置的处理器
* @param index 指定的处理器位置
* @return 返回对应位置的处理器
*/
public ProcessorInterface get(int index) {
return processorChain.get(index);
}
/**
* 该方法用于替换指定位置的处理器
* @param index 指定的处理器位置
* @param processor 待替换的处理器
* @return 返回原处理器
*/
public ProcessorInterface set(int index, ProcessorInterface processor) {
return processorChain.set(index, processor);
}
/**
* 该方法用于返回处理链的长度
* @return 处理链的长度
*/
public int size() {
return processorChain.size();
}
/**
* 该方法通过传入的处理器名称来查找处理链中是否存在该处理器存在则返回对应
* 的下标不存在则返回-1调用该方法时需要处理器重写的toString()方法是输出类名的
* @param processorName 待搜索的处理器名称
* @return 对应的下标或者-1
*/
public int indexOf(String processorName) {
//循环遍历数组
for (int i = 0; i < processorChain.size(); i++) {
//判断每一个元素的toSting()方法得到的字符串是否存在与传入的参数相同忽略大小写若有相同则返回相应的下标
if ( processorChain.get(i).toString().equalsIgnoreCase(processorName) ) {
return i;
}
}
//循环结束则表示未找到对应的处理器则返回-1
return -1;
}
/**
* 该方法通过传入处理器类对象来来查找处理链中是否存在该处理器存在则返回对应的下标不存在则返回-1
* @param processor 传入的处理器类对象
* @return 对应的下标或者-1
*/
public int indexOf(ProcessorInterface processor) {
return processorChain.indexOf(processor);
}
/**
* 用于对所有的处理器进行处理
* @param 传入的文件路径
* @return 返回处理后的路径
*/
@Override
public StringBuilder doProcessor(StringBuilder path, ProcessorChain chain) {
//下标向前移动
index++;
if ( index == chain.size() ) {
return null;
}
//调用处理器的doProcessor()对象
processorChain.get(index).doProcessor(path, chain);
//返回处理后的文件路径
return path;
}
@Override
public String toString() {
StringBuilder s = new StringBuilder("ProcessorChain [ ");
for ( ProcessorInterface p : processorChain ) {
s.append(p.toString());
s.append(" ");
}
s.append("]");
return s.toString();
}
}

View File

@ -1,26 +0,0 @@
package pres.auxiliary.directory.processor.directoryprocessor.processorinterface;
import pres.auxiliary.directory.processor.directoryprocessor.processorchain.ProcessorChain;
/**
* 该接口定义处理传入的文件路径的方法
*
* @author 彭宇琦
* @version Ver1.0
*/
public interface ProcessorInterface {
/**
* 该方法用于处理传入的文件路径
*
* @param path
* 指定的文件路径
* @return 返回处理后的文件路径
*/
public abstract StringBuilder doProcessor(StringBuilder path, ProcessorChain chain);
/**
* 重写toString()方法用于输出类名
* */
@Override
public abstract String toString();
}

View File

@ -70,9 +70,6 @@ import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.opencsv.CSVReader;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
import pres.auxiliary.directory.operate.MakeDirectory;
/**
* 该类用于定义生成测试报告类共用的方法
*

View File

@ -38,7 +38,6 @@ import org.dom4j.io.XMLWriter;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import pres.auxiliary.directory.exception.UndefinedDirectoryException;
import pres.auxiliary.work.selenium.xml.ByType;
import pres.auxiliary.work.selenium.xml.ReadXml;

View File

@ -70,7 +70,7 @@ public class EasyResponse {
//转换为JSONObject格式若不能转换则responseJson为null
try {
responseJson = JSONObject.parseObject(responseText);
responseJson = JSON.parseObject(responseText);
responseType = ResponseType.JSON;
} catch (JSONException jsonException) {
//设置responseJson为null

View File

@ -1,5 +1,6 @@
package pres.auxiliary.tool.randomstring;
import java.util.ArrayList;
import java.util.Random;
/**
@ -109,7 +110,7 @@ public class PresetString {
*
* @return 生成的身份证号码
*/
public static String IdentityCard() {
public static String identityCard() {
StringBuilder sb = new StringBuilder();
RandomString rs = new RandomString("123456789");
@ -120,7 +121,7 @@ public class PresetString {
//区县
String[] county = {"01", "02", "03", "04", "05"};
//生日年份前两位
int[] year = {19, 18};
int[] year = {19};
//加权数
int[] factors = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
@ -192,8 +193,19 @@ public class PresetString {
}
}
private static String getMobleNumber(MobleNumberType mobleNumberType) {
/**
* 根据运营商生成相应运营商号段的随机号码
* @param mobleNumberType 运营商号段枚举
* @return 相应运营商的随机号码
*/
public static String mobleNumber(MobleNumberType mobleNumberType) {
RandomString rs = new RandomString(StringMode.NUM);
ArrayList<String> regexList = mobleNumberType.getRegex();
//根据运营商号码开头规则随机选择一个号段
String regex = regexList.get(new Random().nextInt(regexList.size()));
//再根据号段的长度生成相应位数的尾号
return regex + rs.toString(11 - regex.length());
}
}

View File

@ -1,272 +0,0 @@
package pres.auxiliary.work.easycode.event;
import java.io.File;
import org.openqa.selenium.WebDriver;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.CommonBy;
import pres.auxiliary.work.selenium.element.DataListBy;
import pres.auxiliary.work.selenium.element.SelectBy;
import pres.auxiliary.work.selenium.event.ClickEvent;
import pres.auxiliary.work.selenium.event.TextEvent;
public class Event {
/**
* 用于进行单一元素获取
*/
private CommonBy commonBy;
/**
* 用于进行选项元素获取
*/
private SelectBy selectBy;
/**
* 用于进行点击事件
*/
private ClickEvent clickEvent;
/**
* 用于进行文本事件
*/
private TextEvent textEvent;
/**
* 用于执行当前需要切换的xml文件对象
*/
private File xmlFile;
/**
* 用于指向是否需要切换到顶层
*/
private boolean isBreakRootFrame;
/**
* 存储WebDriver对象
*/
private WebDriver driver;
/**
* 初始化{@link WebDriver}对象
* @param driver {@link WebDriver}对象
*/
public Event(WebDriver driver) {
//初始化元素获取类
commonBy = new CommonBy(driver);
selectBy = new SelectBy(driver);
//初始化元素操作类
clickEvent = new ClickEvent(driver);
textEvent = new TextEvent(driver);
}
/**
* 通过{@link AbstractBrower}对象初始化{@link WebDriver}对象
* @param brower {@link AbstractBrower}对象
*/
public Event(AbstractBrower brower) {
this(brower.getDriver());
}
/**
* 用于切换相应的xml文件
* @param xmlFile xml文件对象
* @param isBreakRootFrame 是否切换回到顶层
*/
public void switchXmlFile(File xmlFile, boolean isBreakRootFrame) {
commonBy.setXmlFile(xmlFile, isBreakRootFrame);
selectBy.setXmlFile(xmlFile, isBreakRootFrame);
this.xmlFile = xmlFile;
this.isBreakRootFrame = isBreakRootFrame;
}
/**
* 用于根据元素名称对单一元素进行点击事件
* @param name 元素名称
* @param keys 需要替换的定位方式内容的关键词
*/
public void click(String name, String...keys) {
clickEvent.click(commonBy.getElement(name, keys));
}
/**
* 用于根据元素名称对列表元素进行点击事件
* @param name 元素名称
* @param index 元素所在下标
* @param keys 需要替换的定位方式内容的关键词
*/
public void click(String name, int index, String...keys) {
DataListBy dataListBy = new DataListBy(driver);
dataListBy.setXmlFile(xmlFile, isBreakRootFrame);
dataListBy.add(name, keys);
clickEvent.click(dataListBy.getElement(name, index));
}
/**
* 用于根据元素名称对单一元素进行双击事件
* @param name 元素名称
* @param keys 需要替换的定位方式内容的关键词
*/
public void doubleClick(String name, String...keys) {
clickEvent.doubleClick(commonBy.getElement(name));
}
/**
* 用于根据元素名称对列表元素进行双击事件
* @param name 元素名称
* @param index 元素所在下标
* @param keys 需要替换的定位方式内容的关键词
*/
public void doubleClick(String name, int index, String...keys) {
DataListBy dataListBy = new DataListBy(driver);
dataListBy.setXmlFile(xmlFile, isBreakRootFrame);
dataListBy.add(name, keys);
clickEvent.doubleClick(dataListBy.getElement(name, index));
}
/**
* 用于根据元素名称对单一元素进行右击事件
* @param name 元素名称
* @param keys 需要替换的定位方式内容的关键词
*/
public void rightClick(String name, String...keys) {
clickEvent.rightClick(commonBy.getElement(name));
}
/**
* 用于根据元素名称对列表元素进行右击事件
* @param name 元素名称
* @param index 元素所在下标
* @param keys 需要替换的定位方式内容的关键词
*/
public void rightClick(String name, int index, String...keys) {
DataListBy dataListBy = new DataListBy(driver);
dataListBy.setXmlFile(xmlFile, isBreakRootFrame);
dataListBy.add(name, keys);
clickEvent.rightClick(dataListBy.getElement(name, index));
}
/**
* 用于根据元素名称对单一元素进行连续点击事件
* @param name 元素名称
* @param clickCount 点击次数
* @param sleepInMillis 操作时间间隔单位为毫秒
* @param keys 需要替换的定位方式内容的关键词
*/
public void continuousClick(String name, int clickCount, long sleepInMillis, String...keys) {
clickEvent.continuousClick(commonBy.getElement(name), clickCount, sleepInMillis);
}
/**
* 用于根据元素名称对列表元素进行连续点击事件
* @param name 元素名称
* @param clickCount 点击次数
* @param sleepInMillis 操作时间间隔单位为毫秒
* @param index 元素所在下标
* @param keys 需要替换的定位方式内容的关键词
*/
public void continuousClick(String name, int index, int clickCount, long sleepInMillis, String...keys) {
DataListBy dataListBy = new DataListBy(driver);
dataListBy.setXmlFile(xmlFile, isBreakRootFrame);
dataListBy.add(name, keys);
clickEvent.continuousClick(dataListBy.getElement(name, index), clickCount, sleepInMillis);
}
/**
* 用于根据控件名称清除单一控件的内容
* @param name 控件名称
* @param keys 需要替换的定位方式内容的关键词
* @return 被清除的内容
*/
public String clear(String name, String...keys) {
return textEvent.clear(commonBy.getElement(name));
}
/**
* 用于根据控件名称清除列表控件的内容
* @param name 控件名称
* @param index 元素所在下标
* @param keys 需要替换的定位方式内容的关键词
* @return 被清除的内容
*/
public String clear(String name, int index, String...keys) {
DataListBy dataListBy = new DataListBy(driver);
dataListBy.setXmlFile(xmlFile, isBreakRootFrame);
dataListBy.add(name, keys);
return textEvent.clear(dataListBy.getElement(name, index));
}
/**
* 用于根据控件名称获取单一控件指定属性的内容
* @param name 控件名称
* @param attributeName 属性名称
* @param keys 需要替换的定位方式内容的关键词
* @return 控件属性的内容
*/
public String getAttributeValue(String name, String attributeName, String...keys) {
return textEvent.getAttributeValue(commonBy.getElement(name), attributeName);
}
/**
* 用于根据控件名称获取列表控件指定属性的内容
* @param name 控件名称
* @param index 元素所在下标
* @param attributeName 属性名称
* @param keys 需要替换的定位方式内容的关键词
* @return 控件属性的内容
*/
public String getAttributeValue(String name, int index, String attributeName, String...keys) {
DataListBy dataListBy = new DataListBy(driver);
dataListBy.setXmlFile(xmlFile, isBreakRootFrame);
dataListBy.add(name, keys);
return textEvent.getAttributeValue(dataListBy.getElement(name, index), attributeName);
}
/**
* 用于根据控件名称获取单一控件的内容
* @param name 控件名称
* @param keys 需要替换的定位方式内容的关键词
* @return 控件的内容
*/
public String getText(String name, String...keys) {
return textEvent.getText(commonBy.getElement(name));
}
/**
* 用于根据控件名称获取列表控件的内容
* @param name 控件名称
* @param index 元素所在下标
* @param keys 需要替换的定位方式内容的关键词
* @return 控件的内容
*/
public String getText(String name, int index, String...keys) {
DataListBy dataListBy = new DataListBy(driver);
dataListBy.setXmlFile(xmlFile, isBreakRootFrame);
dataListBy.add(name, keys);
return textEvent.getText(dataListBy.getElement(name, index));
}
/**
* 用于根据控件名称对单一控件进行输入
* @param name 控件名称
* @param text 输入的内容
* @param keys 需要替换的定位方式内容的关键词
* @return 输入到控件的内容
*/
public String input(String name, String text, String...keys) {
return textEvent.input(commonBy.getElement(name), text);
}
/**
* 用于根据控件名称获取列表控件的内容
* @param name 控件名称
* @param index 元素所在下标
* @param text 输入的内容
* @param keys 需要替换的定位方式内容的关键词
* @return 输入到控件的内容
*/
public String input(String name, int index, String text, String...keys) {
DataListBy dataListBy = new DataListBy(driver);
dataListBy.setXmlFile(xmlFile, isBreakRootFrame);
dataListBy.add(name, keys);
return textEvent.input(dataListBy.getElement(name, index), text);
}
}

View File

@ -29,9 +29,6 @@ import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
import pres.auxiliary.directory.operate.MakeDirectory;
/**
* 该类用于向指定的路径下生成用于上传至禅道上的测试用例模版目前实现已基本模拟从禅道专业版上导出的
* 模版文件用户从禅道开源版导出csv的模块数据后通过类中存储的方法可实现向模块项与需求项中添加数据有效性

View File

@ -22,7 +22,6 @@ import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import pres.auxiliary.directory.exception.UndefinedDirectoryException;
import pres.auxiliary.work.old.testcase.change.CaseTab;
import pres.auxiliary.work.old.testcase.change.Tab;
import pres.auxiliary.work.old.testcase.templet.ZentaoExcel;

View File

@ -3,6 +3,7 @@ package pres.auxiliary.work.selenium.brower;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -36,6 +37,8 @@ public abstract class AbstractBrower {
* 存储打开的页面
*/
HashMap<String, Page> pageMap = new HashMap<String, Page>(16);
HashSet<String> windowHandleSet = new HashSet<>();
/**
* 用于存储WebDriver当前指向的页面信息
@ -162,7 +165,9 @@ public abstract class AbstractBrower {
overridePage();
}
}
//存储当前打开窗口的handle
windowHandleSet.add(nowPage.getHandle());
// 切换至相应的窗口
driver.switchTo().window(nowPage.getHandle());
}
@ -220,6 +225,14 @@ public abstract class AbstractBrower {
return pageList;
}
/**
* 用于返回当前指向的窗体打开的页面{@link Page}对象
* @return {@link Page}对象
*/
public Page getNowPage() {
return nowPage;
}
/**
* 用于重启浏览器若未生成WebDriver对象时即未调用{@link #getDriver()}方法时则方法调用无效
@ -296,11 +309,13 @@ public abstract class AbstractBrower {
public void switchWindow(String pageName) {
try {
driver.switchTo().window(findPageHandle(pageName));
//切换当前指向的页面
nowPage = pageMap.get(pageName);
} catch (NoSuchWindowException e) {
throw new IncorrectPageException("页面未在浏览器中打开");
}
}
/**
* 用于根据页面切换页面
*
@ -311,14 +326,14 @@ public abstract class AbstractBrower {
if (pageMap.containsKey(page.getPageName())) {
try {
driver.switchTo().window(page.getHandle());
//切换当前指向的页面
nowPage = page;
} catch (NoSuchWindowException e) {
throw new IncorrectPageException("页面未在浏览器中打开");
}
}
}
/**
* 用于切换到当前页面
*/
@ -328,7 +343,100 @@ public abstract class AbstractBrower {
switchWindow(nowPage);
}
}
/**
* 用于切换到弹窗上当浏览器存在多个弹窗时该方法无法保证能切换至理想的窗口
* 但调用该方法后其弹窗会作为{@link Page}类对象进行存储其页面名称为当前窗口的
* handle值若切换的窗口非理想的窗口则可以多次调用该方法直至切换至理想的窗口
* 为止若当前不存在弹窗则返回false若切换弹窗成功则返回true
*
* @return 是否成功切换弹窗
*/
public boolean switchPopuWindow() {
//判断当前是否存在弹窗若不存在则直接失败
if (!hasPopuWindow()) {
return false;
}
//若存在弹窗则获取获取当前所有窗口的handle获取其中一个弹窗的handle值进行存储
String popuHandle = getPopuHandle(driver.getWindowHandles());
//切换弹窗
driver.switchTo().window(popuHandle);
//将弹窗转换为Page类对象存储至pageMap中以避免存在多个弹窗时其他弹窗无法被切换的情况
Page popuPage = new Page(driver.getCurrentUrl(), popuHandle);
popuPage.setHandle(popuHandle);
popuPage.setAssertTitle(driver.getTitle());
//存储弹窗
pageMap.put(popuHandle, popuPage);
//将当前页面指向到弹窗页面上
nowPage = popuPage;
//返回切换弹窗成功
return true;
}
/**
* 用于判断当前浏览器中是否存在弹窗未被存储的浏览器标签注意若在
* 浏览器上自行打开的标签其也会被计算为弹窗
* @return 是否存在弹窗
*/
public boolean hasPopuWindow() {
//获取当前浏览器上的窗口handle
Set<String> nowWindowHandleSet = driver.getWindowHandles();
//移除被手动关闭的标签
removeClosePage(nowWindowHandleSet);
//若nowWindowHandleSet中的数量与windowHandleSet不一致则可认为存在弹窗
return nowWindowHandleSet.size() != windowHandleSet.size();
}
/**
* 定位到弹框上并且点击确定按钮并返回弹框上的文本
*
* @return 弹框上的文本
*/
public String alertAccept() {
String text = alertGetText();
driver.switchTo().alert().accept();
return text;
}
/**
* 定位到弹框上并且点击取消按钮并返回弹框上的文本
*
* @return 弹框上的文本
*/
public String alertDimiss() {
String text = alertGetText();
driver.switchTo().alert().dismiss();
return text;
}
/**
* 定位到弹框上并且在其文本框中输入信息
*
* @param content 需要输入的信息
* @return 弹框上的文本
*/
public String alertInput(String content) {
String text = alertGetText();
driver.switchTo().alert().sendKeys("");
return text;
}
/**
* 获取弹框上的文本
*
* @return 弹框上的文本
*/
public String alertGetText() {
return driver.switchTo().alert().getText();
}
/**
* 用于新增一个标签页并打开指定站点
*
@ -373,7 +481,7 @@ public abstract class AbstractBrower {
break;
}
}
return newHandle;
}
@ -423,4 +531,33 @@ public abstract class AbstractBrower {
// 若类中未存储相应page则返回null
return null;
}
/**
* 用于在pageMap中移除已被关闭的浏览器标签该方法主要用于清除手动关闭的标签
* @param handleList 当前浏览器存储的标签值
*/
private void removeClosePage(Set<String> handleList) {
ArrayList<String> removeKeyList = new ArrayList<>();
//遍历pageMap若其handle值不存在于handleList中则记录需要移除的key值
pageMap.forEach((key, value) -> {
if (!handleList.contains(value.getHandle())) {
removeKeyList.add(key);
}
});
//遍历removeKeyList在pageMap中移除相应的key
removeKeyList.forEach(key -> {
pageMap.remove(key);
});
}
/**
* 用于返回当前浏览器中其中一个弹窗的handle值当存在多个弹窗时
* 该方法不保证返回的handle为理想的handle值
* @param handleList 当前浏览器中所有的窗口handle集合
* @return 其中一个弹窗的handle值
*/
private String getPopuHandle(Set<String> handleSet) {
return handleSet.stream().filter(handle -> findPage(handle) == null).findAny().get();
}
}

View File

@ -110,10 +110,12 @@ public class SelectBy extends MultiBy {
* @param fristIsEmpty 首个选项是否为不可选择的选项或者文本为空的选项
* @see #add(String)
*/
/*
public void add(String name, boolean fristIsEmpty) {
this.fristIsEmpty = fristIsEmpty;
add(name);
}
*/
/**
* 用于添加选项并指明首个选项是否为不可选择的选项或者文本为空的选项其他效果与{@link #add(String, ByType)}一致
@ -122,10 +124,12 @@ public class SelectBy extends MultiBy {
* @param fristIsEmpty 首个选项是否为不可选择的选项或者文本为空的选项
* @see #add(String, ByType)
*/
/*
public void add(String name, ByType byType, boolean fristIsEmpty) {
this.fristIsEmpty = fristIsEmpty;
add(name, byType);
}
*/
@Override
public void add(String name, ByType byType, String... links) {
@ -147,11 +151,13 @@ public class SelectBy extends MultiBy {
* @param fristIsEmpty 首个选项是否为不可选择的选项或者文本为空的选项
* @param links 替换词语
*/
/*
public void add(String name, ByType byType, boolean fristIsEmpty, String... links) {
this.fristIsEmpty = fristIsEmpty;
add(name, byType, links);
}
*/
/**
* 可用于指明首行是否为空选项其他说明可参考{@link #add(String, String...)}
@ -159,11 +165,21 @@ public class SelectBy extends MultiBy {
* @param fristIsEmpty 首个选项是否为不可选择的选项或者文本为空的选项
* @param links 替换词语
*/
/*
public void add(String name, boolean fristIsEmpty, String... links) {
this.fristIsEmpty = fristIsEmpty;
add(name, null, links);
}
*/
/**
* 设置首个选项是否为不可选择的选项
* @param fristIsEmpty 首个选项是否为不可选择
*/
public void setFristIsEmpty(boolean fristIsEmpty) {
this.fristIsEmpty = fristIsEmpty;
}
@Override
void add(ElementInformation elementInformation) {

View File

@ -0,0 +1,329 @@
package pres.auxiliary.work.selenium.element.copy;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.UnrecognizableLocationModeException;
import pres.auxiliary.work.selenium.xml.ByType;
import pres.auxiliary.work.selenium.xml.ReadXml;
/**
* <p><b>文件名</b>AbstractElement.java</p>
* <p><b>用途</b></p>
* <p><pre>
* 对辅助化测试工具selenium的获取元素代码进行的二次封装通过类中提供的方法以及配合相应存储元素的
* xml文件以更简便的方式对页面元素进行获取减少编程时的代码量
* </pre></p>
* <p><b>编码时间</b>2020年4月25日 下午4:18:37</p>
* <p><b>修改时间</b>2020年4月25日 下午4:18:37</p>
* @author 彭宇琦
* @version Ver1.0
* @since JDK 12
*/
public abstract class AbstractBy {
/**
* 用于指向存储控件定位方式的xml文件设置属性为静态用于在编写脚本时不需要频繁切换xml文件
*/
static ReadXml xml;
/**
* 用于存储浏览器对象
*/
AbstractBrower brower;
/**
* 存储单个控件的等待时间
*/
private HashMap<String, Long> controlWaitTime = new HashMap<String, Long>();
/**
* 用于存储元素通用的等待时间默认5秒
*/
private long waitTime = 5;
/**
* 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象
*/
public AbstractBy(AbstractBrower brower) {
this.brower = brower;
}
/**
* 用于设置元素查找等待时间默认时间为5秒
*
* @param waitTime 事件等待时间
*/
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}
/**
* 用于对符合正则表达式的控件名称设置等待时间
*
* @param regex 正则表达式
* @param waitTime 等待时间
*/
public void setContorlWaitTime(String regex, long waitTime) {
controlWaitTime.put(regex, waitTime);
}
/**
* 用于设置指向存储元素定位方式的xml文件对象并根据传参判断窗体是否需要回到顶层
* @param xmlFile 存储元素定位方式的xml文件对象
* @param isBreakRootFrame 是否需要将窗体切回到顶层
*/
public void setXmlFile(File xmlFile) {
if (xml == null) {
xml = new ReadXml(xmlFile);
} else {
xml.setXmlPath(xmlFile);
}
}
/**
* <p>
* 用于根据传入的控件名称或定位方式对控件在页面上定位返回其WebElement对象形参可以传入在xml文件中元素的名称
* 亦可以传入页面元素的定位方式但目前识别只支持xpath和css两种方式
* 该方法获取的是一组元素可用于对列表元素事件中
* </p>
* <p>
* 元素识别判断方式按照以下步骤进行<br>
* 1.先对xml文件进行扫描若存在该元素对应的标签则读取xml文件的定位方式并识别有效的定位方式一一匹配直到正确为止<br>
* 2.若在xml文件中查找不到该元素则按照xpath和css的规则进行匹配直到判断出该元素的定位方式位置<br>
* 3.若仍找不到元素则抛出UnrecognizableLocationModeException
* </p>
*
* @param name 元素名称或元素的定位方式
* @return 返回页面一组元素的定位方式对象
* @throws TimeoutException 元素在指定时间内未查找到时抛出的异常
* @throws UnrecognizableLocationModeException 元素无法识别时抛出的异常
*/
List<By> recognitionElement(ElementInformation elementInformation) {
if (isXmlElement(elementInformation.name)) {
//若指定了xml文件且传入的元素名称存在与xml文件中则判断元素相应的定位方式及定位内容
return recognitionXmlElement(elementInformation);
} else {
//若未指定xml文件或者在xml文件中无法查到相应的元素时则将name的值赋给value且根据value判断相应定位方式
return recognitionCommonElement(elementInformation);
}
}
/**
* 获取普通元素的By对象
* @param elementInformation 元素信息类对象
* @return 元素信息指向的By对象
*/
private List<By> recognitionCommonElement(ElementInformation elementInformation) {
List<By> byList = new ArrayList<>();
//判断传入的ByType对象是否为null
if (elementInformation.byType == null) {
byList.addAll(getCommonElementBy(elementInformation.name));
} else {
byList.add(valueToBy(elementInformation.name, elementInformation.byType));
}
return byList;
}
/**
* 获取xml文件内元素的By对象
* @param elementInformation 元素信息类对象
* @return 元素信息指向的By对象
*/
private List<By> recognitionXmlElement(ElementInformation elementInformation) {
//查找元素的父层级结构
elementInformation.iframeList = getParentFrameName(elementInformation.name);
//存储元素的By对象集合
List<By> byList = new ArrayList<>();
//判断传入的ByType对象是否为null
if (elementInformation.byType == null) {
byList.addAll(getXmlElementBy(elementInformation.name, elementInformation.linkKeyList));
} else {
byList.add(xml.getBy(elementInformation.name, elementInformation.byType, elementInformation.linkKeyList));
}
return byList;
}
/**
* 用于返回控件的等待时间若设置单个控件的等待时间使用{@link #setContorlWaitTime(String, long)}方法设置
* 则返回设置的控件等待时间若未设置单个控件的等待时间则返回设置的通用等待时间使用{@link #setWaitTime(long)}方法
* 若未对通用时间进行设置则返回默认时间{@link #waitTime}
* @param name 控件名称
* @return 相应控件的等待时间
* @see #setContorlWaitTime(String, long)
* @see #setWaitTime(long)
*/
long getWaitTime(String name) {
for (String regex : controlWaitTime.keySet()) {
if (Pattern.compile(regex).matcher(name).matches()) {
return controlWaitTime.get(regex);
}
}
return waitTime;
}
/**
* 用于获取元素在xml文件中所有的父窗体并以集合的形式返回存储的顺序为父窗体在前子窗体在后若当前元素没有窗体
* 则集合的长度为0
* @param name 元素在xml文件中的名称
* @return 元素在xml文件中所有的父窗体集合
*/
List<String> getParentFrameName(String name) {
//存储获取到的父层窗体名称
List<String> nameList = new ArrayList<String>();
//获取元素所在窗体的名称
String iframeName = xml.getIframeName(name);
//循环判断窗体是否存在方法返回不为空若存在则再将父窗体进行存储
while(!iframeName.isEmpty()) {
//存储窗体
nameList.add(iframeName);
//再以当前窗体的名称再次获取该窗体的父窗体
iframeName = xml.getIframeName(iframeName);
}
return nameList;
}
/**
* 用于根据传入的参数识别非xml文件内的元素定位方式
* 该方法能快速识别xpath定位方式以及绝对css定位方式若不是以上两种定位方式
* 则会遍历所有的定位方式此时会降低运行速度建议在不是以上两种定位方式的
* 情况下直接指定元素的定位方式以提高效率
*/
List<By> getCommonElementBy(String value) {
List<By> byList = new ArrayList<>();
// 如果抛出元素名称查找不到的的异常则对应匹配xpath和绝对css路径两种定位方式
// 匹配xpath定位判定方法判断text的第一个字符是否是/
//由于是识别普通元素非xml元素其value就是元素的名称name 故获取等待时间时可直接将value传入
if (value.indexOf("/") == 0) {
byList.add(valueToBy(value, ByType.XPATH));
} else if (value.indexOf("html") == 0) {
//在页面中查找元素若元素能找到则结束查找
byList.add(valueToBy(value, ByType.CSS));
} else {
//若元素无法识别则将所有的定位类型排除xpath类型与之进行对比直到在页面上找到元素为止
for(ByType type : ByType.values()) {
if (type == ByType.XPATH) {
continue;
}
byList.add(valueToBy(value, type));
}
}
return byList;
}
/**
* 用于设置xml文件内的元素的定位方式及定位内容
*/
List<By> getXmlElementBy(String name, List<String> linkList) {
//用于存储从xml文件中读取到的所有内容并封装成By对象
List<By> byList = new ArrayList<>();
// 循环逐个在页面上配对有效的标签对应的定位方式
for (ByType mode : xml.getElementMode(name)) {
byList.add(valueToBy(xml.getValue(name, mode, linkList), mode));
}
return byList;
}
/**
* 根据元素的参数返回元素的By对象
* @return 元素的By对象
*/
By valueToBy(String value, ByType byType) {
//根据元素的定位方式对定位内容进行选择返回相应的By对象
switch (byType) {
case XPATH:
return By.xpath(value);
case CLASSNAME:
return By.className(value);
case CSS:
return By.cssSelector(value);
case ID:
return By.id(value);
case LINKTEXT:
return By.linkText(value);
case NAME:
return By.name(value);
case TAGNAME:
return By.tagName(value);
default:
throw new UnrecognizableLocationModeException("无法识别的定位类型:" + byType);
}
}
/**
* 用于判断元素是否为xml文件内的元素
* @param name 元素名称
* @return 是否为xml文件内的元素
*/
boolean isXmlElement(String name) {
return (xml != null && xml.isElement(name));
}
/**
* <p><b>文件名</b>AbstractElement.java</p>
* <p><b>用途</b>
* 存储获取元素时的信息
* </p>
* <p><b>编码时间</b>2020年5月9日上午7:57:24</p>
* <p><b>修改时间</b>2020年5月22日上午8:18:39</p>
* @author 彭宇琦
* @version Ver1.1
* @since JDK 1.8
*
*/
class ElementInformation {
/**
* 存储元素的名称或定位内容
*/
public String name;
/**
* 存储元素的定位方式
*/
public ByType byType;
/**
* 用于标记元素的类型
*/
public ElementType elementType;
/**
* 用于存储在xml文件中需要外链的词语
*/
public List<String> linkKeyList;
/**
* 用于存储元素的父层结构
*/
public List<String> iframeList;
/**
* 构造元素信息
* @param name 元素名称
* @param byType 元素定位的By类型枚举
* @param elementType 元素类型枚举
* @param linkKeyList xml文件中需要外部替换的词语
*/
public ElementInformation(String name, ByType byType, ElementType elementType, List<String> linkKeyList) {
super();
this.name = name;
this.byType = byType;
this.elementType = elementType;
this.linkKeyList = linkKeyList;
}
}
}

View File

@ -0,0 +1,114 @@
package pres.auxiliary.work.selenium.element.copy;
import java.util.Arrays;
import java.util.Iterator;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.xml.ByType;
/**
* <p><b>文件名</b>CommonElement.java</p>
* <p><b>用途</b>
* 提供在辅助化测试中对页面单一元素获取的方法类中获取元素的方法兼容传入定位方式对
* 元素进行查找建议使用xml对页面元素的定位方式进行存储以简化编码时的代码量也便于
* 对代码的维护
* </p>
* <p><b>编码时间</b>2020年4月26日下午10:34:55</p>
* <p><b>修改时间</b>2020年4月26日下午10:34:55</p>
* @author 彭宇琦
* @version Ver1.0
* @since JDK 8
*
*/
public class CommonBy extends AbstractBy {
/**
* 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象
*/
public CommonBy(AbstractBrower brower) {
super(brower);
}
/**
* 用于根据xml文件中元素的名称返回对应的{@link Element}对象该方法亦可传入元素
* 定位内容通过遍历所有的定位方式在页面上查找元素来获取元素的WebElement对象
* 建议传入的定位内容为xpath路径或绝对的css路径若非这两路径则在识别元素时会很慢降低
* 程序运行速度若非xml文件中的元素且不是xpath路径或绝对的css路径建议使用{@link #getElement(String, ByType)}方法
* @param name 元素的名称或元素定位内容
* @return {@link Element}对象
*/
public Element getElement(String name) {
return getElement(new ElementInformation(name, null, ElementType.COMMON_ELEMENT, null));
}
/**
* 用于根据xml文件中元素的名称与定位方式返回对应的{@link Element}对象该方法亦可传入元素
* 定位内容并根据定位方式对页面数据进行查找
* @param name 元素的名称或元素定位内容
* @return {@link Element}对象
*/
public Element getElement(String name, ByType byType) {
return getElement(new ElementInformation(name, byType, ElementType.COMMON_ELEMENT, null));
}
/**
* 用于根据xml文件中元素的名称与定位方式返回对应的{@link Element}对象该方法亦可传入元素
* 定位内容并根据定位方式对页面数据进行查找该方法可对由xml文件读取的内容进行词语替换根据
* 传参中词语的顺序对需要替换的词语进行替换
* @param name 元素名称或定位方式内容
* @param byType 元素定位方式
* @param links 替换词语
* @return {@link Element}对象
*/
public Element getElement(String name, ByType byType, String...links) {
return getElement(new ElementInformation(name, byType, ElementType.COMMON_ELEMENT, Arrays.asList(links)));
}
/**
* 用于根据xml文件中元素的名称返回对应的{@link Element}对象该方法亦可传入元素
* 定位内容通过遍历所有的定位方式在页面上查找元素来获取元素的WebElement对象
* 建议传入的定位内容为xpath路径或绝对的css路径若非这两路径则在识别元素时会很慢降低
* 程序运行速度若非xml文件中的元素且不是xpath路径或绝对的css路径建议使用{@link #getElement(String, ByType, String...)}方法
* @param name 元素的名称或元素定位内容
* @param links 替换词语
* @return {@link Element}对象
*/
public Element getElement(String name, String...links) {
return getElement(new ElementInformation(name, null, ElementType.COMMON_ELEMENT, Arrays.asList(links)));
}
/**
* 获取元素的底层方法
* @param elementInformation 元素信息类对象
* @return WebElement对象
*/
private Element getElement(ElementInformation elementInformation) {
Element element = new Element(brower, elementInformation.name, ElementType.COMMON_ELEMENT, 0);
element.setWaitTime(getWaitTime(elementInformation.name));
element.setByList(recognitionElement(elementInformation));
//构造元素的父层元素若元素不存在窗体结构则不进行构造
if (elementInformation.iframeList != null && elementInformation.iframeList.size() != 0) {
//指向当前元素用于设置当前元素的父层窗体元素
Element childElement = element;
//使用Iterator
Iterator<String> it = elementInformation.iframeList.iterator();
//循环一一设置父层结构
do {
//获取父层的元素的名称
String iframeName = it.next();
//构造父层元素
Element iframeElement = new Element(brower, iframeName, ElementType.COMMON_ELEMENT, 0);
//设置父层元素的获取方式及等待时间
iframeElement.setWaitTime(getWaitTime(iframeName));
iframeElement.setByList(getXmlElementBy(iframeName, null));
//设置父层
childElement.setIframeElement(iframeElement);
//将子元素指向父层元素以获取下一层窗体元素
childElement = iframeElement;
} while(it.hasNext());
}
return element;
}
}

View File

@ -0,0 +1,365 @@
package pres.auxiliary.work.selenium.element.copy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
/**
* <p><b>文件名</b>Element.java</p>
* <p><b>用途</b>
* 用于返回和查找页面元素以方便在元素过期时能进行重新获取
* </p>
* <p><b>编码时间</b>2020年5月18日上午8:39:05</p>
* <p><b>修改时间</b>2020年5月18日上午8:39:05</p>
* @author 彭宇琦
* @version Ver1.0
* @since JDK 8
*
*/
public class Element {
/**
* 存储元素
*/
private WebElement element = null;
/**
* 存储查找元素的By对象
*/
private List<By> byList;
/**
* 用于存储窗体元素
*/
private Element iframeElement = null;
/**
* 用于存储当前已指向的窗体
*/
private static ArrayList<Element> iframeElementList = new ArrayList<>();
/**
* 存储获取需要获取的元素下标
*/
private int elementIndex;
/**
* 存储WebDriver对象以查找相应元素
*/
private WebDriver driver;
/**
* 用于存储当前打开的浏览器对象
*/
// private AbstractBrower brower;
/**
* 用于存储元素的名称
*/
private String name;
/**
* 标记元素的类型以用于重新获取时
*/
private ElementType elementType;
/**
* 用于存储元素查找等待时间默认3秒
*/
private long waitTime = 3;
/**
* TODO 确定构造后添加注释
*/
public Element(AbstractBrower brower, String name, ElementType elementType, int elementIndex) {
super();
//存储Driver对象
this.driver = brower.getDriver();
this.name = name;
this.elementType = elementType;
this.elementIndex = elementIndex;
}
/**
* 用于根据存储的元素信息在相应的页面中查找并返回一个{@link WebElement}对象
* @return {@link WebElement}对象
*/
public WebElement getWebElement() {
//切换窗体
autoSwitchIframe();
//若element为null则对元素进行一次查找
if (element == null) {
findElemen();
}
//返回相应的内容
return element;
}
/**
* 用于设置元素定位的{@link By}对象集合调用该方法后将清空原存储的内容重新添加{@link By}对象集合
* @param byList {@link By}对象集合
*/
public void setByList(List<By> byList) {
this.byList = byList;
}
/**
* 用于设置元素的父层窗体
* @param iframeElement 元素的父层窗体
*/
public void setIframeElement(Element iframeElement) {
this.iframeElement = iframeElement;
}
/**
* 用于返回元素所在的窗体元素对象
* @return 元素所在的窗体元素对象
*/
public Element getIframeElement() {
return iframeElement;
}
/**
* 用于返回当前存储的{@link WebDriver}对象
* @return {@link WebDriver}对象
*/
public WebDriver getDriver() {
return driver;
}
/**
* 用于返回元素名称
* @return 元素名称
*/
public String getName() {
return name;
}
/**
* 用于设置元素查询等待时间该时间为元素每个{@link By}对象在页面查询的时间注意若添加
* 过多无效的{@link By}对象会导致查询等待时间过长
* @param waitTime 元素查询等待时间
*/
public void setWaitTime(long waitTime) {
this.waitTime = waitTime;
}
/**
* 用于返回元素在列表中的下标
* @return 元素下标
*/
public int getElementIndex() {
return elementIndex;
}
/**
* 用于返回元素所在的所有父窗体
* @return 父窗体集合
*/
public ArrayList<Element> getAllIframe() {
//存储当前元素的所在的所有窗体
ArrayList<Element> iframeList = new ArrayList<>();
//用于指向元素所在的窗体
Element iframe = iframeElement;
//若窗体元素不为null则循环
while(iframe != null) {
//存储窗体元素
iframeList.add(iframe);
//向下探寻是否存在下一级窗体元素
iframe = iframe.getIframeElement();
}
//若iframeList中未存储元素则不进行倒叙
if (iframeList.size() != 0) {
//由于存储顺序为子窗体在前不符合切换窗体的顺序故需要对集合进行倒叙操作
Collections.reverse(iframeList);
}
return iframeList;
}
/**
* 用于将窗体切换至顶层
*/
public void switchRootIframe() {
//切换窗体至顶层
driver.switchTo().defaultContent();
//将iframeElementList中的内容清空
iframeElementList.clear();
}
/**
* 用于向下切换一层窗体
* @param iframeElement 窗体元素类对象
*/
public void switchIframe(Element iframeElement) {
//切换窗体
driver.switchTo().frame(iframeElement.findIframeElement());
//存储窗体切换记录
iframeElementList.add(iframeElement);
}
/**
* 用于向上切换指定数量的窗体若传入的数量大于当前窗体的数量则将窗体切换至顶层若传入的数量小于
* 等于0则不进行切换
* @param count 需要向上切换窗体的数量
*/
public void switchParentIframe(int count) {
//判断count是否小于等于0若小于等于0则不进行切换
if (count <= 0) {
return;
}
//判断count是否大于iframeElementList中所有元素的个数若大于则切回至顶层
if (count > iframeElementList.size()) {
switchRootIframe();
return;
}
//循环对窗体进行切换
for (int i = 0; i < count; i++) {
//向上切换窗体
driver.switchTo().parentFrame();
//移除iframeElementList中最后一个元素
iframeElementList.remove(iframeElementList.size() - 1);
}
}
/**
* 用于根据By对象集合查找有效的By对象并根据有效的By对象查找相应的元素集合
*/
public void findElemen() {
//遍历By集合查找有效的By对象若所有的By对象均无法查到页面元素则直接抛出超时异常
for (int i = 0; i < byList.size(); i++) {
//查找元素若抛出异常则移除该元素保证有效的By对象在第一个元素上
try {
if (isExistElement(byList.get(i))) {
break;
} else {
byList.remove(i);
i--;
}
} catch (Exception e) {
byList.remove(i);
i--;
}
}
//若byList被清空则抛出查找超时的异常
if (byList.size() == 0) {
throw new TimeoutException("页面无法查找到相应的元素,“" + name + "”元素无有效的By对象");
}
//根据正确的By对象通过Webdriver查找到WebElement对象存储
//由于在遍历byList时无效的By对象被剔除查找到By对象时会返回故此时可直接使用第一个元素为有效的By对象
switch (elementType) {
case COMMON_ELEMENT:
case DATA_LIST_ELEMENT:
case SELECT_DATAS_ELEMENT:
element = driver.findElements(byList.get(0)).get(elementIndex);
break;
case SELECT_OPTION_ELEMENT:
element = new Select(driver.findElement(byList.get(0))).getOptions().get(elementIndex);
break;
default:
throw new IllegalArgumentException("Unexpected value: " + elementType);
}
}
/**
* 用于自动切换元素所在窗体
*/
private void autoSwitchIframe() {
//获取元素所在的所有窗体并存储
ArrayList<Element> iframeList = getAllIframe();
//判断iframeList中是否存在元素若不存在则切回顶层后结束运行
if (iframeList.isEmpty()) {
switchRootIframe();
return;
}
//判断iframeElementList是否为空或iframeList的第一个元素是否存在于iframeElementList中若不存在则切回到顶层并根据iframeList切换窗体
if (iframeElementList.size() == 0 || !iframeElementList.contains(iframeList.get(0))) {
switchRootIframe();
iframeList.forEach(iframeElement -> {
switchIframe(iframeElement);
});
return;
}
//判断iframeElementList中的最后一个元素是否与iframeList中的最后一个元素一致若一致则无需切换
if (iframeElementList.get(iframeElementList.size() - 1).equals(iframeList.get(iframeList.size() - 1))) {
return;
}
//遍历iframeList查看iframeList中的窗体元素是否存在于iframeElementList中
int index = 0;
for (; index < iframeList.size(); index++) {
//若当前遍历的元素不存在于iframeElementList中则结束循环
if (!iframeElementList.contains(iframeList.get(index))) {
break;
}
}
//计算需要向上切换窗体的个数
//当窗体不存在于iframeElementList中时其index以比存在的窗体下标大1位
//index可直接用于计算需要切换窗体的个数
switchParentIframe(iframeElementList.size() - index);
//切换到相应的父层后再根据iframeList剩余的元素进行切换
for (; index < iframeList.size(); index++) {
switchIframe(iframeList.get(index));
}
}
/**
* 用于返回窗体{@link WebElement}元素
* @return 窗体{@link WebElement}元素
*/
private WebElement findIframeElement() {
//若elementList为null或其内无元素则对元素进行一次查找
if (element == null) {
findElemen();
}
//返回相应的内容
return element;
}
/**
* 判断根据传入的{@link By}对象判断是否能查找到元素
* @param by {@link By}对象
* @return 是否查找到元素
*/
boolean isExistElement(By by) {
//当查找到元素时则返回true若查不到元素则会抛出异常故返回false
return new WebDriverWait(driver, waitTime, 200).
until((driver) -> {
WebElement element = driver.findElement(by);
return element != null;
});
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Element other = (Element) obj;
if (element == null) {
if (other.element != null)
return false;
} else if (!element.equals(other.element))
return false;
return true;
}
}

View File

@ -0,0 +1,32 @@
package pres.auxiliary.work.selenium.element.copy;
/**
* <p><b>文件名</b>EelementType.java</p>
* <p><b>用途</b>
* 用于标记当前传入的元素是以何种方式进行获取
* </p>
* <p><b>编码时间</b>2020年5月22日上午7:57:32</p>
* <p><b>修改时间</b>2020年5月22日上午7:57:32</p>
* @author
* @version Ver1.0
* @since JDK 12
*
*/
public enum ElementType {
/**
* 指向普通类型元素
*/
COMMON_ELEMENT,
/**
* 指向数据列表类型元素
*/
DATA_LIST_ELEMENT,
/**
* 指向标准下拉框选择类型元素
*/
SELECT_OPTION_ELEMENT,
/**
* 指向列表型下拉框选择类型元素
*/
SELECT_DATAS_ELEMENT;
}

View File

@ -0,0 +1,189 @@
package pres.auxiliary.work.selenium.element.copy;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.copy.AbstractBy.ElementInformation;
/**
* <p><b>文件名</b>ListElement.java</p>
* <p><b>用途</b>
* 提供获取列表类型元素时的基本方法
* </p>
* <p><b>编码时间</b>2020年5月22日上午7:54:55</p>
* <p><b>修改时间</b>2020年5月22日上午7:54:55</p>
* @author 彭宇琦
* @version Ver1.0
* @since JDK 12
*
*/
public class ListBy extends AbstractBy {
/**
* 用于存储获取到的列表一列元素key为列表名称value为列表元素
*/
LinkedHashMap<ElementInformation, List<Element>> elementMap = new LinkedHashMap<>(16);
/**
* 通过浏览器对象{@link AbstractBrower}进行构造
* @param brower {@link AbstractBrower}对象
*/
public ListBy(AbstractBrower brower) {
super(brower);
}
/**
* 返回列表名称对应的元素个数若该列未被获取则返回-1
* @param name 被获取的列名称
* @return 列名对应列的元素个数
*/
public int getSize(String name) {
ElementInformation element = nameToElementInformation(name);
if (element != null) {
return elementMap.get(element).size();
} else {
return -1;
}
}
/**
* 该方法用于返回所有列的名称
* @return 所有列的名称
*/
public ArrayList<String> getNames() {
ArrayList<String> nameList = new ArrayList<>();
elementMap.forEach((key, value) -> {
nameList.add(key.name);
});
return nameList;
}
@Override
void add(ElementInformation elementInformation) {
//判断传入的元素是否在xml文件中若存在再判断是否自动切换窗体若需要则获取元素的所有父窗体并进行切换
if (xml != null && xml.isElement(elementInformation.name) && isAutoSwitchIframe) {
switchFrame(getParentFrameName(elementInformation.name));
}
List<Element> elementList = new ArrayList<Element>();
//获取元素
By by = recognitionElement(elementInformation);
int size = driver.findElements(by).size();
//构造Element对象
for (int i = 0; i < size; i++) {
elementList.add(new Element(driver, ElementType.DATA_LIST_ELEMENT, by, elementInformation.name, i));
}
//elementList = driver.findElements(recognitionElement(elementInformation));
//添加元素
elementMap.put(elementInformation, elementList);
}
/**
* 用于清除或移除指定的列及列中的元素当参数传入false时则只清理列表中存储的元素不移除
* 整个列若传入true时则直接移除整个列若列名称对应的列未被获取则返回null
* @param name 已被获取的元素列名称
* @param isRemove 是否需要将该列移除
* @return 被移除列中存储的所有元素
*/
public List<Element> clearColumn(String name, boolean isRemove) {
ElementInformation element = nameToElementInformation(name);
//若元素不存在则直接返回null
if (element == null) {
return null;
}
//用于存储被移除的元素
List<Element> elementList = elementMap.get(element);
//判断元素是否需要被完全移除
if (isRemove) {
//若元素需要被完全移除则直接移除元素
elementMap.remove(element);
//由于元素被移除若该列存在元素个数统计则同样将该元素移除
/*
if (elementSizeMap.containsKey(name)) {
elementSizeMap.remove(name);
}
*/
} else {
//若元素无需移除则将元素存储的列表内容清空
elementMap.get(element).clear();
}
return elementList;
}
@Override
public void againGetElement() {
// 读取elements中的元素
elementMap.forEach((key, value) -> {
// 清空元素中的内容
clearColumn(key.name, false);
// 对页面内容重新进行获取
add(key);
});
}
/**
* 根据元素名称反推元素信息类对象用于根据列名称查找数据以及判断列是否存在若列名不存在则返回null
* @return ElementInformation对象
*/
ElementInformation nameToElementInformation(String name) {
//遍历elementMap若查找与name一致的名称则结束循环并返回相应的ElementInformation对象
for (ElementInformation element : elementMap.keySet()) {
if (element.name.equals(name)) {
return element;
}
}
return null;
}
/**
* 该方法用于根据列名称查找到相应的列并返回与传入下标对应的元素下标支持从后向前获取传入的下标
* 与元素实际所在位置一致当传入0时则表示随机获取一个元素<br>
* {@code getWebElement("姓名", 1)}表示获取名称为姓名的列中的第1个元素<br>
* {@code getWebElement("姓名", 0)}表示获取名称为姓名的列中在长度范围内随机一个元素<br>
* {@code getWebElement("//*[@id='name']", -1)}表示获取//*[@id='name']对应列中的倒数第1个元素<br>
*
* @param name 列名称
* @param index 元素下标即列表中对应的某一个元素
* @return 对应列指定的元素
* @throws NoSuchElementException 当未对name列进行获取数据或index的绝对值大于列表最大值时抛出的异常
*/
public Element getElement(String name, int index) {
//获取元素信息并判断元素是否存在不存在则抛出异常
ElementInformation element = nameToElementInformation(name);
if (element == null) {
throw new NoSuchElementException("不存在的定位方式:" + name);
}
// 转义下标
index = getIndex(elementMap.get(element).size(), index, true);
// 转义下标后返回对应的元素
return elementMap.get(element).get(index);
}
/**
* 该方法用于根据列名称获取该列下所有的元素
*
* @param name 列名称
* @return 对应列元素
* @throws NoSuchElementException 当未对name列进行获取数据时抛出的异常
*/
public List<Element> getAllElement(String name) {
//获取元素信息并判断元素是否存在不存在则抛出异常
ElementInformation element = nameToElementInformation(name);
if (element == null) {
throw new NoSuchElementException("不存在的定位方式:" + name);
}
return elementMap.get(element);
}
}

View File

@ -27,8 +27,6 @@ import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
import pres.auxiliary.directory.operate.MakeDirectory;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
/**

View File

@ -6,10 +6,6 @@ import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
import pres.auxiliary.directory.exception.UndefinedDirectoryException;
import pres.auxiliary.directory.operate.MakeDirectory;
/**
* <p><b>文件名</b>Log.java</p>
* <p><b>用途</b>用于在txt文件中生成自动化测试相关的日志亦可指定输出的内容</p>

View File

@ -10,7 +10,6 @@ import javax.imageio.ImageIO;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
/**
* <p>

View File

@ -11,10 +11,6 @@ import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
import pres.auxiliary.directory.exception.UndefinedDirectoryException;
import pres.auxiliary.directory.operate.MakeDirectory;
/**
* 该类用于在使用selenium进行自动化测试中进行截图的工具使用该类时可以指定截图保存的位置以及
* 截图的名称若不设置则默认路径为C:\\AutoTest\\Screenshot\\默认文件名称为Image
@ -213,35 +209,6 @@ public class Screenshot {
}).start();
}
/**
* 该方法用于创建截图并保存到相应的路径下通过指定的截图文件名称和类中存储的WebDriver对象截图保存路径来创建截图
* 该方法可先按照控件名称查找页面是否存在该控件存在则截图若不存在则返回null
*
* @param event 事件类Event对象
* @param controlName 控件名称
* @param imageName 指定的截图文件名
* @return
* @throws IOException
* 文件流状态不正确时抛出的异常
* @throws WebDriverException
* WebDriver引用错误时抛出的异常
* @throws NullPointerException
* WebDriver为空时抛出的异常
* @throws UndefinedDirectoryException
* 截图保存路径或截图名称为指定时抛出的异常
* @see #creatImage(String)
*/
public File creatImage(Event event, String controlName, String imageName) throws WebDriverException, IOException {
//判断控件名对应的控件是否存在存在后则截图否则返回null
if ( event.getJudgeEvent().judgeControl(controlName).getBooleanValue() ) {
return null;
}
// 将名称放入属性中
setImageName(imageName);
// 调用无参方法
return saveScreenshot();
}
/**
* 该方法用于保存并转移截图
*

View File

@ -1,576 +0,0 @@
package pres.auxiliary.work.selenium.xml;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
import pres.auxiliary.directory.operate.MakeDirectory;
/**
* <p><b>文件名</b>CreateXML.java</p>
* <p><b>用途</b>用于通过指定样式的txt文件来创建自动化测试所需要的xml文件</p>
* <p><b>编码时间</b>2019年6月1日上午11:41:02</p>
* <p><b>修改时间</b>2019年6月1日上午11:41:02</p>
* @author 彭宇琦
*
*/
public class CreateXml {
// 用于设置到xml文件存放的路径
private static StringBuilder xmlPath = new StringBuilder(
"C:\\AutoTest\\Xml\\");
private static StringBuilder xmlName = new StringBuilder("");
// 用于存储用户选择的定位方式标签
private static StringBuilder mode = new StringBuilder("");
// 定义字段
/** 添加xpath标签 */
public static final short XPATH = 0;
/** 添加css标签 */
public static final short CSS = 1;
/** 添加id标签 */
public static final short ID = 2;
/** 添加linktext标签 */
public static final short LINKTEXT = 3;
/** 添加name标签 */
public static final short NAME = 4;
/** 添加tagname标签 */
public static final short TAGNAME = 5;
/** 添加classname标签 */
public static final short CLASSNAME = 6;
/** 添加default默认标签 */
public static final short DEFAULT = 7;
/**
* 该方法用于返回xml文件的名称不带后缀
*
* @return xml文件的名称
*/
public static String getXmlName() {
return xmlName.toString();
}
/**
* 该方法用于设置xml文件的名称传入的名称不需要添加后缀不能为中文
*
* @param xmlName
* xml文件的名称
*/
public static void setXmlName(String xmlName) {
// 判断传入的测试结果文件名称是否符合windows下的命名规则若不符合则抛出IncorrectDirectoryException异常
if (!MakeDirectory.isFileName(xmlName)) {
throw new IncorrectDirectoryException("不合理的文件名称,文件名称:" + xmlName);
}
// 通过判断后则清空xmlName存储的信息并将新的文件名称放入xmlName种属性中
CreateXml.xmlName.delete(0, CreateXml.xmlName.length());
CreateXml.xmlName.append(xmlName);
}
/**
* 该方法用于返回xml文件存放的位置
*
* @return xml文件存放的位置
*/
public static String getXmlPath() {
return xmlPath.toString();
}
/**
* 该方法用于重新设置xml文件存放的路径并将Document对象指向新的XML文件
*
* @param xmlPath
* xml的存放路径
*/
public static void setXmlPath(String xmlPath) {
// 将传入的参数进行格式化
StringBuilder sb = new StringBuilder(xmlPath);
sb = MakeDirectory.formatPath(sb);
// 判断格式化后的文件路径格式是否符合windonws下文件路径的命名规则,不符合则抛出异常
if (!MakeDirectory.isPath(sb.toString())) {
System.out.println(sb.toString());
throw new IncorrectDirectoryException("不合理的文件夹路径,文件路径:"
+ sb.toString());
}
// 将文件路径设置入属性中
CreateXml.xmlPath = sb;
}
/**
* 该方法用于返回使用的定位标签的情况
*
* @return 正在使用的定位标签
*/
public static String getMode() {
StringBuilder sb = new StringBuilder();
sb.append("mode [ ");
// 判断mode包含的标签
if (mode.indexOf("0") > -1) {
sb.append("xpath, ");
}
if (mode.indexOf("1") > -1) {
sb.append("css, ");
}
if (mode.indexOf("2") > -1) {
sb.append("id, ");
}
if (mode.indexOf("3") > -1) {
sb.append("linktext, ");
}
if (mode.indexOf("4") > -1) {
sb.append("name, ");
}
if (mode.indexOf("5") > -1) {
sb.append("tagname, ");
}
if (mode.indexOf("6") > -1) {
sb.append("classname, ");
}
// 删除多余的逗号
sb.delete(sb.lastIndexOf(","), sb.lastIndexOf(",") + 1);
sb.append("]");
return sb.toString();
}
/**
* 该方法用于设置需要使用的定位标签可传入多个参数若该标签的定位方式已存在则不重复添加
*
* @param modes
* 传入定位方式组
*/
public static void setMode(int... modes) {
for (int mode : modes) {
// 判断mode中是否已经存在定位模型不存在则添加该模型
if (CreateXml.mode.indexOf(String.valueOf(mode)) < 0) {
CreateXml.mode.append(String.valueOf(mode));
}
}
}
/**
* 该方法通过存储的xml文件名创建一个空的xml文件相当于导出一个模版
*
* @throws XmlFileNameIsNullException
* 当xml文件名为空时抛出
* @throws RepeatedXmlFileNameException
* 当文件夹中存在与定义的xml文件名同名时抛出运行时异常
*
* @see #create(String...)
* @see #create(List)
* @see #create(String, List)
*/
public static void create() throws XmlFileNameIsNullException {
create("");
}
/**
* 该方法通过存储的xml文件名称创建一个已定义元素名称的xml文件 传入的名称个数即为创建xml文件内元素的个数
*
* @param names
* 传入的元素名称组
* @throws XmlFileNameIsNullException
* 当xml文件名为空时抛出
* @throws RepeatedXmlFileNameException
* 当文件夹中存在与定义的xml文件名同名时抛出运行时异常
* @see #create()
* @see #create(List)
* @see #create(String, List)
*/
public static void create(String... names)
throws XmlFileNameIsNullException {
create(Arrays.asList(names));
}
/**
* 该方法通过传入的xml文件名称创建一个已定义元素名称的xml文件 传入的数组中存储的名称个数即为创建xml文件内元素的个数
*
* @param xmlName
* 定义的xml文件名称
* @param names
* 传入的元素名称组
* @throws XmlFileNameIsNullException
* 当xml文件名为空时抛出
* @throws RepeatedXmlFileNameException
* 当文件夹中存在与定义的xml文件名同名时抛出运行时异常
* @see #create()
* @see #create(String...)
* @see #create(List)
*/
public static void create(String xmlName, List<String> names)
throws XmlFileNameIsNullException {
setXmlName(xmlName);
create(names);
}
/**
* 该方法通过存储的xml文件名称创建一个已定义元素名称的xml文件 传入的数组中存储的名称个数即为创建xml文件内元素的个数
*
* @param names
* 传入的元素名称组
* @throws XmlFileNameIsNullException
* 当xml文件名为空时抛出
* @throws RepeatedXmlFileNameException
* 当文件夹中存在与定义的xml文件名同名时抛出运行时异常
* @see #create()
* @see #create(String...)
* @see #create(String, List)
*/
public static void create(List<String> texts)
throws XmlFileNameIsNullException {
// 判断xml文件的名称是否为空若为空则抛出异常
if ("".equals(xmlName.toString())) {
throw new XmlFileNameIsNullException("xml文件名为空");
}
// 创建存放xml的文件夹
File xmlfile = new File(xmlPath.toString());
xmlfile.mkdirs();
// 将File对象定位到xml文件上
xmlfile = new File(xmlfile, (xmlName.toString() + ".xml"));
if (xmlfile.exists()) {
throw new RepeatedXmlFileNameException("存在的文件名:"
+ (xmlName.toString() + ".xml"));
}
//创建空的xml文件
Document dom = DocumentHelper.createDocument();
//设置根元素并设置根元素的属性
dom.setRootElement(dom.addElement("project"));
dom.getRootElement().addAttribute("name", xmlName.toString());
//插入控件元素
for (String text : texts) {
//创建元素
Element e = dom.getRootElement().addElement("element");
String name = "";
String value = "";
short valueMode = -1;
//判断传入的信息中是否包含分隔符空格包含则表示存在录入的数据则直接写入到xml文件中
if ( text.split(" ").length > 1 ) {
name = text.split(" ")[0];
//value = text.split(" ")[1]; 由于css路径是存在空格的故不能按照切分的方法存入应按照截取的方法从第一个空格的下一位开始截取
value = text.substring(text.indexOf(" ") + 1);
//判断传入结果的模型
valueMode = judgeValue(value);
} else {
name = text;
}
//设置元素的name属性
e.addAttribute("name", name);
//创建定位方式元素
// 定义空mode的开关当mode为空时则开关打开并在mode中添加所有的定位标签最后若该开关为开启状态则清空mode中所有的内容
boolean modeIsEmpty = false;
// 判断mode中是否为空为空则将开关打开并想mode中添加所有标签的定位方式
if ("".equals(mode.toString())) {
modeIsEmpty = true;
mode.append(String.valueOf(XPATH));
mode.append(String.valueOf(CSS));
mode.append(String.valueOf(ID));
mode.append(String.valueOf(LINKTEXT));
mode.append(String.valueOf(NAME));
mode.append(String.valueOf(TAGNAME));
mode.append(String.valueOf(CLASSNAME));
}
// 判断mode包含的标签
if (mode.indexOf(String.valueOf(XPATH)) > -1 || valueMode == XPATH) {
//添加节点
Element childElement = e.addElement("xpath");
childElement.addAttribute("is_use", "true");
//添加value中的内容若内容为空也不会将其添加到xml文件中故此处可以直接这样写
if (valueMode == XPATH) {
childElement.addText(value);
//清空value中的内容避免出现后面的标签也存入信息
value = "";
}
}
if (mode.indexOf(String.valueOf(CSS)) > -1 || valueMode == CSS) {
//添加节点
Element childElement = e.addElement("css");
childElement.addAttribute("is_use", "true");
//添加value中的内容若内容为空也不会将其添加到xml文件中故此处可以直接这样写
if (valueMode == CSS) {
childElement.addText(value);
//清空value中的内容避免出现后面的标签也存入信息
value = "";
}
}
if (mode.indexOf(String.valueOf(ID)) > -1) {
e.addElement("id").addAttribute("is_use", "true");
}
if (mode.indexOf(String.valueOf(LINKTEXT)) > -1) {
e.addElement("linktext").addAttribute("is_use", "true");
}
if (mode.indexOf(String.valueOf(NAME)) > -1) {
e.addElement("name").addAttribute("is_use", "true");
}
if (mode.indexOf(String.valueOf(TAGNAME)) > -1) {
e.addElement("tagname").addAttribute("is_use", "true");
}
if (mode.indexOf(String.valueOf(CLASSNAME)) > -1) {
e.addElement("classname").addAttribute("is_use", "true");
}
//如果存在模型值但系统识别为非xpath和css时则添加一个temp标签对模型值进行存储
if ( valueMode == DEFAULT ) {
//添加注释
e.addComment("当前节点作为临时存储节点,该节点在自动化测试中不被读取,请将节点的值放入到相应的标签中");
//添加节点
Element childElement = e.addElement("temp");
childElement.addAttribute("is_use", "false");
//存储模型值
childElement.addText(value);
}
// 判断modeIsEmpty开关是否开启若开启则清空mode中的内容
if (modeIsEmpty) {
mode.delete(0, mode.length());
}
}
/*
// 用于存储xml文件的内容并添加头文件
StringBuilder sb = new StringBuilder();
// 添加头标签
sb.append("<?xml version=\"1.0\" encoding=\"GBK\"?>\r\n");
// 添加dtd文件
// sb.append("<!DOCTYPE project SYSTEM \"ElementDTD.dtd\">\r\n");
// 添加根标签
sb.append("<project name=\"" + xmlName.toString() + "\">\r\n");
// 添加已有名称的标签
for (String name : names) {
sb.append(element(name));
sb.append("\r\n");
}
sb.append("</project>\r\n");
// 创建写入流
try {
FileWriter fw = new FileWriter(xmlfile);
fw.write(sb.toString());
fw.flush();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
*/
// 使用dom4j的漂亮格式
OutputFormat format = OutputFormat.createPrettyPrint();
// 设置xml文件的编码方式
format.setEncoding("GBK");
//关闭自闭和标签若不设置此开关则当元素无内容时其标签会被写为半闭合标签但我希望标签成对出现
format.setExpandEmptyElements(true);
// 写入xml
XMLWriter xmlWriter = null;
try {
xmlWriter = new XMLWriter(new FileOutputStream(xmlfile),
format);
xmlWriter.write(dom);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
xmlWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// createDTD();
}
/**
* 该方法用于向文件中读取控件名称并在指定的路径下创建带控件名称的xml文件通过该方法创建的xml文件名称为读取的文件名称<br/>
* 注意使用该方法时除了后缀名前可以带. 文件名称中不能再出现该符号否则方法可能会报错
*
* @param files
* 指定的文件可传入多个
* @throws XmlFileNameIsNullException
* 当xml文件名为空时抛出
* @throws RepeatedXmlFileNameException
* 当文件夹中存在与定义的xml文件名同名时抛出运行时异常
*/
public static void create(File... files) throws XmlFileNameIsNullException {
// 用于存储从文件中获取到的元素名称
List<String> l = new ArrayList<>();
// 循环读取传入的文件
for (File f : files) {
// 判断该文件是否为文件夹若为文件夹则继续循环
if (f.isDirectory()) {
continue;
}
// 根据符号.对获取的文件名称进行分割使其在xml文件中不再带后缀
setXmlName(f.getName().split("\\.")[0]);
// 封装高效缓冲文件流
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(f));
// 循环将读取到的元素名称存储l中结束条件为若l中最后一个元素为空则表示上一次未读取到内容测试跳出循环
String s = br.readLine();
while (s != null) {
// 直接读取一行文本并将其存入l中
l.add(s);
s = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
// 调用类中的方法将存储的控件名称转换成xml若文件名重复则跳过
try {
create(l);
} catch (RepeatedXmlFileNameException e) {
//TODO 控制台输出跳过创建的信息
System.out.println(f.getName().split("\\.")[0] + ".xml文件已存在跳过");
}
// 清空l中的所有内容重新进行循环
l.clear();
}
}
/**
* 用于判断传入的值但目前只能判断xpath和css若非这两种则返回default
*/
private static short judgeValue(String value) {
// 如果抛出元素名称查找不到的的异常则对应匹配xpath和css两种定位方式
// 匹配xpath定位判定方法判断text的第一个字符是否是/
if (value.indexOf("/") == 0) {
return XPATH;
} else if (value.indexOf("html") == 0) {
// 匹配css判断方法判断text的前四个字符是否是html
return CSS;
} else {
return DEFAULT;
}
}
/**
* 该方法用于创建元素标签以及元素下的定位方式标签
*
* @param name
* element标签的name属性值
* @return 添加标签后的StringBuilder对象
*/
/*
private static StringBuilder element(String name) {
// 定义空mode的开关当mode为空时则开关打开并在mode中添加所有的定位标签最后若该开关为开启状态则清空mode中所有的内容
boolean modeIsEmpty = false;
// 判断mode中是否为空为空则将开关打开并想mode中添加所有标签的定位方式
if (mode.toString().equals("")) {
modeIsEmpty = true;
mode.append(String.valueOf(XPATH));
mode.append(String.valueOf(CSS));
mode.append(String.valueOf(ID));
mode.append(String.valueOf(LINKTEXT));
mode.append(String.valueOf(NAME));
mode.append(String.valueOf(TAGNAME));
mode.append(String.valueOf(CLASSNAME));
}
// 用于拼接xml文件内容
StringBuilder sb = new StringBuilder();
// 添加element标签
sb.append(" <element name=\"" + name + "\">\r\n");
// 添加所有的定位方式标签
// 判断mode包含的标签
if (mode.indexOf("0") > -1) {
sb.append(" <xpath is_use=\"true\"></xpath>\r\n");
}
if (mode.indexOf("1") > -1) {
sb.append(" <css is_use=\"true\"></css>\r\n");
}
if (mode.indexOf("2") > -1) {
sb.append(" <id is_use=\"true\"></id>\r\n");
}
if (mode.indexOf("3") > -1) {
sb.append(" <linktext is_use=\"true\"></linktext>\r\n");
}
if (mode.indexOf("4") > -1) {
sb.append(" <name is_use=\"true\"></name>\r\n");
}
if (mode.indexOf("5") > -1) {
sb.append(" <tagname is_use=\"true\"></tagname>\r\n");
}
if (mode.indexOf("6") > -1) {
sb.append(" <classname is_use=\"true\"></classname>\r\n");
}
sb.append(" </element>\r\n");
// 判断modeIsEmpty开关是否开启若开启则清空mode中的内容
if (modeIsEmpty) {
mode.delete(0, mode.length());
}
return sb;
}
*/
/**
* 该方法用于配套xml生成的DTD文件用于限制输入
*/
/*
private static void createDTD() {
// 在xml文件存放的目录下创建一个dtd文件
File f = new File(xmlPath.toString() + "\\ElementDTD.dtd");
// 判断ElementDTD.dtd文件是否存在存在则不创建文件返回
if (f.exists()) {
return;
}
// 若不存在则存储dtd代码并生成文件
StringBuilder sb = new StringBuilder();
// 限制project标签下可以有多个element元素
sb.append("<!ELEMENT project (element+)>\r\n");
// 限制element标签下的定位方式标签可出现一次或零次
sb.append("<!ELEMENT element (xpath?,css?,id?,linktext?,name?,tagname?,classname?)>\r\n");
// 对于定位方式标签限制没有子标签数据为字符型数据
sb.append("<!ELEMENT xpath (#PCDATA)>\r\n");
sb.append("<!ELEMENT css (#PCDATA)>\r\n");
sb.append("<!ELEMENT id (#PCDATA)>\r\n");
sb.append("<!ELEMENT linktext (#PCDATA)>\r\n");
sb.append("<!ELEMENT name (#PCDATA)>\r\n");
sb.append("<!ELEMENT tagname (#PCDATA)>\r\n");
sb.append("<!ELEMENT classname (#PCDATA)>\r\n");
// 限制project中的name属性的值为非必要
sb.append("<!ATTLIST project name CDATA #IMPLIED>\r\n");
// 限制element中的name属性的值为唯一且必要
sb.append("<!ATTLIST element name ID #REQUIRED>\r\n");
try {
FileWriter fw = new FileWriter(f);
fw.write(sb.toString());
fw.flush();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
*/
}

View File

@ -1,86 +0,0 @@
package pres.auxiliary.work.selenium.xml;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
import pres.auxiliary.directory.operate.MakeDirectory;
/**
* 该类用于向xml文件中写入页面元素的定位方式
* @author 彭宇琦
* @version Ver0.7
*/
public class WriteXml {
// 用于设置到xml文件存放的路径
private StringBuilder xmlPath;
// 用于读取XML文件
private Document dom;
/**
* 用于构造对象并设置xml文件的路径
*
* @param xmlPath
* 代读取的xml文件路径
*/
public WriteXml(String xmlPath) {
setXmlPath(xmlPath);
}
/**
* 该方法用于返回xml文件存放的位置
*
* @return xml文件存放的位置
*/
public String getXmlPath() {
return xmlPath.toString();
}
/**
* 该方法用于重新设置xml文件存放的路径并将Document对象指向新的XML文件
*
* @param xmlPath
* xml的存放路径
*/
public void setXmlPath(String xmlPath) {
// 将传入的参数进行格式化
StringBuilder sb = new StringBuilder(xmlPath);
sb = MakeDirectory.formatPath(sb);
// 判断格式化后的文件路径格式是否符合windonws下文件路径的命名规则,不符合则抛出异常
if (!MakeDirectory.isPath(sb.toString())) {
throw new IncorrectDirectoryException("不合理的文件夹路径,文件路径:"
+ sb.toString());
}
// 重新构造Document对象使其指向新的XML文件
try {
dom = new SAXReader().read(sb.toString());
} catch (DocumentException e) {
// 若抛出异常则将异常转换为自定义的IncorrectXMLFileException异常使其不需要在编译时处理
throw new IncorrectXmlPathException("XML文件不正确或XML路径不正确");
}
// 将文件路径设置入属性中
this.xmlPath = sb;
}
/**
* 该方法用于向xml文件中添加页面元素的定位方式
* @param name 页面元素的名称
* @param mode 定位的方式
* @param value 定位路径
* @return
*/
public boolean writeElement(String name, String mode, String value) {
//获取根元素
Element e = dom.getRootElement();
//在根元素下方添加新元素
e.addElement("element").addAttribute("name", name).addText(value);
return true;
}
}

View File

@ -32,6 +32,7 @@ import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import pres.auxiliary.work.selenium.datadriven.ListFileRead;
import pres.auxiliary.work.testcase.templet.Case;
import pres.auxiliary.work.testcase.templet.LabelNotFoundException;

View File

@ -20,6 +20,7 @@ import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import pres.auxiliary.work.selenium.datadriven.ListFileRead;
import pres.auxiliary.work.testcase.templet.LabelNotFoundException;
/**

View File

@ -20,7 +20,6 @@ import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
import pres.auxiliary.directory.exception.IncorrectDirectoryException;
import pres.auxiliary.work.old.testcase.templet.ZentaoTemplet;
public class WriteCaseMainFrame extends JFrame {

View File

@ -4,7 +4,6 @@ import java.io.File;
import org.junit.Test;
import pres.auxiliary.work.selenium.xml.CreateXml;
import pres.auxiliary.work.selenium.xml.XmlFileNameIsNullException;
/**

View File

@ -0,0 +1,15 @@
package pres.auxiliary.tool.randomstring;
import org.testng.annotations.Test;
public class PresetStringTest {
@Test
public void IdentityCardTest() {
System.out.println(PresetString.identityCard());
}
@Test
public void getMobleNumberTest() {
System.out.println(PresetString.mobleNumber(MobleNumberType.CHINA_MOBILE));
}
}

View File

@ -3,6 +3,8 @@ package pres.auxiliary.work.selenium.brower;
import java.io.File;
import java.util.Scanner;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
@ -228,4 +230,70 @@ public class TestChromeBrower {
cb.switchWindow(page);
cb.closeLabel();
}
@Test
public void hasPopuWindowTest() {
Page page = new Page("http://test.gxjzgr.caihcloud.com/#/home/index", "桂建通");
cb = new ChromeBrower(driverFile, page);
//不加载图片
cb.addConfig(ChromeOptionType.DONOT_LOAD_IMAGE);
cb.addConfig(ChromeOptionType.SET_WINDOW_MAX_SIZE);
WebDriver driver = cb.getDriver();
System.out.println("是否存在弹窗:" + cb.hasPopuWindow());
driver.findElement(By.xpath("//*[text()='账号注册']")).click();
driver.findElement(By.xpath("//*[text()='账号注册']")).click();
driver.findElement(By.xpath("//*[text()='账号注册']")).click();
System.out.println("是否存在弹窗:" + cb.hasPopuWindow());
}
@Test
public void switchPopuWindowTest_singlePage() {
Page page = new Page("http://test.gxjzgr.caihcloud.com/#/home/index", "桂建通");
cb = new ChromeBrower(driverFile, page);
//不加载图片
cb.addConfig(ChromeOptionType.DONOT_LOAD_IMAGE);
cb.addConfig(ChromeOptionType.SET_WINDOW_MAX_SIZE);
WebDriver driver = cb.getDriver();
driver.findElement(By.xpath("//*[text()='账号注册']")).click();
// cb.switchNowPage();
System.out.println("是否切换至弹窗:" + cb.switchPopuWindow());
System.out.println(cb.getNowPage().getPageName());
cb.closeLabel();
}
@Test
public void switchPopuWindowTest_MuPage() {
Page page = new Page("http://test.gxjzgr.caihcloud.com/#/home/index", "桂建通");
cb = new ChromeBrower(driverFile, page);
//不加载图片
cb.addConfig(ChromeOptionType.DONOT_LOAD_IMAGE);
cb.addConfig(ChromeOptionType.SET_WINDOW_MAX_SIZE);
WebDriver driver = cb.getDriver();
driver.findElement(By.xpath("//*[text()='账号注册']")).click();
driver.findElement(By.xpath("//*[text()='账号注册']")).click();
driver.findElement(By.xpath("//*[text()='账号注册']")).click();
driver.findElement(By.xpath("//*[text()='账号注册']")).click();
// cb.switchNowPage();
int i = 0;
do {
try {
driver.findElement(By.xpath("//*[@alog-action=\"search11111\"]")).click();
break;
} catch (Exception e) {
}
System.out.println(i++);
} while(cb.switchPopuWindow());
}
}

View File

@ -7,7 +7,6 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import pres.auxiliary.work.selenium.datadriven.DataDriven;
import pres.auxiliary.work.selenium.datadriven.DataNotFoundException;
public class TestDataDriven {

View File

@ -9,6 +9,7 @@ import org.testng.annotations.Test;
import pres.auxiliary.work.selenium.brower.ChromeBrower;
import pres.auxiliary.work.selenium.brower.ChromeBrower.ChromeOptionType;
import pres.auxiliary.work.selenium.element.copy.CommonBy;
/**
* <p><b>文件名</b>CommonElementTest.java</p>
@ -38,11 +39,6 @@ public class CommonByTest {
cb.getDriver().quit();
}
@BeforeMethod
public void switchRootFrame() {
ce.switchRootFrame();
}
/**
* 用于测试非xml文件中的传参进行窗体切换与元素的获取
*/
@ -99,7 +95,7 @@ public class CommonByTest {
@Test
public void getElementTest() {
File xmlFile = new File("src/test/java/pres/auxiliary/work/selenium/element/测试文件.xml");
ce.setXmlFile(xmlFile, false);
ce.setXmlFile(xmlFile);
System.out.println(ce.getElement("搜索条件", "工资单编号").getWebElement().getAttribute("type"));
}
}

View File

@ -0,0 +1,91 @@
package pres.auxiliary.work.selenium.element;
import java.io.File;
import java.util.ArrayList;
import org.openqa.selenium.By;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import pres.auxiliary.work.selenium.brower.ChromeBrower;
import pres.auxiliary.work.selenium.brower.ChromeBrower.ChromeOptionType;
import pres.auxiliary.work.selenium.element.copy.Element;
import pres.auxiliary.work.selenium.element.copy.ElementType;
public class ElementTest {
/**
* 主窗体元素
*/
Element mainFrameElement;
/**
* 工资发放详情窗体元素
*/
Element payrollFrameElement;
/**
* 单位名称元素
*/
Element comNameElement;
/**
* 专户名称元素
*/
Element payrollElement;
/**
* 标题元素
*/
Element titleElement;
ChromeBrower cb;
@BeforeClass
public void init() {
cb = new ChromeBrower(new File("Resource/BrowersDriver/Chrom/78.0394.70/chromedriver.exe"));
cb.addConfig(ChromeOptionType.CONTRAL_OPEN_BROWER, "127.0.0.1:9222");
ArrayList<By> mainFrameByList = new ArrayList<By>();
mainFrameByList.add(By.xpath("//iframe[contains(@src,'/Regulatory/admin/index.jsp')]"));
mainFrameElement = new Element(cb, "主窗体元素", ElementType.COMMON_ELEMENT, 0);
mainFrameElement.setByList(mainFrameByList);
ArrayList<By> payrollFrameByList = new ArrayList<By>();
payrollFrameByList.add(By.xpath("//iframe[contains(@src,'工资单管理')]"));
payrollFrameElement = new Element(cb, "工资发放详情窗体元素", ElementType.COMMON_ELEMENT, 0);
payrollFrameElement.setByList(payrollFrameByList);
payrollFrameElement.setIframeElement(mainFrameElement);
ArrayList<By> comNameByList = new ArrayList<By>();
comNameByList.add(By.xpath("//*[@id='listBox']/li[1]/div[1]/p/span[1]"));
comNameElement = new Element(cb, "单位名称元素", ElementType.COMMON_ELEMENT, 0);
comNameElement.setByList(comNameByList);
comNameElement.setIframeElement(payrollFrameElement);
ArrayList<By> payrollByList = new ArrayList<By>();
payrollByList.add(By.xpath("//*[@class='pay-code']"));
payrollElement = new Element(cb, "专户名称元素", ElementType.COMMON_ELEMENT, 0);
payrollElement.setByList(payrollByList);
payrollElement.setIframeElement(payrollFrameElement);
ArrayList<By> titleByList = new ArrayList<By>();
titleByList.add(By.xpath("//*[@lay-id='工资单管理']"));
titleElement = new Element(cb, "标题元素", ElementType.COMMON_ELEMENT, 0);
titleElement.setByList(titleByList);
titleElement.setIframeElement(mainFrameElement);
}
@AfterClass
public void closeDriver() {
cb.getDriver().quit();
}
@Test
public void getWebElementTest() {
System.out.println(comNameElement.getWebElement().getText());
System.out.println("----------------------------------------");
System.out.println(payrollElement.getWebElement().getText());
System.out.println("----------------------------------------");
System.out.println(titleElement.getWebElement().getText());
System.out.println("----------------------------------------");
System.out.println(payrollElement.getWebElement().getText());
}
}

View File

@ -2,7 +2,6 @@ package test.javase;
import java.io.File;
import pres.auxiliary.work.selenium.xml.CreateXml;
import pres.auxiliary.work.selenium.xml.XmlFileNameIsNullException;

View File

@ -1,7 +1,5 @@
package test.javase;
import pres.auxiliary.directory.operate.MakeDirectory;
public class TestMakeDirector {
public static void main(String[] args) {
// MakeDirectory.createAllFolder();