Understanding No Such Element Exception in Selenium
By Sonal Dwivedi, Community Contributor - May 31, 2024
What is NoSuchElementException in Selenium
Most of the websites in today’s world are dynamic which means it loads the web pages and web elements lazily. A dynamic website generates and loads the web pages in real time as per the screen size, device type and browser.
NoSuchElementException is thrown by the findElement() method in Selenium WebDriver when the desired web element cannot be located using the specified locator, such as ID, name, CSS Selector, or XPath. This exception indicates that at the time of execution, the web element you are trying to interact with is not present on the webpage.
There are two types of exceptions,
- Checked Exceptions, which are checked by the compiler at the runtime for the smooth execution of the program
- Unchecked Exceptions, which are not checked by the compiler and it arises only after the test is executed.
NoSuchElementException is an unchecked exception which is a subclass of NotFoundException
- What is NoSuchElementException in Selenium
- When does No Such Element Exception in Selenium occur?
- 1. Changes in DOM structure
- 2. Element not present
- 3. Element not yet loaded
- 4. Wrong Locator Strategy
When does No Such Element Exception in Selenium occur?
NoSuchElementException in Selenium occurs in the following cases:
1. Changes in DOM structure
Some web elements are very dynamic in nature. In such cases the specified locator cannot be accessed by Selenium WebDriver as its properties keep on changing causing NoSuchElementException.
For example, while automating, the locator value was “//a[@class=’abc_123’]”, however while executing the test the class value got changed to “abc_456”.
Such changes in the DOM structure leads to No Such Element Exception in Selenium.
2. Element not present
At times, the element’s visibility depends on certain conditions. If those conditions are not met at the time of execution, Selenium will throw NoSuchElementException.
For example, suppose in an automation script, the element to be clicked is visible only after checking a particular radio button. In that case, if for any reason WebDriver fails to click the radio button, the desired element is not visible and hence an exception will be thrown.
3. Element not yet loaded
Some elements might take some time to load due to various factors such as network speed, dynamic rendering or JavaScript execution. Selenium execution is very fast. Hence, in such cases, for dynamic web applications, if the WebDriver action on the element takes place before the rendering of the element, NoSuchElementException is thrown.
4. Wrong Locator Strategy
Selenium provides 8 locator strategies, among which some of the most widely used are ID, name, XPath and CSSSelector. If the locator strategy used to find the element is incorrect, Selenium will throw the exception.
Read More: Locators in Selenium
Sample code to click offers tab in BStackDemo app:
public void verifyOffersClick() { driver.get("https://bstackdemo.com/"); WebElement offers= driver.findElement(By.cssSelector("a#offer strong")); offers.click(); }
Here, the “offers” webelement is holding incorrect locator value, as the correct locator should be “a#offers strong”. Hence, Selenium will throw NoSuchElementException.
How to handle NoSuchElementException in Selenium
Here are different ways to handle NoSuchElementException in Selenium:
1. Using WebDriverWait
WebDriverWait allows you to wait for an element to satisfy a specific condition defined through the ExpectedConditions class in Selenium. For example, you can use WebDriverWait to wait for some seconds until the desired element is present in the DOM.
Below example demonstrates navigating to BStackDemo application, clicking on the offers tab and verifying that it lands to Sign In page.
public class NoSuchElementException { WebDriver driver=new ChromeDriver(); @Test public void verifyOffersClick () { driver.get("https://bstackdemo.com/"); WebDriverWait wait =new WebDriverWait(driver, Duration.ofSeconds(10)); By offer= By.cssSelector("a#offers strong"); WebElement offers=wait.until(ExpectedConditions.elementToBeClickable(offer)); offers.click(); By uname= By.xpath("//div[text()='Select Username']"); WebElement username=wait.until(ExpectedConditions.presenceOfElementLocated(uname)); Assert.assertTrue(username.isDisplayed()); } @AfterTest public void tearDown() { driver.quit(); } }
In the above program, “offers” and “username” web elements are created and they have been associated with WebDriver wait which tells them to wait for 10 seconds so that the interacted web element gets rendered completely to receive any commands later by Selenium WebDriver.
2. Using Try-Catch block
Surround the code block which you feel may throw a NoSuchElementException with a try-catch block. This helps to catch the exception if it occurs and let the code continue to work without abruptly stopping the execution.
In the try block, add the code which may throw an exception and in the catch block add the required actions to handle the exception gracefully.
@Test public void verifyOffersClick() { driver.get("https://bstackdemo.com/"); WebElement offers=driver.findElement(By.cssSelector("a#offers strong")); try { offers.click(); }catch (Exception e) { e.printStackTrace(); offers.click(); } }
In the above code, a web element “offers” is created and in the try block it is clicked. If any exception occurs the execution control goes to the catch block and clicks the offers link.
3. Use findElements() instead of findElement()
findElement() method of WebDriver returns the first web element matching the locator whereas findElements() returns a list of web elements matching the locator.
If the web element is created using findElement() method and the web element is not present in the DOM, Selenium will surely throw a NoSuchElementException. To avoid this, you can use findElements() method which returns a list of web elements and by checking the size of the list, the visibility of the web element can be determined.
Read More: findElement and findElements in Selenium
@Test public void verifyOffersClick() { List<WebElement> offers= driver.findElements(By.cssSelector("a#offers strong")); if(offers.size()>0) { offers.get(0).click(); } }
4. Use more reliable selectors
Locators such as ID and name should be preferably used while creating locators. And if there is no unique ID or name, XPath should be used.
It is always recommended to use relative XPath locators instead of absolute as it is less likely to be changed in case of DOM structure change hence reducing the chances of exceptions.
By researching this way, the most suitable locator should be used to avoid NoSuchElementException.
Sample code to click on offers link on BStackDemo application:
public void verifyOffersClick() { driver.get("https://bstackdemo.com/"); WebElement offers= driver.findElement(By.cssSelector("a#offers strong")); offers.click(); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2)); WebElement username= driver.findElement(By.xpath("//div[text()='Select Username']")); Assert.assertTrue(username.isDisplayed()); }
5. Switch to frame/ iFrame
Some web elements are inside frame/ iframe and it is only discovered when you encounter an exception. Always check if the element is inside any frame and in such case switch to the frame/ iframe and then perform the action on the desired web element. After the action is complete, switch the driver back to the parent window by using driver.switchTo().defaultContent().
Read More: How to handle iFrame in Selenium
Just to demonstrate the switching of driver, assume that in BStack Demo application, “offers” link is inside a frame. Below code shows how to switch to the frame, perform desired action on the web element and switch back to the default content.
@Test public void verifyOffersClick() { driver.switchTo().frame("1"); WebElement offers= driver.findElement(By.cssSelector("a#offers strong")); offers.click(); driver.switchTo().defaultContent(); }
Why Testing on Real Devices and Browsers is important?
Handling dynamic web elements in Selenium is crucial for robust test automation. By using explicit waits, correct locator strategy, frame handling, and try-catch mechanisms, one can effectively deal with dynamic elements in the automation scripts.
It may also happen that NoSuchElementException may arise in some specific device, which demands to test the applications on real devices and browsers.
In today’s ever growing mobile market it is not feasible to procure and test on all the latest devices and browsers. To cope with this issue, it is best to invest in any platform which aids in testing the application on a wide range of devices and browsers.
BrowserStack Automate is one of the cloud-based platforms that provides a comprehensive infrastructure for cross-device and cross-browser testing with zero hassle in setting up the device and environment.
Testing applications on real devices and browsers is obligatory to ensure a positive user experience, reliability, performance and compatibility of the application across a diverse range of devices, browsers and platforms.