java之web自动化,隐式等待,显式等待
元素的等待有几种,如下:
1.强制等待
//强制等待 Thread.sleep(2000);
2.显式等待
当页面寻找元素时,先看有没有,如果没有,判断元素等待时间有没有超过设置的时间,如果没有超过这个时间,则再次寻找这个元素,直到找到该元素,或者时间超过设置时间,如果没找到,并且超时,会报一个超时异常。
显式等待作用域只限于某一条查询元素的代码,并不是全局生效
3.隐式等待
在页面寻找元素时,首先去找web元素,如果没有找到,判断时间是否超过设置的时间,如果没有超过,则会再次去寻找这个元素,直到找到元素或者时间超过设置时间。
隐式等待的作用域与driver示例的生命周期一致,意思就是设置隐式等待,那么隐式等待对于全局的寻找元素都会生效!
package com.web_java01; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.annotations.AfterSuite; import org.testng.annotations.AfterTest; import org.testng.annotations.Test; import java.util.concurrent.TimeUnit; public class web_test07 extends Base { @Test public void test() throws InterruptedException { //设置超时抛出异常,TimeUnit.SECONDS时间单位为秒,设置2秒为超时 driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS); //访问百度 driver.get("http://www.baidu.com"); //隐式等待,TimeUnit.SECONDS时间单位为秒,设置10秒为超时 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.findElement(By.id("kw")); //一、显式等待,new WebDriverWait 里面要传一个驱动对象,然后是超时时间,以秒为单位,后面是轮询时间(默认是500毫秒),以毫秒为单位 WebDriverWait wait = new WebDriverWait(driver, 10,500); //通过wait.until里面的方法找到元素 WebElement weekelement = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("kw"))); //执行点击或者输入值操作 weekelement.click(); //二、这是通过封装的显示等待定位元素,上面未封装需要三步操作点击,封装后,直接只需一步 getElement(By.id("kw"), 20).click(); //切换到iframe旷课也可以用显式等待 //不用显式等待操作 WebElement iframeelement = driver.findElement(By.cssSelector("iframe[src='course-plan']")); //切换到iframe窗口 driver.switchTo().frame(iframeelement); //操作元素 driver.findElement(By.cssSelector("div.ul")).click(); //用显式等待操作 WebElement iframeelement2 = getElement(By.cssSelector("iframe[src='course-plan']"),20); //切换到iframe窗口 driver.switchTo().frame(iframeelement2); //操作元素 driver.findElement(By.cssSelector("div.ul")).click(); //强制等待 Thread.sleep(3000); //图片验证写到cookies中的情况 String verifycode = driver.manage().getCookieNamed("verifycode").getValue(); //然后再把读取到的验证码写到输入框中去 driver.findElement(By.id("kw")).sendKeys(verifycode); driver.quit(); } //定义一个显式等待元素定位的方法,presenceOfElementLocated方法能保证元素出现在dom树上,但不能保证可见 public WebElement getElement(By by,long outtime){ //显式等待,new WebDriverWait 里面要传一个驱动对象,然后是超时时间,以秒为单位,后面是轮询时间(默认是500毫秒),以毫秒为单位 WebDriverWait wait = new WebDriverWait(driver, outtime); try { WebElement weekelement = wait.until(ExpectedConditions.presenceOfElementLocated(by)); return weekelement; } catch (Exception e) { System.out.println("定位元素超时"); return null; } } //所以需要再加一个获取一个可见元素方法 public WebElement getVibileElement(By by){ //显式等待,new WebDriverWait 里面要传一个驱动对象,然后是超时时间,以秒为单位,后面是轮询时间(默认是500毫秒),以毫秒为单位 WebDriverWait wait = new WebDriverWait(driver, 30); try { WebElement weekelement = wait.until(ExpectedConditions.visibilityOfElementLocated(by)); return weekelement; } catch (Exception e) { System.out.println("定位元素超时"); return null; } } //定义一个显式等待页面加载完成的方法 public WebElement getpagereadyElement(By by){ //显式等待,new WebDriverWait 里面要传一个驱动对象,然后是超时时间,以秒为单位,后面是轮询时间(默认是500毫秒),以毫秒为单位 WebDriverWait wait = new WebDriverWait(driver, 30); try { String jsToBeExecute = "return document.readyState == 'complete'"; Boolean isready = (Boolean) wait.until(ExpectedConditions.jsReturnsValue(jsToBeExecute)); if (isready){ return getVibileElement(by); } } catch (Exception e) { System.out.println("页面加载超时"); } return null; } @AfterSuite public void teardown() throws InterruptedException { Thread.sleep(3000); driver.quit(); } }