2017-10-13 6 views
2

ボタンをクリックすると、新しいページがフォームで開き、そのページのフィールドを入力する必要があります。要素を塗りつぶす前にスクリーンに表示されるのを待つようにするには?

ただし、ページの読み込みが開始されるとすぐに、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

分度器またはミンクはこれに対してフレームウォーカー機能を備えていませんか? –

答えて

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など)を使用している場合、behatはDOMが正しく構成され、準備が整っている(そしてjsが解釈または実行されることはない)ときに制御を戻します。 Selenium2のようなものを使用していて、フィールドが非同期呼び出しから構築されている場合(正しく理解すれば、これがあなたのケースです)、ページ全体が読み込まれていることを確認する必要があります。リクエストには応答があり、コントロールはBehatプロセスに戻されるからです。
この問題の解決策の1つは、各ajax/asyncコールの直前にボディにクラスを追加し、コールが終了するたびにそのクラスを削除することです。次に、あなたの行動コンテキストに「スピナー」関数を作成して、クラスを削除するかどうかを確認します。

+0

私はこのスピン機能を使っていました。ありがとうございました! ' $ element = null; return $ element && $$ this-> spin(function($ context))を使用すると、&lt;要素&$のコンテキスト&gt; getSession() - > findField( 'voucher_subject'); 要素 - > isVisible(); }); $ element-> setValue($ faker-> text); ' –

1

私の視点から、これは今、よりエレガントに行うことができます。

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

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

あなたはまた、いくつかのprivate関数内でこれをラップすることができます。

関連する問題