2017-10-13 149 views
2

當我點擊一個按鈕,一個新的頁面打開一個表單,我需要填寫該頁面上的一個字段。如何讓behat在填充之前等待屏幕上顯示一個元素?

但是,只要頁面開始加載,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); 
    } 

有人能幫助我嗎?

+0

使用帶定時器的「do-while」循環。 – lauda

+0

量角器或水貂是否沒有提供framewokr功能? –

回答

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。

0

如果你使用的是隻模擬瀏覽器的驅動程序(比如BrowserKit或Goutte),只有當DOM被正確編寫並準備好(當然沒有js可以被解釋或執行)時,behat纔會有控制權。如果你使用類似Selenium2的東西,並且該字段是從異步調用構建的(如果我理解正確,這是你的情況),取決於你是否確定該頁面是完整加載的。這是因爲請求有響應,並且控制權被傳回Behat進程。
這個問題的一個可能的解決方案是在每個ajax/async調用之前將一個類追加到主體中,並在每次調用完成後將其剝離。然後,在你的behat上下文中創建一個「微調器」函數來檢查課程是否會消失。

+0

我用這個旋轉功能,它的工作原理!謝謝! ' $ element = null;使用(&$ element){$ element = $ context-> getSession() - > getPage() - > findField('voucher_subject'); return $ element && $ element-> isVisible(); }); $ element-> setValue($ faker-> text); ' –

1

從我的角度來看可以做到這一點,現在更優雅:

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

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

你也可以把這個包裏面的一些private功能。

相關問題