264

Is there any way in either Selenium 1.x or 2.x to scroll the browser window so that a particular element identified by an XPath is in view of the browser? There is a focus method in Selenium, but it does not seem to physically scroll the view in FireFox. Does anyone have any suggestions on how to do this?

The reason I need this is I'm testing the click of an element on the page. Unfortunately the event doesn't seem to work unless the element is visible. I don't have control of the code that fires when the element is clicked, so I can't debug or make modifications to it, so, easiest solution is to scroll the item into view.

John Smith
  • 7,243
  • 6
  • 49
  • 61
Dan at Demand
  • 3,259
  • 3
  • 19
  • 10
  • You may try this hacky one *if nothing else works for you*: https://stackoverflow.com/a/53771434/7093031 – Zoette Dec 16 '18 at 21:18
  • 3 ways to do it `JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("window.scrollBy(0,250)", "”);` `Actions action = new Actions(driver); action.moveToElement(element).perform();` `WebElement element = driver.findElement(By.)); element.sendKeys(Keys.DOWN);` – Gulshan Nadaph Jul 21 '22 at 18:29

37 Answers37

291

Have tried many things with respect to scroll, but the below code has provided better results.

This will scroll until the element is in view:

WebElement element = driver.findElement(By.id("id_of_element"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
Thread.sleep(500); 

//do anything you want with the element
John Smith
  • 7,243
  • 6
  • 49
  • 61
Amith
  • 6,818
  • 6
  • 34
  • 45
  • 7
    This is a neat solution for when you may have an element with `position: fixed` on your page and it is obscuring the element Selenium wants to click. Quite often these fixed elements go at the bottom, so setting `scrollIntoView(true)` moves it nicely to the top of the viewport. – Mandible79 Oct 02 '14 at 10:41
  • 3
    Based on the newest version of selenium (2.53), this is now a great helper solution. Selenium is not always scrolling the element into view, so this definitely comes in handy. – Zoidberg Apr 12 '16 at 12:46
  • 48
    Pass in `true` to `scrollIntoView` if the object you're scrolling to is beneath where you currently are, `false` if the object you're scrolling to is above where you currently are. I had a hard time figuring that out. – Big Money Jul 27 '16 at 22:07
  • Thanks for this answer. I've modified it a bit for our needs cause we have a fixed header + a fixed footer. So I'm simply scrolling 100px up as a "padding". Not the cleanest solution but it should work for all our needs. ``((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true); window.scrollBy(0,-100);", element); element.click()`;`` – Patrick Winkelmayer Jan 31 '17 at 11:49
  • Did not work for me :-| Used https://stackoverflow.com/a/23902068/661414 instead. – Leukipp Aug 21 '18 at 10:06
  • 2
    Why do you need thread sleep? executeScript should be synchronous – riccardo.tasso Sep 04 '18 at 14:44
  • C# one line version WebDriver.ExecuteJavaScript("arguments[0].scrollIntoView(true);", driver.findElement(By.id("id_of_element"))); – Raghu May 12 '19 at 00:49
  • 1
    @BigMoney what you wrote is not correct. See the [documentation](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView). `true` aligns the element to the top of the screen, while `false` aligns the element to the bottom of the screen. – Jonathan Benn Jun 06 '19 at 17:25
  • 3
    @riccardo.tasso a sleep might have been implemented to deal with the unknown of the target app. If it has dynamic scrolling, or a single-page app that loads the next bit of the page after scrolling, among other possibilities. Speaking from experience, Selenium has frequently broken my company's site because the automated action occurred faster than the Javascript could complete, and thus passed an incomplete data model. Some places may consider it a bug, but I was told "No human could ever invoke such a scenario, so it's not a real bug." C'est la vie. – Solonotix Nov 21 '19 at 18:24
  • True or False as the first argument can be omitted, it's optional. It works for me without any arguments. – Ron HD Aug 06 '20 at 00:22
195

You can use the org.openqa.selenium.interactions.Actions class to move to an element.

Java:

WebElement element = driver.findElement(By.id("my-id"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.perform();

Python:

from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).move_to_element(driver.sl.find_element_by_id('my-id')).perform()
supervacuo
  • 9,072
  • 2
  • 44
  • 61
sascha
  • 1,951
  • 1
  • 11
  • 3
  • 7
    Will this work if the WebElement is not in the View Port? – virusrocks Nov 04 '15 at 06:45
  • This will only move the mouse to the middle of the element according to the [docs](https://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/interactions/Actions.html#moveToElement-org.openqa.selenium.WebElement-) – Dominik Mohr Nov 25 '15 at 08:40
  • 11
    @Dominik: How will Selenium move the mouse to an element that is outside the screen? OBVIOUSLY it must first scroll the element into view and then move the mouse to it. I tested it. This code works on Firefox Webdriver 2.48 but there is a bug: When you have an iframe in a page the scrolling does not work correctly in the iframe while element.LocationOnScreenOnceScrolledIntoView scrolls correctly. (Although the documentation says that this command only returns a location, it also scrolls!) – Elmue Dec 05 '15 at 15:11
  • 9
    The docs at https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/interactions/Actions.html#moveToElement-org.openqa.selenium.WebElement- now clearly state "Moves the mouse to the middle of the element. The element is scrolled into view and its location is calculated using getBoundingClientRect." – George Pantazes Sep 09 '17 at 16:54
  • Can I retract my upvote? The question is about scrolling the element into view, not moving the mouse to the element, which is what this answer suggests. – Jorn Sep 21 '17 at 14:23
  • 7
    The above code is "the official way" Java Selenium wants you to do scroll an element into viewport however after trying many things the JS implementation seemed to work more reliably to me. [This method](http://learn-automation.com/how-to-scroll-into-view-in-selenium-webdriver) in particular. – Kenji Miwa Sep 26 '17 at 17:57
  • The python equivalent of this is: `from selenium.webdriver.common.action_chains import ActionChains #... ActionChains(driver).move_to_element(element).perform()` – phyatt Feb 20 '18 at 20:29
  • 2
    Did not work for me :-| Used https://stackoverflow.com/a/23902068/661414 instead. – Leukipp Aug 21 '18 at 10:07
  • @Elmue Thanks to your comment, I solved it by scrolling down to iframe first before executing `driver.switch_to.frame()`. – Leonard Jan 20 '19 at 20:27
  • Before I used LocationOnScreenOnceScrolledIntoView which does NOT scroll anymore with the newer Gecko drivers. They broke it. On the other side actions.moveToElement() does not work with Safari on iOS: "Actions not supported". Apart from that moveToElement() does nothing if the top of the element is already visible. But if you have a large element and only the top is visible this command is completely useless. The only correct way to scroll an element so it can automated is executing a JavaScript with "arguments[0].scrollIntoView(true);" and let the browser scroll it to the top of the screen. – Elmue Aug 03 '19 at 20:15
  • This doesn't scroll window and only moves the mouse to the element, which doesn't answer the question – TK Tang Sep 25 '19 at 00:41
  • I am finding that in headless Chrome there is still a need to wait for the element to become visible before clicking on it with this `WebDriverWait(self.driver, 10).until(expected_conditions.visibility_of_element_located((By.ID, 'my-id')))` – David R. Mar 20 '20 at 16:19
29
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250,350)");

You may want to try this.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Mayur
  • 676
  • 8
  • 16
  • 1
    Thanks. I needed to use this method in a case where a Selenium's auto-scroll was causing another element to obscure the element I needed to click on. I was able to scroll an arbitrary amount to make the element visible in the viewport, without being obscured. – Daniel Richnak Aug 28 '12 at 19:42
  • This will only work in FIrefox, Chrome and IE dont support this method – virusrocks Jul 11 '15 at 03:12
  • This is why you use `js.ExecuteScript("arguments[0].scrollIntoView(true);" + "window.scrollBy(0,-100);", e);` for IE and Firefox and `js.ExecuteScript("arguments[0].scrollIntoViewIfNeeded(true);", e);` for Chrome. Simple. – IamBatman Oct 09 '17 at 15:46
  • `((JavascriptExecutor) driver).executeScript("javascript:window.scrollBy(0,250)");` This worked in Chrome. And the only solution that actually worked for me. Same situation as the first commenter, I had a fixed element at the bottom that kept obscuring the element I needed to click. – k_rollo Dec 09 '19 at 12:40
  • https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollBy – k_rollo Dec 09 '19 at 13:24
  • And it doesn't work if you have a scrollable `div` :/ – akostadinov May 19 '20 at 09:52
17

If you want to scroll on the Firefox window using the Selenium webdriver, one of the ways is to use JavaScript in the Java code. The JavaScript code to scroll down (to bottom of the web page) is as follows:

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollTo(0, Math.max(document.documentElement.scrollHeight, document.body.scrollHeight, document.documentElement.clientHeight));");
John Smith
  • 7,243
  • 6
  • 49
  • 61
Ankit Pandey
  • 339
  • 3
  • 4
15

Targeting any element and sending down keys (or up/left/right) seems to work also. I know this is a bit of a hack, but I'm not really into the idea of using JavaScript to solve the scrolling problem either.

For example:

WebElement.sendKeys(Keys.DOWN);
DevDave
  • 6,700
  • 12
  • 65
  • 99
  • This is no less of a hack than using js and it really is the simplest thing. I found this primarily a problem with IE where a click tries to scroll the element into view but doesn't quite make it. Solution is just as elegant using {PGUP} if done with proper try/catch/loop scenario. – jibbs Dec 15 '15 at 23:07
  • You saved my day! Thanks – Jesko R. Mar 04 '16 at 11:46
  • In my case page down was the thing that worked. This is a nice hack (vs all js hacks). – akostadinov May 19 '20 at 12:02
  • Thanks @DevDave! Equivalent in C#: `var elem = driver.FindElement(By.Id("element_id")); elem.SendKeys(Keys.PageDown);` – Watth Jun 05 '20 at 18:51
12

In Selenium we need to take the help of a JavaScript executor to scroll to an element or scroll the page:

je.executeScript("arguments[0].scrollIntoView(true);", element);

In the above statement element is the exact element where we need to scroll. I tried the above code, and it worked for me.

I have a complete post and video on this:

http://learn-automation.com/how-to-scroll-into-view-in-selenium-webdriver/

John Smith
  • 7,243
  • 6
  • 49
  • 61
Mukesh otwani
  • 821
  • 8
  • 11
  • @Mukesh otwani the above code will scroll down,but how abt scroll up without using any pixels defined in it. – khan Oct 12 '18 at 07:17
10
webElement = driver.findElement(By.xpath("bla-bla-bla"));
((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", webElement);

For more examples, go here. All in Russian, but Java code is cross-cultural :)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
VovecUdalec
  • 151
  • 1
  • 8
7

I found that the bounding rect of my element was not correct, leading to the browser scrolling well off the screen. However, the following code works rather well for me:

private void scrollToElement(WebElement webElement) throws Exception {
    ((JavascriptExecutor)webDriver).executeScript("arguments[0].scrollIntoViewIfNeeded()", webElement);
    Thread.sleep(500);
}
Ashley Frieze
  • 4,993
  • 2
  • 29
  • 23
6

This worked for me:

IWebElement element = driver.FindElements(getApplicationObject(currentObjectName, currentObjectType, currentObjectUniqueId))[0];
 ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", element);
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
user103
  • 79
  • 1
  • 8
6

You can use this code snippet to scroll:

C#

var element = Driver.FindElement(By.Id("element-id"));
Actions actions = new Actions(Driver);
actions.MoveToElement(element).Perform();

There you have it

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Mohsin Awan
  • 1,176
  • 2
  • 12
  • 29
5

Use the driver to send keys like the pagedown or downarrow key to bring the element into view. I know it's too simple a solution and might not be applicable in all cases.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ganesh S
  • 371
  • 6
  • 26
  • 1
    This is nonsense. You may have to send a dozen of page down on a large page. It is slow and not reliable. – Elmue Sep 14 '15 at 17:38
  • 2
    Yes. I agree. But I did say "not applicable in all cases" – Ganesh S Dec 28 '15 at 13:01
  • Finding some known `element` in the viewable page and sending PageDown `element.SendKeys(Keys.PageDown);` worked for me. – Gokul Oct 04 '17 at 05:59
  • I'd advise to use Alt key so that you don't scroll the page and use try/except (Python) clause to handle errors which can occur while trying to send keys to some elements. – Alex K. Jun 26 '18 at 13:07
4

From my experience, Selenium Webdriver doesn't auto scroll to an element on click when there are more than one scrollable section on the page (which is quite common).

I am using Ruby, and for my AUT, I had to monkey patch the click method as follows;

class Element

      #
      # Alias the original click method to use later on
      #
      alias_method :base_click, :click

      # Override the base click method to scroll into view if the element is not visible
      # and then retry click
      #
      def click
        begin
          base_click
        rescue Selenium::WebDriver::Error::ElementNotVisibleError
          location_once_scrolled_into_view
          base_click
        end
      end

The 'location_once_scrolled_into_view' method is an existing method on WebElement class.

I apreciate you may not be using Ruby but it should give you some ideas.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Robbie Wareham
  • 3,380
  • 1
  • 20
  • 38
  • I declared the above in `module Capybara :: module Node`, and I needed to call `native.location_once_scrolled_into_view` instead of just `location_once_scrolled_into_view` . I also rescued `::Selenium::WebDriver::Error::UnknownError` , which is what I'm getting often in Firefox 44.0.2. But I find this solution not to be flexible enough and ultimately put the `.native.location_once_scrolled_into_view` calls in the acceptance test itself, followed immediately by `page.execute_script('window.scrollByPages(-1)')` where needed. – Al Chou Feb 26 '16 at 11:35
  • Watir has the method `Element#scroll_into_view` which delegates to Selenium's `location_once_scrolled_into_view`. But both do nothing different from Seleniums default behavior so overflow elements still can obstruct whatever we try to click. – akostadinov May 19 '20 at 10:17
3

The Ruby script for scrolling an element into view is as below.

$driver.execute_script("arguments[0].scrollIntoView(true);", element)
sleep(3)
element.click
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
2

Selenium 2 tries to scroll to the element and then click on it. This is because Selenium 2 will not interact with an element unless it thinks that it is visible.

Scrolling to the element happens implicitly so you just need to find the item and then work with it.

AutomatedTester
  • 22,188
  • 7
  • 49
  • 62
  • Thanks, I guess I'm going to have to upgrade to 2.0. I knew the day would come ;-) – Dan at Demand Aug 04 '10 at 19:34
  • 24
    How is this an answer to the question? – reinierpost Aug 14 '12 at 10:11
  • 63
    doesn't appear to be working that way for me. Am getting 'element not clickable' errors for elements that are out of view – DevDave May 17 '13 at 12:05
  • 6
    @DevDave I have the same problem, except in my case, selenium does not perform click action on the element and there is no exceptions. I didn't have the problem before and I don't know what has caused that. – Zeinab Abbasimazar Nov 12 '13 at 13:50
  • This wasn't working for me properly because there was a static fixed header on the page I was testing. I had to do a manual window.scrollBy(0, -100) to make sure it was in view. – Jon Tirsen Sep 09 '14 at 12:46
  • 5
    The implicit scrolling varies between browsers. I have a test of an element in a pop-up menu partway down a page. With the Ruby gem selenium_webdriver 2.43 I find chromium-browser 37 (and I believe Internet Explorer) does indeed scroll the menu item into view and clicks it. But Firefox 32 doesn't seem to scroll at all, and then fails with "Element is not currently visible and so may not be interacted with". – skierpage Sep 16 '14 at 19:47
  • 11
    This answer is wrong. According to the specification for Selenium 2.0 `WebElement.click()` requires the element to be visible in order to click on it. It will not scroll on your behalf. – Gili Nov 22 '14 at 03:37
  • Does not work for Selenium 2.44 with Chrome 39 (scrolling downwards seems to work, but scrolling upwards does not) – Nick Baker Jan 09 '15 at 09:52
  • This is wrong. This does not work. It might work in some circumstances but not in what I need it for. – Dave Lawrence Aug 09 '16 at 11:20
  • The answer at http://stackoverflow.com/a/26461431/489888 to me, answers this question. – Steve Martin Dec 13 '16 at 15:50
  • @Gili "According to the specification for Selenium 2.0" -- can you please provide exact link? I found this https://www.w3.org/TR/2013/WD-webdriver-20130117/#widl-WebElement-click-void and it says "If the element is outside the viewport (according to the [CSS21] spec), the implementation should bring the element into view first" – Adrian Herscu Jun 10 '19 at 08:31
  • @AdrianHerscu I can no longer find a mention of this in the Selenium Javadoc but you should note that Selenium's APi predates the W3C standard so it's possible that the specification has changed. – Gili Jun 11 '19 at 02:32
2

Sometimes I also faced the problem of scrolling with Selenium. So I used javaScriptExecuter to achieve this.

For scrolling down:

WebDriver driver = new ChromeDriver();
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.scrollBy(0, 250)", "");

Or, also

js.executeScript("scroll(0, 250);");

For scrolling up:

js.executeScript("window.scrollBy(0,-250)", "");

Or,

js.executeScript("scroll(0, -250);");
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Anuraj R
  • 524
  • 2
  • 8
  • 24
2

This is a repeated solution with JavaScript, but with an added waiting for element.

Otherwise ElementNotVisibleException may appear if some action on the element is being done.

this.executeJavaScriptFunction("arguments[0].scrollIntoView(true);", elementToBeViewable);
WebDriverWait wait = new WebDriverWait(getDriver(), 5);
wait.until(ExpectedConditions.visibilityOf(elementToBeViewable));
Lukasz
  • 368
  • 4
  • 9
1

Something that worked for me was to use the Browser.MoveMouseToElement method on an element at the bottom of the browser window. Miraculously it worked in Internet Explorer, Firefox, and Chrome.

I chose this over the JavaScript injection technique just because it felt less hacky.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
David Peters
  • 1,938
  • 1
  • 20
  • 18
1

I have used this way for scrolling the element and click:

List<WebElement> image = state.getDriver().findElements(By.xpath("//*[contains(@src,'image/plus_btn.jpg')]"));

for (WebElement clickimg : image)
{
  ((JavascriptExecutor) state.getDriver()).executeScript("arguments[0].scrollIntoView(false);", clickimg);
  clickimg.click();
}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Bibek
  • 64
  • 4
  • In my case, `scrollIntoView(false)` worked, but `scrollIntoView(true)` didn't. [Either can work](https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView), it depends on your scenario. – rsenna Sep 16 '14 at 18:02
  • My case is the opposite - true works, false fails, but only as far as the click goes. It does scroll correctly for false, and it's what I prefer, but for whatever reason Selenium still cannot see it for click. Using true scrolls everything way too high, but at least it works. – Bill Hileman Mar 07 '17 at 17:56
  • User sendkeys enter instead of click when ever possible - it avoids issues if browser is not at 100% zoom. – Zunair May 11 '20 at 15:44
1
def scrollToElement(element: WebElement) = {
  val location = element.getLocation
  driver.asInstanceOf[JavascriptExecutor].executeScript(s"window.scrollTo(${location.getX},${location.getY});")
}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
omnomnom
  • 8,911
  • 4
  • 41
  • 50
1

You may want to visit page Scroll Web elements and Web page- Selenium WebDriver using Javascript:

public static void main(String[] args) throws Exception {

    // TODO Auto-generated method stub
    FirefoxDriver ff = new FirefoxDriver();
    ff.get("http://toolsqa.com");
    Thread.sleep(5000);
    ff.executeScript("document.getElementById('text-8').scrollIntoView(true);");
}
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
virusrocks
  • 861
  • 1
  • 5
  • 19
1

If you think other answers were too hacky, this one is too, but there is no JavaScript injection involved.

When the button is off the screen, it breaks and scrolls to it, so retry it... ¯\_(ツ)_/¯

try
{
    element.Click();
}
catch {
    element.Click();
}
David Clarke
  • 12,888
  • 9
  • 86
  • 116
vicentedealencar
  • 913
  • 1
  • 10
  • 20
  • this. this is so bad i can't even... Don't waste try catch all in this way, you can build better code by ready any other answer – Giulio Caccin Nov 18 '21 at 19:23
1

In most of the situation for scrolling this code will work.

WebElement element = driver.findElement(By.xpath("xpath_Of_Element"));    
js.executeScript("arguments[0].click();",element);
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
sp324
  • 285
  • 2
  • 20
1

JAVA

Try scroll to element utilize x y position, and use JavascriptExecutor with this is argument: "window.scrollBy(x, y)".

Following import:

import org.openqa.selenium.WebElement;
import org.openqa.selenium.JavascriptExecutor;

First you need get x y location the element.

//initialize element
WebElement element = driver.findElement(By.id("..."));
        
//get position
int x = element.getLocation().getX();
int y = element.getLocation().getY();
        
//scroll to x y 
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollBy(" +x +", " +y +")");
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
frianH
  • 7,295
  • 6
  • 20
  • 45
1

I am not sure if the question is still relevant but after referring to scrollIntoView documentation from https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView.

The easiest solution would be

executor.executeScript("arguments[0].scrollIntoView({block: \"center\",inline: \"center\",behavior: \"smooth\"});",element);

This scrolls the element into center of the page.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
kiranjith
  • 141
  • 1
  • 5
1

Javascript

The solustion is simple:

const element = await driver.findElement(...)
await driver.executeScript("arguments[0].scrollIntoView(true);", element)
await driver.sleep(500);
Masih Jahangiri
  • 9,489
  • 3
  • 45
  • 51
0

In Java we can scroll by using JavaScript, like in the following code:

driver.getEval("var elm = window.document.getElementById('scrollDiv'); if (elm.scrollHeight > elm.clientHeight){elm.scrollTop = elm.scrollHeight;}");

You can assign a desired value to the "elm.scrollTop" variable.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Hemant
  • 99
  • 2
0

Selenium can scroll to some element in the scrollbar automatically for some simple UI, but for lazy-load UI, scrollToElement is still needed.

This is my implementation in Java with JavascriptExecutor. You can find more details in Satix source code: http://www.binpress.com/app/satix-seleniumbased-automation-testing-in-xml/1958

public static void perform(WebDriver driver, String Element, String ElementBy, By by) throws Exception {
 try {
  //long start_time = System.currentTimeMillis();           
  StringBuilder js = new StringBuilder();
  String browser = "firefox";

  if (ElementBy.equals("id")) {
   js.append("var b = document.getElementById(\"" +
    Element + "\");");
  } else if (ElementBy.equals("xpath")) {
   if (!"IE".equals(browser)) {
    js.append("var b = document.evaluate(\"" +
     Element +
     "\", document, null, XPathResult.ANY_TYPE, null).iterateNext();");
   } else {
    throw new Exception("Action error: xpath is not supported in scrollToElement Action in IE");
   }
  } else if (ElementBy.equals("cssSelector")) {
   js.append("var b = document.querySelector(\"" +
    Element + "\");");
  } else {
   throw new Exception("Scroll Action error");
  }

  String getScrollHeightScript = js.toString() + "var o = new Array(); o.push(b.scrollHeight); return o;";

  js.append("b.scrollTop = b.scrollTop + b.clientHeight;");
  js.append("var tmp = b.scrollTop + b.clientHeight;");
  js.append("var o = new Array(); o.push(tmp); return o;");

  int tries = 1;
  String scrollTop = "0";
  while (tries > 0) {
   try {
    String scrollHeight = ((JavascriptExecutor) driver).executeScript(getScrollHeightScript).toString();
    if (scrollTop.equals(scrollHeight)) {
     break;
    } else if (driver.findElement(by).isDisplayed()) {
     break;
    }
    Object o = ((JavascriptExecutor) driver).executeScript(js.toString());
    scrollTop = o.toString();
    Thread.sleep(interval);
    tries++;
   } catch (Exception e) {
    throw new Exception("Action error:" +
     " javascript execute error : " + e.getMessage() + ", javascript : " + js.toString());
   }
  }

 } catch (Exception e) {
  try {
   ScreenshotCapturerUtil.saveScreenShot(driver, CLASSNAME);
  } catch (IOException e1) {
   throw new Exception("Save screenshot error!", e1);
  }
  throw e;
 }
}
William Desportes
  • 1,412
  • 1
  • 22
  • 31
Effie
  • 11
0

I've been doing testing with ADF components and you have to have a separate command for scrolling if lazy loading is used. If the object is not loaded and you attempt to find it using Selenium, Selenium will throw an element-not-found exception.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0

This code is working for me:

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250, 350)");
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
0

If nothing works, try this before clicking:

public void mouseHoverJScript(WebElement HoverElement) {

    String mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}";
    ((JavascriptExecutor) driver).executeScript(mouseOverScript, HoverElement);
}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Prateek
  • 1,145
  • 1
  • 8
  • 21
0

The default behavior of Selenium us to scroll so the element is barely in view at the top of the viewport. Also, not all browsers have the exact same behavior. This is very dis-satisfying. If you record videos of your browser tests, like I do, what you want is for the element to scroll into view and be vertically centered.

Here is my solution for Java:

public List<String> getBoundedRectangleOfElement(WebElement we)
{
    JavascriptExecutor je = (JavascriptExecutor) driver;
    List<String> bounds = (ArrayList<String>) je.executeScript(
            "var rect = arguments[0].getBoundingClientRect();" +
                    "return [ '' + parseInt(rect.left), '' + parseInt(rect.top), '' + parseInt(rect.width), '' + parseInt(rect.height) ]", we);
    System.out.println("top: " + bounds.get(1));
    return bounds;
}

And then, to scroll, you call it like this:

public void scrollToElementAndCenterVertically(WebElement we)
{
    List<String> bounds = getBoundedRectangleOfElement(we);
    Long totalInnerPageHeight = getViewPortHeight(driver);
    JavascriptExecutor je = (JavascriptExecutor) driver;
    je.executeScript("window.scrollTo(0, " + (Integer.parseInt(bounds.get(1)) - (totalInnerPageHeight/2)) + ");");
    je.executeScript("arguments[0].style.outline = \"thick solid #0000FF\";", we);
}
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
djangofan
  • 28,471
  • 61
  • 196
  • 289
0

A solution is:

public void javascriptclick(String element)
{
    WebElement webElement = driver.findElement(By.xpath(element));
    JavascriptExecutor js = (JavascriptExecutor) driver;

    js.executeScript("arguments[0].click();", webElement);
    System.out.println("javascriptclick" + " " + element);
}
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
0

If this object passing does not works:

await browser.executeScript( "arguments[0].scrollIntoView()", await browser.wait( until.elementLocated( By.xpath( "//div[@jscontroller='MC8mtf']" ) ), 1000 ) );

There is a demonstration for scroll to microphone button, on google page. Found it by javascript xpath, using chromedriver and selenium-webdriver.

start1() start a browser in narrow window, the microphone button does not shows.

start2() start a browser in narrow window, then scroll to microphone button.

require('chromedriver');
const { Builder, 
        By, 
        Key, 
        until
      }                = require('selenium-webdriver');

async function start1()  {

  var browser = new Builder()
                    .forBrowser( 'chrome' )
                    .build();
  await browser
        .manage()
        .window()
        .setRect( { width: 80, 
                    height: 1040, 
                    x:-10, 
                    y:0} 
                );
  await browser.navigate().to( "https://www.google.com/" );
}

async function start2()  {

  var browser = new Builder()
                    .forBrowser( 'chrome' )
                    .build();
  await browser
        .manage()
        .window()
        .setRect( { width: 80, 
                    height: 1040, 
                    x:-10, 
                    y:0} 
                );
  await browser.navigate().to( "https://www.google.com/" );
  await browser.executeScript( "document.evaluate(\"//div[@jscontroller='MC8mtf']\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.scrollIntoView(true);");
}

start1();
start2();
Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
0

For OpenQA.Selenium in C#:

WebDriver.ExecuteJavaScript("arguments[0].scrollIntoView({block: \"center\", inline: \"center\"});", Element);

Where WebDriver is new ChromeDriver(options) or similar.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
Iain Ballard
  • 4,433
  • 34
  • 39
-2

Here is how I do it with PHP webDriver for Selenium. It Works for Selenium stand-alone server 2.39.0 + https://github.com/Element-34/php-webdriver + Firefox 25.0

$element=$session->welement("xpath", "//input[@value='my val']");
$element->click();
$element=$session->welement("xpath", "//input[@value='ma val2']");
$element->location_in_view(); // < -- this is the candy
$element->click();

Note: I use a customized version of the Element34 PHP-webdriver. But there is not any change in the core. I just use my "welement" instead of "element". But it makes no influence on the case in question. The driver author says "to allow almost all API calls to be a direct transformation of what is defined in the WebDriver protocol itself." So you should have no problem with other programming languages.

Just clicking will not work in my setup. It will do a scroll instead of click, so I had to click twice without calling "location_in_view()".

Note: This method works for elements that can be viewed, like an input of type button.

Take a look at: http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/location

The description for JsonWireProtocol# suggest usage of location + moveto, because location _in_view is an internal method.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
-3

Do a random click down the page:

driver.findElement(By.id("ID of a web element present below")).click

Then perform what you want to do.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33
-4

I agree with everyone here, who say "Selenium has an implicit scroll option". Also if you were in Selenium 1 and now you have upgraded yourself to Selenium 2 and look for previous version's commands, you can use the command known as:

Seleniumbackeddriver.

WebDriver driver = new FirefoxDriver();
public void setUp() throws Exception {

    String baseUrl = "http://www.google.co.in/";
    selenium = new WebDriverBackedSelenium(driver, baseUrl);
}

You could make use of these and use commands of both versions.

Benjamin Loison
  • 3,782
  • 4
  • 16
  • 33