c# - Selenium - 搜索带有类和文本的元素

标签 c# selenium timeout

我有以下代码将搜索具有给定类名和文本的元素,直到找到或超时。我不喜欢 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>

最佳答案

您始终可以编写一个 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);
    }
}

关于c# - Selenium - 搜索带有类和文本的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27974516/

相关文章:

javascript - 页面需要 2-3 分钟呈现会导致 javascript 'taking too long' 警告

c# - 在单元测试中模拟 IHttpContextAccessor

ios - Nightwatch.js - 无法使用 Appium(iOS 模拟器)执行 touchAction 或滚动,寻找解决方案

java - 如何通过 Selenium Java 初始化 PhantomJS 浏览器

python - 如何优雅地处理 selenium 中的 NoSuchElementElement 异常?

java - Java 超时哈希表

c# - SQL 对称 key 并从 C# 打开它

c# - 命令绑定(bind)不起作用 - MVVM Light RelayCommand 和 XAML 问题

C# 特殊字符的正则表达式是什么

Ansible 中基于 SSH 的 GIT 挂起,即使设置了 ssh-agent 转发