16

I am using nightwatch for e2etesting my app. One of the tests fails because it cannot scroll to the element that it is testing I suspect. Question do I need to scroll or is there another way to do it? This is the element I am testing:

 return this.waitForElementVisible('#myElement', 4000) //wait for it to be visible
       .assert.visible('#myElement')
       .click('#myElement')

The element is at the top of the page but the testrunner has scrolled a bit down the page and it is not visible in the screenshot. How can I if need be scroll to this element? or : How can I test this element?

bier hier
  • 13,692
  • 28
  • 72
  • 140

5 Answers5

11

There is a native method in nightwatch to get elements into view. (In general elements should always be scrolled into view from nightwatch/selenium. But if you want to do that by hand you can use getLocationInView():

return this.getLocationInView('#myElement')
   .assert.visible('#myElement')
   .click('#myElement')

Nightwatch also supports doing this directly via the Webdriver Protocol using moveTo() without any abstraction. In that case it would look more like:

const self = this;
return this.api.element('#myElement', (res) => {
  self.api.moveTo(res.value.ELEMENT, 0, 0, () => {
    self.assert.visible('#myElement');
    self.click('#myElement');
  })
});

(this was just written from top of my head, hope I didn't make a mistake)

But what could help in your case is changing seleniums element scroll behaviour in the config like:

firefox: {
  desiredCapabilities: {
    browserName: 'firefox',
    javascriptEnabled: true,
    acceptSslCerts: true,
    elementScrollBehavior: 1
  }
}

Default is 0 -> Elements are scrolled to top of page

elementScrollBavior 1 -> Elements are scrolled to bottom of page

Karl Adler
  • 12,243
  • 9
  • 55
  • 77
TheBay0r
  • 335
  • 2
  • 9
  • 1
    It would be helpful to mention that the native method is http://nightwatchjs.org/api/moveTo.html – Mike Davlantes Feb 13 '18 at 01:47
  • @MikeDavlantes Thanks for you input. I tried to extend my description, hope I remembered how to use it in nightwatch correctly :'D – TheBay0r Feb 13 '18 at 14:07
8

you can use the moveToElement()

simply use it like this

browser.
.moveToElement(#myElement, 10, 10)
.waitForElementVisible(#myElement, 500)
OliverAssad
  • 832
  • 10
  • 8
6

Remember that:

.execute() inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous and the result of evaluating the script is returned to the client.

and

Window.scrollTo() Scrolls to a particular set of coordinates in the document.

Your test will look like this:

module.exports = {
    'your-test': function (browser) {
        browser
            .url("http://example.com")
            .waitForElementPresent('body', 2000, "Be sure that the page is loaded")
            .execute('scrollTo(x, y)')
            .yourFirstAssertionHere()
            .yourSecondAssertionHere()
            ...
            .yourLastAssertionHere()
            .end()
    }
};
  • If you know that the element with id myElement is at the top of the page you can just change x and y by 0 (just to be sure that you'll scroll to the top of the page).

  • If you need to get the exact values of x and y, you can use: getLocationInView() like this:

    module.exports = { 'your-test': function (browser) { browser .url("http://example.com") .waitForElementPresent('body', 2000, "Be sure that the page is loaded") .getLocationInView("#myElement", function(result) { //The x value will be: result.value.x //The y value will be: result.value.y }); } }

    .getLocationInView(): Determine an element's location on the screen once it has been scrolled into view... Returns The X and Y coordinates for the element on the page.

Hope this help you.

Ala Eddine JEBALI
  • 4,649
  • 3
  • 35
  • 48
3

You can execute this javascript with execute document.querySelector({{ACTUAL_SELECTOR}}).scrollIntoView();

  • `scrollIntoView()` is compatible in all major browsers. https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView#Browser_compatibility – lasec0203 Dec 31 '17 at 22:14
1

In addition an example I used as page object command (be_expand) where my selector was an xpath already used in a element (@be_click):

    be_expand() {
        this.api.execute(function(xpath) {
            function getElementByXpath(path) {
                return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
            }
            var res = getElementByXpath(xpath);
            res.scrollIntoView(true);
        }, [this.elements.be_click.selector]);
        this.assert.visible('@be_click');
        this.click('@be_click');
        return this;
    }