Nadin Nadin - 3 months ago 99
Javascript Question

Protractor: How to scroll a few times in ui-grid

I am trying to write function which scrolls to a latter row in a table. The ui-grid has infinite scrolling through the rows.

I have found answers that explain scrolling to a last element, but my table has many hidden elements after an one scrolling and I need a solution to scroll through the full grid. (Protractor: Scrolling a table and testing for infinite scroll)

The solution: How to getText from all rows & columns in an infinite scrolling ng-grid using protractor - doesn't help me

My grid is:



<div class="ui-grid-viewport ng-isolate-scope" ng-style="colContainer.getViewportStyle()" role="rowgroup" ui-grid-viewport="" style="overflow-x: hidden; overflow-y: scroll;">
<div class="ui-grid-canvas">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index" style="margin-top: 630px;">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index" style="">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
<div class="ui-grid-row ng-scope" ng-style="Viewport.rowStyle(rowRenderIndex)" ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index">
</div>
</div>





According to the case, there are 24 rows visible in DOM and 65 hidden.

My algorithm is "to scroll" while a scrolled distance between top element and "last" element won't be changed (and collect all necessary text), but the WHILE body does not work properly, it scrolls one time only:

this.tableContent = function tableContent() {

//for loop
var start = {};
var distance = {};
var lastRow = {};
var div = element(by.css('div.ui-grid-viewport'));
lastRow.elm = element.all(by.css('div.ui-grid-row')).last();

browser.executeScript("return arguments[0].scrollTop;", lastRow.elm.getWebElement()).then(function (dst) {
return distance.value = dst;
}).then(function () {


while (start.value !== distance.value) {
//console.log('The distance before scrolling ' + dst);


start.value = distance.value;

//scroll
browser.executeScript("arguments[0].scrollIntoView();", lastRow.elm.getWebElement());
browser.wait(protractor.ExpectedConditions.presenceOf(element.all(by.css('div.ui-grid-row')).last()), 1000);

lastRow.elm = element.all(by.css('div.ui-grid-row')).last();


browser.executeScript("return arguments[0].scrollTop;", div.getWebElement()).then(function (dst) {

//console.log('the distance after scroll is ' + dst)
return distance.value = dst;

}).then(function () {

console.log('the distance is ' + distance.value);
console.log('The start.value is ' + start.value);

});


}


});


Any help or idea are highly appreciated,

thanks in advance.

Answer

OK, After a long research I have an answer. The problem is promises (as usually :)). Thanks for this article (While loop using bluebird promises), my solution that works for me is below:

     var promiseWhile = Promise.method(function (condition, action) {
        if (!condition()) return;
        return action().then(promiseWhile.bind(null, condition, action));
    });

    lastRow.elm = element.all(by.css('div.ui-grid-row')).last();


    browser.executeScript("return arguments[0].scrollTop;", lastRow.elm.getWebElement()).then(function (dst) {
        return distance.value = dst;

    })
    .then(function () {


        promiseWhile(function () {

            // Condition for stopping
            return start.value !== distance.value;

        }, function () {
                start.value = distance.value;

                return collectData().then(function () { 

                    //scroll
                    browser.executeScript("arguments[0].scrollIntoView();", lastRow.elm.getWebElement());
                    browser.wait(protractor.ExpectedConditions.presenceOf(element.all(by.css('div.ui-grid-row')).last()), 1000);

                    lastRow.elm = element.all(by.css('div.ui-grid-row')).last();
                    browser.executeScript("return arguments[0].scrollTop;", div.getWebElement()).then(function (dst) {
                        distance.value = dst;
                    });

                });

            });
        });




    var collectData = function collectData() { 

        // HERE COLLECT YOUR DATA and don't forget return result!
     }
Comments