1、Selenium 介绍
Selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。
2、注意事项
我们这里不是入门教程,所以就不对 Selenium 和 Xpath 的用法做说明,已经会了的朋友,可以继续往下看,不会的朋友可以先学习一下Selenium 和Xpath。
3、工具包代码
原理其实很简单,我们只需要构造一个类似 Factory 的类,这样的好处是为了以后代码的更新换代,如果这个技术已经落后了,或者有了新的技术,我们的项目只需要更改 Factory 的实现就行了。
其次我们需要在每个方法中返回这个类对象,就可以实现链式编程。这样我们在开发中就会很方便,不用写很多冗余的代码。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
/**
* @company amazon
* @author huayanh
* @data 2019/07/08 16:25
*
*/
public class SeleniumFactory {
private boolean browseDisplayStatus;
private Integer maxTime;
private WebDriver driver;
private WebElement currentElement;
private List<WebElement> currentElements;
public boolean getBrowseDisplayStatus() {
return browseDisplayStatus;
}
public SeleniumFactory setBrowseDisplayStatus(boolean browseDisplayStatus) {
this.browseDisplayStatus = browseDisplayStatus;
return this;
}
public Integer getMaxTime() {
return maxTime;
}
public SeleniumFactory setMaxTime(Integer maxTime) {
this.maxTime = maxTime;
return this;
}
public SeleniumFactory build() throws Exception {
// Init Driver
try {
// Driver Path
System.setProperty("webdriver.gecko.driver", "geckodriver.exe");
// Display Browse
if (!browseDisplayStatus) {
FirefoxBinary firefoxBinary = new FirefoxBinary();
firefoxBinary.addCommandLineOptions("--disable-gpu");
firefoxBinary.addCommandLineOptions("--headless");
FirefoxOptions firefoxOptions = new FirefoxOptions();
firefoxOptions.setBinary(firefoxBinary);
driver = new FirefoxDriver(firefoxOptions);
} else {
driver = new FirefoxDriver();
}
// Page Load Time
driver.manage().timeouts().pageLoadTimeout(maxTime, TimeUnit.SECONDS);
return this;
} catch (Exception e) {
throw new Exception("Open Driver Exception,Please Update geckodriver.exe");
}
}
public SeleniumFactory openUrl(String url) throws Exception {
try {
driver.get(url);
scrollBottom();
scrollTop();
return this;
} catch (Exception e) {
throw new Exception("Open Url(" + url + ") Time Out Exception");
}
}
public SeleniumFactory findElementByXpath(String xpath) throws Exception {
int retryCount = 1;
while (true) {
try {
currentElement = driver.findElement(By.xpath(xpath));
return this;
} catch (Exception e) {
if (retryCount >= maxTime) {
throw new Exception("Find Element Xpath(" + xpath + ") Time Out Exception");
}
}
retryCount++;
Thread.sleep(1000);
}
}
public SeleniumFactory findElementsByXpath(String xpath) throws Exception {
int retryCount = 1;
while (true) {
currentElements = driver.findElements(By.xpath(xpath));
if (currentElements.size() != 0) {
return this;
}
if (retryCount >= maxTime) {
throw new Exception("Find Elements Xpath(" + xpath + ") Time Out Exception");
}
retryCount++;
Thread.sleep(1000);
}
}
public SeleniumFactory click() throws Exception {
try {
currentElement.click();
return this;
} catch (Exception e) {
throw new Exception("Click Element Time Out Exception");
}
}
public SeleniumFactory clickList() throws Exception {
try {
currentElements.forEach(ele -> {
ele.click();
});
return this;
} catch (Exception e) {
throw new Exception("Click Element List Time Out Exception");
}
}
public SeleniumFactory sendKey(CharSequence... keysToSend) throws Exception {
try {
currentElement.sendKeys(keysToSend);
return this;
} catch (Exception e) {
throw new Exception("Send Key To Element Time Out Exception");
}
}
public SeleniumFactory sendKeyList(CharSequence... keysToSend) throws Exception {
try {
currentElements.forEach(ele -> {
ele.sendKeys(keysToSend);
});
return this;
} catch (Exception e) {
throw new Exception("Send Key To Element List Time Out Exception");
}
}
public String getAttributeValue(String attributeName) throws Exception {
try {
return currentElement.getAttribute(attributeName);
} catch (Exception e) {
throw new Exception("Get Element Attribute Value Time Out Exception");
}
}
public List<String> getAttributeValueList(String attributeName) throws Exception {
try {
List<String> attributeValueList = new ArrayList<>();
currentElements.forEach(ele -> {
String attributeValue = ele.getAttribute(attributeName);
attributeValueList.add(attributeValue);
});
return attributeValueList;
} catch (Exception e) {
throw new Exception("Get Element Attribute Value List Time Out Exception");
}
}
public String getText() throws Exception {
try {
return currentElement.getText();
} catch (Exception e) {
throw new Exception("Get Element Text Time Out Exception");
}
}
public List<String> getTextList() throws Exception {
try {
List<String> textList = new ArrayList<>();
currentElements.forEach(ele -> {
String attributeValue = ele.getText();
textList.add(attributeValue);
});
return textList;
} catch (Exception e) {
throw new Exception("Get Element Text List Time Out Exception");
}
}
public void scrollBottom() throws Exception {
int retryCount = 1;
while (true) {
try {
String js = "document.documentElement.scrollTop=10000000";
((JavascriptExecutor) driver).executeScript(js);
break;
} catch (Exception e) {
if (retryCount >= maxTime) {
throw new Exception("JS Scroll Bottom Time Out Exception");
}
}
retryCount++;
Thread.sleep(1000);
}
}
public void scrollTop() throws Exception {
int retryCount = 1;
while (true) {
try {
String js = "document.documentElement.scrollTop=0";
((JavascriptExecutor) driver).executeScript(js);
break;
} catch (Exception e) {
if (retryCount >= maxTime) {
throw new Exception("JS Scroll Top Time Out Exception");
}
}
retryCount++;
Thread.sleep(1000);
}
}
public void close() throws Exception {
try {
driver.quit();
} catch (Exception e) {
throw new Exception("Close Driver Exception");
}
}
}
4、如何使用此工具
首先,创建一个Factory对象,之后按照顺序依次调用就可以实现。
我们这个例子是:模拟打开 Firefox 浏览器,打开百度,输入Java关键词,点击搜索。
import com.amazon.util.SeleniumFactory;
public class TestSelenium {
public static void main(String[] args) {
SeleniumFactory factory = new SeleniumFactory();
try {
factory.setBrowseDisplayStatus(true).setMaxTime(30).build();
factory.openUrl("https://www.baidu.com/")
.findElementByXpath("//input[@id=\"kw\"]").sendKey("Java")
.findElementByXpath("//input[@id=\"su\"]").click();
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
factory.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
5、声明
这里面的方法都是我封装了selenium 官方的一些方法,自己有其他想法的可以去尝试开发新的内容,而且我的代码中写了循环查询,其中我觉得selenium的等待机制不好用,所以自己写了个简单的。