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

How can you save resources when instantiaing driver?

I asked on my previous post about what was wrong in instantiating driver on set up method? And here is the solution video on my YouTube channel (After 5 years of gap I finally added new video tutorial :)) The solution described on video tutorial uses following set up - public class BaseClassOnDemandDriverSetup { private WebDriver driver ; @BeforeMethod public void setupTest () { // Any other set up goes here } @AfterMethod public void teardown () { if ( driver != null ) { driver .quit() ; } } public WebDriver getDriver () { if ( driver == null ) { WebDriverManager. chromedriver ().setup() ; driver = new ChromeDriver() ; } return driver ; } }

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

Using xPath to reach parent of an element

Well, I am big fan of css locator my self there are times when css locators don't fit requirement. One such requirement is when you want to navigate to parent element of an element and may be parent of parent and even more. Unfortunately css locators don't provide any mechanism to navigate to parent of an element. See this for more. Of late I came across a scenario when I wanted to click on a link depending upon the text in a text box. Herein parent of text box and parent of link were at the same location. More over there could have been many such combinations in application. Fortunately I just need to pick first such instance and Web Driver any way considers only first instance when multiple locators are found matching an element. Element in question is in following html - Here I need to click on highlighted anchor on the basis of input element (which is also highlighted in image) Herein first I need to reach div parent (class = 'left couponmainarea