如何让behat在填充之前等待元素显示在屏幕上?

时间:2017-10-13 20:01:50

标签: php testing bdd behat mink

当我点击按钮时,会打开一个带有表单的新页面,我需要填写该页面上的字段。

但是,只要页面开始加载,就会尝试填充尚未加载的字段。

我想在尝试填充字段之前等待显示字段的隐式等待。

   /**
    * @Given que preencho corretamente os campos da tela
    */
   public function quePreenchoCorretamenteOsCamposDaTela()
   {
    $faker = Faker\Factory::create();
    $this->getPage()->findField('voucher_subject')->setValue($faker->text);
    $this->getPage()->findField('voucher_nameRecipient')->setValue($faker->name);
   }

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:2)

从我的观点来看,现在可以做得更优雅了:

$page = $this->getSession()->getPage();

$page->waitFor(5000,
    function () use ($page) {
        return $page->findField('voucher_subject')->isVisible();
    }
);

您也可以将其包含在某个private函数中。

答案 1 :(得分:1)

你可以使用旋转功能:

trait FeatureContextHelper
{
    public function spin (callable $lambda, $wait = 5)
    {
        $lastErrorMessage = '';

        for ($i = 0; $i < $wait; $i++) {
            try {
                if ($lambda($this)) {
                    return true;
                }
            } catch (Exception $e) {
                // do nothing
                $lastErrorMessage = $e->getMessage();
            }

            sleep(1);
        }


        throw new ElementNotVisible('The element is not visible ' . $lastErrorMessage);
    }
}

然后在你的背景下:

class FeatureContext extends MinkContext
{
    use FeatureContextHelper;

    /**
     * @Given que preencho corretamente os campos da tela
     */
     public function quePreenchoCorretamenteOsCamposDaTela()
     {
         $this->spin(function ($context) {
             $faker = Faker\Factory::create();
             $context->getSession()->getPage()->findField('voucher_subject')->setValue($faker->text);
             $context->getSession()->getPage()->findField('voucher_nameRecipient')->setValue($faker->name);
             return true;
         }
     }
}

它将尝试在5秒内找到该元素,然后在没有找到它时超时。它对Selenium2和Goutte很有用。

答案 2 :(得分:0)

如果您正在使用仅模拟浏览器的驱动程序(如BrowserKit或Goutte),那么只有在DOM正确组合并准备就绪时才能进行控制(当然,没有j可以解释或执行) 。如果您使用Selenium2之类的东西,并且该字段是从异步调用构建的(如果我理解正确,这是您的情况),由您决定是否完整地加载页面。这是因为请求有响应并且控制权传递回Behat流程 这个问题的一个可能的解决方案是在每个ajax / async调用之前将一个类附加到正文,并在每次调用完成后立即将其删除。然后,创建一个&#34;微调器&#34;在你的behat上下文中运行以检查要离开的类。