2

In real-time automation, do we check for the presence of every element(in test) before performing some action on them?

Wherever there is a findElement statement, there is a chance of NoSuchElementException. My question is whether we check for the presence of the element everytime?

Does every findElement statement need to be surrounded by try-catch block?

5 Answers5

1

There are two cases to account for:

  1. Is the element present; meaning does it exist in the DOM.
  2. Is the element visible; meaning it is in DOM and does not have a hidden or equivalent flag.

For the first case, I use the following helper method:

this.waitForElement = function(locator) {
    browser.wait(function() {
      return browser.isElementPresent(locator);
    }, testData.Timeout.TWO_MINUTES);
};

This will wait for an arbitrary amount of time for the element matching the provided locator to become present (It exists in the DOM).

For the second case, I use this helper method:

this.waitForElementIsVisible = function(el){
    let EC = protractor.ExpectedConditions;
    browser.wait(EC.visibilityOf(el), testData.Timeout.TWO_MINUTES, "Element did not become visible after 2 minutes");
};

This takes a WebElement as the single parameter and waits until the element becomes visible (It exists in the DOM and is not hidden via a css style or something)

As a bonus, I also found this helper method to be useful for testing error states in a form:

this.waitForElementIsClickable = function(el){
    let EC = protractor.ExpectedConditions;
    browser.wait(EC.elementToBeClickable(el), testData.Timeout.TWO_MINUTES, "Element did not become clickable after 2 minutes");
};

Takes a WebElement as the first parameter and waits until that WebElement can be clicked.

Note, I am using protractor, and reference Protractor in these snippets. So unless you are using Protractor as well, it's likely these will not work 100% through a straight copy+paste. Should be easy enough to tweak them to suite your setup though.

lTyl
  • 126
  • 4
1

Answering your questions one by one:

  • "In real-time automation, do we check for the presence of every element(in test) before performing some action on them" : Yes as per best practices whenever user is redirected to a new page you need to ensure the state of the element as per your desired action.

There are 3 most widely used ExpectedConditions which can be used in-conjuction with WebDriverWait to validate an element's state as follows:

presenceOfElementLocated

presenceOfElementLocated(By locator) is defined as follows :

public static ExpectedCondition<WebElement> presenceOfElementLocated(By locator)

Description : An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible.

visibilityOfElementLocated

visibilityOfElementLocated(By locator) is defined as follows :

public static ExpectedCondition<WebElement> visibilityOfElementLocated(By locator)

Description : An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0.

elementToBeClickable

elementToBeClickable(By locator) is defined as follows :

public static ExpectedCondition<WebElement> elementToBeClickable(By locator)

Description : An expectation for checking an element is visible and enabled such that you can click it.

  • "Wherever there is a findElement statement, there is a chance of NoSuchElementException": No, not at all. If you construct a proper Locator Strategy, you won't face NoSuchElementException.

Here you will find a detailed discussion on NoSuchElementExeption, selenium unable to locate element

  • Does every findElement statement need to be surrounded by try-catch block: No, not always. If your usecase involves handling of both affirmative and negative scenarios then try-catch {} block is perfecto.
DebanjanB
  • 118,661
  • 30
  • 168
  • 217
0

The most direct, simplest way to check for the existence of a web element is to use findElements() (notice the plural) which returns an array, i.e.

if (driver.findElements(By.xpath("//a")).isEmpty())
    // no links exist

The same method can be used to check for a single element, it does not have to be an array. A returned .size() of zero means there were no matches, and thus the desired element is not in the DOM.

A better method, some would argue, is to wrap the .findElement in a method which does do try/catch and logs/responds accordingly to various results, like element not found, or stale element, etc.

I use both methods in my tests, and use my own exists function with the .findElements logic but use the wrapper for other scenarios.

Bill Hileman
  • 2,630
  • 2
  • 12
  • 21
  • Thanks. I understand that we can write our own functions to check for the presence of the element in any of the ways you mentioned. My question is whether we check the presence of an element in every step where there is a `findElement` statement? – Mehavarnan Murugan May 30 '18 at 18:18
  • 1
    That's why I generally use a wrapper, or in my particular case, page object model. The test code itself should not have to repeat the same code over and over, but it does need to be robust enough to be able to handle situations where the expected element is not present, so go with a wrapper or better, go with page object model/pattern. – Bill Hileman May 30 '18 at 18:37
0

You may find the use of the class AbstractWebDriverEventListener particularly useful. This class implements the interface WebDriverEventListener which defines before and after hooks for the events triggered by WebDriver.

One such before hook beforeFindBy could be implemented to check the presence of element. For example:

public void beforeFindBy(By by, WebElement element, WebDriver driver) {
    // Explicit wait to check for the presence of the element using the "by" locator
}

Similarly the before hook beforeClickOn could be implemented to check that the element is clickable before the click event is performed on that element.

GPT14
  • 769
  • 5
  • 12
0

Short answer: No. Longer answer: One approach is to wait until a "page is finished" indicator to use an explicit wait. This will signal you're safe to findElement's as needed. If one of those elements isn't available, the test will fail, indicating it couldn't find the element. Using Explicit waits as needed (when you expect the page/DOM to change) within the test.

But again, there is some opinion to this question and it's answers. Checking/waiting for element to be present every step along the way does have a cost in the time to run and may just prolong a test that could fail quicker.

DMart
  • 2,198
  • 1
  • 11
  • 17