Selenium c#Webdriver:等到元素存在

我想在webdriver开始做东西之前确定一个元素。

我试图得到这样的工作:

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

我主要是在努力如何设置anynomousfunction..

或者,您可以使用隐式等待:

 driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); 

一个隐含的等待就是告诉WebDriver在查找一个或多个元素(如果不是立即可用的)时轮询DOM一段时间。 默认设置为0.一旦设置,隐式等待就设置为WebDriver对象实例的生命周期。

使用Mike Kwan提供的解决scheme可能会对整体testing性能产生影响,因为在所有FindElement调用中将使用隐式等待。 很多时候,你会希望FindElement在元素不存在的时候马上失败(你正在testing格式不正确的页面,缺less元素等等)。 在隐式等待的情况下,这些操作会在抛出exception之前等待整个超时过期。 默认的隐含等待设置为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); } } 

我没有cachingWebDriverWait对象,因为它的创build非常便宜,这个扩展可能同时用于不同的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(); 

你也可以使用

ExpectedConditions.ElementExists

所以你会search这样的元素可用性

 new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut)).Until(ExpectedConditions.ElementExists((By.Id(login)))); 

资源

这是@ Loudenvier解决scheme的一个变种,也可以用于获取多个元素:

 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); } public static ReadOnlyCollection<IWebElement> FindElements(this IWebDriver driver, By by, int timeoutInSeconds) { if (timeoutInSeconds > 0) { var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds)); return wait.Until(drv => (drv.FindElements(by).Count > 0) ? drv.FindElements(by) : null); } return driver.FindElements(by); } } 

受Loudenvier解决scheme的启发,这里有一个适用于所有ISearchContext对象的扩展方法,而不仅仅是前者的专门化IWebDriver。 此方法也支持等待,直到显示元素。

 static class WebDriverExtensions { /// <summary> /// Find an element, waiting until a timeout is reached if necessary. /// </summary> /// <param name="context">The search context.</param> /// <param name="by">Method to find elements.</param> /// <param name="timeout">How many seconds to wait.</param> /// <param name="displayed">Require the element to be displayed?</param> /// <returns>The found element.</returns> public static IWebElement FindElement(this ISearchContext context, By by, uint timeout, bool displayed=false) { var wait = new DefaultWait<ISearchContext>(context); wait.Timeout = TimeSpan.FromSeconds(timeout); wait.IgnoreExceptionTypes(typeof(NoSuchElementException)); return wait.Until(ctx => { var elem = ctx.FindElement(by); if (displayed && !elem.Displayed) return null; return elem; }); } } 

用法示例:

 var driver = new FirefoxDriver(); driver.Navigate().GoToUrl("http://localhost"); var main = driver.FindElement(By.Id("main")); var btn = main.FindElement(By.Id("button")); btn.Click(); var dialog = main.FindElement(By.Id("dialog"), 5, displayed: true); Assert.AreEqual("My Dialog", dialog.Text); driver.Close(); 

我用谓词混淆了不规范的函数。 下面是一个小帮手的方法:

  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))); } 

你可以在C#中find这样的东西。

这是我在JUnit中使用的 – Selenium

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

做导入相关的包

在Selenium IDE中selectWebdriver格式时,clickAndWait命令不会被转换。 这是解决方法。 在下面添加等待线。 实际上,问题是在我的C#代码中的这一行之前发生的点击或事件。 但是,确实,在引用“By”对象的任何操作之前,请确保您有一个WaitForElement。

HTML代码:

 <a href="http://www.google.com">xxxxx</a> 

C#/ NUnit代码:

 driver.FindElement(By.LinkText("z")).Click; driver.WaitForElement(By.LinkText("xxxxx")); driver.FindElement(By.LinkText("xxxxx")).Click(); 

python:

 from selenium import webdriver from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By driver.find_element_by_id('someId').click() WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.ID, 'someAnotherId')) 

从EC你可以select其他条件,以及试试这个: http : //selenium-python.readthedocs.org/api.html#module-selenium.webdriver.support.expected_conditions

显式等待

 public static WebDriverWait wait = new WebDriverWait(driver, 60); 

例:

 wait.until(ExpectedConditions.visibilityOfElementLocated(UiprofileCre.UiaddChangeUserLink)); 
 //wait up to 5 seconds with no minimum for a UI element to be found WebDriverWait wait = new WebDriverWait(_pagedriver, TimeSpan.FromSeconds(5)); IWebElement title = wait.Until<IWebElement>((d) => { return d.FindElement(By.ClassName("MainContentHeader")); }); 

我看到多个解决scheme已经发布,工作很好! 但是,为了防止任何人需要其他的东西,我想我会发布两个解决scheme,我个人用在seleniumC#来testing是否存在一个元素! 希望它有帮助,欢呼!

 public static class IsPresent { public static bool isPresent(this IWebDriver driver, By bylocator) { bool variable = false; try { IWebElement element = driver.FindElement(bylocator); variable = element != null; } catch (NoSuchElementException){ } return variable; } } 

这是第二个

  public static class IsPresent2 { public static bool isPresent2(this IWebDriver driver, By bylocator) { bool variable = true; try { IWebElement element = driver.FindElement(bylocator); } catch (NoSuchElementException) { variable = false; } return variable; } } 
 public bool doesWebElementExist(string linkexist) { try { driver.FindElement(By.XPath(linkexist)); return true; } catch (NoSuchElementException e) { return false; } } 

这是我的解决scheme,你不想等到元素改变之前。 在这个代码中,webdriver等待2秒钟,然后继续。


 WebDriverWait等待=新的WebDriverWait(驱动程序,TimeSpan.FromMilliseconds(2000));
 wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.Name( “HTML-名”)));

试试这个代码:

  New WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(Function(d) d.FindElement(By.Id("controlName")).Displayed) 

正在寻找如何在Selenium等待条件,降落在这个线程,这里是我现在使用的:

  WebDriverWait wait = new WebDriverWait(m_driver, TimeSpan.FromSeconds(10)); wait.Until(d => ReadCell(row, col) != ""); 

ReadCell(row, col) != ""可以是任何条件。 像这样,因为:

  • 这是我的
  • 允许内联
  new WebDriverWait(driver, TimeSpan.FromSeconds(10)). Until(ExpectedConditions.PresenceOfAllElementsLocatedBy((By.Id("toast-container")))); 

第一个答案是好的,我的问题是, 未处理的exception没有正确closuresnetworking驱动程序,并保持了我曾经使用的第一个值是1秒。

如果你得到同样的问题

restart you visual studio并确保all the exceptions are handled正确。