当前使用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.Name
,By.ClassName
,By.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使我离这儿很近,但是我仍然有点绿,无法完全解决这个问题,感谢任何帮助。
答案 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
的实例,因为它与特定的驱动程序实例有关,并且如果您打算并行运行,则会引起问题。