Exceptions are basically abnormal/unexpected conditions that may occur while running code/test.
These exceptions may disrupt the execution, but we can handle them using java exception handling features.
Examples of some exception are, divide any number by zero, file/object not found, accessing array elements beyond it’s size etc…
For almost all kind of abnormal situations that may occur in a program, Java has classes for each of those expected exceptions.
To all those expected exception classes, Exception is the parent class.
An Exception object is created by the code at the point where the error condition arises, this Exception object holds all kind of exception that are declared in java and each of this exception object has details of exceptional condition and also includes a full stack trace for debugging.
(A stack trace is the list of all the methods called, and the order in which they were called to reach the point where the exception was thrown.)
By taking these above exception details we can handle the exception (using try catch finally or throw keyword, will discuss later…)
Let’s see the selenium exceptions –
WebDriverException has all the child exceptions which is listed under this below link –
https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/WebDriverException.html
To know description of each exceptions, refer below link –
https://www.selenium.dev/selenium/docs/api/py/common/selenium.common.exceptions.html
Let’s see most common selenium exceptions in detail, when they occur and how to handle them
NoSuchElementException
This exception occurs when the element with given criteria not found or the element is not present on DOM by the time it’s identified.
public class ExceptionTest { WebDriver driver; @Test public void Test1() throws InterruptedException { WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(); driver.get("https://qavbox.github.io/demo/signup/"); WebElement el = driver.findElement(By.id("username1")); //wrong id nosuchelementexception el.click(); }
This above code will throw NoSuchElementException, as id username1 is wrong.
To handle this, either we need to provide some wait time, so the element will be present on DOM or update the locator value to correct one.
Note – you can use implicit or explicit wait to handle this, so selenium will wait till it appears on DOM.
WebDriverException or NoSuchSessionException
Occurs when using the driver instance after the driver.quit() or driver.close()
@Test public void Test1() throws InterruptedException { WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(); driver.get("https://qavbox.github.io/demo/signup/"); driver.close(); driver.findElement(By.id("username")).sendKeys("someValue"); }
Here we are using the driver instance after the driver is closed, so the exception will appear.
So when these kind of exception occurs, make sure you shouldn’t use driver after it’s closed.
NoAlertFoundExpection
This exception occurs when you are trying to handle an alert before it appears.
If this exception comes, then make sure you wait for the alert to present, and then handle the alert [accept or dismiss]
driver.switchTo().alert().accept();
NoSuchWindowException
driver.switchTo().window("something");
This exception occurs when you are trying to switch to window or pop up before it appears.
If this exception comes, then make sure a new window pops up and then handle or switch to the window.
NoSuchFrameException
This exception occurs when there is no frame on browser, but we are trying to switch to the frame or switching to wrong frame [wrong frame index / frame id]
Example –
@Test public void NoSuchFrame(){ WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(); driver.get("https://qavbox.github.io/demo/iframes/"); System.out.println(driver.getTitle()); //driver.switchTo().frame(0); // driver.switchTo().frame(2); //on this screen, we have only 2 frames, but switching to 3rd one which is not present System.out.println(driver.findElement(By.id("frametext")).getText()); driver.switchTo().defaultContent(); driver.findElement(By.linkText("Blogger")).isDisplayed(); driver.quit(); }
Output –
org.openqa.selenium.NoSuchFrameException: no such frame
Throws exception, as we are switching to 3rd frame where as we have only 2 frames on the screen.
if you try to switch to frame(0) or frame(1), test will pass.
ElementNotInteractableException
This exception occurs when we are performing action on any element that is disabled.
Example – on the site https://qavbox.github.io/demo/signup/
when you try to send text to text box – Fax
driver.findElement(By.id("fax")).sendKeys("456789");
StaleElementException
Thrown when a reference to an element is now “stale”.
Stale means the element no longer appears on the DOM of the page.Possible causes of StaleElementReferenceException include, but not limited to:
- You are no longer on the same page, or the page may have refreshed since the element was located.
- The element may have been removed and re-added to the screen, since it was located. Such as an element being relocated. This can happen typically with a javascript framework when values are updated and the node is rebuilt.
- Element may have been inside an iframe or another context which was refreshed.
Let’s try to recreate this exception, we will 1st identify the element, then refresh the page and then perform action on the element.
@Test public void Test11() throws InterruptedException { WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(); driver.get("https://qavbox.github.io/demo/signup/"); WebElement element = driver.findElement(By.id("username")); driver.navigate().refresh(); element.sendKeys("someValue"); Thread.sleep(1000); }
Output –
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
Element is identified properly, but then we refresh the page, means it will take some time to load the html DOM, so the reference to that element on DOM got changed, even the element is present it will throw exception.
so when the page is refreshed or DOM changed, we have to identify the element again.
Let’s see how to avoid this exception
@Test public void Test11() throws InterruptedException { WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(); driver.get("https://qavbox.github.io/demo/signup/"); WebElement element = driver.findElement(By.id("username")); driver.navigate().refresh(); Thread.sleep(2000); element = driver.findElement(By.id("username")); element.sendKeys("someValue"); Thread.sleep(1000); }
After the page is refreshed or if we know the DOM is changed, then better to wait for sometime so DOM will be loaded, then identify the element and use it, this is what we have done to above code and it will not throw exception.
Another way is to identify the element each time we want to perform some operation instead of identify the element and use it later.
@Test public void Test11() throws InterruptedException { WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(); driver.get("https://qavbox.github.io/demo/signup/"); //WebElement element = driver.findElement(By.id("username")); driver.navigate().refresh(); //element.sendKeys("someValue"); type(driver, By.id("username"), "somevalue"); Thread.sleep(1000); } public void type(WebDriver driver, By by, String Text){ WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5)); wait.until(ExpectedConditions.presenceOfElementLocated(by)).sendKeys(Text); }
Like we have implemented type(), we can have all element methods like click(), getText etc..
Hope this helps!
If you are interested about assertions, refer Assert – Hard & Soft Asserts