有没有办法找到XCUIElement是否有焦点?

时间:2015-10-01 22:21:42

标签: ios xcode7 ui-testing xcode-ui-testing

我的一个屏幕有多个文本字段,我可以从不同的其他屏幕登陆到此屏幕。在每种情况下,我将一个或另一个文本字段作为第一响应者。我无法编写测试来确定所需的textField是否具有焦点。

当我在控制台中打印文本字段时

  

输出:{             TextField 0x131171d40:traits:146031247360,聚焦,{{6.0,108.3},{402.0,35.0}},值:           }

但我在XCUIElement上找不到任何focus / isFocus属性。

有没有办法实现这个目标?

5 个答案:

答案 0 :(得分:22)

我对派对来说有点迟了:)但是从转储变量XCUIElement可以看出它有一个有趣的属性:

  

属性名称:hasKeyboardFocus

     

属性类型:TB,R

因此,您可以通过以下方式检查您的元素是否具有焦点:

let hasFocus = (yourTextField.value(forKey: "hasKeyboardFocus") as? Bool) ?? false

注意:您可以使用以下扩展名转储任何NSObject子类的属性变量:

extension NSObject {
    func dumpProperties() {
        var outCount: UInt32 = 0

        let properties = class_copyPropertyList(self.dynamicType, &outCount)
        for index in 0...outCount {
            let property = properties[Int(index)]
            if nil == property {
                continue
            }
            if let propertyName = String.fromCString(property_getName(property)) {
                print("property name: \(propertyName)")
            }
            if let propertyType = String.fromCString(property_getAttributes(property)) {
                print("property type: \(propertyType)")
            }
        }
    }
}

更新:属性转储,Swift 4:*

extension NSObject {
    func dumpProperties() {
        var outCount: UInt32 = 0

        let properties = class_copyPropertyList(type(of: self), &outCount)
        for index in 0...outCount {
            guard let property = properties?[Int(index)] else {
                continue
            }
            let propertyName = String(cString: property_getName(property))
            print("property name: \(propertyName)")
            guard let propertyAttributes = property_getAttributes(property) else {
                continue
            }
            let propertyType = String(cString: propertyAttributes)
            print("property type: \(propertyType)")
        }
    }
}

答案 1 :(得分:4)

基于@hris.to's excellent answer,我整理了这个小扩展名(也可以在Swift 4中使用)...

extension XCUIElement
{
    func hasFocus() -> Bool {
        let hasKeyboardFocus = (self.value(forKey: "hasKeyboardFocus") as? Bool) ?? false
        return hasKeyboardFocus
    }
}

答案 2 :(得分:0)

我不知道selected XCUIElement上的.modal属性是您正在寻找的内容。试试吧。

答案 3 :(得分:0)

NSObject通过extension(来自UIAccessibility.h)提供了一种方法,该方法可在名为XCUIElement的{​​{1}}上找到,但似乎没有即使该元素的accessibilityElementIsFocused()清楚地显示true,也请返回debugDescription。还有一些其他相关方法FocusedaccessibilityElementDidLoseFocus(),它们似乎是旨在被accessibilityElementDidBecomeFocused()的子类覆盖的方法,以通知NSObject状态的更改

在挖掘之后,我倾向于说我们正在讨论的Focused概念与Focused状态不同,这可能是你希望的知道。我相信在这一点上,焦点表明该元素是firstResponder等辅助技术的焦点,基于对这些方法的一些评论。

如果您希望能够直接判断某个项目是否为VoiceOver,我认为此时需要提交错误报告。

如果有方法可以直接与软件键盘进行交互,那么一个hacky解决方法可能是为firstResponder获取XCUIElement并比较UITextField value使用键盘键入前后的元素(您可能需要键入一个字符,然后键入一个退格键)。话虽如此,我无法弄清楚如何在粗略的尝试中直接拿到键盘。

答案 4 :(得分:0)

我观察过一些

的情况
XCUIApplication().textFields[{index/identifier}].selected
即使我将光标聚焦在文本字段上,

也不会返回true,但我能够使用.typeText()输入文本。但是,.enabled正确返回true,显示“enabled”值表示UI元素已启用辅助功能,您可以与其进行交互。

不是一个干净的解决方案,但你可以尝试,

XCUIApplication().textFields.elementMatchingPredicate("predicate")

.elementMatchingType()获取XCUIElement并在使用guard语句处理异常条件时编写测试块,以便在找不到textField时抛出相应的错误。

相关问题