XCUIElement 的 Select parent

Select parent of XCUIElement

如何在 XCUITest 中 select XCUIElement 的 parent 元素?根据 documentation,class 有 children()descendants(),但 select parent 或兄弟姐妹没有。在我看来,我一定错过了一些东西 - Apple 怎么会有没有双向导航的元素树???

我知道 XCUIElementQuery 上有一个方法 containing(),但那是不一样的。我也知道 accessibilityIdentifier 可能会有所帮助,但我正在考虑编写一种通用方法来测试具有给定导航栏标签的任何视图。传入我想访问的所有元素的所有标识符似乎不是一个好的选择。

不幸的是,没有直接命名的方法来访问类似于 Apple 提供的 children()descendants() 的 parent 元素,但您实际上在 containing() 的正确轨道上.当我需要根据 children/descendants:

定位 parent 元素时,我通常采用两种方法
  1. 使用containing(_:identifier:)
    let parentElement = app.otherElements.containing(.textField, identifier: "test").firstMatch

    let parentElement = app.otherElements.containing(.textField, identifier: "test").element(boundBy: 0)
  2. 使用containing(_ predicate: NSPredicate)
    let parentElement = app.otherElements.containing(NSPredicate(format: "label CONTAINS[c] 'test'").firstMatch

    let parentElement = app.otherElements.containing(NSPredicate(format: "label CONTAINS[c] 'test'").element(boundBy: 0)

这些只是随机 data/element 类型的示例,因为您没有确切提及您想要实现的目标,但您可以从那里开始。

更新:
像往常一样,Apple 文档没有提供很好的服务。他们说 'descendants' 但他们实际上的意思是直系后代(children)和 non-direct 后代(descendants)。不幸的是,没有保证,也没有通用的解决方案。它应该基于您当前的需求和应用程序实现。更多可能有用的示例:

  1. 如果您不想要查询中的第一个元素,最好使用 element(boundBy: index)。所以如果你知道 XCUIElementQuery 会给你 5 个元素并且你知道你需要第三个元素:
    let parentElement = app.otherElements.containing(.textField, identifier: "test").element(boundBy: 2)
  2. 细化元素定位器。假设您有 3 个带有标识符“SomeView”的视图,这 3 个视图每个包含 2 个其他子视图,并且子视图有一个带有标识符“SomeButton”的按钮。
let parentViews = app.otherElements.matching(identifier: "SomeView")
let subView = parentViews.element(boundBy: 2).otherElements.containing(.button, identifier: "SomeButton").element(boundBy: 1)

这将为您提供第二个子视图,其中包含一个标识符为“SomeButton”的按钮,而第三个 parent 视图的标识符为“SomeView”。使用这种方法,您可以进行微调,直到获得您真正需要的东西,而不是所有 parents、grandparents、great-grandparents 等

我希望 Apple 为 XCTest 的定位器提供更多的灵活性,就像 Xpath 为 Appium 所做的那样,但大多数时候即使这些工具也足够了。