1

I have a page that has elements that become visible as you scroll down. I am trying to execute a test to make sure the elements are not there until the scroll is to the bottom of the elements, but I can't seem to figure out how to pass the size from one call (elementIdSize()) to the scroll offset of the next call (scroll()). Admittedly my brain does not yet get the concept of "promises" past simple call chaining.

I tried something like this:

this.browser
    .setViewportSize({width: 1000, height: 600})
    .element(selector)
    .then(function(e) { 
        console.log('then element: ', e);
        element = e; 
    })
    .elementIdSize(element.id)
    .then(function(size) {
        console.log('Size: ', size);
    })
    .call(callback);

Which I was hoping would use the passed-in selector to get the element, set the element in the then(), then call elementIdSize() on the element's ID, but the var element is never set from the element() call, and the objects I am getting back don't seem to be what I am trying to get anyway. I feel this is some simple piece of knowledge I am missing here that will make all this "click".

I am using the APIs here for looking up the Webdriver calls, but the documentation doesn't give much details.

CodeChimp
  • 8,016
  • 5
  • 41
  • 79

1 Answers1

1

It's important to understand that all parameters will get resolved once you execute the chain. That means you can't change them anymore once you've executed the first command basically. In your example you set the value of the element variable in a promise callback. At the time you do that, elementIdSize already read the element variable (and probably threw an error).

The proper way to this is to execute commands that have arguments which get resolved at a later time in then or finish routines. You can also save commands in WebdriverIO by using action commands instead of raw protocol commands. So just use getSize instead of call element first and then call elementIdSize. That is the job of getSize ;-)

I am not sure what exactly you try to do but here is the code that should do the trick:

this.browser
    .setViewportSize({width: 1000, height: 600})
    .getElementSize(selector).then(function(size) { 
        console.log('size of element "' + selector + " is', size);
        // now as we have the size execute the scroll in a then callback
        return this.scroll(0, 600 + size.height);
    })
    // this get executed once we we did the scrolling since
    // the getSize promise is only then fulfilled once the promise
    // within the then function is resolved
    .isVisible(otherElem).should.be.eventually.be(true, 'element was visible after scrolling')
    .call(callback);

(As a side note: we already working on WebdriverIO v4 that will allow to execute commands synchronously, so no more promise headaches ;-))

ChristianB
  • 1,967
  • 14
  • 25
  • I didn't see a `getSize()` in the WebDriver API. Is there a better set of documentation somewhere, or is this one of those things where you simply have to dig through code and see what's there? – CodeChimp Sep 17 '15 at 11:12
  • dang I was wrong..the command is called getElementSize http://webdriver.io/api/property/getElementSize.html .. updated the code example – ChristianB Sep 17 '15 at 21:35