【问题标题】:Selenium - Search for Element With Class and TextSelenium - 使用类和文本搜索元素
【发布时间】:2015-01-15 22:54:03
【问题描述】:

我有以下代码,它将搜索具有给定类名和文本的元素,直到找到或超时。我不喜欢它在 returnElement == null 时处于开环 30 秒的事实。有没有更有效的方法来做到这一点?注意:它不能仅根据文本找到元素。

    #region FindAndWaitForElementListWithClassAndText
    public static IWebElement FindAndWaitForElementWithClassAndText(IWebDriver driver, string className, string text, int timeout = 30)
    {
        if (driver == null)
            throw new ApplicationException("No Selenium Driver defined, cannot continue.");

        WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
        IWebElement returnElement = null;

        wait.Until(a => driver.FindElements(By.ClassName(className)));

        //Starts task that times out after specified TIMEOUT_MILLIS
        var tokenSource = new CancellationTokenSource();
        CancellationToken token =  tokenSource.Token;
        var task = Task.Factory.StartNew(() => searchForElementWtihClassAndText(driver, className, text), token);
        if(!task.Wait(TIMEOUT_MILLIS, token))
        {
            LoggerHelper.ErrorFormat("Could not find element with class and text: {0} :: {1}", className, text);
            returnElement = null;
        }

        returnElement = task.Result;

        return returnElement;
    }
    #endregion

    private static IWebElement searchForElementWtihClassAndText(IWebDriver driver, String className, String text)
    {
        IWebElement returnElement = null;

        while (returnElement == null)
        {
            var theList = driver.FindElements(By.ClassName(className));
            if (theList != null && theList.Count > 0)
            {
                foreach (IWebElement el in theList)
                {
                    if (el.Text.Equals(text, StringComparison.OrdinalIgnoreCase))
                    {
                        returnElement = el;
                        LoggerHelper.InfoFormat("Found Class Name and Text: {0} / {1}", className, text);
                    }
                }
            }
        }
        return returnElement;
    }

这是一个示例元素:

<div class="smtListItem smtMessageItem">
    <!-- ngIf: message.SentItem -->
    <!-- ngIf: !message.SentItem -->
    <span class="smtListName ng-binding ng-
    scope" data-ng if=
    "!message.SentItem">user08&nbsp;EIGHT</span>
    <!-- end ngIf: !message.SentItem -->

    ...
</div>

【问题讨论】:

  • 您是指具有特定类名和文本的元素吗?你能给出具体的html sn-p吗?
  • 当然,我添加了一个示例元素。
  • 这里的主要问题是您没有正确使用WebDriverWait。如果您愿意,它可以采用完整的谓词。所以@Saifur 下面的回答会很好。那里有大约 20 行重复。

标签: c# selenium timeout


【解决方案1】:

您总是可以写一个xpath 来查找该元素并检查它是否存在。

高级实现可能如下所示

public void Test()
{
    By @by = By.XPath("//span[contains(@class,'smtListName')][contains(text(),'lastname')]");

    try
    {
        new WebDriverWait(Driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementExists(@by));
    }
    catch (NoSuchElementException exception)
    {
        Console.WriteLine(exception.Message);
    }
}

【讨论】:

  • 请提供html和stacktrace。这应该是要走的路
  • 我正在尝试这个,但它似乎无法找到该元素。我在 XPath 方面没有太多经验:By @by = By.XPath("//div[@class = 'smtListName'][contains(text(), 'user08 Eight')]"); 用于 html:&lt;div class="smtListItem smtMessageItem"&gt; &lt;!-- ngIf: message.SentItem --&gt; &lt;!-- ngIf: !message.SentItem --&gt;&lt;span class="smtListName ng-binding ng-scope" data-ng-if="!message.SentItem"&gt;user08&amp;nbsp;EIGHT&lt;/span&gt;&lt;!-- end ngIf: !message.SentItem --&gt;
  • 它只是在 30 秒后超时。找不到元素。
  • 所以元素不退出?你真的需要告诉我我提供的xpath 是否符合你的标准
  • xpath 似乎是错误的。我正在尝试://span[@class = 'smtListName' and normalize-space(text()) = 'user08 EIGHT']
猜你喜欢
  • 2020-08-30
  • 1970-01-01
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
  • 1970-01-01
  • 2019-09-06
  • 2016-11-26
相关资源
最近更新 更多