我想确保在webdriver开始做事情之前,一个元素是存在的。
我正在尝试这样做:
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, 5));
wait.Until(By.Id("login"));
我主要是挣扎如何设置匿名功能…
我想确保在webdriver开始做事情之前,一个元素是存在的。
我正在尝试这样做:
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, 5));
wait.Until(By.Id("login"));
我主要是挣扎如何设置匿名功能…
当前回答
下面是如何在Selenium中等待一个条件:
WebDriverWait wait = new WebDriverWait(m_driver, TimeSpan.FromSeconds(10));
wait.Until(d => ReadCell(row, col) != "");
ReadCell(row, col) != ""可以是任何条件。这样做是因为:
它是我的 允许内联
其他回答
使用Mike Kwan提供的解决方案可能会对整体测试性能产生影响,因为隐式等待将在所有FindElement调用中使用。
很多时候,您希望FindElement在一个元素不存在时立即失败(您正在测试一个畸形的页面、缺失的元素等)。使用隐式等待,这些操作将在抛出异常之前等待整个超时到期。默认的隐式等待设置为0秒。
我写了一个小扩展方法到IWebDriver,它添加了一个超时(秒)参数FindElement()方法。这是不言而喻的:
public static class WebDriverExtensions
{
public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds)
{
if (timeoutInSeconds > 0)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
return wait.Until(drv => drv.FindElement(by));
}
return driver.FindElement(by);
}
}
我没有缓存WebDriverWait对象,因为它的创建非常便宜,这个扩展可以同时用于不同的WebDriver对象,我只在最终需要的时候做优化。
用法很简单:
var driver = new FirefoxDriver();
driver.Navigate().GoToUrl("http://localhost/mypage");
var btn = driver.FindElement(By.CssSelector("#login_button"));
btn.Click();
var employeeLabel = driver.FindElement(By.CssSelector("#VCC_VSL"), 10);
Assert.AreEqual("Employee", employeeLabel.Text);
driver.Close();
因为我使用一个已经找到的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;
}
};
}
使用c#扩展方法:我们可以解决等待直到元素可见的问题。 一个特定元素的最大reties是100。
public static bool WaitForElementToBeVisible(IWebDriver browser, By by)
{
int attemptToFindElement = 0;
bool elementFound = false;
IWebElement elementIdentifier = null;
do
{
attemptToFindElement++;
try
{
elementIdentifier = browser.FindWebElement(by);
elementFound = (elementIdentifier.Displayed && elementIdentifier.Enabled) ? true : false;
}
catch (Exception)
{
elementFound = false;
}
}
while (elementFound == false && attemptToFindElement < 100);
return elementFound;
}
WebDriverWait将不生效。
var driver = new FirefoxDriver(
new FirefoxOptions().PageLoadStrategy = PageLoadStrategy.Eager
);
driver.Navigate().GoToUrl("xxx");
new WebDriverWait(driver, TimeSpan.FromSeconds(60))
.Until(d => d.FindElement(By.Id("xxx"))); // A tag that close to the end
一旦页面是“交互式的”,这将立即抛出异常。我不知道为什么,但是超时就好像它不存在一样。
也许SeleniumExtras。WaitHelpers很管用,但我没试过。这是官方的,但它被拆分为另一个NuGet包。你可以参考c# Selenium 'ExpectedConditions is obsolete'。
我使用FindElements并检查Count == 0。如果为真,则使用await Task.Delay。这真的不是很有效。
这是一个可重用的函数,用于使用显式等待等待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;
}
});
}