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

Distributed Load Testing with JMeter

Distributed Testing with JMeter When one JMeter client is not able to offer amount of threads required for load testing then distributed testing is used. In distributed testing - One instance of JMeter client can control number of JMeter instances and collect data from them Test plan does not need to be copied to each server, the client sends it to all servers note - JMeter will run all the threads on all the servers, hence 100 threads on 5 JMeter server would pump 500 threads in total. If many server instances are used, the client JMeter can become overloaded and so the client network connection. This has been improved in latest versions of JMeter by switching to Stripped modes, but you should always check that your client is not overloaded When Client (master) and Server (slave) nodes are on same network (no SSH required) Configure Client Node Herein client is referred as the machine controlling test execution on other JMeter nodes. This is also referred

Appium and android mobile app automation

Next appium and Android mobile app automation video tutoria l is live. If you are new to appium then please check - appium-tutorial This video tutorial covers - Start vysor (Just for this session and not mobile automation :)) Start appium and start appium inspector Desired Capabilities platformName - Android deviceName - L2N0219828001013 (as seen on "adb devices") Saved Capability Sets Start Session Scan app elements using appium inspector Get appPackage and appActivity using "APK info" app Install "APK info" app and open app whose appPackage and appActivity are required i.e. calculator Check top section of app icon com.android.calculator2 is app package com.android.calculator2.Calculator is app activity testng.xml file settings for running Android app tests Test details com.seleniumtests.tests.mobile.AndroidAppTest and CalculatorScreen class View beautiful STF test report  

Verify email confirmation using Selenium

Note: If you are new to java and selenium then start with selenium java training videos .     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