Recently encountered projects, found many elements, are not marked ID, text, content-desc,classname and many are the same, resulting in unable to locate
First, the appium1.5 and later versions discard the name attribute (such as the Name= bill, will not be supported for positioning), so the basic positioning will be the use of the ID is good. The rest is not much to say.
Second, here's a look at XPath positioning. The main scenario is that there is no ID or text, or the text is an uncontrolled value (or a value that changes, such as a text field of $10, which may change each time). In fact, the simple point is to locate by path including a level or multilevel path. By the way, there are two ways of path, one is absolute (the first tag is the reference), the other is the relative path (the other known label is the Reference), and the relative path is used as far as possible when locating.
1, first say that there is an ID or text scene using XPath case. (ID or name why not use it directly?) The following are relative paths)
The name above is deprecated, but the XPath notation, such as//android.widget.textview[@text= "Bill", is supported
For example, the above "Bill" and "I Want" ID are com.wlqq:id/title_left_btn, and assume that the current page only these two location IDs are written earlier, then you use the ID to locate the "Bill", you can use the XPath, because the ID is not unique.
Use ID to locate "bill" for:
Xpath= (//android.widget.textview[@resource-id= "COM.WLQQ:ID/TITLE_LEFT_BTN"]) [1],
Locate "I Want" for:
Xpath= (//android.widget.textview[@resource-id= "COM.WLQQ:ID/TITLE_LEFT_BTN"]) [2]
Here are three points to note:
A, the subscript is starting from 1, not 0;
b, if there is subscript, you need to enclose the preceding part in parentheses, and the front need to add xpath=, perhaps some people are accustomed to the front are added xpath=, but like I only used to write//start, do not write xpath= is the pit miserable ... It is not easy to find out because there is no writing xpath=, it may be my personal comparison pit bar.
C, and the web is not the same as the value of the tag, where the value of the class is taken =android.widget.textview instead of the label TextView to see, the specific reason did not delve into. Anyway, remember to use class instead of labels.
Also, the above is just to illustrate the use of XPath at only 1 levels, and the 1 layer is a relative path. Because no write starts from the property of the first position. XPath's writing rules are basically as few as possible. So the less hierarchy is the better. There are 1 layers that can be uniquely positioned without 2 layers. Maybe a bit of crap.
2, let's say that there is no ID or name of the scene. Take a picture first:
Now there's a scene where I'm going to navigate to the little villain icon I need to click on, but without text, ID, CONTENT-DESC, the only classname or the same as the others, the way you can think of it is XPath.
The absolute path is written as: if the first on the graph is the topmost, it is:
This, which requires 7 levels, is written in turn:
android.widget.linearlayout/android.widget.framelayout/android.widget.linearlayout/ android.widget.relativelayout/android.widget.relativelayout/android.widget.linearlayout[2]/ Android.widget.ImageButton
Note the following:
A, [2] Note is 2 instead of 3 because it is related to the value of the label. There are only 2 linearlayout.
b, the path length is too long, and because there are only class values, there may be more than one page control, which is probably not unique.
C, absolute path is rarely used, if the character is too poor, encountered the page is all no ID or name, then there is no way. or consider some coordinates.
3, (important) The use of relative paths in a scenario where no ID or name is used to locate. This paper mainly introduces the parent-child relationship (subordinate) and sibling relationship in the hierarchical relationship.
As you can see, there is a unique Chinese word in this picture-"purse". We can use this purse to locate our villain's picture. Analyze the position relationship first
Looking for a relationship that is, the villain Icon 3 is the wallet 1 brother 2LinearLayout tagged son ImageButton. The son understands that the hierarchical relationship of XPath is the parent-child relationship used/expressed. Android.widget.linearlayout/android.widget.imagebutton that would be the son of a brother. But now the question is, how do you show your wallet's brother? There is an axis in XPath, and a simple point can be understood as a function. I think so. Preceding-sibling:: Can be found in front of the node is the elder brother node, following-sibling:: You can find the node behind the younger brother node, about the axis of more usage ah, can self-Baidu XPath grammar. There is one more use of the parent::, you can find the node's father node. But the Father node can be used. Said. Here's how to use it specifically:
The basics have been introduced here. So the positioning method here is 3 levels://android.widget.textview[@text= "wallet"]/following-sibling:: Android.widget.linearlayout/android.widget.imagebutton. The first level is the only one to find the wallet this position, the next level is the wallet brother, that is following-sibling::android.widget.linearlayout. Of course, because it is next to each other, so the younger brother did not work, imagine if it is the first few brothers, add a subscript bar. Brother is the same.
In front of the use of the relationship between brothers, the following talk about the relationship between the son and father. A parent-child relationship or a diagram to illustrate
Our wallet 1 Father 2 has a son 3 son 4 is our villain icon. This is about finding a relationship. Relationship has been found, then we can use this relationship to write XPath.
The second class= of the Father (/parent::android.widget.relativelayout) of the purse (//android.widget.textview[@text= "wallet") Android.widget.LinearLayout son (/android.widget.linearlayout[2]) son (villain/android.widget.imagebutton), good, we connect up is:// android.widget.textview[@text= "wallet"]/parent::android.widget.relativelayout/android.widget.linearlayout [2]/android.widget.imagebutton.
By the way, father, this location can be used. To replace, compared to many people know. In the path refers to the superior. So you can use//android.widget.textview[@text= "wallet"]/. /android.widget.linearlayout[2]/android.widget.imagebutton this to replace the above notation.
Note: Finally, again, about this place, the subscript is [2], because it is only related to the same class. The wallet is not the same class. So it's not going to be okay.
On the relative path of the parent-child relationship, as well as brotherhood, compared to people should have some experience. If you still don't understand, let's take a more complicated example. Maybe it's just an example of the syntax. The actual following may not be so complicated to write. First:
Suppose we need to locate our immediate position button by adding to the shopping cart, then one of our writing is the relationship 7 level on the graph. That is, add the cart 7 (//android.widget.textview[@text= "add to Cart"]) of the Father 1 (/.. ) Father of 2 (/.. Father of 3 (/..) The second brother of 4 (/following-sibling::android.view.view[2]) son of 5 (/android.view.view) son 6 (i.e. our immediate purchase/ Android.widget.TextView),
It's even.
android.widget.textview[@text= "Add to Cart"]/. /.. /.. /following-sibling::android.view.view[2]/android.view.view/android.widget.textview.
Note: When using text, avoid using the input box's default input value, because when you actually enter a value, there is no text, and you cannot find the path. In addition, you can use fuzzy matching, XPath has a contains function. Usage//android.widget.textview[contains (@text, "Shopping cart"). You can also find the "Add to Cart" location.
Scene: Locate Please enter the password this input box, no ID, text, Content-desc,classname also have a lot of repetition
Using XPath, handwriting positioning
1. Select the login button as the node first
android.widget.textview[@text = ' Login ']
2. Re-locate to Parent
/.. That's/parent::android.view.view.
3, re-location sibling brother
/PRECEDING-SIBLING::ANDROID.VIEW.VIEW[1]
Note: [1], subscript is up number, apply to preceding-sibling
If it is following-sibling, then the number down
It's all starting from 1 to remove the label
4. Re-locate the child
Child::android.widget.edittext
To connect it together is:
android.widget.textview[@text = ' login ']/. /preceding-sibling::android.view.view[1]/child::android.widget.edittext
appium-on the XPath localization problem of Appium native control and its common methods