[控制滚动]
package util;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;public class ScrollBarUtil {/*** 控制滚动条向下拉到底* @param driver 浏览器驱动*/public static void toBottom(WebDriver driver) {JavascriptExecutor js = (JavascriptExecutor) driver;//向下拉到底//js.executeScript("document.documentElement.scrollTop=10000");}/*** 控制滚动条向上拉到顶* @param driver 浏览器驱动*/public static void toTop(WebDriver driver) {JavascriptExecutor js = (JavascriptExecutor) driver;//向上拉到顶js.executeScript("document.documentElement.scrollTop=0");}/*** 控制滚动条向下拉到底* @param driver 浏览器驱动*/public static void scrolltoBottom(WebDriver driver) {JavascriptExecutor js = (JavascriptExecutor) driver;//向下拉到底js.executeScript("window.scrollTo(0,100000)");}/*** 控制滚动条向上拉到顶* @param driver 浏览器驱动*/public static void scrolltoTop(WebDriver driver) {JavascriptExecutor js = (JavascriptExecutor) driver;//向上拉到顶js.executeScript("window.scrollTo(0,1)");}/*** 控制滚动条拉到中间* @param driver 浏览器驱动*/public static void verticaltoMiddle(WebDriver driver) {JavascriptExecutor js = (JavascriptExecutor) driver;//上下拉到中间js.executeScript("window.scrollBy(0, 0-document.body.scrollHeight *1/2)");}/*** 控制水平滚动条左右拉到中间* @param driver 浏览器驱动*/public static void horizontaltoMiddle(WebDriver driver) {JavascriptExecutor js = (JavascriptExecutor) driver;//左右拉到中间js.executeScript("window.scrollBy(0, 0-document.body.scrollWidht *1/2)");}/*** 控制滚动条拉到元素可见* @param driver 浏览器驱动* @param element 页面元素定位*/public static void scrolltoPresence(WebDriver driver, WebElement element) {JavascriptExecutor js = (JavascriptExecutor) driver;//移动到元素element对象的“顶端”与当前窗口的“顶部”对齐//js.executeScript("arguments[0].scrollIntoView();", element);js.executeScript("arguments[0].scrollIntoView(true);", element);//移动到元素element对象的“底端”与当前窗口的“底部”对齐//js.executeScript("arguments[0].scrollIntoView(false);", element);}/*** 使用JavaScript的ScrollTo函数和document.body.scrollHeight参数* 将页面滚动到最下方* @param driver 浏览器驱动*/public static void scrollingToBottomofPage(WebDriver driver){((JavascriptExecutor) driver).executeScript("window.scrollTo(0, document.body.scrollHeight)");try{Thread.sleep(3000);}catch (InterruptedException e){e.printStackTrace();}}/*** 使用JavaScript的ScrollTo函数,使用0和800的横纵坐标参数* 将页面的滚动条纵向下滑800个像素* @param driver 浏览器驱动*/public static void scrollingByCoordinateofPage(WebDriver driver){((JavascriptExecutor) driver).executeScript("window.scrollBy(0,200)");try{Thread.sleep(3000);}catch (InterruptedException e){e.printStackTrace();}}
}
[模拟键盘]
package util;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;public class KeyBoardUtil {/**Tab键封装*/public static void pressTabKey(){Robot robot = null;try{robot = new Robot();}catch (AWTException e){e.printStackTrace();}//调用keypress方法来实现按下Tab键assert robot != null;robot.keyPress(KeyEvent.VK_TAB);//调用keyrelease方法来实现释放Tab键robot.keyRelease(KeyEvent.VK_TAB);}/**Enter键封装*/public static void pressEnterKey(){Robot robot = null;try{robot = new Robot();}catch (AWTException e){e.printStackTrace();}//调用keypress方法来实现按下Enter键assert robot != null;robot.keyPress(KeyEvent.VK_ENTER);//调用keyrelease方法来实现释放Enter键robot.keyRelease(KeyEvent.VK_ENTER);}/**将指定字符串设为剪切板内容,执行黏贴操作*将页面焦点切换到输入框后,调用此函数,将指定字符串黏贴到输入框*/public static void setAndctrlVClipboardData(String string){StringSelection stringSelection = new StringSelection(string);Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);Robot robot = null;try{robot = new Robot();}catch (AWTException e){e.printStackTrace();}assert robot != null;robot.keyPress(KeyEvent.VK_CONTROL);robot.keyPress(KeyEvent.VK_V);robot.keyRelease(KeyEvent.VK_V);robot.keyRelease(KeyEvent.VK_CONTROL);}/*** 键盘向下键封装*/public static void pressDownKey(){Robot robot = null;try{robot = new Robot();}catch (AWTException e){e.printStackTrace();}assert robot != null;robot.keyPress(KeyEvent.VK_DOWN);robot.keyRelease(KeyEvent.VK_DOWN);}
}
[修改页面元素属性]
package Util;import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;/*** Summary: add/modify/delete attribute of elements** @author: davieyang* @create: 2018-08-05 2:29*/
public class ModifyElementsAttributeByJS {public void setAttribute(WebDriver driver, WebElement element, String attributeName, String value){JavascriptExecutor js = (JavascriptExecutor) driver;/*** 调用js修改页面元素的属性值arguments[0]-arguments[2]会由element,attributeName,value替换*/js.executeScript("arguments[0].setAttribute(arguments[1],arguments[2])", element,attributeName,value);}public void removeAttribute(WebDriver driver, WebElement element, String attributeName){JavascriptExecutor js = (JavascriptExecutor) driver;/*** 调用js修改页面元素的属性值arguments[0]-arguments[1]会由element,attributeName替换*/js.executeScript("arguments[0].removeAttribute(arguments[1],arguments[2])", element,attributeName);}}
[Javascript实现页面单击操作]
/** the method of invoking js to do something** @author davieyang* @create 2018-08-05 1:37*/
package util;
import org.openqa.selenium.*;
import java.util.Arrays;public class JavaScriptToDo {/**** @param driver 浏览器驱动* @param xpath xpath定位表达式*/public static void javaScriptClick(WebDriver driver, String xpath) {WebElement element = driver.findElement(By.xpath(xpath));try{if(element.isEnabled() && element.isDisplayed()){System.out.println("使用JS进行也面元素单击");//执行JS语句arguments[0].click();((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);}else {System.out.println("页面上元素无法进行单击操作");}}catch (StaleElementReferenceException e){System.out.println("页面元素没有附加在页面中" + Arrays.toString(e.getStackTrace()));}catch (NoSuchElementException e){System.out.println("在页面中没有找到要操作的元素" + Arrays.toString(e.getStackTrace()));}catch (Exception e){System.out.println("无法完成单击操作" + Arrays.toString(e.getStackTrace()));}}
}
[启动浏览器]
/*** 定义函数initBrowser* @param browser:字符串参数chrome/ie/xx* @return 并返回驱动*/public static WebDriver initBrowser(String browser) {if(browser.equalsIgnoreCase("firefox")) {System.setProperty("webdriver.gecko.driver", Path_BrowserDrivers+"geckodriver.exe");driver = new FirefoxDriver();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);info("启动Firefox浏览器");}else if (browser.equalsIgnoreCase("ie")){System.setProperty("webdriver.ie.driver",Path_BrowserDrivers+"IEDriverServer.exe");driver = new InternetExplorerDriver();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);info("启动IE浏览器");}else {System.setProperty("webdriver.chrome.driver",Path_BrowserDrivers+"chromedriver.exe");driver = new ChromeDriver();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);info("启动Chrome浏览器");}driver.manage().window().maximize();info("最大化浏览器");return driver;}/*** 进入页面url* @param url:驱动浏览器,打开的页面url* @param browser:字符串参数chrome/ie/xx* @param timeOutInSeconds:等待时常*/public static void openBrowser(String url, String browser, int timeOutInSeconds) {driver = initBrowser(browser);driver.manage().timeouts().implicitlyWait(timeOutInSeconds, TimeUnit.SECONDS);driver.get(url);}
[JS][AWT处理点击]
方法一
selenium提供的click()方法
driver.findElement(By.xpath(".....")).click();
方法二
那么我们一定是要点了它才能完成测试用例的执行,第一种方式不行,还有什么其他方法呢,我去手动测试这个按钮,是否接受键盘的Enter键,果然响应了Enter键,于是立刻用selenium提供的方法代码实现
driver.findElement(By.xpath("...")).sendKeys(Keys.ENTER);
方法三
于是封装了敲击键盘的方法,尝试不用Selenium提供的方法,实现敲击Enter键
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
public class KeyBoardUtil {/**Enter键封装*/public static void pressEnterKey(){Robot robot = null;try{robot = new Robot();}catch (AWTException e){e.printStackTrace();}//调用keypress方法来实现按下Enter键assert robot != null;robot.keyPress(KeyEvent.VK_ENTER);//调用keyrelease方法来实现释放Enter键robot.keyRelease(KeyEvent.VK_ENTER);}
}
方法四
/**** @param driver 浏览器驱动* @param xpath xpath定位表达式*/public static void javaScriptClick(WebDriver driver, String xpath) {WebElement element = driver.findElement(By.xpath(xpath));try{if(element.isEnabled() && element.isDisplayed()){System.out.println("使用JS进行也面元素单击");//执行JS语句arguments[0].click();((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);}else {System.out.println("页面上元素无法进行单击操作");}}catch (StaleElementReferenceException e){System.out.println("页面元素没有附加在页面中" + Arrays.toString(e.getStackTrace()));}catch (NoSuchElementException e){System.out.println("在页面中没有找到要操作的元素" + Arrays.toString(e.getStackTrace()));}catch (Exception e){System.out.println("无法完成单击操作" + Arrays.toString(e.getStackTrace()));}}
[AutoIt上传文件]
通常情况下实现自动化上传文件,都是通过sendKeys函数直接将文件全路径传给页面空间就能完成,然而这种情况只能对Input类型的控件有效,对于非Input类型的控件可以借助AutoIt来完成
下载AutoIt
下载地址为:https://www.autoitscript.com/site/autoit/downloads/
获取定位
启动AutoIt Window Info,如图右侧窗口所示,拖动Finder Tool到你想获取信息的控件上,即可获取控件相关信息
编写SciTE Script
编写SciTE Script, 如图函数中的参数均是在第一步使用Finder Tool获取
编辑完,可以执行测试一下是否能完成上传动作,之后保存成.au3格式的文件
生成可执行文件
启动AutoIt的Compile Script to .exe, 选中刚才保存的.au3文件,点击Convert按钮即可生成.exe文件
执行上传代码示例
编写java脚本,在合适的位置调用该.exe文件完成文件的上传
[处理Table]
测试代码
@Testpublic void test_Table() throws Exception {//获取表单,xpath是表单的定位WebElement tableElement=driver.findElement(By.xpath("//*[@id='app']/section/section/main/section/div[1]/div[3]/table"));//将表单的所有tr放进列表,每个tr是表单的一行,逐行遍历List<WebElement> rows=tableElement.findElements(By.tagName("tr"));for (int i = 0; i < rows.size(); i++) {//将表单的td放进list里,每个td是表单的一列,逐列遍历List<WebElement> cols=rows.get(i).findElements(By.tagName("td"));for (int j = 0; j < cols.size();) {String tdText = cols.get(j).getText();sleep(1000);System.out.println(tdText +"\t");//判断哪行哪列的内容包含字段"mysql01", 如果包含则进行操作if(tdText.contains("mysql01")){System.out.println(i+1);System.out.println(j+1);int row = i + 1;//点击mysql01所在行的下拉按钮WebElement dropdown = driver.findElement(By.xpath("//*[@id='app']/section/section/main/section/div[1]/div[3]/table/tbody/tr["+row+"]/td[6]/div/div/span"));dropdown.click();}break;}}}
实际上如果页面存在检索功能,完全可以写几步检索操作,让页面只有一条你要的数据,那么它的位置就是固定了,然后再进行操控
处理Table方法
package util;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import java.util.List;
import java.util.NoSuchElementException;
import static util.WaitElementUtil.sleep;/** some method of controlling table** @author: davieyang* @create: 2018-08-05 14:04*/
public class TableUtil {//声明一个WebElement对象,用于存储页面的表格元素对象private WebElement _table;//为构造函数传入页面表格元素对象参数,调用TableUtil类的settable方法,将页面表格元素赋值给TableUtil类的_table成员变量public TableUtil (WebElement table){setTable(table);}//获取页面表格对象的方法public WebElement getTable(){return _table;}//将页面表格元素赋值给TableUtil类中_table成员变量的方法public void setTable(WebElement _table){this._table = _table;}//获取表格元素的行数,查找表格元素有几个tr元素,有几个tr元素,就可以知道表格有几行,tr数量和表格行数相一致public int getRowCount(){List<WebElement> tableRows = _table.findElements(By.tagName("tr"));return tableRows.size();}//获取表格元素的列数,使用get(0)从容器中取出表格第一行的元素,查找有几个“td”,td数量和列数一致public int getColumnCount(){List<WebElement> tableRows = _table.findElements(By.tagName("tr"));return tableRows.get(0).findElements(By.tagName("td")).size();}//获取表格中某行某列的单元格对象public WebElement getCell(int rowNo, int colNo)throws NoSuchElementException{try{List<WebElement> tableRows = _table.findElements(By.tagName("tr"));System.out.println("行总数:" + tableRows.size());System.out.println("行号:" + rowNo);WebElement currentRow = tableRows.get(rowNo - 1);List<WebElement> tableCols = currentRow.findElements(By.tagName("td"));System.out.println("列总数:" + tableCols.size());WebElement cell = tableCols.get(colNo-1);System.out.println("列号:" + colNo);return cell;}catch (NoSuchElementException e){throw new NoSuchElementException("没有找到相关元素");}}/*** 获得表格中某行某列的单元格中的某个页面元素对象,by参数用于定位某个表格中的页面元素,例如by.xpath("input[@type='text']")可以定义到表格中的输入框*/public WebElement getWebElementInCell(int rowNo, int colNo, By by)throws NoSuchElementException{try{List<WebElement> tableRows = _table.findElements(By.tagName("tr"));//找到表格中的某一行,行号从0开始,例如第三行,则需要进行3-1来获取即“2”WebElement currentRow = tableRows.get(rowNo-1);List<WebElement> tableCols = currentRow.findElements(By.tagName("td"));//找到表格中的某一列,因为也是从0开始,所以要找到第三列,则需要进行3-1来获取即“2”WebElement cell = tableCols.get(colNo-1);return cell.findElement(by);}catch (NoSuchElementException e){throw new NoSuchElementException("没有找到相关元素");}}/**** @param driver 浏览器驱动* @param row 行号* @param column 列号* @return 函数接受浏览器驱动,表格行数和列数,注意表头行,返回某个cell的值*/public static String tableCell(WebDriver driver, int row, int column) {String text = null;//avoid get the head line of the tablerow=row+1;String xpath="//*[@id='table138']/tbody/tr["+row+"]/td["+column+"]";WebElement table=driver.findElement(By.xpath(xpath));text=table.getText();return text;}
}
[兼容性测试]
兼容性测试的思路实际上可行的只有两个,一个是分布式自动化,由一个大脑驱动若干分支,另一个就是为不同的环境编写不同的测试代码实例,然后在程序入口分别调用
/** @FileName Demo: Demo* @author davieyang* @create 2018-11-06 16:01*/
package testscript;import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;import java.util.concurrent.TimeUnit;import static org.testng.Assert.assertEquals;public class Demo_Compatibility_Testing {static {//指定log4j配置文件为log4j.xmlDOMConfigurator.configure("log4j.xml");}// 主要方法是使用 InternetExplorerDriver FirefoxDriver ChromeDriver 运行相同的测试脚本,// 将每一种Driver 的启动写成 @Test 的方法,如下所示:@Test@Parameters( { "webSite" })public void setUp_InternetExplorerDriver(String webSite) throws Exception {//.\\lib\\IEDriverServer.exe 是lib目录下的驱动System.setProperty("webdriver.ie.driver", ".\\lib\\IEDriverServer.exe");DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,true);WebDriver driver = new InternetExplorerDriver(capabilities);String baseUrl = webSite;driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);script(driver);}@Test@Parameters( { "firefox_dir", "webSite" })public void setUp_FirefoxDriver(String firefox_dir, String webSite)throws Exception {//firefox_dir 为本机 firefox安装目录System.setProperty("webdriver.firefox.bin", firefox_dir);WebDriver driver = new FirefoxDriver();String baseUrl = webSite;driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);script(driver);}@Test@Parameters( { "webSite" })public void setUp_ChromeDriver(String webSite) throws Exception {//.\\lib\\IEDriverServer.exe 是lib目录下的驱动System.setProperty("webdriver.chrome.driver", "./lib/chromedriver.exe");WebDriver driver = new ChromeDriver();String baseUrl = webSite;driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);script(driver);}// 对于具体的测试脚本,写成一个新的方法,每一个driver都会调用该方法,如下所示:private void script(WebDriver driver) throws Exception {try {String baseUrl = "http://www.baidu.com";Logger logger=Logger.getLogger(Demo_Compatibility_Testing.class);logger.info("开始");driver.get(baseUrl);driver.findElement(By.id("kw")).clear();driver.findElement(By.id("kw")).sendKeys("selenium");driver.findElement(By.id("kw")).submit();driver.findElement(By.linkText("下一页>")).click();driver.findElement(By.linkText("下一页>")).click();driver.findElement(By.linkText("下一页>")).click();assertEquals("selenium", driver.findElement(By.id("kw")).getAttribute("value"));logger.info("结束");} catch (Exception e) {throw e;} finally {driver.quit();}}
}
[Log4j处理日志]
Log4j是个开源项目,可以控制日志信息的输出目的地,例如控制台、文件、GUI组件等,其配置文件用来设置日志的级别,文件格式只能是XML、json、yaml或properties
配置依赖
<!-- https://mvnrepository.com/artifact/log4j/log4j --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency>
Log4j配置文件properties
log4j.rootLogger=info, toConsole, toFile
log4j.appender.file.encoding=UTF-8
log4j.appender.toConsole=org.apache.log4j.ConsoleAppender
log4j.appender.toConsole.Target=System.out
log4j.appender.toConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.toConsole.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] [%p] %m%n
log4j.appender.toFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.toFile.file=result/log/testlog.log
log4j.appender.toFile.append=false
log4j.appender.toFile.Threshold=info
log4j.appender.toFile.layout=org.apache.log4j.PatternLayout
log4j.appender.toFile.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] [%p] %m%n
Log4j引用
package com.davieyang.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;@SpringBootApplication
//@SpringBootApplication 代表将程序作为SpringBoot应用来运行
public class Application {static Logger logger = Logger.getLogger(Application.class.getName());public static void main(String[] args){PropertyConfigurator.configure("log4j.properties");// DOMConfigurator.configure("D:\\SpringBootDemo\\result\\log4j.xml");SpringApplication.run(Application.class, args);logger.debug("debug message");logger.info("info message");logger.error("error message");//调用run方法并传入当前Class作为参数来运行程序,同时传入main方法的args参数}
}
Log4j配置文件XML
<?xml version="1.0" encoding = "GB2312" ?>
<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
<appender name="fileAppender" class="org.apache.log4j.FileAppender">
<param name="Threshold" value="INFO" />
<param name="File" value="Automation.log" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" />
</layout>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="fileAppender"/>
</root>
</log4j:configuration>
二次封装
package util;
import org.apache.log4j.Logger;import java.io.IOException;public class LogUtil {private static Logger Log = Logger.getLogger(LogUtil.class.getName());//定义测试用例开始执行的打印方法,在日志中打印开始执行测试用例的信息public static void startTestCases(String testCaseName){Log.info("------------------ \"" + testCaseName + "\"开始执行 -----------------");}//定义测试用例执行完毕的打印方法,在日志中打印测试用例执行完毕的心public static void endTestCases(String testCaseName){Log.info("------------------ \"" + testCaseName + "\"执行结束 -----------------");}//定义打印info级别日志的方法public static void info(String message){Log.info(message);}//定义打印error级别日志的方法public static void error(String message, IOException e){Log.error(message);}//定义打印debug级别日志的方法public static void debug(String message){Log.debug(message);}
}
引用Log4j
package util;
import org.apache.log4j.xml.DOMConfigurator;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.ui.Select;
import org.testng.Assert;
import org.testng.Reporter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static constants.Constants.MainPageandNavigation_Property;
import static constants.Constants.Path_BrowserDrivers;
import static util.LogUtil.info;public class KeyActionsUtil {//声明静态的Webdriver对象,用于在此类中相关Driver的操作public static WebDriver driver;//声明存储定位表达式配置文件的ObjectMap对象private static GetElementUtil getElementUtil = new GetElementUtil(MainPageandNavigation_Property);static {//指定log4j配置文件为log4j.xmlDOMConfigurator.configure("log4j.xml");}/*** 定义函数initBrowser* @param browser:字符串参数chrome/ie/xx* @return 并返回驱动*/public static WebDriver initBrowser(String browser) {if(browser.equalsIgnoreCase("firefox")) {System.setProperty("webdriver.gecko.driver", Path_BrowserDrivers+"geckodriver.exe");driver = new FirefoxDriver();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);info("启动Firefox浏览器");}else if (browser.equalsIgnoreCase("ie")){System.setProperty("webdriver.ie.driver",Path_BrowserDrivers+"IEDriverServer.exe");driver = new InternetExplorerDriver();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);info("启动IE浏览器");}else {System.setProperty("webdriver.chrome.driver",Path_BrowserDrivers+"chromedriver.exe");driver = new ChromeDriver();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);info("启动Chrome浏览器");}driver.manage().window().maximize();info("最大化浏览器");return driver;}/*** 进入页面url* @param url:驱动浏览器,打开的页面url* @param browser:字符串参数chrome/ie/xx* @param timeOutInSeconds:等待时常*/public static void openBrowser(String url, String browser, int timeOutInSeconds) {driver = initBrowser(browser);driver.manage().timeouts().implicitlyWait(timeOutInSeconds, TimeUnit.SECONDS);driver.get(url);}//定义函数navigate,用于获取浏览器要访问的链接public static void navigate(String url){driver.get(url);info("访问地址为"+url);}//通过从剪切板黏贴的方式,在文件上传框体的文件名输入框中输入要上传文件的路径和名称"uploadpathandname"public static void uploadFileName(String uploadpathandname){try{KeyBoardUtil.setAndctrlVClipboardData(uploadpathandname);}catch (Exception e){e.printStackTrace();}}//页面上不止一个相同功能并且xpath相同的元素,此种情况处理是将他们存储到List中,然后用索引的方式用其一public static void twoWay(String ElementNameInproFile){try {List<WebElement> elements = driver.findElements(getElementUtil.getLocator(ElementNameInproFile));elements.get(0).click();System.out.println("按钮被成功点击");}catch (Exception e){e.printStackTrace();}}/*** 断言文字内容* @param driver:浏览器驱动* @param assertstring:要断言的字符串*/public static void assertString(WebDriver driver,String assertstring){try{Assert.assertTrue(driver.getPageSource().contains(assertstring));Reporter.log("成功断言关键字“"+ assertstring +"”");}catch (AssertionError e){Reporter.log("断言失败,具体失败信息为:" + e.getMessage());System.out.println("断言失败");throw e;}}//断言文字不存在public static void assertNoString(WebDriver driver, String assertstring){try{Assert.assertFalse(driver.getPageSource().contains(assertstring)); info("成功断言关键字“"+ assertstring +"” + “不存在”");}catch (AssertionError e){info("断言失败,具体信息为:" + e.getMessage());System.out.println("断言失败");}}
}
此处除了用到了封装好的info方法,还用到了TestNG的Reporter.log("断言失败,具体失败信息为:" + e.getMessage());
配置文件详解
Appenders配置项 | 描述 |
---|---|
ConsoleAppender | 控制台,输出结果到system.out或system.err |
FileAppender | 输出结果到指定文件,同时可以指定输出数据的格式appender=true指定追加到文件末尾 |
DailyRollingFileAppender | 每天产生一个日志文件 |
RollingFileAppender | 文件大小到达指定数值后生成新的文件 |
WriterAppender | 将日志信息以流格式发送到任意指定的地方 |
Level值 | 描述 |
---|---|
OFF | 关闭所有日志 |
FATAL | 致命错误 |
ERROR | 严重错误 |
WARN | 警告信息 |
INFO | 通知类一般类状态类普通信息 |
DEBUG | 调试信息 |
TRACE | 追踪信息 |
ALL | 输出所有日志 |
Layout配置项 | 描述 |
---|---|
HTMLLayout | 以HTML表格形式布局 |
PatternLayout | 可以灵活的指定布局模式 |
SimpleLayout | 包含日志信息的级别和信息字符串 |
TTCCLayout | 包含日志产生的时间线程类别等信息 |
ConversionPatter配置项 | 描述 |
---|---|
%m | 输出代码中指定的信息 |
%p | 输出优先级 DEBUG、INFO、WARN、ERROR、FATAL |
%r | 输出自应用启动到输出该log信息耗费的毫秒数 |
%c | 输出所属的类,通常为类的全名 |
%t | 输出产生日志事件的线程名 |
%n | 输出一个回车换行符,Windows平台中为“rn”, UNIX平台为“n” |
%d | 输入日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,例如%d{yyyy MMM dd HH:mm:ss,SSS}, 输出类似于2020年8月20日3:39:00 921 |
%l | 输出日志事件的发生位置,包含类名线程以及代码中的行数 |
[模拟鼠标]
package util;import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.WebDriver;public class MouseUtil {/*** 模拟鼠标左键单击* @param driver* @param xpathExpression*/public void lefClick(WebDriver driver, String xpathExpression) {Actions actions = new Actions(driver);// 鼠标左键在当前停留的位置做单击操作actions.click();// 鼠标左键点击指定的元素actions.click(driver.findElement(By.xpath(xpathExpression)));}/*** 模拟鼠标右键单击* @param driver* @param xpathExpression*/public void rightClick(WebDriver driver, String xpathExpression) {Actions actions = new Actions(driver);// 鼠标右键在当前停留的位置做单击操作actions.contextClick();// 鼠标右键点击指定的元素actions.contextClick(driver.findElement(By.xpath(xpathExpression)));}/*** 模拟鼠标左键双击* @param driver* @param xpathExpression*/public void doubleClick(WebDriver driver, String xpathExpression) {Actions actions = new Actions(driver);// 鼠标在当前停留的位置做双击操作actions.doubleClick();// 鼠标双击指定的元素actions.doubleClick(driver.findElement(By.xpath(xpathExpression)));}/*** 模拟鼠标拖拽* @param driver* @param source* @param target*/public void dragAction(WebDriver driver, WebElement source, WebElement target) {Actions actions = new Actions(driver);// 鼠标拖拽动作,将 source 元素拖放到 target 元素的位置actions.dragAndDrop(source, target);}/*** 模拟鼠标拖拽到某坐标* @param driver* @param source* @param xOffset* @param yOffset*/public void dragtoXY(WebDriver driver, WebElement source, int xOffset, int yOffset) {Actions actions = new Actions(driver);// 鼠标拖拽动作,将 source 元素拖放到 (xOffset, yOffset) 位置,其中 xOffset 为横坐标,yOffset 为纵坐标actions.dragAndDropBy(source, xOffset, yOffset);}/*** 模拟鼠标拖拽从元素A到元素B* @param driver* @param source* @param target*/public void dragActionReleaseMouse(WebDriver driver, WebElement source, WebElement target) {Actions actions = new Actions(driver);// 鼠标拖拽动作,将 source 元素拖放到 target 元素的位置actions.clickAndHold(source).moveToElement(target).perform();actions.release();}/*** 模拟鼠标单击并不释放* @param driver* @param element*/public void clickAndHole(WebDriver driver, WebElement element) {Actions actions = new Actions(driver);//action.clickAndHold();鼠标悬停在当前位置,既点击并且不释放// 鼠标悬停在 onElement 元素的位置actions.clickAndHold(element);}/*** 模拟鼠标拖拽* @param driver* @param xOffset* @param yOffset*/public void moveToXY(WebDriver driver, int xOffset, int yOffset){Actions actions = new Actions(driver);/**将鼠标移到元素 toElement 的 (xOffset, yOffset) 位置,这里的 (xOffset, yOffset) 是以元素 toElement 的左上角为 (0,0) 开始的 (x, y) 坐标轴*action.moveToElement(toElement,xOffset,yOffset)*以鼠标当前位置或者 (0,0) 为中心开始移动到 (xOffset, yOffset) 坐标轴*/actions.moveByOffset(xOffset, yOffset);actions.release();// 释放鼠标}
[JavaScript实现高亮元素]
/** the method of invoking js to do something** @author davieyang* @create 2018-08-05 1:37*/
package util;
import org.openqa.selenium.*;
import java.util.Arrays;public class JavaScriptToDo {/**** @param driver 浏览器驱动* @param element 页面元素对象*/public static void highLightElement(WebDriver driver, WebElement element){JavascriptExecutor js = (JavascriptExecutor) driver;/*调用js将传入参数的页面元素对象的背景颜色和边框颜色分别设定为黄色和红色*/js.executeScript("arguments[0].setAttribute('style', arguments[1]);", element, "background: yellow; border:2px solid red;");}
}
[智能等待]
package util;
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.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.Reporter;import static util.LogUtil.info;public class WaitElementUtil {//public WebDriver driver = null;//private int timeOutInSeconds =10;/**用于测试执行过程中暂停程序执行的等待方法*/public static void sleep(long millsecond){try{Thread.sleep(millsecond);Reporter.log("强制等待"+ millsecond + "毫秒...");}catch (Exception e){e.printStackTrace();}}/*** 同上* @param driver* @param by* @param timeOutInSeconds*/public static void waitWebElementPresence(WebDriver driver, By by, int timeOutInSeconds){WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(by));}/*** 显示等待页面元素可被点击状态,参数为页面元素xpath定位表达式* @param driver* @param by* @param timeOutInSeconds*/public static void waitWebElementToBeClickable(WebDriver driver, By by, int timeOutInSeconds){WebDriverWait waitElement = new WebDriverWait(driver, timeOutInSeconds);WebElement element = waitElement.until(ExpectedConditions.elementToBeClickable(by));}/*** 显示等待页面元素被选中状态,参数为页面元素xpath定位表达式* @param driver* @param xpathExpression* @param timeOutInSeconds*/public static void waitWebElementToBeSelected(WebDriver driver, String xpathExpression, int timeOutInSeconds){WebDriverWait waitElement = new WebDriverWait(driver, timeOutInSeconds);Boolean element = waitElement.until(ExpectedConditions.elementToBeSelected(By.xpath(xpathExpression)));}/*** 显示等待页面元素出现,参数为页面元素xpath定位表达式* @param driver* @param xpathExpression* @param text* @param timeOutInSeconds*/public static void waitWebElementToBePresentInElementValue(WebDriver driver, String xpathExpression, String text, int timeOutInSeconds){WebDriverWait waitElement = new WebDriverWait(driver, timeOutInSeconds);Boolean element = waitElement.until(ExpectedConditions.textToBePresentInElementValue(By.xpath(xpathExpression), text));}/*** 显示等待页面标题包含"title"元素出现,参数为页面元素xpath定位表达式* @param driver* @param title* @param timeOutInSeconds*/public static void waitWebElementTitleContains(WebDriver driver, String title, int timeOutInSeconds){WebDriverWait waitElement = new WebDriverWait(driver, timeOutInSeconds);Boolean element = waitElement.until(ExpectedConditions.titleContains(title));}/*** 显示等待页面元素加载* @param by:等待元素elementName加载完成* @param timeOutInSeconds:等待时常* @throws Exception*/public static void waitElement(WebDriver driver, By by, int timeOutInSeconds) throws Exception {try{waitWebElementPresence(driver, by, timeOutInSeconds);info("显示等待页面元素出现成功, 页面元素是" + by);}catch (Exception e){info("显示等待页面元素时出现异常,异常信息为:" + e.getMessage());e.printStackTrace();}}/*** 显示等待元素加载* @param driver:浏览器驱动* @param timeOut:等待时常* @param by:元素定位*/public static void intelligentWait(WebDriver driver,int timeOut, final By by) {try {(new WebDriverWait(driver, timeOut)).until(new ExpectedCondition<Boolean>() {public Boolean apply(WebDriver driver) {WebElement element = driver.findElement(by);return element.isDisplayed();}});} catch (TimeoutException e) {Assert.fail("超时L !! " + timeOut + " 秒之后还没找到元素 [" + by + "]", e);}}
}
[截图方法]
package util;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import java.io.File;
import java.io.IOException;
import java.util.Date;public class ScreenShotUtil {public WebDriver driver;public ScreenShotUtil(WebDriver driver) {this.driver = driver;}/**截图并存储到screenPath** @param driver* @param screenPath*/private static void takeScreenshot(WebDriver driver, String screenPath) {try {File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(scrFile, new File(screenPath));} catch (IOException e) {System.out.println("Screen shot error: " + screenPath);}}/**截图并存储到固定目录下test-output/snapshot中** @param driver 浏览器驱动*/public void takeScreenshot(WebDriver driver) {String screenName = String.valueOf(new Date().getTime()) + ".jpg";File dir = new File("test-output/snapshot");if (!dir.exists())dir.mkdirs();String screenPath = dir.getAbsolutePath() + "/" + screenName;this.takeScreenshot(driver, screenPath);}
}