Java Selenium webdriverwait 解决元素不可点击问题

350人浏览 / 0人评论

关于元素不可点击的原因分析详情参见:selenium报错Element is not clickable at point及四种解决方法

webdriver有两种等待方式:显式等待和隐式等待

因为现在大部分的web应用程序会使用AJAX技术。AJAX技术简单来说就是异步JavaScript和xml,是一种用户创建快速动态网页的技术,AJAX可以使网页实现异步更新,也就是可以不重新加载整个网页的情况下,对网页部分进行更新。

也就是加载网页的时候,页面的元素可能并不是同时被加载,这就对页面元素的定位产生了一定的困难。有可能在定位元素的过程中,由于某个需要定位的元素没有及时加载出来,可能会报ElementNotVisibleException这种情况,会极大降低自动化脚本的稳定性,所以我们可以通过设置等待的方式,来改善这种情况。

一、显式等待

显式等待有两种:一种是强制等待:通过线程等待函数,让自动化测试做一定时间的等待,Thread.sleep(1000);

使用此方法会出现两种不能避免的情况:1.若设置的时间较短,仍不能解决上述问题;2.若设置时间较长,会花费大量的等待时间。我们很难去确定等待时间的长度,因为加载时间的长度会受到外部环境的影响,比如:网络情况,应用的大小,主机的配置情况,主机的内存和CPU的消耗情况。

 二是 使webdriver等待某个条件成立(界面某元素出现或者某可点击等条件)时,继续执行后续的操作,否则时间达到最大限值之后就抛出异常。采用WebDriverWait类 + ExceptedConditions接口

笔者比较推荐的方式就是这种方式

 ExpectedConditions类有很多方法,下面列出一些常用的方法

方法 说明
titleIs(String)
 
标题是不是“xxxx”
 
titleContains(String) 标题是不是包含“XXX”
presenceOfElementLocated(By)  
判断该元素是否被加载在DOM中,并不代表该元素一定可见 
 
visibilityOfElementLocated(By)  
判断元素是否可见(非隐藏,并且元素的宽和高都不等以0)
 
visibilityOf(WebElement)  
判断元素(定位后)是否可见
 
presenceOfAllElementsLocatedBy(By)  
只要存在一个就是true
 
 
 
textToBePresentInElementLocated(By, String)  
元素中的text是否包含预期的字符串
 
 textToBePresentInElementValue(By, String)  
元素的value属性中是否包含预期的字符串
 
 frameToBeAvailableAndSwitchToIt(By)  
判断该表单是否可以切过去,可以就切过去并返回true,否则返回false
 
 invisibilityOfElementLocated(By)  
判断某个元素是否不存在于DOM树或不可见
 
 elementToBeClickable(By)  
判断元素是否可见并且是可以点击的
 
 stalenessOf(WebElement)  
等到一个元素从DOM树中移除
 
 elementToBeSelected(WebElement)  
判断某个元素是否被选中,一般用在下拉列表
 
 elementSelectionStateToBe(By, boolean)  
判断某个元素的选中状态是否符合预期
 
elementSelectionStateToBe(WebElement, boolean)  
 
  1.  
    与上一个方法一样,只是该方法参数为定位后的元素,上一个方法接收的参数为定位
  2.  
    判断某个元素(已定位)的选中状态是否符合预期
 
  alertIsPresent()  
判断页面中是否存在alert
 

二、隐式等待  

相当于设置全局的等待,在定位元素时,对所有元素设置超时时间。

      隐式等待使得WebDriver在查找一个Element或者Element数组时,如果一直查找不到,每隔一段特定的时间就会轮询一次DOM。

      注:默认设置超时时间为0,一旦设置,这个隐式等待会在WebDriver对象实例的整个生命周期起作用。

隐式等待是通过一定的时长等待页面上某个元素加载完成。如果超过了设置的时长元素还没有被加载出来,则抛出NoSuchElementException异常。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

 代码中设置等待时间为10秒。首先这个10秒并非是一个固定的等待时间,它并不会影响脚本的执行速度。其次,它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则它将会以轮询的方式不断地判断元素是否被定位到。假设,第5秒等位到元素,就继续执行;但是如果超出设置的这个10秒,那就直接抛出异常

import org.openqa.selenium.WebDriver; 
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
 
import org.openqa.selenium.By;
import bsh.This;
 
public class BasicScene {
	WebDriver driver;
	String name;
	public BasicScene(WebDriver driver){
		
		this.driver =driver;
		this.name="888888";
	}
	
	public WebElement WaitUntilVisableEle(WebElement ele) {
		WebDriverWait wait = new WebDriverWait(this.driver, 20);
		wait.until(ExpectedConditions.visibilityOf(ele));
		return ele;	
	}
	public WebElement WaitUntilClickable(WebElement ele ) {
		WebDriverWait wait = new WebDriverWait(this.driver,20);
		wait.until(ExpectedConditions.elementToBeClickable(ele));
		return ele;
	}
    public WebElement Waittobeclickable(By locator){
        WebDriverWait wait = new WebDriverWait(driver, 10);
        // locator:By.id("someid")
        WebElement element =             
        wait.until(ExpectedConditions.elementToBeClickable(locator));
        return element
    }
 
}

转载自:https://blog.csdn.net/chen498858336/article/details/86383182

全部评论