2015-09-28 17 views
31

Nel mio test ho un campo di testo con un testo preesistente. Voglio eliminare il contenuto e digitare una nuova stringa.UI Test eliminazione del testo nel campo di testo

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

Quando si elimina la stringa con la tastiera hardware Registrazione generata per me nulla. Dopo aver fatto lo stesso con tastiera software ho ottenuto:

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

o

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

Ero preoccupato che la mia prova è dipendente dalla lingua così ho creato qualcosa di simile per i miei lingue supportate:

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

sembra più bello in codice:

app.keys.deleteKey.pressForDuration(1.5) 

ma è molto fragile. Dopo aver lasciato il simulatore, il Toggle software keyboard è stato ripristinato e il test è fallito. La mia soluzione non funziona bene con i test CI. Come può essere risolto questo per essere più universale?

+0

Non riesco a riprodurre l'errore riscontrato. Ho aggiunto la stessa estensione, ho cambiato la lingua del mio simulatore in polacco e ho verificato che il tasto "Usún" fosse intercettato. Il riavvio/ripristino del simulatore non sembra avere alcun effetto sull'impostazione "Attiva tastiera software". C'è qualcos'altro nella visualizzazione del testo che potrebbe nascondere/chiudere la tastiera? –

+0

Forse dopo il riavvio del sistema ho ripristinato il comando "Attiva tastiera software". Non è predefinito per il simulatore (e non so se questo può essere modificato). In questo modo o nell'altro il mio metodo non è affidabile finché non è possibile correggere le impostazioni della lingua e della tastiera del software dal livello del test (o dallo schema di test). –

+0

Il mio commento mi ha dato un'idea e ho trovato l'impostazione della lingua in Schema> Opzioni> Lingua dell'applicazione. Il problema della tastiera rimane ancora irrisolto. –

risposta

92

Ho scritto un metodo di estensione per fare questo per me ed è piuttosto veloce:

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

Questo viene poi utilizzato abbastanza facilmente: app.textFields["Email"].clearAndEnterText("[email protected]")

+0

Funziona come un fascino! Grazie per aver condiviso. –

+17

È possibile creare "cancella stringa" in modo più funzionale con: 'let deleteString = stringValue.characters.map {_ in" \ u {8} "} .joinWithSeparator (" ")' –

+1

Oh fantastico! Non sapevo che avevano aggiunto 'joinWithSeparator' in Swift 2. Grazie! –

17

Dal momento che hai risolto il problema del nome della chiave di cancellazione localizzato nei commenti delle tue domande, suppongo che tu possa accedere alla chiave di cancellazione semplicemente chiamando "Elimina".

Il codice qui sotto ti permette di eliminare in modo affidabile il contenuto del vostro campo:

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

Ma, allo stesso tempo, il problema potrebbe indicare la necessità di risolvere il più elegante per migliorare l'usabilità della vostra applicazione . Nel campo di testo puoi anche aggiungere un Clear button con il quale un utente può immediatamente svuotare il campo di testo;

Aprire lo storyboard e selezionare il campo di testo, sotto l'ispettore attributi trovare "Cancella pulsante" e impostarlo sull'opzione desiderata (ad es. È sempre visibile).

Clear button selection

Ora gli utenti possono cancellare il campo con un semplice tocco sulla croce a destra del campo di testo:

Clear button

O nel test UI:

textField.buttons["Clear text"].tap() 
+0

Mi piace l'idea con il pulsante di cancellazione, ma sto ancora cercando un modo per forzare la tastiera del software nei test. Come se si trattasse di loop while - ogni tocco ha un ritardo dopo di esso, quindi rende i test lenti per le stringhe lunghe. –

+1

+1 Sì! Utilizzare il processo di scrittura dei test per migliorare il software. Forse non ha soddisfatto i requisiti dell'OP ma è esattamente il puntatore di cui avevo bisogno quando ho riscontrato un problema simile. –

+3

Questo mi dà "UI Testing Failure - Nessuna corrispondenza trovata per" Elimina "Key in Xcode 7.2 – Oded

3

Quindi, non ho trovato alcuna soluzione buon ancora:/

E che non mi piacciono soluzioni dipendenti delle versioni locali, come sopra, con esplicito Ricerca "testo chiaro".

Quindi, faccio il tipo di controllo, poi cercando di trovare il pulsante chiaro nel campo di testo Funziona bene se non si ha campo di testo personalizzato con più di un pulsante

Il mio migliore ora è (non ho il testo personalizzato campi con più pulsanti):

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

ho trovato seguente soluzione:

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 

Quando si tocca e si tiene premuto sul campo di testo si apre menù w qui puoi toccare il pulsante "Seleziona tutto". Dopo tutto quello che ti serve è rimuovere quel testo con il pulsante "cancella" sulla tastiera o semplicemente inserire un nuovo testo. Sovrascriverà quello vecchio.

+2

puoi anche usare 'myTextView.doubleTap()' per far apparire il menu, che potrebbe essere un po 'più veloce – Hudson

0

Ho avuto qualche difficoltà a ottenere le soluzioni di cui sopra per funzionare per un problema simile che stavo avendo: il curser si posizionerebbe prima del testo e quindi tornerà indietro da lì. Inoltre, volevo controllare che il campo di testo contenesse del testo prima di eliminarlo. Ecco la mia soluzione ispirata all'estensione https://stackoverflow.com/users/482361/bay-phillips scritta. Vorrei sottolineare che l'toccando il tasto di cancellazione può richiedere molto tempo, e può essere sostituito con .pressForDuration

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

Sono nuovo di test UI con iOS, ma sono stato in grado di cancellare i campi di testo con questa semplice soluzione . Lavorare con Xcode8 e pensiamo di refactoring questo presto:

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... 
} 
2

questo lavoro per campo di testo e TextView

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

per 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) 
    } 
} 
Problemi correlati