3

I have a page. when I scroll it manually, it grows and then I can scroll it again and again until the scroll arrives to the bottom (a good example is a facebook timeline page).

I try to write:

static IWebDriver driver = new ChromeDriver(@"C:\selenium\net40");
IJavaScriptExecutor js = driver as IJavaScriptExecutor;

then I entered a page and did:

js.ExecuteScript("window.scroll(0, document.height)");

but I can scroll more.

how can I make it to scroll to the bottom even if the page is growing?

any help appreciated!

AndersDaniel
  • 1,152
  • 9
  • 20
Alon Shmiel
  • 6,753
  • 23
  • 90
  • 138
  • Given the answers you currently have, i think we may need some clarification. When exactly do you want this scroll to occur? – MaxPRafferty Jul 19 '13 at 16:39

4 Answers4

2

Unfortunately there is no event that triggers when the total height of the page changes. Therefore there are two possible solutions:

You can use an timer to 'blindly' scroll to the bottom every interval.

setInterval(function () { window.scroll(0, document.height); }, 100);

Or you can scroll to the bottom every time the height changes, using the 'DOMSubtreeModified' event. This event fires every time anything changes in the document, so it might slow down your browser if you are changing the DOM very frequently. This solution however will guarantee that you instantly scroll to the bottom when the page grows.

//scroll to bottom when anything changes in the dom tree.
var height = document.height;
document.addEventListener('DOMSubtreeModified', function () {
    if (document.height != height) {
        height = document.height;
        window.scroll(0, height);
    }
});
Bas
  • 26,772
  • 8
  • 53
  • 86
2

window.scroll(0, document.height) will scroll to the known scrollable area. The problem is that more data are downloaded when you reach bottom of the page. So, the scrollable area is changed. You need to scroll as many times as required.

for example use this script

var timeId = setInterval( function() {
    if(window.scrollY!==document.body.scrollHeight)
        window.scrollTo(0,document.body.scrollHeight);
    else
        clearInterval(timeId);
},500);

EDIT :

On some pages, window.scrollY will never be equal to document.body.scrollHeight, so setIntervanl will never be cleared : this will prevent you to go to top.

var timeId = setInterval( function() {
    if(window.scrollY<(document.body.scrollHeight-window.screen.availHeight))
        window.scrollTo(0,document.body.scrollHeight);
    else
    {
        clearInterval(timeId);
        window.scrollTo(0,0);
    }
},500);
Cybermaxs
  • 24,378
  • 8
  • 83
  • 112
  • @CybermaxsBetclic, thank you! you are so closer.. the scroll goes to the bottom, and then I am trying to take it to the top: it arrives to the top but then continues moving to the bottom: js.ExecuteScript("var timeId = setInterval( function() { if(window.scrollY!=document.body.scrollHeight) window.scrollTo(0,document.body.scrollHeight); else clearInterval(timeId); },500);"); js.ExecuteScript("window.scrollTo(0, 0);"); – Alon Shmiel Jul 19 '13 at 10:01
2

I'm ok with the goal but not with the suggested code approaches from a user perspective. If I land in a page where there is a design need to load all the content partially using ajax (or any other method), I'll expect the page to do it silently without disturbing me with unwanted scrolls. Therefore the best approach is to make the calls in the background one after the other as long there is more content to load. If you agree with this solution, then in general you will need a function for the window.onload event to make the first call, handle the response and call itself for more content.

  • seems a good approach but I see two problems : you may not know how to call for more content and this will require to put site-specific js code in the selenium test (not easy to maintain). In Selenium, user perspective does not really matter – Cybermaxs Jul 18 '13 at 07:16
  • site-specific code? Isn't your entire test suite site specific anyway. I'm betting your test suite for google+ fails when I run it against Facebook... – Ardesco Jul 18 '13 at 10:32
1

The following two functions will force your page to scroll when new content loads:

JS:

var attachScrollModified = function () {
    document.addEventListener('DOMSubtreeModified', function () {
        this.removeEventListener('DOMSubtreeModified', arguments.callee, false);
        window.scroll(0, getBottomElemPos());
        attachScrollModified();
    });
}

var getBottomElemPos = function () {
    var scrollElem = document.getElementById("scrollElem");
    if (scrollElem) {
        document.body.removeChild(scrollElem);
    }
    scrollElem = document.createElement("div");
    scrollElem.id = "scrollElem";
    document.body.appendChild(scrollElem);
    return scrollElem.offsetTop;
}

Example at : http://jsfiddle.net/MaxPRafferty/aHGD6/

place those in a <script> on your page, and then call:

js.ExecuteScript("attachScrollModified();");

That said, this may cause an infinite loop of continuously ajax-ing more content.

MaxPRafferty
  • 4,819
  • 4
  • 32
  • 39
  • thank you very much for your trying but I don't have any button and I didn't understand how to remove the line of the button in your code.. thank you very much! – Alon Shmiel Jul 19 '13 at 10:04
  • 1
    @AlonShmiel Ok! Modified answer and jsfiddle to make it attachable outside of a user click. – MaxPRafferty Jul 19 '13 at 17:25