How to scroll a specific DIV using Selenium WebDriver with Java?
Asked Answered
D

11

43

Some of WebElements are not recognized by WebDriver, WebDriver fails to find the element which is not visible in browser's visible area.

In order to make the WebElement viewable by WebDriver, We need to make that element to visible in browser's view to do scroll down on particular div!

How can I perform my action(scroll down and click) on particular area of my webpage. I tried lot, doesn't helped me.

Please help me resolve my issue.

Delarosa answered 28/11, 2014 at 12:57 Comment(2)
Please check , I have modified my answer. Try this : JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("javascript:window.scrollBy(250,350)");Bilk
@Pandiaraj - The image shown here seems like a ListBox. In that u can select multiple values. Check what type of html element it is. eg:- (Check whether it is a Select element). If it is a select element, Why not to use Select obj = new Select(element); obj.SelectByText("Australia"). And if u want to select multiple values use advance for loop in java to acheive the samePooka
M
20

First of all, most of the answers posted here are just off the topic. I have been working with selenium 2 and selenium 3 now, the webdriver can handle window scroll to make an element visible.

For everyone posting snippets like:

driver.execute_script('scrollBy(0, 250)')

you do not get the question at all!

Actually I still did not find a way to properly simulate the drag action of scroll handle but this answer seems promising -- but I did not try.

So so far personally there are two ways to do this for me:

  1. Use Keys.ARROW_DOWN
  2. Use Keys.PAGE_DOWN

Actually there is a third way, just give up selenium and contact the website if they provide any API.

Matheny answered 14/6, 2017 at 9:0 Comment(2)
Correct. Also for element.send_keys(Keys.PAGE_DOWN), element needs to fit in your screen, otherwise Selenium will reject the send_keys() command.Pernicious
FYI this answer does not work in C#. The driver returns a "cannot focus element" exception because you're trying to use SendKeys on something other than a text field. Clicking the element to give focus has no effect. In this case, it looks like javascript may still be the best bet....Pyrene
B
11

The easiest way to do that is executing a Javascript to scroll the element up/down.

JavascriptExecutor jsExec = (JavascriptExecutor) driver;
jsExec.executeScript("document.getElementById('id').scrollDown += 100");
Bautzen answered 5/9, 2016 at 14:57 Comment(1)
Did you mean scrollTop instead of scrollDown ? (currently working with chrome)Posture
R
6
driver.get("http://www.***.com/");
driver.manage().window().maximize();
WebElement scroll = driver.findElement(By.id("someId"));
scroll.sendKeys(Keys.PAGE_DOWN);
Ross answered 19/8, 2015 at 11:43 Comment(4)
I am using Keys.DOWN to scroll, but how will you identify that the scroll has loaded new elements from an ajax call? Problem what I am facing is, before even the Keys.DOWN finishes (no new elements loaded), my script fetches the old set of element from the div.Kell
This will not work if the "someId" element can not get the Focus.Adenocarcinoma
Ok, but who does prevent you from waiting the time till all dom elements will have downloaded? Or click to button or link which opens hidden elements?Ross
Thank you. This solution was the only one which worked for me today. Upvoted.Claudy
C
3

Scroll Down:

import org.openqa.selenium.JavascriptExecutor;
WebDriver driver = new FirefoxDriver();
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("scroll(0, 250)"); //y value '250' can be altered

Scroll up:

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("scroll(250, 0)"); //x value '250' can be altered

Scroll bottom of the Page:

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));");

or

Actions actions = new Actions(driver);
actions.keyDown(Keys.CONTROL).sendKeys(Keys.END).perform();

Full scroll to bottom in slow motion:

for (int second = 0;; second++) {
    if(second >=60){
        break;
    }
    ((JavascriptExecutor) driver).executeScript("window.scrollBy(0,400)", ""); //y value '400' can be altered
    Thread.sleep(3000);
}

or

JavascriptExecutor jse = (JavascriptExecutor)driver;
for (int second = 0;; second++) {
    if(second >=60){
        break;
    }
    jse.executeScript("window.scrollBy(0,800)", ""); //y value '800' can be altered
    Thread.sleep(3000);
}

Scroll automatically to your WebElement:

Point hoverItem =driver.findElement(By.xpath("Value")).getLocation();
((JavascriptExecutor)driver).executeScript("return window.title;");    
Thread.sleep(6000);
((JavascriptExecutor)driver).executeScript("window.scrollBy(0,"+(hoverItem.getY())+");"); 
// Adjust your page view by making changes right over here (hoverItem.getY()-400)

or

((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", driver.findElement(By.xpath("Value')]")));

or

WebElement element = driver.findElement(By.xpath("Value"));
Coordinates coordinate = ((Locatable)element).getCoordinates(); 
coordinate.onPage(); 
coordinate.inViewPort();
Champagne answered 28/11, 2014 at 13:4 Comment(6)
This is just a copy-paste job of every example related to scrolling, most of which are totally irrelevant to the question. The question is about scrolling a specific div not scrolling the window itself.Mcpherson
@Rupesh Shinde: are you sure you have really understood the question asked? The author asked how to scroll content inside a particular div and you just copied here all possible ways of how to scroll the main window content which does not really help.Azure
How could this answer get so much up rating?, its irrelevant to questionPhysician
This last one worked for me. I also found that solution here sqa.stackexchange.com/a/17480/30196.Hanaper
This is a pat answer and does not answer the question asked and it should never have been upvoted.Restitution
The last one worked for me. Thanks @RupeshVa
N
3

Another way of doing it using JavascriptExceutor's scrollIntoView() method:

WebElement DIVelement = driver.findElement(By.xpath("xpath to div"));

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView(true)", DIVelement);
Narcosis answered 24/5, 2017 at 10:54 Comment(0)
B
2

First you should do scroll rather than find element so do like below :

document.getElementById("your div id").scrollTop(250);

After above you can find that specific div.

You can also try below :

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250,350)");
Bilk answered 28/11, 2014 at 13:3 Comment(0)
A
1

None of the posted answers worked for me, however I have found a solution based on this post.

((JavascriptExecutor) driver).executeScript(
    "arguments[0].scrollTop=arguments[1].offsetTop",
    divWithScrollbarElement,
    elementToScrollTo);

where divWithScrollbarElement is the div element which you are looking to scroll, and elementToScrollTo is the child element which you want to make viewable (which in my case was actually the parent of the element which I was initially trying to view). If elementToScrollTo is not actually in the DOM yet, you may need to use the script once to scroll down as far as possible, and then again once more elements have loaded.

Avoid answered 10/11, 2017 at 17:4 Comment(0)
P
0

Consider your HTML is like below:

<div id="someId" class="className" style="position: relative; top: 0px; left: opx;>

you can observe style attribute in div check for the value of top which is 0px in above example

Now try to do something like:

$('.className').animate({top: "-60px"});

which will help you to scroll down. Its a JavaScript executor so of course you need to implement it.

Physician answered 27/3, 2017 at 9:53 Comment(0)
T
0

My 'WORKAROUND' is to scroll to the position by element's x and y co-ordinates. I also added an offset to y so that any header/footer or other element don't block the visibility of the element that I want to scroll to.

I have my answer posted under this question -

Selenium webdriver can't click on a link outside the page

Thyroid answered 23/5, 2017 at 16:55 Comment(0)
D
0

As you found, webdriver won't find elements that aren't visible so you need to scroll to the element. However you can't scroll directly to the element because webdriver won't find it until it is visible. Catch-22.

However I do have a way that you can scroll within a DIV. First assign the DIV you want to scroll to an element variable, and then you can use javascript to scroll that element instead of scrolling the entire window.

Some VB.NET example code that should be easily adapted to other languages:

Dim div_to_scroll As IWebElement = driver.FindElement(By.XPath("[put your xpath here]"))

driver.ExecuteJavaScript("arguments[0].scrollBy(0,500)", div_to_scroll)

' Short pause to make sure the screen updates:
System.Threading.Thread.Sleep(500)

If you don't know how far you need to scroll then you will need a loop with a test to see if the desired element is visible yet. This isn't a particularly elegant or fast way of doing things but webdriver isn't a fast solution to begin with and I have found this method to be very robust.

Decapolis answered 9/3, 2020 at 7:18 Comment(0)
S
0

Just in case for anyone looking for an alternative solution, here I put mine using python, which should be easy to transform to Java. First, I was using:

more = panel.find_elements(By.CSS_SELECTOR, "//li")
self.driver.execute_script("arguments[0].scrollIntoView();", more[-1])

if last == more[-1]:
    break
else:
    last = more_followers[-1]
    #wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "//li")))
    time.sleep(0.5)

in a loop for a ul inside a div. However, the more li elements appear, the slowest was selenium to perfom this action. At the end, because the div containing the ul had a unique class name I used the following in a loop:

while num_of_il<num_of_elements:
        self.driver.execute_script("document.getElementsByClassName('myclass')[0].scrollTop += 100;");
        time.sleep(0.5)
        num_of_il = self.driver.execute_script("return document.getElementsByTagName('li').length")
        print("Num of li "+str(num_of_il))

This way is not slow anymore, and with the 0.5 I give enough time to load my next entries. You can also have other getElementsBy as getElementById(), getElementsByName(), getElementsByTagName() and getElementsByTagNameNS(). Look methods at https://developer.mozilla.org/en-US/docs/Web/API/document/ You can check the number of elements loaded accessing the num_of_il variable. Consider introducing some code to break the loop in case num_of_il does not change (e.g. end of items reached).

Shoa answered 29/12, 2021 at 11:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.