除了在我的测试中使用sleep()
之外,我想知道是否有人知道在继续我的断言之前明确等待表单提交(POST)完成的更好策略。这是我的测试看起来非常精简的版本,一起使用来自Facebook的phpunit php-webdriver。
function test_form_submission()
{
// setup
$web_driver = new WebDriver();
$session = $web_driver->session();
$session->open('http://example.com/login');
// enter data
$session->element('css selector', 'input[name=email]')->value(array('value' => str_split('test@example.com')));
$session->element('css selector', 'input[name=password]')->value(array('value' => str_split('testpassword')));
// click button to submit form
$session->element('css selector', 'button[name=submit]')->click();
// How do I wait here until the click() above submits the form
// so I can check that we correctly arrives at the destination below
// without resorting to sleep()?
// Confirm that login was successful because we landed on account page
$this->assertSame('http://example.com/account', $session->url());
// teardown
$session->close();
}
答案 0 :(得分:19)
php-webdriver已于2013年6月重写。您可以像这样轻松等待网址。
// wait for at most 10 seconds until the URL is 'http://example.com/account'.
// check again 500ms after the previous attempt.
$driver->wait(10, 500)->until(function ($driver) {
return $driver->getCurrentURL() === 'http://example.com/account';
})
答案 1 :(得分:2)
好的,所以我知道这是一个非常古老的问题,但是当我偶然发现它时,我希望这对某人(甚至是OP?: - )仍然有用。)
经过一些搜索和阅读Google Code上的文章和消息后,我发现了一个我觉得非常难看的解决方案,但是没有一个很好的选择。您可以阅读here,WebDriver无法检测页面何时加载。所以,我们必须恢复等待。现在,OP正在使用Facebook的PHP WebDriver,它不包括等待实用程序AFAIK,但在使用this maintained clone时,您将获得WebDriverWait的实现。
现在的问题是:我们还等什么?您可以等待URL更改,但这绝不是一种可靠的方法,因为当URL已经更改时页面可能尚未加载。下一个选项:等待您要知道的要加载的页面上显示的元素。那会起作用,但是如果你想要更通用的方法呢?幸运的是,我读到了一个非常好的想法in the thread我在上面提到过。您可以等待两个页面上的元素消失并重新出现,例如页脚。
我刚刚实现了它,它似乎工作。下面的函数可以通过你的$session
并且只会在加载新页面时返回(或者至少页脚再次可用)。
public static function waitForNextPage($pWDSession) {
$aWait = new PHPWebDriver_WebDriverWait($pWDSession);
// wait for footer to not be available anymore
$aWait->until(
function($pWDSession) {
return (0 === count($pWDSession->elements(PHPWebDriver_WebDriverBy::CSS_SELECTOR, "#footer,#mx-footer")));
}
);
// wait for footer to be available again
$aWait->until(
function($pWDSession) {
return (0 < count($pWDSession->elements(PHPWebDriver_WebDriverBy::CSS_SELECTOR, "#footer,#mx-footer")));
}
);
}
你可以显然改变选择器或使用其他一些元素,这个想法保持不变。
我希望它有所帮助!干杯!
答案 2 :(得分:1)
您可以使用Implicit Wait and Explicit Wait
等待特定的Web元素,直到它出现在页面中。您可以定义的等待时间取决于应用程序。
明确等待
显式等待是您定义的代码,用于在进一步执行代码之前等待某个条件发生。如果达到的条件将终止等待并继续进一步的步骤。
代码:
WebDriverWait wait = new WebDriverWait(driver,30);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id(strEdit)));
或
WebElement myDynamicElement = (new WebDriverWait(driver, 30))
.until(new ExpectedCondition<WebElement>(){
@Override
public WebElement apply(WebDriver d) {
return d.findElement(By.id("myDynamicElement"));
}});
在抛出TimeoutException之前等待最多30秒,或者如果它发现元素将在0-30秒内返回它。默认情况下,WebDriverWait每500毫秒调用一次ExpectedCondition,直到它成功返回。成功返回的是ExpectedCondition类型是布尔返回true或非null返回值,用于所有其他ExpectedCondition类型。
您可以根据需要使用ExpectedConditions类。
隐含等待
隐式等待是告诉WebDriver在尝试查找一个或多个元素时,如果它们不能立即可用,则会在一定时间内轮询DOM
代码:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
要记住的一件事是,一旦设置了隐式等待 - 它将保留WebDriver对象实例的生命周期
有关详细信息,请使用此链接http://seleniumhq.org/docs/04_webdriver_advanced.jsp
答案 3 :(得分:0)
而不是click()
应该可以使用clickAndWait()
,以便等到下一页已加载。