How to scroll in Appium using python

all the above option are not working for python

You need to provide much more detail for anyone to be able to offer assistance.

Pretend you’re filing a bug report - tell us about your AUT and environment, provide steps you’re attempting (your Python code), include app XML (self.driver.page_source or Cop XML from inspector), and any Appium logging for the failure.

Hi,
how to scroll to a particular content in python.

That was already covered above: driver.execute_script("mobile: scrollTo", {"element": <webdriver object element>.id})

could you plz tell how to find the element by id bcoz I am not able to find the element by id

one more question for hybrid apps I am not abe to find the web elements in UI Automator, for native apps, I could find the web elements.

You can get the webdriver element using whatever method you wish, then substitute that element for <webdriver object element> in the scrollTo code. Such as:

el = self.driver.find_element_by_xpath(<your_xpath>) driver.execute_script("mobile: scrollTo", {"element": el.id})

For Webview you need to switch to the Webview, then access the webview elements using Selenium code, then switch back to Nativeview before interacting with the native elements. Again, this is covered in posts above.

"You can read more details in this thread: Mobile: scrollTo fails in iOS hybrid webview "

I tried using the method you mentioned: try an operation on an element and appium handles the scroll to the element.
It doesnt work for my python client. If the elment is not in the field of view( which is why we need a scroll) it raises : NoSuchElementException: Message: An element could not be located on the page using the given search parameters.

I also tried using the below but to no avail:
scrollobj=dict(direction=“down”, element=self.driver.find_element_by_name(“SUITS & BLAZERS”))
self.driver.execute_script(“mobile: scrollTo”,scrollobj)

Error:

ERROR: testcategory_men (main.TestHomeScreendisplay)

Traceback (most recent call last):
File “android_piQit.py”, line 65, in testcategory_men
scrollobj=dict(direction=“down”, element=self.driver.find_element_by_name(“SUITS & BLAZERS”))
File “/Library/Python/2.7/site-packages/selenium-2.46.0-py2.7.egg/selenium/webdriver/remote/webdriver.py”, line 324, in find_element_by_name
return self.find_element(by=By.NAME, value=name)
File “/Library/Python/2.7/site-packages/selenium-2.46.0-py2.7.egg/selenium/webdriver/remote/webdriver.py”, line 684, in find_element
{‘using’: by, ‘value’: value})[‘value’]
File “/Library/Python/2.7/site-packages/selenium-2.46.0-py2.7.egg/selenium/webdriver/remote/webdriver.py”, line 195, in execute
self.error_handler.check_response(response)
File “/Library/Python/2.7/site-packages/Appium_Python_Client-0.14-py2.7.egg/appium/webdriver/errorhandler.py”, line 29, in check_response
raise wde
NoSuchElementException: Message: An element could not be located on the page using the given search parameters.


Could you suggest aby other alternative. Like you said it is still a achallenge in appium for python clients. I have tried using many alternatives and while most dont work, the ones that do, do not have any effect on the native app.
I tried using the operation : driver.press(x=100,y=100).move_to(x=100,y=300).release().perform()
using valid cordinates and even though the code worked flawlessly,the screen did not show any signs of scroll.

Based on File "android_piQit.py", line 65, in testcategory_men it looks like you’re working with Android. Everything I’ve personally stated above is based my iOS testing experience thus far.

I’ve just begun working on Android testing, and just finally made it into views where the data exceeds the vertical screen space so I’m in the same boat as you right now. I’ll post details when I [hopefully] figure out some of the various options. Initially it seems like I’ll have to poll the raw page_source which will document ALL of the elements, including out-of-view elements, then leveraging that information to scroll. Or so I think… :slight_smile:

Scratch that, page_source fails to show all of the elements like I thought it would.

Thanks, I will try that out too.
Will update here if I am able to get things ‘rolling’(literally) myself.

Here’s a successful method to scroll in Android.

element_to_tap = self.driver.find_element_by_xpath(<xpath_to_element_near_bottom_of_screen>) element_to_drag_to = self.driver.find_element_by_xpath(<xpath_to_element_near_top_of_screen>) self.driver.scroll(element_to_tap, element_to_drag_to)

All you need to do is feed it two webdriverobjects, it seems to do the rest. But I haven’t fully validated it works in all of my scenarios, that it can scroll down as well as up, that it doesn’t over-scroll, etc.

It doesn’t look like Android will ever provide page_source that contains out-of-view elements, including after you scroll (items at the top of the page are now out-of-view after a scroll and are dropped from XML). So there’s going to have to be some pretty clever functions coded to support all of the various scrolling I will need to do.

For example, many of my tests need to count the number of rows //android.widget.ListView/android.widget.LinearLayout in my view to make sure it matches summary counts elsewhere in the app. I’m going to need to scroll, count up the visible rows, scroll more, count up the visible rows making sure not to count ones already counted (guess I’ll have to keep track of some hopefully visible unique identifier in each row), and stop counting once the list has beens scrolled (again keeping track of hopefully visible unique identifier and stop scrolling once no new uniques appear after a scroll). It all seems overly complicated. I’d think by now these would be basic functions provided by Appium.

I’m hoping someone with more experience will chime in with the “best” way to do this.

4 Likes

Hey Christopher,

Thanks for the details. Not sure to understand why we cannot do that for iOS part.

I also found scrollTo for iOS, but it seems to be used to scroll in a UITableView to a content, not to a defined cell / web element.

Do you have an other way to do that than avoiding a script?

scrollTo is only implemented in the iOS native context. I haven’t personally attempted scrolling in iOS WebView at this time.

You can try: "mobile: scroll" in the Webview. I don’t have more specific details, unfortunately.

According this: https://github.com/appium/appium/issues/3974 the answer is: “…the correct way to achieve what you want is to use mobile: scroll and then check that the element in question is within the bounds of the viewport.”

Okay thanks, however, I wasn’t be able to make scrollTo work for native context in iOS.

According to this one, Scroll To / Swipe Action in iOS 8 it’s not working anyway.

@Christopher_Graham thanks a lot for the solution.
Guys this worked perfectly for me in Android Native app - Real device testing.

Did anyone find a way to scroll down in a Hybrid App Ios and Android? Please help me with this.

Im getting this error"

Traceback (most recent call last):
File “appium_test.py”, line 27, in
action.press(el).move_to(x=10, y=-500).release().perform()
File “C:\Python27\lib\site-packages\appium\webdriver\common\touch_action.py”, line 94, in perform
self._driver.execute(Command.TOUCH_ACTION, params)
File “C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py”, line 196, in execute
self.error_handler.check_response(response)
File “C:\Python27\lib\site-packages\appium\webdriver\errorhandler.py”, line 24, in check_response
super(MobileErrorHandler, self).check_response(response)
File “C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py”, line 103, in check_response
status = value[‘status’]
TypeError: string indices must be integers

Appium 1.5

el = self.driver.find_element_by_xpath(“xpath”)
self.driver.execute_script(“mobile: scroll”, {“direction”: ‘down’, ‘element’: el})

I have tested this on apk: APIDemo.apk

def test_swipe(self):
x = []
sleep(1)
self.driver.find_element_by_name(“Views”).click()
sleep(1)
while x == []: #Perform below till i get the desired item which i am looking for. In this case the item is in second page
x = self.driver.find_elements_by_name(“Grid”)
if x == []: #Perform the scroll only if not able to locate the desired item in current screen
size = self.driver.get_window_size()
starty = int(size[“height”] * 0.80)
endy = int(size[“height”]*0.20)
startx = int(size[“width”]/2)
sleep(2)
self.driver.swipe(startx, starty, startx, endy, 3000) #Swipe from bottom to top
sleep(2)
else:
pass
sleep(1)
x[0].click()

Python - iOS

el = self.driver.find_element_by_id(‘Logout’)
self.driver.execute_script(‘mobile: scroll’, {“element”: el, “toVisible”: True})

Python - Android.

Change the value of end_y depending on how much you try to scroll down for each swipe.

self.driver.swipe(470, 1400, 470, 1200, 400)

driver.swipe(start_x, start_y, end_x, end_y, duration)

1 Like