2017-11-06 22 views
-1

要素が存在するかどうかを確認する前に、ページが完全に読み込まれるまでSelenium WebDriverWait型を使用しようとしています。私はこの2つの異なったやり方を試みた。C#Selenium WebDriverWait.IgnoreExceptionTypesが機能しない

最初のメソッドはIgnoreExceptionTypesを使用し、Untilメソッド内でFindElementを呼び出します。これは、待機せずにただちにNoSuchElementExceptionをスローします。私はNoSuchElementExceptionを無視して、これがタイムアウトまで要素を見つけることを試みることを期待しました。このように動作するようには見えません。なぜMethod1は機能しませんか?

2番目のメソッドはExpectedConditions.ElementExistsを使用しており、正しく待機しているようです。

driver.Navigate().GoToUrl("http://www.google.com"); 
var myId = "myId"; 

//Method 1 
var wait1 = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); 
wait1.IgnoreExceptionTypes(typeof(NoSuchElementException)); 

//Does not wait. Immediately throws NoSuchElementException 
var result1 = wait1.Until(x => x.FindElement(By.Id(myId))); 

//Method 2 - works as expected 
var wait2= new WebDriverWait(driver,TimeSpan.FromSeconds(10)) 
    .Until(ExpectedConditions.ElementExists(By.Id(myId))); 
+0

を使用していますか?ページオブジェクトモデルを使用していますか? – JeffC

+0

私はそうは思わない。私の質問は、ドライバを作成する以外のすべてのコードを持っています – mje777

答えて

1

だから私はこのすべての時間を行う...

を新たに言い換え、質問に答えます。ページオブジェクトモデルを使用してオートメーションを作成するので、これはうまくいくが、ページオブジェクトモデルを使用していなくても使用できる。

これは基本的なコンセプトです。最後にロードされた要素を見つけ、その要素を待ちます。その時点で、ページの読み込みが完了していて、読み込みが完了していないページの一部の要素とのやりとりを心配することなくスクリプトを続行できます。

警告...どのような要素が最後にロードされているのかわかりますか?何も思いつきません。あなたは基本的に推測(うまくいけば推測)し、それが失敗するまで使用します。あなたのページがひどく動的でない場合は、要素について選択するだけです。ページの一部が遅くロードされている場合は、ページのその部分の中の要素を選択します。

これは一般的にどのように私のために行くのですか。いくつかのページにページオブジェクトを書きます。私はページ上の一意の要素を選択し、By waitForLocatorと宣言します。私は

By waitForLocator = By.Id("myId"); 
new WebDriverWait(Driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(waitForLocator)); 

呼び出すページの読み込みが終了するまで待機したいときに今、今、私は、ページがロード行われ、私は上のページオブジェクトのための書き込み方法については行くとすることを(かなり)確信しています。私は、そのページオブジェクトを消費し、テストケースに応じてページとやりとりしてスクリプトを実行するスクリプトを作成します。うまくいけば私はwaitForLocatorをうまく選んだ。私がしていない場合、いくつかの要素が完全に読み込まれていない(それは、選択した要素の後に読み込まれた)ため、スクリプトの実行中のある時点でいくつかの例外が発生します。だから、私はwaitForElementを、私がちょうどそれとやり取りした要素に変更して例外をスローしました。そして、最後のロード要素でより良い推測をするべきです。基本的には、例外がなくなるまでこのプロセスを繰り返します。

これは非常に危険な方法です。それは本当にそれよりもはるかに危険なようです。あなたのサイトとあなたのページを知っているなら、かなり良い最初の推測をするでしょう。私はその推測を一度変更しなければならないことは非常にまれであり、それを一度以上変更しなければならないことは本当にまれです。つまり、それを変更するのは本当に簡単です。あなたはすでに例外をスローした要素のロケータを持っています。それをwaitForLocatorの宣言に貼り付ければ完了です。あなたが適切にあなたのwaitForLocatorと、ページがロードされた後を選択した場合

は、あなたがに実行するかもしれない唯一の例外は、あなたが動的にページの他のいくつかの部分をロードするページ上のいくつかの要素をクリックしてください。このシナリオは、ページが読み込まれるのを待っている範囲を超えています。この場合、クリックが行われた後にページの新しく読み込まれた部分のロードが完了するのを待つ別の待機を構築する必要があります。ページの読み込みメカニズムには影響しません。


追加コメント

帰るとあなたの質問を読んだ後、ここであなたの人生が容易になりますいくつかの追加情報です。

私は/この原則

public void ClickElementById(RemoteWebDriver driver, string id) 
{ 
    driver.FindElement(By.Id(id)).Click(); 
} 

にこの方法が書かれている方法を実証するために、以下の単純化された変更した方法を持っていたあなたの元の質問は、あなたがそれぞれのロケーター・タイプのための方法を作るために自分自身を強制

、ID、名前、CSSセレクタ、XPathなど。文字列を渡すのではなく、Byロケータを渡します。

public void ClickElement(RemoteWebDriver driver, By locator) 
{ 
    driver.FindElement(locator).Click(); 
} 

この新しい方法では、完全に柔軟です。任意のロケータタイプを渡すことができ、それは動作します。それを呼び出すには

ClickElement(driver, By.Id("someId")); 
+0

私は混乱しています。投稿したメソッドにはパラメータとしてdriverとidがありますが、カスタム待ち時間と既存の要素について話しています。おそらくあなたが実際にやっていることについて質問を明確にする必要があります。なぜなら、あなたがここで質問している質問とは違うからです。 – JeffC

+0

更新された質問、削除されたコメント – mje777

+1

新しい情報に基づいて私の答えが更新されました – JeffC

関連する問題