这是等待selenium WebElement的最佳方式吗?

时间:2016-04-16 08:26:02

标签: c# selenium

public static IWebElement FindElement(ExpectedConditions expectedConditions, By by, int timeoutInSeconds)
{
    DefaultWait<IWebDriver> wait = new DefaultWait<IWebDriver>(driver);
    wait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
    wait.PollingInterval = TimeSpan.FromMilliseconds(10000);
    wait.IgnoreExceptionTypes(typeof(NoSuchElementException));

    IWebElement element =
        wait.Until<IWebElement>(ExpectedConditions.ElementIsVisible(by));
}

我的问题:

如何设置此expectedConditions而不是我方法中的当前内容?

我试着改变:

    IWebElement element =
        wait.Until<IWebElement>(ExpectedConditions.ElementIsVisible(by));

用这个:

    IWebElement element =
        wait.Until<IWebElement>(expectedConditions(by));

并收到此错误:

  

预期的方法名称。

1 个答案:

答案 0 :(得分:6)

Until方法需要谓词作为第一个参数。 谓词是一个定期调用的函数,直到它返回与nullfalse不同的内容。

因此,在您的情况下,您需要让它返回谓词而不是IWebElement

public static Func<IWebDriver, IWebElement> MyCondition(By locator) {
    return (driver) => {
        try {
            var ele = driver.FindElement(locator);
            return ele.Displayed ? ele : null;
        } catch (StaleElementReferenceException){
            return null;
        }
    };
}

// usage
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement element1 = wait.Until(MyCondition(By.Id("...")));

等于:

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement element = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("...")));
element.Click();

您也可以使用lambda表达式

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement element = wait.Until((driver) => {
    try {
        var ele = driver.FindElement(By.Id("..."));
        return ele.Displayed ? ele : null;
    } catch (StaleElementReferenceException){
        return null;
    }
});
element.Click();

或扩展方法:

public static IWebElement WaitElementVisible(this IWebDriver driver, By by, int timeout = 10) {
    return new WebDriverWait(driver, TimeSpan.FromSeconds(timeout)).Until((drv) => {
        try {
            var ele = drv.FindElement(by);
            return ele.Displayed ? ele : null;
        } catch (StaleElementReferenceException){ 
            return null;
        } catch (NotFoundException){ 
            return null; 
        }
    });
}


// usage
IWebElement element = driver.WaitElementVisible(By.Id("..."));
element.Click();

如您所见,有很多方法可以等待元素处于特定状态。