Prueba de interfaz de usuario eliminar texto en el campo de texto


En mi prueba tengo un campo de texto con un texto preexistente. Quiero eliminar el contenido y escribir una nueva cadena.

let textField = app.textFields
textField.tap()
// delete "Old value"
textField.typeText("New value")

Al eliminar la cadena con la grabación de teclado de hardware generado para mí nada. Después de hacer lo mismo con el teclado de software obtuve:

let key = app.keys["Usuń"] // Polish name for the key
key.tap()
key.tap() 
... // x times

O

app.keys["Usuń"].pressForDuration(1.5)

Me preocupaba que mi prueba dependiera del idioma, así que he creado algo como esto para mis idiomas compatibles:

extension XCUIElementQuery {
    var deleteKey: XCUIElement {
        get {
            // Polish name for the key
            if self["Usuń"].exists {
                return self["Usuń"]
            } else {
                return self["Delete"]
            }
        }
    }
}

Se ve mejor en código:

app.keys.deleteKey.pressForDuration(1.5)

Pero es muy frágil. Después de salir del Simulador Toggle software keyboard se reinició y tengo una prueba fallida. Mi solución no funciona bien con las pruebas de CI. ¿Cómo se puede resolver esto para ser más universal?

Author: Tomasz Bąk, 2015-09-28

9 answers

Escribí un método de extensión para hacer esto por mí y es bastante rápido:

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 = stringValue.characters.map { _ in XCUIKeyboardKeyDelete }.joined(separator: "")

        self.typeText(deleteString)
        self.typeText(text)
    }
}

Esto se usa bastante fácilmente: app.textFields["Email"].clearAndEnterText("[email protected]")

 110
Author: Bay Phillips,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-17 10:01:53

Dado que solucionó el problema del nombre de la clave de eliminación localizada en los comentarios de sus preguntas, asumiré que puede acceder a la clave de eliminación simplemente llamándola "Eliminar".

El siguiente código le permitirá eliminar de forma fiable el contenido de su campo:

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

Pero al mismo tiempo, su problema podría indicar la necesidad de resolver esto de manera más elegante para mejorar la usabilidad de su aplicación. En el campo de texto también puede agregar un Clear button con el que un usuario puede vaciar inmediatamente el texto campo;

Abra el guion gráfico y seleccione el campo de texto, bajo el inspector de atributos encuentre "Borrar botón" y configúrelo a la opción deseada (por ejemplo, siempre está visible).

Borrar selección de botón

Ahora los usuarios pueden borrar el campo con un simple toque en la cruz a la derecha del campo de texto:

Borrar botón

O en su prueba de IU:

textField.buttons["Clear text"].tap()
 18
Author: Martijn Hols,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-29 10:53:10

Encontré la siguiente solución:

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

Cuando mantienes pulsado el campo de texto, se abre el menú donde puedes pulsar en el botón "Seleccionar todo". Después de eso, todo lo que necesita es eliminar ese texto con el botón "eliminar" en el teclado o simplemente ingresar texto nuevo. Sobrescribirá el viejo.

 9
Author: oliverfrost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-02 04:55:01

Esto funcionará para textfield y textview

Para 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)
    }
}

Para SWIFT 4 a SWIFT 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)
    }
}

ACTUALIZAR XCODE 9

Hay un error de apple donde si el campo de texto está vacío, el valor y el valor del marcador de posición son iguales

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)
    }
}
 5
Author: Ted,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-02 10:35:14

Entonces, no encontré ninguna buena solución todavía: /

Y no me gustan las soluciones dependientes de la configuración regional, como las anteriores con búsqueda explícita de "Texto claro".

Entonces, escribo check, luego trato de encontrar el botón clear en el campo de texto Funciona bien a menos que tenga un campo de texto personalizado con más de un botón

Mi mejor ahora es (no tengo campos de texto personalizados con más botones):

    class func clearTextField(textField : XCUIElement!) -> Bool {

        guard textField.elementType != .TextField else {
            return false
        }

        let TextFieldClearButton = textField.buttons.elementBoundByIndex(0)

        guard TextFieldClearButton.exists else {
            return false
        }

        TextFieldClearButton.tap()

        return true
    }
 4
Author: Oleg Shanyuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-06 14:53:01

Xcode 9, Swift 4

Probó las soluciones anteriores, pero ninguna funcionó debido a un comportamiento extraño al tocar: movió el cursor al principio del campo de texto o en algún punto aleatorio del texto. El enfoque que he utilizado es lo que @ oliverfrost describe aquí , pero he añadido algunos toques para trabajar alrededor de los problemas y combinarlo en una extensión ordenada. Espero que pueda ser útil para alguien.

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) }
    }
}

Uso:

let app = XCUIApplication()
//Just clear text
app.textFields["field1"].clearText() 
//Replace text    
app.secureTextFields["field2"].clearText(andReplaceWith: "Some Other Text")
 2
Author: zysoft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-12 20:38:37

Tuve algunas dificultades para conseguir que las soluciones anteriores funcionaran para un problema similar que estaba teniendo: El curser se colocaría antes del texto y luego trabajaría hacia atrás desde allí. Además, quería comprobar que el textfield tenía texto antes de eliminarlo. Aquí está mi solución inspirada en la extensión https://stackoverflow.com/users/482361/bay-phillips escribió. Debo tener en cuenta que el toque de la tecla eliminar puede tomar mucho tiempo, y se puede sustituir con .pressForDuración

func clearAndEnterText(element: XCUIElement, text: String) -> Void
    {
        guard let stringValue = element.value as? String else {
            XCTFail("Tried to clear and enter text into a non string value")
            return
        }

        element.tap()

        guard stringValue.characters.count > 0 else
        {
            app.typeText(text)
            return
        }

       for _ in stringValue.characters
        {
            app.keys["delete"].tap()
        }
        app.typeText(text)
    }
 0
Author: Phillip English,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:11

Soy nuevo en las pruebas de interfaz de usuario con iOS, pero pude borrar los campos de texto con esta solución simple. Trabajando con Xcode8 y planea refactorizar esto pronto:

func testLoginWithCorrectUsernamePassword() {
      //Usually this will be completed by Xcode
    let app = XCUIApplication()
      //Set the text field as a constant
    let usernameTextField = app.textFields["User name"]
      //Set the delete key to a constant
    let deleteKey = app.keys["delete"]
      //Tap the username text field to toggle the keyboard
    usernameTextField.tap()
      //Set the time to clear the field.  generally 4 seconds works
    deleteKey.press(forDuration: 4.0);
      //Enter your code below...
}
 0
Author: Jonathan Sweeney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-22 19:35:26

Haga esto para eliminar el valor de cadena actual en un cuadro de texto sin depender del teclado virtual.

/ / lee el valor de tu cuadro de texto en esta variable let textInTextField: String =

  let characterCount: Int = textInTextField.count
  for _ in 0..<characterCount {
    textFields[0].typeText(XCUIKeyboardKey.delete.rawValue)
  }

Lo bueno de esta solución es que funciona independientemente de que el simulador tenga teclado virtual o no.

 0
Author: Dilip Agheda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-20 06:24:48