-1

I am automating a windows application through a desktop session using Appium and Windows Application Driver. Certain elements I want to interact with don't have unique accessibility IDs but the combination of their class names and IDs does seem to be unique. How can I first get a list of elements by their class name and then fetch one of them with certain ID?

I am aware that the second line of code provided is not correct, I'm just showing it to demonstrate what behavior I need.

Below is through class name:

class_elements = driver.find_elements_by_class_name("some_class_name")

Below is through an accessibility id:

specific_element = class_elements.find_element_by_accessibility_id("some_id")
specific_element.click()

Is there a way to put both of these together in a loop?

Thank you @Moshe Slavin for your suggestion

I tried the following piece of code

@pytest.mark.trial
def test_trial():
    className = "UIProperty"
    class_elements = ds.find_elements_by_class_name("UIProperty")

    for elm in class_elements:
        print(elm.get_attribute('id'))
        if elm.get_attribute('id') == "System.ItemNameDisplay":
            elm.click()

I decided to print the IDs as well. I got the following results:
None
None
None
... I'm quite confused as to why this is happening. I'm using the Windows Inspect tool from SDK to gather properties of the UI elements and there definitely is and element present that matches both the class name and the ID.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
CrispJam
  • 159
  • 1
  • 6
  • 16

2 Answers2

3

It should look something like:

class_elements = driver.find_elements_by_class_name("some_class_name")

for elm in class_elements:
    if elm.get_attribute('accesibilityID') == "some_id":
        elm.click()

EDIT:

As @Bill Hileman has pointed out the attribute OP was looking for is accesibilityID not just id.

Thanks Bill

Hope this helps you!

Moshe Slavin
  • 5,127
  • 5
  • 23
  • 38
2

Moshe Slavin answer works, but you can try like this also.

Suppose you have some class name and you are storing it in some variable like below :

className = "some class name"

then you can get all the matching class names using the below line and you are aware of that :

 driver.find_elements_by_class_name(className)

Instead of finding all the elements and storing the values, store the accessibility id that you want to check in some variable like below :

accessibilityID = "some accessibility id"

Then you can search for an element which contains both the class name and accessibility id(is just for an indicative purpose, so use app related attribute which identifies required field) using the below xpath without performing any looping :

element = driver.find_element_by_xpath("//*[@class='"+className+"' and @accesibilityID='"+accessibilityID +"']");

I hope it works too...

Ali
  • 1,689
  • 1
  • 5
  • 12
  • 1
    Your solution won't work as written. When using xpath with a native app, "ID" is not the same thing as accesibilityID. It is if you defined the driver correctly and use by.id because that logic attempts accessibility, resource, and regular ID's, but xpath will only check literally what you tell it. I saw this first-hand in an appium training series of videos and the instructor could not figure out why his xpath would not work, and just gave up saying "xpath is fragile." He used the wrong attribute. – Bill Hileman Feb 11 '19 at 16:32
  • Thanks @Bill Hileman, I know `ID` is not the same thing as `accessibilityID`. I have mentioned that for an indicative purpose only. – Ali Feb 11 '19 at 16:41
  • Hi @CrispJam, check the xpath which I have provided - substitute `className` and `some unique id` in that xpath. – Ali Feb 11 '19 at 16:44
  • If you change your attribute from `@id` to `@accesibilityID` (not certain of the case or if it's hyphenated) in your last code line the answer would be correct. – Bill Hileman Feb 11 '19 at 16:45