2

私はこの問題を明示的に待ちます。私はThread.Sleep()を使いたくありません。これは、ページを開いて前後に移動する簡単なテストです。このページをロードするのに約2〜3秒かかるので、これを動的な方法(テスト)で実行したいと思います。私はあまりにもconfusigではないことを願っています。私は多くの研究をしましたが、何もうまくいかず、多分私は何か間違っています。Selenium C#で明示的に待機しても機能しません。なにが問題ですか?

https://www.dropbox.com/s/1k5vjc5czvmdd3u/ConsoleApplication2.rar?dl=0

私はので、私はそれだけでこれを呼び出すことは簡単だろうと考えていFindElementメソッドに拡張を使用しています:ここで私はまた、解決策がある

を(私はユニットテストを実行するために、ReSharperのを使用しています)メソッドを呼び出し、それ自身で待ちます。私は解決策にコメントしたいくつかの説明があります。誰かが私に助けてくれたら嬉しいです。 (申し訳ありませんが、完璧な英語はありません)。

using System; 
using System.Threading; 
using ConsoleApplication2.Extensions; 
using NUnit.Framework; 
using OpenQA.Selenium; 
using OpenQA.Selenium.Chrome; 
using OpenQA.Selenium.Support.UI; 

namespace ConsoleApplication2 
{ 
    class UnitTest1 
    { 
     private IWebDriver driver = new ChromeDriver(); 
     [SetUp] 
     public void Initialize() 
     { 
      driver.Url = "some url"; 
      Thread.Sleep(3500); 
      // driver.Manage().Timeouts().ImplicitlyWait(TimeSpan(20)); 

     } 

     [Test] 
     public void CheckBackForward() 
     { 
      //Go to first page in Online Help 
      driver.FindElement(By.XPath("//span/ul/li/span/a")).Click(); 
      // So if I am commenting this Thread.Sleep 
      // it will throw an exception at the extension method at line 13 at "@by" 
      // I've also checked this without extension method but still the same problem. It doesn'w wait at all, it will throw this 
      // exception as soon as FindElement method is called. 
      // I know that I shouldn't mix explicit waits with implicit ones. 
      //Thread.Sleep(1500); 
      //Store title 
      var title_text = driver.FindElement(By.XPath("//div[@id='shellAreaContent']/div/div[2]/ol/li[3]/span"),60).Text; 
      //Check if Back is enabled 
      Assert.IsTrue(driver.FindElement(By.XPath("//div[3]/a/span")).Enabled); 
      //Go back 
      driver.FindElement(By.XPath("//div[3]/a/span")).Click(); 
      //Check if Forward is enabled 
      Assert.IsTrue(driver.FindElement(By.XPath("//div[4]/a/span")).Enabled); 
      //Go forward 
      driver.FindElement(By.XPath("//div[4]/a/span")).Click(); 
      //Store title 
      var title_text2 = driver.FindElement(By.XPath("//div[@id='shellAreaContent']/div/div[2]/ol/li[3]/span")).Text; 
      //Check if you are on the same page 
      Assert.AreEqual(title_text2,title_text); 
     } 



     [TearDown] 
     public void EndTest() 
     { 
      driver.Quit(); 
     } 

    } 
} 

そしてここに拡張したものです:

using System; 
using OpenQA.Selenium; 
using OpenQA.Selenium.Support.UI; 

namespace ConsoleApplication2.Extensions 
{ 
    public static class Extension 
    { 
     public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds) 
     { 
      if (timeoutInSeconds <= 0) return driver.FindElement(@by); 
      var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds)); 
      return wait.Until(drv => drv.FindElement(@by)); 
     } 



    } 
} 

答えて

6

私は6+ヶ月間、セレンでコーディングしていると私はあなたと同じ問題を抱えていました。私はこの拡張メソッドを作成し、それは毎回私のために働く。

コードの内容は次のとおりです。 20秒間、その要素がページに存在するかどうかに関係なく、それぞれ500msがチェックされます。 20秒後に見つからなければ、例外がスローされます。 これは、動的な待機を行うのに役立ちます。

public static class SeleniumExtensionMethods { 
     public static WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20)); 
     public static void SafeClick(this IWebElement webElement) { 
      try { 
       wait.Until(ExpectedConditions.ElementToBeClickable(webElement)).Click(); 
      } catch (TargetInvocationException ex) { 
       Console.WriteLine(ex.InnerException); 
      } 

     } 

してからあなたのこのコードに置き換えますと

driver.FindElement(By.XPath("//span/ul/li/span/a")).Click(); 

を:私はこれを行います

IWebElement x = driver.FindElement(By.XPath("//span/ul/li/span/a")); 
x.SafeClick(); 
+0

が、今、私は私の解決策にとのためにあなたの答えを適応しようとしています今私は元気ではない。 – user3672802

+0

あなたの答えは私を助けました。これは、私にとって唯一の便利な行です:wait.Until(ExpectedConditions.ElementToBeClickable(webElement))。();をクリックします。 – user3672802

+0

それは素晴らしいです:) –

関連する問題