所以我创建了这个通用的find元素函数:
public static IWebElement FindElement(IWebDriver driver, Func<IWebDriver, IWebElement> expectedCondtions, int timeoutInSeconds)
{
WebDriverWait webDriverWait = CreateWebDriverWait(driver, finder,timeoutInSeconds);
webDriverWait.IgnoreExceptionTypes(typeof(NoSuchElementException));
return webDriverWait.Until(expectedCondtions);
}
public static ReadOnlyCollection<IWebElement> FindElements(IWebDriver driver, Func<IWebDriver, ReadOnlyCollection<IWebElement>> expectedCondtions, int timeoutInSeconds)
{
WebDriverWait webDriverWait = CreateWebDriverWait(driver, finder, timeoutInSeconds);
webDriverWait.IgnoreExceptionTypes(typeof(NoSuchElementException));
return webDriverWait.Until(expectedCondtions);
}
private static WebDriverWait CreateWebDriverWait(IWebDriver driver, IWebElement finder, int timeoutInSeconds)
{
WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
webDriverWait.IgnoreExceptionTypes(typeof(NoSuchElementException));
return webDriverWait;
}
用法:
IWebElement element=
WaitAndFindElement(
driver,
ExpectedConditions.ElementIsVisible(By.CssSelector("...")),
120);
现在我想添加一个选项来查找element
也不使用driver
。
例如,我想要从另一个driver.FindElement
搜索元素而不是element
:
IWebElemen element = ...
element.FindElement...
所以我想改变我的功能签名:
IWebElement FindElement(IWebDriver driver,Func<IWebDriver, IWebElement> expectedCondtions, int timeoutInSeconds)
要:
IWebElement FindElement(IWebDriver driver, IWebElement finder, Func<IWebDriver, IWebElement> expectedCondtions, int timeoutInSeconds)
如果finder
为空,我想使用driver.FindElement
进行搜索。
否则:finder.FindElement
所以我的问题是如何实现这一目标?
答案 0 :(得分:0)
这很好:我在工作中有类似的案例,这就是我在C#中所做的:
IWebElement FindElement(IWebDriver driver, Func<IWebDriver, IWebElement> expectedCondtions, int timeoutInSeconds, IWebElement finder = null)
这意味着&#34; finder&#34;的默认值为null,您可以在指定或不指定函数的情况下调用函数。 (您可以将此参数的默认值添加到所有方法中)
然后,您可以在函数中简单地执行一个简单的if语句来确定如何查找元素。
if(finder != null)
{
//use finder instead of driver and return
}
//Otherwise use driver
答案 1 :(得分:0)
如果您想让它变得通用,我认为您不需要使其复杂化。 这是解决问题的代码
Class WebElementFinder
{
private static IWebElement FindElement(ISearchContext sc, By locator, int timeOutInceconds = 20)
{
DefaultWait<ISearchContext> wait = new DefaultWait<ISearchContext>(sc);
wait.Timeout = TimeSpan.FromSeconds(timeOutInceconds);
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
return wait.Until(x => GetElement(x, locator));
}
private static IWebElement GetElement(ISearchContext sc, By locator)
{
return sc.FindElement(locator);
}
}
让我解释一下这部分代码,它将帮助您理解您提到的代码的问题。
现在回到我的代码片段。 我使用了可以用于WebDriver和IWebElement的DefaultWait。两者都是从ISearchContext驱动的。 Locator将帮助您按照帖子中的要求在驱动程序/ IWebElement对象上查找Web元素
答案 2 :(得分:0)
Class WebElementFinder
{
public static IWebElement FindElement(ISearchContext sc, By locator, Func<IWebElement, bool> elementCondition = null, int timeOutInceconds = 20)
{
DefaultWait<ISearchContext> wait = new DefaultWait<ISearchContext>(sc);
wait.Timeout = TimeSpan.FromSeconds(timeOutInceconds);
wait.PollingInterval = TimeSpan.FromSeconds(3);
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
return wait.Until(x => GetElement(x, locator, elementCondition));
}
private static IWebElement GetElement(ISearchContext sc, By locator, Func<IWebElement, bool> elementCondition = null)
{
IWebElement webElement = sc.FindElement(locator);
if(elementCondition != null)
{
if (elementCondition(webElement))
return webElement;
else
return null;
}
else
{
return webElement;
}
}
}
用法:
Func<IWebElement, bool> isElementVisible = (webElement) => webElement.Displayed;
var element = FindElement(driver, By.Id("name_10"), isElementVisible);
答案 3 :(得分:0)
我尝试用这种方式编写,并且运行正常。可能不是最好的方法,但可以帮上忙,因为它对我有用。
public enum HtmlAttribute
{
ClassName,
CssSelector,
Id,
LinkText,
Name,
TagName,
XPath
}
public IWebElement FindWebELement(HtmlAttribute htmlAttribute, string attributeValue)
{
for (int i = 0; i < 20; i++)
{
switch (htmlAttribute)
{
case HtmlAttribute.ClassName:
webElement = Driver.FindElement(By.ClassName(attributeValue));
break;
case HtmlAttribute.CssSelector:
webElement = Driver.FindElement(By.CssSelector(attributeValue));
break;
case HtmlAttribute.Id:
webElement = Driver.FindElement(By.Id(attributeValue));
break;
case HtmlAttribute.LinkText:
webElement = Driver.FindElement(By.LinkText(attributeValue));
break;
case HtmlAttribute.Name:
webElement = Driver.FindElement(By.Name(attributeValue));
break;
case HtmlAttribute.TagName:
webElement = Driver.FindElement(By.TagName(attributeValue));
break;
case HtmlAttribute.XPath:
webElement = Driver.FindElement(By.XPath(attributeValue));
break;
}
while (!webElement.Displayed)
{
i++;
}
}
return webElement;
}
然后我们可以通过以下方式制作元素: 公共IWebElement webSiteNews => FindWebELement(HtmlAttribute.Id,“ search_query_left”);