iOS 9 Swift Programming Cookbook (2015)
Chapter 9. UI Testing
9.5 Long Pressing on UI Elements
Problem
You want to be able to simulate long-pressing on a UI element using UI tests.
Solution
Use the pressForDuration(_:) method of XCUIElement.
Discussion
Create a single view app and when your view gets loaded, add a long gesture recognizer to your view. The following code waits until the user long-presses the view for 5 seconds:
override func viewDidLoad() {
super.viewDidLoad()
view.isAccessibilityElement = true
let gr = UILongPressGestureRecognizer(target: self,
action: "handleLongPress")
gr.minimumPressDuration = 5
view.addGestureRecognizer(gr)
}
The gesture recognizer is hooked to a method. In this method, we will show an alert controller and ask the user for her name. Once she has answered the question and pressed the Save button on the alert, we will set the entered value as the accessibility value of our view so that we can read it in our UI tests:
func handleLongPress(){
let c = UIAlertController(title: "Name", message: "What is your name?",
preferredStyle: .Alert)
c.addAction(UIAlertAction(title: "Cancel", style: .Destructive,
handler: nil))
c.addAction(UIAlertAction(title: "Save", style: .Destructive){
action in
guard let fields = c.textFields where fields.count == 1 else{
return
}
let txtField = fields[0]
guard let txt = txtField.text where txt.characters.count > 0 else{
return
}
self.view.accessibilityValue = txt
})
c.addTextFieldWithConfigurationHandler {txt in
txt.placeholder = "Foo Bar"
}
presentViewController(c, animated: true, completion: nil)
}
Now let’s go to our UI test code and do the followings:
1. Get an instance of our app.
2. Find our view object with the childrenMatchingType(_:) method of our app.
3. Call the pressForDuration(_:) method on it.
4. Call the typeText(_:) method of our app objectand find the Save button on the dialog.
5. Programmatically press the save button using the tap() method.
6. Check the value of our view and check it against the value that we entered earlier. They should match.
let app = XCUIApplication()
let view = app.windows.childrenMatchingType(.Unknown).elementBoundByIndex(0)
view.pressForDuration(5)
XCTAssert(app.alerts.count > 0)
let text = "Foo Bar"
app.typeText(text)
let alert = app.alerts.elementBoundByIndex(0)
let saveBtn = alert.descendantsMatchingType(.Button).matchingPredicate(
NSPredicate(format: "title like[c] 'Save'")).elementBoundByIndex(0)
saveBtn.tap()
XCTAssert(view.value as! String == text)
NOTE
I highly recommend that you always start by using the auto recorded and written UI tests that Xcode can create for you. This will give you an insight into how you can find your UI elements better on the screen. Having said that, Xcode isn’t always so intelligent in finding the UI elements.
See Also