XCTest Swift - How do I swipe faster or more precisely? XCTest Swift - How do I swipe faster or more precisely? xcode xcode

XCTest Swift - How do I swipe faster or more precisely?


I wrote an extension based on the excellent answer given by Bharathram C.

I find it to be a much gentler swipe than XCUIElement.swipeUp()

//  XCUIElement+GentleSwipe.swiftimport Foundationimport XCTestextension XCUIElement{    enum direction : Int {        case Up, Down, Left, Right    }    func gentleSwipe(_ direction : direction) {        let half : CGFloat = 0.5        let adjustment : CGFloat = 0.25        let pressDuration : TimeInterval = 0.05        let lessThanHalf = half - adjustment        let moreThanHalf = half + adjustment        let centre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: half))        let aboveCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: lessThanHalf))        let belowCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: moreThanHalf))        let leftOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: lessThanHalf, dy: half))        let rightOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: moreThanHalf, dy: half))        switch direction {        case .Up:            centre.press(forDuration: pressDuration, thenDragTo: aboveCentre)            break        case .Down:            centre.press(forDuration: pressDuration, thenDragTo: belowCentre)            break        case .Left:            centre.press(forDuration: pressDuration, thenDragTo: leftOfCentre)            break        case .Right:            centre.press(forDuration: pressDuration, thenDragTo: rightOfCentre)            break        }    }}


Yes, we can have a co-ordinate based swipe in Swift. We can create our own swipe action by using the pressForDuration(duration, thenDragToElement: XCElement). Please see an example below.

For this we will need

  1. Reference Element in the view.(Pick one in the section where the swiping action has to be performed, and it should not be a draggable element).
  2. A beginning co-ordinate with respect to the reference element.
  3. An end co-ordinate/XCUIElement with respect to the reference element.

Then we can have a function similar to below (in Swift 3)

func customSwipe(refElement:XCUIElement,startdelxy:CGVector,enddeltaxy: CGVector){      let swipeStartPoint = refElement.coordinate(withNormalizedOffset: startdelxy)      let swipeEndPoint = refElement.coordinate(withNormalizedOffset: enddeltaxy)      swipeStartPoint.press(forDuration: 0.1, thenDragTo: swipeEndPoint)}

Here if startdelxy is (0.0,0.0) and enddeltaxy is (0.0,-ve), swipe will go upward from the refElement. If enddeltaxy is (0.0,+ve) swipe will go down.This is because our reference element will be the origin, X is +ve going right and Y is +ve going below our reference element. Start with smaller values of Y (say -0.75) and change as necessary. More the Difference, Longer the Swipe.

The swipeStartPoint and swipeEndPoint can be replaced with an element (if such exists in the view). Usually, for swipeEndPoint we can go for an element in the Nav Bar for a swipeUp action. Also, Changing the X can give us customSwipes in the left and right directions.

As for the Speed of swiping, I'm not aware of any API that can swipe faster/slower than the default rate.


Updated the first answer for Swift 4.

extension XCUIElement {    enum Direction: Int {        case up, down, left, right    }    func gentleSwipe(_ direction: Direction) {        let half: CGFloat = 0.5        let adjustment: CGFloat = 0.25        let pressDuration: TimeInterval = 0.05        let lessThanHalf = half - adjustment        let moreThanHalf = half + adjustment        let centre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: half))        let aboveCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: lessThanHalf))        let belowCentre = self.coordinate(withNormalizedOffset: CGVector(dx: half, dy: moreThanHalf))        let leftOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: lessThanHalf, dy: half))        let rightOfCentre = self.coordinate(withNormalizedOffset: CGVector(dx: moreThanHalf, dy: half))        switch direction {        case .up:            centre.press(forDuration: pressDuration, thenDragTo: aboveCentre)        case .down:            centre.press(forDuration: pressDuration, thenDragTo: belowCentre)        case .left:            centre.press(forDuration: pressDuration, thenDragTo: leftOfCentre)        case .right:            centre.press(forDuration: pressDuration, thenDragTo: rightOfCentre)        }    }}