web-dev-qa-db-ja.com

C#Seleniumドライバーに要素が存在するかどうかを確認する方法

したがって、Firefox Selenium Webdriersを使用したこのc#winformがあります。

基本的に、要素が存在するかどうか、また別の要素をクリックしないかどうかを確認する必要があります。ビデオがあり、視聴後にW_VIEWEDになる場合

ここに私がこれまでに得たものがあります

driver.FindElement(By.XPath("//div[@class='video']/a")).Click();
else {
          driver.FindElement(By.XPath("//div[@class='W_VIEWED']/a")).Click();
     }

エラー3代入、呼び出し、インクリメント、デクリメント、待機、および新しいオブジェクト式のみがステートメント242として使用できます

C#Seleniumの新種。ご協力ありがとうございます。

17
Programerszz

要素の終了を確認するか、使用しない

bool isElementDisplayed = driver.findElement(By.xpath("element")).isDisplayed()

findElementthrowsは、要素が見つからない場合に例外をスローするため、適切に処理する必要があることを忘れないでください。

私のアプリケーションの1つで、別の関数の要素をチェックして例外を処理しました。

    private bool IsElementPresent(By by)
    {
        try
        {
            driver.FindElement(by);
            return true;
        }
        catch (NoSuchElementException)
        {
            return false;
        }
    }

関数を呼び出し、

            if (IsElementPresent(By.Id("element name")))
            {
                //do if exists
            }
            else
            {
                //do if does not exists
            }
32
Pranit Kothari

FindElementは例外を発生させるため、FindElementに「s」を付けて存在するかどうかを判断できます。 FindElementsが要素を返さない場合、空のリストを返します。

List<IWebElement> elementList = new List<IWebElement>();
elementList.AddRange(driver.FindElements(By.XPath("//input[@att='something']")));

if(elementList.Count > 0)
{
 //If the count is greater than 0 your element exists.
   elementList[0].Click();
}
16

それで、私は最近別の方法を見つけました。それは非常に高速です。要素に固有のIDまたはページの他の場所に存在しない属性がある場合、PageSourceを確認できます。

driver.PageSource.Contains("UniqueID");

ページをチェックして、IDまたは他の一意のテキストが存在するかどうかを確認します。これは、Try/Catchステートメントを使用する場合とは異なり、ほぼ瞬時に発生します。これには20秒ほどかかります。 FindElementsも実行に時間がかかります。

これは私が使用するものです。 「verify」メソッドは、要素が存在するかどうかに基づいてtrueまたはfalseを返します。 「testfunc」という名前のメソッドは、要素名を入力する場所です。この例では、ページに「英語」が表示されるかどうかを確認しています。また、上記のコメントで、人々はキャッチが機能するまで10秒以上待たなければならないと言っています。キャッチがすぐに機能するように、コードの明示的な待機を削除してみてください。

static public bool verify(string elementName)
    {
        try
        {
            bool isElementDisplayed = driver.FindElement(By.XPath(elementName)).Displayed;
            return true;
        }
        catch
        {
            return false;
        }
        return false;
    }

    static void testfunc()
    {
       bool test = verify("//option[contains(.,'English')]");
        Console.WriteLine(test);

    }
0
agleno

受け入れられた回答のソリューションをしばらくの間使用しましたが、チェックが失敗するたびにタイムアウト期間を待たずに、より高速なチェック方法が必要でした。そこで、IWebElementとIWebDriverで動作する拡張機能を作成し、タグまたはクラスの存在を確認しました。コードブロックの最初と最後で一貫性のないフォーマットをご容赦ください。 SOの編集者は協力していません; P

public static class ExtensionMethods {

public static bool ContainsTag(this IWebElement element, string tagName)
{
    string elementText = element.GetAttribute("innerHTML");
    return CheckStringForTag(elementText, tagName);
}

public static bool ContainsClass(this IWebElement element, string className)
{
    string elementText = element.GetAttribute("innerHTML");
    return CheckStringForClass(elementText, className);
}

public static bool ContainsTag(this IWebDriver driver, string tagName)
{
    return CheckStringForTag(driver.PageSource, tagName);
}

public static bool ContainsClass(this IWebDriver driver, string className)
{
    return CheckStringForClass(driver.PageSource, className);
}

private static bool CheckStringForTag(string text, string tagName)
{
    if (!string.IsNullOrWhiteSpace(text))
    {
        return text.Contains("<" + tagName + ">") || text.Contains("</" + tagName + ">") || text.Contains("<" + tagName + " ");
    }
    return false;
}

private static bool CheckStringForClass(string text, string className)
{
    if (!string.IsNullOrWhiteSpace(text))
    {
        string pattern = string.Format(".*class[\\s]?=[\\s]?.*[\\s'\"]{0}[\\s'\"].*.*", className);
        Match m = Regex.Match(text, className, RegexOptions.IgnoreCase);
        return m.Success;
    }
    return false;
}

public static string InnerHTML(this IWebElement element)
{
    return element.GetAttribute("innerHTML");
}}

注:これは似ていますが、ドミニク・ギャロンバルドの答えを拡張しています。

0
Americus

Dominic Giallombardoの答えは私のために働いた。 backgrowndにロードされるajaxベースの情報では、要素が表示されるまで待機するループが必要です。したがって、要素ラッパーのときに待機してアクションを実行する場合は、lableおよびgoto lable + else条件を使用できます。以下は、ループがトラフになるように要素を待機する変更されたコードです。

           checksomeelement:
        List<IWebElement> elementList = new List<IWebElement>();
        elementList.AddRange(driver.FindElements(By.XPath("//div[@class='video']/a")));

        if (elementList.Count > 0)
        {
            elementList[0].Click();
        }
        else
        {
            System.Threading.Thread.Sleep(2000);
            goto checksomeelement;
        }
0
Atanas Atanasov

このメソッドを使用すると、要素が存在するのを待つことができます。これは、VueJSなどの要素を条件付きで作成するフロントエンドSPAフレームワークで特に重要です。アプリのパフォーマンスに基づいて再試行回数を微調整できます。いずれにしても、ELEMENT_FIND_WAIT_TIME * ELEMENT_FIND_WAIT_RETRY_COUNTミリ秒で完全に失敗します。これにより、私たちが抱えていた問題が解決しました。

protected Func<IWebElement> GetLazyElement(By by, int retryCount=0)
        {
            if (retryCount >= ELEMENT_FIND_WAIT_RETRY_COUNT)
            {
                throw new Exception("Wait timeout for element to show up" + by.ToString());
            }
            return new Func<IWebElement>(() => {
                try
                {
                    Debug.WriteLine("Finding element " + by.ToString());
                    var element = _webDriver.FindElement(by);

                    return element;
                }
                catch (Exception)
                {
                    Debug.WriteLine($"Failed to find element: {by} (Waiting {ELEMENT_FIND_WAIT_TIME}ms)");
                    Thread.Sleep(ELEMENT_FIND_WAIT_TIME);
                    var lazyFunc = GetLazyElement(by, retryCount++);
                    return lazyFunc();

                }

            });
}
0
Tjaart