web-dev-qa-db-ja.com

要素がSelenium Webdriverに読み込まれるのを待つ方法は?

私はSelenium Webdriverを初めて使用し、1つのアプリケーションをテストしています。私のアプリケーションでは、Facebookアカウントのリンクについてテストする必要があります。リンクをクリックするたびに、資格情報を入力する必要があるポップアップが表示されます。リンクできることもあれば、テストが失敗することもあります。ポップアップウィンドウの読み込みに時間がかかり、次のコマンドが実行されて要素を見つけることができないため、理由がわかります。 Thread.Sleepを使用しましたが、暗黙の待機または明示的な待機を使用したいのですが、これはThread.Sleepではなく常に良い習慣です。暗黙の待機を使用する方法とそのコマンドを正確に使用する場所アドバイスをお願いします。ありがとう。

 public void SocialFaceBook()
    {           
        string currentWindow = driver.CurrentWindowHandle;
        PopupWindowFinder Finder = new PopupWindowFinder(driver);
        string facebookWindow = Finder.Click(driver.FindElement(By.XPath("//div[@id='panelFacebook']/div[2]/div[3]/div[3]/a")));
        // Switch To FaceBook Window
        driver.SwitchTo().Window(facebookWindow);
        System.Threading.Thread.Sleep(3000);

        // Link
        // Email Address
        IWebElement faceBookLinkEmail = driver.FindElement(By.Id("email"));
        faceBookLinkEmail.SendKeys(SocialFaceBookEmail);

        // Password
        IWebElement faceBookLinkPass = driver.FindElement(By.Id("pass"));
        faceBookLinkPass.SendKeys(SocialFaceBookPass);

        // Log In Button
        IWebElement faceBookLinkLogin = driver.FindElement(By.XPath("//input[@id='u_0_1']"));
        faceBookLinkLogin.Click();

        // Switch To Main Window
        driver.SwitchTo().Window(currentWindow);
        System.Threading.Thread.Sleep(3000);

        // Sync            
        IWebElement faceBookSync = driver.FindElement(By.XPath("//div[@id='panelFacebook']/div[2]/div[3]/div[2]/a"));
        faceBookSync.Click();

        // Unlink
        IWebElement faceBookUnLink = driver.FindElement(By.XPath("//div[@id='panelFacebook']/div[2]/div[3]/div[1]/a"));
        faceBookUnLink.Click();
    }

ポップアップが正しくロードされていないためにログインの詳細を見つけることができない場合や、Facebookアカウントのリンクに時間がかかるために同期ボタンを見つけることができない場合があります。アドバイスをお願いします。

6
user3931772

WebDriverWait wait = new WebDriverWait(driver、30); wait.until(ExpectedConditions.visibilityOfElementLocated(By.id( "locator")));

要素が見つかると、その要素が見つかるまで最大30秒間待機してから、実行されます。

19
Vicky

@Vickyの答えからいくつかの小さなことを変更する必要がありましたが、これは私が呼び出すことができるメソッドとして得たものです。

public static void WaitForElementLoad(By by, int timeoutInSeconds)
    {
        if (timeoutInSeconds > 0)
        {
            WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(timeoutInSeconds));
            wait.Until(ExpectedConditions.ElementIsVisible(by));
        }
    }

そして私はそれをこのように呼びます:

MyClass.WaitForElementLoad(By.CssSelector("div#div1 div strong a"), 10);
4
tylerlindell

以前は、1秒ごとに存在する要素を検出する関数を作成していました。続行する場合は、タイムアウトエラーをスローします。しかし、その関数ではまだThread.Sleepを使用しています。

他の良い解決策を期待してください。

0
Dexter Yao

スレッドスリープの代わりにExpectedCondition.visibilityOf(element)を使用します

0
bcar

プロジェクトのメソッドを書いた:

public static void WaitForElementPresentBy(By by)
        {
            try
            {
                Wait.Until(ExpectedConditions.ElementIsVisible(by));
            }
            catch (TimeoutException te)
            {

                Assert.Fail("The element with selector {0} didn't appear. The exception was:\n {1}", by, te.ToString());
            }
        }

待機はすでに定義されている必要があります。

0
Ukrainis

暗黙の待機-オブジェクトを識別する最大待機時間。500ミリ秒ごとにオブジェクトを識別します。最大時間内にオブジェクトを識別できない場合、そのような要素の例外はスローされません。

明示的な待機-同じ目的でajaxページの読み込みに使用されます。

最大待機時間はthread.sleepと同じです

0
venkat