Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to add support for element attributes other than ClassName, Name, AutomationId? #19

Closed
mvadym opened this issue Mar 9, 2016 · 29 comments

Comments

@mvadym
Copy link

mvadym commented Mar 9, 2016

How easy to add support for element attributes other than ClassName, Name, AutomationId?
Particularly I consider ControlType when all 3 above are empty.

@NickAb
Copy link
Contributor

NickAb commented Mar 11, 2016

In Winium.Desktop you can try using XPath to locate elements based on attribute values.
@skyline-gleb, can you provide query example for matching by ControlType if it is supported?

@Pranodayd
Copy link

Hi @NickAb .I am doing automation of Windows10 mobile application using Winium.Storeapss.Can we use FindElementByXpath stratergy to find elements in Winium.Storeapps?
Waiting for your reply.

@Pranodayd
Copy link

Hi @NickAb .After using Driver.findElementByXPath("//*[@Class='Windows.UI.Xaml.Controls.TextBox']");
I am getting an error,xpath is not valid or implemented searching strategy.Please suggest.

@NickAb
Copy link
Contributor

NickAb commented Apr 20, 2016

Winium.StoreApps uses class_name as attribute for item class name.

See relevant code https://github.com/2gis/Winium.StoreApps/blob/master/Winium/Winium.StoreApps.InnerServer/Commands/PageSourceCommand.cs#L39-L59 for reference on attributes.

You can try using Winium.StoreApps.Inspector to get idea of XML tree that Winium uses internally.

@Pranodayd
Copy link

Hi @NickAb .
Even for Driver.findElementByXPath("//*[@class_name='Windows.UI.Xaml.Controls.Button' and @value='OK'] ").click(); it gives me same error.

@Pranodayd
Copy link

Hi @NickAb .
I am able to filter object tree in Winium Inspector using Xpath successfully.But not able to understand why Winium.StoreApps driver is not able to execute same xpath query if supplied through java code.I am using Winium.StoreApps.Driver Version 1.6.2 and Winium java Client winium-webdriver-0.1.0-1.jar

Finding elements using Xpath is key point in our framework development.I am stuck here.
Please suggest.

@Pranodayd
Copy link

Hi @NickAb .
When I debug this issue got following stacktrace.
(Response: SessionID: 49dce500-4c5c-4240-bf55-fa50bbe47b7a, Status: 13, Value: {stacktrace= at Winium.StoreApps.InnerServer.Commands.CommandBase.InvokeSync(CoreDispatcher dispatcher, Action action)
at Winium.StoreApps.InnerServer.Commands.CommandBase.Do(), error=unknown error, message=xpath is not valid or implemented searching strategy.})

It seems to be issue with Winium.StoreApps.InnerServer.But then how can I run xpath query from Winium Inspector against the same application instrumented using Winium.StoreApps.InnerServer version 1.6.2?

I am using Windows 8.1 Pro desktop machine and trying to automate Windows 10 mobile application on Windows 10 Simulator

@NickAb
Copy link
Contributor

NickAb commented Apr 20, 2016

@Pranodayd Sorry, I misled you. Winium.StoreApps does not support XPath as a locator strategy at the moment, because Store Apps framework had no classes needed to implement it. XPath only supported on Winium.Desktop.

@Pranodayd
Copy link

Hi @NickAb .
But we require Xpath support.Can it be implemented?

@NickAb
Copy link
Contributor

NickAb commented Apr 20, 2016

I do not think that there is easy way to add fast XPath support.

By it can be hacked by modifying GetPageSource command (by registering all the elements and returning their ids) and evaluating xpath on Driver.exe side (not on the phone) and then requesting element by id from attribute of element obtained during evaluation of XPath.
We might add it later, but not in near future. You can try to add it yourself, PR are always welcome.

@Pranodayd
Copy link

@NickAb I didn't get you exactly.Can you please explain it in more detail?

We have Appium framework implemented for Android and IOS application,now we want to extend this framework to Windows 10 application.This can be only possible by using a tool which is based on Selenium-Webdriver like Winium.We are really looking to Winium as our potential Windows 10 mobile application tool.

We have used Xpaths extensively for element identifications as our developers have not set unique Ids for UI controls and most of our UI controls are developed using custom classes derived from native SDK calsses.Hence we don't really have an option other than Xpath.

@NickAb
Copy link
Contributor

NickAb commented Apr 20, 2016

The preferred way of locating elements in Winium is using Automation Properties, like AutomationId, which are add to elements by developers to improve test-ability. This strategy should be preferred on other platforms too, tests will be less fragile due to UI changes.

@Pranodayd
Copy link

Hi @NickAb .
I am afraid that ,our developers are not open to do any changes required to make application automation ready because of tight release schedule.In our Appium framework we already have done Element Identification using Xpath and main idea is we want to run same scripts on Windows 10 without changing original Appium scripts.Can you please give me some Xpath like alternative?When are you guys planning to give Xpath locator support in Winium.StoreApps?

@Pranodayd
Copy link

@NickAb .I now understood option you gave me in following reply:
By it can be hacked by modifying GetPageSource command (by registering all the elements and retuning their ids) and evaluating xpath on Driver.exe side (not on the phone) and then requesting element by id from attribute of element obtained during evaluation of XPath.

You mean to say here that,Driver will run Xpath and return ID of filtered element and then we can use FindElementById() and pass it the ID which we have got from previous command.

But again in order this to work we need to have Unique Ids for all our controls,which is currently not the case.

@NickAb
Copy link
Contributor

NickAb commented Apr 20, 2016

I was not talking about AutomationId of the element, but rather a concept of id used by selenium. When element is found, selenium assigned internal id to this element. This id is used to identify the element you want to get text from, send keys to, etc.

One can modify GetPageSource implementation on Inner Server side to register each element that is getting printed in page source and append its internal id (generated at runtime by Winium) to page source as attribute on the element.
Then on Driver side (console application) one can use XPath navigation that is supported in desktop version of framework. When element is found matching XPath you can read attribute value with internal id and use it to access elements. This will require modification on both Inner server and Desktop side.

This is described in 2gis/Winium.Mobile#29 (comment)

@Pranodayd
Copy link

Hi @NickAb .
Ok got your point.When can we get these changes in both Inner server and Desktop side so that we can implement this.?
I am really looking forward for this change.

@Pranodayd
Copy link

Hi @NickAb .
Because of this change even if I get PageSource.xml with Internal Ids specified for each element.I can have my Xpaths run on this PageSource.xml and retrieve Internal Id and then can pass this retrieved InternalID to some method which will return me actual element.

@NickAb
Copy link
Contributor

NickAb commented Apr 20, 2016

Yes, it can be done kind of like you wrote in last message, but it all can be hidden in FindElementByXPath on Driver side.
I can not provide any estimates on this issue, we do not use XPath in our tests (we use AutomationId) and we have a lot of priority projects.

Anyway, such implementation will be very slow, I recommend researching a way to use other element locating strategies. In case if element does not have AutomationId we just search for element iteratively limiting our scope on each step. For example, we will first find a parent of element to be found as close as we can. Then we will find all elements of this parent that have the class we need, afterwards we will iterate them and check their value or any other identifying property.

So in your case Driver.findElementByXPath("//*[@class_name='Windows.UI.Xaml.Controls.Button' and @value='OK'] ").click(); it gives me same error. will transform to something like:

buttons = driver.find_elements_by_class('Windows.UI.Xaml.Controls.Button')

for button in buttons:
    if button.text == 'OK':
        button.click()
        break

or even shorter

buttons = driver.find_elements_by_class('Windows.UI.Xaml.Controls.Button')
next(x for x in buttons if x.text=='OK').click()

I used python for sample, as it is what we use, but it should be easy to translate to Java.

@Pranodayd
Copy link

@NickAb .
I got your suggestion.I will have to parse my Xpaths and need to translate them in the way you just suggested.I will try to implement this.
But please try to provide Xpath stratergy in Winium.StoreApps ASAP,atleast in the temporary way we talked about in our previous conversations.Thanks a lot for nice suggestion though.I would be grateful to you if you can give me your personal emailID to get back to you in case of any help.

Many thanks @NickAb for taking out time to respond to my queries.

@NickAb
Copy link
Contributor

NickAb commented Apr 20, 2016

You can contact me at [email protected]

@Pranodayd
Copy link

Hi @NickAb .
I have implemented the suggestion given by you.I am able to parse my xpaths and convert into suggested format except those which contains Xpath axis like following::sibling and preceding::sibling.
If I get all child elements of particular element then I can translate it.But how to get all child elements of particular element without using Xpath and CSS stratergy because both of these strategies are not available in Winium.StoreApps.
Please suggest a way.

Thanks

@NickAb
Copy link
Contributor

NickAb commented May 2, 2016

Assuming the element is parent you can try using this:

parent.find_elements_by_class_name(DESCENDANTS_CLASS_NAME)

But note that:
There is no way to get immediate children of the element, findElements will return all descendants of the element (immediate children and their children, and so on).
Will descendants work for you?

@Pranodayd
Copy link

Hi @NickAb
But how can I get a TextBox element which is following::sibling of Label element for example.

I dont have any option of retrieving the element using the SIBLING relationship it has with some other element.I can manage it though if I get all child elements of certain Parent element e.g. using Parent.findElements(By.cssSelector("*"));

What I can do is,I will get the list of all child elements of parent element irrespective of any class or ID and traverse this till I get the Element,relationship of which I want to take into consideration.And then I will use the List index of this element to further go and search for the desired element in the list.

But I don't have any option currently to retrieve all child elements of any parent element without giving any attribute.

Thanks

@Pranodayd
Copy link

Hi @NickAb
Any way which you can suggest regarding the scenario mentioned above?

@NickAb
Copy link
Contributor

NickAb commented May 3, 2016

I don't think there is any way to query siblings currently. You will have to somehow find a parent element, for example using findElementsByClassName and getting it by known index from a collection. This will let you limit the scope for the following search.

So, for example in case of label and textbox being siblings you could first look for their parent. Lets assume it is stackpanel at index 5.

parent = driver.find_elements_by_class_name(STACKPANEL_CLS)[5]

Then you will simple find the textbox by its known index in the tree:

parent.find_elements_by_class_name(TEXTBOX_CLS)[3]

But this will be hard to maintain and it also will not be performant.

I would suggest you to invest into testability of the app and add AutomationProperties.AutomationId and AutomationProperties.Name to the elements you would like to use in tests. It should be relatively simple and require modification of XAML files only.

@Pranodayd
Copy link

Hi @NickAb .

Thanks for the reply.I got your suggestion.Will try to see if this can be of any help to me.

Actually our developer is only for 1 month with us,and hence he does not want to waste time in making application testable,hence I can't ask him for anything to be done to make application testable,at least for now.

Thanks.
.

@NickAb
Copy link
Contributor

NickAb commented May 3, 2016

@Pranodayd You can do it yourself as it only requires you to edit some XAML files by adding appropriate XML attributes. You can ask developer to guide you for first time. This might be time consuming first time, but then it will be easy and save a lot of time on fixing broken tests when UI changes.

I am closing this issue, because it was initially created for Winium.Desktop project. Moving discussion of Winium.Mobile XPath support to 2gis/Winium.Mobile#29.

Seems that somebody repacked System.Xml.XPath as Nuget package for Silverlight apps, we should try it out and see if it will work in StoreApps project too. No definitive timeline here, will try to find some time in May to test it.

@NickAb NickAb closed this as completed May 3, 2016
@Pranodayd
Copy link

Hi @NickAb .
I will try to see how this :System.Xml.XPath can be of any help to us.Thanks a lot.

@NickAb
Copy link
Contributor

NickAb commented May 3, 2016

@Pranodayd XPath would not help you at the moment as it is not client side, we would need to implement an XPathNavigator based on this package and add xpath as a strategy to Winium. This will require modification of Winium.StoreApps project. But we have already used such approach in Winium.Desktop, so I think it should work out.
Please continue discussion in the issue I have linked 2gis/Winium.Mobile#29.

Meanwhile the only option is to do as I have described in #19 (comment)

@2gis 2gis locked and limited conversation to collaborators May 3, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants