Search code examples
javaseleniumnosuchelementexception

Selenium checking isDisplayed equals false throws NoSuchElementException


I am getting NoSuchElementException when I check for isDisplayed() equals false for an element. Here is my code:

XYZpage.java:

public WebElement cancelButton() { return driver.findElement(By.cssSelector(".cancelButton")); }

XYZtest.java:

softAssertions.assertThat(sellerVehicleEditPage.cancelButton().isDisplayed())
            .isEqualTo(false);

I am asserting here that an element is not displayed. I have seen other solutions on this website and other places where people are suggesting to try ExpectedConditions, among other things. But since the element doesn't exist even ExpectedConditions is eventually throwing NoSuchElementException. This is what I tried in XYZpage.java:

WebDriverWait wait = new WebDriverWait(driver, 5);
public WebElement cancelButton() { return wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".cancelButton"))); }

I have more than 1000 elements with each element used multiple times in different tests. So I do not want to pass By every time I need to call the element, as some of the solutions suggests. Is there a more elegant way to check conditions like .isDisplayed() equals false without getting NoSuchElementException?


Solution

  • Selenium web driver fails finding element matching the locator you are using there, this is why NoSuchElementException Exception is thrown.
    isDisplayed() method can be applied on web element returned by

    driver.findElement(By.cssSelector(".cancelButton"))
    

    or by

    wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".cancelButton")))
    

    methods.
    But this method is not involved since NoSuchElementException exception is thrown before that and the process flow is broken on that point.
    To wait for element presence you can use this method:

    public boolean waitForElementPresence(By element){
        WebDriverWait wait = new WebDriverWait(driver);
        try {
            wait.until(ExpectedConditions.presenceOfElementLocated(element));
            return true;
        }catch (Throwable t){
            return false;
        }
    }
    

    To wait for element visibility:

    public boolean waitForElementVisibility(By element){
        WebDriverWait wait = new WebDriverWait(driver);
        try {
            wait.until(ExpectedConditions.visibilityOfElementLocated(element));
            return true;
        }catch (Throwable t){
            return false;
        }
    }
    

    For more simply element presence validation:

    public boolean isElementFound(By element){
        wait(300);
        return !driver.findElements(element).isEmpty();
    }
    

    UPD
    To use with WebElement as parameter:

    public boolean waitForElementVisibility(WebElement element){
        WebDriverWait wait = new WebDriverWait(driver);
        try {
            wait.until(ExpectedConditions.visibilityOf(element));
            return true;
        }catch (Throwable t){
            return false;
        }
    }