我使用Selenium Webdriver和C#,我想知道是否有办法覆盖FindElement方法?我想做的 - 如果可能的话 - 是在方法中添加一个额外的参数和代码,迫使它在继续之前等待元素可见。 例如,它会是这样的:
Driver.FindElement(By.Id("orion.dialog.box.ok"), 60).Click();
这将等待最多60秒,以便元素显示并可以点击。
任何想法如何做到这一点? 谢谢, 约翰
答案 0 :(得分:0)
你可以使用ImplicitWait。您可以创建一个新的用户定义函数来接受By对象和超时秒,并让函数返回IWebElement,如下所示:
IWebElement elem = MyOwnGetElement(By.id("test"),60);
上述函数可能包含以下代码,其中time_out_sec是函数参数。
WebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(time_out_sec));
driver.Url = "http://somedomain/url_that_delays_loading";
IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement"));
答案 1 :(得分:0)
我建议您将其添加为扩展方法。伪代码:
public static IWebElement WaitForAndFindElement(this IWebDriver driver, By by)
{
// do a wait
// something like...
WebDriverWait wait = new WebDriverWait(TimeSpan.FromSeconds(60)); // hard code it here if you want to avoid each calling method passing in a value
return wait.Until(webDriver =>
{
if (webDriver.FindElement(by).Displayed)
{
return webDriver.FindElement(by);
}
return null; // returning null with force the wait class to iterate around again.
});
}
只是说明,隐含的等待将成为您解决方案的第一部分。它将导致Selenium等待最多60秒,因为元素存在于DOM 中,但可见是完全不同的。
.Displayed
将处理该问题,并且必须在WebDriverWait
内处理。
答案 2 :(得分:0)
我用Selenium编写了6个多月的代码,我和你的问题一样。我创建了这个扩展方法,每次都适合我。
代码的作用是: 在20秒内,它会检查每个500毫秒,无论页面上是否存在该元素。如果在20秒之后,它没有找到,它将抛出异常。 这将有助于您进行动态等待。
public static class SeleniumExtensionMethods {
public static WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
public static void SafeClick(this IWebElement webElement) {
try {
wait.Until(ExpectedConditions.ElementToBeClickable(webElement)).Click();
} catch (TargetInvocationException ex) {
Console.WriteLine(ex.InnerException);
}
}
然后像这样使用它:
IWebElement x = driver.FindElement(By.Id("username"));
x.SafeClick();