调试事件类,使其适应当前元素类,并添加事件及返回值

This commit is contained in:
彭宇琦 2020-10-18 16:39:25 +08:00
parent 296cf3e334
commit d3d394f8a9
32 changed files with 353 additions and 324 deletions

View File

@ -18,11 +18,10 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="lib" path="lib/beautyeye_lnf.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
@ -48,5 +47,6 @@
<attribute name="optional" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -152,13 +152,13 @@
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<!--
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.3.0</version>
<scope>test</scope>
</dependency>
</dependency>-->
</dependencies>
</project>

View File

@ -38,9 +38,6 @@ import org.dom4j.io.XMLWriter;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import pres.auxiliary.work.selenium.xml.ByType;
import pres.auxiliary.work.selenium.xml.ReadXml;
/**
* 该类用于从禅道上导出的BUG列表使用项目路径下Templet的模版文件TestReportTemplet.docx来生成测试报告
* 支持压缩测试报告文件以及发送邮件到项目相关的人员邮件功能需要配置项目路径下的ConfigurationFiles/

View File

@ -13,6 +13,7 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
import javax.swing.border.EmptyBorder;
import org.dom4j.DocumentException;
@ -40,7 +41,7 @@ public class SandMailFrame extends JFrame {
*/
public SandMailFrame() {
setTitle("\u68C0\u67E5\u90AE\u4EF6\u63A5\u6536\u4EBA");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(100, 100, 487, 607);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

View File

@ -25,6 +25,7 @@ import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpinnerDateModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.WindowConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@ -95,7 +96,7 @@ public class TestReportFrame extends JFrame {
public TestReportFrame() {
setResizable(false);
setTitle("\u6D4B\u8BD5\u62A5\u544A\u751F\u6210\u5668");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(100, 100, 634, 791);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

View File

@ -16,6 +16,7 @@ import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;
@ -133,7 +134,7 @@ public class TestReportMainFrame extends JFrame {
public TestReportMainFrame() {
setTitle("\u6D4B\u8BD5\u62A5\u544A\u751F\u6210\u5668");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBounds(100, 100, 530, 207);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

View File

@ -1062,7 +1062,7 @@ public abstract class AbstractWriteExcel<T extends AbstractWriteExcel<T>> {
//遍历所有字符计算相应的值
for (int i = 0; i < indexs.length; i++) {
//按照(字母对应数字) * 26 ^ (字母位下标)的公式对计算的数字进行累加得到对应的数字下标
numberIndex += (((int)(indexs[i] - 'A' + 1)) * Math.pow(26, indexs.length - i - 1));
numberIndex += ((indexs[i] - 'A' + 1) * Math.pow(26, indexs.length - i - 1));
}
return numberIndex;

View File

@ -15,7 +15,6 @@ import pres.auxiliary.work.old.testcase.writecase.BrowseList;
import pres.auxiliary.work.old.testcase.writecase.FileType;
import pres.auxiliary.work.old.testcase.writecase.InputType;
import pres.auxiliary.work.old.testcase.writecase.PhoneType;
import pres.auxiliary.work.selenium.xml.IncorrectXmlPathException;
/**
* 该类用于通过XML文件结构来生成测试用例

View File

@ -316,13 +316,12 @@ public abstract class AbstractBy {
/**
* 用于返回当前存储的{@link WebElement}对象若该对象为空则抛出元素查找超时异常
* @return {@link WebElement}对象
* @throws TimeoutException 元素在页面不存在时抛出的异常
* @throws NoSuchElementException 元素集合不存在指定的下标时抛出的异常
* @throws NoSuchElementException 元素在页面不存在时或元素集合不存在指定的下标时抛出的异常
*/
public WebElement getWebElement() {
//判断元素集合是否为空若为空则抛出查找超时异常
if (elementList == null || elementList.size() == 0) {
throw new TimeoutException("页面上无相应定位方式的元素,当前元素名称:" + elementData.getName());
throw new NoSuchElementException("页面上无相应定位方式的元素,当前元素名称:" + elementData.getName());
}
//判断元素下标是否为-1若为-1则抛出元素不存在异常
@ -333,6 +332,14 @@ public abstract class AbstractBy {
return elementList.get(index);
}
/**
* 用于返回当前元素的{@link ElementData}类对象
* @return 当前元素的{@link ElementData}类对象
*/
public ElementData getElementData() {
return elementData;
}
/**
* 重新根据元素信息在页面查找元素
*/

View File

@ -2,9 +2,13 @@ package pres.auxiliary.work.selenium.event;
import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.AbstractBy.Element;
/**
* <p><b>文件名</b>AbstractEvent.java</p>
* <p><b>用途</b>所有事件类的基类包含了事件类所用到的基础方法以及弹窗处理方法和窗体窗口的切换方法</p>
@ -12,35 +16,50 @@ import org.openqa.selenium.support.ui.WebDriverWait;
* <p><b>修改时间</b>2020年7月10日上午16:49:37</p>
* @author 彭宇琦
* @version Ver1.0
* @since JDK 12
* @since JDK 8
*
*/
public abstract class AbstractEvent {
/**
* 用于存储浏览器的WebDriver对象设为静态保证所有的子类只使用一个WebDriver对象以避免造成WebDriver不正确导致的Bug
* 定义定位到元素相应位置的js代码
*/
WebDriver driver;
protected final String LOCATION_ELEMENT_JS = "arguments[0].scrollIntoView(false);";
/**
* 用于存储浏览器对象
*/
protected AbstractBrower brower;
/**
* 用于存储事件等待事件
*/
WebDriverWait wait;
protected WebDriverWait wait;
/**
* 设置显示等待的超时时间默认3秒
*/
long waitTime = 5;
protected long waitTime = 5;
/**
* 构造对象并存储浏览器的WebDriver对象
*
* @param driver 浏览器的WebDriver对象
* 存储操作的日志文本
*/
public AbstractEvent(WebDriver driver) {
this.driver = driver;
wait = new WebDriverWait(driver, waitTime, 200);
protected String logText = "";
/**
* 存储操作的返回值文本
*/
protected String resultText = "";
/**
* 构造对象并存储浏览器对象
*
* @param brower 浏览器{@link AbstractBrower}对象
*/
public AbstractEvent(AbstractBrower brower) {
this.brower = brower;
wait = new WebDriverWait(brower.getDriver(), waitTime, 200);
wait.withMessage("操作超时,当前元素无法进行该操作");
}
/**
* 用于设置事件等待时间默认时间为3秒
* 用于设置事件等待时间默认时间为5
*
* @param waitTime 事件等待时间
*/
@ -49,10 +68,32 @@ public abstract class AbstractEvent {
}
/**
* 用于返回存储的{@link WebDriver}类对象
* @return{@link WebDriver}类对象
* 返回操作的日志
* @return 操作日志
*/
public WebDriver getDriver() {
return driver;
public String getLogText() {
return logText;
}
/**
* 返回操作的返回值若操作无返回值时则返回空串
* @return 操作返回值
*/
public String getResultText() {
return resultText;
}
/**
* 用于通过js脚本将页面定位元素所在位置
* @param element {@link Element}对象
*/
protected void locationElement(Element element) {
//若抛出NoSuchElementException异常则将异常抛出其他异常将不做处理
try {
((JavascriptExecutor) brower.getDriver()).executeScript(LOCATION_ELEMENT_JS, element.getWebElement());
} catch (NoSuchElementException e) {
throw e;
} catch (Exception e) {
}
}
}

View File

@ -1,11 +1,11 @@
package pres.auxiliary.work.selenium.event;
import org.openqa.selenium.ElementClickInterceptedException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.AbstractBy.Element;
/**
@ -14,103 +14,107 @@ import pres.auxiliary.work.selenium.element.AbstractBy.Element;
* 定义了对控件进行点击操作相关的方法可通过该类对页面进行基本的点击操作
* </p>
* <p><b>编码时间</b>2019年8月29日下午3:24:34</p>
* <p><b>修改时间</b>2020年7月10日上午16:49:37</p>
* <p><b>修改时间</b>2020年10月17日下午16:34:37</p>
*
* @author 彭宇琦
* @version Ver2.0
* @since JDK 12
* @since JDK 8
*
*/
public class ClickEvent extends AbstractEvent {
/**
* 构造ClickEvent类对象
* 构造对象
*
* @param driver WebDriver类对象
* @param brower 浏览器{@link AbstractBrower}类对象
*/
public ClickEvent(WebDriver driver) {
super(driver);
public ClickEvent(AbstractBrower brower) {
super(brower);
}
/**
* 鼠标左键单击事件
*
* @param element 通过查找页面得到的控件元素对象
* @param element {@link Element}对象
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
*/
public void click(Element element) {
//在等待时间内判断元素是否可以点击
try {
wait.until(ExpectedConditions.elementToBeClickable(element.getWebElement()));
} catch (Exception e) {
}
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//进行操作若仍抛出ElementClickInterceptedException异常则再等待直到不再抛出异常
//在指定的时间内判断是否能进行点击若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
element.getWebElement().click();
return true;
} catch (ElementClickInterceptedException e) {
return false;
} catch (StaleElementReferenceException e) {
element.againFindElement();
return false;
throw e;
}
});
logText = "左键点击“" + element.getElementData().getName() + "”元素";
resultText = "";
}
/**
* 鼠标左键双击事件
*
* @param element 通过查找页面得到的控件元素对象
* @param element {@link Element}对象
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
*/
public void doubleClick(Element element) {
//在等待时间内判断元素是否可以点击
try {
wait.until(ExpectedConditions.elementToBeClickable(element.getWebElement()));
} catch (Exception e) {
}
//进行操作若仍抛出ElementClickInterceptedException异常则再等待直到不再抛出异常
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//在指定的时间内判断是否能进行点击若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
new Actions(driver).doubleClick(element.getWebElement()).perform();
return true;
} catch (ElementClickInterceptedException e) {
return false;
} catch (StaleElementReferenceException e) {
element.againFindElement();
return false;
throw e;
}
});
logText = "左键双击“" + element.getElementData().getName() + "”元素";
resultText = "";
}
/**
* 鼠标右键点击事件
* @param element 通过查找页面得到的控件元素对象
* @param element {@link Element}对象
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
*/
public void rightClick(Element element) {
//在等待时间内判断元素是否可以点击
try {
wait.until(ExpectedConditions.elementToBeClickable(element.getWebElement()));
} catch (Exception e) {
}
//进行操作若仍抛出ElementClickInterceptedException异常则再等待直到不再抛出异常
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//在指定的时间内判断是否能进行点击若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
new Actions(driver).contextClick(element.getWebElement()).perform();
return true;
} catch (ElementClickInterceptedException e) {
return false;
} catch (StaleElementReferenceException e) {
element.againFindElement();
return false;
}
throw e;
}
});
logText = "右键点击“" + element.getElementData().getName() + "”元素";
resultText = "";
}
/**
* 连续进行指定次数的鼠标左键点击事件
* @param element 通过查找页面得到的控件元素对象
* @param element {@link Element}对象
* @param clickCount 点击次数
* @param sleepInMillis 操作时间间隔单位为毫秒
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
*/
public void continuousClick(Element element, int clickCount, long sleepInMillis) {
for(int i = 0; i < clickCount; i++) {
@ -122,5 +126,8 @@ public class ClickEvent extends AbstractEvent {
continue;
}
}
logText = "左键连续点击“" + element.getElementData().getName() + "”元素" + clickCount + "";
resultText = "";
}
}

View File

@ -1,7 +1,5 @@
package pres.auxiliary.work.selenium.event;
import pres.auxiliary.work.selenium.element.Element_Old;
/**
* <p><b>文件名</b>EventAction.java</p>
* <p><b>用途</b>

View File

@ -4,7 +4,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import pres.auxiliary.work.selenium.element.Element_Old;
import pres.auxiliary.work.selenium.element.AbstractBy.Element;
/**
* <p><b>文件名</b>EventInformation.java</p>
@ -29,7 +29,7 @@ public class EventInformation {
/**
* 存储传入到方法中的元素类对象由args进行分离
*/
private ArrayList<Element_Old> elementList = new ArrayList<>();
private ArrayList<Element> elementList = new ArrayList<>();
/**
* 构造对象
@ -64,7 +64,7 @@ public class EventInformation {
* 用于返回传入到方法中{@link Element_Old}类对象集合
* @return {@link Element_Old}类对象集合
*/
public ArrayList<Element_Old> getElement() {
public ArrayList<Element> getElement() {
return elementList;
}
@ -73,8 +73,8 @@ public class EventInformation {
*/
private void toElement() {
Arrays.stream(args).forEach(arg -> {
if (arg instanceof Element_Old) {
elementList.add((Element_Old) arg);
if (arg instanceof Element) {
elementList.add((Element) arg);
}
});
}

View File

@ -12,7 +12,6 @@ import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import pres.auxiliary.work.selenium.brower.ChromeBrower;
import pres.auxiliary.work.selenium.element.Element_Old;
/**
* <p><b>文件名</b>EventProxy.java</p>

View File

@ -2,20 +2,17 @@ package pres.auxiliary.work.selenium.event;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.AbstractBy.Element;
import pres.auxiliary.work.selenium.element.ElementType;
/**
* <p>
@ -28,12 +25,12 @@ import pres.auxiliary.work.selenium.element.ElementType;
* <b>编码时间</b>2018年12月2日 下午12:51:19
* </p>
* <p>
* <b>修改时间</b>2020年5月17日 下午5:21:44
* <b>修改时间</b>2020年10月18日 下午3:52:44
* </p>
*
* @author 彭宇琦
* @version Ver1.0
* @since JDK 12
* @since JDK 8
*/
public class JsEvent extends AbstractEvent {
/**
@ -44,21 +41,23 @@ public class JsEvent extends AbstractEvent {
/**
* 构造对象
*
* @param driver 页面WebDriver对象
* @param brower 浏览器{@link AbstractBrower}对象
*/
public JsEvent(WebDriver driver) {
super(driver);
js = (JavascriptExecutor) this.driver;
public JsEvent(AbstractBrower brower) {
super(brower);
}
/**
* 获取元素的指定的属性值若属性不存在时则返回空串
*
* @param element 元素
* @param element {@link Element}对象
* @param attributeName 属性名
* @return 元素对应属性的内容
*/
public String getAttribute(Element element, String attributeName) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
// 获取对应元素的内容
String text = (String) (js.executeScript("return arguments[0].getAttribute('" + attributeName + "');",
wait.until(driver -> {
@ -66,24 +65,30 @@ public class JsEvent extends AbstractEvent {
return element.getWebElement();
} catch (StaleElementReferenceException e) {
element.againFindElement();
return null;
throw e;
}
})));
// 返回对应属性的内容若传入的属性不存在则返回空串
return (text == null) ? "" : text;
logText = "获取“" + element.getElementData().getName() + "”元素的" + attributeName + "属性的属性值";
resultText = (text == null) ? "" : text;
return resultText;
}
/**
* 设置元素的属性值并返回属性的原值若设置的属性名不存在时则在该元素上增加相应的属性
*
* @param element 元素
* @param element {@link Element}对象
* @param attributeName 需要设置的属性名
* @param value 需要设置的属性值
* @return 属性的原值
*/
public String putAttribute(Element element, String attributeName, String value) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
// 获取原属性中的值
String oldValue = getAttribute(element, attributeName);
resultText = getAttribute(element, attributeName);
// 执行代码
js.executeScript("arguments[0].setAttribute('" + attributeName + "','" + value + "');", wait.until(driver -> {
@ -91,21 +96,26 @@ public class JsEvent extends AbstractEvent {
return element.getWebElement();
} catch (StaleElementReferenceException e) {
element.againFindElement();
return null;
throw e;
}
}));
return oldValue;
logText = "设置“" + element.getElementData().getName() + "”元素的" + attributeName + "属性的属性值";
return resultText;
}
/**
* 在指定的元素下方添加一个元素元素将带一个名为temp_attribute的属性其属性的值为一个uuid并且添加成功后
* 方法返回该元素定位xpath格式为//标签名[@temp_attribute='uuid']
*
* @param element 元素
* @param element {@link Element}对象
* @param elementName 新元素标签的名称
* @return 新增元素的定位方式
*/
public String addElement(Element element, String elementName) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
// 获取并将其作为
String script = "var oldElement = arguments[0];";
// 拼接添加元素的代码
@ -122,44 +132,14 @@ public class JsEvent extends AbstractEvent {
return element.getWebElement();
} catch (StaleElementReferenceException e) {
element.againFindElement();
return null;
throw e;
}
}));
return "//" + elementName + "[@temp_attribute='" + uuid + "']";
}
/**
* 根据json中的属性及元素名称信息在指定元素下添加一个元素元素将带一个
* 名为temp_attribute的属性其属性的值为一个uuid并且添加成功后
* 方法返回该元素定位xpath格式为//标签名[@temp_attribute='uuid']
* 传入的json格式可以参照{@link #deleteElement(WebElement)}方法中 返回的json形式
*
* @param element 元素
* @param elementJson 新元素标签的信息
* @return 新增元素的定位方式
*/
public String addElement(Element element, JSONObject elementJson) {
// 添加元素
String elementName = elementJson.getString("tagname");
// 获取新添加元素的xpath
String xpath = addElement(element, elementName);
// 查找新添加的元素由于是新添加的元素肯定能查找到故无需编写等待
Element newElement = new Element(driver, "TeamElement", ElementType.COMMON_ELEMENT);
List<By> byList = new ArrayList<>();
byList.add(By.xpath(xpath));
newElement.setByList(byList);
// 获取元素的所有属性
JSONArray attributes = elementJson.getJSONArray("attributes");
// 遍历属性信息向元素中添加属性
for (int i = 0; i < attributes.size(); i++) {
JSONObject attJson = attributes.getJSONObject(i);
putAttribute(newElement, attJson.getString("name"), attJson.getString("value"));
}
return xpath;
logText = "在“" + element.getElementData().getName() + "”元素下添加“" + elementName + "”元素";
resultText = "//" + elementName + "[@temp_attribute='" + uuid + "']";
return resultText;
}
/**
@ -186,13 +166,16 @@ public class JsEvent extends AbstractEvent {
* @return 元素的信息
*/
public JSONObject deleteElement(Element element) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//获取元素信息
JSONObject json = getElementInfromation(wait.until(driver -> {
try {
return element.getWebElement();
} catch (StaleElementReferenceException e) {
element.againFindElement();
return null;
throw e;
}
}));
@ -206,26 +189,12 @@ public class JsEvent extends AbstractEvent {
// 执行代码由于在获取元素信息时已经对元素的过期进行了判断故此处无需在做判断
js.executeScript(script, element.getWebElement());
/*
var a = document.getElementById('psd')
var aa = a.parentNode
aa.removeChild(a)
*
* */
logText = "删除“" + element.getElementData().getName() + "”元素";
resultText = json.toJSONString();
return json;
}
/**
* 用于执行已经写好的js脚本
*
* @param script js脚本
* @return 执行结果
*/
public Object runScript(String script) {
// 执行代码
return js.executeScript(script);
}
/**
* 用于执行已经写好的js脚本
*
@ -234,6 +203,9 @@ public class JsEvent extends AbstractEvent {
* @return 执行结果
*/
public Object runScript(String script, Object... args) {
logText = "执行脚本:" + script;
resultText = "";
// 执行代码
return js.executeScript(script, args);
}

View File

@ -2,18 +2,18 @@ package pres.auxiliary.work.selenium.event;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import pres.auxiliary.tool.randomstring.RandomString;
import pres.auxiliary.tool.randomstring.StringMode;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
import pres.auxiliary.work.selenium.element.AbstractBy.Element;
import pres.auxiliary.work.selenium.tool.RecognitionImage;
import pres.auxiliary.work.selenium.tool.Screenshot;
@ -22,9 +22,9 @@ import pres.auxiliary.work.selenium.tool.Screenshot;
* <p><b>文件名</b>TextEvent.java</p>
* <p><b>用途</b>定义了对控件文本操作相关的方法可通过该类对页面进行对控件输入文本获取等操作</p>
* <p><b>编码时间</b>2019年9月6日上午9:28:59</p>
* <p><b>修改时间</b>2020年7月10日上午16:49:37</p>
* <p><b>修改时间</b>2020年10月17日下午16:34:37</p>
* @author 彭宇琦
* @version Ver1.0
* @version Ver2.0
* @since JDK 8
*
*/
@ -35,116 +35,169 @@ public class TextEvent extends AbstractEvent {
private final String TESSDATA = "tessdata";
/**
* 构造TextEvent类对象
* @param driver WebDriver类对象
* 构造对象
*
* @param brower 浏览器{@link AbstractBrower}类对象
*/
public TextEvent(WebDriver driver) {
super(driver);
public TextEvent(AbstractBrower brower) {
super(brower);
}
/**
* 该方法通过控件名称或定位方式对页面元素进行定位来清空控件中的内容主要用于清空文本框中已有的数据该方法将存储被清空的
* 文本
* @param element 通过查找页面得到的控件元素对象
* @param element {@link Element}对象
* @return 被清空的文本内容
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
*/
public String clear(Element element) {
//由于需要存储步骤若直接调用getText方法进行返回时其会更改存储的step为保证step正确故存储返回值进行返回
String text = getText(element);
//对元素进行操作若元素过期则重新获取
wait.until(driver -> {
try {
element.getWebElement().clear();
return true;
} catch (StaleElementReferenceException e) {
element.againFindElement();
return false;
}
});
resultText = getText(element);
//由于在获取元素时已对元素进行相应操作等待故此处将不再重新获取
element.getWebElement().clear();
return text;
logText = "清除“" + element.getElementData().getName() + "”元素中的文本内容";
return resultText;
}
/**
* 用于获取元素中的指定属性值的内容
* @param element 通过查找页面得到的控件元素对象
* @param element {@link Element}对象
* @param attributeName 属性名称
* @return 对应属性的值
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
*/
public String getAttributeValue(Element element, String attributeName) {
//等待元素中attributeName指向的属性内容出现
wait.until(ExpectedConditions.attributeToBeNotEmpty(element.getWebElement(), attributeName));
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//对元素进行操作若元素过期则重新获取
return wait.until(driver -> {
//在指定的时间内判断是否能进行操作若抛出StaleElementReferenceException异常则重新获取元素
resultText = wait.until((driver) -> {
try {
return element.getWebElement().getAttribute(attributeName);
} catch (StaleElementReferenceException e) {
element.againFindElement();
return null;
throw e;
}
});
logText = "获取“" + element.getElementData().getName() + "”元素的" + attributeName + "属性的属性值";
return resultText;
}
/**
* 用于获取相应元素中的文本内容
* @param element 通过查找页面得到的控件元素对象
* @param element {@link Element}对象
* @return 对应元素中的文本内容
* @throws NoSuchElementException 元素不存在或下标有误时抛出的异常
* @throws TimeoutException 元素无法操作时抛出的异常
*/
public String getText(Element element) {
//对元素进行操作若元素过期则重新获取
return wait.until(driver -> {
try {
WebElement webElement = element.getWebElement();
return "input".equalsIgnoreCase(webElement.getTagName()) ? webElement.getAttribute("value") : webElement.getText();
} catch (StaleElementReferenceException e) {
element.againFindElement();
return null;
}
});
}
/**
* 用于在指定的控件中输入相应的内容允许向控件中传入{@link Keys}枚举
* @param element 通过查找页面得到的控件元素对象
* @param keysToSend 需要输入到控件中的
* @return 在控件中输入的内容
*/
public String input(Element element, CharSequence... keysToSend) {
//等待事件可操作后对事件进行操作
wait.until(driver -> {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//在指定的时间内判断是否能进行操作若抛出StaleElementReferenceException异常则重新获取元素
resultText = wait.until((driver) -> {
try {
element.getWebElement().sendKeys(keysToSend);
return true;
} catch (Exception e) {
return false;
WebElement webElement = element.getWebElement();
return "input".equalsIgnoreCase(webElement.getTagName()) ? webElement.getAttribute("value") : webElement.getText();
} catch (StaleElementReferenceException e) {
element.againFindElement();
throw e;
}
});
//TODO 拆成两个方法否则不好写返回结果
String result = "[";
for (CharSequence key : keysToSend) {
result += key.toString() + ", ";
}
return keysToSend.toString();
logText = "获取“" + element.getElementData().getName() + "”元素的文本内容";
return resultText;
}
/**
* 用于在指定的控件中输入相应的内容
* @param element {@link Element}对象
* @param text 需要输入到控件中的
* @return 在控件中输入的内容
*/
public String input(Element element, String text) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//在指定的时间内判断是否能进行操作若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
element.getWebElement().sendKeys(text);
return true;
} catch (StaleElementReferenceException e) {
element.againFindElement();
throw e;
}
});
logText = "在“" + element.getElementData().getName() + "”元素中输入" + text;
resultText = text;
return resultText;
}
/**
* 用于向页面上发送键盘按键可使用{@link Keys}枚举类控制发送的特殊按键
* 例如需要在页面上按下alt + d则可以传入<br>
* keyToSend(element, {@link Keys}.ALT, "d")
*
* @param element {@link Element}对象
* @param keys 需要传入的按键可传入{@link Keys}枚举类或字符串,若传入字符串则只取字符串中第一个字母
* @return 发送按键组合每个按键间用 + 字符串连接
*/
public String keyToSend(Element element, CharSequence... keys) {
//定位到元素上若元素不存在或下标有误时会抛出相应的异常
locationElement(element);
//在指定的时间内判断是否能进行操作若抛出StaleElementReferenceException异常则重新获取元素
wait.until((driver) -> {
try {
element.getWebElement().sendKeys(keys);
return true;
} catch (StaleElementReferenceException e) {
element.againFindElement();
throw e;
}
});
StringBuilder textBul = new StringBuilder();
Arrays.asList(keys).stream().map(key -> {
//判断key是否为Keys枚举若是则调用其name()方法否则调用toString()方法
if (key instanceof Keys) {
return ((Keys) key).name();
} else {
return key.toString();
}
}).forEach(text -> {
textBul.append(text);
textBul.append(" + ");
});
//删除最后多余的符号
resultText = textBul.substring(0, textBul.indexOf(" + "));
logText = "在“" + element.getElementData().getName() + "”元素发送按键“" + resultText + "";
return resultText;
}
/**
* 用于对数字+英文类型的图片验证码进行输入的方法根据验证码图片元素位置识别图片中的验证码
* 并将结果填入对应的文本框中注意该方法识别验证码成功的概率不高数字+英文的验证码模式下
* 经常将数字识别为英文
*
* @param textElement 通过查找页面得到的文本框控件元素对象
* @param codeImageElement 通过查找页面得到的验证码图片控件元素对象
* @param textElement 通过查找页面得到的文本框控件{@link Element}对象
* @param codeImageElement 通过查找页面得到的验证码图片控件{@link Element}对象
* @return 输入的内容
*/
public String codeInput(Element textElement, Element codeImageElement) {
// 判断验证码信息是否加载加载后获取其Rectang对象
Rectangle r = codeImageElement.getWebElement().getRect();
// 构造截图对象并创建截图
Screenshot sc = new Screenshot(driver, new File("Temp"));
Screenshot sc = new Screenshot(brower.getDriver(), new File("Temp"));
File image = null;
try {
image = sc.creatImage("code");
@ -163,7 +216,11 @@ public class TextEvent extends AbstractEvent {
image.delete();
new File("Temp").delete();
return input(textElement, text);
resultText = input(textElement, text);
logText = "识别“" + codeImageElement.getElementData().getName() + "”图片中内容,在"
+ textElement.getElementData().getName() + "元素中输入" + text;
return resultText;
}
/**
@ -173,8 +230,11 @@ public class TextEvent extends AbstractEvent {
* @param num 指定的整数
* @param textElements 通过查找页面得到的一组控件元素对象
* @return 由于涉及到多个文本框故其返回值有多个将以值1,值2,值3...的形式进行返回
* @deprecated 当前方法有些BUG请勿调用下个版本修复
*/
@Deprecated
public String avgIntergeInput(int num, Element... elements) {
//TODO 存在BUG需要修改
//定义存储控件数量及需要随机的数量
int contrlNum = elements.length;
String inputNumText = "";
@ -211,72 +271,18 @@ public class TextEvent extends AbstractEvent {
return inputNumText.substring(0, inputNumText.length() - 1);
}
/**
* 通过指定的随机字符串长度与指定的随机字符串模型枚举{@link StringMode}枚举类向控件中
* 随机输入字符串
* @param element 通过查找页面得到的控件元素对象
* @param minLength 字符串最小长度设为小于等于0的数值时则默认为1
* @param maxLength 字符串最大长度设为小于等于0的数值时则默认为1若需要指定字符串的输入长度可设置minLength数值与maxLength一致
* @param modes {@link StringMode}枚举指定字符串输入的类型可传入多种模型参见{@link RandomString#RandomString(StringMode...)}
* @return 在控件中输入的内容
*/
public String randomInput(Element element, int minLength, int maxLength, StringMode... modes) {
return randomInput(element, minLength, maxLength, new RandomString(modes));
}
/**
* 通过指定的随机字符串长度与指定的随机字符串模型向控件中随机输入字符串操作
* @param element 通过查找页面得到的控件元素对象
* @param minLength 字符串最小长度设为小于等于0的数值时则默认为1
* @param maxLength 字符串最大长度设为小于等于0的数值时则默认为1若需要指定字符串的输入长度可设置minLength数值与maxLength一致
* @param mode 可用的随机字符串抽取范围参见{@link RandomString#RandomString(String)}
* @return 在控件中输入的内容
*/
public String randomInput(Element element, int minLength, int maxLength, String mode) {
return randomInput(element, minLength, maxLength, new RandomString(mode));
}
/**
* 用于向控件中上传指定的文件<br>
* @param element 通过查找页面得到的控件元素对象
* 用于向控件中上传指定的文件
*
* @param element {@link Element}对象
* @param updataFile 需要上传到控件中的文件
* @return 上传的文件路径
*/
public String updataFile(Element element, File updataFile) {
return input(element, updataFile.getAbsolutePath());
}
/**
* 向控件随机输入信息的底层方法
* @param element 通过查找页面得到的控件元素对象
* @param minLength 字符串最小长度设为小于等于0的数值时则默认为1
* @param maxLength 字符串最大长度设为小于等于0的数值时则默认为1若需要指定字符串的输入长度可设置minLength数值与maxLength一致
* @param rs 随机字符类对象
* @return 在控件中输入的内容
*/
private String randomInput(Element element, int minLength, int maxLength, RandomString rs) {
// 判断传入的参数是否小于0小于0则将其都设置为1
if (minLength < 0 || maxLength < 0) {
minLength = 1;
maxLength = 1;
}
// 判断传入的随机字符串最小生成长度是否大于最大生成长度若大于则调换两数字的位置
if (minLength > maxLength) {
int tem = minLength;
minLength = maxLength;
maxLength = tem;
}
resultText = input(element, updataFile.getAbsolutePath());
logText = "向“" + element.getElementData().getName() + "”元素中上传文件,文件路径为:“" + resultText + "";
//根据参数生成随机字符串
String text = "";
if (minLength == maxLength) {
text = rs.toString(maxLength);
} else {
text = rs.toString(minLength, maxLength);
}
//调用input方法进行返回
return input(element, text);
return resultText;
}
}

View File

@ -5,29 +5,32 @@ import java.time.Duration;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import pres.auxiliary.work.selenium.element.Element_Old;
import pres.auxiliary.work.selenium.brower.AbstractBrower;
public class EventWait {
public class WaitEvent extends AbstractEvent{
/**
* 控制等待
*/
private WebDriverWait wait;
/**
* 构造WaitEvent类对象默认60秒的查询超时时间可设置超时时间{@link #setOvertime(long)}
* @param driver WebDriver类对象
* 构造对象
*
* @param brower 浏览器{@link AbstractBrower}类对象
*/
public EventWait(WebDriver driver) {
this(driver, 60);
public WaitEvent(AbstractBrower brower) {
this(brower, 60);
}
/**
* 构造WaitEvent类对象并设置等待超时时间单位为秒
* @param driver WebDriver类对象
* 构造对象
*
* @param brower 浏览器{@link AbstractBrower}类对象
*/
public EventWait(WebDriver driver, long overtime) {
wait = new WebDriverWait(driver, overtime, 200);
wait.withMessage("元素仍然存在,操作超时:" + overtime + "");
public WaitEvent(AbstractBrower brower, long waitTime) {
super(brower);
wait = new WebDriverWait(brower.getDriver(), waitTime, 200);
wait.withMessage("等待超时,事件等待失败:" + waitTime + "");
}
/**

View File

@ -7,6 +7,7 @@ import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import pres.auxiliary.tool.date.Time;
@ -74,7 +75,7 @@ public class ExcelRecord extends AbstractWriteExcel<ExcelRecord> {
*/
public ExcelRecord setBrowerInformation(AbstractBrower brower) {
//获取浏览器信息将其转换为JSONObject对象
JSONObject json = JSONObject.parseObject(brower.getAllInformation());
JSONObject json = JSON.parseObject(brower.getAllInformation());
switchSheet("运行记录")
.addContent("brower", json.get("浏览器名称").toString())
.addContent("version", json.get("浏览器版本").toString())

View File

@ -12,7 +12,6 @@ import org.junit.Test;
import org.junit.rules.TestName;
import org.openqa.selenium.TimeoutException;
import pres.auxiliary.work.selenium.tool.ExcelRecord_Old;
import pres.auxiliary.work.selenium.tool.RecordTool;
import pres.auxiliary.work.selenium.tool.Screenshot;

View File

@ -4,8 +4,6 @@ import java.io.File;
import org.junit.Test;
import pres.auxiliary.work.selenium.xml.XmlFileNameIsNullException;
/**
* FileName: TestCreateXML.java
*

View File

@ -1,9 +1,11 @@
package pres.auxiliary.work.selenium.brower;
import java.io.File;
import java.util.Arrays;
import java.util.Scanner;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
@ -36,9 +38,7 @@ public class TestChromeBrower {
*/
@AfterClass
public void quit() {
cb.getAllInformation().forEach((k, v) -> {
System.out.println(k + "" + v);
});
System.out.println(cb.getAllInformation());
Scanner sc = new Scanner(System.in);
sc.next();
cb.closeBrower();
@ -135,6 +135,27 @@ public class TestChromeBrower {
cb.openUrl(new Page("http://www.hao123.com", "hao123"), true);
}
@Test
public void sendKey() {
cb = new ChromeBrower(new File("Resource/BrowersDriver/Chrom/83.0.4103.39/chromedriver.exe"));
//1027*768的分辨率启动
cb.addConfig(ChromeOptionType.CONTRAL_OPEN_BROWER, "127.0.0.1:9222");
cb.getDriver().findElement(By.id("kw")).sendKeys(Keys.CONTROL, "vfffsdfg");
show(Keys.CONTROL, "vfffsdfg");
}
public void show(CharSequence... keysToSend) {
Arrays.asList(keysToSend).stream().map(key -> {
if (key instanceof Keys) {
return ((Keys) key).name();
}
return key.toString();
})
.forEach(System.out :: println);
}
/**
* 测试在新浏览器中以原形式打开新页面并在基础上在当前标签中加载另一个页面
* @throws InterruptedException

View File

@ -8,8 +8,6 @@ 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.delect.CommonBy;
import pres.auxiliary.work.selenium.element.delect.DataListBy;
/**
* <p><b>文件名</b>CommonElementTest.java</p>

View File

@ -10,8 +10,6 @@ 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.delect.Element;
import pres.auxiliary.work.selenium.element.delect.ElementType;
public class ElementTest {
/**

View File

@ -8,9 +8,6 @@ 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.delect.old.CommonBy;
import pres.auxiliary.work.selenium.element.delect.old.Element;
import pres.auxiliary.work.selenium.element.delect.old.SelectBy;
import pres.auxiliary.work.selenium.event.ClickEvent;
/**

View File

@ -8,7 +8,6 @@ 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.delect.old.CommonBy;
import pres.auxiliary.work.selenium.event.EventProxy.ActionType;
public class EventProxyTest {

View File

@ -8,13 +8,11 @@ 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.delect.old.CommonBy;
import pres.auxiliary.work.selenium.element.delect.old.DataListBy;
/**
* <p><b>文件名</b>EventWaitTest.java</p>
* <p><b>用途</b>
* 用于对{@link EventWait}类进行测试
* 用于对{@link WaitEvent}类进行测试
* </p>
* <p><b>页面</b>
* 运维管理系统岗前答题库模块
@ -27,7 +25,7 @@ import pres.auxiliary.work.selenium.element.delect.old.DataListBy;
*
*/
public class EventWaitTest {
EventWait wait;
WaitEvent wait;
ClickEvent c;
TextEvent t;
CommonBy_Old cby;
@ -39,7 +37,7 @@ public class EventWaitTest {
cby = new CommonBy_Old(cb);
c = new ClickEvent(cb.getDriver());
t = new TextEvent(cb.getDriver());
wait = new EventWait(cb.getDriver());
wait = new WaitEvent(cb.getDriver());
}
@ -49,7 +47,7 @@ public class EventWaitTest {
}
/**
* 测试{@link EventWait#disappear(pres.auxiliary.work.selenium.element.Element)}方法
* 测试{@link WaitEvent#disappear(pres.auxiliary.work.selenium.element.Element)}方法
*/
@Test
public void disappearTest() {

View File

@ -13,8 +13,6 @@ import com.alibaba.fastjson.JSONObject;
import pres.auxiliary.work.selenium.brower.ChromeBrower;
import pres.auxiliary.work.selenium.brower.ChromeBrower.ChromeOptionType;
import pres.auxiliary.work.selenium.element.delect.old.CommonBy;
import pres.auxiliary.work.selenium.element.delect.old.Element;
/**
* <p><b>文件名</b>JsEventTest.java</p>

View File

@ -9,9 +9,6 @@ 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.delect.old.CommonBy;
import pres.auxiliary.work.selenium.element.delect.old.DataListBy;
import pres.auxiliary.work.selenium.element.delect.old.Element;
/**
* <p><b>文件名</b>CommonElementTest.java</p>

View File

@ -11,9 +11,7 @@ import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import pres.auxiliary.tool.file.MarkColorsType;
import pres.auxiliary.tool.file.excel.CreateExcelFile;
import pres.auxiliary.work.testcase.file.JiraTestCaseWrite.JiraFieldIdType;
import pres.auxiliary.work.testcase.templet.DataListCase;
/**

View File

@ -2,8 +2,6 @@ package test.javase;
import java.io.File;
import pres.auxiliary.work.selenium.xml.XmlFileNameIsNullException;
public class TestCreateXml {
public static void main(String[] args) throws XmlFileNameIsNullException {

View File

@ -1,7 +1,5 @@
package test.javase;
import pres.auxiliary.work.testcase.ui.WriteCaseMainFrame;
public class TestWriteCaseUI {
public static void main(String[] args) {
WriteCaseMainFrame.Main();

View File

@ -1,7 +1,6 @@
package test.javase;
import org.dom4j.DocumentException;
import pres.auxiliary.work.selenium.xml.XmlFileNameIsNullException;
public class testxml {