How to scroll to element with Selenium WebDriver
Asked Answered
M

13

32

How do I get Selenium WebDriver to scroll to a particular element to get it on the screen. I have tried a lot of different options but have had no luck. Does this not work in the C# bindings?

I can make it jump to a particular location ex

((IJavaScriptExecutor)Driver).ExecuteScript("window.scrollTo(0, document.body.scrollHeight - 150)");

But I want to be able to send it to different elements without giving the exact location each time.

public IWebElement Example { get { return Driver.FindElement(By.Id("123456")); } }

Ex 1)

((IJavaScriptExecutor)Driver).ExecuteScript("arguments[0].scrollIntoView(true);", Example);

Ex 2)

((IJavaScriptExecutor)Driver).ExecuteScript("window.scrollBy(Example.Location.X", "Example.Location.Y - 100)");

When I watch it, it does not jump down the page to the element, and the exception matches the element being off screen.

I added an bool ex = Example.Exists(); after it and checked the results. It does Exist (its true). Its not Displayed (as its still offscreen as it has not moved to the element) Its not Selected ??????

Someone is seeing success By.ClassName. Does anyone know if there is a problem with doing this By.Id in the C# bindings?

Mathieu answered 12/2, 2015 at 9:25 Comment(5)
Maybe you can try simulating "Arrow Down" Keypresses, until the Exception disappears. I know this is running-against-the-wall until the wall breaks, but if you just want it to work somehow it could be a solution?!Tactless
You can try out with one thing, use ExpectedConditions.visibilityOfElement method and put it as a condition of while loop and in loop scroll the view by some say 100, 100 co-ordinates.Tamarisk
Prior to the javascript being called, are you sure WebDriver has found your element?Turquoise
The webelement is already declared (Driver.FindElement). I would have thought it would find it as it finds all other elements on at the top of the page fine and there is a couple of waits before it gets to this element. I'll test that and update again. I would like to scroll until I find the element as Selenium Webdriver does not allow you to do anything to an element that is off screen. I am hoping to avoid any solution that involves just jumping a fixed amount as the page size will vary.Mathieu
Won't driver.FineElement(By.Id('id-of-ele')).Click() do the trick?Caryl
L
66

Its little older question, but I believe that there is better solution than suggested above.

Here is original answer: https://mcmap.net/q/103634/-scroll-element-into-view-with-selenium

You should use Actions class to perform scrolling to element.

var element = driver.FindElement(By.id("element-id"));
Actions actions = new Actions(driver);
actions.MoveToElement(element);
actions.Perform();
Levan answered 6/7, 2015 at 8:30 Comment(2)
This worked great for me, thanks. I've never really paid attention to Actions, but they've come up a couple of times recently. I should really learn more about them.Algerian
Great answer, as much as possible we should always rely on the solutions other people have thoroughly thought through. I say this because I have implemented the JS hack many times and overlooked the default implementation of Scroll To Element. AKA Actions.MoveToElement. CheersEastnortheast
S
22

This works for me in Chrome, IE8 & IE11:

public void ScrollTo(int xPosition = 0, int yPosition = 0)
{
    var js = String.Format("window.scrollTo({0}, {1})", xPosition, yPosition);
    JavaScriptExecutor.ExecuteScript(js);
}

public IWebElement ScrollToView(By selector)
{
    var element = WebDriver.FindElement(selector);
    ScrollToView(element);
    return element;
}

public void ScrollToView(IWebElement element)
{
    if (element.Location.Y > 200)
    {
        ScrollTo(0, element.Location.Y - 100); // Make sure element is in the view but below the top navigation pane
    }

}
Serafina answered 16/2, 2015 at 16:7 Comment(2)
Dude, you are the best!Bakery
Thanks, this works! C# version of ScrollTo() function: IJavaScriptExecutor js = (IJavaScriptExecutor)driver; js.ExecuteScript(String.Format("window.scrollTo({0}, {1})", xPosition, yPosition));Aisne
M
15

This works for me:

var elem = driver.FindElement(By.ClassName("something"));
driver.ExecuteScript("arguments[0].scrollIntoView(true);", elem);
Marylyn answered 15/2, 2015 at 15:1 Comment(3)
By.ClassName would not be unique enough for what I am looking for. I tried the above and it wont work By.Id for me. Are you suggesting that the issue is By.Id? Do you see this scrolling offscreen for By.ClassName but not By.ID?Mathieu
By.ClassName is only an example of finding en element. You can use whatever you want/need to find the element. The real magic here is to scroll to the element which happens in the JavaScript scrollIntoView() method. If you have hard time finding an element try posting the HTML here.Marylyn
I just tested suggested solution and it is working. As user3734429 said, you are not obligated to filter by class name, all you need is WebElement (its up to you how you will get it, selecting by class is just one way).Levan
M
3

This works for me in C# automation:

public Page scrollUp()
{
    IWebElement s = driver.FindElement(By.Id("your_locator")); ;
    IJavaScriptExecutor je = (IJavaScriptExecutor)driver;
    je.ExecuteScript("arguments[0].scrollIntoView(false);", s);
    return this;
}
Milepost answered 19/3, 2019 at 20:35 Comment(0)
E
2

I created a extension for IWebDriver:

public static IWebElement GetElementAndScrollTo(this IWebDriver driver, By by)
{
    var js = (IJavaScriptExecutor)driver;
    try
    {
        var element = driver.FindElement(by);
        if (element.Location.Y > 200)
        {
            js.ExecuteScript($"window.scrollTo({0}, {element.Location.Y - 200 })");
        }
        return element;
    }
    catch (Exception ex)
    {
        return null;
    }
}
Ephrayim answered 19/3, 2019 at 4:0 Comment(1)
Good job! Worked for me too! Thanks.Dotty
M
1
var js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'})", PutYourElementIDHere);
Mopes answered 18/5, 2022 at 20:48 Comment(0)
G
0

For scroll down inside the page here I have small code and solution

My Scenario was until I scroll down the page. Accept and Don't accept button was not getting enabled. I was having 15 terms and conditions from which I needed to select 15th term and condition by inspecting webpage and taking the Id of last terms and condition paragraph.

driver.FindElement(By.Id("para15")).Click();

<div id="para15">One way Non-Disclosure Agreement</div>
Gascon answered 5/11, 2018 at 13:13 Comment(0)
S
0

I had somehow same problem. I was working on a web page and need to click on a button on a child window which by default, was located below screen. This is the code I used and it worked. Actually I just simulated a mouse drag and drop and moved the window 250 points upwards so that the button was in the screen.

Actions action = new Actions(driver);
action.DragAndDropToOffset(driver.FindElement(By.XPath("put an element path which **is in the screen now**, such as a label")), 0, -250);
action.Build().Perform();
Sleight answered 29/8, 2020 at 13:47 Comment(0)
C
0

If the reason we put time is for a long time to load the page, we put it. Just it.

ChromeOptions options = new ChromeOptions();
var driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.w3schools.com/");
Thread.Sleep(5000);
driver.ExecuteScript("scroll(0,400)");
HtmlDocument countriesDocument = new HtmlDocument();
countriesDocument.LoadHtml(driver.PageSource);
Chon answered 18/5, 2021 at 8:21 Comment(1)
Code-only answers are not particularly helpful. Please add some descriptions of how this code solves the problem.Israelitish
G
0

I am providing solution to scroll within a specific element, like a scrollable table.

// Driver is the Selenium IWebDriver
IJavaScriptExecutor exec = (IJavaScriptExecutor) Driver;

int horizontalScroll= direction == Direction.Right ? X : 0;
int verticalScroll  = direction == Direction.Down  ? Y : 0;

exec.ExecuteScript(
    "arguments[0].scrollBy(arguments[1], arguments[2])"
  , Self
  , horizontalScroll
  , verticalScroll);
Gyrostatic answered 28/9, 2021 at 12:8 Comment(0)
A
0
Actions actions = new Actions(driver);
actions.SendKeys(Keys.PageDown).Build().Perform();

You do it through for, it works like clockwork, simple, but not always convenient

Aprylapse answered 20/3, 2022 at 20:18 Comment(0)
D
0
                                var e = driver.FindElement(By.XPath("//*[text()='Timesheet']"));
                                // JavaScript Executor to scroll to element
                                ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", e);
Dislocate answered 3/2, 2023 at 9:27 Comment(0)
K
0

C# Thanks this one worked for me in my testcase

driver.FindElement(By.LinkText("Home")).SendKeys(Keys.PageDown);
Keeper answered 28/4 at 10:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.