2015-09-28 12 views
31

In meinem Test habe ich ein Textfeld mit einem bereits vorhandenen Text. Ich möchte den Inhalt löschen und eine neue Zeichenfolge eingeben.UI Test Löschen von Text im Textfeld

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

Beim Löschen String mit Hardware-Tastatur Aufnahme für mich nichts generiert. Nachdem ich das gleiche mit Software-Tastatur bekam ich:

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

oder

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

Ich war besorgt, dass meine Testsprachabhängig ist, damit ich so etwas für meine unterstützten Sprachen erstellt haben:

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

Es sieht schöner in Code:

app.keys.deleteKey.pressForDuration(1.5) 

aber es ist sehr zerbrechlich. Nach dem Beenden von Simulator wurde zurückgesetzt und ich habe einen fehlgeschlagenen Test. Meine Lösung funktioniert nicht gut mit CI-Tests. Wie kann das gelöst werden, um universeller zu sein?

+0

Ich kann den Fehler, den Sie erleben, nicht reproduzieren. Ich fügte die gleiche Erweiterung hinzu, änderte die Sprache meines Simulators auf Polnisch und vergewisserte sich, dass die Taste "Usún" angetippt wurde. Das Neustarten/Zurücksetzen des Simulators scheint keine Auswirkungen auf die Einstellung "Toggle-Softwaretastatur" zu haben. Gibt es noch etwas in der Textansicht, das die Tastatur verstecken könnte? –

+0

Vielleicht nach dem Neustart des Systems habe ich 'Toggle Software Keyboard' zurückgesetzt. Es ist kein Standard für den Simulator (und ich weiß nicht, ob das geändert werden kann). Auf diese oder jene Weise ist meine Methode nicht zuverlässig, bis Sie die Sprach- und Softwaretastatureinstellungen auf der Ebene des Tests (oder des Testschemas) korrigieren können. –

+0

Mein eigener Kommentar gab mir eine Idee und ich habe die Sprache in Schema> Optionen> Anwendungssprache gefunden. Das Tastaturproblem bleibt weiterhin ungelöst. –

Antwort

92

Ich schrieb eine Erweiterungsmethode, um dies für mich zu tun, und es ist ziemlich schnell:

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

Dies wird dann ziemlich leicht verwendet: app.textFields["Email"].clearAndEnterText("[email protected]")

+0

Funktioniert wie ein Charme! Ich danke Ihnen für das Teilen. –

+17

Sie können "delete string" in mehr funktionaler Weise erstellen mit: 'let deleteString = stringValue.characters.map {_ in" \ u {8} "} .joinWithSeparator (" ")' –

+1

Oh awesome! Ich wusste nicht, dass sie in Swift 2 JoinWithSeparator hinzugefügt hatten. Danke! –

17

Da Sie in den Kommentaren Ihrer Fragen das lokalisierte Problem mit dem Namen des Löschschlüssels behoben haben, nehme ich an, dass Sie auf den Löschschlüssel zugreifen können, indem Sie einfach "Delete" aufrufen.

Der folgende Code ermöglicht es Ihnen, den Inhalt des Feldes zuverlässig zu löschen:

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

Aber zugleich könnte Ihr Problem die Notwendigkeit zeigt diese eleganter zu lösen, um die Benutzerfreundlichkeit Ihrer App zu verbessern . Auf dem Textfeld können Sie auch eine Clear button hinzufügen, mit der ein Benutzer sofort das Textfeld leeren kann;

Öffnen Sie das Storyboard und wählen Sie das Textfeld, unter den Attributen Inspector finden Sie "Clear button" und stellen Sie es auf die gewünschte Option (z. B. ist immer sichtbar).

Clear button selection

Jetzt können Benutzer auf dem Kreuz rechts neben dem Textfeld, das Feld mit einem einfachen Tippen löschen:

Clear button

oder in Ihrem UI-Test:

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

Ich mag die Idee mit klaren Knopf, aber ich suche immer noch einen Weg, um die Software-Tastatur in Tests zu erzwingen. Als ob es zur While-Schleife kommen würde - jede Berührung hat eine Verzögerung nach sich, so dass Tests für lange Saiten langsam werden. –

+1

+1 Ja! Verwenden Sie den Prozess des Schreibens der Tests, um die Software zu verbessern. Vielleicht hat es die Anforderungen des OP nicht ganz erfüllt, aber es ist genau der Zeiger, den ich brauchte, wenn ich auf ein ähnliches Problem stieß. –

+3

Das gibt mir "UI Testing Failure - Keine Übereinstimmungen gefunden für" Delete "Key" in Xcode 7.2 – Oded

3

So habe ich jede gute Lösung noch nicht gefunden:/

Und ich locale abhängige Lösungen nicht gefällt, wie oben mit ausdrücklicher "Text löschen" -Lookup.

Also, ich Art zu überprüfen, dann Clear-Taste im Textfeld zu finden versuchen, gut Es funktioniert, wenn Sie benutzerdefiniertes Textfeld haben mit mehr als eine Taste

Meine besten jetzt (Ich habe keinen benutzerdefinierten Text mit mehr Tasten Felder):

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

ich folgende Lösung gefunden:

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 

Wenn Sie auf das Textfeld tippen und halten öffnet Menü w Hier können Sie auf die Schaltfläche "Alle auswählen" tippen. Danach brauchen Sie nur den Text mit der "Löschen" Taste auf der Tastatur zu entfernen oder einfach einen neuen Text einzugeben. Es wird das alte überschreiben.

+2

Sie können auch 'myTextView.doubleTap()' verwenden, um das Menü aufzurufen, das möglicherweise etwas schneller ist – Hudson

0

Ich hatte einige Schwierigkeiten, die oben genannten Lösungen für ein ähnliches Problem zu bekommen, das ich hatte: Der Cursor würde sich vor dem Text platzieren und dann von dort rückwärts arbeiten. Außerdem wollte ich überprüfen, ob das Textfeld Text enthielt, bevor es gelöscht wurde. Hier ist meine Lösung inspiriert von der Erweiterung https://stackoverflow.com/users/482361/bay-phillips schrieb. Ich soll anmerken, dass die die Löschtaste tippt eine lange Zeit in Anspruch nehmen kann, und es kann mit .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

ich neu mit iOS UI-Tests bin ersetzt werden, aber ich war in der Lage Textfelder mit dieser einfachen Abhilfe löschen . Arbeiten mit Xcode8 und planen diese in Kürze auf Refactoring:

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

dies für Textfeld und Textview arbeiten

für 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) 
    } 
} 

für SWIFT 4 zu SWIFT 99