Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium 2 - How to check if element not present while implicitly waiting?

If you check absent elements with the following code:

// ...
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
try {
    driver.findElement(By.cssSelector("td.name"));
} catch (NoSuchElementException e) {

    // here you go, element not found

}

You get right result, but running time is always 30 seconds, due to findElement method blocking on the implicit wait.

Is there a way to avoid this behavior, while keeping the implicit wait in place?

<EDIT> tests are going to be generated through Selenium IDE by non-developers, so I need a solution that keeps their job as simple as possible (that's keeping waits implicit!). </EDIT>

Thanks,

Marco

like image 474
Marco Bolis Avatar asked Oct 05 '12 13:10

Marco Bolis


People also ask

How do you check if an element is not present in Selenium?

New Selenium IDE To check the presence of an element, we can use the method – findElements. The method findElements returns a list of matching elements. Then, we have to use the method size to get the number of items in the list. If the size is 0, it means that this element is absent from the page.

How do I check if an element is not displayed?

isDisplayed() is the method used to verify a presence of a web element within the webpage. The method returns a “true” value if the specified web element is present on the web page and a “false” value if the web element is not present on the web page.

How do you verify if a value is present in a dropdown in Selenium?

We can verify if we can select multiple options in a static dropdown in Selenium with the help of isMultiple() method. It returns a Boolean value of true or false.


2 Answers

The methods above wait for the provided amount of time even if the element is not present anymore. I wrote my own methods for waiting until element is visible and not present. They work for me. Here they are:

public void waitUntilElementExists(By by, int waitSeconds,
        int noOfRetries) {
    getDriver().manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
    boolean foundElement = false;
    for (int i = 0; i < noOfRetries; i++)
        try {
            getDriver().findElement(by);
            foundElement = true;
            break;
        } catch (Exception e) {
        }
    assertTrue("The searched element was not found after " + noOfRetries * waitSeconds + " seconds!", foundElement);
}

public void waitUntilElementDoesntExist(By by, int waitSeconds,
        int noOfRetries) {
    getDriver().manage().timeouts().implicitlyWait(waitSeconds, TimeUnit.SECONDS);
    boolean elementDisappeared = false;
    for (int i = 0; i < noOfRetries; i++)
        try {
            getDriver().findElement(by);
            waitABit(1000 * waitSeconds);
        } catch (Exception e) {
            elementDisappeared = true;
            break;
        }
    assertTrue("The searched element did not disappear after " + noOfRetries * waitSeconds + " seconds!", elementDisappeared);
}
like image 192
Istvan Kis Avatar answered Sep 20 '22 12:09

Istvan Kis


You might be able to do it with xpath selectors. Find the element just before it that you know should be there, then use "following-sibling" to get the next element. Something like:

//td.previous/following-sibling::td

Then check to see that it hasn't returned the "name" one. Of course that would only work if there is another "td" element.

Personally I'd be tempted to drop the implicit waits and just use waits when they are required.

private WebElement cssWait( final String css )
{
    return new WebDriverWait( driver, 30 ).until( new ExpectedCondition< WebElement >()
    {
        @Override
        public WebElement apply( WebDriver d )
        {
            return d.findElement( By.cssSelector( css ) );
        }
    } );
}
like image 40
Nick Wilson Avatar answered Sep 20 '22 12:09

Nick Wilson