代码之家  ›  专栏  ›  技术社区  ›  Luiza Guerra

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

  •  2
  • Luiza Guerra  · 技术社区  · 7 年前

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

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

       /**
        * @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 回复  |  直到 7 年前
        1
  •  3
  •   freeek    6 年前

    在我看来,现在可以做得更优雅:

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

    你也可以把这个包在里面 private 作用

        2
  •  1
  •   zstate    7 年前

    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秒内找到元素,如果没有找到,则会超时。硒和痛风对我们很有效。

        3
  •  0
  •   DonCallisto    7 年前

    如果您使用的驱动程序只模拟浏览器(如BrowserKit或Goutte),那么只有当DOM正确组合并准备就绪时,behat才能重新控制(当然,没有js可以被解释或执行)。如果您使用Selenium2之类的东西,并且该字段是从异步调用构建的(如果我理解正确,这就是您的情况),则由您确定页面是否完整加载。这是因为请求有一个响应,并且控件被传递回Behat进程。