Php 如何让Mink Selenium 2驱动程序等待页面加载Behat

Php 如何让Mink Selenium 2驱动程序等待页面加载Behat,php,selenium,phantomjs,behat,mink,Php,Selenium,Phantomjs,Behat,Mink,我正在从Behat 2.x系列升级到Behat 3.x系列。在以前的版本中,我可以加载Selenium 1驱动程序,该驱动程序连接到PhantomJS以执行测试。当我这样做时,我能够钩住一个名为waitForPageToLoad()的函数 该函数由php selenium(来自Alexandre Salomé)提供。它连接到selenium并以相同的名称调用驱动程序操作。这非常适合确保Selenium等待页面加载。至少在达到超时之前。这使得测试进行得更快 问题是Selenium 1驱动程序与Be

我正在从Behat 2.x系列升级到Behat 3.x系列。在以前的版本中,我可以加载Selenium 1驱动程序,该驱动程序连接到PhantomJS以执行测试。当我这样做时,我能够钩住一个名为waitForPageToLoad()的函数

该函数由php selenium(来自Alexandre Salomé)提供。它连接到selenium并以相同的名称调用驱动程序操作。这非常适合确保Selenium等待页面加载。至少在达到超时之前。这使得测试进行得更快

问题是Selenium 1驱动程序与Behat 3.x不兼容。看起来它几乎被放弃了,我在Selenium 2驱动程序中没有看到用于Mink的功能

有人知道如何使用Behat 3.x和Selenium 2实现此功能吗?

Selenium 2现在具有此功能

您可以像这样使用它:

/**
 * @Then /^I wait for the ajax response$/
 */
public function iWaitForTheAjaxResponse()
{
    $this->getSession()->wait(5000, '(0 === jQuery.active)');
}
您可以测试的其他条件包括:

  • 页面上某个元素的外观
  • 要完成加载的DOM
使用selenium(或任何其他驱动程序)的selenium网站上概述了更改的原因,我从来不用担心页面是否已加载,只有一个例外:如果页面完成加载,则通过AJAX加载更多内容

要处理此问题,可以使用Behat手册中记录的旋转功能

这样做的好处是:

  • 它不需要您使用selenium驱动程序(例如,如果您希望速度超过外观,您可以使用PhantomJS)
  • 如果您停止使用jQuery并切换到其他东西(例如Angular的$httpProvider),它不会中断
不过我不会用他们的,因为背面的痕迹被破坏了,不管怎样,谁想在两次检查之间再等一秒钟。:)

试试这个:

假设您正在使用(谢谢),您只需每隔一秒左右检查一次页面,直到达到所需的效果 文本出现或消失,或者给定的超时已过期,在这种情况下,我们假设失败

/**
 * @When I wait for :text to appear
 * @Then I should see :text appear
 * @param $text
 * @throws \Exception
 */
public function iWaitForTextToAppear($text)
{
    $this->spin(function(FeatureContext $context) use ($text) {
        try {
            $context->assertPageContainsText($text);
            return true;
        }
        catch(ResponseTextException $e) {
            // NOOP
        }
        return false;
    });
}


/**
 * @When I wait for :text to disappear
 * @Then I should see :text disappear
 * @param $text
 * @throws \Exception
 */
public function iWaitForTextToDisappear($text)
{
    $this->spin(function(FeatureContext $context) use ($text) {
        try {
            $context->assertPageContainsText($text);
        }
        catch(ResponseTextException $e) {
            return true;
        }
        return false;
    });
}

/**
 * Based on Behat's own example
 * @see http://docs.behat.org/en/v2.5/cookbook/using_spin_functions.html#adding-a-timeout
 * @param $lambda
 * @param int $wait
 * @throws \Exception
 */
public function spin($lambda, $wait = 60)
{
    $time = time();
    $stopTime = $time + $wait;
    while (time() < $stopTime)
    {
        try {
            if ($lambda($this)) {
                return;
            }
        } catch (\Exception $e) {
            // do nothing
        }

        usleep(250000);
    }

    throw new \Exception("Spin function timed out after {$wait} seconds");
}
/**
*@当我等待:文本出现时
*@那么我应该看到:文本出现了
*@param$text
*@throws\Exception
*/
公共功能I等待文本出现($text)
{
$this->spin(函数(FeatureContext$context)使用($text){
试一试{
$context->assertPageContainsText($text);
返回true;
}
捕获(响应扩展异常$e){
//努普
}
返回false;
});
}
/**
*@当我等待:文字消失时
*@那么我应该看到:文字消失了
*@param$text
*@throws\Exception
*/
公共函数iWaitForTextToDisappear($text)
{
$this->spin(函数(FeatureContext$context)使用($text){
试一试{
$context->assertPageContainsText($text);
}
捕获(响应扩展异常$e){
返回true;
}
返回false;
});
}
/**
*基于Behat自己的例子
*@见http://docs.behat.org/en/v2.5/cookbook/using_spin_functions.html#adding-a-超时
*@param$lambda
*@param int$wait
*@throws\Exception
*/
公共函数旋转($lambda,$wait=60)
{
$time=time();
$stopTime=$time+$wait;
while(time()<$stopTime)
{
试一试{
如果($lambda($this)){
返回;
}
}捕获(\异常$e){
//无所事事
}
美国LEEP(250000);
}
抛出new\Exception(“自旋函数在{$wait}秒后超时”);
}

为了帮助其他人,我在FeatureContext.php中添加了以下方法:

 /**
 * @Then I wait :sec
 */
public function wait($sec)
{
    sleep($sec);
}
它正在工作 意志


这是我常用的方法,简单有效。然而,在我看来,这个测试包括了应用程序如何工作的限制,而你应该关心的是应用程序是否工作。如果您在应用程序中的任何位置替换jQuery,这将不起作用,并且您不能在不使用jQuery的项目中重用它。当您的测试应该尝试独立于驱动程序时,它还依赖于您运行Selenium。尽管如此,正如我所说,它是有效的,而且很简单。我想如果jQuery不存在,您可以动态地注入和包含它,以使其工作……如果您有一个错误,告诉您jQuery未知,请将条件更改为:
(typeof jQuery!=“undefined”&&0==jQuery.active)
注意:人,您需要扩展,因为它有
assertPageContainsText
这不应该再使用了,因为还有其他更合适的函数等待内容出现在页面上。目前最好的方法是调用wait(),如下所述@brian_d。您能描述一下吗?
/**
* @Then /^I wait for the ajax response$/
*/
public function iWaitForTheAjaxResponse()
{
   $this->getSession()->wait(5000, '(0 === jQuery.active)');
}