How can i remake XPath locators to UIAutomation locators?
Example this xpath locator:
//UIAApplication[1]/UIAWindow[4]/UIAAlert[1]/UIAScrollView[1]/UIAStaticText[2]
Any ideas?
There are different ways to remake xpath value to UIautomation, methods are as follows.
[!Calculator app example]
http://i.stack.imgur.com/WQr3J.png
Before going to these points FYI class name is taken as reference for xpath.
XPath using class and text attribute :
In above image you can see that button 5 has text attribute with value = 5 which is unique. Class name is android.widget.Button which is same for all number buttons. So we can create XPath using text attribute value with class name as bellow.
xpath("//android.widget.Button[#text='5']")
XPath using class and resource-id :
Here resource-id for button 5 is com.android.calculator2:id/digit5. Trailing part (e.g digit5, digit4, digit7) of resource-id is changing for every number buttons so we can use contains function to get relative XPath of button 5 as bellow.
xpath("//android.widget.Button[contains(#resource-id,'digit5')]")
See more at: http://software-testing-tutorials-automation.blogspot.in/2015/10/ui-automator-viewer-get-android-app.html#sthash.08v6jFPe.dpuf
You can get UIAutomator from Instrument.(Xcode - Automation tool)
please find the below UIAutomator for ur code,
UIATarget.localTarget().frontMostApp().windows()[3].alerts()[0].scrollViews()[0].staticTexts()[1]
Note:
In Xpath index starts from 1.but in UIAutomator it starts from 0. Keep this in your mind.
Related
I have an image within a collection view that I am unable to click on. Appium can find the element fine but using the is_displayed() function always returns false. I read up on the iOS Class chain function so attempted to use that to click on the images parent XCUIElementTypeCell (Which can be clicked on, but has no label, or name value annoyingly)
My attempt:
self._driver.find_element(By.IOS_CLASS_CHAIN, "**/XCUIElementTypeImage[`name BEGINSWITH \"Click Me\"`]/**/XCUIElementTypeOther/**/XCUIElementTypeCell")
This gives a NoSuchElementException
The app structure looks like this:
So that XCUIElementTypeImage in the centre is what I am trying to target using name which equals "click me" in this example. The parent XCUIElementTypeOther also can be found but is not clickable so the only solution for me is jump up two levels to the XCUIElementTypeCell
P.S Please no Xpath suggestions
P.S2 Thanks for the help
Try the following:
"**/XCUIElementTypeCell[$type=XCUIElementTypeImage AND name BEGINSWITH 'Click Me'$]"
OR
"**/XCUIElementTypeCell[$type='XCUIElementTypeImage' AND name BEGINSWITH 'Click Me'$]"
Can anyone help me to write xpath in appium 1.7 for iOS..
If two class having same name
driver.findElementByClassName("TextField").sendKeys("abc");
driver.findElementByClassName("TextField").sendKeys("1234");
In any case use className is not reliable search strategy as its not a unique.
I usually suggest following rules:
have unique AccessibilityId for most of elements used in automation tests (talk with developers if they agree to fix this)
If not, build unique Xpath with relation to other elements that have AccessibilityId or more unique className
As a temporary solution you can do this:
List<WebElement> textfields = driver.findElementsByClassName("TextField");
textFields.get(0).sendKeys("abc");
textFields.get(1).sendKeys("1234");
since you didn't provide your page source, better print it out with driver.getPageSource() and think of good XPath that you put in:
List<WebElement> textfields = driver.findElementsByXpath(<your xpath>);
This below code working fine for me
driver.findElementByName("No account? Sign up").click();
driver.findElementByClassName("TextField").sendKeys("abc"); driver.findElementByClassName("SecureTextField").sendKeys("12345"); driver.findElementByClassName("SecureTextField").sendKeys(Keys.ENTER);
driver.findElementByXPath("(//XCUIElementTypeSecureTextField[2]").sendKeys("12345");
driver.findElementByXPath("(//XCUIElementTypeTextField)[2]").sendKeys(Keys.ENTER);
driver.findElementByXPath("(//XCUIElementTypeTextField)[2]").sendKeys("9876543210");
How to find element for date picker in appium, all the buttons have same resource ID and index as well(Some sample code will help, i have tried few but in those case index value were different in date picker). Even im not sure how to find xpath for these, is there a tool or something for finding xpath in appium ?
http://tinypic.com/r/34gstvd/8
Refer to each NumberPicker field and after you can interact with it (sendKeys, clear etc.).
By.xpath("//android.widget.LinearLayout[#index='0']//android.widget.EditText")
By.xpath("//android.widget.LinearLayout[#index='1']//android.widget.EditText")
By.xpath("//android.widget.LinearLayout[#index='2']//android.widget.EditText")
I am writing UI automation tests for an iOS native app using Appium and gradually realizing how most of the element locating strategies don't reliably work for iOS. Apart from XPath which randomly works, other options that I have are:
Accessibility ID (did not work for me)
name (not every element will have value for 'name' attribute)
class (makes sense when you are working with a list of elements)
iOS UiAutomation predicates (steep learning curve for beginners)
I have been trying to understand how to use iOS UiAutomation locator strategy and find elements using it but it's not working on Appium Inspector. I have referred to these documentations (Appium iOS Predicate reference, Apple UIAutomation reference) but I feel they cater to an advanced Appium user audience who have some knowledge on iOS development, not for beginners.
Currently the element hierarchy that I am trying to find element in is something like this:
My current automation setup is:
XCode 6.3.2
Appium 1.4.8
iOS 8.3
Appium Java Client 3.1.0
What will be the locator I can use to locate the highlighted element using UiAutomation predicate strategy? I have been trying a few options on the Appium Inspector like:
applications()[0].windows()[0].navigationBars()[0].textFields().withPredicate("value == 'Search eBay'")
.textFields().withPredicate("value == 'Search eBay'")
These did not work. What am I doing wrong here? Are there any other documentations which clearly explain iOS UiAutomation locators from ground-up? It will really help if someone can explain these basics.
I have never worked with Appium before but I have worked with UIAutomation in javascript.
You can probably find the element using:
....textFields().firstWithName("Search eBay")
Note that UIAuatomation uses UIAccessibility protocol. The value for UITextField is its accessibilityValue and that one will be equal to the searched text, not the placeholder. Once you type something to the field, you will be able to use value.
Of course, in your case grabbing the first text field would work too, as there is only one in the navigation bar.
Just use this .navigationsBars()["EBUH_whateverstring"].textfields()["Search eBay"].textfields()["Search eBay"].
Better way is to ask dev to add accessibility id in case the code is in Obj-C or accessibility identifier if the app code is in Swift. Otherwise if the passed on element value is dynamic then the test will fail in asserting or doing action upon this element.
Another failsafe method is using array values.
.navigationsBars()[0].textfields()[0].textfields()[0] --> Check the array values of your element is [0] or any other. U can use this appium app to get the array value from where it shows xpath value for the element. Or you can use XCode Instruments if you have access to the code to find the exact value as UIAutomation interprets it.
If you are trying to find elements in Appium you will have to write code to do so. Assuming you are using Java, which is what I am using for code, the way you locate these elements is through the driver, tables, and rows.
What do I mean by this? Each element has an XPath associated with it, so one way of doing this is saying
driver.findElementByXPath("xpath_string_here");
This can be very useful when trying to run assertions, for example. using the above code, let us say we want to assert that its name is valid. we can say:
AssertEquals(driver.findElementByXPath("xpath_string_here").getAttribute("name"), 'Practice Example");
When I mention tables and rows, I mean doing something like this:
MobileElement table = (MobileElement) driver.findElementByXPath("string here");
List<WebElement> rows = driver.findElementByClassName("Class name here");
What does this code do? it creates a variable of type MobileElement which will go through the xPath you want, and then the rows value will find elements of that class name present inside of that table view. So in the above image, I would stop at the XPath for the UIAWindow, and then tell my rows to find the elements using class name of "UIAButton" for example.
At this point it is a matter of a simple loop if you want to run some actions on them such as .click(); using their indexes using the .get(int i) method. So for example: rows.get(i).click();
Does this help you with your question?
Once I switch my context to the DOM of the webview, I want to be able to search those elements by tag, but I get the error that searching by tag is deprecated and to search by class instead. This won't work to find DOM elements by tag. Is there still a way to do it? Thanks!
As per Appium documentation for migrating to 1.0:
We've removed the following locator strategies:
-name
-tag name
... tag name has been replaced by class name. So to find an element by its
UI type, use the class name locator strategy for your client.
Why searching by tag name?
Although Selenium still supports this type of query, Appium decided not to do anymore. Actually when interacting with the device, searching by tag name is very inefficient.
Why would you want to do that? Think about it, if your page has a bit of content, you will end up having many p, div, span tags. Your search will return many elements and then you will have to go thorugh the list and locate the one you are interested in. If your page is very little, then you will probably end up with one tag of the type you are looking for, however why not applying a class and solve the problem?
Classes are not for CSS style
Remember that HTML attribute class was not introduced by W3C for applying CSS style. It is used to provide an element with more informationa bout its purpose in the DOM. When you apply a class to an element, you should do that basing on the role that element holds! Thus locating an element by class is sure better.
So forget searching by tag name. You should change your strategy and apply class names to your tags in your hybrid app. If you do not want to do so, then do not switch to the new version of Appium but this will keep you far from future innovations!
Migrating from a tagname based element location to a class name
orientd one is good practice. That's why you should change too.
maybe this can help
element.getAttribute("class")