Most web tests involve interacting with elements on a web page. This would not possible without first locating and
retrieving these elements on the page. When the process of locating the elements of interest in the web page fails,
Selenium throws a
NoSuchElementException
. This represents one of the most common Selenium exceptions, which is why it
is so important to know about it and how to handle it correctly.
In this article, you will learn what a
NoSuchElementException
is, what the most common causes behind this exception
are, and everything you need to know to handle it in your Selenium WebDriver
regression tests
.
What is a NoSuchElementException in Selenium?
NoSuchElementException
is one of the most common exceptions in Selenium WebDriver, and it is thrown when an HTML element cannot be found. A
NoSuchElementException
occurs when the
Selenium locator strategy
defined is unable to
find the desired HTML element in the web page.
importorg.openqa.selenium.*;importorg.openqa.selenium.chrome.ChromeDriver;publicclassMain{publicstaticvoidmain(String[]args){// setting the system property for the Chrome Driver
System.setProperty("webdriver.chrome.driver","<the_path_to_your_chrome_driver>");// initializing the Selenium WebDriver ChromeDriver class
WebDriverdriver=newChromeDriver();driver.get("<your_url>");// trying to retrieve the "foo-button" HTML element
WebElementfooButton=driver.findElement(By.id("foo-button");// ...
When Selenium is not able to locate the HTML element with id “foo-button”, the following
NoSuchElementException
is
thrown:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#foo\-button"}
There are a few reasons why a
NoSuchElementException
can occur. Let’s now delve into them.
When Does NoSuchElementException Occur in a Selenium Test?
There are two main reasons for a
NoSuchElementException
:
The Selenium locator strategy you adopted does not identify any HTML element in the
DOM
. There’s a few ways this can occur:
The HTML element is not yet present in the web page, just when the desired element is rendered asynchronously as a
result of an AJAX call.
The HTML element appears in the web page only after certain operations are performed.
The HTML element is not present in the web page, no matter what.
The HTML element you are trying to locate is inside an
<iframe>
element.
How To Handle NoSuchElementException in Selenium?
There are two ways to deal with
NoSuchElementException
.
Using WebDriverWait
WebDriverWait
allows you to wait for an HTML element to satisfy a specific condition defined through the
ExpectedConditions
class. For example, you can use it to wait some seconds until the HTML element you are looking for is present in the DOM
as below:
// defining a locator for the HTML element with id = "foo-button"
Bylocator=By.id("foo-button");// waiting up to 10 seconds until the "foo-button" HTML element is loaded into the DOM
WebDriverWaitwait=newWebDriverWait(driver,Duration.ofSeconds(10));wait.until(ExpectedConditions.presenceOfElementLocated(locator));// retrieving "foo-button" HTML element
WebElementfooButton=driver.findElement(locator);// ...
This avoids a
NoSuchElementException
due to incomplete page loading. If the “foo-button” HTML element is not displayed
in 10 seconds after calling the
until()
method, then a
TimeoutException
will be thrown. This exception will be
introduced later.
Consider that the approach presented above may not be sufficient when dealing with AJAX calls. This is especially true
when it comes to web apps developed in
React
,
Vue
, or
Angular
that make heavy use of API calls to retrieve data. In this scenario, you may need a more
sophisticated approach involving a polling process. You can implement it as follows:
// defining a locator for the HTML element with id = "foo-button"
Bylocator=By.id("foo-button");// waiting 10 seconds for the "foo-button" HTML element to be present on the page, and
// checking for its presence after 5 seconds sleep
WebDriverWaitwait=newWebDriverWait(driver,Duration.ofSeconds(10),Duration.ofSeconds(5));wait.until(ExpectedConditions.presenceOfElementLocated(locator));// retrieving "foo-button" HTML element
WebElementfooButton=driver.findElement(locator);// ...
The third parameter passed to
WebDriverWait
defines the duration of the sleep time between polls.
Notice that
WebDriverWait
ignores
NotFoundException
s thrown by the
until()
method by default, but immediately propagates all other exceptions. Therefore, also
NoSuchElementException
cannot be
thrown by
until()
when calling it on a
WebDriverWait
instance.
Using more reliable selectors
The Selenium
By
class allows you to
define the locator strategy that Selenium will apply to find HTML elements within a web document. When Selenium fails to
find the HTML element identified with the
By
condition, a
NoSuchElementException
is thrown.
By
offers several ways to locate an HTML element, but some are more reliable than others. For example, retrieving an
HTML element based on its
class
attribute
may not be a good strategy. This is because CSS classes are attributes that can easily change over time.
// retrieving the HTML element with class = "foo-align-right"
WebElementfooElement=driver.findElement(By.className("foo-align-right"));
If the layout of the web page changes or the “foo-align-right” class name is renamed, this line of code will throw a
NoSuchElementException
.
If you want your Selenium tests to be robust to changes in the target web pages, you need to use more reliable
selectors. When it comes to defining selectors, you should prefer IDs to classes. The
id
attribute of an HTML element identifies
it uniquely and is unlikely to change over time.
// retrieving the HTML element with id = "foo-button"
WebElementfooElement=driver.findElement(By.id("foo-button"));
In this case, the selector used to retrieve the HTML element is more reliable.
In general, you should always try to use selectors and locator strategies that are based on the distinctive priorities
of an HTML element. Styling and placement might change many times over time, and relying on them forces you to update
your tests to avoid
NoSuchElementException
s.
Other Common Selenium Exceptions That Can Occur
Let’s take a look at the three most common Selenium exceptions remaining.
InvalidSelectorException
InvalidSelectorException
is
thrown by
By
when the selector passed as a parameter is a CSS or
XPath
expression that is syntactically invalid. You can avoid it
by replacing the selector string used in
By
condition with a valid expression.
Example:
// using an invalid CSS selector expression
WebElementfooButton=driver.findElement(By.cssSelector("/foo-button");
This is the
InvalidSelectorException
error that snippet would cause:
Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for element to be clickable: By.cssSelector: @foo-button
ElementNotInteractableException
is thrown when an HTML element is present in the DOM but is in a state that cannot be interacted with. Note that this
includes an HTML element that is hidden, or whose center point can not be scrolled into the
browser viewport
.
For example,
ElementNotInteractableException
is thrown when calling the
click()
method on a
Selenium
WebElement
you
momentarily cannot interact with. In this case, you can avoid the exception by employing the
ExpectedCondition.elementToBeClickable
method combined with
WebDriverWait
as below:
// defining a locator for the HTML element with id = "foo-button"
Bylocator=By.id("foo-button");// waiting up to 10 seconds for the "foo-button" HTML element to be clickable
WebDriverWaitwait=newWebDriverWait(driver,Duration.ofSeconds(10));wait.until(ExpectedConditions.elementToBeClickable(locator));// retrieving "foo-button" HTML element and clicking it
WebElementfooButton=driver.findElement(locator);fooButton.click()
If the
fooButton
element is in a non-interactable state, the last line would cause the following error:
Exception in thread "main" org.openqa.selenium.ElementNotInteractableException: element not interactable
TimeoutException
TimeoutException
is
thrown when a command does not complete in enough time. For example, when this exception occurs when an
until()
method
on a
WebDriverWait
instance does not satisfy the expected conditions in the given time.
Example:
// defining a locator for the HTML element with id = "foo-button"
Bylocator=By.id("foo-butyon");// waiting 10 seconds for the "foo-button" HTML element to be present on the page, and
// checking for its presence after 5 seconds sleep
WebDriverWaitwait=newWebDriverWait(driver,Duration.ofSeconds(10),Duration.ofSeconds(5));wait.until(ExpectedConditions.presenceOfElementLocated(locator));// retrieving "foo-button" HTML element
WebElementfooButton=driver.findElement(locator);// ...
Notice the typo introduced in the first line in the
By
condition. This would cause
until()
to fail and the following
TimeoutException
error as a result:
Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for presence of element located by: By.id: foo-butyon (tried for10 second(s) with 5000 milliseconds interval)
No More Exceptions With Reflect
When something goes wrong, Selenium raises exceptions. So, you need to know what exceptions your test can raise and how
to handle them accordingly. This is a cumbersome process that only experienced developers can deal with. Thankfully,
there is a solution to this problem! The solution is called
Reflect
, a no-code tool that allows
you to test your web applications with no exceptions involved.
Let’s understand how powerful Reflect is with an example.
Suppose you want to test adding a product to your e-commerce site’s shopping cart. Specifically, when you click the “Add
to basket” button, the site should perform an asynchronous AJAX request to add the product to the cart and show the
“View Cart” button. With Selenium, you would have to write some logic to wait for that HTML element to appear. With
Reflect, you can simply perform the actions you want to test directly in the browser and define a
visual check
to wait for the
desired element to appear on the page.
As you can see, Reflect records these actions for you and builds a test around them. With just a few clicks, you can
define a test involving async logic! This makes testing a lot faster and easier. Stop struggling with exception handling
in your tests,
try Reflect for free
!
Conclusion
In this article, you learned that Selenium WebDriver is a powerful tool to perform automated tests on web applications,
what
NoSuchElementException
is and when it occurs, and how to handle it in Java. Considering how frequent the
NoSuchElementException
is, understanding how it happens and being able to use handle it properly is critical to
building robust Selenium WebDriver tests. Here you learned everything you need to know to interact with it and other
common Selenium exceptions. Also, you understood that dealing with exceptions when it comes to testing is cumbersome and
you can avoid all this with a complete no-code testing tool such as Reflect.
Get started with Reflect today
Create your first test in 2 minutes, no installation or setup required.
Accelerate your testing efforts with fast and maintainable test suites without writing a line of code.
Try Reflect for free
Contact Us
We'd love to hear from you! Use the form or contact us directly at
[email protected]