使用 Selenium WebDriver 和 java 断言 WebElement 不存在

发布于 2024-09-10 15:42:43 字数 529 浏览 7 评论 0原文

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

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

如果存在,则通过,如果不存在,则失败。但现在我想断言链接存在。我不清楚如何执行此操作,因为上面的代码不返回布尔值。

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

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

In tests that I write, if I want to assert a WebElement is present on the page, I can do a simple:

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

This will pass if it exists and it will bomb out if it does not exist. But now I want to assert that a link does not exist. I am unclear how to do this since the code above does not return a boolean.

EDIT This is how I came up with my own fix, I'm wondering if there's a better way out there still.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

夜无邪 2024-09-17 15:42:43

这样做更容易:

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

It's easier to do this:

driver.findElements(By.linkText("myLinkText")).size() < 1
丑疤怪 2024-09-17 15:42:43

我认为你可以捕获 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 */ 
    }
}

I think that you can just catch org.openqa.selenium.NoSuchElementException that will be thrown by driver.findElement if there's no such element:

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 */ 
    }
}
甜心 2024-09-17 15:42:43

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

  • assertNotSomethingSelectedassertTextNotPresent

..

Not Sure which version of selenium you are referring to, however some commands in selenium * can now do this:
http://release.seleniumhq.org/selenium-core/0.8.0/reference.html

  • assertNotSomethingSelected
  • assertTextNotPresent

Etc..

起风了 2024-09-17 15:42:43

有一个名为 ExpectedConditions 的类:

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

There is an Class called ExpectedConditions:

  By loc = ...
  Boolean notPresent = ExpectedConditions.not(ExpectedConditions.presenceOfElementLocated(loc)).apply(getDriver());
  Assert.assertTrue(notPresent);
三生殊途 2024-09-17 15:42:43

试试这个 -

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

Try this -

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;
    }
}
心在旅行 2024-09-17 15:42:43

使用 Selenium Webdriver 会是这样的:

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

With Selenium Webdriver would be something like this:

assertTrue(!isElementPresent(By.linkText("Empresas en Misión")));
自演自醉 2024-09-17 15:42:43
boolean titleTextfield = driver.findElement(By.id("widget_polarisCommunityInput_113_title")).isDisplayed();
assertFalse(titleTextfield, "Title text field present which is not expected");
boolean titleTextfield = driver.findElement(By.id("widget_polarisCommunityInput_113_title")).isDisplayed();
assertFalse(titleTextfield, "Title text field present which is not expected");
留一抹残留的笑 2024-09-17 15:42:43

看起来 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);
}

尽管仍在寻找一种完全避免超时的方法......

It looks like findElements() only returns quickly if it finds at least one element. Otherwise it waits for the implicit wait timeout, before returning zero elements - just like findElement().

To keep the speed of the test good, this example temporarily shortens the implicit wait, while waiting for the element to disappear:

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

Still looking for a way to avoid the timeout completely though...

酒中人 2024-09-17 15:42:43

您可以利用 Arquillian Graphene 框架来实现此目的。因此,您的情况的例子可能是

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

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

You can utlilize Arquillian Graphene framework for this. So example for your case could be

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

Is also provides you bunch of nice API's for working with Ajax, fluent waits, page objects, fragments and so on. It definitely eases a Selenium based test development a lot.

無處可尋 2024-09-17 15:42:43

对于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))
            }

For node.js I've found the following to be effective way to wait for an element to no longer be present:

// 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))
            }
留蓝 2024-09-17 15:42:43

不是问题的答案,但可能是基本任务的想法:

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

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

Not an answer to the very question but perhaps an idea for the underlying task:

When your site logic should not show a certain element, you could insert an invisible "flag" element that you check for.

if condition
    renderElement()
else
    renderElementNotShownFlag() // used by Selenium test
烂柯人 2024-09-17 15:42:43

请查找下面使用 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

Please find below example using Selenium "until.stalenessOf" and Jasmine assertion.
It returns true when element is no longer attached to the DOM.

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

For ref.: Selenium:Until Doc

假面具 2024-09-17 15:42:43

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

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

The way that I have found best - and also to show in Allure report as fail - is to try-catch the findelement and in the catch block, set the assertTrue to false, like this:

    try {
        element = driver.findElement(By.linkText("Test Search"));
    }catch(Exception e) {
        assertTrue(false, "Test Search link was not displayed");
    }
时光瘦了 2024-09-17 15:42:43

这对我来说是最好的方法

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

This is the best approach for me

public boolean isElementVisible(WebElement element) {
    try { return element.isDisplayed(); } catch (Exception ignored) { return false; }
}
扬花落满肩 2024-09-17 15:42:43

对于 JavaScript(支持 TypeScript)实现,我想出了一些虽然不是很漂亮但有效的方法:

  async elementNotExistsByCss(cssSelector: string, timeout=100) {
    try {
      // Assume that at this time the element should be on page
      await this.getFieldByCss(cssSelector, timeout);
      // Throw custom error if element s found
      throw new Error("Element found");
    } catch (e) {
      // If element is not found then we silently catch the error
      if (!(e instanceof TimeoutError)) {
        throw e;
      }
      // If other errors appear from Selenium it will be thrown
    }
  }

PS:我正在使用 "selenium-webdriver": "^4.1.1"

For a JavaScript (with TypeScript support) implementation I came up with something, not very pretty, that works:

  async elementNotExistsByCss(cssSelector: string, timeout=100) {
    try {
      // Assume that at this time the element should be on page
      await this.getFieldByCss(cssSelector, timeout);
      // Throw custom error if element s found
      throw new Error("Element found");
    } catch (e) {
      // If element is not found then we silently catch the error
      if (!(e instanceof TimeoutError)) {
        throw e;
      }
      // If other errors appear from Selenium it will be thrown
    }
  }

P.S: I am using "selenium-webdriver": "^4.1.1"

奢华的一滴泪 2024-09-17 15:42:43

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

findElement will check the html source and will return true even if the element is not displayed. To check whether an element is displayed or not use -

private boolean verifyElementAbsent(String locator) throws Exception {

        boolean visible = driver.findElement(By.xpath(locator)).isDisplayed();
        boolean result = !visible;
        System.out.println(result);
        return result;
}
宛菡 2024-09-17 15:42:43

适用于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());

For appium 1.6.0 and above

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

    Assert.assertTrue(!button.isDisplayed());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文