Have a look at this method that checks if an element is displayed:
public boolean isDisplayed(By by) {
boolean status = false;
try {
WebElement element = driver.findElement(by);
wait.until(ExpectedConditions.visibilityOf(element));
status = element.isDisplayed();
} catch (Exception e) {
status = false;
}
return status;
}
The method tries finding an element. If the element is found, it waits until the element is visible. Then, it returns true if the element is displayed and false otherwise.
The interesting part is that the code is wrapped in a try/catch statement.
What are the consequences of using the try/catch statement?
If the element cannot be found, an exception is generated and the method returns false. If the element is found but it is not visible, an exception is generated and the method returns false.
What is bad about it?
If the method returns false, what does this mean? Is the element not found? Is the element not visible? Or maybe some other unexpected thing happened? Maybe the browser is frozen? Maybe there is a 404 error?
No one knows what happened since the exception is just hidden. No exception info is displayed in the console or in a log. This method catches the exception and ignores it.
Also, the test execution continues. The test will fail eventually but in the wrong spot.
Ignoring an exception and letting the test to continue is a bad idea in this case.
Instead, the method should look as follows:
public boolean isDisplayed(By by) {
WebElement element = driver.findElement(by);
wait.until(ExpectedConditions.visibilityOf(element));
return element.isDisplayed();
}
In this case, if the element is not found, the method fails and the exception/stack trace info about the element not being found are displayed in the console. The test execution is stopped.
If the element is not visible, the method fails as well and the exception/stack trace info about the element not being visible are displayed in the console. The test execution is stopped.
Also, the code of the method is much simpler. The method does not use try/catch and it uses less variables.
Let’s try a different example:
public boolean isWindowDisplayed() {
boolean isDisplayed = false;
try {
WebElement newWindowLink = driver.findElement(newWindowBy);
newWindowLink.click();
List<WebElement> resultList = driver.findElements(resultBy);
int resultCount = resultList.size();
isDisplayed = resultCount > 0;
} catch (Exception e) {
e.printStackTrace();
}
return isDisplayed;
}
This method does not ignore the exception as it displays the stack trace info in the console.
But it returns true or false which is again misleading.
As false can be returned if
newWindowLink is not found
newWindowLink cannot be clicked
no results are found
the site is not responding
an unknown error is generated
It is possible to check what happened by reading the console info.
But the issue here is that the test execution is continued even if something unexpected happens since the method catches the exception and ignores it.
The test will fail eventually but in a different place which will make debugging the failure difficult.
Also, the method can be simplified a lot as follows:
public boolean isWindowDisplayed() {
WebElement newWindowLink = driver.locateElement(newWindowBy);
newWindowLink.click();
List<WebElement> resultList = driver.findElements(resultBy);
return resultList.size() > 0;
}
In this case, if the newWindowLink cannot be found or cannot be clicked, the method fails, the test fails as well and information on the reason for the failure can be found in the console.