UI测试删除文本字段中的文本

Tom*_*Bąk 63 uitextfield uikeyboard swift xcode7 xcode-ui-testing

在我的测试中,我有一个带有预先存在的文本的文本字段.我想删除内容并键入新字符串.

let textField = app.textFields
textField.tap()
// delete "Old value"
textField.typeText("New value")
Run Code Online (Sandbox Code Playgroud)

用硬件键盘删除字符串时没有为我生成记录.用软件键盘做同样的事后我得到了:

let key = app.keys["Usu?"] // Polish name for the key
key.tap()
key.tap() 
... // x times
Run Code Online (Sandbox Code Playgroud)

要么

app.keys["Usu?"].pressForDuration(1.5)
Run Code Online (Sandbox Code Playgroud)

我担心我的测试是依赖于语言的,所以我为我支持的语言创建了类似的东西:

extension XCUIElementQuery {
    var deleteKey: XCUIElement {
        get {
            // Polish name for the key
            if self["Usu?"].exists {
                return self["Usu?"]
            } else {
                return self["Delete"]
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它在代码中看起来更好:

app.keys.deleteKey.pressForDuration(1.5)
Run Code Online (Sandbox Code Playgroud)

但它非常脆弱.从模拟器退出后Toggle software keyboard重置,我有一个失败的测试.我的解决方案不适用于CI测试.如何解决这个问题更加普遍?

Bay*_*ips 134

我写了一个扩展方法为我做这个,它很快:

extension XCUIElement {
    /**
     Removes any current text in the field before typing in the new value
     - Parameter text: the text to enter into the field
     */
    func clearAndEnterText(text: String) {
        guard let stringValue = self.value as? String else {
            XCTFail("Tried to clear and enter text into a non string value")
            return
        }

        self.tap()

        let deleteString = String(repeating: XCUIKeyboardKey.delete.rawValue, count: stringValue.count)

        self.typeText(deleteString)
        self.typeText(text)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后很容易使用它: app.textFields["Email"].clearAndEnterText("newemail@domain.com")

  • 您可以使用以下函数创建"删除字符串":`let deleteString = stringValue.characters.map {_ in"\ u {8}"} .joinWithSeparator("")` (19认同)
  • 对于Swift 4,你可以使用`let deleteString = String(重复:XCUIKeyboardKey.delete.rawValue,count:stringValue.characters.count)` (18认同)
  • 对于Swift 4.2:`let deleteString = String(重复:XCUIKeyboardKey.delete.rawValue,count:stringValue.count)` (12认同)
  • 对于swift4,请使用XCUIKeyboardKey.delete.rawValue (8认同)
  • 在 iPhone X 上,此脚本已损坏,它没有选择所有文本。 (3认同)

Mar*_*ols 19

由于您在问题的评论中修复了本地化删除密钥名称问题,因此我假设您可以通过将其命名为"删除"来访问删除密钥.

下面的代码将允许您可靠地删除您的字段的内容:

    while (textField.value as! String).characters.count > 0 {
        app.keys["Delete"].tap()
    }
Run Code Online (Sandbox Code Playgroud)

但与此同时,您的问题可能表明需要更优雅地解决此问题,以提高应用的可用性.在文本字段中,您还可以添加Clear button用户可以立即清空文本字段的内容;

打开故事板并选择文本字段,在属性检查器下找到"清除按钮"并将其设置为所需选项(例如始终可见).

清除按钮选择

现在,用户只需点击文本字段右侧的十字架即可清除该字段:

清除按钮

或者在您的UI测试中:

textField.buttons["Clear text"].tap()
Run Code Online (Sandbox Code Playgroud)

  • 这给了我"UI测试失败 - 在Xcode 7.2中找不到"删除"键" (3认同)
  • 我是在假设您正在为实际用例编写测试而不仅仅是在测试中做随机事情的情况下写的.使用每一点反馈可以提高可用性,从而为用户提供更好的应用程序. (2认同)

oli*_*ost 11

我发现以下解决方案:

let myTextView = app.textViews["some_selector"]
myTextView.pressForDuration(1.2)
app.menuItems["Select All"].tap()
app.typeText("New text you want to enter") 
// or use app.keys["delete"].tap() if you have keyboard enabled
Run Code Online (Sandbox Code Playgroud)

当您点击并按住文本字段时,它会打开菜单,您可以点击"全选"按钮.之后,您只需使用键盘上的"删除"按钮删除该文本,或只输入新文本.它会覆盖旧的.

  • 你也可以使用`myTextView.doubleTap()`调出菜单,这可能会快一些 (2认同)
  • 这并不总是有效,因为有时长按可以突出显示文本字段内的单词,这会导致“全选”按钮不可见 (2认同)

Ted*_*Ted 11

这适用于textfield和textview

对于SWIFT 3

extension XCUIElement {
    func clearText() {
        guard let stringValue = self.value as? String else {
            return
        }

        var deleteString = String()
        for _ in stringValue {
            deleteString += XCUIKeyboardKeyDelete
        }
        self.typeText(deleteString)
    }
}
Run Code Online (Sandbox Code Playgroud)

适用于SWIFT 4SWIFT 99

extension XCUIElement {
    func clearText() {
        guard let stringValue = self.value as? String else {
            return
        }

        var deleteString = String()
        for _ in stringValue {
            deleteString += XCUIKeyboardKey.delete.rawValue
        }
        self.typeText(deleteString)
    }
}
Run Code Online (Sandbox Code Playgroud)

更新XCODE 9

一个苹果bug,如果textfield为空,则value和placeholderValue相等

extension XCUIElement {
    func clearText() {
        guard let stringValue = self.value as? String else {
            return
        }
        // workaround for apple bug
        if let placeholderString = self.placeholderValue, placeholderString == stringValue {
            return
        }

        var deleteString = String()
        for _ in stringValue {
            deleteString += XCUIKeyboardKey.delete.rawValue
        }
        self.typeText(deleteString)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 哇,你可以预测直到Swift 99? (4认同)

zys*_*oft 8

Xcode 9,斯威夫特 4

尝试了上面的解决方案,但由于一些奇怪的点击行为而没有奏效 - 它将光标移动到文本字段的开头或文本中的某个随机点。我使用的方法是@oliverfrost在此处描述的方法,但我添加了一些方法来解决这些问题,并将其组合在一个简洁的扩展中。我希望它对某人有用。

extension XCUIElement {
    func clearText(andReplaceWith newText:String? = nil) {
        tap()
        tap() //When there is some text, its parts can be selected on the first tap, the second tap clears the selection
        press(forDuration: 1.0)
        let selectAll = XCUIApplication().menuItems["Select All"]
        //For empty fields there will be no "Select All", so we need to check
        if selectAll.waitForExistence(timeout: 0.5), selectAll.exists {
            selectAll.tap()
            typeText(String(XCUIKeyboardKey.delete.rawValue))
        }
        if let newVal = newText { typeText(newVal) }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

let app = XCUIApplication()
//Just clear text
app.textFields["field1"].clearText() 
//Replace text    
app.secureTextFields["field2"].clearText(andReplaceWith: "Some Other Text")
Run Code Online (Sandbox Code Playgroud)


Hon*_*ang 5

您可以使用doubleTap选择所有文本并键入要替换的新文本:

extension XCUIElement {
  func typeNewText(_ text: String) {
    if let existingText = value as? String, !existingText.isEmpty {
      if existingText != text {
        doubleTap()
      } else {
        return
      }
    }

    typeText(text)
  }
}
Run Code Online (Sandbox Code Playgroud)

用法:

textField.typeNewText("New Text")
Run Code Online (Sandbox Code Playgroud)

  • 迄今为止最好的解决方案 (2认同)