Is there a way to find if the XCUIElement has focus or not?

后端 未结 5 1370
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-31 01:53

One of my screen has multiple text fields, I can land to this screen from different other screens. In each case I am making one or another text field as first responder. I a

相关标签:
5条回答
  • 2020-12-31 02:06

    Based on @hris.to's excellent answer, I put together this little extension (works in Swift 4 as well)...

    extension XCUIElement
    {
        func hasFocus() -> Bool {
            let hasKeyboardFocus = (self.value(forKey: "hasKeyboardFocus") as? Bool) ?? false
            return hasKeyboardFocus
        }
    }
    
    0 讨论(0)
  • 2020-12-31 02:07

    I have observed some instances where

    XCUIApplication().textFields[{index/identifier}].selected
    

    does not return true even when I had my cursor focussed on the text field but I was able to enter text with .typeText(). However, .enabled correctly returns true , It appears 'enabled' value represents that UI element has accessibility enabled and you can interact with it.

    Not a clean solution but you can try,

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

    or .elementMatchingType() to get XCUIElement and write your test block while handling the exception condition with guard statement to throw appropriate error if the textField is not found.

    0 讨论(0)
  • 2020-12-31 02:12

    I little bit late for the party :) However as far as I can see from dumping the variable XCUIElement it has one interesting property:

    property name: hasKeyboardFocus

    property type: TB,R

    So you can check if your element has focus the following way:

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

    NB: you can dump the property variables of any NSObject sublass with following extension:

    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)")
                }
            }
        }
    }
    

    Update: Properties dump, 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)")
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-31 02:16

    There is a method on NSObject via an extension (from UIAccessibility.h), which is available on XCUIElement named accessibilityElementIsFocused(), but it seems to not return true even when the debugDescription of that element clearly says Focused. There are a few other related methods accessibilityElementDidLoseFocus() and accessibilityElementDidBecomeFocused(), which appear to be methods intended to be overridden by a subclasses of NSObject to get notified of changes to the Focused state.

    After this digging I'm inclined to say that the notion of Focused that we are discussing is not the same as the firstResponder state, which is probably what you're hoping to know. I believe at this point that focus indicates that the element is the focus of some assistive technology like VoiceOver, based on some of the comments for these methods.

    If you want to be able to tell if an item is firstResponder directly, I think at this point it's time to file a bug report.

    If there is a way to interact directly with the software keyboard, a hacky workaround might be to get an XCUIElement for your UITextField and compare the value of your UITextField element before and after typing with the keyboard (you may want to type a character then a backspace). Having said that, I could not figure out how to get the keyboard directly in a cursory attempt.

    0 讨论(0)
  • 2020-12-31 02:21

    I don't know but maybe selected property on XCUIElement is what you're looking for. Try it.

    0 讨论(0)
提交回复
热议问题