Reputation: 179
Is there a way to scroll the scrollbar of a div inside a web page? To be more exact, I'm trying to automate the scrolling of up and down of an instagram post e.g https://instagram.com/p/9D5Ir3CY3D/?taken-by=bentomonsters. However, as the scrollbar might be hidden using CSS property, I might not be able to detect it as the scrollbar is not an element.
Below is the css style (from firebug) of the scrollbar.
.-cx-PRIVATE-PostInfo__comments {
margin-left: -24px;
margin-right: -24px;
margin-top: -5px;
padding-left: 24px;
padding-right: 24px;
padding-top: 5px;
}
.-cx-PRIVATE-PostInfo__commentsSidebarVariant {
overflow: auto;
padding-bottom: 20px;
}
.-cx-PRIVATE-PostInfo__comments {
flex-grow: 1;
}
ol, ul {
list-style: outside none none;
}
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p,
blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em,
img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i,
center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption,
tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure,
figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary,
time, mark, audio, video {
border: 0 none;
font: inherit;
margin: 0;
padding: 0;
vertical-align: baseline;
}
I have tried ways such as
WebElement commentscroll = dr.findElement(By.className("commentsSidebarVariant"));
jse.executeScript("return arguments[0].scrollTop;", commentscroll);
jse.executeScript("$(\"#commentsSidebarVariant\").animate({ scrollTop: \"100px\" })");
jse.executeScript("arguments[0].scrollTop = arguments[1];", commentscroll);
WebElement commentscroll = dr.findElement(By.cssSelector(".-cx-PRIVATE-PostInfo__commentsSidebarVariant"));
jse.executeScript("arguments[0].scrollTop;", commentscroll);
and none of them works as the scrollbar does not even move.
Upvotes: 2
Views: 1178
Reputation: 4345
I use the following methods for scrolling an overflowing element using pure JS and checking if I reached scroll end. When reaching scroll end you need to scroll back up with a similar method since you might have started scrolling from any position.
The methods below are reference code, not the entire solution:
// Returns true if scroll succeeded, false otherwise
private boolean scrollDownOverflowElement(WebElement element, int lazyLoadingGracePeriodMillis) {
long scrollTopBefore = (long) javascriptExecutor.executeScript("return arguments[0].scrollTop", element);
javascriptExecutor.executeScript("arguments[0].scrollTop = arguments[0].scrollTop + arguments[0].clientHeight", element);
if (isAtEndOfScroll(element)) {
// Wait for 1 second to give additional async results a chance to load (e.g. select2 drop downs)
sleep(lazyLoadingGracePeriodMillis);
}
long scrollTopAfter = (long) javascriptExecutor.executeScript("return arguments[0].scrollTop", element);
return scrollTopAfter != scrollTopBefore;
}
// Returns true if element is at end of scroll, false otherwise
// See https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollHeight
private boolean isAtEndOfScroll(WebElement element) {
// scrollTop is the number of number of pixels scrolled down from the top (0 when scrolled all the way up)
// scrollHeight is the height of the scroll view of an element. It includes the element padding but not its margin.
// clientHeight is the inner height of an element in pixels, including padding but not the horizontal scrollbar height, border, or margin. (the displayed size of an overflow element)
final boolean isAtEnd = (boolean) javascriptExecutor.executeScript("return arguments[0].scrollHeight - arguments[0].scrollTop === arguments[0].clientHeight", element);
return isAtEnd;
}
Upvotes: 1