UI测试失败 - 无论是元素还是任何后代都没有将键盘焦点放在secureTextField上

问题描述 投票:92回答:19

这是我的情况:

let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.tap()
passwordSecureTextField.typeText("wrong_password") //here is an error

UI测试失败 - 元素和任何后代都没有键盘焦点。元件:

怎么了?这对正常的textFields很有用,但问题只出现在secureTextFields。任何解决方法?

ios xcode swift ios9 xcode-ui-testing
19个回答
168
投票

这个问题给我带来了痛苦的世界,但我已经设法找到了一个合适的解决方案。在模拟器中,确保“硬件 - >键盘 - >连接硬件键盘”已关闭。


3
投票

记录案例,但你想要,键盘或没有键盘连接。但在进行测试前请执行以下操作。

在播放测试时,应取消选中以下选项(连接硬件键盘)。

enter image description here


2
投票

[重新发布Bartłomiej Semańczyk的评论作为答案,因为它解决了我的问题]

我需要在模拟器菜单栏中进行模拟器>重置内容和设置,以便开始为我工作。


0
投票

你的第一行只是一个查询定义,这并不意味着passwordSecureTextField实际上会存在。

您的第二行将动态执行查询并尝试(重新)将查询绑定到UI元素。您应该在其上放置一个断点并验证是否找到了一个且只有一个元素。或者只使用断言:

XCTAssertFalse(passwordSecureTextField.exists);

否则它看起来不错,tap应该强制键盘可见,然后typeText应该工作。错误日志应该告诉您更多信息。


0
投票

不要搞砸了,有问题的原因是你记录了你的测试时间,你的应用程序将连接硬件键盘,而你的自动测试时间模拟器只需要软件键盘。所以如何解决这个问题。只需在录制时使用软键盘即可。你可以看到魔力。


0
投票

对我来说问题与特德一样。实际上,如果在登录字段和硬件KB打开后点击密码字段,软件键盘将在第二次点击时自动关闭,并且它不是特定于UI测试。

经过一段时间搞乱AppleScript,这就是我想出的(欢迎改进):

tell application "Simulator" activate tell application "System Events" try tell process "Simulator" tell menu bar 1 tell menu bar item "Hardware" tell menu "Hardware" tell menu item "Keyboard" tell menu "Keyboard" set menuItem to menu item "Connect Hardware Keyboard" tell menu item "Connect Hardware Keyboard" set checkboxStatus to value of attribute "AXMenuItemMarkChar" of menuItem if checkboxStatus is equal to "✓" then click end if end tell end tell end tell end tell end tell end tell end tell on error tell application "System Preferences" activate set securityPane to pane id "com.apple.preference.security" tell securityPane to reveal anchor "Privacy_Accessibility" display dialog "Xcode needs Universal access to disable hardware keyboard during tests(otherwise tests may fail because of focus issues)" end tell end try end tell end tell

使用上面的代码创建一个脚本文件并将其添加到必要的目标(可能只是UI测试目标,您可能希望在开发期间向开发目标添加类似的脚本以重新启用HW键盘)。您应该在构建阶段添加Run Script阶段并使用它:osascript Path/To/Script/script_name.applescript


0
投票

在为包含accessibilityIdentifier子视图的自定义视图(UIStackView子类)设置UIControl值时,我们遇到了同样的错误。在那种情况下,XCTest无法获得后代元素的键盘焦点。

我们的解决方案只是从父视图中删除accessibilityIdentifier,并通过专用属性为子视图设置accessibilityIdentifier


0
投票

有时文本字段不会实现为文本字段,或者它们被包装到另一个UI元素中并且不容易访问。这是一个解决方法:

//XCUIApplication().scrollViews.otherElements.staticTexts["Email"] the locator for the element
RegistrationScreenStep1of2.emailTextField.tap()
let keys = app.keys
 keys["p"].tap() //type the keys that you need
 
 //If you stored your data somewhere and need to access that string //you can cats your string to an array and then pass the index //number to key[]
 
 let newUserEmail = Array(newPatient.email())
 let password = Array(newPatient.password)
 
 //When you cast your string to an array the elements of the array //are Character so you would need to cast them into string otherwise //Xcode will compain. 
 
 let keys = app.keys
     keys[String(newUserEmail[0])].tap()
     keys[String(newUserEmail[1])].tap()
     keys[String(newUserEmail[2])].tap()
     keys[String(newUserEmail[3])].tap()
     keys[String(newUserEmail[4])].tap()
     keys[String(newUserEmail[5])].tap()       

0
投票

另一个答案,但对我们来说问题是视图太接近另一个观点,即手势识别器。我们发现我们需要视图至少20像素(在下面我们的例子中)。字面上15个不起作用,20个或更多起作用。这很奇怪,我承认,但我们有一些UITextViews正在工作,一些不是,所有都在同一个父和相同的其他定位(当然和变量名称)。键盘打开或关闭或任何没有任何区别。可访问性显示了字段。我们重启了电脑。我们做了干净的构建。新鲜的来源结账。


0
投票

为我解决这个问题的原因是增加了1秒的睡眠时间:

let textField = app.textFields["identifier"]
textField.tap()
sleep(1)
textField.typeText(text)

-1
投票

与Securetextfields有同样的问题。我的模拟器中的连接硬件选项是,但仍遇到问题。最后,这对我有用(Swift 3):

 let enterPasswordSecureTextField = app.secureTextFields["Enter Password"]
    enterPasswordSecureTextField.tap()
    enterPasswordSecureTextField.typeText("12345678")

14
投票

最近我们发现了一个黑客从接受的答案持久化解决方案。要禁用模拟器设置:'硬件 - >键盘 - >连接硬件键盘'从命令行应该写:

defaults write com.apple.iphonesimulator ConnectHardwareKeyboard 0

它不会影响正在运行的模拟器 - 您需要重新启动模拟器或启动新模拟器才能使该设置生效。


14
投票

我写了一个小扩展(Swift),对我来说非常适合。这是代码:

extension XCTestCase {

    func tapElementAndWaitForKeyboardToAppear(element: XCUIElement) {
        let keyboard = XCUIApplication().keyboards.element
        while (true) {
            element.tap()
            if keyboard.exists {
                break;
            }
            NSRunLoop.currentRunLoop().runUntilDate(NSDate(timeIntervalSinceNow: 0.5))
        }
    }
}

主要思想是在键盘出现之前继续点击元素(文本字段)。


11
投票

斯坦尼斯拉夫有正确的想法。

在团队环境中,您需要能够自动运行的东西。我在我的博客上想出了修复here

基本上你只需粘贴:

UIPasteboard.generalPasteboard().string = "Their password"
let passwordSecureTextField = app.secureTextFields["password"]
passwordSecureTextField.pressForDuration(1.1)
app.menuItems["Paste"].tap()

6
投票

此错误的另一个原因是,如果您正在尝试输入设置为辅助功能元素(view.isAccessibilityElement = true)的文本的文本字段的父视图。在这种情况下,XCTest无法获取子视图上的句柄以输入文本并返回错误。

UI测试失败 - 元素和任何后代都没有键盘焦点。

并不是没有元素具有焦点(因为你经常可以在UITextField中看到键盘向上和闪烁的光标),它只是没有它可以到达的元素具有焦点。尝试在UISearchBar中输入文本时遇到了这个问题。搜索栏本身不是文本字段,将其设置为辅助功能元素时,对基础UITextField的访问被阻止。要解决这个问题,searchBar.accessibilityIdentifier = "My Identifier"设置在UISearchBar上,但是isAccessibilityElement没有设置为true。在此之后,测试代码的形式如下:

app.otherElements["My Identifier"].tap()
app.otherElements["My Identifier"].typeText("sample text")

作品


5
投票

在启动应用程序和在像这样的文本字段中键入数据之间使用休眠:

sleep(2)

在我的情况下,我每次都会收到此错误,只有这个解决方案帮助了我。


4
投票
func pasteTextFieldText(app:XCUIApplication, element:XCUIElement, value:String, clearText:Bool) {
    // Get the password into the pasteboard buffer
    UIPasteboard.generalPasteboard().string = value

    // Bring up the popup menu on the password field
    element.tap()

    if clearText {
        element.buttons["Clear text"].tap()
    }

    element.doubleTap()

    // Tap the Paste button to input the password
    app.menuItems["Paste"].tap()
}

4
投票

它发生在我身上很多次了。您必须在模拟器中禁用键盘硬件和与OSX相同的布局

硬件/键盘(全部禁用)

之后,键盘软件不会被解雇,您的测试可以输入文本

Disable Hardware


3
投票

这可能有所帮助:我只是在错误之前添加“点击”动作;就这样 :)

[app.textFields[@"theTitle"] tap];
[app.textFields[@"theTitle"] typeText:@"kk"];
© www.soinside.com 2019 - 2024. All rights reserved.