Skip to main content

Catching java script errors with WebDriver

The topic of catching java script errors with webdriver has been discussed time and again. This was also a hot topic during the days of Selenium RC. There have been quite a few approaches to catch java script errors with WebDriver, like  -


  • Adding extra script to web page and using JavascriptExecutor to retrieve them. I won’t recommend this approach as it requires application code to be changed to be able to test it


  • Using Firefox extension to catch the java script errors


  • And of late, there has been a beta feature available in WebDriver APIs which lets you capture browser console log. Using this you can capture browser level logs. I like this approach as it does not require application code to be modified or adding extra extension to a browser. I experimented this approach with FF 47.0.1, Chrome 50 and Selenium 2.53.1 and worked like a charm.


Let’s consider blog - https://rationaleemotions.wordpress.com/ which has a 404 error and it is visible on console. (By the very useful blog, you may like to follow it if not already :)) -


Screenshot from 2016-07-11 16:54:06.png


Browser console is also the place where javascript error would logged. Let’s catch and print this error on Chrome. Here is a sample code to do this -


package com.seleniumtests.tests;


import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.testng.annotations.Test;


public class JavaScriptErrorTest {
  WebDriver webDriver;
  LogEntries logEntries;


  public static void logConsoleEntries (LogEntries logEntries) {
      for (LogEntry logEntry : logEntries) {
          System.out.println(String.valueOf(" Time Stamp: " + logEntry.getTimestamp()));
          System.out.println(String.valueOf(" Log Level: " + logEntry.getLevel()));
          System.out.println(String.valueOf(" Log Message: " + logEntry.getMessage()));
      }
  }


  @Test
  public void catchJavaScriptError() throws Exception {
      String url = "https://rationaleemotions.wordpress.com/";
      System.setProperty("webdriver.chrome.driver",
              "chromedriver");
      webDriver = new ChromeDriver();
      webDriver.get(url);
      logEntries = webDriver.manage().logs().get(LogType.BROWSER);
      logConsoleEntries(logEntries);
      webDriver.quit();
  }
}


And following message is printed -


Time Stamp: 1468249126412 Log Level: SEVERE Log Message: https://s0.wp.com/wp-content/themes/pub/themorningafter/inc/style-wpcom.css?ver=4.5.3-20160628 0:0 Failed to load resource: the server responded with a status of 404 ()


You can build your assert statement around log.


Let’s see an example of javascript error now and this time with Firefox browser. We will consider website - http://www.softwaretestingtricks.com/ for testing and it seems to have quite a few java scripts errors. Lets update our test to use Firefox driver -


@Test
public void catchJavaScriptError() throws Exception {
  String url = "http://www.softwaretestingtricks.com/";
  webDriver = new FirefoxDriver();
  webDriver.get(url);
  logEntries = webDriver.manage().logs().get(LogType.BROWSER);
  logConsoleEntries(logEntries);
  webDriver.quit();
}


This would print lots of logs and one log would be a js error -


Time Stamp: 1468310250086 Log Level: SEVERE Log Message: TypeError: $(...).flexslider is not a function


If you want to restrict the amount of logs then you can restrict the logs to a given level when instantiating your driver -


DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
LoggingPreferences loggingPreferences = new LoggingPreferences();
loggingPreferences.enable(LogType.BROWSER, Level.SEVERE);
desiredCapabilities.setCapability(CapabilityType.LOGGING_PREFS, loggingPreferences);
webDriver = new FirefoxDriver(desiredCapabilities);


And now you would only have sever errors printed. I am reluctant to use this method of restricting amount of logs as I see different results in chrome and firefox. For example logging SEVERE errors reported following on chrome -


Time Stamp: 1468311387330 Log Level: SEVERE Log Message: http://reportage.wp-theme.pro/wp-content/themes/reportage/images/social/facebook.png 0:0 Failed to load resource: net::ERR_NAME_NOT_RESOLVED Time Stamp: 1468311387331 Log Level: SEVERE Log Message: http://reportage.wp-theme.pro/wp-content/themes/reportage/images/social/twitter.png 0:0 Failed to load resource: net::ERR_NAME_NOT_RESOLVED Time Stamp: 1468311387331 Log Level: SEVERE Log Message: http://reportage.wp-theme.pro/wp-content/themes/reportage/images/social/vimeo.png 0:0 Failed to load resource: net::ERR_NAME_NOT_RESOLVED Time Stamp: 1468311387331 Log Level: SEVERE Log Message: http://reportage.wp-theme.pro/wp-content/themes/reportage/images/social/linkedin.png 0:0 Failed to load resource: net::ERR_NAME_NOT_RESOLVED Time Stamp: 1468311387331 Log Level: SEVERE Log Message: http://reportage.wp-theme.pro/wp-content/themes/reportage/images/social/googleplus.png 0:0 Failed to load resource: net::ERR_NAME_NOT_RESOLVED Time Stamp: 1468311387584 Log Level: SEVERE Log Message: javascript 1:187 Uncaught TypeError: Cannot read property 'title' of undefined Time Stamp: 1468311387859 Log Level: SEVERE Log Message: javascript 1:4571 Uncaught TypeError: Cannot read property '0' of undefined


And following on firefox -


Time Stamp: 1468311872314 Log Level: SEVERE Log Message: TypeError: entry is undefined Time Stamp: 1468311872464 Log Level: SEVERE Log Message: TypeError: json.feed.entry is undefined Time Stamp: 1468311873221 Log Level: SEVERE Log Message: TypeError: json.feed.entry is undefined Time Stamp: 1468311873969 Log Level: SEVERE Log Message: SyntaxError: missing ) after argument list Time Stamp: 1468311876268 Log Level: SEVERE Log Message: TypeError: $(...).flexslider is not a function


Hence I prefer to not restrict the amount the log, print all the log and parse log for possible errors.


Form the above example, it is clear that we can capture logs for both Firefox and Chrome browser. But beware that this function is yet beta (at the time of writing this post) and you may encounter unexpected errors.

But collecting browser logs for javascript errors on each event would result in lots of extra code and corresponding checks. What if we could automate javascript error check which takes place on each test method? I can think of listener doing this for us. What do you think?

Popular posts from this blog

Using chrome console to test xPath and css selectors

Since the advent of selenium there have been many plugin to test xPath / css selectors but you don’t need any of them if you have chrome browser. Using Chrome console you can test both xPath and css selectors. Launch website to be tested in chrome browser and hit F-12 and you would see chrome console opened in lower pane of application - Hit escape key and console would open another pane to write element locators - And now you can start writing xPath or css selectors in chrome console and test them - The syntax for writing css id - $$(“ ”) And hit the enter key. If your expression is right then html snippet of the application element corresponding to the css selector would be displayed - If you mouse over the html snippet in chrome console then it would highlight the corresponding element in application - If you want to clean console of previously written element selectors then just hit ctrl+L keys and chrome console would be empty again. Pro

Verify email confirmation using Selenium

Email confirmation seems to be integral part of any registration process. I came across an application which lets you provide your email address. You can follow the sign up link in you mail and then complete the registration process. Lets consider we provide GMail address for it. Now if were to use only Selenium then we would have to follow following steps - Launch GMail using Selenium; Some how search for new mail in the list of available mails; Some how click on it; Parse the mail message; Get the registration link; Follow up with registration process What do you think of an approach in which you can

Return only first or last element from webelements collection

We often come across situation when there are multiple elements on a page and we probably like to exercise only a few of them using selenium webdriver. May be just first and last element. For example on a search result page we may like to click on only first and last link and not all. This is when Iterables API comes handy. (By the way I am assuming that you have already completed watching selenium training videos :)). Once we have collection of web element then we can use Iterables to get only first or last element as following - Consider that we fetch collection of element as - List< WebElement > webElements = getDriver().findElements(By. id ( "htmlID" ));   Now we can get the first web element from this collection as -  WebElement firstElement = Iterables. getFirst (webElements,  getDriver().findElement(By. id ( "defaultElement" )));   Herein second argument -   (getDriver().findElement(By. id ( "defaultElement" )))    in the me