How to get elementid attribute of a node from appium programatically? - appium

In Appium inspector when you hover over a selected element, there is an elementId attribute. Is there any way I can get this elementId programatically maybe generate it from the xml tree or adb shell commands.
Also, I found very scarce information on elementId attribute. It would also be great to know if someone can share what is elementId and how it is generated by the appium driver. Thanks

I believe 'elementId' is generated dynamically by iOS so won't really be of much use to you. It would be best to stick to 'name', 'label', 'value' and 'type' when searching for elements.
See here for finding elements: https://appium.io/docs/en/commands/element/find-elements/
iOS findElementsByIosNsPredicate can be quite powerful and useful e.g. from your screen shot:
findElementsByIosNsPredicate("label == 'save' AND name == 'save' AND type == 'XCUIElementTypeButton'")

Related

How to write xpath if two text field having same class name in appium 1.7.for ios

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");

View HTML of plain capybara element without using the driver

Please note the difference between my question and others like this one is that I am looking for a way to do this without using driver methods.
Is there a way to view all the HTML of a given Capybara Element without driver support?
Currently, a plain Capybara element allows you to access the attributes, if you know about them:
# <span class="one" id="two" data="three">
el = find(".klass")
el['class'] #=> "one"
el['id'] #=> "two"
It seems like surely there should be a way to just view the entire set of attributes, but I can't find a way without driver support. Is there a way to get something like this?
el.html #=> <span class=\"one\" id=\"two\" data=\"three\">
No, there is not. Here are the methods you get. The closest you get is the native method, which you do not wish to use. You can see how it is done by drivers by looking at their code - you need the driver. You can verify this yourself by running my_cabybara_element.methods.sort, there just isn't anything there for this.

Understanding basics of iOS uiautomation selector strategy for Appium

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?

In Appium 1.0+, now that finding elements by tag is deprecated, how do I find an element by tag name when operating on the DOM of the webview?

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")

Perfecto Mobile ScriptOnce - Is it Possible to perform an action on an object (not just retrieving the value) using html_id instead of control_id

Working with MobileCloud Automation from Perfecto Mobile using ScriptOnce on a jquery-mobile application.
I want to find out if it is possible to perform an action on an object (not just retrieving the value) using html_id instead of Perfecto Mobile's control_id.
Background:
We have already created an object repository with html_id ids.
I want to have the scriptOnce automation more easily find the objects by the html_id values in our object repository.
Is it possible, and how do I set the html ids to be used?
You have the option to work with html_id's or html_name's.
You need to check the "show advanced parameters" box and then just type the id or name of the html element.
If you work with their QTP solution, and say you want to put the user name in a text box with id = userIdInput, then the syntax would be something like that:
Device("DUT").MWebEdit("html_id:=userIdInput").Set "my_username"
Hope it helps.

Resources