Protractor: Scrolling a table and testing for infinite scroll

Problem

How can I get protractor to scroll down on a table? My table does infinite scrolling - it loads 20 records, and when the second-to-last-row is displayed, it fetches the next 20 records. Not all records are in view...some are below yet to be scrolled into, and some are above when the user has scrolled past it. I was thinking the test is

it('should fetch next set of records on scroll') {
    element.all(by.id('users')).map(function (elm) {
        return elm;
    }).then(function (users) {
        expect(users.length).toBe(20);
    });

    // Scroll the table to the bottom to trigger fetching more records

    element.all(by.id('users')).map(function (elm) {
        return elm;
    }).then(function (users) {
        expect(users.length).toBe(40);
    });
};

Is this the right way of doing this?

HTML table code:

<div ng-if="users && users.length > 0" class="table-scroll" ng-infinite-scroll="loadMoreUsers()">
    <table id="users-table" class="table table-hover text-overflow-ellipsis">
        <thead>
            <td class="col1"></td>
            <td id="users-table-name-col" class="col2">User</td>
            <td id="users-table-date-col" class="col3">Birthday</td>
        </thead>
        <tbody ng-repeat="group in users">
            <tr ng-repeat="user in group.users" ng-click="userClicked(user);">
                <td class="col1">
                    <img class="col-xs-1 profile-picture" style="padding:0" ng-src="{{user.profile_picture}}"></td>
                <td class="col2">
                    <div id="user-name"> {{ user.last_name }}, {{ user.first_name }} </div>
                </td>
                <td class="col3">
                    <div id="user-date"> {{user.date}} </div>
                </td>
            </tr>
         </tbody>
     </table>
</div>
Problem courtesy of: Jason

Solution

The idea is to find the latest element in the table (tr tag) and scroll to it by setting the parent's scrollTop to the last element's offsetTop.

The Element.scrollTop property gets or sets the number of pixels that the content of an element is scrolled upward. An element's scrollTop is a measurement of the distance of an element's top to its topmost visible content.

The HTMLElement.offsetTop read-only property returns the distance of the current element relative to the top of the offsetParent node.

var div = element(by.css('div.table-scroll'));
var lastRow = element(by.css('table#myid tr:last-of-type'));

browser.executeScript("return arguments[0].offsetTop;", lastRow.getWebElement()).then(function (offset) {
    browser.executeScript('arguments[0].scrollTop = arguments[1];', div.getWebElement(), offset).then(function() {
        // assertions

    });
});

Also see (similar solution used):

Solution courtesy of: alecxe

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.