As you start writing more and more automated tests with Selenium WebDriver, you will start encountering various exceptions. I’ll guide you through the most common Selenium exceptions and help you solve them so your C# automation framework is more reliable.
Table of Contents – 10 Common Selenium Exceptions in C# and How to Fix Them
What are exceptions?
Exceptions are errors that occur during application execution. Exception objects are created and then they are thrown with the throw keyword. When unhandled, they disrupt the normal program execution.
Common Selenium exceptions
Let’s go through the most common Selenium exceptions that you might encounter, understand their causes, and see the possible solutions.
1. NoSuchElementException
The NoSuchElementException is thrown when the element cannot be found on the web page. This can happen for a number of reasons:
- You are using the wrong locator. There is no “one fits all” locator strategy, but you have to make sure that you are using a locator that is both unique, and correct. Pay extra attention if you are using CSS selectors or XPaths, and make sure they are correct.
- The web page was not completely loaded and the element is not found. To solve it, you can use Selenium explicit waits, and wait until the element can be found on the page. Here’s a code example in C# (you’ll also need to install the DotNetSeleniumExtras NuGet package):
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); IWebElement LoginButton = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(By.Id("login")));
- The element is not visible on the page and you have to scroll up or down to reach it. You can do this using a JavaScript executor:
public void scrollDown() { IJavaScriptExecutor js = (IJavaScriptExecutor)driver; js.ExecuteScript("window.scrollBy(0,250)", ""); }
2. ElementNotVisibleException
This one is a bit different than the NoSuchElementException, because it means that the element was found in the DOM, but it is not visible on the page. This also means that we cannot interact with the element, so we can’t click, send keys, or perform other actions on it. It can happen if:
- The element is hidden.
- The locator strategy you are using finds more elements with the same locator, and the first one is not visible.
To fix this, first make sure that you are using a unique locator, and that you are identifying the correct element on the page.
If your locator is good, then you can add a wait, that checks when the element is visible:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); IWebElement LoginButton = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.Id("login")));
3. InvalidSelectorException
This Selenium exception is thrown if you are using an incorrect selector. An example of this would be using a compound class name, which is not allowed:
private IWebElement LoginButton => driver.FindElement(By.ClassName("login button"));
The solution for this is to make sure that the locator is correct. In the above scenario, you can replace the ClassName locator strategy with CssSelector:
private IWebElement LoginButton => driver.FindElement(By.CssSelector("login.button"));
4. ElementClickInterceptedException
This Selenium exception is usually thrown when the element was found on the page, but the click action would be performed on a different element that is overlapped our element. For example, if you go to the TestProject blog page and scroll down a bit, you will see a message prompting you to Sign Up for the TestProject test automation platform. You won’t be able to click any of the links on the page until you close it.
So, if you have something like this in a Selenium test, and your test tries to click a blog title, you will get an ElementClickInterceptedException.
One solution to this exception is to use the Action class for performing the click:
Actions _action = new Actions(driver); _action.MoveToElement(elementToClick).Click();
Or if the element is simply out of view and scrolling will reveal it, you can use the JavaScript scroll executor as shown above for the NoSuchElementException.
5. StaleElementReferenceException
The StaleElementReferenceException means that a reference to an element is now “stale”, i.e. the element is no longer available on the web page DOM. In other words, the element was initially found on the DOM, but the DOM has changed since then. The common causes for this are:
- The element was deleted from the DOM.
- The element is no longer attached to the DOM.
One possible solution is to refresh the page and try to find the element again:
driver.Navigate().Refresh(); driver.FindElement(By.Id("ElementId")).Click();
Or you can wait for the element to load before you manipulate it. Again, you can do this using explicit waits:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); IWebElement elementToInteract = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.Id("elementId")));
6. UnhandledAlertException
This exception is thrown when an alert is present on the page, preventing you from interacting with the elements. You can dismiss or accept the alert, as needed, and move on with the test steps:
// Dismiss the alert driver.SwitchTo().Alert().Dismiss(); // Accept the alert driver.SwitchTo().Alert().Accept();
7. NoAlertPresentException
The NoAlertPresentException is thrown when Selenium is trying to interact with an alert that is not loaded on the webpage. If the alert is indeed not loaded at all, then you may have found a bug in your AUT, or perhaps you are missing the steps that lead to the alert opening. Another reason can be that the alert is displayed slower than Selenium performs the actions. In this case, you can add an implicit wait to your code, so the action performed on the alert is delayed by a few seconds:
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
However, be mindful when using implicit waits, as the timespan you select will apply even if the element or alert you are waiting for has already been loaded on the page.
8. NoSuchFrameException
Similar to the NoSuchElementException, this Selenium exception is thrown when a frame is not found. Again, this can happen for multiple reasons:
- You are using an incorrect frame Id or name. In this case, make sure that you correctly identify the frame you want to switch to.
- The frame was not yet loaded. To solve this, you can use the solution above and add an implicit wait.
- The frame is nested inside a different frame. In this case, you must first switch to the parent frame, then to the frame you want to use.
In this example, to interact with elements inside “frame-left”, you would first need to switch to “frame-top”:
driver.SwitchTo().Frame("frame-top"); driver.SwitchTo().Frame("frame-left");
9. NoSuchWindowException
This one is very similar to the previous exception, applied to windows. This happens when you try to switch to a new window (or tab), which cannot be found. You can solve this by getting all the windows handles, then switching to the correct one:
var windows = driver.WindowHandles; driver.SwitchTo().Window(windows[1]);
10. TimeoutException
This exception will be thrown when the page or element was not loaded after the specified wait time. To overcome this, you can increase the wait time, if you are using an implicit wait, or better yet, replace the implicit wait with an explicit wait.
Handling exceptions with try-catch
Sometimes, the expected result is to actually have an exception thrown. In this case, you don’t want your code to stop executing or to throw the exception. Instead, you want to catch the exception and perform a certain action when the exception is thrown.
That means you need to handle the exception. This can be done with a try-catch block. Let’s assume you have a method that searches for the Logout button. You will use it in the test assertions, and you expect the button to be found when the login is successful, and not found when the login fails. In this case, the method will return a boolean, and if the element is not found it will throw a NoSuchElementException. Instead of the exception, you want the method to return false. This can be achieved by using the following code:
public bool IsElementFound() { try { driver.FindElement(By.Id("LogoutButton")); return true; } catch (NoSuchElementException e) { return false; } }
Another scenario can be that even though you don’t expect the error, you still want your program to continue running, and have the failure result logged and displayed gracefully in your test report. In this case, you can use the catch block to log the error and display a more user-friendly message, such as “The test failed because the Logout button was not found”. Looks a lot more better than “ClassName=OpenQA.Selenium.NoSuchElementException, Message=no such element: Unable to locate element”. 😊
Conclusion
The more tests you write, the higher the chances that you’ll encounter at least some of these Selenium exceptions during your work. Hopefully, this article can help you understand them and deal with them 💪