[java] Assert that a WebElement is not present using Selenium WebDriver with java

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

This question is related to java selenium-webdriver assertion

The answer is


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 */ 
    }
}

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...


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

boolean titleTextfield = driver.findElement(By.id("widget_polarisCommunityInput_113_title")).isDisplayed();
assertFalse(titleTextfield, "Title text field present which is not expected");

It's easier to do this:

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

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


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

There is an Class called ExpectedConditions:

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

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.


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

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

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

With Selenium Webdriver would be something like this:

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

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

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to selenium-webdriver

SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81 Selenium: WebDriverException:Chrome failed to start: crashed as google-chrome is no longer running so ChromeDriver is assuming that Chrome has crashed WebDriverException: unknown error: DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser How to configure ChromeDriver to initiate Chrome browser in Headless mode through Selenium? How to make Firefox headless programmatically in Selenium with Python? Selenium Web Driver & Java. Element is not clickable at point (x, y). Other element would receive the click How do you fix the "element not interactable" exception? Scrolling to element using webdriver? Only local connections are allowed Chrome and Selenium webdriver Check if element is clickable in Selenium Java

Examples related to assertion

How to verify a Text present in the loaded page through WebDriver Best way to check that element is not present using Selenium WebDriver with java What is the use of "assert"? Assert that a WebElement is not present using Selenium WebDriver with java What does the "assert" keyword do? Why do I get a C malloc assertion failure? How do I assert my exception message with JUnit Test annotation? How do I use Assert.Throws to assert the type of the exception? Best practice for using assert?