Selenium WebDriver - Test if element is present
有没有一种方法可以测试元素是否存在?任何findelement方法都将以异常结束,但这不是我想要的,因为它可能是一个元素不存在,这是正常的,这不是测试的失败,因此异常不能是解决方案。
我发现了这篇文章:Selenium C WebDriver:等待元素出现但这是给C的,我不太擅长。有人能把代码翻译成Java吗?对不起,伙计们,我在Eclipse中试用过,但是我没有把它放进Java代码中。
这是代码:
1 2 3 4 5 6 7 8 9 10 11 | 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); } } |
用
如果没有找到匹配的元素而不是异常,
要检查元素是否存在,可以尝试此操作
1 |
如果至少找到一个元素,则返回true;如果不存在,则返回false。
对于一个只查找元素并确定其是否存在的私有方法,该如何处理:
1 2 3 4 5 6 7 8 | private boolean existsElement(String id) { try { driver.findElement(By.id(id)); } catch (NoSuchElementException e) { return false; } return true; } |
这很容易,而且能完成任务。
编辑:你甚至可以更进一步,以
我发现这对于Java是有效的:
1 2 3 | WebDriverWait waiter = new WebDriverWait(driver, 5000); waiter.until( ExpectedConditions.presenceOfElementLocated(by) ); driver.FindElement(by); |
1 2 3 4 5 6 | public static WebElement FindElement(WebDriver driver, By by, int timeoutInSeconds) { WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds); wait.until( ExpectedConditions.presenceOfElementLocated(by) ); //throws a timeout exception if element not present after waiting <timeoutInSeconds> seconds return driver.findElement(by); } |
我也有同样的问题。对于我来说,根据用户的权限级别,某些链接、按钮和其他元素将不会显示在页面上。我的套件的一部分是测试应该缺失的元素是否缺失。我花了好几个小时想弄清楚。我终于找到了完美的解决方案。
它的作用是告诉浏览器查找基于指定的任何和所有元素。如果结果是
这是在
1 2 3 4 5 6 7 8 | public void verifyPermission(string link) { IList<IWebElement> adminPermissions = driver.FindElements(By.CssSelector(link)); if (adminPermissions.Count == 0) { Console.WriteLine("User's permission properly hidden"); } } |
根据您的测试需要,您还可以选择其他路径。
下面的代码片段检查页面上是否存在非常具体的元素。根据元素的存在,我让测试执行if-else。
如果元素存在并显示在页面上,我会让
如果元素不存在,并且不显示在页面上。我在if-else中有else执行测试。
1 2 3 4 5 6 7 | IList<IWebElement> deviceNotFound = driver.FindElements(By.CssSelector("CSS LINK GOES HERE")); //if the element specified above results in more than 0 elements and is displayed on page execute the following, otherwise execute whats in the else statement if (deviceNotFound.Count > 0 && deviceNotFound[0].Displayed){ //script to execute if element is found } else { //Test script goes here. } |
我知道我对手术的反应有点晚了。希望这能帮助到别人!
试试这个:调用此方法并传递3个参数:
示例:waitForelementPresent(driver,by.id("id"),10);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public static WebElement waitForElementPresent(WebDriver driver, final By by, int timeOutInSeconds) { WebElement element; try{ driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait() WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds); element = wait.until(ExpectedConditions.presenceOfElementLocated(by)); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); //reset implicitlyWait return element; //return the element } catch (Exception e) { e.printStackTrace(); } return null; } |
用Java编写以下函数/方法:
1 2 3 4 5 6 7 8 9 | protected boolean isElementPresent(By by){ try{ driver.findElement(by); return true; } catch(NoSuchElementException e){ return false; } } |
在断言期间使用适当的参数调用方法。
通过在try catch语句之前缩短selenium超时,可以使代码运行得更快。
我使用以下代码检查元素是否存在。
1 2 3 4 5 6 7 8 9 10 11 12 13 | protected boolean isElementPresent(By selector) { selenium.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS); logger.debug("Is element present"+selector); boolean returnVal = true; try{ selenium.findElement(selector); } catch (NoSuchElementException e){ returnVal = false; } finally { selenium.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS); } return returnVal; } |
如果您在Ruby中使用rspec webdriver,那么可以使用这个脚本,假定一个元素确实不应该存在,并且它是一个通过的测试。
首先,从类rb文件中首先编写这个方法
1 2 3 4 5 6 7 8 | class Test def element_present? begin browser.find_element(:name,"this_element_id".displayed? rescue Selenium::WebDriver::Error::NoSuchElementError puts"this element should not be present" end end |
然后,在规范文件中,调用该方法。
1 2 3 4 5 | before(:all) do @Test= Test.new(@browser) end @Test.element_present?.should == nil |
如果元素不存在,规范将通过,但是如果元素存在,它将抛出一个错误,测试失败。
这对我很有用:
1 2 3 4 5 | if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){ //THEN CLICK ON THE SUBMIT BUTTON }else{ //DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE } |
我在Java中发现的最简单的方法是:
1 2 3 | List<WebElement> linkSearch= driver.findElements(By.id("linkTag")); int checkLink=linkSearch.size(); if(checkLink!=0){ //do something you want} |
要找到某个特定元素是否存在,我们必须使用findElements()方法而不是findElement()。
1 2 3 4 5 |
这对我有用……如果我错了,建议我……
您可以尝试隐式等待:
1 2 3 4 | WebDriver driver = new FirefoxDriver(); driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10)); driver.Url ="http://somedomain/url_that_delays_loading"; IWebElement myDynamicElement = driver.FindElement(By.Id("someDynamicElement")); |
`
或者您可以尝试显式等待一个:`
1 2 3 4 5 6 7 | IWebDriver driver = new FirefoxDriver(); driver.Url ="http://somedomain/url_that_delays_loading"; WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); IWebElement myDynamicElement = wait.Until<IWebElement>((d) => { return d.FindElement(By.Id("someDynamicElement")); }); |
`
explicit将在某些操作之前检查元素是否存在。隐式等待可以在代码的每个位置调用。例如,在一些Ajax操作之后。
更多信息请访问Seleniumhq页面
给出我的代码片段。因此,下面的方法检查页面上是否存在随机的web元素"创建新应用程序"按钮。请注意,我使用的等待时间是0秒。
1 2 3 4 5 6 7 8 9 10 11 12 | public boolean isCreateNewApplicationButtonVisible(){ WebDriverWait zeroWait = new WebDriverWait(driver, 0); ExpectedCondition<WebElement> c = ExpectedConditions.presenceOfElementLocated(By.xpath("//input[@value='Create New Application']")); try { zeroWait.until(c); logger.debug("Create New Application button is visible"); return true; } catch (TimeoutException e) { logger.debug("Create New Application button is not visible"); return false; } } |
我会使用Scala(旧代码)好的"Java 5月8日与此类似的代码":
1 2 3 4 5 6 7 8 9 10 11 12 13 | object SeleniumFacade { def getElement(bySelector: By, maybeParent: Option[WebElement] = None, withIndex: Int = 0)(implicit driver: RemoteWebDriver): Option[WebElement] = { val elements = maybeParent match { case Some(parent) => parent.findElements(bySelector).asScala case None => driver.findElements(bySelector).asScala } if (elements.nonEmpty) { Try { Some(elements(withIndex)) } getOrElse None } else None } ... } |
那么,
1 | val maybeHeaderLink = SeleniumFacade getElement(By.xpath(".//a"), Some(someParentElement)) |
应该这样做:
1 2 3 4 5 6 | try { driver.findElement(By.id(id)); } catch (NoSuchElementException e) { //do what you need here if you were expecting //the element wouldn't exist } |
1 2 3 | public boolean isElementDisplayed() { return !driver.findElements(By.xpath("...")).isEmpty(); } |
就我个人而言,我总是选择上述答案的混合,并创建一个使用size()<0建议的可重用静态实用程序方法:
1 2 3 4 5 6 | public Class Utility { ... public static boolean isElementExist(WebDriver driver, By by) { return driver.findElements(by).size() < 0; ... } |
这是整洁,可重复使用,可维护…所有的好东西;—)