【问题标题】:Assert that a WebElement is not present using Selenium WebDriver with java使用 Selenium WebDriver 和 java 断言 WebElement 不存在
【发布时间】:2011-03-18 00:48:09
【问题描述】:

在我编写的测试中,如果我想断言页面上存在 WebElement,我可以做一个简单的操作:

driver.findElement(By.linkText("Test Search"));

如果存在就会通过,如果不存在就会爆炸。但现在我想断言链接确实 not 存在。我不清楚如何执行此操作,因为上面的代码不返回布尔值。

编辑这就是我想出自己的修复方法的方法,我想知道是否还有更好的方法。

public static void assertLinkNotPresent (WebDriver driver, String text) throws Exception {
List<WebElement> bob = driver.findElements(By.linkText(text));
  if (bob.isEmpty() == false) {
    throw new Exception (text + " (Link is present)");
  }
}

【问题讨论】:

    标签: java selenium-webdriver assertion


    【解决方案1】:

    这样做更容易:

    driver.findElements(By.linkText("myLinkText")).size() < 1
    

    【讨论】:

    • 谢谢,即使对于非 Java 绑定,这似乎也是最好的方法。
    • 这是迄今为止避免 findElement 抛出异常的更好答案。
    • 很好的解决方案。但是,这会尝试 timeout 秒来查找元素。因此,您可能想要设置(然后重置)驱动程序超时。也许在一种方法中。
    【解决方案2】:

    如果没有这样的元素,我认为你可以抓住org.openqa.selenium.NoSuchElementException 将被driver.findElement 抛出:

    import org.openqa.selenium.NoSuchElementException;
    
    ....
    
    public static void assertLinkNotPresent(WebDriver driver, String text) {
        try {
            driver.findElement(By.linkText(text));
            fail("Link with text <" + text + "> is present");
        } catch (NoSuchElementException ex) { 
            /* do nothing, link is not present, assert is passed */ 
        }
    }
    

    【讨论】:

    • 好主意。虽然很奇怪,但 Web Driver 中没有一种机制来处理这种断言
    • 为了使这个更具遗传性,您可以传入 By.id/cssSelector 等而不是字符串文本。
    • 虽然这可行,但我认为它并不理想。当您为 webdriver 配置隐式等待时,测试将变得非常慢。
    • 这真的不推荐,它会减慢你的测试速度,并且可能是难以发现的错误的来源: - 如果元素不存在(最常见)你的测试将等待隐式每次都等待 - 如果元素存在但它正在消失,则不会使用隐式等待,并且您的测试将立即失败,即误报。
    • 由于隐含的等待问题,这需要大力反对。
    【解决方案3】:

    不确定您指的是哪个版本的 selenium,但是 selenium * 中的一些命令现在可以执行此操作: http://release.seleniumhq.org/selenium-core/0.8.0/reference.html

    • assertNotSomethingSelected
    • assertTextNotPresent

    等等。

    【讨论】:

    • 链接已损坏
    • OPs 原始问题似乎表明当元素不存在时引发了异常。
    【解决方案4】:

    有一个类叫ExpectedConditions:

      By loc = ...
      Boolean notPresent = ExpectedConditions.not(ExpectedConditions.presenceOfElementLocated(loc)).apply(getDriver());
      Assert.assertTrue(notPresent);
    

    【讨论】:

    • 出于某种原因,这对我不起作用(至少在 Selenium 2.53.0 中)。相反,我不得不像这样使用 all 元素的存在:ExpectedConditions.not(ExpectedConditions.presenceOfAllElementsLocatedBy(locator)));.
    • 使用一些最新版本的 Selenium,现在有一个名为 invisibilityOfElementLocated 的方法用于此检查。用法很简单:webDriver.wait(ExpectedConditions.invisibilityOfElementLocated(xpath("&lt;xpath expression&gt;")))
    【解决方案5】:

    试试这个 -

    private boolean verifyElementAbsent(String locator) throws Exception {
        try {
            driver.findElement(By.xpath(locator));
            System.out.println("Element Present");
            return false;
    
        } catch (NoSuchElementException e) {
            System.out.println("Element absent");
            return true;
        }
    }
    

    【讨论】:

    • 我怀疑这行不通。我使用 Perl 绑定并尝试使用这种方法,问题是驱动程序实例在没有找到元素时死亡。不确定Java是否也会发生同样的情况。
    【解决方案6】:

    使用 Selenium Webdriver 会是这样的:

    assertTrue(!isElementPresent(By.linkText("Empresas en Misión")));
    

    【讨论】:

    • 最好assertFalse(...)
    【解决方案7】:

    看起来findElements() 只有在找到至少一个元素时才会快速返回。否则,它会等待隐式等待超时,然后返回零个元素 - 就像 findElement()

    为了保持测试的速度不错,这个例子暂时缩短了隐式等待,同时等待元素消失:

    static final int TIMEOUT = 10;
    
    public void checkGone(String id) {
        FluentWait<WebDriver> wait = new WebDriverWait(driver, TIMEOUT)
                .ignoring(StaleElementReferenceException.class);
    
        driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
        try {
            wait.until(ExpectedConditions.numberOfElementsToBe(By.id(id), 0));
        } finally {
            resetTimeout();
        }
    }
    
    void resetTimeout() {
        driver.manage().timeouts().implicitlyWait(TIMEOUT, TimeUnit.SECONDS);
    }
    

    仍在寻找完全避免超时的方法...

    【讨论】:

      【解决方案8】:
      boolean titleTextfield = driver.findElement(By.id("widget_polarisCommunityInput_113_title")).isDisplayed();
      assertFalse(titleTextfield, "Title text field present which is not expected");
      

      【讨论】:

        【解决方案9】:

        您可以为此使用Arquillian Graphene 框架。因此,您的案例可能是

        Graphene.element(By.linkText(text)).isPresent().apply(driver));
        

        Is 还为您提供了一堆很好的 API,用于处理 Ajax、流畅的等待、页面对象、片段等。它无疑大大简化了基于 Selenium 的测试开发。

        【讨论】:

          【解决方案10】:

          对于 node.js,我发现以下是等待元素不再存在的有效方法:

          // variable to hold loop limit
              var limit = 5;
          // variable to hold the loop count
              var tries = 0;
                  var retry = driver.findElements(By.xpath(selector));
                      while(retry.size > 0 && tries < limit){
                          driver.sleep(timeout / 10)
                          tries++;
                          retry = driver.findElements(By.xpath(selector))
                      }
          

          【讨论】:

          • 如果元素没有消失,您的代码可能会陷入无限循环
          • 一个很好的观点。解决了这个问题。我不会添加错误处理。
          【解决方案11】:

          不是对这个问题的回答,而是对潜在任务的一个想法:

          当您的网站逻辑不应该显示某个元素时,您可以插入一个不可见的“标志”元素以供检查。

          if condition
              renderElement()
          else
              renderElementNotShownFlag() // used by Selenium test
          

          【讨论】:

            【解决方案12】:

            请在下面找到使用 Selenium "until.stalenessOf" 和 Jasmine 断言的示例。 当元素不再附加到 DOM 时,它返回 true。

            const { Builder, By, Key, until } = require('selenium-webdriver');
            
            it('should not find element', async () => {
               const waitTime = 10000;
               const el = await driver.wait( until.elementLocated(By.css('#my-id')), waitTime);
               const isRemoved = await driver.wait(until.stalenessOf(el), waitTime);
            
               expect(isRemoved).toBe(true);
            });
            

            参考:Selenium:Until Doc

            【讨论】:

              【解决方案13】:

              我发现最好的方法 - 并且在 Allure 报告中显示为失败 - 是尝试捕获 findelement 并在 catch 块中,将 assertTrue 设置为 false,如下所示:

                  try {
                      element = driver.findElement(By.linkText("Test Search"));
                  }catch(Exception e) {
                      assertTrue(false, "Test Search link was not displayed");
                  }
              

              【讨论】:

                【解决方案14】:

                这对我来说是最好的方法

                public boolean isElementVisible(WebElement element) {
                    try { return element.isDisplayed(); } catch (Exception ignored) { return false; }
                }
                

                【讨论】:

                  【解决方案15】:

                  findElement 将检查 html 源代码,即使元素未显示也会返回 true。要检查元素是否显示,请使用 -

                  private boolean verifyElementAbsent(String locator) throws Exception {
                  
                          boolean visible = driver.findElement(By.xpath(locator)).isDisplayed();
                          boolean result = !visible;
                          System.out.println(result);
                          return result;
                  }
                  

                  【讨论】:

                    【解决方案16】:

                    适用于 appium 1.6.0 及以上版本

                        WebElement button = (new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//XCUIElementTypeButton[@name='your button']"))));
                        button.click();
                    
                        Assert.assertTrue(!button.isDisplayed());
                    

                    【讨论】:

                    • 最好直接assertFalse(...)
                    猜你喜欢
                    • 1970-01-01
                    • 2014-07-03
                    • 1970-01-01
                    • 2017-05-26
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-03-16
                    • 2016-06-28
                    • 1970-01-01
                    相关资源
                    最近更新 更多