0

I need to scroll an inner window (i.e. div). I found this web site How to scroll to an element inside a div?

but this shows how to do Javascript. I am calling the executor but I don't think I can pass values back to java (height, etc). This is my code section. Basically there is a div window with a bunch of elements. Some are hidden on the bottom and do not actually appear in the html unless scrolled to. Once they are scrolled to I believe the will remain there. So I figured I could just scroll a large number and it would not give an error if it were too much, it would just scroll as much as possible.

I scroll to the top and then done, like this:

    String sid = rolesScroller.getAttribute("id");
    js.executeScript("document.getElementById('" + sid + "').scrollTop -= 1000");
    js.executeScript("document.getElementById('" + sid + "').scrollTop += 1000");
    waitForXPathVisibility("Scroll", ROLES_SCROLLER_X);

will this be ok or do I need to somehow figure the exact amount to scroll and scroll just by that amount?

I see there is an element.scrollHeight. Does the possible values for scrollTop go from 0 to scrollHeight? Are the units both in pixels?

The elements in the divs are themselves nodes (list values) which can also be expanded creating more elements underneath. Every time I search for a value I have to do the above to make sure everything is in view. The way I have it now works to an extent. But sometimes after scrolling when I try to access a node I get a StaleElementException. However if I do a waitForStaleElement() it sometimes gives an error saying the element did not go stale. Is there a way after executing the javascript that you can make sure all actions have completed so that a stale element won't happen?

To Summarize

  1. When using the javascript executor from Java/Selenium is there a way to pass the javascript variables back to java so they can be used in later jasascript executor commands? (if that example above of -1000 +1000 is OK then this does not matter).

  2. How can you ensure that the javascript command has completed before continuing so when you try to access an element in the scrolled div you will not get a stale element (I tried examining one element in the div, and the div itself).

Community
  • 1
  • 1
Tony
  • 1,127
  • 1
  • 18
  • 29

1 Answers1

1

It seems that the container is dynamically constructed upon scrolling. Try to scroll the last element at the top with scrollIntoView and then wait for a different element at the end:

WebDriverWait wait = new WebDriverWait(driver, 5);
JavascriptExecutor jse = (JavascriptExecutor)driver;

// get the last element
By lastChild = By.cssSelector("#list > div:last-of-type");
WebDriver elem = driver.findElement(lastChild);

// scroll the last element at the top
jse.executeScript("arguments[0].scrollIntoView(true);", elem);

// wait for a new element at the end
wait.until((WebDriver drv) -> !elem.equals(drv.findElement(lastChild)))
Florent B.
  • 41,537
  • 7
  • 86
  • 101
  • Thanks. I believe this should work. A couple concerns. Every time so far there have been more items than fit in the window so a new element would appear. However, if there was some circumstance where there were not so many list items (not sure it will happen) would it give an error in the wait? Perhaps it could wait but not give an error if there were no new elements? Since I think the second time it was called it might be the same? – Tony Dec 02 '16 at 16:36
  • @Tony, a test case shouldn't have any logic. So for some given steps, you should know exactly if a scroll is expected to return new elements or not. – Florent B. Dec 02 '16 at 16:47