> web的自动化测试中,我们经常会遇到这样一种情况:当我们的程序执行时需要页面某个元素,而此时这个元素还未加载完成,这时我们的程序就会报错。怎么办?等待。等待元素出现后再进行对这个元素的操作。
在selenium-webdriver中我们用两种方式进行等待:明确的等待和隐性的等待。
[TOC]
#### 明确的等待
>明确的等待是指在代码进行下一步操作之前等待某一个条件的发生。最不好的情况是使用sleep()去设置一段确认的时间去等待。但为什么说最不好呢?因为一个元素的加载时间有长有短,你在设置sleep的时间之前要自己把握长短,太短容易超时,太长浪费时间。selenium webdriver提供了一些方法帮助我们等待正好需要等待的时间,比如以下例子中我们设置的最长等待时间为15秒。
~~~
<?php
namespace Facebook\WebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
require_once('vendor/autoload.php');
header("Content-Type: text/html; charset=UTF-8");
// start Firefox with 5 second timeout
$host = 'http://localhost:4444/wd/hub'; // this is the default
$waitSeconds = 15; //需等待加载的时间,一般加载时间在0-15秒,如果超过15秒,报错。
$capabilities = DesiredCapabilities::chrome();
$driver = RemoteWebDriver::create($host, $capabilities, 5000);
$driver->get('https://www.baidu.com/');
//由于下拉框是通过点击“搜索设置”按钮触发JS动态生成的DOM,所以这里使用Wait for new element to appear方式,不然直接调用查找元素会报错,说找不到元素
$driver->wait($waitSeconds)->until(
WebDriverExpectedCondition::visibilityOfElementLocated(
WebDriverBy::id('kw')
)
);
$driver->findElement(WebDriverBy::id('kw'))->sendKeys('wwe');
echo 'done!';
//关闭浏览器
//$driver->quit();
?>
~~~
#### 隐性等待
> 隐性等待是指当要查找元素,而这个元素没有马上出现时,告诉WebDriver查询Dom一定时间。默认值是0,但是设置之后,这个时间将在WebDriver对象实例整个生命周期都起作用。上面的代码就变成了这样:
~~~
<?php
namespace Facebook\WebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
require_once('vendor/autoload.php');
header("Content-Type: text/html; charset=UTF-8");
// start Firefox with 5 second timeout
$host = 'http://localhost:4444/wd/hub'; // this is the default
$capabilities = DesiredCapabilities::chrome();
$driver = RemoteWebDriver::create($host, $capabilities, 5000);
$driver->manage()->timeouts()->implicitlyWait(15); //隐性设置15秒
$driver->get('https://www.baidu.com/');
$driver->findElement(WebDriverBy::id('kw'))->sendKeys('wwe');
echo 'done!';
//关闭浏览器
//$driver->quit();
?>
~~~
>两者选其一,第二种看起来比较一劳永逸。
如果一个无素没有出现都会默认等待你所设定的时间,直到超时或者元素出现