Selenium: Check for the presence of element
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?
Solution 1:
There are two cases to account for:
- Is the element present; meaning does it exist in the DOM.
- 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.
Solution 2:
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 thentry-catch {}
block is perfecto.