125

I am still learning and in response to one of my questions: here, I was told to that it might be due because the element in question is not in view.

I looked through the documentation and SO, here was the most relevant answer: here

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

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

When I try to use the above to scroll to the element: It says WebElement not defined.

I think this is because I have not imported the relevant module. Can someone point out what I am supposed to import?

Edit: As pointed out by alecxe, this was java code.

But in the meantime right after trying to figure it out for some time. I have found out the import method for WebElement:

from selenium.webdriver.remote.webelement import WebElement

Might help someone like me.

The how of it is also a good lesson, IMO:

Went to: Documentation The

class selenium.webdriver.remote.webelement.WebElement(parent, id_, w3c=False)

Need to be separated into the command form mentioned above.

8 Answers 8

226

You are trying to run Java code with Python. In Python/Selenium, the org.openqa.selenium.interactions.Actions are reflected in ActionChains class:

from selenium.webdriver.common.action_chains import ActionChains

element = driver.find_element_by_id("my-id")

actions = ActionChains(driver)
actions.move_to_element(element).perform()

Or, you can also "scroll into view" via scrollIntoView():

driver.execute_script("arguments[0].scrollIntoView();", element)

If you are interested in the differences:

Sign up to request clarification or add additional context in comments.

6 Comments

Ah...there I was for 3 hours trying every method I found on SO and the documentation. I tried the first solution but must have messed it up somehow. I will read the ScrollIntoView Vs moveToElement. Just a quick question, I need the same steps to be done 100 times, I am thinking of using a for loop. Would this be a good approach?
will move_to_element(ele).perform() simply scroll to an element, even if the element isn't currently in view?
@alecxe I don't get how this works (it doesn't with my project) because how can selenium find the object to scroll to if the object isn't visible? Mine is unable to locate the element that I want it to scroll to.
When I called move_to as you suggested, I got selenium.common.exceptions.MoveTargetOutOfBoundsException: Message: (164, 1297) is out of bounds of viewport width (1366) and height (694). I'm grateful for your answer and I think this IS the way (and also I've learned about ActionChains from your answer), but looks like it needs a bit of improvement. Thanks1
find_element_by_id is now: element = driver.find_element(By.ID,'my-id'), as you can see here
|
78

It's not a direct answer on question (its not about Actions), but it also allow you to scroll easily to required element:

element = driver.find_element_by_id('some_id')
element.location_once_scrolled_into_view

This actually intend to return you coordinates (x, y) of element on page, but also scroll down right to target element

6 Comments

Thanks @Andersson I was trying to find the way to do this since you pointed out this might be the problem on the other question. :)
at first i appended () behind, and error ''dict' object is not callable', i checked the element type is WebElement. then i removed () and worked. isn't this a method? I mean, why no () need?
@LeiYang, because location_once_scrolled_into_view is a Python property. Properties takes no arguments (except object instance -self) and should be called without parenthesis
@Andersson .move_to_element() didn't work for me (I commented on alecxe answer) but yours solution did. THANKS!
@LeiYang Here is the source code about location_once_scrolled_into_view, to help explain why () not need : selenium/webelement.py at d3b6ad006bd7dbee59f8539d81cee4f06bd81d64 · SeleniumHQ/selenium
|
16

In addition to move_to_element() and scrollIntoView() I wanted to pose the following code which attempts to center the element in the view:

desired_y = (element.size['height'] / 2) + element.location['y']
window_h = driver.execute_script('return window.innerHeight')
window_y = driver.execute_script('return window.pageYOffset')
current_y = (window_h / 2) + window_y
scroll_y_by = desired_y - current_y

driver.execute_script("window.scrollBy(0, arguments[0]);", scroll_y_by)

2 Comments

Thanks for your solution, tried other ways but element wasnt clickable. Some time not enought scroll, element was under "Chat box" on bottom, other code too much scroll element was on top below. menu
An easier way to do this is simply: driver.execute_script('arguments[0].scrollIntoView({block: "center", inline: "center"})', elem)
8

Example:

driver.execute_script("arguments[0].scrollIntoView();", driver.find_element_by_css_selector(.your_css_selector))

This one always works for me for any type of selectors. There is also the Actions class, but for this case, it is not so reliable.

Comments

2

This can be done using driver.execute_script():-

driver.execute_script("document.getElementById('myelementid').scrollIntoView();")

Comments

1

This might be helpful to whoever gets here, as the methods in the top answer here didn't work for me - actions.move_to_element(element).perform() did nothing, and driver.execute_script("arguments[0].scrollIntoView();", element) scrolled the view so the element was obscured by a floating menu bar positioned on top of the view. What worked for me was using scrollIntoView with options that centered it in the view, to make sure it was clickable:

driver.execute_script('arguments[0].scrollIntoView({block: "center", inline: "center"})', elem)

Comments

0

There is another option to scroll page to required element if element has "id" attribute

If you want to navigate to page and scroll down to element with @id, it can be done automatically by adding #element_id to URL...

Example

Let's say we need to navigate to Selenium Waits documentation and scroll page down to "Implicit Wait" section. We can do

driver.get('https://selenium-python.readthedocs.io/waits.html')

and add code for scrolling...OR use

driver.get('https://selenium-python.readthedocs.io/waits.html#implicit-waits')

to navigate to page AND scroll page automatically to element with id="implicit-waits" (<div class="section" id="implicit-waits">...</div>)

Comments

0

You can scroll to the element by using javascript through the execute_javascript method. For example here is how I do it using SeleniumLibrary on Robot Framework:

web_element = self.selib.find_element(locator)
self.selib.execute_javascript(
    "ARGUMENTS",
    web_element,
    "JAVASCRIPT",
    'arguments[0].scrollIntoView({behavior: "instant", block: "start", inline: "start"});'
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.