Enumerate all elements in Selenium Python bindings for Appium Enumerate all elements in Selenium Python bindings for Appium selenium selenium

Enumerate all elements in Selenium Python bindings for Appium


I still would like a way to introspect the Selenium interface from Python. But I have found a workable way to get a clear image of how the app is laid out, and it's pretty easy to then figure out how to write the Selenium tests.

First, get your app running, either on a real device connected to your Android development computer or in an emulator. Basically if you run adb devices you want to see a single device, the one running your app. Next, run the uiautomatorviewer tool, and then click on the Device Screenshot toolbar icon. (There are only two toolbar icons: the first is the Open icon and looks like a file folder, and the one you want looks like a stack of mobile phones.)

Once you have done that, an image of your app appears, with a screenshot on the left, and a browsable tree outline on the right. The outline shows all the controls of the app, along with their text labels if any, and other information (such as whether the clickable property is true or false for that control).

One warning: the controls are shown numbered, but in the Selenium bindings, the numbers might not be the same. On the ApiDemos example app, the Graphics button has index number 4 as it is the fifth button, but to access it by its position I had to use index 5. Index 0 was a non-clickable object holding the text "API Demos", in a different FrameLayout object making up the header for the screen.

So, I was able to make this change to the android.py script:

#elem = driver.find_element_by_name('Graphics')elem = driver.find_elements_by_tag_name('TextView')[5]

Comment out the driver.find_element_by_name() call, and instead find the sixth TextView in the entire app. That's not best practice but it shows that the uiautomationviewer results do let me view the stuff I need to know about the controls.

Now I know enough to do a little bit of introspection:

for elem in driver.find_elements_by_tag_name('TextView'):    if elem.text == "Graphics":        breakelse:    print("Could not find desired item")

This isn't better than just calling driver.find_element_by_name() but it shows that I am on the right track.

uiautomatorviewer is a practical solution to my problem. If you have a pure-Python one please let me know about it.


Appium supports WebDriver's "page source" method. So you can do this:

# assume you have a driver objectimport jsonsource = driver.page_sourcesource = json.loads(source)# you can now work with source as a python object