Meaning of allElementsBoundByAccessibilityElement
Asked Answered
G

1

13

I'm learning to use XCTest for UI testing. I couldn't understand of doc of XCUIElementQuery.allElementsBoundByAccessibilityElement:

Immediately evaluates the query and returns an array of elements bound to the resulting accessibility elements.

What does "elements bound to the resulting accessibility elements" mean? Also, what's the difference from allElementsBoundByIndex?

Grape answered 15/3, 2018 at 19:11 Comment(1)
Did you ever find out what the difference is?Floria
G
11

The documentation for allElementsBoundByAccessibilityElement is not so great but I determined the difference from allElementsBoundByIndex by poking around with a debugger.

Calling either allElementsBoundByAccessibilityElement or allElementsBoundByIndex will return an array of XCUIElement objects.

let app = XCUIApplication();
app.launch();

let elementsByAccessibilityElement = app.images.allElementsBoundByAccessibilityElement;

let elementsByIndex = allElementsBoundByIndex;

Immediately after returning this array, the XCUIElement objects themselves are not actually resolved, and keep a reference to the original query.

Try to access a property like .label on the XCUIElement though...

And you will see the element resolve itself by snapshotting the accessibility hierarchy and then re-running the original query to find the element. You can see this in the debug console an output like this:

    t =     5.76s Get all elements bound by index for: Descendants matching type Other
    t =     5.84s     Snapshot accessibility hierarchy for app with pid 4267
    t =    10.79s     Find: Descendants matching type Other

The big difference between the two methods when the element is resolving and running the original query. When you call allElementsBoundByIndex, the XCUIElement instance finds itself by running the original query and then getting the result at that index.

That means if the app UI changes between calling allElementsBoundByIndex and actually resolving the XCUIElement objects in the array, you may receive a different set of elements in the array than you originally expected.

When you call allElementsBoundByAccessibilityElement, the XCUIElement instance finds itself by running the original query and then getting the result matching the accessibility identifier that element had at the time the query was created.

If the app UI changes between calling allElementsBoundByAccessibilityElement and actually resolving the XCUIElement objects in the array, and one of the original elements is no longer present, the app will throw an error.

Gerstner answered 10/1, 2019 at 7:16 Comment(2)
Nice research work! So maybe a better name would be allElementsBoundByIdentifier.Grape
Indeed it would be a better name. If you take a look at the private headers on the XCUIElementQuery you can see it actually stores an array expressedIdentifiers when you use allElementsBoundByAccessibilityElementGerstner

© 2022 - 2024 — McMap. All rights reserved.