11

I am testing my Android application using Appium framework. I have an android screen that doesn't have ids for its views (and I don't want to add...), so I thought using Xpath.

This is how the screen looks like in UI Automator Viewer: enter image description here

I want to get all the relative layouts (marked in red - sixteen items)

I tried the following:

 List<WebElement> webElementslist =
 mAppDriver.findElementsByXPath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.ViewAnimator[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.ScrollView[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[2]");

But I didn't get any items.

I searched the web and found the next xpath tutorials, tried more options, but again with no success.

http://www.zvon.org/comp/r/tut-XPath_1.html#intro

http://www.w3.org/TR/xpath/

Would appreciate any help.

Madhan
  • 5,750
  • 4
  • 28
  • 61
Ofir A.
  • 3,112
  • 11
  • 57
  • 83
  • That's looks too verbose, how about something like this: `//LinearLayout[TextView]/LinearLayout/LinearLayout/RelativeLayout`? (I'm not familiar with XPath in appium though) – har07 Oct 02 '14 at 11:41
  • Still not good, giving me zero items. I tried also less detailed, still with no results. – Ofir A. Oct 02 '14 at 11:47
  • If it is Me, I'd start with simplest XPath that return something then tweak it further to return only the elements I wanted. Is `//android.widget.LinearLayout[android.widget.TextView]` or even `//android.widget.TextView` return something? – har07 Oct 03 '14 at 09:20
  • This is what strange about it. When the xPath is only _//android.widget.TextView_ I get all the TextViews I have, but it multiplies them - if I have 16 TextViews I get 240.. – Ofir A. Oct 06 '14 at 07:11
  • Put up a gist to the server logs please. – Jess Oct 08 '14 at 21:16
  • Can you share the screen shot of the activity / page. As there can be several techniques for identifying an element. I generally use some special widget like - "ScrollView, ListView, HorizontalView" etc. to start with as my base path and continue down the hierarchy. Example - //android.widget.ScrollView[1]/android.widget.LinearLayout/android.widget.TextView[1]. Please share the screenshot if possible. – user2220762 Oct 09 '14 at 06:43
  • Sorry, can't share the screenshot - it's company property and the application is still under development. Thanks. – Ofir A. Oct 09 '14 at 18:49

4 Answers4

10

Right now there's a couple nasty bugs with XPath on android that explain the behaviors you're seeing. They are scheduled to be fixed in the 1.3.1 release

  1. You can't search by root nodes.. link
    • Unfortunately, this means that a verbose xpath is likely the xpath(pun) to success
  2. You sometimes get 240 of an element when you only have 16 link

Ideally, you could look for the resource-id of the android.widget.LinearLayout parent of all 16 RelativeLayouts and then do something like:

//android.widget.LinearLayout[@resource-id="foo"]/android.widget.RelativeLayout

Your verbose solution did not work because you gave one of the layouts a position of [2].

Here it is, fixed:

//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.ViewAnimator[1]/android.widget.FrameLayout[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.RelativeLayout[1]/android.widget.ScrollView[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout/android.widget.RelativeLayout

.... please, please use the first solution.

I'm looking into a solution for your problem using UiAutomator locator strategy, but no answers yet (because .fromChild() and .fromParent() seem to be broken)

Jess
  • 3,097
  • 2
  • 16
  • 42
  • 1
    Thanks for your answer, I will try your first solution, maybe it will solve my problem. – Ofir A. Oct 09 '14 at 18:51
  • Had a typo. You need double quotes around your resource-id in the locator. How do you usually test your locators for Appium? – Jess Oct 09 '14 at 19:10
  • Usually I'm testing my locators using resource-id, but the problem is that this screen is not a regular Android screen, he is built from json. When I'm adding ids I can't see them in the UI Automator Viewer. This is why I don't want to add anything new, but test it as is. – Ofir A. Oct 09 '14 at 19:28
  • 1
    Yeah. Ideally that would work, but Appium is very new and has lots of bugs. Often times we need to make changes to make it easier to automate. I sometimes do this with accessibility tags in iOS – Jess Oct 09 '14 at 19:51
  • searching for elements by root node explained here: https://discuss.appium.io/t/xpath-cannot-select-from-root-node/777/7 quads in the comment id!! – TinyTimZamboni Oct 09 '14 at 20:03
  • Still not good. I can't use your first solution because I don't have any ids, and the second solution gave me only the first relative layout and not all of them. – Ofir A. Oct 12 '14 at 10:31
  • I tried that also, still not good. I guess Appium is getting only the first items it encounters - I'm still getting only the first row of items. I thought Appium is a good tool to work with, now I'm not so sure... – Ofir A. Oct 13 '14 at 07:17
  • Do you have any other solution? – Ofir A. Oct 13 '14 at 13:47
  • Yeah there's a few other choices but it's a little hard to advise you just based on the hierarchy. Did @TinyTimZamboni 's solution work? – Jess Oct 13 '14 at 14:10
  • Is there anything about them that you can latch onto aside from their position in the view hierarchy? Do the Linear Layouts or scrollview have a name or accessibility id – Jess Oct 13 '14 at 14:14
  • If I had names or ids I would use them already. @TinyTimZamboni 's solution didn't work also, it's the same issue like your answer - gave only the first row. Do you have another recommended testing framework that is better than Appium, it seems that they have a lot of bugs? – Ofir A. Oct 14 '14 at 07:45
  • They do have tons of bugs, but I've tried most other frameworks. It's the most reliable, most extensible. KIF is the other good one, but all the tests to be in Obj-C and you have to modify the application to use Apple's private libs -- so when you release the app, you need to remove those libs from the build script. – Jess Oct 14 '14 at 14:16
  • KIF also doesn't play nice with CocoaPods (they might have fixed it) so it was a pain for us to integrate – Jess Oct 14 '14 at 14:26
  • 1
    is @OfirA using the latest version of appium? If my answer didn't work, it's not because of a bug in appium, it'd be because it's a bad xpath expression. Experiment and try to figure out an expression which will work, you're the only one with access to your specific layout. – TinyTimZamboni Oct 14 '14 at 19:43
  • I tried a lot of xpath expressions but all of them didn't work as expected. What is more strange is that there is no tool to get the xpath expression for Windows. The Appium tool is only supports Mac and I'm working on Windows. The Android tool doesn't have xpath option... and yes I'm working with the latest Appium version. – Ofir A. Oct 15 '14 at 22:19
  • I suggest moving this discussion to discuss.appium.io -- you'll get more results/help there. – Jess Oct 16 '14 at 19:48
3

Just try this u can access easily

driver.findElement(By.xpath("//*[@class='android.widget.FrameLayout' and @bounds='[418,564][780,885]']")).click();

Screenshot of UI

waka
  • 3,362
  • 9
  • 35
  • 54
Rajesh G
  • 31
  • 1
1

Keeping in mind the fact that //foo[1] returns all foo nodes which are the first children of a their parent (not the first child of the foo node) try something like this:

//ScrollView/LinearLayout/LinearLayout[2]/LinearLayout/RelativeLayout

Not tested, but it should give you all the RelativeLayouts which are a child of a LinearLayout which is a child of a LinearLayout which is the second child of a LinearLayout which is the child of a ScrollView.

TinyTimZamboni
  • 5,275
  • 3
  • 28
  • 24
0

The following code worked for me:

WebElement webElement = driver.findElementByXPath("//android.widget.ListView[1]/android.widget.LinearLayout[1]");

Courtesy: Unable to locate element using xpath in Appium

Yannick
  • 813
  • 8
  • 17
Mat
  • 178
  • 7