5.6 WebDriver API实例讲解(31-40)
31.判断页面元素是否存在
public static void testElementExist(){ driver.get("http://www.sogou.com"); try{ driver.findElement(By.id("query")); System.out.println("element is found."); }catch(NoSuchElementException e){ System.out.println("element is not found."); } }
32.浏览器窗口切换
public static void identifyPopUpWindowByTitle(){ driver.get("http://www.qq.com"); driver.manage().window().maximize(); sleep(2000); String parentWindowHandle=driver.getWindowHandle(); WebElement element=driver.findElement(By.linkText("科技")); element.click(); Set<String> allWindowsHandles=driver.getWindowHandles(); if(!allWindowsHandles.isEmpty()){ for(String windowHandle:allWindowsHandles){ try{ driver.switchTo().window(windowHandle);
Thread.sleep(5000);
if (driver.getTitle().equals("科技频道_腾讯网")) { element=driver.findElement(By.xpath("//form[@name='soso_search_box']//input[@name='query']")); element.clear(); element.sendKeys("Elon Musk"); driver.findElement(By.xpath(".//form[@name='soso_search_box']//input[@role='button']")).click(); sleep(2000); } }catch(NoSuchWindowException e){ e.printStackTrace(); } } } driver.switchTo().window(parentWindowHandle); System.out.println("当前窗口title是:"+driver.getTitle()); }
33.操作JavaScript的Alert弹窗
public static void testAlert() { driver.get("file:///D:/%E6%95%99%E5%AD%A6/2015-2016-2/%E8%AF%BE%E4%BB%B6/w9/SeleniumDemo/files/Demo1/demo.html"); driver.manage().window().maximize(); sleep(2000); driver.findElement(By.className("alert")).click(); sleep(2000); Alert alert=driver.switchTo().alert(); //通过switch切换到windows弹窗上面 String alertMessage=alert.getText(); //获得弹框中的文字 System.out.println(alertMessage); alert.accept(); //弹框中,点击确认 //alert.dismiss(); //弹框中,点击取消 }
34.操作IFrame中的页面元素
public static void testIframe() { driver.get("file:///D:/%E6%95%99%E5%AD%A6/2015-2016-2/%E8%AF%BE%E4%BB%B6/w9/SeleniumDemo/files/Demo1/demo.html"); driver.manage().window().maximize(); driver.findElement(By.id("user")).sendKeys("test"); sleep(2000); driver.switchTo().frame("aa"); //其他方法一:Driver.switchTo.frame(0); /*/其他方法二:WebElement element=Driver.findElement(By.xpath("//iframe[@name='aa']")); Driver.switchTo().frame(element);*/ driver.findElement(By.id("user")).sendKeys("iframe test"); sleep(2000); driver.switchTo().defaultContent(); sleep(2000); driver.findElement(By.id("user")).sendKeys(" | new test"); }
35.操作浏览器的Cookie
能够遍历输出所有Cookie的key和value;能够删除指定的Cookie对象;能够删除所有的Cookie对象。
被测试网页的地址:http://www.sogou.com。
public static void testCookie(){ driver.get("http://www.sogou.com"); Cookie newCookie=new Cookie("cookieName","cookieValue"); driver.manage().addCookie(newCookie); Set<Cookie> cookies=driver.manage().getCookies(); System.out.println(String.format("Domain->name->value->expiry->path")); for(Cookie cookie:cookies) { System.out.println(String.format("%s->%s->%s->%s->%s", cookie.getDomain(),cookie.getName(), cookie.getValue(),cookie.getExpiry(),cookie.getPath())); } driver.manage().deleteCookieNamed("CookieName"); driver.manage().deleteCookie(newCookie); driver.manage().deleteAllCookies(); sleep(2000); cookies=driver.manage().getCookies(); if(cookies.isEmpty()) System.out.println("Cookie is empty."); }
36.控制HTML5语言实现的视频播放器
目的是能够获取HTML5语言实现的视频播放器视频文件的地址、时长,控制播放器进行播放或暂停播放。
private static void html5VedioTest(WebDriver driver) throws InterruptedException { driver.get("http://videojs.com/"); Thread.sleep(2000); //找到vedio元素 WebElement vedio = driver.findElement(By.id("preview-player_html5_api")); //声明js执行器 JavascriptExecutor js = (JavascriptExecutor) driver; //对vedio这个元素执行播放操作 js.executeScript("arguments[0].play()", vedio); //为了观察效果暂停5秒 Thread.sleep(5000); //对vedio这个元素执行暂停操作 js.executeScript("arguments[0].pause()", vedio); //为了观察效果暂停2秒 Thread.sleep(2000); //对vedio这个元素执行播放操作 js.executeScript("arguments[0].play()", vedio); //为了观察效果暂停2秒 Thread.sleep(2000); //对vedio这个元素执行重新加载视频的操作 js.executeScript("arguments[0].load()", vedio); //为了观察效果暂停2秒 Thread.sleep(2000); }
37.在Ajax方式产生的浮动框中操作
有些被测试的页面包含Ajax的局部刷新机制,并且会产生显示多条数据的浮动框,需要操作浮动框中的选项。
public static void Ex37_Ajax() throws InterruptedException{ driver=new FirefoxDriver(); driver.get("http://www.baidu.com"); WebElement searchInputBox=driver.findElement(By.id("kw")); searchInputBox.sendKeys("雷军"); Thread.sleep(1000); List<WebElement> suggestionOptions=driver.findElements(By.xpath("//form[@id='form']/div/ul/li")); for(WebElement element:suggestionOptions) { System.out.println(element.getText()); } suggestionOptions.get(2).click(); }
38.使用Log4j在测试过程中打印执行日志
log4j是一个用Java编写的可靠、快速和灵活的日志框架(API),它在Apache软件许可下发布。它已经被移植到了C、C++、C#、Perl、Python和Ruby等语言中。
Log4j中有三个主要组成部分:
-
loggers: 负责捕获记录信息。
-
appenders : 负责发布日志信息,以不同的首选目的地。
-
layouts: 负责格式化不同风格的日志信息。
在自动化测试脚本的执行过程中,使用Log4j在日志文件中打印执行日志,用于监控和后续调试测试脚本。
(1)下载log4j的zip包
(2)解压zip下载包,把压缩后的log4j-api.jar和log4j-core.jar文件添加到项目的BuilPath中即可。
(3)在工程根目录src文件夹下,新建一个名为log4j2.xml文件。
<?xml version="1.0" encoding="UTF-8"?> <configuration status="off" name="test"> <!-- 添加输出源 --> <appenders> <Console name="out" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss} [%t] %-5p: %m%n" /> </Console> <File name="outFile" fileName="Log/logfile.log"> <PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss} [%t] %-5p: %m%n" /> </File> </appenders> <loggers> <root level="info"> <appenderRef ref="out" /> <appenderRef ref="outFile"/> </root> </loggers> </configuration>
(4)在TestNG包中,新建测试脚本。
package otherFun; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; public class TestLog4j { public WebDriver driver; String baseUrl="http://www.sogou.com/"; //设定访问网站的地址 public static Logger logger=LogManager.getLogger(TestLog4j.class.getName()); @Test public void testSearch(){ //向日志文件中打印搜索测试用例开始执行的日志信息 logger.trace("搜索"); //打开sogou首页 driver.get(baseUrl+"/"); //打印“打开sogou首页”的日志信息 logger.info("打开sogou首页"); //在搜索框中输入“自动化测试” driver.findElement(By.id("query")).sendKeys("自动化测试"); //打印输入搜索关键字“光荣之路自动化测试”的日志信息 logger.info("输入搜索关键字“自动化测试”"); //单击“搜索”按钮 driver.findElement(By.id("stb")).click(); //打印“单击搜索按钮”的日志信息 logger.info("单击搜索按钮"); //向日志文件中打印搜索测试用例执行结束的日志信息 logger.traceExit("搜索"); } @BeforeMethod public void beforeMethod(){ System.setProperty("webdriver.gecko.driver", "MyDriver/geckodriver.exe"); driver=new FirefoxDriver(); //打开Firefox浏览器 } @AfterMethod public void afterMethod(){ driver.quit(); //关闭打开的浏览器 } }
执行测试类之后,会在当前测试工程的Log文件夹下,生成一个日志文件logfile.log,生成的日志如下。
代码解释:
(1)在log4j2中, 日志信息共有8个级别,按照从低到高为:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF。
(2)XML文件中的语句<PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss} [%t] %-5p: %m%n" />,定义了日志的格式信息。%d表示打印日志时候的年月日分秒毫秒信息,%-5p表示日志的级别(info),%m表示打印具体的日志内容,%n表示打印一个回车。
39.在测试中断言失败的步骤进行屏幕截图
在测试过程汇总,在断言语句执行失败的时候,对当前浏览器显示的内容进行截屏操作,并在磁盘上新建一个名为当前日期表示的yyyy-mm-dd格式的目录,并在目录中新建一个名称以断言执行失败发生时间表示的hh-mm-ss格式的截图文件。
1.FileUtil类
package apiSample; import java.io.File; import java.io.IOException; /*FileUtil类用于创建目录和文件*/ public class FileUtil { public static boolean createFile(String destFileName){ File file=new File(destFileName); if(file.exists()){ System.out.println("创建单个文件"+destFileName+"失败,目标文件已存在!"); return false; } if(destFileName.endsWith(File.separator)){ System.out.println("创建单个文件"+destFileName+"失败,目标文件不能为目录"); return false; } //判断目标文件所在的目录是否存在 if(!file.getParentFile().exists()){ //如果目标文件所在的目录不存在,则创建父目录 System.out.println("目标文件所在目录不存在,准备创建它!"); if(!file.getParentFile().mkdirs()){ System.out.println("创建目标文件所在目录失败!"); return false; } } //创建目标文件 try{ if(file.createNewFile()){ System.out.println("创建单个文件"+destFileName+"成功!"); return true; }else{ System.out.println("创建单个文件"+destFileName+"失败!"); return false; } }catch(IOException e){ e.printStackTrace(); System.out.println("创建单个文件"+destFileName+"失败!"+e.getMessage()); return false; } } public static boolean createDir(String destDirName){ File dir=new File(destDirName); if(dir.exists()){ System.out.println("创建目录"+destDirName+"失败,目标目录已经存在"); return false; } //创建目录 if(dir.mkdirs()){ System.out.println("创建目录"+destDirName+"成功!"); return true; }else{ System.out.println("创建目录"+destDirName+"失败!"); return false; } } }
2.DateUtil类
package apiSample; //用于生成年、月、日、小时、分钟和秒的信息,用于生成保存截图文件目录名和文件名 public class DateUtil { /* * 格式化输出日期 * @return返回字符型日期 */ public static String format(java.util.Date date, String format){ String result=""; try{ if(date!=null){ java.text.DateFormat df=new java.text.SimpleDateFormat(format); result=df.format(date); } }catch(Exception e){ e.printStackTrace(); } return result; } /* * 返回年份 * @return 返回年份 */ public static int getYear(java.util.Date date){ java.util.Calendar c=java.util.Calendar.getInstance(); c.setTime(date); return c.get(java.util.Calendar.YEAR); } /* * 返回月份 * @return 返回月份 */ public static int getMonth(java.util.Date date){ java.util.Calendar c=java.util.Calendar.getInstance(); c.setTime(date); return c.get(java.util.Calendar.MONTH) +1; } /* * 返回在月份中的第几天 * @return 返回月份中的第几天 */ public static int getDay(java.util.Date date){ java.util.Calendar c=java.util.Calendar.getInstance(); c.setTime(date); return c.get(java.util.Calendar.DAY_OF_MONTH); } /* * 返回小时 * @return 返回小时 */ public static int getHour(java.util.Date date){ java.util.Calendar c=java.util.Calendar.getInstance(); c.setTime(date); return c.get(java.util.Calendar.HOUR_OF_DAY); } /* * 返回分钟 * @return 返回分钟 */ public static int getMinute(java.util.Date date){ java.util.Calendar c=java.util.Calendar.getInstance(); c.setTime(date); return c.get(java.util.Calendar.MINUTE); } /* * 返回秒 * @return 返回秒 */ public static int getSecond(java.util.Date date){ java.util.Calendar c=java.util.Calendar.getInstance(); c.setTime(date); return c.get(java.util.Calendar.SECOND); } }
3.TestFailCaptureScreen
package apiSample; import java.io.File; import java.util.Date; import org.apache.commons.io.FileUtils; import org.junit.Assert; import org.openqa.selenium.By; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; public class TestFailCaptureScreen { public WebDriver driver; String baseUrl="http://www.sogou.com/"; @Test public void testSearch(){ driver.get(baseUrl+"/"); driver.findElement(By.id("query")).sendKeys("雷军"); driver.findElement(By.id("stb")).click(); try{ //断言页面的代码中是否存在“事在人为”这4个关键字,因为页面中没有这4个字,所以会触发catch语句的执行,并触发截图操作 Assert.assertTrue(driver.getPageSource().contains("事在人为")); System.out.println("assert后继续执行了"); }catch(AssertionError e){ System.out.println("catch中的代码被执行了"); takeTakesScreenshot(driver); } } @BeforeMethod public void beforeMethod(){ System.setProperty("webdriver.gecko.driver", "MyDriver/geckodriver.exe"); driver=new FirefoxDriver(); } @AfterMethod public void afterMethod(){ driver.quit(); } //在测试类中声明截图的方法,截图方法调用了时间类和文件操作类的静态方法,用来以时间格式生成目录名称和截图文件名称 public void takeTakesScreenshot(WebDriver driver){ try{ Date date=new Date(); //调用DateUtil类中的方法,生成截图所在的文件夹日期名称 String picDir="d:\\"+String.valueOf(DateUtil.getYear(date))+"-"+ String.valueOf(DateUtil.getMonth(date))+"-"+String.valueOf(DateUtil.getDay(date)); if(!new File(picDir).exists()){ FileUtil.createDir(picDir); } //调用DateUtil类中的方法,生成截图文件的时间名称 String filePath=picDir+"\\"+String.valueOf(DateUtil.getHour(new Date()))+"-"+String.valueOf(DateUtil.getMinute(new Date())) +"-"+String.valueOf(DateUtil.getSecond(new Date()))+".png"; //进行截图,并将文件内容保存在srcFile对象中 File srcFile=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); //将截图文件内容写入到磁盘中,生成截图文件 FileUtils.copyFile(srcFile, new File(filePath)); }catch(Exception e){ e.printStackTrace(); } } }
此例子借助了两个工具类来实现测试目的,此种方式将常用的代码进行封装,便于提高代码的复用度,提高测试脚本编写的效率。
40.高亮显示正在被操作的页面元素
在测试过程中,经常会进行调试工作,使用高亮显示被操作页面元素的方式可以提高调试过程中的效率,以图形高亮的方式提示测试人员目前正在操作页面上的哪些元素。
package apiSample; 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.FirefoxDriver; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; public class TestHighLightWebElement { public WebDriver driver; private String baseUrl; @BeforeMethod public void setUp() throws Exception{ System.setProperty("webdriver.gecko.driver", "MyDriver/geckodriver.exe"); driver=new FirefoxDriver(); baseUrl="http://wwww.sogou.com"; } @AfterMethod public void tearDown() throws Exception{ driver.quit(); } @Test public void testHightLightWebElement() throws InterruptedException{ driver.navigate().to(baseUrl); WebElement searchInputBox=driver.findElement(By.id("query")); WebElement submitButton=driver.findElement(By.id("stb")); //调用高亮显示元素的封装函数,将搜索输入框进行高亮显示 highlightElement(searchInputBox); searchInputBox.sendKeys("雷军"); //停顿3秒查看高亮效果 Thread.sleep(3000); //调用高亮显示元素的封装函数,将搜索按钮进行高亮显示 highlightElement(submitButton); Thread.sleep(3000); //停顿3秒查看高亮效果 submitButton.click(); } //封装好的高亮显示元素的函数 public void highlightElement(WebElement element){ JavascriptExecutor js=(JavascriptExecutor) driver; //使用JavaScript语句将传入参数的页面元素对象的背景颜色和边框颜色分别设定为黄色和红色 js.executeScript("arguments[0].setAttribute('style', arguments[1]);",element,"background:yellow;border:2px solid red;"); } }