在对元素进行定位时,有时候网页加载时间比较长,元素还没有加载出来,这个时候去查找这个元素的话程序中就会抛出异常,所以我们在编写代码时需要考虑延时问题,在selenium中有几种延时机制可以使用如下:
6.1.硬性等待 硬性等待就是不管你浏览器元素是否加载完成,都要进行等待设置好的时间,利用 java 语言中的线程类 Thread 中的 sleep 方法,进行强制等待。
Thread.sleep(long millis) 该方法会让线程进行休眠。
如:Thread.sleep(3000) 表示程序执行的线程暂停 3 秒钟。
这种方法在一定的程度上是可以解决元素加载过慢的情况,但是不建议使用该方法,因为一般情况下我们无法判断网页到底需要多长时间加载完成,如果我们设置的时间过长,非常影响效率。
6.2.隐式等待 隐式等待的理解,就是我们通过代码设置一个等待时间,如果在这个等待时间内,网页加载完成后就执行下一步,否则一直等待到时间截止。
代码表示:
driver.manage.timeouts.implicitlyWait(long time, TimeUtil unit);
这种方法相对于硬性等待显的会灵活一点,但是隐式等待也有个弊端,因为这个设置是全局的,程序需要等待整个页面加载完成,直到超时,有时候我需要找的那个元素早就加载完成了,只是页面上有个别其他元素加载比较慢,程序还是会一直等待下去。直到所有的元素加载完成在执行下一步。
6.3.显式等待 显示等待是等待指定元素设置的等待时间,在设置时间内,默认每隔0.5s检测一次当前的页面这个元素是否存在,如果在规定的时间内找到了元素则执行相关操作,如果超过设置时间检测不到则抛出异常。默认抛出异常为:NoSuchElementException。推荐使用显示等待。
代码表示:
WebDriberWait wait = new WebDriverWait(dirver, timeOutInSeconds); wait.nutil(expectCondition);具体使用案例:
1.查找元素是否已经加载出来
WebDriverWait wait = new WebDriverWait(driver, 5); // 查找id为“kw"的元素是否加载出来了(已经在页面DOM中存在) wait.until(ExpectedConditions.presenceOfElementLocated(By.id("kw"))); // 在设定时间内找到后就返回,超时直接抛异常2.查找元素是否可见
WebDriverWait wait = new WebDriverWait(driver, 5); // 查找id为"kw"的元素是否可见 wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("kw")));3.查找元素是否可点击
WebDriverWait wait = new WebDriverWait(driver, 5); // 查找id为"kw"的元素是否可以点击 wait.until(ExpectedConditions.elementToBeClickable(By.id("kw")));4.自定义方法,重写ExpectedCondition中的apply方法
/* 自定义查找元素的方法,对元素查找方法进行二次封装,更加的灵活,可以加上自己逻辑。 */ public WebElement getElement(long timeOutInSecond, By by) { WebDriverWait wait = new WebDriverWait(driver, timeOutInSecond); WebElement element = wait.until(new ExpectedCondition<WebElement>() { @NullableDecl @Override public WebElement apply(@NullableDecl WebDriver webDriver) { return webDriver.findElement(by); } }); return element; } 6.3.1.ExpectedConditions类中常用方法 方法 描述presenceOfElementLocated(By locator) 判断某个元素是否被加到了dom树里,并不代表该元素一定可见;
visibilityOfElementLocated(By locator) 判断某个元素是否可见(代表元素非隐藏,元素的宽和高都不等于0);
elementToBeClickable(By locator) 判断某个元素中是否可见并且是enable的且可点击;
elementToBeSelected(By locator) 判断某个元素是否被选中了,一般用在下拉列表;
alertIsPresent() 判断页面上是否存在alert;
titleIs(String title) 判断当前页面的title是否精确等于预期;
titleContains(String title) 判断当前页面的title是否包含预期字符串;
textToBePresentInElement(By locator, String text) 判断某个元素中的text是否包含了预期的字符串;
textToBePresentInElementValue(By locator, String text) 判断某个元素中的value属性是否包含了预期的字符串;
invisibilityOfElementLocated(By locator) 判断某个元素中是否不存在于dom树或不可见;
frameToBeAvailableAndSwitchToIt(By) 判断iframe可用,并且切换到iframe中
6.4.页面加载超时设置