-
-
Notifications
You must be signed in to change notification settings - Fork 767
Closed
Description
java-client : 2.1.0
appium server : 1.3.4
i want to get all the android.widget.RelativeLayout elements which is child of the ListView.
java code:
AndroidDriver appDriver;
List<WebElement> list = appDriver.findElementsByAndroidUIAutomator("new UiSelector().className(\"android.widget.ListView\").childSelector(new UiSelector().className(\"android.widget.RelativeLayout\"))");
System.out.print(list.size());
for(int i = 0; i <= list.size() - 1; i++){
System.out.println("i==" + i + " " + list.get(i).getLocation().getX());
System.out.println("i==" + i + " " + list.get(i).getLocation().getY());
}
it only find the first android.widget.RelativeLayout which is child of android.widget.ListView.
appium.log:
> info: --> POST /wd/hub/session/5bd47fe5-edc4-461c-a40a-47eda889cd16/elements {"using":"-android uiautomator","value":"new UiSelector().className(\"android.widget.ListView\").childSelector(new UiSelector().className(\"android.widget.RelativeLayout\"))"}
> info: [debug] Waiting up to 1000ms for condition
> info: [debug] Pushing command to appium work queue: ["find",{"strategy":"-android uiautomator","selector":"new UiSelector().className(\"android.widget.ListView\").childSelector(new UiSelector().className(\"android.widget.RelativeLayout\"))","context":"","multiple":true}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"-android uiautomator","selector":"new UiSelector().className(\"android.widget.ListView\").childSelector(new UiSelector().className(\"android.widget.RelativeLayout\"))","context":"","multiple":true}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: find
> info: [debug] [BOOTSTRAP] [debug] Finding new UiSelector().className("android.widget.ListView").childSelector(new UiSelector().className("android.widget.RelativeLayout")) using ANDROID_UIAUTOMATOR with the contextId: multiple: true
> info: [debug] [BOOTSTRAP] [debug] Parsing selector: new UiSelector().className("android.widget.ListView").childSelector(new UiSelector().className("android.widget.RelativeLayout"))
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: java.lang.Class<T> arg: "android.widget.ListView"
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class java.lang.String arg: "android.widget.ListView"
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class com.android.uiautomator.core.UiSelector arg: new UiSelector().className("android.widget.RelativeLayout")
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: java.lang.Class<T> arg: "android.widget.RelativeLayout"
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class java.lang.String arg: "android.widget.RelativeLayout"
> info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[CLASS=android.widget.ListView, CHILD=UiSelector[CLASS=android.widget.RelativeLayout]]
> info: [debug] [BOOTSTRAP] [debug] getElements selector:UiSelector[CLASS=android.widget.ListView, CHILD=UiSelector[CLASS=android.widget.RelativeLayout]]
> info: [debug] [BOOTSTRAP] [debug] Element[] is null: (0)
> info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.ListView, INSTANCE=0, CHILD=UiSelector[CLASS=android.widget.RelativeLayout]]
> info: [debug] [BOOTSTRAP] [debug] Element[] is null: (1)
> info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.ListView, INSTANCE=1, CHILD=UiSelector[CLASS=android.widget.RelativeLayout]]
> info: [debug] [BOOTSTRAP] [debug] Updating class "class com.android.uiautomator.core.UiDevice" to enable field "mUiAutomationBridge"
> info: [debug] [BOOTSTRAP] [debug] Updating class "class com.android.uiautomator.core.UiAutomatorBridge" to enable field "mInteractionController"
> info: [debug] [BOOTSTRAP] [debug] Finding methods on class: class com.android.uiautomator.core.UiObject
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":[{"ELEMENT":"22"}],"status":0}
> info: [debug] Responding to client with success: {"status":0,"value":[{"ELEMENT":"22"}],"sessionId":"5bd47fe5-edc4-461c-a40a-47eda889cd16"}
> info: <-- POST /wd/hub/session/5bd47fe5-edc4-461c-a40a-47eda889cd16/elements 200 111.159 ms - 90 {"status":0,"value":[{"ELEMENT":"22"}],"sessionId":"5bd47fe5-edc4-461c-a40a-47eda889cd16"}
> info: --> GET /wd/hub/session/5bd47fe5-edc4-461c-a40a-47eda889cd16/element/22/location {}
> warn: location will be removed in a future version of Appium, please use location_in_view
> info: [debug] Pushing command to appium work queue: ["element:getLocation",{"elementId":"22"}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:getLocation","params":{"elementId":"22"}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: getLocation
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":{"y":272,"x":0},"status":0}
> info: [debug] Responding to client with success: {"status":0,"value":{"y":272,"x":0},"sessionId":"5bd47fe5-edc4-461c-a40a-47eda889cd16"}
> info: <-- GET /wd/hub/session/5bd47fe5-edc4-461c-a40a-47eda889cd16/element/22/location 200 41.363 ms - 87 {"status":0,"value":{"y":272,"x":0},"sessionId":"5bd47fe5-edc4-461c-a40a-47eda889cd16"}
> info: --> GET /wd/hub/session/5bd47fe5-edc4-461c-a40a-47eda889cd16/element/22/location {}
> info: [debug] Pushing command to appium work queue: ["element:getLocation",{"elementId":"22"}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:getLocation","params":{"elementId":"22"}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: getLocation
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":{"y":272,"x":0},"status":0}
> info: [debug] Responding to client with success: {"status":0,"value":{"y":272,"x":0},"sessionId":"5bd47fe5-edc4-461c-a40a-47eda889cd16"}
> info: <-- GET /wd/hub/session/5bd47fe5-edc4-461c-a40a-47eda889cd16/element/22/location 200 25.430 ms - 87 {"status":0,"value":{"y":272,"x":0},"sessionId":"5bd47fe5-edc4-461c-a40a-47eda889cd16"}
> info: --> DELETE /wd/hub/session/5bd47fe5-edc4-461c-a40a-47eda889cd16 {}
and use fromParent can only get the first element:
code:
List<WebElement> list2 = appDriver.findElementsByAndroidUIAutomator("new UiSelector().className(\"android.widget.ListView\").childSelector(new UiSelector().className(\"android.widget.RelativeLayout\")).fromParent(new UiSelector().className(\"android.widget.RelativeLayout\"))");
System.out.print(list2.size());
for(int i = 0; i <= list2.size() - 1; i++){
System.out.println("i==" + i + " " + apm.getCenterY(appDriver,list2.get(i)));
System.out.println("i==" + i + " " + list2.get(i).getLocation().getY());
}
appium.log
> info: --> POST /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/elements {"using":"-android uiautomator","value":"new UiSelector().className(\"android.widget.ListView\").childSelector(new UiSelector().className(\"android.widget.RelativeLayout\")).fromParent(new UiSelector().className(\"android.widget.RelativeLayout\"))"}
> info: [debug] Waiting up to 1000ms for condition
> info: [debug] Pushing command to appium work queue: ["find",{"strategy":"-android uiautomator","selector":"new UiSelector().className(\"android.widget.ListView\").childSelector(new UiSelector().className(\"android.widget.RelativeLayout\")).fromParent(new UiSelector().className(\"android.widget.RelativeLayout\"))","context":"","multiple":true}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"find","params":{"strategy":"-android uiautomator","selector":"new UiSelector().className(\"android.widget.ListView\").childSelector(new UiSelector().className(\"android.widget.RelativeLayout\")).fromParent(new UiSelector().className(\"android.widget.RelativeLayout\"))","context":"","multiple":true}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: find
> info: [debug] [BOOTSTRAP] [debug] Finding new UiSelector().className("android.widget.ListView").childSelector(new UiSelector().className("android.widget.RelativeLayout")).fromParent(new UiSelector().className("android.widget.RelativeLayout")) using ANDROID_UIAUTOMATOR with the contextId: multiple: true
> info: [debug] [BOOTSTRAP] [debug] Parsing selector: new UiSelector().className("android.widget.ListView").childSelector(new UiSelector().className("android.widget.RelativeLayout")).fromParent(new UiSelector().className("android.widget.RelativeLayout"))
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: java.lang.Class<T> arg: "android.widget.ListView"
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class java.lang.String arg: "android.widget.ListView"
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class com.android.uiautomator.core.UiSelector arg: new UiSelector().className("android.widget.RelativeLayout")
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: java.lang.Class<T> arg: "android.widget.RelativeLayout"
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class java.lang.String arg: "android.widget.RelativeLayout"
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class com.android.uiautomator.core.UiSelector arg: new UiSelector().className("android.widget.RelativeLayout")
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: java.lang.Class<T> arg: "android.widget.RelativeLayout"
> info: [debug] [BOOTSTRAP] [debug] UiSelector coerce type: class java.lang.String arg: "android.widget.RelativeLayout"
> info: [debug] [BOOTSTRAP] [debug] Using: UiSelector[CLASS=android.widget.ListView, CHILD=UiSelector[CLASS=android.widget.RelativeLayout, PARENT=UiSelector[CLASS=android.widget.RelativeLayout]]]
> info: [debug] [BOOTSTRAP] [debug] getElements selector:UiSelector[CLASS=android.widget.ListView, CHILD=UiSelector[CLASS=android.widget.RelativeLayout, PARENT=UiSelector[CLASS=android.widget.RelativeLayout]]]
> info: [debug] [BOOTSTRAP] [debug] Element[] is null: (0)
> info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.ListView, INSTANCE=0, CHILD=UiSelector[CLASS=android.widget.RelativeLayout, PARENT=UiSelector[CLASS=android.widget.RelativeLayout]]]
> info: [debug] [BOOTSTRAP] [debug] Element[] is null: (1)
> info: [debug] [BOOTSTRAP] [debug] getElements tmp selector:UiSelector[CLASS=android.widget.ListView, INSTANCE=1, CHILD=UiSelector[CLASS=android.widget.RelativeLayout, PARENT=UiSelector[CLASS=android.widget.RelativeLayout]]]
> info: [debug] [BOOTSTRAP] [debug] Updating class "class com.android.uiautomator.core.UiDevice" to enable field "mUiAutomationBridge"
> info: [debug] [BOOTSTRAP] [debug] Updating class "class com.android.uiautomator.core.UiAutomatorBridge" to enable field "mInteractionController"
> info: [debug] [BOOTSTRAP] [debug] Finding methods on class: class com.android.uiautomator.core.UiObject
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":[{"ELEMENT":"22"}],"status":0}
> info: [debug] Responding to client with success: {"status":0,"value":[{"ELEMENT":"22"}],"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
> info: <-- POST /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/elements 200 242.106 ms - 90 {"status":0,"value":[{"ELEMENT":"22"}],"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
> info: --> GET /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/element/22/displayed {}
> info: [debug] Pushing command to appium work queue: ["element:getAttribute",{"elementId":"22","attribute":"displayed"}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:getAttribute","params":{"elementId":"22","attribute":"displayed"}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: getAttribute
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":"true","status":0}
> info: [debug] Responding to client with success: {"status":0,"value":true,"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
> info: <-- GET /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/element/22/displayed 200 53.573 ms - 76 {"status":0,"value":true,"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
> info: --> GET /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/element/22/location {}
> warn: location will be removed in a future version of Appium, please use location_in_view
> info: [debug] Pushing command to appium work queue: ["element:getLocation",{"elementId":"22"}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:getLocation","params":{"elementId":"22"}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: getLocation
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":{"y":272,"x":0},"status":0}
> info: [debug] Responding to client with success: {"status":0,"value":{"y":272,"x":0},"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
> info: <-- GET /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/element/22/location 200 26.538 ms - 87 {"status":0,"value":{"y":272,"x":0},"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
> info: --> GET /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/element/22/size {}
> info: [debug] Pushing command to appium work queue: ["element:getSize",{"elementId":"22"}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:getSize","params":{"elementId":"22"}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: getSize
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":{"height":276,"width":1440},"status":0}
> info: [debug] Responding to client with success: {"status":0,"value":{"height":276,"width":1440},"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
> info: <-- GET /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/element/22/size 200 25.118 ms - 99 {"status":0,"value":{"height":276,"width":1440},"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
> info: --> GET /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/element/22/location {}
> info: [debug] Pushing command to appium work queue: ["element:getLocation",{"elementId":"22"}]
> info: [debug] [BOOTSTRAP] [debug] Got data from client: {"cmd":"action","action":"element:getLocation","params":{"elementId":"22"}}
> info: [debug] [BOOTSTRAP] [debug] Got command of type ACTION
> info: [debug] [BOOTSTRAP] [debug] Got command action: getLocation
> info: [debug] [BOOTSTRAP] [debug] Returning result: {"value":{"y":272,"x":0},"status":0}
> info: [debug] Responding to client with success: {"status":0,"value":{"y":272,"x":0},"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
> info: <-- GET /wd/hub/session/d8f97ee6-8efc-41b8-86ac-73b0159ace07/element/22/location 200 23.356 ms - 87 {"status":0,"value":{"y":272,"x":0},"sessionId":"d8f97ee6-8efc-41b8-86ac-73b0159ace07"}
Activity
[-]why findElementsByAndroidUIAutomator can only get the first element ,not all elements if uiAutomator expression with childSelector or fromParent ?[/-][+]findElementsByAndroidUIAutomator can only get the first element ,not all elements if uiAutomator expression with childSelector or fromParent ?[/+]liqing380 commentedon Feb 3, 2015
so,how to user findElementsByAndroidUIAutomator to get all elements which are children of another element?
is there anything wrong with my uiatomator expression ? or is something wrong whith findElementsByAndroidUIAutomator ?
Jonahss commentedon Feb 3, 2015
Hmm, you're UIAutomator expression looks ok. The way I would debug this is by creating an actual UIAutomator test and trying the selector from there, have it print the elements it returns.
Or you can try similar queries on other classes. It could end up being a bug in the way we parse UiSelector expressions.
vietnq254 commentedon Feb 11, 2015
I have the same problem with this function!
I used:
liqing380 commentedon Feb 26, 2015
@Jonahss yes,i have try similar queries on other classes,got the same problem
Jonahss commentedon Mar 2, 2015
Hm, to eliminate other sources of error, the next step is to create a regular UiAutomation test, through the usual Android testing method, and see if the same expression works there.
wanmich commentedon May 10, 2016
You might want to try this:
List<WebElement> list1 = driver.findElementsByAndroidUIAutomator("new UiSelector().className("+"android.widget.ListView"+").className(\"android.widget.RelativeLayout\")");
aquintiliano commentedon Jun 16, 2016
@wanmich why are you using "+" instead of "?
jeitae commentedon Mar 6, 2017
try using only UiSelector().className("android.widget.ListView") and get fields like list1.get(index)
saikrishna321 commentedon May 25, 2017
@SrinivasanTarget close this... Inactive thread
jcyrss commentedon Jun 5, 2017
closed ,why?
I met the same issue with python client . And I really doubt it is a bug of appium server.
with the following , I get only one element returned. But actually we have 4 elements matched.
but only append a 'instance(3)' at the end of java code statment, I get another element matched.
It seems obviously the issue of appium server.
jeitae commentedon Jun 5, 2017
i have this on java:
@AndroidFindBy(uiAutomator = "new UiSelector().resourceId("com.application.activities:id/iconImageView")")
public List< MobileElement > products;
products.get(0).click();
products.get(1).click();
products.get(2).click();
products.get(n).click();
kirillbilchenko commentedon Jun 11, 2017
Confirm see the same thing example is:
((AndroidDriver)getDriver()).findElementsByAndroidUIAutomator("new UiSelector().resourceIdMatches(".id/notificationFrame.").childSelector(new UiSelector().resourceIdMatches(".id/friendShip."))")
result is 1 element
and ((AndroidDriver)getDriver()).findElementsByAndroidUIAutomator("new UiSelector().resourceIdMatches(".id/friendShip.")")
result is 2 elements in the list
@SrinivasanTarget
lanzelot1989 commentedon Sep 5, 2017
Has anybody been able to tackle this?
Could this be reopened, I am facing the same issue on the C# driver of Appium.
olescheller commentedon Sep 7, 2017
I can confirm this problem still exists in Appium version 1.6.5.
For now I suggest to use a xpath query string if you need to match more than 1 element.
anthonypdawson commentedon Jan 14, 2018
Still an issue - noticed when using the helper app. Using a selector like this should have returned more than one element (note: 'container_id' matches a single element, while 'another_id' matches multiple)
Returns a single element
Returns 4 elements
Returns 4 elements
Tried fromParent thinking that maybe it wouldn't limit the return, but it still doesn't work quite correctly
Returned no elements
Kignuf commentedon Mar 16, 2018
+1 to this bug. It is easily reproducible, provided you have an app with one container element and multiple child elements.
@anthonypdawson sumarized this well.
Refactorings.
mike-pt commentedon Mar 1, 2019
I'm seeing the same issue with this in python:
self.driver.find_elements_by_android_uiautomator('new UiSelector().resourceId("%s").childSelector(new UiSelector().resourceId("%s"))' % (parentID, childID))
I wonder does this still happen for the folks using java client?
mike-pt commentedon Mar 1, 2019
Also my workaround for this right now it to use find_element_by_android_uiautomator so I get a UiObject then from that find_elements_by_android_uiautomator:
self.driver.find_element_by_android_uiautomator('new UiSelector().resourceId("parentID")').find_elements_by_android_uiautomator('new UiSelector().resourceId("childID")')
Which seems to work fine
Jonahss commentedon Mar 1, 2019
@mike-pt @Kignuf If you supply a simple sample app for me to reproduce this issue on, I can hunt it down.
The issue is either with the UiAutomator framework in Android, or more likely, has to do with the javascript parser, which takes in a string and then parses it and uses reflection to build the Java statement which runs on the device.
A good way of testing would be to take the app and then write a UiAutomator test (rather than Appium) to see if the
childSelector
works as expected. If it works, then I can fix the js parser.mike-pt commentedon Mar 1, 2019
Interesting you said that, cause using the "uiautomatorviewer" (included in appium) the same selector also just picks the first, which means that maybe the issue is in appium not any of the "clients" ?
But I can certainly try to import UiAutomator and see how that works, I actually considered it since it seems you can do some cool stuff with
UiObject
rather then a WebElement and find_by uiautomatorJonahss commentedon Mar 1, 2019
Oh yeah. It's definitely not an issue with the client. All the clients just send this as text to be interpreted by Appium.