有没有办法找到 XCUIElement 是否有焦点?
Is there a way to find if the XCUIElement has focus or not?
我的一个屏幕有多个文本字段,我可以从不同的其他屏幕登陆到这个屏幕。在每种情况下,我都会将一个或另一个文本字段作为第一响应者。我无法编写测试来确定所需的文本字段是否具有焦点。
当我在控制台中打印文本字段时 -
Output: {
TextField 0x131171d40: traits: 146031247360, Focused, {{6.0, 108.3}, {402.0, 35.0}}, value:
}
但是我在 XCUIElement 上找不到任何 focus/isFocus 属性。
有办法实现吗?
我不知道,但也许 XCUIElement
上的 selected
属性 就是您要找的。试试吧。
NSObject
上有一个通过 extension
的方法(来自 UIAccessibility.h
),它在 XCUIElement
上可用,名为 accessibilityElementIsFocused()
,但似乎不 return true
即使该元素的 debugDescription
明确表示 Focused
。还有一些其他相关方法 accessibilityElementDidLoseFocus()
和 accessibilityElementDidBecomeFocused()
,它们似乎是旨在被 NSObject
的子类覆盖的方法,以获取 Focused
状态更改的通知.
经过这次挖掘,我倾向于说我们正在讨论的 Focused
的概念与 firstResponder
状态不同,这可能是您希望知道的.我相信在这一点上,根据对这些方法的一些评论,焦点表明该元素是某些辅助技术的焦点,例如 VoiceOver
。
如果您希望能够直接判断一个项目是否 firstResponder
,我认为此时是提交错误报告的时候了。
如果有一种方法可以直接与软件键盘交互,一个棘手的解决方法可能是为您的 UITextField
获取一个 XCUIElement
并比较您的 [=] 的 value
27=] 元素在使用键盘输入之前和之后(您可能想先输入一个字符,然后输入一个退格键)。话虽如此,我草草想不出如何直接获取键盘。
我观察到一些情况
XCUIApplication().textFields[{index/identifier}].selected
不 return 正确,即使我将光标聚焦在文本字段上但我能够使用 .typeText()
输入文本。但是,.enabled
正确地 return 是 true ,看起来 'enabled' 值表示 UI 元素启用了辅助功能,您可以与之交互。
不是一个干净的解决方案,但您可以尝试,
XCUIApplication().textFields.elementMatchingPredicate("predicate")
或 .elementMatchingType()
获取 XCUIElement 并编写测试块,同时使用 guard
语句处理异常情况,如果未找到 textField 则抛出适当的错误。
我参加聚会有点晚了 :) 但是据我转储变量 XCUIElement 所见,它有一个有趣的 属性:
property name: hasKeyboardFocus
property type: 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)")
}
}
}
基于 ,我整理了这个小扩展(也适用于 Swift 4)...
extension XCUIElement
{
func hasFocus() -> Bool {
let hasKeyboardFocus = (self.value(forKey: "hasKeyboardFocus") as? Bool) ?? false
return hasKeyboardFocus
}
}
我的一个屏幕有多个文本字段,我可以从不同的其他屏幕登陆到这个屏幕。在每种情况下,我都会将一个或另一个文本字段作为第一响应者。我无法编写测试来确定所需的文本字段是否具有焦点。
当我在控制台中打印文本字段时 -
Output: { TextField 0x131171d40: traits: 146031247360, Focused, {{6.0, 108.3}, {402.0, 35.0}}, value: }
但是我在 XCUIElement 上找不到任何 focus/isFocus 属性。
有办法实现吗?
我不知道,但也许 XCUIElement
上的 selected
属性 就是您要找的。试试吧。
NSObject
上有一个通过 extension
的方法(来自 UIAccessibility.h
),它在 XCUIElement
上可用,名为 accessibilityElementIsFocused()
,但似乎不 return true
即使该元素的 debugDescription
明确表示 Focused
。还有一些其他相关方法 accessibilityElementDidLoseFocus()
和 accessibilityElementDidBecomeFocused()
,它们似乎是旨在被 NSObject
的子类覆盖的方法,以获取 Focused
状态更改的通知.
经过这次挖掘,我倾向于说我们正在讨论的 Focused
的概念与 firstResponder
状态不同,这可能是您希望知道的.我相信在这一点上,根据对这些方法的一些评论,焦点表明该元素是某些辅助技术的焦点,例如 VoiceOver
。
如果您希望能够直接判断一个项目是否 firstResponder
,我认为此时是提交错误报告的时候了。
如果有一种方法可以直接与软件键盘交互,一个棘手的解决方法可能是为您的 UITextField
获取一个 XCUIElement
并比较您的 [=] 的 value
27=] 元素在使用键盘输入之前和之后(您可能想先输入一个字符,然后输入一个退格键)。话虽如此,我草草想不出如何直接获取键盘。
我观察到一些情况
XCUIApplication().textFields[{index/identifier}].selected
不 return 正确,即使我将光标聚焦在文本字段上但我能够使用 .typeText()
输入文本。但是,.enabled
正确地 return 是 true ,看起来 'enabled' 值表示 UI 元素启用了辅助功能,您可以与之交互。
不是一个干净的解决方案,但您可以尝试,
XCUIApplication().textFields.elementMatchingPredicate("predicate")
或 .elementMatchingType()
获取 XCUIElement 并编写测试块,同时使用 guard
语句处理异常情况,如果未找到 textField 则抛出适当的错误。
我参加聚会有点晚了 :) 但是据我转储变量 XCUIElement 所见,它有一个有趣的 属性:
property name: hasKeyboardFocus
property type: 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)")
}
}
}
基于
extension XCUIElement
{
func hasFocus() -> Bool {
let hasKeyboardFocus = (self.value(forKey: "hasKeyboardFocus") as? Bool) ?? false
return hasKeyboardFocus
}
}