我想确保在webdriver开始做事情之前,一个元素是存在的。

我正在尝试这样做:

WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, 5));
wait.Until(By.Id("login"));

我主要是挣扎如何设置匿名功能…


当前回答

我正在用这个,效果很好:

public static bool elexists(By by, WebDriver driver)
{
    try
    {
        driver.FindElement(by);
        return true;
    }
    catch (NoSuchElementException)
    {
        return false;
    }
}

public static void waitforelement(WebDriver driver, By by)
{
    for (int i = 0; i < 30; i++)
    {
        System.Threading.Thread.Sleep(1000);
        if (elexists(by, driver))
        {
            break;
        }
    }
}

当然,您可以添加超过30次的尝试,并将周期缩短到1秒以内进行检查。

用法:

waitforelement(driver, By.Id("login"));
IWebElement login = driver.FindElement(By.Id("login"));
login.Click();

其他回答

我混淆了匿名函数和谓词。这里有一个小帮手方法:

   WebDriverWait wait;
    private void waitForById(string id)
    {
        if (wait == null)
            wait = new WebDriverWait(driver, new TimeSpan(0, 0, 5));

        //wait.Until(driver);
        wait.Until(d => d.FindElement(By.Id(id)));
    }

这是一个可重用的函数,用于使用显式等待等待DOM中出现的元素。

public void WaitForElement(IWebElement element, int timeout = 2)
{
    WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromMinutes(timeout));
    wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
    wait.IgnoreExceptionTypes(typeof(StaleElementReferenceException));
    wait.Until<bool>(driver =>
    {
        try
        {
            return element.Displayed;
        }
        catch (Exception)
        {
            return false;
        }
    });
}

你可以在c#中找到类似的东西。

这是我在JUnit - Selenium中使用的

WebDriverWait wait = new WebDriverWait(driver, 100);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));

导入相关的包。

你可以使用下面的方法

WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0,0,5));
wait.Until(ExpectedConditions.ElementToBeClickable((By.Id("login")));

因为我使用一个已经找到的IWebElement来分离页面元素定义和页面测试场景,所以可以这样做:

public static void WaitForElementToBecomeVisibleWithinTimeout(IWebDriver driver, IWebElement element, int timeout)
{
    new WebDriverWait(driver, TimeSpan.FromSeconds(timeout)).Until(ElementIsVisible(element));
}

private static Func<IWebDriver, bool> ElementIsVisible(IWebElement element)
{
    return driver => {
        try
        {
            return element.Displayed;
        }
        catch(Exception)
        {
            // If element is null, stale or if it cannot be located
            return false;
        }
    };
}