是否可以通过UI测试中的代码"切换软件键盘"?

ext*_*mpl 16 xcode ios ios-simulator xcode-ui-testing

我有测试登录功能的UI测试(并用它来测试其他东西),但有时当焦点从一个字段更改为另一个字段时 - 键盘隐藏,虽然光标在字段中闪烁,但我收到错误field.typeText- no focused fields to fill.

不知怎的,我意识到,点击一个Hardware -> Keyboard -> toggle software keyboard让键盘在屏幕上保持不变,所以测试效果很好.但是我需要让它在任何开发人员机器上的任何测试设备上工作,所以我想以编程方式设置这个选项,而不要讨厌"如果测试失败,请在项目的自述文件中设置...并手动设置...".

可能吗?

Bro*_*ois 15

模拟器的.plist文件已更改为添加对多个模拟器的支持.ConnectHardwareKeyboard布尔值现在嵌套在设备的UDID下面.幸运的是,这个UDID也存储在plist文件中.您可以在UITest目标的构建阶段使用"运行脚本"添加此代码.

Xcode 9回答:

#grab the UDID from the plist
UDID=$(defaults read com.apple.iphonesimulator CurrentDeviceUDID)

#overwrite the existing value with false
#OR if the plist doesn't have that value add it in
/usr/libexec/PlistBuddy -c "Set :DevicePreferences:$UDID:ConnectHardwareKeyboard 
false" ~/Library/Preferences/com.apple.iphonesimulator.plist 
|| 
/usr/libexec/PlistBuddy -c  "Add :DevicePreferences:$UDID:ConnectHardwareKeyboard
bool false" ~/Library/Preferences/com.apple.iphonesimulator.plist
Run Code Online (Sandbox Code Playgroud)

或者您可以使用此其他代码来影响所有模拟器:

/usr/libexec/PlistBuddy -c "Print :DevicePreferences" ~/Library/Preferences/com.apple.iphonesimulator.plist | perl -lne 'print $1 if /^    (\S*) =/' | while read -r a; do /usr/libexec/PlistBuddy -c "Set :DevicePreferences:$a:ConnectHardwareKeyboard
false" ~/Library/Preferences/com.apple.iphonesimulator.plist || /usr/libexec/PlistBuddy -c  "Add :DevicePreferences:$a:ConnectHardwareKeyboard
bool false" ~/Library/Preferences/com.apple.iphonesimulator.plist; done
Run Code Online (Sandbox Code Playgroud)


Jer*_*oia 10

在Xcode 9之前,您可以通过禁用Simulator.app中的硬件键盘来解决此问题,这将导致软件键盘始终存在.例如:

defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool NO
Run Code Online (Sandbox Code Playgroud)

  • 看起来在模拟器中手动启用它后,它也保持启用 UI 测试。伤心。 (2认同)

Chr*_*ski 7

在Xcode 10.3和Xcode 11中进行了测试。下面的代码段必须位于应用程序目标中(而不是测试包中),例如,在AppDelegate.swift中。通过将any UIKeyboardInputModeautomaticHardwareLayout属性设置为,将禁止任何硬件键盘自动连接nil

不依赖于模拟器的设置。

注意:这在Simulator 11.0(Xcode 11)中似乎已修复。

#if targetEnvironment(simulator)
// Disable hardware keyboards.
let setHardwareLayout = NSSelectorFromString("setHardwareLayout:")
UITextInputMode.activeInputModes
    // Filter `UIKeyboardInputMode`s.
    .filter({ $0.responds(to: setHardwareLayout) })
    .forEach { $0.perform(setHardwareLayout, with: nil) }
#endif
Run Code Online (Sandbox Code Playgroud)

或目标-c:

#if TARGET_IPHONE_SIMULATOR
SEL setHardwareLayout = NSSelectorFromString(@"setHardwareLayout:");
for (UITextInputMode *inputMode in [UITextInputMode activeInputModes]) {
    if ([inputMode respondsToSelector:setHardwareLayout]) {
        // Note: `performSelector:withObject:` will complain, so we have to use some black magic.
        ((void (*)(id, SEL, id))[inputMode methodForSelector:setHardwareLayout])(inputMode, setHardwareLayout, NULL);
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

  • 这似乎是唯一有效的解决方案。 (4认同)
  • 可以添加到 AppDelegate:didFinishLaunchingWithOptions 中,效果很好。将修复测试,但甚至不会通过更改模拟器设置来惹恼您。顶级解决方案! (2认同)
  • 对于那些使用 fastlane 快照的人来说,这是对我有用的解决方案。谢谢@ChrisZielinski (2认同)

Eve*_*nha 6

根据布鲁克斯的精彩回答,这适用于所有模拟器:

/usr/libexec/PlistBuddy -c "Print :DevicePreferences" ~/Library/Preferences/com.apple.iphonesimulator.plist | perl -lne 'print $1 if /^    (\S*) =/' | while read -r a; do /usr/libexec/PlistBuddy -c "Set :DevicePreferences:$a:ConnectHardwareKeyboard
false" ~/Library/Preferences/com.apple.iphonesimulator.plist || /usr/libexec/PlistBuddy -c  "Add :DevicePreferences:$a:ConnectHardwareKeyboard
bool false" ~/Library/Preferences/com.apple.iphonesimulator.plist; done
Run Code Online (Sandbox Code Playgroud)

  • 在 Xcode 9.4.1 上测试并运行。这些不是多条线,而是一根长线。也尽量不要粘贴富文本。有时第一次运行时不起作用。您也可以尝试使用此文件 https://github.com/evertoncunha/cocoaheads-2018-07/blob/master/fastlane/enable_simulators_keyboards.sh (4认同)
  • 感谢您提供脚本@EvertonCunha。不幸的是,当我运行它时,我可以看到 plist 已被编辑,但模拟器仍然不显示键盘。我什至检查了你的要点,我发现你包含了一个杀死模拟器的命令,但这对我来说也不起作用。有什么线索吗? (3认同)
  • 无法在 Xcode 9.4 上工作,返回“无法识别的类型: false” (2认同)