2015-09-28 21 views
31

W moim teście mam pole tekstowe z wcześniej istniejącym tekstem. Chcę usunąć zawartość i wpisać nowy ciąg.UI Test usuwania tekstu w polu tekstowym

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

Podczas usuwania znaków z klawiatury sprzętowej nagrywania wygenerowanego dla mnie niczym. Po robi to samo z klawiaturą oprogramowania mam:

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

lub

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

Martwiłam się, że mój test jest zależne od języka, więc stworzyliśmy coś takiego dla moich obsługiwanych języków:

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

wygląda ładniej w kodzie:

app.keys.deleteKey.pressForDuration(1.5) 

, ale jest bardzo delikatna. Po wyjściu z symulatora Toggle software keyboard został zresetowany i mam test niesprawności. Moje rozwiązanie nie działa dobrze z testowaniem CI. Jak można to rozwiązać, aby było bardziej uniwersalne?

+0

Nie mogę odtworzyć awarii, której doświadczasz. Dodałem to samo rozszerzenie, przełączyłem język mojego symulatora na język polski i zweryfikowałem, że klawisz "Usún" zaczyna być podsłuchiwany. Ponowne uruchomienie/resetowanie symulatora nie ma żadnego wpływu na ustawienie 'Toggle software keyboard'. Czy w widoku tekstowym jest coś jeszcze, co mogłoby ukrywać/zwalniać klawiaturę? –

+0

Może po zrestartowaniu systemu mam reset "Toggle software keyboard". Nie jest to wartość domyślna dla symulatora (i nie wiem, czy można to zmienić). W ten czy inny sposób moja metoda nie jest niezawodna, dopóki nie można ustalić ustawień klawiatury językowej i oprogramowania z poziomu testu (lub schematu testowania). –

+0

Mój własny komentarz wpadł mi na pomysł i znalazłem ustawienie językowe w Scheme> Options> Application Language. Problem z klawiaturą nadal pozostaje nierozwiązany. –

Odpowiedz

92

Napisałem metodę rozszerzenia, aby zrobić to dla mnie i jest to dość szybkie:

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

ta jest następnie wykorzystywana dość łatwo: app.textFields["Email"].clearAndEnterText("[email protected]")

+0

Działa jak urok! Dziękuję za podzielenie się. –

+17

Możesz utworzyć "usuń ciąg" w bardziej funkcjonalny sposób za pomocą: 'let deleteString = stringValue.characters.map {_ in" \ u {8} "} .joinWithSeparator (" ")' –

+1

Oh awesome! Nie wiedziałem, że dodali "joinWithSeparator" w Swift 2. Dzięki! –

17

Po naprawieniu zlokalizowanego problemu nazwy klucza usuwanego w komentarzach do pytań, zakładam, że możesz uzyskać dostęp do klucza usuwania, po prostu nazywając go "Usuń".

Poniższy kod będzie można wiarygodnie usunąć zawartość swojej dziedzinie:

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

Ale w tym samym czasie, Twój problem może wskazywać na potrzebę rozwiązania to bardziej elegancko, aby poprawić użyteczność aplikacji . W polu tekstowym można również dodać Clear button, za pomocą którego użytkownik może natychmiast opróżnić pole tekstowe;

Otwórz scenopis i zaznacz pole tekstowe, w inspektorze atrybutów znajdź przycisk "Wyczyść" i ustaw go na żądaną opcję (np. Jest zawsze widoczny).

Clear button selection

Teraz użytkownicy mogą usunąć pole z prostym kurkiem na krzyżu po prawej stronie pola tekstowego:

Clear button

lub w teście Ui:

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

Podoba mi się pomysł z wyraźnym przyciskiem, ale wciąż szukam sposobu na wymuszenie testowania klawiatury oprogramowania. Jakby chodziło o pętlę while - każde stuknięcie ma opóźnienie, więc powoduje długie testy długich ciągów. –

+1

+1 Tak! Skorzystaj z procesu pisania testów, aby ulepszyć oprogramowanie. Może nie spełniały one w pełni wymagań PO, ale jest to dokładnie wskazówka, której potrzebowałem, gdy trafiłem na podobny problem. –

+3

To daje mi "Błąd testowania interfejsu użytkownika - Nie znaleziono dopasowań dla" Usuń "klucz" w Xcode 7.2 – Oded

3

Więc, nie znaleziono żadnych dobry rozwiązanie jeszcze:/

I nie podoba rozwiązań zależnych od lokalizacji, jak wyżej, z wyraźną Wyszukiwanie "Wyczyść tekst".

Tak, mam kontrolę typu, a następnie próbuje znaleźć jasną przycisk w polu tekstowym to działa dobrze, chyba że masz niestandardowe pole tekstowe z więcej niż jednego przycisku

Mój najlepszy obecnie jest (nie mam własny tekst Pola z kilku przycisków):

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

znalazłem następujące rozwiązanie:

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 

po dotknięciu i przytrzymaniu na polu tekstowym otwiera menu w tutaj możesz dotknąć przycisku "Wybierz wszystko". Następnie wystarczy usunąć ten tekst za pomocą przycisku "Usuń" na klawiaturze lub po prostu wprowadzić nowy tekst. Nadpisze to stare.

+2

możesz również użyć 'myTextView.doubleTap()', aby wywołać menu, które może być trochę szybsze – Hudson

0

Miałem trudności z uzyskaniem powyższych rozwiązań dla podobnego problemu, jaki miałem: kurator umieszczałby się przed tekstem, a następnie od tego miejsca. Dodatkowo chciałem sprawdzić, czy pole tekstowe zawierało tekst przed usunięciem. Oto moje rozwiązanie zainspirowane rozszerzeniem https://stackoverflow.com/users/482361/bay-phillips. Należy zauważyć, że naciskając klawisz Delete może trwać bardzo długo, a to może być podstawiony .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

Jestem nowy testów UI z iOS, ale udało mi się wyczyścić pola tekstowe z tego prostego obejście . Praca z Xcode8 i planu na refactoring to wkrótce:

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

to będzie działać na polu tekstowym i TextView

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

dla SWIFT 4 do 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) 
    } 
} 
Powiązane problemy