Java自动化测试系列[v1.0.0][常见页面操作处理]

[控制滚动]

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);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/238717.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

houdini 常用节点

雾化 撒点 减面 点连线 trace 节点 labs skelete 图片转模型 齿轮制作 polyextrude point to point connect primuv

sqli-labs第二十九三十

Less-29&#xff08;GET - Error based - IMPIDENCE MISMATCH - Having a WAF in front of web application) 手工注入 正常注入的时候发现 此处似乎没有sql注入 但是我上一个说了这个是有waf的 http://192.168.21.149/Less-29/?id1&id0‘union select 1,2,3-- 这里其…

金蝶云星空执行部署包后业务对象会被标记上部署包的开发码

文章目录 金蝶云星空执行部署包后业务对象会被标记上部署包的开发码 金蝶云星空执行部署包后业务对象会被标记上部署包的开发码 会被标记成开发码的业务对象包括以下&#xff1a; 新增的业务对象&#xff0c;扩展的业务对象 --查询二开的元数据打包 FPACKAGEID不为空&#xff…

Mac电脑上soucetree账户更改

在开发公司项目的时候遇到一个问题。soucetree提示需要输入已离职员工-张三的密码。 问题&#xff1a;Mac电脑使用souetree&#xff0c;拉取仓库代码提示需要输入其他员工密码。 解决&#xff1a; Mac电脑 SourceTree去掉之前的账户 1、前往文件路径 /Library/Application Su…

27. 过滤器

Filter(过滤器)简介 Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截&#xff0c;从而在 Servlet 进行响应处理的前后实现一些特殊的功能。在 Servlet API 中定义了三个接口类来开供开发人员编写 Filter 程序&#xff1a;Filter, FilterChain, FilterConfigFi…

关于redis单线程和IO多路复用的理解

首先&#xff0c;Redis是一个高性能的分布式缓存中间件。其复杂性不言而喻&#xff0c;对于Redis整体而言肯定不是只有一个线程。 我们常说的Redis 是单线程&#xff0c;主要是指 Redis 在网络 IO和键值对读写是采用一个线程来完成的&#xff0c;这也是 Redis 对外提供键值存储…

docker数据卷数据卷容器

前言 今天调休在家&#xff0c;随便玩玩&#xff0c;简单做下学习记录 1. 数据卷特点 数据卷在容器启动时初始化&#xff0c;如果容器使用的镜像在挂载点包含了数据&#xff0c;这些数据会被拷贝到新初始化的数据卷中数据卷可以在容器之间共享和重用可以对数据卷里的内容直接…

vscode | python | remote-SSH | Debug 配置 + CLIP4Clip实验记录

安装Extension 本地安装Remote-SSH、python 远程服务器上安装Python 难点&#xff1a;主机和远程服务器上安装Python扩展失败&#xff0c;可能是网络、代理等原因导致解决方法&#xff1a; 主机在官方网站下载Python扩展&#xff1a;https://marketplace.visualstudio.com/it…

beaglebone black狗板,交叉编译Qt5(eglfs)

1. 下载buildroot-2023.023.7版本 make beaglebone_qt5_defconfig 然后编译&#xff0c;出现错误大多数是因为下载不了包&#xff0c;用bing搜索找到放到对应的dl目录下&#xff0c;最终完成编译。 备注&#xff1a;用系统默认配置&#xff0c;不要参考网上的&#xff0c;网…

ansible的脚本:playbook剧本

&#xff08;一&#xff09;playbook的组成部分 tasks 任务&#xff0c;包含要在主机上执行的操作&#xff0c;使用模块定义这些操作&#xff0c;每一个任务都是一个模块的调用 variables 变量&#xff0c;存储和传递数据&#xff08;和shell脚本中的变量是一个意思&#xf…

Tomcat转SpringBoot、tomcat升级到springboot、springmvc改造springboot

Tomcat转SpringBoot、tomcat升级到springboot、springmvc改造springboot 起因&#xff1a;我接手tomcat-springmvc-hibernate项目&#xff0c;使用tomcat时问题不大。自从信创开始&#xff0c;部分市场使用国产中间件&#xff0c;例如第一次听说的宝兰德、东方通&#xff0c;还…

【python】进阶--->网络编程(二)

一、分层模型 OSI/RM(开放系统互联参考模型) 是由国际标准化组织提出来的一种网络互联模型,成为所有的销售商都能实现的开放网络模型.(OSI模型提供我们理解网络协议的内部运作) OSI模型将网络通信工作分为7层,每一层为上一层服务,并为上一层提供一个访问的接口或者界面. 越下…

TCP/IP:从数据包到网络的演变

引言 TCP/IP协议的起源可以追溯到20世纪60年代末和70年代初&#xff0c;美国国防部高级研究计划局&#xff08;ARPA&#xff09;研究开发一种可靠的通信协议&#xff0c;用于连接分散在不同地点的计算机和资源。 在当时&#xff0c;计算机之间的连接并不像现在这样普遍和便捷…

RocketMQ系统性学习-RocketMQ高级特性之消息大量堆积处理、部署架构和高可用机制

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 【11来了】文章导读地址&#xff1a;点击查看文章导读&#xff01; &#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f3…

算法通关村-番外篇排序算法

大家好我是苏麟 , 今天带来番外篇 . 冒泡排序 BubbleSort 最基本的排序算法&#xff0c;最常用的排序算法 . 我们以关键字序列{26,53,48,11,13,48,32,15}看一下排序过程: 代码如下 : (基础版) class Solution {public int[] sortArray(int[] nums) {for(int i 0;i < n…

简单了解一下当前火热的大数据 -- Kylin

神兽麒麟 一、Apache Kylin 是什么&#xff1f;二、Kylin架构结语 一、Apache Kylin 是什么&#xff1f; 由eBay公司中国团队研发&#xff0c;是一个免费开源的OLAP多维数据分析引擎优点 超快的响应速度&#xff0c;亚秒级支持超大数据集&#xff08;PB以上&#xff0c;千亿记…

天津web前端就业培训班,Web机构选择重点

Web前端培训是目前非常热门的培训领域之一。很多领域都会涉及到web前端开发&#xff0c;比如传统互联网、房地产、金融、游戏、影视传媒等行业都需要web前端技术的支持。越来越多的企业和个人也需要建立自己的网站和移动应用程序&#xff0c;因此市场对web前端工程师的需求是非…

Linux 磁盘空间占满故障解决方法

故障排查&#xff1a; 使用命令查看磁盘使用量 # 使用人类可读的格式(预设值是不加这个选项的...) df -h # --inodes 列出 inode 资讯&#xff0c;不列出已使用 block df -i # 查看当前目录下各个文件及目录占用空间大小 du -sh / 情况一&#xff1a;一般磁盘空间满了&a…

【前缀和】【单调栈】LeetCode2281:巫师的总力量和

作者推荐 map|动态规划|单调栈|LeetCode975:奇偶跳 涉及知识点 单调栈 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 题目 作为国王的统治者&#xff0c;你有一支巫师军队听你指挥。 给你一个下标从 0 开始的整数数组 strength &…

isp代理/双isp代理/数据中心代理的区别?如何选择?

本文我们来详细科普一下几种不同的代理类型&#xff1a;isp代理/双isp代理/数据中心代理&#xff0c;了解他们的区别&#xff0c;选择更适合自己的代理类型。 在讲述这几种代理类型之前&#xff0c;我们先复习一下代理大类有哪几种。 一、机房代理和非机房代理 在做代理ip选…