When an error occurs in a test automation script, an exception is being thrown. 

Exceptions are used to signal that an error or exceptional situation has occurred.

When an exception is generated, the test method execution is stopped and the remaining code is ignored. 

A test automation method may throw an exception for many reasons, for instance if a web element cannot be found. 

For example, the following test method throws an exception on its 3rd line: 


@Test public void findSearchTextBox() 
{
 By incorrectSearchTextBoxLocator = By.xpath("//input[@id='globalQuery1']");  driver.get("http://www.vpl.ca"); 
 WebElement searchTextBox = driver.findElement(incorrectSearchTextBoxLocator);




The third line tries finding the searchTextBox element. 

Because the element's XPATH locator is incorrect, the code throws an exception with the following details: 


org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":"//input[@id='globalQuery1']"} Command duration or timeout: 31 milliseconds ........................................................................ *** Element info: {Using=xpath, value=//input[@id='globalQuery1']} Session ID: 38e9d95c-bee0-46e7-986e-1cbf9cbc3a79 Driver info: org.openqa.selenium.firefox.FirefoxDriver Capabilities [{platform=WINDOWS, acceptSslCerts=true, javascriptEnabled=true, cssSelectorsEnabled=true, databaseEnabled=true, browserName=firefox, handlesAlerts=true, ........................................................................ ........................................................................ at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:355) at ThrowExceptions.findSearchTextBox(ThrowExceptions.java:92) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 



The exception uses the NoSuchElementException exception class. 



CATCHING EXCEPTIONS 


The previous test method threw a NoSuchElementException exception when the searchTextBox element could not be found. 

The exception can be caught and handled with a try-catch block. 


@Test public void findSearchTextBox() 
{
 By incorrectSearchTextBoxLocator = By.xpath("//input[@id='globalQuery1']");
 driver.get("http://www.vpl.ca"); 
 try
 {
   WebElement searchField = driver.findElement(incorrectSearchTextBoxLocator);
 }
 catch(NoSuchElementException exception) 
 {
  System.out.println("search text box not found"); 
 } 



The NoSuchElementException parameter exception inside the catch-clause points to the exception thrown from the findSearchTextBox() method. 

If no exception is thrown by the code inside the try-block, the catch-block is simply ignored.

Because of the try/catch block, the test method does not fail any longer. 

Instead, it displays an error message in the Console and then it passes. 

The fact that the test method passes is obviously not correct since it just had a error in it.



FINALLY CLAUSE  


Instead of displaying a message in the console, we want the test method to fail and display a user friendly error message in the JUNIT view. 

We can do this in multiple ways.

1. by failing the test method in the catch() clause 

This is done using the fail() JUNIT method which is equivalent to an assertion that fails.

@Test public void findSearchTextBox() 
{
 By incorrectSearchTextBoxLocator = By.xpath("//input[@id='globalQuery1']");
 driver.get("http://www.vpl.ca"); 
 try
 {
  WebElement searchField = driver.findElement(incorrectSearchTextBoxLocator);
 }
 catch(NoSuchElementException ex) 
 {
   fail("search text box not found"); 
 } 



The test script fails properly with the following error: 


java.lang.AssertionError: search text box not found at org.junit.Assert.fail(Assert.java:88) at ThrowExceptions.findSearchTextBox(ThrowExceptions.java:160) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) .......................................................... 




2. by adding a finally clause to the try/catch block 

Lets change the test method by adding to the catch clause code that logs the exception details. 

@Test public void findSearchTextBox() throws IOException 
{
 By incorrectSearchTextBoxLocator = By.xpath("//input[@id='globalQuery1']");
 driver.get("http://www.vpl.ca"); 
 try
 {
   WebElement searchField = driver.findElement(incorrectSearchTextBoxLocator);
 }
 catch(NoSuchElementException exception) 
 { 
   openLog(); 
   addToLog(exception.getMessage()); 
   closeLog();  
   fail("search text box not found"); 
 } 




Lets assume that the addToLog() can generate an IOException. 

When the IOException is generated, the last 2 lines of the catch clause are ignored so the log is not closed. 

And the test method fails because of an exception that is not caught (IOException).

We can fix this by adding a finally clause to the try/catch block. 

The code inside the finally clause will always be executed, even if an exception is thrown from within the try or catch block. 

@Test public void findSearchTextBox() throws IOException 
{
  By incorrectSearchTextBoxLocator = By.xpath("//input[@id='globalQuery1']");
  driver.get("http://www.vpl.ca"); 
  try
  {
    WebElement searchField = driver.findElement(incorrectSearchTextBoxLocator);
  }
  catch(NoSuchElementException exception) 
  { 
    openLog(); 
    addToLog(exception.getMessage()); 
  } 
  finally 
  { 
    closeLog(); 
    fail("search text box not found"); 
  } 




In this case, the test script fails properly after the log is closed: 

java.lang.AssertionError: search text box not found at org.junit.Assert.fail(Assert.java:88) at ThrowExceptions.findSearchTextBox(ThrowExceptions.java:160) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) .......................................................... 



THROWING CUSTOM EXCEPTIONS 

So far, we failed the test script using the fail() JUNIT method. 

This works and provides the following details in the JUNIT view: 

But we could end the test method in a better way. 

First, we remove fail() from the finally clause. 

Then, since the addToLog() method throws an IOException exception, we catch this exception with a second try/catch block. 

And in the second catch clause, we re-throw the exception using a custom exception class:



@Test public void findSearchTextBox() throws IOException, ElementNotFoundException 
{
 By incorrectSearchTextBoxLocator = By.xpath("//input[@id='globalQuery1']");
 driver.get("http://www.vpl.ca"); 
 try
 {
   WebElement searchField = driver.findElement(incorrectSearchTextBoxLocator);
 }
 catch(NoSuchElementException exception) 
 { 
   openLog(); 
   try 
   { 
     addToLog(exception.getMessage()); 
   } 
   catch (IOException ex) 
   { 
     throw new ElementNotFoundException("search text box not found", exception); 
   } 
 } 
 finally 
 { 
   closeLog();
 } 



The test script still fails but we have more information displayed in the JUNIT view: 

ElementNotFoundException: search text box not found at ThrowExceptions.findSearchTextBox5(ThrowExceptions.java:181) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) .................................................................. Caused by: org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":"//input[@id='globalQuery1']"} Command duration or timeout: 37 milliseconds ................................................................... Session ID: 15f68d69-4623-4de3-865f-df78d1ae3136 Driver info: org.openqa.selenium.firefox.FirefoxDriver Capabilities [{platform=WINDOWS, acceptSslCerts=true, javascriptEnabled=true, cssSelectorsEnabled=true, databaseEnabled=true, browserName=firefox, handlesAlerts=true, nativeEvents=false, webStorageEnabled=true, rotatable=false, locationContextEnabled=true, applicationCacheEnabled=true, takesScreenshot=true, version=37.0}] ................................................................ at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:355) at ThrowExceptions.findSearchTextBox5(ThrowExceptions.java:170) ... 25 more Caused by: org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":"//input[@id='globalQuery1']"} 



SELENIUM COMMON EXCEPTIONS 

See below the list of common exceptions that can be generated by the Selenium WebDriver library.

selenium.common.exceptions.ElementNotSelectableException

Thrown when trying to select an unselectable element. exception 


selenium.common.exceptions.ElementNotVisibleException

Thrown when an element is present on the DOM, but it is not visible, and so is not able to be interacted with. 
Most commonly encountered when trying to click or read text of an element that is hidden from view. 

selenium.common.exceptions.ErrorInResponseException(response, msg)

Thrown when an error has occurred on the server side. 
This may happen when communicating with the firefox extension or the remote driver server. 

selenium.common.exceptions.InvalidCookieDomainException

Thrown when attempting to add a cookie under a different domain than the current URL.

selenium.common.exceptions.InvalidElementStateException
selenium.common.exceptions.InvalidSelectorException

Thrown when the selector which is used to find an element does not return a WebElement. 

Currently this only happens when the selector is an xpath expression and it is either syntactically invalid (i.e. it is not a xpath expression) or the expression does not select WebElements (e.g. “count(//input)”). 

selenium.common.exceptions.InvalidSwitchToTargetException

Thrown when frame or window target to be switched doesn’t exist. 

selenium.common.exceptions.NoAlertPresentException

Thrown when switching to no presented alert. 
This can be caused by calling an operation on the Alert() class when an alert is not yet on the screen. 

selenium.common.exceptions.NoSuchAttributeException

Thrown when the attribute of element could not be found. 
You may want to check if the attribute exists in the particular browser you are testing against. 
Some browsers may have different property names for the same property. (IE8’s .innerText vs. Firefox .textContent) 

selenium.common.exceptions.NoSuchElementException

Thrown when element could not be found. 

If you encounter this exception, you may want to check the following: Check your selector used in your find_by... Element may not yet be on the screen at the time of the find operation, (webpage is still loading) see selenium.webdriver.support.wait.WebDriverWait() for how to write a wait wrapper to wait for an element to appear. 

selenium.common.exceptions.NoSuchFrameException

Thrown when frame target to be switched doesn’t exist. 

selenium.common.exceptions.NoSuchWindowException

Thrown when window target to be switched doesn’t exist. 
To find the current set of active window handles, you can get a list of the active window handles in the following way: print driver.window_handles 

selenium.common.exceptions.StaleElementReferenceException

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: 

  1. You are no longer on the same page, or the page may have refreshed since the element was located. 
  2. The element may have been removed and re-added to the screen, since it was located. Such as an element being relocated. 
  3. Element may have been inside an iframe or another context which was refreshed. 


selenium.common.exceptions.TimeoutException

Thrown when a command does not complete in enough time. 

selenium.common.exceptions.UnableToSetCookieException

Thrown when a driver fails to set a cookie. 

selenium.common.exceptions.UnexpectedAlertPresentException

Thrown when an unexpected alert is appeared. 
Usually raised when when an expected modal is blocking webdriver form executing any more commands. 

selenium.common.exceptions.UnexpectedTagNameException

Thrown when a support class did not get an expected web element. 

selenium.common.exceptions.WebDriverException

Base webdriver exception.

See more details on this link.