Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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 am not able to write test to determine whether the desired textField has focus or not.

When I print the textfield in console -

Output: { TextField 0x131171d40: traits: 146031247360, Focused, {{6.0, 108.3}, {402.0, 35.0}}, value: ​ }

But I could not find any focus/isFocus property on XCUIElement.

Is there a way to achieve this ?

like image 775
Sandy Avatar asked Oct 01 '15 22:10

Sandy


2 Answers

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)")
        }
    }
}
like image 143
hris.to Avatar answered Sep 27 '22 20:09

hris.to


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
    }
}
like image 11
leanne Avatar answered Sep 27 '22 20:09

leanne