2015-09-28 3 views
31

В моем тесте у меня есть текстовое поле с уже существующим текстом. Я хочу удалить содержимое и ввести новую строку.UI Test, удаляющий текст в текстовом поле

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

При удалении строки с аппаратной клавиатурой Запись не генерирует для меня ничего. После того, как делать то же самое с программной клавиатурой я получил:

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

или

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

Я был обеспокоен тем, что мой тест зависит от языка, так что я создал что-то вроде этого для моих поддерживаемых языков:

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

Это выглядит лучше в коде:

app.keys.deleteKey.pressForDuration(1.5) 

но очень хрупкий. После выхода из Simulator Toggle software keyboard был сброшен, и у меня был провал. Мое решение не очень хорошо работает с тестированием CI. Как это можно решить, чтобы быть более универсальным?

+0

Я не могу воспроизвести неудачу, с которой вы столкнулись. Я добавил то же расширение, переключил язык своего симулятора на польский и проверил, что ключ «Usún» получает прослушивание. Перезапуск/сброс симулятора, похоже, не влияет на настройку «Toggle software keyboard». Есть ли что-то еще в текстовом представлении, которое может скрывать/отклонять клавиатуру? –

+0

Возможно, после перезагрузки системы у меня перезагрузилась клавиатура «Toggle software keyboard». Это не по умолчанию для симулятора (и я не знаю, можно ли это изменить). Этот способ или другой метод не является надежным, пока вы не сможете исправить языковые и программные настройки клавиатуры с уровня теста (или схемы тестирования). –

+0

Мой собственный комментарий дал мне представление, и я нашел настройки языка в Scheme> Options> Application Language. Проблема с клавиатурой по-прежнему остается нерешенной. –

ответ

92

Я написал метод расширения, чтобы сделать это для меня, и это довольно быстро:

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

Это затем используется довольно легко: app.textFields["Email"].clearAndEnterText("[email protected]")

+0

Работает как шарм! Спасибо, что поделились. –

+17

Вы можете создать «удалить строку» более функционально с помощью: 'let deleteString = stringValue.characters.map {_ in" \ u {8} "} .joinWithSeparator (" ")' –

+1

Oh awesome! Я не знал, что они добавили 'joinWithSeparator' в Swift 2. Спасибо! –

17

Поскольку в комментариях к вашим вопросам была исправлена ​​локализованная проблема с именем имени ключа, я предположим, что вы можете получить доступ к ключу удаления, просто называя его «Удалить».

Приведенный ниже код позволит вам надежно удалить содержимое поля:

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

Но в то же время, ваш вопрос может указывать на необходимость решить эту проблему более элегантно, чтобы улучшить юзабилити вашего приложения , В текстовом поле вы также можете добавить Clear button, с помощью которого пользователь может немедленно удалить текстовое поле;

Откройте раскадровку и выберите текстовое поле, под инспектором атрибутов найдите «Очистить кнопку» и установите его на нужную опцию (например, всегда видна).

Clear button selection

Теперь пользователи могут очистить поле с простым нажатием на кресте справа от текстового поля:

Clear button

Или в тесте UI:

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

Мне нравится идея с четкой кнопкой, но я все еще ищу способ заставить клавиатуру программного обеспечения в тестах. Как будто это происходит во время цикла - у каждого нажатия есть задержка после него, поэтому он делает тесты медленными для длинных строк. –

+1

+1 Да! Используйте процесс написания тестов для улучшения программного обеспечения. Возможно, это не совсем соответствовало требованиям OP, но это именно тот указатель, который мне нужен, когда я сталкивался с подобной проблемой. –

+3

Это дает мне «Ошибка тестирования пользовательского интерфейса». Не найдено совпадений для «Удалить ключ» в Xcode 7.2 – Oded

3

Так что, я не нашел ни одного хорошее решение еще:/

И мне не нравится региональные зависимые решения, как выше, с явным «Очистить текст».

Итак, я проверку типа, а затем пытается найти четкую кнопку в текстовом поле Это хорошо работает, если у вас нет пользовательского текстового поля с более чем одной кнопкой

Мой лучший сейчас (у меня нет пользовательского текста поля с большим количеством кнопок):

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

я нашел следующее решение:

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 

При нажатии и удерживании на текстовом поле открывает меню ш здесь вы можете нажать кнопку «Выбрать все». После этого вам нужно только удалить этот текст с помощью кнопки «удалить» на клавиатуре или просто ввести новый текст. Он перезапишет старый.

+2

, вы также можете использовать 'myTextView.doubleTap()' для вызова меню, которое может быть немного быстрее – Hudson

0

У меня возникли трудности с получением вышеуказанных решений для работы с аналогичной проблемой, с которой я столкнулся: курсор помещается перед текстом, а затем откладывается назад. Кроме того, я хотел проверить, чтобы текстовое поле содержало текст перед удалением. Вот мое решение, вдохновленное расширением https://stackoverflow.com/users/482361/bay-phillips. Я хотел бы отметить, что нажав клавишу удаления может занять много времени, и он может быть замещен .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

Я новичок тестирования пользовательского интерфейса с прошивкой, но я был в состоянии очистить текстовые поля с помощью этого простого обхода , Работа с Xcode8 и планом на рефакторинг это в ближайшее время:

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

это будет работать на текстовое поле и TextView

для СВИФТА 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) 
    } 
} 

для СВИФТ 4 к СВИФТУ 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) 
    } 
} 
Смежные вопросы