JavaScript Error Handling with Javascriptexecutor in Selenium

Javascript error handling is generally painful in selenium webdriver test automation projects. In some cases in test automation run, we need to handle javascript alert and javascript notification messages. Some of the javascript alerts visible only limited time such as 5 seconds. Then, they disappear. If we are using built-in selenium webdriver wait features, we may have flaky test executions. Thus, we should wait and handle these kinds of javascript alerts by using javascriptexecutor in selenium and custom javascript codes.

Hi all,

In this article, I will share with you a javascriptexecutor method to handle javascript notification messages in your test automation projects. Sometimes we deal with notification messages for a limited period of time. They appear and then disappear. In these kinds of circumstances, selenium webdriver visibility or presence features don’t work so resilient. It is better to make the notification handling more robust with javascriptexecutor and our custom javascript codes. Let’s take a look an example and then try to create a solution together.

Our test website is https://www.odamax.com/en/ it is one of the leading tourism websites. When we click the Log in link, we see the login screen and when we click the login button, we see the red error message on right top of the browser. This error message is visible only 4-5 seconds and we have a limited time to handle this error message in our automation code. First, Let’s look at what happens in the DOM when we click the login button. Now, open the developer tools of the chrome and then click the login button. When you see the error message, click it with the inspector. When we click the login button, there is a line appears in the DOM which has a class name as “ns-box ns-bar ns-effect-slidetop ns-type-error ns-show”. It is visible for a limited period of time.

javascript error handling

When I use Selenium Webdriver’s visibility expected condition, sometimes I get a failure because time is elapsing before checking the visibility of the alert message. Javascript error handling is needed to get the alert message and make the tests more robust. Thus, I changed my wait tactic as follows:

  • First, I click the login button.
  • Then, I wait for the presence of element. It checks that the element is available in the DOM.
  • After that, I will write a JavaScript code to get the error code.
  • Then, I write an assertion to check the error message as expected.

Now, let’s check what is happening when I click the login button on the console. As you see below screenshots, I got an XHR error message as “Your e-mail address or password doesn’t match any account.”

javascript error message

javascriptexecutor selenium

Then, I wrote the below Javascript code to get this error message for javascript error handling operation.

window.getError = {message : null,
                   init : function(){
                   var _self = this; 
                   $( document ).ajaxError(function(xhr, response) {
                   return _self.message =  $(response.responseText).text().replace('Error', '')
                   });
                   }
                   }

With above code snippet, first, we should call init function to assign XHR error response to message variable and also we replace “Error” text with “” to remove it. Thus, we will get only “Your e-mail address or password doesn’t match any account.” error message.

We can test this on the console. First, open a new browser and open the console and execute the above code.

Then, run the “window.getError.init()” function to execute the function.

Then, try to login with empty credentials and see the error message.

Then, run the “window.getError.message” command to see the error message. This is shown in below screenshot.

Now, we can write our test automation code in combination with the javascript code. I wrote inline comments. If you don’t understand some points in the code, please write a comment about your javascript error handling problems.

JavaScript Error Handling Example Code

package javascriptexecutor;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class OdamaxLoginTest {
    public WebDriver driver;
    public WebDriverWait wait;
    public JavascriptExecutor jsExec;
    private String url = "https://www.odamax.com/en/";

    //Setup Driver
    @BeforeClass
    public void setupTest() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver,10);
        driver.navigate().to(url);
        driver.manage().window().maximize();
        jsExec =(JavascriptExecutor)driver;
        //Run the JavascriptExecutor to define the getError in global window. It will be persistent in this way.
        jsExec.executeScript("window.getError = {\n" +
                "message : null,\n" +
                "init : function(){\n" +
                "\n" +
                "var _self = this; \n" +
                "\n" +
                "$( document ).ajaxError(function(xhr, response) {\n" +
                "\n" +
                "\treturn _self.message =  $(response.responseText).text().replace('Error', '')\n" +
                "\n" +
                "});\n" +
                "}\n" +
                "}");
        //Run the init function
        jsExec.executeScript("window.getError.init()");
    }

    @Test
    public void T01_returnTest(){
        //Go to Login
        driver.findElement(By.cssSelector("li:nth-of-type(2) .hidden-xs")).click();

        //Wait Visibility of Login Button and click it
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".btn.btn-info.v")));
        driver.findElement(By.cssSelector(".btn.btn-info.v")).click();

        //Wait presence of error message (I will use just "ns-box" class
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.ns-box")));

        //Then get the XHR error test with JavaScriptExecutor
        Object errorTextJS = jsExec.executeScript("return window.getError.message");

        //And do the assertion
        Assert.assertEquals(errorTextJS.toString(), "Your e-mail address or password doesn't match any account.");
    }

    //Close Driver
    @AfterClass
    public void quitDriver() {
        driver.quit();
    }
}

In this way, our tests will be more robust. We learned javascript error handling in selenium webdriver projects.

You can find another JavaScriptExecutor Tips and Trick here: http://www.swtestacademy.com/selenium-javascriptexecutor/

[fusion_widget_area name=”avada-custom-sidebar-seleniumwidget” title_size=”” title_color=”” background_color=”” padding_top=”” padding_right=”” padding_bottom=”” padding_left=”” hide_on_mobile=”small-visibility,medium-visibility,large-visibility” class=”” id=””][/fusion_widget_area]

Thanks.
-Onur

4 thoughts on “JavaScript Error Handling with Javascriptexecutor in Selenium”

  1. Using the same concept, how can I capture all network traffic xhr requests with all the requests and its corresponding response.
    I have a scenario where I login to a web application, navigate to a page and then hit a POST request and then continue with the same session using selenium
    My app creates a unique authorization token each time a user logs in. So I need authorization token generated by selenium session, then use its authorization token for the POST request and then continue with selenium again ?

    BTW love your blogs and guest blogs. Your work has has helped me immensely with frameworks and Allure and increased my knowledge
    Thanks.

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.