Tuesday, December 12Be an Automation Engineer

Javascript Executor in protractor

Most of the time we interact with web elements using selenium internal methods like click, sendKeys, select etc..

Why we need javascript executor?
Selenium is written in the way that it should not interact hidden elements on the webpage. Real user can not interact with the hidden elements in the web page so selenium guys are also not allowing to interact with hidden element with their operative methods which I have mentioned above.

But for an automation engineer it is required some times to interact with hidden elements that is the place where javascriptExecutor can help a lot.

Protractor is also dependent on Selenium, so protractor also has same limitations when it comes to interact with hidden elements. So protractor also supports javascript executor.

Basically javascript executor "executes javascript within the browser".

There are two methods available in protractor to execute javascript.

  • browser.executeScript – Usually we use executeScript to run normal javascript or JQuery code within the browser
  • browser.executeAsyncScript – We use executeAsyncScript to execute ajax calls or any javascript code with callback functions.

1. browser.executeScript(javascriptString, arguments…)

browser.executeScript will take one or more arguments. The first argument should be raw javascript code. From second argument onwards we can pass protractor elements.

Lets take a look at few scenarios where we can use executeScript:

1. Finding element and click on it

We can use document.getElementById('identifier') to identify an element and .click() to simulate click operation.

browser.executeScript("document.getElementById('identifier1').click()");

2. Pass protractor element to javascript code and click on it

We can use arguments[0].click() to simulate click operation.

var element = element(by.linkText('webdriverjs'));
browser.executeScript("arguments[0].click()",element);

3. Hover on an element

Use the below javascript code to hover on an element. We can also hover on an element using actions object. We will explain about it in another post.

var element = element(by.css('.sf-with-ul'));
browser.executeScript("if(document.createEvent){"+
       "var hoverEventObj = document.createEvent('MouseEvents');"+
       "hoverEventObj.initEvent('mouseover',true,false);"+
       "arguments[0].dispatchEvent(hoverEventObj);"+
       "}"+
       "else if(document.createEventObject){"+
       "arguments[0].fireEvent('onmouseover');"+
       "}",about);

Complete example program to hover on a menu and click on a menu item using executeScript().

describe('JavascriptExecutor', function () {
    it('Hove and click', function () {
        browser.ignoreSynchronization = true;
        browser.get("http://webdriverjs.com");
        var about = element(by.css('.sf-with-ul'));
        var aboutUs = element(by.xpath("//a[@href='http://www.webdriverjs.com/about/']"));
        browser.executeScript("if(document.createEvent){" +
            "var hoverEventObj = document.createEvent('MouseEvents');" +
            "hoverEventObj.initEvent('mouseover',true,false);" +
            "arguments[0].dispatchEvent(hoverEventObj);" +
            "}" +
            "else if(document.createEventObject){" +
            "arguments[0].fireEvent('onmouseover');" +
            "}arguments[1].click();", about, aboutUs);
    });
});

4. Scroll to view the element and click

Some times we may need to bring element into visible area and they perform action it. Use the below javascript code to move to interacting element.

browser.executeScript("arguments[0].scrollIntoView();",element);

Complete Example:

describe('JavascriptExecutor', function () {
    it('Scroll into view and click', function () {
        browser.ignoreSynchronization = true;
        browser.get("http://webdriverjs.com");
        var home_footer = element(by.css('.vl-footer-2 ul li:nth-child(1) a'));
        browser.executeScript("arguments[0].scrollIntoView();arguments[1].click();", home_footer, home_footer);
    });
});

5. Get text of an element using JQuery

Before explaining about getting text. We need to know that executeScript returns a promise. we can get the response using .then.

browser.executeScript("javascriptCode").then(function(result){
//Your code here
});

We can get text of an element using element.text() in Jquery. Have a look at the below script.

describe('JavascriptExecutor', function () {
    it('Get text', function () {
        browser.ignoreSynchronization = true;
        browser.get("http://angularjs.org");
        browser.executeScript("return $('.dropdown-toggle').eq(0).text();").then(function(text){
            console.log(text);
        });
    });
});

2. browser.executeAsyncScript(AsynchronousjavascriptString, arguments…)

executeAsyncScript is used to execute any asynchronous javascript code in protractor tests.

Click here to know about executeAsyncScript in detail with explanation and examples.

Happy Testing!!!

  • KAVITHA KRISHNAKUMAR

    i am exactly looking for this for past 3 days..thank you so much…it worked as a charm!

    • Vijay

      I am happy that the post helped you to solve the problem. Happy Testing!!!

  • Anuj Chaudhary

    After using browser.executeScript(“javascriptCode”).then(function(result){
    console.log(‘Value of result is’+result);
    }); I a m getting output as “Value of result is undefined “

    • Vijay Daram

      Hi Anuj,

      Sorry for the late reply. Actually, you should replace javascriptCode string with your actual javascript code. I have given an example. Please try that.

  • SD

    I have to scroll down on HandsonTable application

    http://jsfiddle.net/begbprme/

    The grid looks this way.. as shown in the above link..

    https://docs.handsontable.com/0.15.0-beta3/demo-scrollbars.html

    Is it possible with this execute Script ?

    • Vijay Daram

      Hi vijayendrajoshi,

      It is very much possible to scroll to a particular element in the table.

      var yourElement = element(by.css(‘tr:nth-child(50) td:nth-child(10)’));

      browser.executeScript(“arguments[0].scrollIntoView();”,yourElement);

      //The above statement will scroll to the element provided

      If you want scroll by fixed size form current position you can use window.scrollBy(horizontalLength, verticalLength). Means if you say
      1. window.scrollBy(100,0) — moves horizontally BY 100px.
      2. window.scrollBy(0,100) — moves down by 100px from current position
      3. window.scrollBy(-100,0) — moves back horizontally by 100px
      4. window.scrollBy(0,-100) — moves up by 100px

      scrollBy reference: https://www.w3schools.com/jsref/met_win_scrollby.asp

      There is one more scroll option which is window.scrollTo(X-coordinate, Y-coordinate).
      1. window.scrollTo(100,100) — Moved to 100 X 100 pixel position

      scrollTo reference: https://www.w3schools.com/jsref/met_win_scrollto.asp

      There is one more way to scroll to element using it’s offset value. You can find it in https://stackoverflow.com/questions/22855341/how-to-scroll-table-to-particular-tr-programmatically

      • SD

        Can this be executed inside JavascriptExecutor statement Selenium Webdriver (Java)?

        Because I need to scroll down till the end of the grid .. I am not very familiar with Javascript.

    • Vijay Daram

      Absolutely. Go to below link
      http://jsfiddle.net/begbprme/1/

      window.scrollTo(0,container.offsetTop+container.offsetHeight);

      The above line will scroll to end of the table.

      Your code will look like below

      WebElement element = driver.findElement(By.id(“example1”));
      JavascriptExecutor js = (JavascriptExecutor) driver;
      js.executeScript(“var container = arguments[0];window.scrollTo(0,container.offsetTop+container.offsetHeight);
      “,element);

      • SD

        Thank you Vijay Will try. This blog is really good.

      • SD

        public void scrollDown() throws InterruptedException {
        // TODO Auto-generated method stub

        WebElement ele = driver.findElement(By.xpath(“.//*[@id=’dgrid’]”));
        JavascriptExecutor js =(JavascriptExecutor)driver;

        int elementOffsetTop = Integer.parseInt(js.executeScript(“return Math.round($(arguments[0]).offset().top)”, ele).toString());

        System.out.println(elementOffsetTop);

        int elementOffSetHeight = Integer.parseInt(js.executeScript(“return Math.round($(arguments[0]).offset().height)”, ele).toString());

        System.out.println(elementOffSetHeight);

        js.executeScript(“window.scrollTo(0,elementOffsetTop+elementOffSetHeight)”,ele);
        }

        I tried this but i am encountering NullPointerException

        Also can I execute ($(window).height() – this.$el.offset().top) – 65
        this.$el is grid area

        in Javascript Executor

      • SD

        Basically I have a HandsonTable Grid which has say 2000 rows of data, so I want to scroll down till the end of the element.

        Is it possible..

        I tried the same but could not suceed.

%d bloggers like this: