将长语句重构为可重用的功能

时间:2019-05-29 14:33:51

标签: c# function selenium-webdriver

当前使用C#和Visual Studio学习Selenium时,您通常必须等待Web元素被启用才能与之交互,因此您使用类似于以下内容的wait语句:

using ec = SeleniumExtras.WaitHelpers.ExpectedConditions;
            IWebElement submitPassword = wait.Until(ec.ElementToBeClickable(By.Id("submitPassword")));
            submitPassword.Click();

每次输入的内容很多,所以我试图将其缩短为一个更简单的功能,到目前为止,我已经做到了:

        private static IWebElement waitById(WebDriverWait wait, String ElementId)
        {
        return wait.Until(ec.ElementToBeClickable(By.Id(ElementId)));
        }

这使我可以将以上内容简化为:

 IWebElement passwordField= waitById(wait, "submitPassword");
 passwordField.Click();

方法By.后可以跟随几种搜索类型,例如By.NameBy.ClassNameBy.XPath等。

我希望函数接受搜索类型,所以我可以这样做:

IWebElement passwordField= waitById(wait,ClassName, "submitPassword");

并通过ClassName而不是Id进行搜索,但是我似乎无法让我的函数接受它作为参数。当我查看By的定义时,似乎每种类型都是其自己的子函数(如果使用不正确的术语,则表示歉意),我尝试将其放在:

        private static IWebElement waitById(WebDriverWait wait,String SearchType, String ElementId)
        {
        return wait.Until(ec.ElementToBeClickable(By.SearchType(ElementId)));
        }

但是我只是收到一条错误消息,说By不包含SearchType的定义,因此我不理解如何将此参数传递给该特定方法。 Googling使我离这儿很近,但是我仍然有点绿,无法完全解决这个问题,感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

您应该传递By实例而不是字符串。使用您的方法,您将必须为每个定位器方法(id,xpath,css选择器,名称等)编写一个方法,然后为每种等待类型(当前,可见,可单击)编写另一个方法。进入很多方法使用By,您只能使用三种方法,每种等待类型都使用一种。这就是我会用的...

public IWebElement WaitForPresence(By locator)
{
    return new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementExists(locator));
}

public IWebElement WaitForVisible(By locator)
{
    return new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(locator));
}

public IWebElement WaitForClickable(By locator)
{
    return new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(locator));
}

我删除了static关键字,因为如果您打算并行运行自动化,通常应该避免使用它。如果您不小心,可能会遇到麻烦,并使线程彼此踩到。

我会避免绕过WebDriverWait的实例,因为它与特定的驱动程序实例有关,并且如果您打算并行运行,则会引起问题。