如何在 selenium c# 中创建自定义显式等待函数,传入 WebElements 而不是 By

Posted

技术标签:

【中文标题】如何在 selenium c# 中创建自定义显式等待函数,传入 WebElements 而不是 By【英文标题】:How to create a custom explicit wait function in selenium c# passing in WebElements instead of By 【发布时间】:2021-10-21 19:14:26 【问题描述】:

我正在尝试重构我的旧代码,我的清单上的一件事是将我的显式等待包装到一个函数中,然后调用该函数。

现在我正在使用 lambdas 而不是预期的条件,因为 lamdas 是 c# 的方式,我不想依赖过时的类/不受支持的 nuget 包。

为了分解我当前的项目,每次我创建一个方法时,我都定义了一个明确的等待,如下所示:

public void someFunc()

    var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
    wait.Until(driver => element.Displayed);

我希望不必在每个函数中定义我的等待,我可以调用一个等待方法并从那里开始。

问题是我不确定如何使用 WebElements 作为参数有效地做到这一点。

我创造了你可以想象的这样的东西

public void waitForElement(IWebElement element)

    var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
    wait.Until(driver => element.Displayed);

但是当我在我的测试或另一个函数中调用这个方法时,我得到一个异常,感谢另一个用户,我知道为什么。

当我打电话时

waitForElement(myWebElement);

webdriver 失败,因为页面上尚不存在该元素。它没有到达函数内的代码,因为该元素不作为参数存在。

我尝试了所有方法,从添加驱动程序作为参数,从使用 webdriverwait 作为参数和使用 lambda 作为参数,从将函数更改为 bool 并使用 lambda)

在 c# 中有什么好的/干净的方法可以做到这一点吗?我错过了什么吗?请帮忙

请注意,我使用“By”作为参数让它工作,但我不想使用 by,因为它可能导致难以维护代码。

【问题讨论】:

您可以在设置驱动程序时尝试单个implicit wait,看看是否对您有帮助。隐式等待将延迟所有 NoSuchElementsExecptions 直到元素 EXISTS(存在!= 正确的状态,例如显示) - 然后您可以根据需要使用您的方法来验证状态。文档说您不应该同时使用这两种等待类型,因为它会导致 ON FAILING 项的时间不一致问题。它仍然是动态等待(准备就绪后将继续),您可以通过将显式时间作为隐式时间的一个因素来减轻时间影响......相当长的评论。如果您需要了解更多信息,请大声喊叫? 但是你的回答是对的 - Webelement 是一个找到的元素,你不需要等待它,因为你已经有了它。使用 By 是完全可以接受的 - 您只需将其作为页面对象类文件中的属性 每次我需要使用等待时写 By.Locator("locator") 在我看来并不理想,至少在页面对象类中它只是在一个位置。如果我必须等待多个元素写入多个 Bys,如果 html 更改,则如果我使用多个等待,代码可能变得难以管理。我也觉得如果我将隐式等待与显式一起使用它不会真正解决我想要的,因为我只会在每个函数中定义隐式等待,如果是这种情况,我只会将代码与显式等待保持原样在函数中 您可以扩展 selenium webdriver - 可能希望使用您自己的等待引发的实现来扩展或覆盖核心 findElement。或者,您可以对元素使用方法而不是 lamda。使用一种方法,您只会在调用时尝试识别元素,并且该方法可以包含您的同步函数或覆盖的 findelement - 如果没有看到您的代码 + 结构,很难建议正确的课程。 【参考方案1】:

您可以为WebDriverWait 类创建扩展方法:

namespace OpenQA.Selenium

    public static class WebDriverWaitExtensions
    
        public static void UntilElementIsDisplayed(this WebDriverWait wait, IWebElement element)
        
            wait.Until(driver => element.Displayed);
        
    

现在任何有WebDriverWait对象的地方,都可以调用wait.UntilElementIsDisplayed(element);

var element = driver.FindElement(By.XPath("..."));
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));

wait.UntilElementIsDisplayed(element);

请务必将 using OpenQA.Selenium; 添加到 C# 文件的顶部。

这是我用来替换过时的 ExpectedConditions 类中几乎所有内容的模式。扩展方法和 lambda 表达式是要走的路。

【讨论】:

以上是关于如何在 selenium c# 中创建自定义显式等待函数,传入 WebElements 而不是 By的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中创建自定义登录 Windows 屏幕?

如何使用 C# 中的 Nuget 包在谷歌分析中创建自定义维度和自定义指标

在 Android 中创建自定义视图

在 dotnet 3.5 中创建自定义控件的命令 [关闭]

如何在 laravel 中创建自定义关系?

如何在 QML 中创建自定义对象?