Behat 旋转方法找不到 Selennium 选择器
Behat spin method not finding Selennium selector
鉴于我从 Behat 文档中获取了以下场景:
@javascript
Scenario: Searching for a page with autocompletion
Given I am on "/wiki/Main_Page"
When I fill in "search" with "Behavior Driv"
And I wait for the suggestion box to appear
Then I should see "Behavior Driven Development"
我的 FeatureContext
class 扩展了 MinkContext
并具有以下方法:
/**
* @Given /^I wait for the suggestion box to appear$/
*/
public function iWaitForTheSuggestionBoxToAppear()
{
$this->spin(function (FeatureContext $context) {
return $context->assertElementOnPage('.suggestions-result');
}, 15);
return true;
}
public function spin ($lambda, $wait = 15)
{
for ($i = 0; $i < $wait; $i++)
{
try {
if ($lambda($this)) {
return true;
}
} catch (Exception $e) {
// do nothing
}
sleep(1);
}
$backtrace = debug_backtrace();
throw new Exception(
"Timeout thrown by " . $backtrace[1]['class'] . "::" . $backtrace[1]['function'] . "()\n" .
$backtrace[0]['file'] . ", line " . $backtrace[0]['line']
);
}
我的 Behat 配置设置为:
default:
extensions:
Behat\MinkExtension:
base_url: http://en.wikipedia.org
goutte: ~
selenium2:
browser: phantomjs
为什么我发现传递给 spin
的函数从未 returns 为真?如果我传入页面首次加载时存在的选择器,例如 body
,它会工作正常,但我希望它能发现自动完成结果(或者更确切地说包含结果的标记)可用。
我是不是哪里出错了?
selennium 服务器的日志显示选择器试图查找元素:
20:44:40.924 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:41.161 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:42.218 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:42.445 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:43.454 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:43.696 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:44.724 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:44.962 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:45.969 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:46.249 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:47.273 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:47.519 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:48.529 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:48.816 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:49.829 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:50.075 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:51.082 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:51.306 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:52.314 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:52.540 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:53.546 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:53.768 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:54.773 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:54.994 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:56.011 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:56.226 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:57.234 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:57.479 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:58.485 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:58.720 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:59.837 INFO - Executing: [delete session: d95ac5c9-6969-4ecb-b8f2-aafc6f8b82a5])
[INFO - 2016-04-08T20:44:59.866Z] ShutdownReqHand - _handle - About to shutdown
20:45:00.425 INFO - Done: [delete session: d95ac5c9-6969-4ecb-b8f2-aafc6f8b82a5]
最后放弃了spin函数,因为遇到了同样的问题
我们发现一个可行的方法是隐式等待。
您可以将其粘贴到您的上下文中并像这样使用它们:
public function turnOnImplicitWait()
{
// Set up implicit timeouts
$driver = $this->getSession()->getDriver()->getWebDriverSession();
$driver->timeouts()->implicit_wait(array("ms" => 10000));
}
public function turnOffImplicitWait()
{
// Set up implicit timeouts
$driver = $this->getSession()->getDriver()->getWebDriverSession();
$driver->timeouts()->implicit_wait(array("ms" => 0));
}
/**
* @Given /^I set (?:|the )implicit wait to ([\d]+)? (m|mins?|s|seconds?|ms|milliseconds)?(?:| .*)$/
*/
public
function setImplicitWait($time, $msormins)
{
$driver = $this->getSession()->getDriver()->getWebDriverSession();
if ($msormins == "min" | $msormins == "mins") {
$time = $time * 60000;
} elseif ($msormins == "s" | $msormins == "seconds") {
$time = $time * 1000;
} elseif ($msormins == "ms" | $msormins == "milliseconds") {
$time = $time * 1;
}
$driver->timeouts()->implicit_wait(array("ms" => $time));
}
您也可以将其添加到您的功能上下文中,它将针对每个场景进行设置:
/**
* @BeforeScenario
*/
public function implicitlyWait($event)
{
// Set up implicit timeouts
$driver = $this->getSession()->getDriver()->getWebDriverSession();
$driver->timeouts()->implicit_wait(array("ms" => 10000));
}
请注意:
关闭隐式等待预期不会看到元素的步骤,你应该没问题。在它成功地没有看到元素后将其重新打开。不这样做会使它在隐式等待期间挂起。
鉴于我从 Behat 文档中获取了以下场景:
@javascript
Scenario: Searching for a page with autocompletion
Given I am on "/wiki/Main_Page"
When I fill in "search" with "Behavior Driv"
And I wait for the suggestion box to appear
Then I should see "Behavior Driven Development"
我的 FeatureContext
class 扩展了 MinkContext
并具有以下方法:
/**
* @Given /^I wait for the suggestion box to appear$/
*/
public function iWaitForTheSuggestionBoxToAppear()
{
$this->spin(function (FeatureContext $context) {
return $context->assertElementOnPage('.suggestions-result');
}, 15);
return true;
}
public function spin ($lambda, $wait = 15)
{
for ($i = 0; $i < $wait; $i++)
{
try {
if ($lambda($this)) {
return true;
}
} catch (Exception $e) {
// do nothing
}
sleep(1);
}
$backtrace = debug_backtrace();
throw new Exception(
"Timeout thrown by " . $backtrace[1]['class'] . "::" . $backtrace[1]['function'] . "()\n" .
$backtrace[0]['file'] . ", line " . $backtrace[0]['line']
);
}
我的 Behat 配置设置为:
default:
extensions:
Behat\MinkExtension:
base_url: http://en.wikipedia.org
goutte: ~
selenium2:
browser: phantomjs
为什么我发现传递给 spin
的函数从未 returns 为真?如果我传入页面首次加载时存在的选择器,例如 body
,它会工作正常,但我希望它能发现自动完成结果(或者更确切地说包含结果的标记)可用。
我是不是哪里出错了?
selennium 服务器的日志显示选择器试图查找元素:
20:44:40.924 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:41.161 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:42.218 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:42.445 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:43.454 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:43.696 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:44.724 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:44.962 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:45.969 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:46.249 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:47.273 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:47.519 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:48.529 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:48.816 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:49.829 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:50.075 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:51.082 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:51.306 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:52.314 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:52.540 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:53.546 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:53.768 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:54.773 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:54.994 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:56.011 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:56.226 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:57.234 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:57.479 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:58.485 INFO - Executing: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]])
20:44:58.720 INFO - Done: [find elements: By.xpath: //html/descendant-or-self::*[@class and contains(concat(' ', normalize-space(@class), ' '), ' suggestions-result ')]]
20:44:59.837 INFO - Executing: [delete session: d95ac5c9-6969-4ecb-b8f2-aafc6f8b82a5])
[INFO - 2016-04-08T20:44:59.866Z] ShutdownReqHand - _handle - About to shutdown
20:45:00.425 INFO - Done: [delete session: d95ac5c9-6969-4ecb-b8f2-aafc6f8b82a5]
最后放弃了spin函数,因为遇到了同样的问题
我们发现一个可行的方法是隐式等待。
您可以将其粘贴到您的上下文中并像这样使用它们:
public function turnOnImplicitWait()
{
// Set up implicit timeouts
$driver = $this->getSession()->getDriver()->getWebDriverSession();
$driver->timeouts()->implicit_wait(array("ms" => 10000));
}
public function turnOffImplicitWait()
{
// Set up implicit timeouts
$driver = $this->getSession()->getDriver()->getWebDriverSession();
$driver->timeouts()->implicit_wait(array("ms" => 0));
}
/**
* @Given /^I set (?:|the )implicit wait to ([\d]+)? (m|mins?|s|seconds?|ms|milliseconds)?(?:| .*)$/
*/
public
function setImplicitWait($time, $msormins)
{
$driver = $this->getSession()->getDriver()->getWebDriverSession();
if ($msormins == "min" | $msormins == "mins") {
$time = $time * 60000;
} elseif ($msormins == "s" | $msormins == "seconds") {
$time = $time * 1000;
} elseif ($msormins == "ms" | $msormins == "milliseconds") {
$time = $time * 1;
}
$driver->timeouts()->implicit_wait(array("ms" => $time));
}
您也可以将其添加到您的功能上下文中,它将针对每个场景进行设置:
/**
* @BeforeScenario
*/
public function implicitlyWait($event)
{
// Set up implicit timeouts
$driver = $this->getSession()->getDriver()->getWebDriverSession();
$driver->timeouts()->implicit_wait(array("ms" => 10000));
}
请注意: 关闭隐式等待预期不会看到元素的步骤,你应该没问题。在它成功地没有看到元素后将其重新打开。不这样做会使它在隐式等待期间挂起。